home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / CMCD0304.ISO / Software / Freeware / Programare / nullsoft / nsis20.exe / Source / lineparse.h < prev    next >
C/C++ Source or Header  |  2003-07-12  |  5KB  |  200 lines

  1. #ifndef _LINEPARSE_H_
  2. #define _LINEPARSE_H_
  3.  
  4. class LineParser {
  5.   public:
  6.  
  7.     LineParser(bool bCommentBlock)
  8.     {
  9.       m_bCommentBlock=bCommentBlock;
  10.       m_nt=m_eat=0;
  11.       m_tokens=0;
  12.     }
  13.     
  14.     ~LineParser()
  15.     {
  16.       freetokens();
  17.     }
  18.     
  19.     bool InCommentBlock()
  20.     {
  21.       return m_bCommentBlock;
  22.     }
  23.     
  24.     int parse(char *line, int ignore_escaping=0) // returns -1 on error
  25.     {
  26.       freetokens();
  27.       bool bPrevCB=m_bCommentBlock;
  28.       int n=doline(line, ignore_escaping);
  29.       if (n) return n;
  30.       if (m_nt) 
  31.       {
  32.         m_bCommentBlock=bPrevCB;
  33.         m_tokens=(char**)malloc(sizeof(char*)*m_nt);
  34.         n=doline(line, ignore_escaping);
  35.         if (n) 
  36.         {
  37.           freetokens();
  38.           return -1;
  39.         }
  40.       }
  41.       return 0;
  42.     }
  43.  
  44.     int getnumtokens() { return m_nt-m_eat; }
  45.  
  46.     void eattoken() { m_eat++; }
  47.  
  48.     double gettoken_float(int token, int *success=0)
  49.     {
  50.       token+=m_eat;
  51.       if (token < 0 || token >= m_nt) 
  52.       {
  53.         if (success) *success=0;
  54.         return 0.0;
  55.       }
  56.       if (success)
  57.       {
  58.         char *t=m_tokens[token];
  59.         *success=*t?1:0;
  60.         while (*t) 
  61.         {
  62.           if ((*t < '0' || *t > '9')&&*t != '.') *success=0;
  63.           t++;
  64.         }
  65.       }
  66.       return atof(m_tokens[token]);
  67.     }
  68.     int gettoken_int(int token, int *success=0) 
  69.     { 
  70.       token+=m_eat;
  71.       if (token < 0 || token >= m_nt || !m_tokens[token][0]) 
  72.       {
  73.         if (success) *success=0;
  74.         return 0;
  75.       }
  76.       char *tmp;
  77.       int l;
  78.       if (m_tokens[token][0] == '-') l=strtol(m_tokens[token],&tmp,0);
  79.       else l=(int)strtoul(m_tokens[token],&tmp,0);
  80.       if (success) *success=! (int)(*tmp);
  81.       return l;
  82.     }
  83.     char *gettoken_str(int token) 
  84.     { 
  85.       token+=m_eat;
  86.       if (token < 0 || token >= m_nt) return "";
  87.       return m_tokens[token]; 
  88.     }
  89.     int gettoken_enum(int token, const char *strlist) // null seperated list
  90.     {
  91.       int x=0;
  92.       char *tt=gettoken_str(token);
  93.       if (tt && *tt) while (*strlist)
  94.       {
  95.         if (!stricmp(tt,strlist)) return x;
  96.         strlist+=strlen(strlist)+1;
  97.         x++;
  98.       }
  99.       return -1;
  100.     }
  101.   private:
  102.     void freetokens()
  103.     {
  104.       if (m_tokens)
  105.       {
  106.         int x;
  107.         for (x = 0; x < m_nt; x ++)
  108.           free(m_tokens[x]);
  109.         free(m_tokens);
  110.       }
  111.       m_tokens=0;
  112.       m_nt=0;
  113.     }
  114.  
  115.     int doline(char *line, int ignore_escaping=0)
  116.     {
  117.       m_nt=0;
  118.       if ( m_bCommentBlock )
  119.       {
  120.         while ( *line )
  121.         {
  122.           if ( *line == '*' && *(line+1) == '/' )
  123.           {
  124.             m_bCommentBlock=false; // Found end of comment block
  125.             line+=2;
  126.             break;
  127.           }
  128.           line++;
  129.         }
  130.       }
  131.       while (*line == ' ' || *line == '\t') line++;
  132.       while (*line) 
  133.       {
  134.         int lstate=0; // 1=", 2=`, 4='
  135.         if (*line == ';' || *line == '#') break;
  136.         if (*line == '/' && *(line+1) == '*')
  137.         {
  138.           m_bCommentBlock = true;
  139.           line+=2;
  140.           return doline(line, ignore_escaping);
  141.         }
  142.         if (*line == '\"') lstate=1;
  143.         else if (*line == '\'') lstate=2;
  144.         else if (*line == '`') lstate=4;
  145.         if (lstate) line++;
  146.         int nc=0;
  147.         char *p = line;
  148.         while (*line)
  149.         {
  150.           if (line[0] == '$' && line[1] == '\\') {
  151.             switch (line[2]) {
  152.               case '"':
  153.               case '\'':
  154.               case '`':
  155.                 nc += ignore_escaping ? 3 : 1;
  156.                 line += 3;
  157.                 continue;
  158.             }
  159.           }
  160.           if (lstate==1 && *line =='\"') break;
  161.           if (lstate==2 && *line =='\'') break;
  162.           if (lstate==4 && *line =='`') break;
  163.           if (!lstate && (*line == ' ' || *line == '\t')) break;
  164.           line++;
  165.           nc++;
  166.         }
  167.         if (m_tokens)
  168.         {
  169.           int i;
  170.           m_tokens[m_nt]=(char*)malloc(nc+1);
  171.           for (i = 0; p < line; i++, p++) {
  172.             if (!ignore_escaping && p[0] == '$' && p[1] == '\\') {
  173.               switch (p[2]) {
  174.                 case '"':
  175.                 case '\'':
  176.                 case '`':
  177.                   p += 2;
  178.               }
  179.             }
  180.             m_tokens[m_nt][i] = *p;
  181.           }
  182.           m_tokens[m_nt][nc]=0;
  183.         }
  184.         m_nt++;
  185.         if (lstate)
  186.         {
  187.           if (*line) line++;
  188.           else return -2;
  189.         }
  190.         while (*line == ' ' || *line == '\t') line++;
  191.       }
  192.       return 0;
  193.     }
  194.     
  195.     int m_eat;
  196.     int m_nt;
  197.     bool m_bCommentBlock;
  198.     char **m_tokens;
  199. };
  200. #endif//_LINEPARSE_H_