home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_01 / cmenu.exe / CMENU3.C < prev    next >
Text File  |  1991-10-17  |  5KB  |  216 lines

  1. /************************************************************
  2.  *    Program: CMENU Menu Compiler
  3.  *  Module: cmenu3.c
  4.  *        Menu Compiler:
  5.  *        Token Processing Functions
  6.  *    Written by: Leor Zolman, 7/91
  7.  ************************************************************/
  8.  
  9. #include "cmenu.h"
  10. #include "ccmenu.h"
  11.  
  12. #include <ctype.h>
  13.  
  14. static int unget_flag = FALSE;
  15. static int unget_token;
  16. static char unget_tparam[MAX_CMD];
  17. static int unget_vparam;
  18.  
  19. static int quoted_text;
  20.  
  21. #if __STDC__
  22. char *getword(void);
  23. int matchkey(char *);
  24. #else
  25. char *getword();
  26. int matchkey();
  27. #endif
  28.  
  29. /************************************************************
  30.  * ungettok():
  31.  *    Push a token back into the input stream, to
  32.  *    be returned by the following call to gettok().
  33.  *    Only one level of push-back is supported; any attempt to
  34.  *    push back a token when there is already one pushed back
  35.  *    draws an "internal error" diagnostic.
  36.  ************************************************************/
  37.  
  38. Void ungettok(tok)
  39. int tok;
  40. {
  41.     if (unget_flag)        /* can't "unget" more than 1 item! */
  42.         fatalerr("internal error: ungettok() overflow");
  43.     
  44.     unget_flag = TRUE;
  45.     unget_token = tok;
  46.     unget_vparam = vparam;
  47.     strcpy(unget_tparam, tparam);
  48.     return;
  49. }
  50.  
  51.  
  52. /************************************************************
  53.  * gettok():
  54.  *    Read a token from the source input stream.
  55.  *    If the token is a reserved word, the appropriate token
  56.  *        value is returned.
  57.  *    If the token is a string, the global "tparam" is set
  58.  *        to the text of the string. White space within the
  59.  *        string is only recognized if double quote ("...")
  60.  *        characters are used to delimit the string.
  61.  *        T_STRING is returned.
  62.  *    If the token is a numeric value, the global "vparam"
  63.  *        is set to the integer value specified, and
  64.  *        T_VALUE is returned.
  65.  *    Returns T_EOF on end-of-file.
  66.  ************************************************************/
  67.  
  68. int gettok()
  69. {
  70.     register c;
  71.     char nexttok[MAX_CMD];
  72.     char *wordp;
  73.     
  74.     if (unget_flag)        /* was a token "pushed back"?    */
  75.     {            /* yes. set the pushed-back values and    */
  76.         vparam = unget_vparam;            /* attributes    */
  77.         strcpy(tparam, unget_tparam);    /* clear the    */
  78.         unget_flag = FALSE;                /* flag            */
  79.         return unget_token;        /* return pushed token    */
  80.     }
  81.     
  82.     *tparam = '\0';                    /* clear parameter    */
  83.     vparam = 0;                        /* value registers    */
  84.  
  85.     if (!*(wordp = getword()))        /* get a token.        */
  86.         return token = T_EOF;        /* End of file        */
  87.     
  88.     if (quoted_text)                /* string enclosed    */
  89.     {                                /* in quotes?        */
  90.         strcpy(tparam, wordp);
  91.         return T_STRING;
  92.     }
  93.  
  94.     if (!strcmp(wordp, ":"))        /* colon is special    */
  95.         return T_COLON;                /* (non-alphabetic)    */
  96.  
  97.     if (c = matchkey(wordp))        /* reserved word?    */
  98.         return c;                    /* yes, just return    */
  99.  
  100.     if (isdigit(*wordp))            /* handle numeric value    */
  101.     {
  102.         vparam = atoi(wordp);
  103.         return T_VALUE;
  104.     }
  105.     else
  106.     {
  107.         strcpy(tparam, wordp);
  108.         return T_STRING;
  109.     }
  110. }
  111.  
  112.  
  113. /************************************************************
  114.  * getword():
  115.  *    Read the next syntactic object from the input stream,
  116.  *    and return a pointer to it.
  117.  *    Return pointer to a null string on EOF.
  118.  *    If object is a quoted string, drop the quotes and
  119.  *        set the quoted_text flag (preserve whitespace).
  120.  *    Otherwise strip all whitespace, commas and comments,
  121.  *        return pointer to next word/number.
  122.  *  Track current line number by incrementing lineno
  123.  *        on each newline encountered.
  124.  ************************************************************/
  125.  
  126. char *getword()
  127. {
  128.     static char tok[MAX_CMD];
  129.     char quote_char;
  130.     register c,i;
  131.     
  132.     quoted_text = FALSE;
  133.     *tok = '\0';
  134.  
  135.     while ((c = getc(fp)) != EOF)
  136.     {
  137.         if (c == '\n')                /* bump line number if    */
  138.             lineno++;                /* newline encountered    */
  139.         
  140.         if (isspace(c))                /* skip all whitespace    */
  141.             continue;
  142.  
  143.         if (c == ',' || c == ';')    /* legal separators: ,; */
  144.             continue;
  145.                 
  146.         if (c == ':')                /* special case: colon    */
  147.             return ":";
  148.         
  149.         if (c == '#')                /* process comment        */
  150.         {                        /* wait for newline or EOF    */
  151.             while(c = getc(fp))
  152.             {
  153.                 if (c == EOF)
  154.                     break;
  155.                 if (c == '\n')
  156.                 {
  157.                     lineno++;
  158.                     break;
  159.                 }
  160.             }
  161.             continue;                /* then get next token    */
  162.         }
  163.         
  164.         if (c == '"' || c == '\'')    /* quoted string?        */
  165.         {
  166.             quoted_text = TRUE;
  167.             quote_char = c;
  168.             for (i = 0; ;i++)
  169.             {
  170.                 switch (c = getc(fp))
  171.                 {
  172.                     case '\n':
  173.                         fatalerr("Unterminated string");
  174.                         return NULL;
  175.                         
  176.                     case EOF:
  177.                         fatalerr("Unterminated string (line %d)",
  178.                                 lineno);
  179.                         return NULL;
  180.                     
  181.                     case '"':
  182.                     case '\'':
  183.                         if (c == quote_char)
  184.                         {
  185.                             tok[i] = '\0';
  186.                             return tok;
  187.                         }
  188.  
  189.                     default:
  190.                         if (i == MAX_CMD)
  191.                         {
  192.                             tok[i - 1] = '\0';
  193.                             fatalerr("String too long (max %d chars)",
  194.                                 MAX_CMD);
  195.                             return NULL;
  196.                         }
  197.                         tok[i] = c;
  198.                 }
  199.             }
  200.         }
  201.         
  202.         tok[0] = c;
  203.         for (i = 1; (c = getc(fp)) != EOF; i++)
  204.             if (isspace(c) || c == ';' || c == ','
  205.                     || c == ':')
  206.                 break;
  207.             else
  208.                 tok[i] = tolower(c);
  209.         tok[i] = '\0';
  210.         ungetc(c, fp);
  211.         break;
  212.     }
  213.     return tok;
  214. }
  215.  
  216.