earlybrowserreborn - Rev 1

Subversion Repositories:
Rev:

/* MODULE                                                       HTLex.c
**              LEXICAL ANALYSOR
**
** AUTHORS:
**      AL      Ari Luotonen    luotonen@dxcern.cern.ch
**
** HISTORY:
**
**
** BUGS:
**
**
*/


#include "HTAAUtil.h"
#include "HTLex.h"      /* Implemented here */


/*
** Global variables
*/

PUBLIC char lex_buffer[40];     /* Read lexical string          */
PUBLIC int lex_line = 1;        /* Line number in source file   */


/*
** Module-wide variables
*/

PRIVATE int lex_cnt;
PRIVATE BOOL lex_template;
PRIVATE LexItem lex_pushed_back = LEX_NONE;
PRIVATE FILE *cache = NULL;


PUBLIC void unlex ARGS1(LexItem, lex_item)
{
    lex_pushed_back = lex_item;
}


PUBLIC LexItem lex ARGS1(FILE *, fp)
{
    int ch;

    if (fp != cache) {  /* This cache doesn't work ok because the system  */
        cache = fp;     /* often assign same FILE structure the next open */
        lex_line = 1;   /* file. So, if there are syntax errors in setup  */
    }                   /* files it may confuse things later on.          */

    if (lex_pushed_back != LEX_NONE) {
        LexItem ret = lex_pushed_back;
        lex_pushed_back = LEX_NONE;
        return ret;
    }

    lex_cnt = 0;
    lex_template = NO;

    for(;;) {
        switch (ch = getc(fp)) {
          case EOF:
          case ' ':
          case '\t':
          case '\r':
          case '\n':
          case ':':
          case ',':
          case '(':
          case ')':
          case '@':
            if (lex_cnt > 0) {
                if (ch != EOF) ungetc(ch,fp);
                if (lex_template) return LEX_TMPL_STR;
                else              return LEX_ALPH_STR;
            }
            else switch(ch) {
              case EOF:         return LEX_EOF;         break;
              case '\n':
                lex_line++;     return LEX_REC_SEP;     break;
              case ':':         return LEX_FIELD_SEP;   break;
              case ',':         return LEX_ITEM_SEP;    break;
              case '(':         return LEX_OPEN_PAREN;  break;
              case ')':         return LEX_CLOSE_PAREN; break;
              case '@':         return LEX_AT_SIGN;     break;
              default:  ;       /* Leading white space ignored (SP,TAB,CR) */
            }
            break;
          default:
            lex_buffer[lex_cnt++] = ch;
            lex_buffer[lex_cnt] = (char)0;
            if ('*' == ch) lex_template = YES;
        } /* switch ch */
    } /* forever */
}


PUBLIC char *lex_verbose ARGS1(LexItem, lex_item)
{
    static char msg[100];

    switch (lex_item) {
      case LEX_NONE:            /* Internally used      */
        return "NO-LEX-ITEM";
        break;
      case LEX_EOF:             /* End of file          */
        return "end-of-file";
        break;
      case LEX_REC_SEP:         /* Record separator     */
        return "record separator (newline)";
        break;
      case LEX_FIELD_SEP:       /* Field separator      */
        return "field separator ':'";
        break;
      case LEX_ITEM_SEP:        /* List item separator  */
        return "item separator ','";
        break;
      case LEX_OPEN_PAREN:      /* Group start tag      */
        return "'('";
        break;
      case LEX_CLOSE_PAREN:     /* Group end tag        */
        return "')'";
        break;
      case LEX_AT_SIGN:         /* Address qualifier    */
        return "address qualifier '@'";
        break;
      case LEX_ALPH_STR:        /* Alphanumeric string  */
        sprintf(msg, "alphanumeric string '%s'", lex_buffer);
        return msg;
        break;
      case LEX_TMPL_STR:        /* Template string      */
        sprintf(msg, "template string '%s'", lex_buffer);
        return msg;
        break;
      default:
        return "UNKNOWN-LEX-ITEM";
        break;
    }
}