PRIVATE ItemList *parse_item_list ARGS1(FILE *, fp) { ItemList *item_list = HTList_new(); Item *item; LexItem lex_item; for(;;) { if (!(item = parse_item(fp))) { HTList_delete(item_list); /* @@@@ */ item_list = NULL; return NULL; } HTList_addObject(item_list, (void*)item); lex_item = lex(fp); if (lex_item != LEX_ITEM_SEP) { unlex(lex_item); return item_list; } /* ** Here lex_item == LEX_ITEM_SEP; after item separator it ** is ok to have one or more newlines (LEX_REC_SEP) and ** they are ignored (continuation line). */ do { lex_item = lex(fp); } while (lex_item == LEX_REC_SEP); unlex(lex_item); } }
unsigned get_arg(void) { SCRATCH int c; SCRATCH unsigned a, u; a = NUM; u = 0; bad = FALSE; switch (lex() -> attr & TYPE) { case SEP: exp_error('S'); a = NONE; break; case EOL: unlex(); a = NONE; break; case REG: a = token.valu; break; case OPR: if (token.valu == '(') { if ((lex() -> attr & TYPE) == REG) { a = token.valu; lex(); switch (a) { case C: a = C_IND; break; case BC: case DE: case SP: a += SP_IND - SP; break; case HL: a = HL_IND; break; case IX: a = IX_IND; goto do_ix_ind; case IY: a = IY_IND; do_ix_ind: if ((token.attr & TYPE) == OPR && (token.valu == '+' || token.valu == '-')) { unlex(); if ((u = eval(LPREN)) > 0x7f && u < 0xff80) exp_error('V'); } break; default: exp_error('R'); break; } if ((token.attr & TYPE) != OPR || token.valu != ')') exp_error(')'); break; } else { unlex(); u = eval(LPREN); trash(); pushc(c = popc()); if (c == ',' || c == '\n') { a = NUM_IND; break; } token.attr = VAL; token.valu = u; } } case VAL: case STR: unlex(); u = eval(START); unlex(); break; } arg.valu = bad ? 0 : u; return arg.attr = a; }
PRIVATE Item *parse_item ARGS1(FILE *, fp) { Item *item = NULL; UserDefList *user_def_list = NULL; AddressDefList *address_def_list = NULL; LexItem lex_item; lex_item = lex(fp); if (lex_item == LEX_ALPH_STR || lex_item == LEX_OPEN_PAREN) { unlex(lex_item); user_def_list = parse_user_part(fp); lex_item = lex(fp); } if (lex_item == LEX_AT_SIGN) { lex_item = lex(fp); if (lex_item == LEX_ALPH_STR || lex_item == LEX_TMPL_STR || lex_item == LEX_OPEN_PAREN) { unlex(lex_item); address_def_list = parse_address_part(fp); } else { if (user_def_list) { HTList_delete(user_def_list); /* @@@@ */ user_def_list = NULL; } syntax_error(fp, "Expected address part (single address or list)", lex_item); return NULL; } } else unlex(lex_item); if (!user_def_list && !address_def_list) { syntax_error(fp, "Empty item not allowed", lex_item); return NULL; } item = (Item*)calloc(1, sizeof(Item)); item->user_def_list = user_def_list; item->address_def_list = address_def_list; return item; }
/* * La procedure "parser" fait l'analyse syntaxique du fichier source. * Entree/Sortie : * bsp Scene surfacique polygonale a lire. */ void parser (Bound_scene *bsp) { int token; while ((token = lex ()) != T_EOF) switch (token) { case '$' : switch (lex ()) { case T_IDENT : /* saute la commande inconnue */ skip_cmd (/* stderr */); unlex (); break; case T_EXIT : return; break; case T_BOUND : if (bsp->bound.nbr == BOUND_NBR) { fprintf (stderr, "mire: too much bound\n"); return; } fscanf_Bound ( &(bsp->bound.ptr[bsp->bound.nbr++])); break; #ifdef used case T_REMOVE : fscanf_Remove (get_remove ()); break; case T_VIEW : fscanf_View_parameters (get_view_parameters ()); set_projection (void); break; #endif /* used */ default : lexerr ("start", "keyword expected", NULL); break; } break; default : lexerr ("start", "symbol '$' expected", NULL); break; } }
void HTAA_parseProtFile( HTAAProt *prot, FILE *fp ) { if ( prot && fp ) { LexItem lex_item; char *fieldname = 0; do { lex_item = lex( fp ); if ( lex_item != LEX_EOF ) { for ( ; lex_item == LEX_REC_SEP; ) { lex_item = lex( fp ); } if ( lex_item == LEX_EOF ) goto B7; else { if ( lex_item == LEX_ALPH_STR ) { HTSACopy( &fieldname, HTlex_buffer ); lex_item = lex( fp ); if ( lex_item != LEX_FIELD_SEP ) unlex( lex_item ); if ( strncasecomp( fieldname, "Auth", 4 ) == 0 ) { lex_item = lex( fp ); do { if ( lex_item == LEX_ALPH_STR ) { HTAAScheme scheme = HTAAScheme_enum( HTlex_buffer ); if ( scheme ) { if ( prot->valid_schemes == 0 ) { prot->valid_schemes = HTList_new( ); } HTList_addObject( &prot->valid_schemes, &scheme ); if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "%s %s `%s'\n", "HTAA_parseProtFile: valid", "authentication scheme:", HTAAScheme_name( scheme ) ); } } else if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "%s %s `%s'\n", "HTAA_parseProtFile: unknown", "authentication scheme:", HTlex_buffer ); } lex( fp ); while ( lex_item = lex( fp ), lex_item == LEX_ITEM_SEP ) { lex( fp ); } } } while ( lex_item != LEX_REC_SEP ); } else { if ( strncasecomp( fieldname, "mask", 4 ) == 0 ) { prot->mask_group = HTAA_parseGroupDef( fp ); lex_item = LEX_REC_SEP; if ( WWW_TraceFlag ) { if ( prot->mask_group ) { fwrite( "HTAA_parseProtFile: Mask group:\n", 1, 32, TraceFP( ) ); HTAA_printGroupDef( &prot->mask_group ); } else { fwrite( "HTAA_parseProtFile: Mask group syntax error\n", 1, 44, TraceFP( ) ); } } } else { lex_item = lex( fp ); if ( lex_item == LEX_ALPH_STR ) { if ( prot->values == 0 ) { prot->values = HTAssocList_new( ); } HTAssocList_add( &prot->values, fieldname, HTlex_buffer ); lex_item = lex( fp ); if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "%s `%s' bound to value `%s'\n", "HTAA_parseProtFile: Name", fieldname, HTlex_buffer ); } } } } } if ( lex_item != LEX_EOF && lex_item != LEX_REC_SEP ) { if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "%s %s %d (that line ignored)\n", "HTAA_parseProtFile: Syntax error", "in protection setup file at line", HTlex_line ); } do { lex_item = lex( fp ); } while ( lex_item != LEX_EOF && lex_item != LEX_REC_SEP ); } } } B7:; if ( fieldname == 0 ) break; free( fieldname ); break; } while ( lex_item != LEX_REC_SEP ); } return; }
static long subexpr(register int precedence, int* pun) { register int c; register long n; register long x; register int operand = 1; int un = 0; int xn; switch (lex(c)) { case 0: case '\n': unlex(c); if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "more tokens expected"; return 0; case '-': n = -subexpr(13, &un); break; case '+': n = subexpr(13, &un); break; case '!': n = !subexpr(13, &un); break; case '~': n = ~subexpr(13, &un); break; default: unlex(c); n = 0; operand = 0; break; } un <<= 1; for (;;) { switch (lex(c)) { case 0: case '\n': goto done; case ')': if (!precedence) { if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "too many )'s"; return 0; } goto done; case '(': n = subexpr(1, &un); if (lex(c) != ')') { unlex(c); if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "closing ) expected"; return 0; } gotoperand: if (operand) { if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "operator expected"; return 0; } operand = 1; un <<= 1; continue; case '?': if (precedence > 1) goto done; un = 0; if (lex(c) == ':') { if (!n) n = subexpr(2, &un); else { x = pp.mode; pp.mode |= INACTIVE; subexpr(2, &xn); pp.mode = x; } } else { unlex(c); x = subexpr(2, &xn); if (lex(c) != ':') { unlex(c); if (!errmsg && !(pp.mode & INACTIVE)) errmsg = ": expected for ? operator"; return 0; } if (n) { n = x; un = xn; subexpr(2, &xn); } else n = subexpr(2, &un); } break; case ':': goto done; case T_ANDAND: case T_OROR: xn = (c == T_ANDAND) ? 4 : 3; if (precedence >= xn) goto done; if ((n != 0) == (c == T_ANDAND)) n = subexpr(xn, &un) != 0; else { x = pp.mode; pp.mode |= INACTIVE; subexpr(xn, &un); pp.mode = x; } un = 0; break; case '|': if (precedence > 4) goto done; n |= subexpr(5, &un); break; case '^': if (precedence > 5) goto done; n ^= subexpr(6, &un); break; case '&': if (precedence > 6) goto done; n &= subexpr(7, &un); break; case T_EQ: case T_NE: if (precedence > 7) goto done; n = (n == subexpr(8, &un)) == (c == T_EQ); un = 0; break; case '<': case T_LE: case T_GE: case '>': if (precedence > 8) goto done; x = subexpr(9, &un); switch (c) { case '<': switch (un) { case 01: n = n < (unsigned long)x; break; case 02: n = (unsigned long)n < x; break; case 03: n = (unsigned long)n < (unsigned long)x; break; default: n = n < x; break; } break; case T_LE: switch (un) { case 01: n = n <= (unsigned long)x; break; case 02: n = (unsigned long)n <= x; break; case 03: n = (unsigned long)n <= (unsigned long)x; break; default: n = n <= x; break; } break; case T_GE: switch (un) { case 01: n = n >= (unsigned long)x; break; case 02: n = (unsigned long)n >= x; break; case 03: n = (unsigned long)n >= (unsigned long)x; break; default: n = n >= x; break; } break; case '>': switch (un) { case 01: n = n > (unsigned long)x; break; case 02: n = (unsigned long)n > x; break; case 03: n = (unsigned long)n > (unsigned long)x; break; default: n = n > x; break; } break; } un = 0; break; case T_LSHIFT: case T_RSHIFT: if (precedence > 9) goto done; x = subexpr(10, &un); if (c == T_LSHIFT) n <<= x; else n >>= x; un >>= 1; break; case '+': case '-': if (precedence > 10) goto done; x = subexpr(11, &un); if (c == '+') n += x; else n -= x; break; case '*': case '/': case '%': if (precedence > 11) goto done; x = subexpr(12, &un); if (c == '*') n *= x; else if (x == 0) { if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "divide by zero"; return 0; } else if (c == '/') n /= x; else n %= x; break; case '#': pp.state |= DISABLE; c = pplex(); pp.state &= ~DISABLE; if (c != T_ID) { if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "# must precede a predicate identifier"; return 0; } n = predicate(0); goto gotoperand; case T_ID: n = predicate(1); goto gotoperand; case T_CHARCONST: c = *(pp.toknxt - 1); *(pp.toknxt - 1) = 0; n = chrtoi(pp.token + 1); *(pp.toknxt - 1) = c; if (n & ~((1<<CHAR_BIT)-1)) { if (!(pp.mode & HOSTED)) error(1, "'%s': multi-character character constants are not portable", pp.token); } #if CHAR_MIN < 0 else n = (char)n; #endif goto gotoperand; case T_DECIMAL_U: case T_DECIMAL_UL: case T_OCTAL_U: case T_OCTAL_UL: case T_HEXADECIMAL_U: case T_HEXADECIMAL_UL: un |= 01; /*FALLTHROUGH*/ case T_DECIMAL: case T_DECIMAL_L: case T_OCTAL: case T_OCTAL_L: case T_HEXADECIMAL: case T_HEXADECIMAL_L: n = strtoul(pp.token, NiL, 0); if ((unsigned long)n > LONG_MAX) un |= 01; goto gotoperand; case T_WCHARCONST: n = chrtoi(pp.token); goto gotoperand; default: if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "invalid token"; return 0; } if (errmsg) return 0; if (!operand) goto nooperand; } done: unlex(c); if (!operand) { nooperand: if (!errmsg && !(pp.mode & INACTIVE)) errmsg = "operand expected"; return 0; } if (un) *pun |= 01; return n; }
static int predicate(int warn) { register char* args; register struct pplist* p; register struct ppsymbol* sym; register int type; int index; static char pred[MAXID + 1]; /* * first gather the args */ index = (int)hashref(pp.strtab, pp.token); if (warn && peekchr() != '(') switch (index) { case X_DEFINED: case X_EXISTS: case X_INCLUDED: case X_MATCH: case X_NOTICED: case X_OPTION: case X_SIZEOF: case X_STRCMP: break; default: if (pp.macref) pprefmac(pp.token, REF_IF); return 0; } strcpy(pred, pp.token); pp.state |= DISABLE; type = pppredargs(); pp.state &= ~DISABLE; switch (type) { case T_ID: case T_STRING: break; default: unlex(type); /*FALLTHROUGH*/ case 0: if (index && !(pp.state & STRICT)) error(1, "%s: predicate argument expected", pred); if (pp.macref) pprefmac(pred, REF_IF); return 0; } args = pp.args; /* * now evaluate */ debug((-6, "pred=%s args=%s", pred, args)); if ((pp.state & STRICT) && !(pp.mode & HOSTED)) switch (index) { case X_DEFINED: case X_SIZEOF: break; default: error(1, "%s(%s): non-standard predicate test", pred, args); return 0; } switch (index) { case X_DEFINED: if (type != T_ID) error(1, "%s: identifier argument expected", pred); else if ((sym = pprefmac(args, REF_IF)) && sym->macro) return 1; else if (args[0] == '_' && args[1] == '_' && !strncmp(args, "__STDPP__", 9)) { if (pp.hosted == 1 && pp.in->prev->type == IN_FILE) { pp.mode |= HOSTED; pp.flags |= PP_hosted; } return *(args + 9) ? (int)hashref(pp.strtab, args + 9) : 1; } break; case X_EXISTS: case X_INCLUDED: return exists(index, pred, args); case X_MATCH: case X_STRCMP: return compare(pred, args, index == X_MATCH); case X_NOTICED: if (type != T_ID) error(1, "%s: identifier argument expected", pred); else if (((sym = pprefmac(args, REF_IF)) || (sym = ppsymref(pp.symtab, args))) && (sym->flags & SYM_NOTICED)) return 1; break; case X_OPTION: return ppoption(args); case X_SIZEOF: error(2, "%s invalid in #%s expressions", pred, dirname(IF)); break; default: if (warn && !(pp.mode & HOSTED) && (sym = ppsymref(pp.symtab, pred)) && (sym->flags & SYM_PREDICATE)) error(1, "use #%s(%s) to disambiguate", pred, args); if (p = (struct pplist*)hashget(pp.prdtab, pred)) { if (!*args) return 1; while (p) { if (streq(p->value, args)) return 1; p = p->next; } } break; } return 0; }