1145519Sdarrenr/* $FreeBSD$ */ 2145510Sdarrenr 3145510Sdarrenr/* 4170268Sdarrenr * Copyright (C) 2002-2006 by Darren Reed. 5145510Sdarrenr * 6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr */ 8145510Sdarrenr#include <ctype.h> 9145510Sdarrenr#include "ipf.h" 10145510Sdarrenr#ifdef IPFILTER_SCAN 11145510Sdarrenr# include "netinet/ip_scan.h" 12145510Sdarrenr#endif 13145510Sdarrenr#include <sys/ioctl.h> 14145510Sdarrenr#include <syslog.h> 15145510Sdarrenr#ifdef TEST_LEXER 16145510Sdarrenr# define NO_YACC 17145510Sdarrenrunion { 18145510Sdarrenr int num; 19145510Sdarrenr char *str; 20145510Sdarrenr struct in_addr ipa; 21145510Sdarrenr i6addr_t ip6; 22145510Sdarrenr} yylval; 23145510Sdarrenr#endif 24145510Sdarrenr#include "lexer.h" 25145510Sdarrenr#include "y.tab.h" 26145510Sdarrenr 27145510SdarrenrFILE *yyin; 28145510Sdarrenr 29145510Sdarrenr#define ishex(c) (ISDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || \ 30145510Sdarrenr ((c) >= 'A' && (c) <= 'F')) 31145510Sdarrenr#define TOOLONG -3 32145510Sdarrenr 33145510Sdarrenrextern int string_start; 34145510Sdarrenrextern int string_end; 35145510Sdarrenrextern char *string_val; 36145510Sdarrenrextern int pos; 37145510Sdarrenrextern int yydebug; 38145510Sdarrenr 39145510Sdarrenrchar *yystr = NULL; 40145510Sdarrenrint yytext[YYBUFSIZ+1]; 41172776Sdarrenrchar yychars[YYBUFSIZ+1]; 42145510Sdarrenrint yylineNum = 1; 43145510Sdarrenrint yypos = 0; 44145510Sdarrenrint yylast = -1; 45145510Sdarrenrint yyexpectaddr = 0; 46145510Sdarrenrint yybreakondot = 0; 47145510Sdarrenrint yyvarnext = 0; 48145510Sdarrenrint yytokentype = 0; 49145510Sdarrenrwordtab_t *yywordtab = NULL; 50145510Sdarrenrint yysavedepth = 0; 51145510Sdarrenrwordtab_t *yysavewords[30]; 52145510Sdarrenr 53145510Sdarrenr 54145510Sdarrenrstatic wordtab_t *yyfindkey __P((char *)); 55172776Sdarrenrstatic int yygetc __P((int)); 56145510Sdarrenrstatic void yyunputc __P((int)); 57145510Sdarrenrstatic int yyswallow __P((int)); 58145510Sdarrenrstatic char *yytexttostr __P((int, int)); 59145510Sdarrenrstatic void yystrtotext __P((char *)); 60172776Sdarrenrstatic char *yytexttochar __P((void)); 61145510Sdarrenr 62172776Sdarrenrstatic int yygetc(docont) 63172776Sdarrenrint docont; 64145510Sdarrenr{ 65145510Sdarrenr int c; 66145510Sdarrenr 67145510Sdarrenr if (yypos < yylast) { 68145510Sdarrenr c = yytext[yypos++]; 69145510Sdarrenr if (c == '\n') 70145510Sdarrenr yylineNum++; 71145510Sdarrenr return c; 72145510Sdarrenr } 73145510Sdarrenr 74145510Sdarrenr if (yypos == YYBUFSIZ) 75145510Sdarrenr return TOOLONG; 76145510Sdarrenr 77145510Sdarrenr if (pos >= string_start && pos <= string_end) { 78145510Sdarrenr c = string_val[pos - string_start]; 79145510Sdarrenr yypos++; 80145510Sdarrenr } else { 81145510Sdarrenr c = fgetc(yyin); 82172776Sdarrenr if (docont && (c == '\\')) { 83172776Sdarrenr c = fgetc(yyin); 84172776Sdarrenr if (c == '\n') { 85172776Sdarrenr yylineNum++; 86172776Sdarrenr c = fgetc(yyin); 87172776Sdarrenr } 88172776Sdarrenr } 89145510Sdarrenr } 90145510Sdarrenr if (c == '\n') 91145510Sdarrenr yylineNum++; 92145510Sdarrenr yytext[yypos++] = c; 93145510Sdarrenr yylast = yypos; 94145510Sdarrenr yytext[yypos] = '\0'; 95145510Sdarrenr 96145510Sdarrenr return c; 97145510Sdarrenr} 98145510Sdarrenr 99145510Sdarrenr 100145510Sdarrenrstatic void yyunputc(c) 101145510Sdarrenrint c; 102145510Sdarrenr{ 103145510Sdarrenr if (c == '\n') 104145510Sdarrenr yylineNum--; 105145510Sdarrenr yytext[--yypos] = c; 106145510Sdarrenr} 107145510Sdarrenr 108145510Sdarrenr 109145510Sdarrenrstatic int yyswallow(last) 110145510Sdarrenrint last; 111145510Sdarrenr{ 112145510Sdarrenr int c; 113145510Sdarrenr 114172776Sdarrenr while (((c = yygetc(0)) > '\0') && (c != last)) 115145510Sdarrenr ; 116145510Sdarrenr 117145510Sdarrenr if (c != EOF) 118145510Sdarrenr yyunputc(c); 119145510Sdarrenr if (c == last) 120145510Sdarrenr return 0; 121145510Sdarrenr return -1; 122145510Sdarrenr} 123145510Sdarrenr 124145510Sdarrenr 125172776Sdarrenrstatic char *yytexttochar() 126172776Sdarrenr{ 127172776Sdarrenr int i; 128172776Sdarrenr 129172776Sdarrenr for (i = 0; i < yypos; i++) 130172776Sdarrenr yychars[i] = (char)(yytext[i] & 0xff); 131172776Sdarrenr yychars[i] = '\0'; 132172776Sdarrenr return yychars; 133172776Sdarrenr} 134172776Sdarrenr 135172776Sdarrenr 136145510Sdarrenrstatic void yystrtotext(str) 137145510Sdarrenrchar *str; 138145510Sdarrenr{ 139145510Sdarrenr int len; 140145510Sdarrenr char *s; 141145510Sdarrenr 142145510Sdarrenr len = strlen(str); 143145510Sdarrenr if (len > YYBUFSIZ) 144145510Sdarrenr len = YYBUFSIZ; 145145510Sdarrenr 146145510Sdarrenr for (s = str; *s != '\0' && len > 0; s++, len--) 147145510Sdarrenr yytext[yylast++] = *s; 148145510Sdarrenr yytext[yylast] = '\0'; 149145510Sdarrenr} 150145510Sdarrenr 151145510Sdarrenr 152145510Sdarrenrstatic char *yytexttostr(offset, max) 153145510Sdarrenrint offset, max; 154145510Sdarrenr{ 155145510Sdarrenr char *str; 156145510Sdarrenr int i; 157145510Sdarrenr 158145510Sdarrenr if ((yytext[offset] == '\'' || yytext[offset] == '"') && 159145510Sdarrenr (yytext[offset] == yytext[offset + max - 1])) { 160145510Sdarrenr offset++; 161145510Sdarrenr max--; 162145510Sdarrenr } 163145510Sdarrenr 164145510Sdarrenr if (max > yylast) 165145510Sdarrenr max = yylast; 166145510Sdarrenr str = malloc(max + 1); 167145510Sdarrenr if (str != NULL) { 168145510Sdarrenr for (i = offset; i < max; i++) 169145510Sdarrenr str[i - offset] = (char)(yytext[i] & 0xff); 170145510Sdarrenr str[i - offset] = '\0'; 171145510Sdarrenr } 172145510Sdarrenr return str; 173145510Sdarrenr} 174145510Sdarrenr 175145510Sdarrenr 176145510Sdarrenrint yylex() 177145510Sdarrenr{ 178145510Sdarrenr int c, n, isbuilding, rval, lnext, nokey = 0; 179145510Sdarrenr char *name; 180145510Sdarrenr 181145510Sdarrenr isbuilding = 0; 182145510Sdarrenr lnext = 0; 183145510Sdarrenr rval = 0; 184145510Sdarrenr 185145510Sdarrenr if (yystr != NULL) { 186145510Sdarrenr free(yystr); 187145510Sdarrenr yystr = NULL; 188145510Sdarrenr } 189145510Sdarrenr 190145510Sdarrenrnextchar: 191172776Sdarrenr c = yygetc(0); 192172776Sdarrenr if (yydebug > 1) 193172776Sdarrenr printf("yygetc = (%x) %c [%*.*s]\n", c, c, yypos, yypos, yytexttochar()); 194145510Sdarrenr 195145510Sdarrenr switch (c) 196145510Sdarrenr { 197145510Sdarrenr case '\n' : 198161357Sguido lnext = 0; 199161357Sguido nokey = 0; 200145510Sdarrenr case '\t' : 201145510Sdarrenr case '\r' : 202145510Sdarrenr case ' ' : 203145510Sdarrenr if (isbuilding == 1) { 204145510Sdarrenr yyunputc(c); 205145510Sdarrenr goto done; 206145510Sdarrenr } 207145510Sdarrenr if (yylast > yypos) { 208145510Sdarrenr bcopy(yytext + yypos, yytext, 209145510Sdarrenr sizeof(yytext[0]) * (yylast - yypos + 1)); 210145510Sdarrenr } 211145510Sdarrenr yylast -= yypos; 212145510Sdarrenr yypos = 0; 213145510Sdarrenr lnext = 0; 214145510Sdarrenr nokey = 0; 215145510Sdarrenr goto nextchar; 216145510Sdarrenr 217145510Sdarrenr case '\\' : 218145510Sdarrenr if (lnext == 0) { 219145510Sdarrenr lnext = 1; 220145510Sdarrenr if (yylast == yypos) { 221145510Sdarrenr yylast--; 222145510Sdarrenr yypos--; 223145510Sdarrenr } else 224145510Sdarrenr yypos--; 225145510Sdarrenr if (yypos == 0) 226145510Sdarrenr nokey = 1; 227145510Sdarrenr goto nextchar; 228145510Sdarrenr } 229145510Sdarrenr break; 230145510Sdarrenr } 231145510Sdarrenr 232145510Sdarrenr if (lnext == 1) { 233145510Sdarrenr lnext = 0; 234145510Sdarrenr if ((isbuilding == 0) && !ISALNUM(c)) { 235145510Sdarrenr return c; 236145510Sdarrenr } 237145510Sdarrenr goto nextchar; 238145510Sdarrenr } 239145510Sdarrenr 240145510Sdarrenr switch (c) 241145510Sdarrenr { 242145510Sdarrenr case '#' : 243145510Sdarrenr if (isbuilding == 1) { 244145510Sdarrenr yyunputc(c); 245145510Sdarrenr goto done; 246145510Sdarrenr } 247145510Sdarrenr yyswallow('\n'); 248145510Sdarrenr rval = YY_COMMENT; 249145510Sdarrenr goto nextchar; 250145510Sdarrenr 251145510Sdarrenr case '$' : 252145510Sdarrenr if (isbuilding == 1) { 253145510Sdarrenr yyunputc(c); 254145510Sdarrenr goto done; 255145510Sdarrenr } 256172776Sdarrenr n = yygetc(0); 257145510Sdarrenr if (n == '{') { 258145510Sdarrenr if (yyswallow('}') == -1) { 259145510Sdarrenr rval = -2; 260145510Sdarrenr goto done; 261145510Sdarrenr } 262172776Sdarrenr (void) yygetc(0); 263145510Sdarrenr } else { 264145510Sdarrenr if (!ISALPHA(n)) { 265145510Sdarrenr yyunputc(n); 266145510Sdarrenr break; 267145510Sdarrenr } 268145510Sdarrenr do { 269172776Sdarrenr n = yygetc(1); 270145510Sdarrenr } while (ISALPHA(n) || ISDIGIT(n) || n == '_'); 271145510Sdarrenr yyunputc(n); 272145510Sdarrenr } 273145510Sdarrenr 274145510Sdarrenr name = yytexttostr(1, yypos); /* skip $ */ 275145510Sdarrenr 276145510Sdarrenr if (name != NULL) { 277145510Sdarrenr string_val = get_variable(name, NULL, yylineNum); 278145510Sdarrenr free(name); 279145510Sdarrenr if (string_val != NULL) { 280145510Sdarrenr name = yytexttostr(yypos, yylast); 281145510Sdarrenr if (name != NULL) { 282145510Sdarrenr yypos = 0; 283145510Sdarrenr yylast = 0; 284145510Sdarrenr yystrtotext(string_val); 285145510Sdarrenr yystrtotext(name); 286145510Sdarrenr free(string_val); 287145510Sdarrenr free(name); 288145510Sdarrenr goto nextchar; 289145510Sdarrenr } 290145510Sdarrenr free(string_val); 291145510Sdarrenr } 292145510Sdarrenr } 293145510Sdarrenr break; 294145510Sdarrenr 295145510Sdarrenr case '\'': 296145510Sdarrenr case '"' : 297145510Sdarrenr if (isbuilding == 1) { 298145510Sdarrenr goto done; 299145510Sdarrenr } 300145510Sdarrenr do { 301172776Sdarrenr n = yygetc(1); 302145510Sdarrenr if (n == EOF || n == TOOLONG) { 303145510Sdarrenr rval = -2; 304145510Sdarrenr goto done; 305145510Sdarrenr } 306145510Sdarrenr if (n == '\n') { 307145510Sdarrenr yyunputc(' '); 308145510Sdarrenr yypos++; 309145510Sdarrenr } 310145510Sdarrenr } while (n != c); 311170268Sdarrenr rval = YY_STR; 312170268Sdarrenr goto done; 313170268Sdarrenr /* NOTREACHED */ 314145510Sdarrenr 315145510Sdarrenr case EOF : 316145510Sdarrenr yylineNum = 1; 317145510Sdarrenr yypos = 0; 318145510Sdarrenr yylast = -1; 319145510Sdarrenr yyexpectaddr = 0; 320145510Sdarrenr yybreakondot = 0; 321145510Sdarrenr yyvarnext = 0; 322145510Sdarrenr yytokentype = 0; 323145510Sdarrenr return 0; 324145510Sdarrenr } 325145510Sdarrenr 326145510Sdarrenr if (strchr("=,/;{}()@", c) != NULL) { 327145510Sdarrenr if (isbuilding == 1) { 328145510Sdarrenr yyunputc(c); 329145510Sdarrenr goto done; 330145510Sdarrenr } 331145510Sdarrenr rval = c; 332145510Sdarrenr goto done; 333145510Sdarrenr } else if (c == '.') { 334145510Sdarrenr if (isbuilding == 0) { 335145510Sdarrenr rval = c; 336145510Sdarrenr goto done; 337145510Sdarrenr } 338145510Sdarrenr if (yybreakondot != 0) { 339145510Sdarrenr yyunputc(c); 340145510Sdarrenr goto done; 341145510Sdarrenr } 342145510Sdarrenr } 343145510Sdarrenr 344145510Sdarrenr switch (c) 345145510Sdarrenr { 346145510Sdarrenr case '-' : 347145510Sdarrenr if (yyexpectaddr) 348145510Sdarrenr break; 349145510Sdarrenr if (isbuilding == 1) 350145510Sdarrenr break; 351172776Sdarrenr n = yygetc(0); 352145510Sdarrenr if (n == '>') { 353145510Sdarrenr isbuilding = 1; 354145510Sdarrenr goto done; 355145510Sdarrenr } 356145510Sdarrenr yyunputc(n); 357145510Sdarrenr rval = '-'; 358145510Sdarrenr goto done; 359145510Sdarrenr 360145510Sdarrenr case '!' : 361145510Sdarrenr if (isbuilding == 1) { 362145510Sdarrenr yyunputc(c); 363145510Sdarrenr goto done; 364145510Sdarrenr } 365172776Sdarrenr n = yygetc(0); 366145510Sdarrenr if (n == '=') { 367145510Sdarrenr rval = YY_CMP_NE; 368145510Sdarrenr goto done; 369145510Sdarrenr } 370145510Sdarrenr yyunputc(n); 371145510Sdarrenr rval = '!'; 372145510Sdarrenr goto done; 373145510Sdarrenr 374145510Sdarrenr case '<' : 375145510Sdarrenr if (yyexpectaddr) 376145510Sdarrenr break; 377145510Sdarrenr if (isbuilding == 1) { 378145510Sdarrenr yyunputc(c); 379145510Sdarrenr goto done; 380145510Sdarrenr } 381172776Sdarrenr n = yygetc(0); 382145510Sdarrenr if (n == '=') { 383145510Sdarrenr rval = YY_CMP_LE; 384145510Sdarrenr goto done; 385145510Sdarrenr } 386145510Sdarrenr if (n == '>') { 387145510Sdarrenr rval = YY_RANGE_OUT; 388145510Sdarrenr goto done; 389145510Sdarrenr } 390145510Sdarrenr yyunputc(n); 391145510Sdarrenr rval = YY_CMP_LT; 392145510Sdarrenr goto done; 393145510Sdarrenr 394145510Sdarrenr case '>' : 395145510Sdarrenr if (yyexpectaddr) 396145510Sdarrenr break; 397145510Sdarrenr if (isbuilding == 1) { 398145510Sdarrenr yyunputc(c); 399145510Sdarrenr goto done; 400145510Sdarrenr } 401172776Sdarrenr n = yygetc(0); 402145510Sdarrenr if (n == '=') { 403145510Sdarrenr rval = YY_CMP_GE; 404145510Sdarrenr goto done; 405145510Sdarrenr } 406145510Sdarrenr if (n == '<') { 407145510Sdarrenr rval = YY_RANGE_IN; 408145510Sdarrenr goto done; 409145510Sdarrenr } 410145510Sdarrenr yyunputc(n); 411145510Sdarrenr rval = YY_CMP_GT; 412145510Sdarrenr goto done; 413145510Sdarrenr } 414145510Sdarrenr 415145510Sdarrenr /* 416145510Sdarrenr * Now for the reason this is here...IPv6 address parsing. 417145510Sdarrenr * The longest string we can expect is of this form: 418145510Sdarrenr * 0000:0000:0000:0000:0000:0000:000.000.000.000 419145510Sdarrenr * not: 420145510Sdarrenr * 0000:0000:0000:0000:0000:0000:0000:0000 421145510Sdarrenr */ 422145510Sdarrenr#ifdef USE_INET6 423145510Sdarrenr if (yyexpectaddr == 1 && isbuilding == 0 && (ishex(c) || c == ':')) { 424145510Sdarrenr char ipv6buf[45 + 1], *s, oc; 425145510Sdarrenr int start; 426145510Sdarrenr 427145510Sdarrenr start = yypos; 428145510Sdarrenr s = ipv6buf; 429145510Sdarrenr oc = c; 430145510Sdarrenr 431145510Sdarrenr /* 432145510Sdarrenr * Perhaps we should implement stricter controls on what we 433145510Sdarrenr * swallow up here, but surely it would just be duplicating 434145510Sdarrenr * the code in inet_pton() anyway. 435145510Sdarrenr */ 436145510Sdarrenr do { 437145510Sdarrenr *s++ = c; 438172776Sdarrenr c = yygetc(1); 439145510Sdarrenr } while ((ishex(c) || c == ':' || c == '.') && 440145510Sdarrenr (s - ipv6buf < 46)); 441145510Sdarrenr yyunputc(c); 442145510Sdarrenr *s = '\0'; 443145510Sdarrenr 444145510Sdarrenr if (inet_pton(AF_INET6, ipv6buf, &yylval.ip6) == 1) { 445145510Sdarrenr rval = YY_IPV6; 446145510Sdarrenr yyexpectaddr = 0; 447145510Sdarrenr goto done; 448145510Sdarrenr } 449145510Sdarrenr yypos = start; 450145510Sdarrenr c = oc; 451145510Sdarrenr } 452145510Sdarrenr#endif 453145510Sdarrenr 454145510Sdarrenr if (c == ':') { 455145510Sdarrenr if (isbuilding == 1) { 456145510Sdarrenr yyunputc(c); 457145510Sdarrenr goto done; 458145510Sdarrenr } 459145510Sdarrenr rval = ':'; 460145510Sdarrenr goto done; 461145510Sdarrenr } 462145510Sdarrenr 463145510Sdarrenr if (isbuilding == 0 && c == '0') { 464172776Sdarrenr n = yygetc(0); 465145510Sdarrenr if (n == 'x') { 466145510Sdarrenr do { 467172776Sdarrenr n = yygetc(1); 468145510Sdarrenr } while (ishex(n)); 469145510Sdarrenr yyunputc(n); 470145510Sdarrenr rval = YY_HEX; 471145510Sdarrenr goto done; 472145510Sdarrenr } 473145510Sdarrenr yyunputc(n); 474145510Sdarrenr } 475145510Sdarrenr 476145510Sdarrenr /* 477145510Sdarrenr * No negative numbers with leading - sign.. 478145510Sdarrenr */ 479145510Sdarrenr if (isbuilding == 0 && ISDIGIT(c)) { 480145510Sdarrenr do { 481172776Sdarrenr n = yygetc(1); 482145510Sdarrenr } while (ISDIGIT(n)); 483145510Sdarrenr yyunputc(n); 484145510Sdarrenr rval = YY_NUMBER; 485145510Sdarrenr goto done; 486145510Sdarrenr } 487145510Sdarrenr 488145510Sdarrenr isbuilding = 1; 489145510Sdarrenr goto nextchar; 490145510Sdarrenr 491145510Sdarrenrdone: 492145510Sdarrenr yystr = yytexttostr(0, yypos); 493145510Sdarrenr 494170268Sdarrenr if (yydebug) 495170268Sdarrenr printf("isbuilding %d yyvarnext %d nokey %d\n", 496170268Sdarrenr isbuilding, yyvarnext, nokey); 497145510Sdarrenr if (isbuilding == 1) { 498145510Sdarrenr wordtab_t *w; 499145510Sdarrenr 500145510Sdarrenr w = NULL; 501145510Sdarrenr isbuilding = 0; 502145510Sdarrenr 503145510Sdarrenr if ((yyvarnext == 0) && (nokey == 0)) { 504145510Sdarrenr w = yyfindkey(yystr); 505145510Sdarrenr if (w == NULL && yywordtab != NULL) { 506145510Sdarrenr yyresetdict(); 507145510Sdarrenr w = yyfindkey(yystr); 508145510Sdarrenr } 509145510Sdarrenr } else 510145510Sdarrenr yyvarnext = 0; 511145510Sdarrenr if (w != NULL) 512145510Sdarrenr rval = w->w_value; 513145510Sdarrenr else 514145510Sdarrenr rval = YY_STR; 515145510Sdarrenr } 516145510Sdarrenr 517145510Sdarrenr if (rval == YY_STR && yysavedepth > 0) 518145510Sdarrenr yyresetdict(); 519145510Sdarrenr 520145510Sdarrenr yytokentype = rval; 521145510Sdarrenr 522145510Sdarrenr if (yydebug) 523170268Sdarrenr printf("lexed(%s) [%d,%d,%d] => %d @%d\n", yystr, string_start, 524170268Sdarrenr string_end, pos, rval, yysavedepth); 525145510Sdarrenr 526145510Sdarrenr switch (rval) 527145510Sdarrenr { 528145510Sdarrenr case YY_NUMBER : 529145510Sdarrenr sscanf(yystr, "%u", &yylval.num); 530145510Sdarrenr break; 531145510Sdarrenr 532145510Sdarrenr case YY_HEX : 533145510Sdarrenr sscanf(yystr, "0x%x", (u_int *)&yylval.num); 534145510Sdarrenr break; 535145510Sdarrenr 536145510Sdarrenr case YY_STR : 537145510Sdarrenr yylval.str = strdup(yystr); 538145510Sdarrenr break; 539145510Sdarrenr 540145510Sdarrenr default : 541145510Sdarrenr break; 542145510Sdarrenr } 543145510Sdarrenr 544145510Sdarrenr if (yylast > 0) { 545145510Sdarrenr bcopy(yytext + yypos, yytext, 546145510Sdarrenr sizeof(yytext[0]) * (yylast - yypos + 1)); 547145510Sdarrenr yylast -= yypos; 548145510Sdarrenr yypos = 0; 549145510Sdarrenr } 550145510Sdarrenr 551145510Sdarrenr return rval; 552145510Sdarrenr} 553145510Sdarrenr 554145510Sdarrenr 555145510Sdarrenrstatic wordtab_t *yyfindkey(key) 556145510Sdarrenrchar *key; 557145510Sdarrenr{ 558145510Sdarrenr wordtab_t *w; 559145510Sdarrenr 560145510Sdarrenr if (yywordtab == NULL) 561145510Sdarrenr return NULL; 562145510Sdarrenr 563145510Sdarrenr for (w = yywordtab; w->w_word != 0; w++) 564145510Sdarrenr if (strcasecmp(key, w->w_word) == 0) 565145510Sdarrenr return w; 566145510Sdarrenr return NULL; 567145510Sdarrenr} 568145510Sdarrenr 569145510Sdarrenr 570145510Sdarrenrchar *yykeytostr(num) 571145510Sdarrenrint num; 572145510Sdarrenr{ 573145510Sdarrenr wordtab_t *w; 574145510Sdarrenr 575145510Sdarrenr if (yywordtab == NULL) 576145510Sdarrenr return "<unknown>"; 577145510Sdarrenr 578145510Sdarrenr for (w = yywordtab; w->w_word; w++) 579145510Sdarrenr if (w->w_value == num) 580145510Sdarrenr return w->w_word; 581145510Sdarrenr return "<unknown>"; 582145510Sdarrenr} 583145510Sdarrenr 584145510Sdarrenr 585145510Sdarrenrwordtab_t *yysettab(words) 586145510Sdarrenrwordtab_t *words; 587145510Sdarrenr{ 588145510Sdarrenr wordtab_t *save; 589145510Sdarrenr 590145510Sdarrenr save = yywordtab; 591145510Sdarrenr yywordtab = words; 592145510Sdarrenr return save; 593145510Sdarrenr} 594145510Sdarrenr 595145510Sdarrenr 596145510Sdarrenrvoid yyerror(msg) 597145510Sdarrenrchar *msg; 598145510Sdarrenr{ 599145510Sdarrenr char *txt, letter[2]; 600145510Sdarrenr int freetxt = 0; 601145510Sdarrenr 602145510Sdarrenr if (yytokentype < 256) { 603145510Sdarrenr letter[0] = yytokentype; 604145510Sdarrenr letter[1] = '\0'; 605145510Sdarrenr txt = letter; 606145510Sdarrenr } else if (yytokentype == YY_STR || yytokentype == YY_HEX || 607145510Sdarrenr yytokentype == YY_NUMBER) { 608145510Sdarrenr if (yystr == NULL) { 609145510Sdarrenr txt = yytexttostr(yypos, YYBUFSIZ); 610145510Sdarrenr freetxt = 1; 611145510Sdarrenr } else 612145510Sdarrenr txt = yystr; 613145510Sdarrenr } else { 614145510Sdarrenr txt = yykeytostr(yytokentype); 615145510Sdarrenr } 616145510Sdarrenr fprintf(stderr, "%s error at \"%s\", line %d\n", msg, txt, yylineNum); 617145510Sdarrenr if (freetxt == 1) 618145510Sdarrenr free(txt); 619145510Sdarrenr exit(1); 620145510Sdarrenr} 621145510Sdarrenr 622145510Sdarrenr 623145510Sdarrenrvoid yysetdict(newdict) 624145510Sdarrenrwordtab_t *newdict; 625145510Sdarrenr{ 626145510Sdarrenr if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { 627145510Sdarrenr fprintf(stderr, "%d: at maximum dictionary depth\n", 628145510Sdarrenr yylineNum); 629145510Sdarrenr return; 630145510Sdarrenr } 631145510Sdarrenr 632145510Sdarrenr yysavewords[yysavedepth++] = yysettab(newdict); 633145510Sdarrenr if (yydebug) 634145510Sdarrenr printf("yysavedepth++ => %d\n", yysavedepth); 635145510Sdarrenr} 636145510Sdarrenr 637145510Sdarrenrvoid yyresetdict() 638145510Sdarrenr{ 639170268Sdarrenr if (yydebug) 640170268Sdarrenr printf("yyresetdict(%d)\n", yysavedepth); 641145510Sdarrenr if (yysavedepth > 0) { 642145510Sdarrenr yysettab(yysavewords[--yysavedepth]); 643145510Sdarrenr if (yydebug) 644145510Sdarrenr printf("yysavedepth-- => %d\n", yysavedepth); 645145510Sdarrenr } 646145510Sdarrenr} 647145510Sdarrenr 648145510Sdarrenr 649145510Sdarrenr 650145510Sdarrenr#ifdef TEST_LEXER 651145510Sdarrenrint main(argc, argv) 652145510Sdarrenrint argc; 653145510Sdarrenrchar *argv[]; 654145510Sdarrenr{ 655145510Sdarrenr int n; 656145510Sdarrenr 657145510Sdarrenr yyin = stdin; 658145510Sdarrenr 659145510Sdarrenr while ((n = yylex()) != 0) 660145510Sdarrenr printf("%d.n = %d [%s] %d %d\n", 661145510Sdarrenr yylineNum, n, yystr, yypos, yylast); 662145510Sdarrenr} 663145510Sdarrenr#endif 664