1145519Sdarrenr/* $FreeBSD: stable/11/contrib/ipfilter/tools/lexer.c 369245 2021-02-09 13:47:46Z git2svn $ */ 2145510Sdarrenr 3145510Sdarrenr/* 4255332Scy * Copyright (C) 2012 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; 45255332Scyint yydictfixed = 0; 46145510Sdarrenrint yyexpectaddr = 0; 47145510Sdarrenrint yybreakondot = 0; 48145510Sdarrenrint yyvarnext = 0; 49145510Sdarrenrint yytokentype = 0; 50145510Sdarrenrwordtab_t *yywordtab = NULL; 51145510Sdarrenrint yysavedepth = 0; 52145510Sdarrenrwordtab_t *yysavewords[30]; 53145510Sdarrenr 54145510Sdarrenr 55369245Sgit2svnstatic wordtab_t *yyfindkey(char *); 56369245Sgit2svnstatic int yygetc(int); 57369245Sgit2svnstatic void yyunputc(int); 58369245Sgit2svnstatic int yyswallow(int); 59369245Sgit2svnstatic char *yytexttostr(int, int); 60369245Sgit2svnstatic void yystrtotext(char *); 61369245Sgit2svnstatic char *yytexttochar(void); 62145510Sdarrenr 63172776Sdarrenrstatic int yygetc(docont) 64255332Scy int docont; 65145510Sdarrenr{ 66145510Sdarrenr int c; 67145510Sdarrenr 68145510Sdarrenr if (yypos < yylast) { 69145510Sdarrenr c = yytext[yypos++]; 70145510Sdarrenr if (c == '\n') 71145510Sdarrenr yylineNum++; 72145510Sdarrenr return c; 73145510Sdarrenr } 74145510Sdarrenr 75145510Sdarrenr if (yypos == YYBUFSIZ) 76145510Sdarrenr return TOOLONG; 77145510Sdarrenr 78145510Sdarrenr if (pos >= string_start && pos <= string_end) { 79145510Sdarrenr c = string_val[pos - string_start]; 80145510Sdarrenr yypos++; 81145510Sdarrenr } else { 82145510Sdarrenr c = fgetc(yyin); 83172776Sdarrenr if (docont && (c == '\\')) { 84172776Sdarrenr c = fgetc(yyin); 85172776Sdarrenr if (c == '\n') { 86172776Sdarrenr yylineNum++; 87172776Sdarrenr c = fgetc(yyin); 88172776Sdarrenr } 89172776Sdarrenr } 90145510Sdarrenr } 91145510Sdarrenr if (c == '\n') 92145510Sdarrenr yylineNum++; 93145510Sdarrenr yytext[yypos++] = c; 94145510Sdarrenr yylast = yypos; 95145510Sdarrenr yytext[yypos] = '\0'; 96145510Sdarrenr 97145510Sdarrenr return c; 98145510Sdarrenr} 99145510Sdarrenr 100145510Sdarrenr 101145510Sdarrenrstatic void yyunputc(c) 102255332Scy int c; 103145510Sdarrenr{ 104145510Sdarrenr if (c == '\n') 105145510Sdarrenr yylineNum--; 106145510Sdarrenr yytext[--yypos] = c; 107145510Sdarrenr} 108145510Sdarrenr 109145510Sdarrenr 110145510Sdarrenrstatic int yyswallow(last) 111255332Scy int last; 112145510Sdarrenr{ 113145510Sdarrenr int c; 114145510Sdarrenr 115172776Sdarrenr while (((c = yygetc(0)) > '\0') && (c != last)) 116145510Sdarrenr ; 117145510Sdarrenr 118145510Sdarrenr if (c != EOF) 119145510Sdarrenr yyunputc(c); 120145510Sdarrenr if (c == last) 121145510Sdarrenr return 0; 122145510Sdarrenr return -1; 123145510Sdarrenr} 124145510Sdarrenr 125145510Sdarrenr 126172776Sdarrenrstatic char *yytexttochar() 127172776Sdarrenr{ 128172776Sdarrenr int i; 129172776Sdarrenr 130172776Sdarrenr for (i = 0; i < yypos; i++) 131172776Sdarrenr yychars[i] = (char)(yytext[i] & 0xff); 132172776Sdarrenr yychars[i] = '\0'; 133172776Sdarrenr return yychars; 134172776Sdarrenr} 135172776Sdarrenr 136172776Sdarrenr 137145510Sdarrenrstatic void yystrtotext(str) 138255332Scy char *str; 139145510Sdarrenr{ 140145510Sdarrenr int len; 141145510Sdarrenr char *s; 142145510Sdarrenr 143145510Sdarrenr len = strlen(str); 144145510Sdarrenr if (len > YYBUFSIZ) 145145510Sdarrenr len = YYBUFSIZ; 146145510Sdarrenr 147145510Sdarrenr for (s = str; *s != '\0' && len > 0; s++, len--) 148145510Sdarrenr yytext[yylast++] = *s; 149145510Sdarrenr yytext[yylast] = '\0'; 150145510Sdarrenr} 151145510Sdarrenr 152145510Sdarrenr 153145510Sdarrenrstatic char *yytexttostr(offset, max) 154255332Scy int offset, max; 155145510Sdarrenr{ 156145510Sdarrenr char *str; 157145510Sdarrenr int i; 158145510Sdarrenr 159145510Sdarrenr if ((yytext[offset] == '\'' || yytext[offset] == '"') && 160145510Sdarrenr (yytext[offset] == yytext[offset + max - 1])) { 161145510Sdarrenr offset++; 162145510Sdarrenr max--; 163145510Sdarrenr } 164145510Sdarrenr 165145510Sdarrenr if (max > yylast) 166145510Sdarrenr max = yylast; 167145510Sdarrenr str = malloc(max + 1); 168145510Sdarrenr if (str != NULL) { 169145510Sdarrenr for (i = offset; i < max; i++) 170145510Sdarrenr str[i - offset] = (char)(yytext[i] & 0xff); 171145510Sdarrenr str[i - offset] = '\0'; 172145510Sdarrenr } 173145510Sdarrenr return str; 174145510Sdarrenr} 175145510Sdarrenr 176145510Sdarrenr 177145510Sdarrenrint yylex() 178145510Sdarrenr{ 179255332Scy static int prior = 0; 180255332Scy static int priornum = 0; 181145510Sdarrenr int c, n, isbuilding, rval, lnext, nokey = 0; 182145510Sdarrenr char *name; 183255332Scy int triedv6 = 0; 184145510Sdarrenr 185145510Sdarrenr isbuilding = 0; 186145510Sdarrenr lnext = 0; 187145510Sdarrenr rval = 0; 188145510Sdarrenr 189145510Sdarrenr if (yystr != NULL) { 190145510Sdarrenr free(yystr); 191145510Sdarrenr yystr = NULL; 192145510Sdarrenr } 193145510Sdarrenr 194145510Sdarrenrnextchar: 195172776Sdarrenr c = yygetc(0); 196172776Sdarrenr if (yydebug > 1) 197255332Scy printf("yygetc = (%x) %c [%*.*s]\n", 198255332Scy c, c, yypos, yypos, yytexttochar()); 199145510Sdarrenr 200145510Sdarrenr switch (c) 201145510Sdarrenr { 202145510Sdarrenr case '\n' : 203161357Sguido lnext = 0; 204161357Sguido nokey = 0; 205145510Sdarrenr case '\t' : 206145510Sdarrenr case '\r' : 207145510Sdarrenr case ' ' : 208145510Sdarrenr if (isbuilding == 1) { 209145510Sdarrenr yyunputc(c); 210145510Sdarrenr goto done; 211145510Sdarrenr } 212145510Sdarrenr if (yylast > yypos) { 213145510Sdarrenr bcopy(yytext + yypos, yytext, 214145510Sdarrenr sizeof(yytext[0]) * (yylast - yypos + 1)); 215145510Sdarrenr } 216145510Sdarrenr yylast -= yypos; 217255332Scy if (yyexpectaddr == 2) 218255332Scy yyexpectaddr = 0; 219145510Sdarrenr yypos = 0; 220145510Sdarrenr lnext = 0; 221145510Sdarrenr nokey = 0; 222145510Sdarrenr goto nextchar; 223145510Sdarrenr 224145510Sdarrenr case '\\' : 225145510Sdarrenr if (lnext == 0) { 226145510Sdarrenr lnext = 1; 227145510Sdarrenr if (yylast == yypos) { 228145510Sdarrenr yylast--; 229145510Sdarrenr yypos--; 230145510Sdarrenr } else 231145510Sdarrenr yypos--; 232145510Sdarrenr if (yypos == 0) 233145510Sdarrenr nokey = 1; 234145510Sdarrenr goto nextchar; 235145510Sdarrenr } 236145510Sdarrenr break; 237145510Sdarrenr } 238145510Sdarrenr 239145510Sdarrenr if (lnext == 1) { 240145510Sdarrenr lnext = 0; 241145510Sdarrenr if ((isbuilding == 0) && !ISALNUM(c)) { 242255332Scy prior = c; 243145510Sdarrenr return c; 244145510Sdarrenr } 245145510Sdarrenr goto nextchar; 246145510Sdarrenr } 247145510Sdarrenr 248145510Sdarrenr switch (c) 249145510Sdarrenr { 250145510Sdarrenr case '#' : 251145510Sdarrenr if (isbuilding == 1) { 252145510Sdarrenr yyunputc(c); 253145510Sdarrenr goto done; 254145510Sdarrenr } 255145510Sdarrenr yyswallow('\n'); 256145510Sdarrenr rval = YY_COMMENT; 257255332Scy goto done; 258145510Sdarrenr 259145510Sdarrenr case '$' : 260145510Sdarrenr if (isbuilding == 1) { 261145510Sdarrenr yyunputc(c); 262145510Sdarrenr goto done; 263145510Sdarrenr } 264172776Sdarrenr n = yygetc(0); 265145510Sdarrenr if (n == '{') { 266145510Sdarrenr if (yyswallow('}') == -1) { 267145510Sdarrenr rval = -2; 268145510Sdarrenr goto done; 269145510Sdarrenr } 270172776Sdarrenr (void) yygetc(0); 271145510Sdarrenr } else { 272145510Sdarrenr if (!ISALPHA(n)) { 273145510Sdarrenr yyunputc(n); 274145510Sdarrenr break; 275145510Sdarrenr } 276145510Sdarrenr do { 277172776Sdarrenr n = yygetc(1); 278145510Sdarrenr } while (ISALPHA(n) || ISDIGIT(n) || n == '_'); 279145510Sdarrenr yyunputc(n); 280145510Sdarrenr } 281145510Sdarrenr 282145510Sdarrenr name = yytexttostr(1, yypos); /* skip $ */ 283145510Sdarrenr 284145510Sdarrenr if (name != NULL) { 285145510Sdarrenr string_val = get_variable(name, NULL, yylineNum); 286145510Sdarrenr free(name); 287145510Sdarrenr if (string_val != NULL) { 288145510Sdarrenr name = yytexttostr(yypos, yylast); 289145510Sdarrenr if (name != NULL) { 290145510Sdarrenr yypos = 0; 291145510Sdarrenr yylast = 0; 292145510Sdarrenr yystrtotext(string_val); 293145510Sdarrenr yystrtotext(name); 294145510Sdarrenr free(string_val); 295145510Sdarrenr free(name); 296145510Sdarrenr goto nextchar; 297145510Sdarrenr } 298145510Sdarrenr free(string_val); 299145510Sdarrenr } 300145510Sdarrenr } 301145510Sdarrenr break; 302145510Sdarrenr 303145510Sdarrenr case '\'': 304145510Sdarrenr case '"' : 305145510Sdarrenr if (isbuilding == 1) { 306145510Sdarrenr goto done; 307145510Sdarrenr } 308145510Sdarrenr do { 309172776Sdarrenr n = yygetc(1); 310145510Sdarrenr if (n == EOF || n == TOOLONG) { 311145510Sdarrenr rval = -2; 312145510Sdarrenr goto done; 313145510Sdarrenr } 314145510Sdarrenr if (n == '\n') { 315145510Sdarrenr yyunputc(' '); 316145510Sdarrenr yypos++; 317145510Sdarrenr } 318145510Sdarrenr } while (n != c); 319170268Sdarrenr rval = YY_STR; 320170268Sdarrenr goto done; 321170268Sdarrenr /* NOTREACHED */ 322145510Sdarrenr 323145510Sdarrenr case EOF : 324145510Sdarrenr yylineNum = 1; 325145510Sdarrenr yypos = 0; 326145510Sdarrenr yylast = -1; 327145510Sdarrenr yyexpectaddr = 0; 328145510Sdarrenr yybreakondot = 0; 329145510Sdarrenr yyvarnext = 0; 330145510Sdarrenr yytokentype = 0; 331255332Scy if (yydebug) 332255332Scy fprintf(stderr, "reset at EOF\n"); 333255332Scy prior = 0; 334145510Sdarrenr return 0; 335145510Sdarrenr } 336145510Sdarrenr 337145510Sdarrenr if (strchr("=,/;{}()@", c) != NULL) { 338145510Sdarrenr if (isbuilding == 1) { 339145510Sdarrenr yyunputc(c); 340145510Sdarrenr goto done; 341145510Sdarrenr } 342145510Sdarrenr rval = c; 343145510Sdarrenr goto done; 344145510Sdarrenr } else if (c == '.') { 345145510Sdarrenr if (isbuilding == 0) { 346145510Sdarrenr rval = c; 347145510Sdarrenr goto done; 348145510Sdarrenr } 349145510Sdarrenr if (yybreakondot != 0) { 350145510Sdarrenr yyunputc(c); 351145510Sdarrenr goto done; 352145510Sdarrenr } 353145510Sdarrenr } 354145510Sdarrenr 355145510Sdarrenr switch (c) 356145510Sdarrenr { 357145510Sdarrenr case '-' : 358172776Sdarrenr n = yygetc(0); 359145510Sdarrenr if (n == '>') { 360145510Sdarrenr isbuilding = 1; 361145510Sdarrenr goto done; 362145510Sdarrenr } 363145510Sdarrenr yyunputc(n); 364255332Scy if (yyexpectaddr) { 365255332Scy if (isbuilding == 1) 366255332Scy yyunputc(c); 367255332Scy else 368255332Scy rval = '-'; 369255332Scy goto done; 370255332Scy } 371255332Scy if (isbuilding == 1) 372255332Scy break; 373145510Sdarrenr rval = '-'; 374145510Sdarrenr goto done; 375145510Sdarrenr 376145510Sdarrenr case '!' : 377145510Sdarrenr if (isbuilding == 1) { 378145510Sdarrenr yyunputc(c); 379145510Sdarrenr goto done; 380145510Sdarrenr } 381172776Sdarrenr n = yygetc(0); 382145510Sdarrenr if (n == '=') { 383145510Sdarrenr rval = YY_CMP_NE; 384145510Sdarrenr goto done; 385145510Sdarrenr } 386145510Sdarrenr yyunputc(n); 387145510Sdarrenr rval = '!'; 388145510Sdarrenr goto done; 389145510Sdarrenr 390145510Sdarrenr case '<' : 391145510Sdarrenr if (yyexpectaddr) 392145510Sdarrenr break; 393145510Sdarrenr if (isbuilding == 1) { 394145510Sdarrenr yyunputc(c); 395145510Sdarrenr goto done; 396145510Sdarrenr } 397172776Sdarrenr n = yygetc(0); 398145510Sdarrenr if (n == '=') { 399145510Sdarrenr rval = YY_CMP_LE; 400145510Sdarrenr goto done; 401145510Sdarrenr } 402145510Sdarrenr if (n == '>') { 403145510Sdarrenr rval = YY_RANGE_OUT; 404145510Sdarrenr goto done; 405145510Sdarrenr } 406145510Sdarrenr yyunputc(n); 407145510Sdarrenr rval = YY_CMP_LT; 408145510Sdarrenr goto done; 409145510Sdarrenr 410145510Sdarrenr case '>' : 411145510Sdarrenr if (yyexpectaddr) 412145510Sdarrenr break; 413145510Sdarrenr if (isbuilding == 1) { 414145510Sdarrenr yyunputc(c); 415145510Sdarrenr goto done; 416145510Sdarrenr } 417172776Sdarrenr n = yygetc(0); 418145510Sdarrenr if (n == '=') { 419145510Sdarrenr rval = YY_CMP_GE; 420145510Sdarrenr goto done; 421145510Sdarrenr } 422145510Sdarrenr if (n == '<') { 423145510Sdarrenr rval = YY_RANGE_IN; 424145510Sdarrenr goto done; 425145510Sdarrenr } 426145510Sdarrenr yyunputc(n); 427145510Sdarrenr rval = YY_CMP_GT; 428145510Sdarrenr goto done; 429145510Sdarrenr } 430145510Sdarrenr 431145510Sdarrenr /* 432145510Sdarrenr * Now for the reason this is here...IPv6 address parsing. 433145510Sdarrenr * The longest string we can expect is of this form: 434145510Sdarrenr * 0000:0000:0000:0000:0000:0000:000.000.000.000 435145510Sdarrenr * not: 436145510Sdarrenr * 0000:0000:0000:0000:0000:0000:0000:0000 437145510Sdarrenr */ 438145510Sdarrenr#ifdef USE_INET6 439255332Scy if (yyexpectaddr != 0 && isbuilding == 0 && 440255332Scy (ishex(c) || isdigit(c) || c == ':')) { 441145510Sdarrenr char ipv6buf[45 + 1], *s, oc; 442145510Sdarrenr int start; 443145510Sdarrenr 444255332Scybuildipv6: 445145510Sdarrenr start = yypos; 446145510Sdarrenr s = ipv6buf; 447145510Sdarrenr oc = c; 448145510Sdarrenr 449255332Scy if (prior == YY_NUMBER && c == ':') { 450255332Scy sprintf(s, "%d", priornum); 451255332Scy s += strlen(s); 452255332Scy } 453255332Scy 454145510Sdarrenr /* 455145510Sdarrenr * Perhaps we should implement stricter controls on what we 456145510Sdarrenr * swallow up here, but surely it would just be duplicating 457145510Sdarrenr * the code in inet_pton() anyway. 458145510Sdarrenr */ 459145510Sdarrenr do { 460145510Sdarrenr *s++ = c; 461172776Sdarrenr c = yygetc(1); 462145510Sdarrenr } while ((ishex(c) || c == ':' || c == '.') && 463145510Sdarrenr (s - ipv6buf < 46)); 464145510Sdarrenr yyunputc(c); 465145510Sdarrenr *s = '\0'; 466145510Sdarrenr 467145510Sdarrenr if (inet_pton(AF_INET6, ipv6buf, &yylval.ip6) == 1) { 468145510Sdarrenr rval = YY_IPV6; 469145510Sdarrenr yyexpectaddr = 0; 470145510Sdarrenr goto done; 471145510Sdarrenr } 472145510Sdarrenr yypos = start; 473145510Sdarrenr c = oc; 474145510Sdarrenr } 475145510Sdarrenr#endif 476145510Sdarrenr 477255332Scy if ((c == ':') && (rval != YY_IPV6) && (triedv6 == 0)) { 478255332Scy#ifdef USE_INET6 479255332Scy yystr = yytexttostr(0, yypos - 1); 480255332Scy if (yystr != NULL) { 481255332Scy char *s; 482255332Scy 483255332Scy for (s = yystr; *s && ishex(*s); s++) 484255332Scy ; 485255332Scy if (!*s && *yystr) { 486255332Scy isbuilding = 0; 487255332Scy c = *yystr; 488255332Scy free(yystr); 489255332Scy triedv6 = 1; 490255332Scy yypos = 1; 491255332Scy goto buildipv6; 492255332Scy } 493255332Scy free(yystr); 494255332Scy } 495255332Scy#endif 496145510Sdarrenr if (isbuilding == 1) { 497145510Sdarrenr yyunputc(c); 498145510Sdarrenr goto done; 499145510Sdarrenr } 500145510Sdarrenr rval = ':'; 501145510Sdarrenr goto done; 502145510Sdarrenr } 503145510Sdarrenr 504145510Sdarrenr if (isbuilding == 0 && c == '0') { 505172776Sdarrenr n = yygetc(0); 506145510Sdarrenr if (n == 'x') { 507145510Sdarrenr do { 508172776Sdarrenr n = yygetc(1); 509145510Sdarrenr } while (ishex(n)); 510145510Sdarrenr yyunputc(n); 511145510Sdarrenr rval = YY_HEX; 512145510Sdarrenr goto done; 513145510Sdarrenr } 514145510Sdarrenr yyunputc(n); 515145510Sdarrenr } 516145510Sdarrenr 517145510Sdarrenr /* 518145510Sdarrenr * No negative numbers with leading - sign.. 519145510Sdarrenr */ 520145510Sdarrenr if (isbuilding == 0 && ISDIGIT(c)) { 521145510Sdarrenr do { 522172776Sdarrenr n = yygetc(1); 523145510Sdarrenr } while (ISDIGIT(n)); 524145510Sdarrenr yyunputc(n); 525145510Sdarrenr rval = YY_NUMBER; 526145510Sdarrenr goto done; 527145510Sdarrenr } 528145510Sdarrenr 529145510Sdarrenr isbuilding = 1; 530145510Sdarrenr goto nextchar; 531145510Sdarrenr 532145510Sdarrenrdone: 533145510Sdarrenr yystr = yytexttostr(0, yypos); 534145510Sdarrenr 535170268Sdarrenr if (yydebug) 536255332Scy printf("isbuilding %d yyvarnext %d nokey %d fixed %d addr %d\n", 537255332Scy isbuilding, yyvarnext, nokey, yydictfixed, yyexpectaddr); 538145510Sdarrenr if (isbuilding == 1) { 539145510Sdarrenr wordtab_t *w; 540145510Sdarrenr 541145510Sdarrenr w = NULL; 542145510Sdarrenr isbuilding = 0; 543145510Sdarrenr 544145510Sdarrenr if ((yyvarnext == 0) && (nokey == 0)) { 545145510Sdarrenr w = yyfindkey(yystr); 546255332Scy if (w == NULL && yywordtab != NULL && !yydictfixed) { 547145510Sdarrenr yyresetdict(); 548145510Sdarrenr w = yyfindkey(yystr); 549145510Sdarrenr } 550145510Sdarrenr } else 551145510Sdarrenr yyvarnext = 0; 552145510Sdarrenr if (w != NULL) 553145510Sdarrenr rval = w->w_value; 554145510Sdarrenr else 555145510Sdarrenr rval = YY_STR; 556145510Sdarrenr } 557145510Sdarrenr 558255332Scy if (rval == YY_STR) { 559255332Scy if (yysavedepth > 0 && !yydictfixed) 560255332Scy yyresetdict(); 561255332Scy if (yyexpectaddr != 0) 562255332Scy yyexpectaddr = 0; 563255332Scy } 564145510Sdarrenr 565145510Sdarrenr yytokentype = rval; 566145510Sdarrenr 567145510Sdarrenr if (yydebug) 568255332Scy printf("lexed(%s) %d,%d,%d [%d,%d,%d] => %d @%d\n", 569255332Scy yystr, isbuilding, yyexpectaddr, yysavedepth, 570255332Scy string_start, string_end, pos, rval, yysavedepth); 571145510Sdarrenr 572145510Sdarrenr switch (rval) 573145510Sdarrenr { 574145510Sdarrenr case YY_NUMBER : 575145510Sdarrenr sscanf(yystr, "%u", &yylval.num); 576145510Sdarrenr break; 577145510Sdarrenr 578145510Sdarrenr case YY_HEX : 579145510Sdarrenr sscanf(yystr, "0x%x", (u_int *)&yylval.num); 580145510Sdarrenr break; 581145510Sdarrenr 582145510Sdarrenr case YY_STR : 583145510Sdarrenr yylval.str = strdup(yystr); 584145510Sdarrenr break; 585145510Sdarrenr 586145510Sdarrenr default : 587145510Sdarrenr break; 588145510Sdarrenr } 589145510Sdarrenr 590145510Sdarrenr if (yylast > 0) { 591145510Sdarrenr bcopy(yytext + yypos, yytext, 592145510Sdarrenr sizeof(yytext[0]) * (yylast - yypos + 1)); 593145510Sdarrenr yylast -= yypos; 594145510Sdarrenr yypos = 0; 595145510Sdarrenr } 596145510Sdarrenr 597255332Scy if (rval == YY_NUMBER) 598255332Scy priornum = yylval.num; 599255332Scy prior = rval; 600145510Sdarrenr return rval; 601145510Sdarrenr} 602145510Sdarrenr 603145510Sdarrenr 604145510Sdarrenrstatic wordtab_t *yyfindkey(key) 605255332Scy char *key; 606145510Sdarrenr{ 607145510Sdarrenr wordtab_t *w; 608145510Sdarrenr 609145510Sdarrenr if (yywordtab == NULL) 610145510Sdarrenr return NULL; 611145510Sdarrenr 612145510Sdarrenr for (w = yywordtab; w->w_word != 0; w++) 613145510Sdarrenr if (strcasecmp(key, w->w_word) == 0) 614145510Sdarrenr return w; 615145510Sdarrenr return NULL; 616145510Sdarrenr} 617145510Sdarrenr 618145510Sdarrenr 619145510Sdarrenrchar *yykeytostr(num) 620255332Scy int num; 621145510Sdarrenr{ 622145510Sdarrenr wordtab_t *w; 623145510Sdarrenr 624145510Sdarrenr if (yywordtab == NULL) 625145510Sdarrenr return "<unknown>"; 626145510Sdarrenr 627145510Sdarrenr for (w = yywordtab; w->w_word; w++) 628145510Sdarrenr if (w->w_value == num) 629145510Sdarrenr return w->w_word; 630145510Sdarrenr return "<unknown>"; 631145510Sdarrenr} 632145510Sdarrenr 633145510Sdarrenr 634145510Sdarrenrwordtab_t *yysettab(words) 635255332Scy wordtab_t *words; 636145510Sdarrenr{ 637145510Sdarrenr wordtab_t *save; 638145510Sdarrenr 639145510Sdarrenr save = yywordtab; 640145510Sdarrenr yywordtab = words; 641145510Sdarrenr return save; 642145510Sdarrenr} 643145510Sdarrenr 644145510Sdarrenr 645145510Sdarrenrvoid yyerror(msg) 646255332Scy char *msg; 647145510Sdarrenr{ 648145510Sdarrenr char *txt, letter[2]; 649145510Sdarrenr int freetxt = 0; 650145510Sdarrenr 651145510Sdarrenr if (yytokentype < 256) { 652145510Sdarrenr letter[0] = yytokentype; 653145510Sdarrenr letter[1] = '\0'; 654145510Sdarrenr txt = letter; 655145510Sdarrenr } else if (yytokentype == YY_STR || yytokentype == YY_HEX || 656145510Sdarrenr yytokentype == YY_NUMBER) { 657145510Sdarrenr if (yystr == NULL) { 658145510Sdarrenr txt = yytexttostr(yypos, YYBUFSIZ); 659145510Sdarrenr freetxt = 1; 660145510Sdarrenr } else 661145510Sdarrenr txt = yystr; 662145510Sdarrenr } else { 663145510Sdarrenr txt = yykeytostr(yytokentype); 664145510Sdarrenr } 665145510Sdarrenr fprintf(stderr, "%s error at \"%s\", line %d\n", msg, txt, yylineNum); 666145510Sdarrenr if (freetxt == 1) 667145510Sdarrenr free(txt); 668145510Sdarrenr exit(1); 669145510Sdarrenr} 670145510Sdarrenr 671145510Sdarrenr 672255332Scyvoid yysetfixeddict(newdict) 673255332Scy wordtab_t *newdict; 674255332Scy{ 675255332Scy if (yydebug) 676255332Scy printf("yysetfixeddict(%lx)\n", (u_long)newdict); 677255332Scy 678255332Scy if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { 679255332Scy fprintf(stderr, "%d: at maximum dictionary depth\n", 680255332Scy yylineNum); 681255332Scy return; 682255332Scy } 683255332Scy 684255332Scy yysavewords[yysavedepth++] = yysettab(newdict); 685255332Scy if (yydebug) 686255332Scy printf("yysavedepth++ => %d\n", yysavedepth); 687255332Scy yydictfixed = 1; 688255332Scy} 689255332Scy 690255332Scy 691145510Sdarrenrvoid yysetdict(newdict) 692255332Scy wordtab_t *newdict; 693145510Sdarrenr{ 694255332Scy if (yydebug) 695255332Scy printf("yysetdict(%lx)\n", (u_long)newdict); 696255332Scy 697145510Sdarrenr if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { 698145510Sdarrenr fprintf(stderr, "%d: at maximum dictionary depth\n", 699145510Sdarrenr yylineNum); 700145510Sdarrenr return; 701145510Sdarrenr } 702145510Sdarrenr 703145510Sdarrenr yysavewords[yysavedepth++] = yysettab(newdict); 704145510Sdarrenr if (yydebug) 705145510Sdarrenr printf("yysavedepth++ => %d\n", yysavedepth); 706145510Sdarrenr} 707145510Sdarrenr 708145510Sdarrenrvoid yyresetdict() 709145510Sdarrenr{ 710170268Sdarrenr if (yydebug) 711170268Sdarrenr printf("yyresetdict(%d)\n", yysavedepth); 712145510Sdarrenr if (yysavedepth > 0) { 713145510Sdarrenr yysettab(yysavewords[--yysavedepth]); 714145510Sdarrenr if (yydebug) 715145510Sdarrenr printf("yysavedepth-- => %d\n", yysavedepth); 716145510Sdarrenr } 717255332Scy yydictfixed = 0; 718145510Sdarrenr} 719145510Sdarrenr 720145510Sdarrenr 721145510Sdarrenr 722145510Sdarrenr#ifdef TEST_LEXER 723145510Sdarrenrint main(argc, argv) 724255332Scy int argc; 725255332Scy char *argv[]; 726145510Sdarrenr{ 727145510Sdarrenr int n; 728145510Sdarrenr 729145510Sdarrenr yyin = stdin; 730145510Sdarrenr 731145510Sdarrenr while ((n = yylex()) != 0) 732145510Sdarrenr printf("%d.n = %d [%s] %d %d\n", 733145510Sdarrenr yylineNum, n, yystr, yypos, yylast); 734145510Sdarrenr} 735145510Sdarrenr#endif 736