home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE51.TAR / mbase51 / src / mb_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-04  |  6.2 KB  |  339 lines

  1. /*
  2.  * METALBASE 5.1
  3.  *
  4.  * Released January 1st, 1993 by Huan-Ti [ t-richj@microsoft.com ]
  5.  *
  6.  */
  7.  
  8. #include <mbase.h>
  9. #include <parse.h>
  10.  
  11.  
  12. /*
  13.  * MACROS ---------------------------------------------------------------------
  14.  *
  15.  */
  16.  
  17. #define isEOL(x)   (x=='\n' || x=='\r')
  18. #define isQuote(x) (x=='\"')
  19. #define isWhite(x) (x==' ' || x=='\t')
  20.  
  21. #define isChar(x)  (isalnum(x) || (x=='.') || (x=='_'))
  22.  
  23. #define isToken(x) ( x=='(' || x==')' || x==';' || x=='#'  || \
  24.                      x=='[' || x==']' || x==':' || x=='\'' || \
  25.                      x=='{' || x=='}' || x==',')
  26.  
  27. #define isDupEOL(p) ( (*p == '\n' && *(p+1) == '\r') || \
  28.                       (*p == '\r' && *(p+1) == '\n') )
  29.  
  30.  
  31. /*
  32.  * PROTOTYPES -----------------------------------------------------------------
  33.  *
  34.  */
  35.  
  36.    static bool    fpFillBuffer  XARGS( (FParse *) );
  37.    static charptr fpCleanup     XARGS( (FParse *, charptr, charptr) );
  38.  
  39.  
  40. /*
  41.  * FILE PARSING ROUTINES ------------------------------------------------------
  42.  *
  43.  */
  44.  
  45. void
  46. fpClose (fp)
  47. FParse  *fp;
  48. {
  49.    if (fp != NULL)
  50.       {
  51.       if (fp->fh > 0)
  52.          {
  53.          close (fp->fh);
  54.          }
  55.       free (fp);
  56.       }
  57. }
  58.  
  59. FParse *
  60. fpInitStr (str, fLower)
  61. charptr    str;
  62. bool            fLower;
  63. {
  64.    FParse *fp;
  65.  
  66.    if ((fp = New (FParse)) == NULL)
  67.       return NULL;
  68.  
  69.    fp->fh       =  0;
  70.    fp->str      =  str;
  71.    fp->fLower   = fLower;
  72.    fp->lastpos  = -1L;
  73.    fp->curpos   =  0L;
  74.    fp->fEOF     =  FALSE;
  75.    fp->fQuoted  =  FALSE;
  76.    fp->buf[0]   =  0;
  77.    fp->nBuf     =  0;
  78.    fp->nLines   =  1;
  79.  
  80.    return fp;
  81. }
  82.  
  83. FParse *
  84. fpInit (name, fLower)
  85. charptr name;
  86. bool          fLower;
  87. {
  88.    FParse *fp;
  89.  
  90.    if ((fp = New (FParse)) == NULL)
  91.       return NULL;
  92.  
  93.    if ((fp->fh = openx (name, READMODE)) <= 0)
  94.       {
  95.       free (fp);
  96.       return NULL;
  97.       }
  98.  
  99.    fp->str      =  NULL;
  100.    fp->fLower   = fLower;
  101.    fp->lastpos  = -1L;
  102.    fp->curpos   =  0L;
  103.    fp->fEOF     =  FALSE;
  104.    fp->fQuoted  =  FALSE;
  105.    fp->buf[0]   =  0;
  106.    fp->nBuf     =  0;
  107.    fp->nLines   =  1;
  108.  
  109.    return fp;
  110. }
  111.  
  112. void
  113. fpSetPos (fp, pos, lineno)
  114. FParse   *fp;
  115. long          pos;
  116. int                lineno;
  117. {
  118.    fp->lastpos  = -1L;
  119.    fp->curpos   =  pos;
  120.    fp->fEOF     =  FALSE;
  121.    fp->fQuoted  =  FALSE;
  122.    fp->buf[0]   =  0;
  123.    fp->nBuf     =  0;
  124.    fp->nLines   = max (lineno, 1);
  125.  
  126.    if (fp->fh > 0)  lseek (fp->fh, pos, 0);
  127. }
  128.  
  129. bool
  130. fpBackup (fp)
  131. FParse   *fp;
  132. {
  133.    if (! fp || (fp->lastpos == -1L))
  134.       return FALSE;
  135.  
  136.    fp->curpos   =  fp->lastpos;
  137.    fp->lastpos  = -1L;
  138.    fp->buf[0]   =  0;
  139.    fp->nBuf     =  0;
  140.    fp->fEOF     =  FALSE;
  141.    fp->nLines   =  fp->nLast;
  142.  
  143.    if (fp->fh > 0)  lseek (fp->fh, fp->curpos, 0);
  144.  
  145.    return TRUE;
  146. }
  147.  
  148. charptr
  149. fpWord (fp)
  150. FParse *fp;
  151. {
  152.    charptr  pLine, pWord;
  153.  
  154.    if (! fpFillBuffer (fp))
  155.       return NULL;
  156.  
  157.    *( pWord = fp->word ) = 0;
  158.    for (pLine = fp->buf; *pLine; pLine++)
  159.       {
  160.       *pWord = 0;
  161.  
  162.       if (! fp->fQuoted)
  163.          {
  164.          if (! strncmp (fp->word, "\/\*", 2))  break;
  165.          if (! strncmp (fp->word, "\*\/", 2))  break;
  166.          if (! strncmp (fp->word, "\/\/", 2))  break;
  167.  
  168.          if ( (pWord - fp->word) >= 2 )
  169.             {
  170.             if ( (isChar(*(pWord-2)) && !isChar(*(pWord-1))) ||
  171.                  (isChar(*(pWord-1)) && !isChar(*(pWord-2))) )
  172.                {
  173.                pLine--;
  174.                pWord--;
  175.                break;
  176.                }
  177.             }
  178.          }
  179.  
  180.       if (isQuote (*pLine))
  181.          {
  182.          if (fp->fQuoted)
  183.             {
  184.             pLine++;
  185.             break;
  186.             }
  187.          if (pWord != fp->word)
  188.             break;
  189.          fp->fQuoted = TRUE;
  190.          continue;
  191.          }
  192.  
  193.       if (isEOL (*pLine))
  194.          {
  195.          if (pWord != fp->word)  /* A newline terminates a quoted string; */
  196.             break;               /* there is no error condition for this. */
  197.          fp->nLines++;
  198.          if (isDupEOL (pLine))
  199.             pLine++;
  200.          continue;
  201.          }
  202.  
  203.       if (! fp->fQuoted)
  204.          {
  205.          if (isWhite (*pLine))
  206.             {
  207.             if (pWord != fp->word)
  208.                break;
  209.             continue;
  210.             }
  211.  
  212.          if (isToken (*pLine))
  213.             {
  214.             if (pWord != fp->word)
  215.                break;
  216.             *pWord = tolower (*pLine);
  217.             pWord++;
  218.             pLine++;
  219.             break;
  220.             }
  221.  
  222.          if (fp->fLower)
  223.             {
  224.             *pWord = tolower (*pLine);
  225.             pWord++;
  226.             continue;
  227.             }
  228.          }
  229.  
  230.       *pWord = *pLine;
  231.       pWord++;
  232.       }
  233.  
  234.    return fpCleanup (fp, pLine, pWord);
  235. }
  236.  
  237. charptr
  238. fpLine (fp)
  239. FParse *fp;
  240. {
  241.    charptr  pLine, pWord;
  242.    bool     fQuoted = FALSE;
  243.  
  244.    if (! fpFillBuffer (fp))
  245.       return NULL;
  246.  
  247.    pWord = fp->word;
  248.    for (pLine = fp->buf; *pLine; pLine++, pWord++)
  249.       {
  250.       if (isEOL (*pLine))
  251.          {
  252.          fp->nLines++;
  253.  
  254.          if (isDupEOL (pLine))
  255.             pLine++;
  256.          pLine++;
  257.  
  258.          break;
  259.          }
  260.       if (isQuote (*pLine))
  261.          {
  262.          fQuoted = (fQuoted) ? FALSE : TRUE;
  263.          }
  264.  
  265.       if (fp->fLower && !fQuoted)
  266.          {
  267.          *pWord = tolower(*pLine);
  268.          }
  269.       else
  270.          {
  271.          *pWord = *pLine;
  272.          }
  273.       }
  274.  
  275.    return fpCleanup (fp, pLine, pWord);
  276. }
  277.  
  278.  
  279. /*
  280.  * SERVICE ROUTINES -----------------------------------------------------------
  281.  *
  282.  */
  283.  
  284. static charptr
  285. fpCleanup (fp, pLine, pWord)
  286. FParse    *fp;
  287. charptr        pLine, pWord;
  288. {
  289.    fp->curpos += (pLine - fp->buf);
  290.    fp->nBuf   -= (pLine - fp->buf);
  291.  
  292.    strzcpy (fp->buf, pLine, strlen(pLine));  /* Ensure strcpy() goes -> */
  293.  
  294.    *pWord = 0;
  295.  
  296.    return fp->word;
  297. }
  298.  
  299. static bool
  300. fpFillBuffer (fp)
  301. FParse       *fp;
  302. {
  303.    int  nRead;
  304.  
  305.    if (! fp)
  306.       return FALSE;
  307.  
  308.    fp->fLastEOF = FALSE;
  309.    fp->nLast    = fp->nLines;
  310.    fp->lastpos  = fp->curpos;
  311.    fp->fQuoted  = FALSE;
  312.  
  313.    if (fp->nBuf < MAX_LINE)
  314.       {
  315.       if (fp->fh > 0)
  316.          {
  317.          nRead = readx (fp->fh, &fp->buf [fp->nBuf], MAX_BUF - fp->nBuf);
  318.  
  319.          fp->nBuf += nRead;
  320.          fp->buf [fp->nBuf] = 0;
  321.          }
  322.       else
  323.          {
  324.          strncpy (fp->buf, &fp->str[fp->curpos], MAX_BUF-fp->nBuf);
  325.          fp->buf[MAX_BUF] = 0;
  326.  
  327.          fp->nBuf = nRead = strlen (fp->buf);
  328.          }
  329.  
  330.       if (nRead == 0)
  331.          {
  332.          fp->fEOF = TRUE;
  333.          }
  334.       }
  335.  
  336.    return TRUE;
  337. }
  338.  
  339.