基于wxWidgets的JSMin工具

 JSMin是一个很好的JS压缩工具,只是使用时比较不方便,于是,我给它加了个GUI,增加了多线程支持,这样,可以尽量提高JSMin的操作性。 http://p.blog.csdn.net/images/p_blog_csdn_net/ynzhangyao/EntryImages/20081130/wxJSMin.JPG
//核心代码
void JSMinDialog::DoOK(const wxString& srcPath,const wxString& destPath)
{
    if(srcPath == destPath)
    {
        wxLog::OnLog(wxLOG_Error,wxT("源文件目录下输出目录不能是同一个"),time(NULL));
        return;
    }
    wxDir srcDir(srcPath);
    wxDir destDir(destPath);
    wxArrayString fiels;
    size_t srcs = srcDir.GetAllFiles(srcPath, &fiels, wxT("*.js"));
    wxString srcFileName;
    wxString destFileName;
    wxString destFilePath;
    for(int i=0; i<fiels.Count(); ++i)
    {
        srcFileName = fiels.Item(i);
        destFileName = srcFileName;
        destFilePath = ::wxPathOnly(destFileName);
        destFilePath.Replace(srcPath,destPath);
        if(!::wxDirExists(destFilePath))
        {
            if(!::wxMkdir(destFilePath))
            {
                continue;
            }
        }
        destFileName.Replace(srcPath,destPath);
        CJSMin* js = new CJSMin(srcFileName,destFileName,wxT(""));
        CJSMinThread* pThread = new CJSMinThread(js);
        if(pThread->Create() != wxTHREAD_NO_ERROR)
        {
            delete js;
            wxLog::OnLog(wxLOG_Error,wxT("生成") + destFileName + wxT("错误"),wxDateTime::GetTimeNow());
        }
        else
        {
            wxLog::OnLog(wxLOG_Message,wxT("处理")+srcFileName+wxT(" > ") + destFileName,wxDateTime::GetTimeNow());
            pThread->Run();
        }
    }
}
  1. #ifndef WXJSMIN_H_INCLUDED
  2. #define WXJSMIN_H_INCLUDED
  3. #include <wx/file.h>
  4. #define INLINE inline
  5. class CJSMin
  6. {
  7.     private:
  8.         static const int eof = EOF;
  9.     private:
  10.         wxFile inf;
  11.         wxFile outf;
  12.         int   theA;
  13.         int   theB;
  14.         int   theLookahead;
  15.     private:
  16.         INLINE void action(int d);
  17.         INLINE int isAlphanum(int c);
  18.         INLINE int get();
  19.         INLINE int next();
  20.         INLINE int peek();
  21.     public:
  22.         INLINE void jsmin();
  23.     public:
  24.         CJSMin(wxString src,wxString dest,wxString copyRiht):inf(src),outf(dest,wxFile::write),theLookahead(EOF){}
  25.         virtual ~CJSMin();
  26. };
  27. INLINE int CJSMin::isAlphanum(int c)
  28. {
  29.     return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
  30.         (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '//' ||
  31.         c > 126);
  32. }
  33. /* get -- return the next character from stdin. Watch out for lookahead. If
  34.         the character is a control character, translate it to a space or
  35.         linefeed.
  36. */
  37. INLINE int CJSMin::get()
  38. {
  39.     int c = theLookahead;
  40.     theLookahead = eof;
  41.     if (c == eof) {
  42.         char t = 0;
  43.         //c = getc(stdin);
  44.         if(!inf.Eof())
  45.         {
  46.             inf.Read(&t,1);
  47.             c = t;
  48.         }
  49.         else
  50.         {
  51.             c = eof;
  52.         }
  53.     }
  54.     if (c >= ' ' || c == '/n' || c == eof) {
  55.         return c;
  56.     }
  57.     if (c == '/r') {
  58.         return '/n';
  59.     }
  60.     return ' ';
  61. }
  62. /* peek -- get the next character without getting it.
  63. */
  64. INLINE int CJSMin::peek()
  65. {
  66.     theLookahead = get();
  67.     return theLookahead;
  68. }
  69. /* next -- get the next character, excluding comments. peek() is used to see
  70.         if a '/' is followed by a '/' or '*'.
  71. */
  72. INLINE int CJSMin::next()
  73. {
  74.     int c = get();
  75.     if  (c == '/') {
  76.         switch (peek()) {
  77.         case '/':
  78.             for (;;) {
  79.                 c = get();
  80.                 if (c <= '/n') {
  81.                     return c;
  82.                 }
  83.             }
  84.         case '*':
  85.             get();
  86.             for (;;) {
  87.                 switch (get()) {
  88.                 case '*':
  89.                     if (peek() == '/') {
  90.                         get();
  91.                         return ' ';
  92.                     }
  93.                     break;
  94.                 case eof:
  95.                     fprintf(stderr, "Error: JSMIN Unterminated comment./n");
  96.                     exit(1);
  97.                 }
  98.             }
  99.         default:
  100.             return c;
  101.         }
  102.     }
  103.     return c;
  104. }
  105. /* action -- do something! What you do is determined by the argument:
  106.         1   Output A. Copy B to A. Get the next B.
  107.         2   Copy B to A. Get the next B. (Delete A).
  108.         3   Get the next B. (Delete B).
  109.    action treats a string as a single character. Wow!
  110.    action recognizes a regular expression if it is preceded by ( or , or =.
  111. */
  112. INLINE void CJSMin::action(int d)
  113. {
  114.     switch (d) {
  115.     case 1:
  116.         //putc(theA, stdout);
  117.         outf.Write(&theA,1);
  118.     case 2:
  119.         theA = theB;
  120.         if (theA == '/'' || theA == '"') {
  121.             for (;;) {
  122.                 //putc(theA, stdout);
  123.                 outf.Write(&theA,1);
  124.                 theA = get();
  125.                 if (theA == theB) {
  126.                     break;
  127.                 }
  128.                 if (theA == '//') {
  129.                     //putc(theA, stdout);
  130.                     outf.Write(&theA,1);
  131.                     theA = get();
  132.                 }
  133.                 if (theA == eof) {
  134.                     fprintf(stderr, "Error: JSMIN unterminated string literal.");
  135.                     exit(1);
  136.                 }
  137.             }
  138.         }
  139.     case 3:
  140.         theB = next();
  141.         if (theB == '/' && (theA == '(' || theA == ',' || theA == '=' ||
  142.                             theA == ':' || theA == '[' || theA == '!' ||
  143.                             theA == '&' || theA == '|' || theA == '?' ||
  144.                             theA == '{' || theA == '}' || theA == ';' ||
  145.                             theA == '/n')) {
  146.             //putc(theA, stdout);
  147.             //putc(theB, stdout);
  148.             outf.Write(&theA,1);
  149.             outf.Write(&theB,1);
  150.             for (;;) {
  151.                 theA = get();
  152.                 if (theA == '/') {
  153.                     break;
  154.                 }
  155.                 if (theA =='//') {
  156.                     //putc(theA, stdout);
  157.                     outf.Write(&theA,1);
  158.                     theA = get();
  159.                 }
  160.                 if (theA == eof) {
  161.                     fprintf(stderr,
  162. "Error: JSMIN unterminated Regular Expression literal./n");
  163.                     exit(1);
  164.                 }
  165.                 //putc(theA, stdout);
  166.                 outf.Write(&theA,1);
  167.             }
  168.             theB = next();
  169.         }
  170.     }
  171. }
  172. /* jsmin -- Copy the input to the output, deleting the characters which are
  173.         insignificant to JavaScript. Comments will be removed. Tabs will be
  174.         replaced with spaces. Carriage returns will be replaced with linefeeds.
  175.         Most spaces and linefeeds will be removed.
  176. */
  177. INLINE void CJSMin::jsmin()
  178. {
  179.     theA = '/n';
  180.     action(3);
  181.     while (theA != eof) {
  182.         switch (theA) {
  183.         case ' ':
  184.             if (isAlphanum(theB)) {
  185.                 action(1);
  186.             } else {
  187.                 action(2);
  188.             }
  189.             break;
  190.         case '/n':
  191.             switch (theB) {
  192.             case '{':
  193.             case '[':
  194.             case '(':
  195.             case '+':
  196.             case '-':
  197.                 action(1);
  198.                 break;
  199.             case ' ':
  200.                 action(3);
  201.                 break;
  202.             default:
  203.                 if (isAlphanum(theB)) {
  204.                     action(1);
  205.                 } else {
  206.                     action(2);
  207.                 }
  208.             }
  209.             break;
  210.         default:
  211.             switch (theB) {
  212.             case ' ':
  213.                 if (isAlphanum(theA)) {
  214.                     action(1);
  215.                     break;
  216.                 }
  217.                 action(3);
  218.                 break;
  219.             case '/n':
  220.                 switch (theA) {
  221.                 case '}':
  222.                 case ']':
  223.                 case ')':
  224.                 case '+':
  225.                 case '-':
  226.                 case '"':
  227.                 case '/'':
  228.                     action(1);
  229.                     break;
  230.                 default:
  231.                     if (isAlphanum(theA)) {
  232.                         action(1);
  233.                     } else {
  234.                         action(3);
  235.                     }
  236.                 }
  237.                 break;
  238.             default:
  239.                 action(1);
  240.                 break;
  241.             }
  242.         }
  243.     }
  244. }
  245. #endif // WXJSMIN_H_INCLUDED
    1. #ifndef THREAD_H_INCLUDED
    2. #define THREAD_H_INCLUDED
    3. #include "wx/thread.h"
    4. class CJSMin;
    5. class CJSMinThread : public wxThread
    6. {
    7.     CJSMin* m_jsmin;
    8. public:
    9.     CJSMinThread(CJSMin* jsmin):m_jsmin(jsmin){}
    10. public:
    11.     virtual void* Entry();
    12. };
    13. #endif // THREAD_H_INCLUDED
    14. #include "../thread/thread.h"
    15. #include "../jsmin/wxjsmin.h"
    16. void* CJSMinThread::Entry()
    17. {
    18.    m_jsmin->jsmin();
    19.    delete m_jsmin;
    20.    return NULL;
    21. }

你可能感兴趣的:(基于wxWidgets的JSMin工具)