| 1 | %{ |
| 2 | /* |
| 3 | * Copyright (c) 1989 Jan-Simon Pendry |
| 4 | * Copyright (c) 1989 Imperial College of Science, Technology & Medicine |
| 5 | * Copyright (c) 1989 The Regents of the University of California. |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * This code is derived from software contributed to Berkeley by |
| 9 | * Jan-Simon Pendry at Imperial College, London. |
| 10 | * |
| 11 | * %sccs.include.redist.c% |
| 12 | * |
| 13 | * @(#)fsi_lex.l 5.3 (Berkeley) %G% |
| 14 | * |
| 15 | * $Id: fsi_lex.l,v 5.2.1.3 91/05/07 22:19:03 jsp Alpha $ |
| 16 | * |
| 17 | */ |
| 18 | |
| 19 | /* |
| 20 | * Lexical analyzer for fsinfo. |
| 21 | * TODO: Needs rewriting. |
| 22 | */ |
| 23 | |
| 24 | static int xinput(); |
| 25 | static void xunput(); |
| 26 | |
| 27 | #ifdef FLEX_SCANNER |
| 28 | static int yylineno; |
| 29 | /* Flex support with help from Vern Paxson <vern@helios.ee.lbl.gov> */ |
| 30 | #undef YY_INPUT |
| 31 | #define YY_INPUT(buf,result,max_size) \ |
| 32 | { \ |
| 33 | int i; \ |
| 34 | for (i = 0; i < max_size; i++) { \ |
| 35 | int ch = xinput(i == 0); \ |
| 36 | if (ch == 0) \ |
| 37 | break; \ |
| 38 | buf[i] = ch; \ |
| 39 | } \ |
| 40 | result = i; \ |
| 41 | } |
| 42 | |
| 43 | #define INIT_STATE { \ |
| 44 | switch ((yy_start - 1) / 2) { \ |
| 45 | case 0: \ |
| 46 | BEGIN F; \ |
| 47 | break; \ |
| 48 | } \ |
| 49 | } |
| 50 | |
| 51 | |
| 52 | #else |
| 53 | /* |
| 54 | * Using old lex... |
| 55 | */ |
| 56 | #undef unput |
| 57 | #define unput(ch) xunput(ch) |
| 58 | #undef input |
| 59 | #define input() xinput(1) |
| 60 | |
| 61 | #define INIT_STATE { \ |
| 62 | switch (yybgin - yysvec - 1) { \ |
| 63 | case 0: \ |
| 64 | BEGIN F; \ |
| 65 | break; \ |
| 66 | } \ |
| 67 | } |
| 68 | |
| 69 | #endif /* FLEX_SCANNER */ |
| 70 | |
| 71 | #include "../fsinfo/fsinfo.h" |
| 72 | #include "fsi_gram.h" |
| 73 | #include <ctype.h> |
| 74 | |
| 75 | static char *filename; |
| 76 | static char *optr; |
| 77 | static char ostr[1024]; |
| 78 | static find_resword(); |
| 79 | static unsigned char ibuf[64]; |
| 80 | static unsigned char *iptr = ibuf; |
| 81 | static int quoted; |
| 82 | static int lastch, nextch = '\n'; |
| 83 | YYSTYPE yylval; |
| 84 | |
| 85 | struct r { |
| 86 | char *rw; |
| 87 | int tok; |
| 88 | } rr[] = { |
| 89 | { "->", tEQ }, |
| 90 | { "arch", tARCH }, |
| 91 | { "as", tAS }, |
| 92 | { "automount", tAUTOMOUNT }, |
| 93 | { "cluster", tCLUSTER }, |
| 94 | { "config", tCONFIG }, |
| 95 | { "dumpset", tDUMPSET }, |
| 96 | { "exportfs", tEXPORTFS }, |
| 97 | { "freq", tFREQ }, |
| 98 | { "from", tFROM }, |
| 99 | { "fs", tFS }, |
| 100 | { "fstype", tFSTYPE }, |
| 101 | { "host", tHOST }, |
| 102 | { "hwaddr", tHWADDR }, |
| 103 | { "inaddr", tINADDR }, |
| 104 | { "localhost", tLOCALHOST }, |
| 105 | { "log", tLOG }, |
| 106 | { "mount", tMOUNT }, |
| 107 | { "netif", tNETIF }, |
| 108 | { "netmask", tNETMASK }, |
| 109 | { "opts", tOPTS }, |
| 110 | { "os", tOS }, |
| 111 | { "passno", tPASSNO }, |
| 112 | { "sel", tSEL }, |
| 113 | { "volname", tVOLNAME }, |
| 114 | { 0, 0 }, |
| 115 | }; |
| 116 | #define NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1) |
| 117 | |
| 118 | %} |
| 119 | |
| 120 | %start F Q |
| 121 | |
| 122 | %% |
| 123 | INIT_STATE; /* witchcraft */ |
| 124 | |
| 125 | <F>[^ \t\n"={}]+ { return find_resword(yytext); } |
| 126 | <F>[ \t] ; |
| 127 | <F>"\n" { yylineno++; } |
| 128 | <F>[={}] { return *yytext; } |
| 129 | |
| 130 | <F>\" { BEGIN Q; optr = ostr; quoted = 1; } |
| 131 | <Q>\n { yylineno++; yyerror("\" expected"); BEGIN F; } |
| 132 | <Q>\\b { *optr++ = '\b'; /* escape */ } |
| 133 | <Q>\\t { *optr++ = '\t'; /* escape */ } |
| 134 | <Q>\\\" { *optr++ = '\"'; /* escape */ } |
| 135 | <Q>\\\\ { *optr++ = '\\'; /* escape */ } |
| 136 | <Q>\\\n { yylineno++; /* continue */ } |
| 137 | <Q>\\r { *optr++ = '\r'; /* escape */ } |
| 138 | <Q>\\n { *optr++ = '\n'; /* escape */ } |
| 139 | <Q>\\f { *optr++ = '\f'; /* escape */ } |
| 140 | <Q>\\. { yyerror("Unknown \\ sequence"); } |
| 141 | <Q>([ \t]|"\\\n"){2,} { char *p = yytext-1; while (p = strchr(p+1, '\n')) yylineno++; } |
| 142 | <Q>"\\ " { *optr++ = ' '; /* force space */ } |
| 143 | <Q>\" { BEGIN F; quoted = 0; |
| 144 | *optr = '\0'; |
| 145 | yylval.s = strdup(ostr); |
| 146 | return tSTR; |
| 147 | } |
| 148 | <Q>. { *optr++ = *yytext; } |
| 149 | |
| 150 | %% |
| 151 | |
| 152 | static int find_resword(s) |
| 153 | char *s; |
| 154 | { |
| 155 | int tok = 0; |
| 156 | |
| 157 | int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1; |
| 158 | int rc = 0; |
| 159 | |
| 160 | m = NRES_WORDS/2; |
| 161 | |
| 162 | #define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q)) |
| 163 | |
| 164 | while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) { |
| 165 | /*fprintf(stderr, "failed to cmp(%s, %s), %d, %d, %d\n", s, rr[m].rw, l, m, h);*/ |
| 166 | if (rc < 0) |
| 167 | h = m - 1; |
| 168 | else |
| 169 | l = m + 1; |
| 170 | m = (h + l) / 2; |
| 171 | } |
| 172 | |
| 173 | if (rc == 0) |
| 174 | tok = rr[m].tok; |
| 175 | |
| 176 | switch (tok) { |
| 177 | case tLOCALHOST: |
| 178 | s = "${host}"; |
| 179 | /* fall through... */ |
| 180 | case 0: |
| 181 | yylval.s = strdup(s); |
| 182 | tok = tSTR; |
| 183 | /* fall through... */ |
| 184 | default: |
| 185 | return tok; |
| 186 | } |
| 187 | |
| 188 | } |
| 189 | |
| 190 | int yyerror(s, s1, s2, s3, s4) |
| 191 | char *s; |
| 192 | char *s1, *s2, *s3, *s4; |
| 193 | { |
| 194 | col_cleanup(0); |
| 195 | fprintf(stderr, "%s:%d: ", filename ? filename : "/dev/stdin", yylineno); |
| 196 | fprintf(stderr, s, s1, s2, s3, s4); |
| 197 | fputc('\n', stderr); |
| 198 | parse_errors++; |
| 199 | } |
| 200 | |
| 201 | ioloc *current_location() |
| 202 | { |
| 203 | ioloc *ip = ALLOC(ioloc); |
| 204 | ip->i_line = yylineno; |
| 205 | ip->i_file = filename; |
| 206 | return ip; |
| 207 | } |
| 208 | |
| 209 | #ifdef FLEX_SCANNER |
| 210 | #undef yywrap |
| 211 | #endif |
| 212 | |
| 213 | int yywrap() |
| 214 | { |
| 215 | static int first = 1; |
| 216 | if (first) { |
| 217 | char prog[16*1024]; |
| 218 | strcpy(prog, "for file in "); |
| 219 | while (*++g_argv) { |
| 220 | if (access(*g_argv, 4) < 0) { |
| 221 | error("\"%s\": Cannot open for reading", *g_argv); |
| 222 | file_io_errors++; |
| 223 | } else { |
| 224 | strcat(prog, *g_argv); |
| 225 | strcat(prog, " "); |
| 226 | } |
| 227 | } |
| 228 | strcat(prog, "; do /lib/cpp "); |
| 229 | strcat(prog, idvbuf); |
| 230 | strcat(prog, " -DHOSTNAME=\'"); |
| 231 | strcat(prog, hostname); |
| 232 | strcat(prog, "\' \"$file\"; done"); |
| 233 | yyin = popen(prog, "r"); |
| 234 | if (yyin) { |
| 235 | /*if (filename) free(filename);*/ |
| 236 | filename = strdup("unknown"); |
| 237 | yylineno = 1; |
| 238 | first = 0; |
| 239 | return 0; |
| 240 | } else { |
| 241 | perror(prog); |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | if (!first && yyin && pclose(yyin) != 0) |
| 246 | parse_errors++; |
| 247 | |
| 248 | return 1; |
| 249 | } |
| 250 | |
| 251 | #define xgetc(fp) ((iptr > ibuf) ? (*--iptr) : (lastch = nextch, nextch = getc(fp), (nextch == EOF ? nextch = lastch, EOF : nextch))) |
| 252 | |
| 253 | static int xinput(need) |
| 254 | int need; |
| 255 | { |
| 256 | static int c_comment = 0; |
| 257 | int ch, ch2; |
| 258 | |
| 259 | do { |
| 260 | ch = xgetc(yyin); |
| 261 | /* fprintf(stderr, "ch = %c, %#x, %d\n", ch, ibuf,iptr-ibuf); */ |
| 262 | if (ch == EOF) return 0; |
| 263 | if (quoted) |
| 264 | return ch; |
| 265 | if (c_comment) { |
| 266 | ch2 = ch; |
| 267 | do { |
| 268 | if (ch2 == '\n') { |
| 269 | nextch = '\n'; |
| 270 | return ch2; |
| 271 | } |
| 272 | /* C style comment */ |
| 273 | do { |
| 274 | ch2 = getc(yyin); |
| 275 | if (ch2 == '\n') { |
| 276 | nextch = '\n'; |
| 277 | return ch2; |
| 278 | } |
| 279 | } while (ch2 != '*' && ch2 != EOF); |
| 280 | |
| 281 | while (ch2 == '*') |
| 282 | ch2 = getc(yyin); |
| 283 | } while (ch2 != '/' && ch2 != EOF); |
| 284 | c_comment = 0; |
| 285 | if (ch2 == EOF) |
| 286 | break; |
| 287 | continue; |
| 288 | } |
| 289 | |
| 290 | if (ch == '#') { |
| 291 | /*log("lastch = '%c' (%#x)", lastch, lastch);*/ |
| 292 | if (lastch == '\n') { |
| 293 | char fname[MAXPATHLEN]; |
| 294 | char *fptr; |
| 295 | if (!need) { |
| 296 | xunput('#'); |
| 297 | nextch = '\n'; |
| 298 | return 0; |
| 299 | } |
| 300 | fname[0] = '\0'; |
| 301 | /* Skip past space */ |
| 302 | do { |
| 303 | ch2 = getc(yyin); |
| 304 | } while (ch2 != EOF && ch2 != '\n' && !isdigit(ch2)); |
| 305 | if (isdigit(ch2)) { |
| 306 | /* Read in line number */ |
| 307 | fptr = fname; |
| 308 | do { |
| 309 | *fptr++ = ch2; |
| 310 | ch2 = getc(yyin); |
| 311 | } while (isdigit(ch2)); |
| 312 | *fptr = '\0'; |
| 313 | if (fptr != fname) |
| 314 | yylineno = atoi(fname) - 1; |
| 315 | } |
| 316 | /* Skip past space */ |
| 317 | while (ch2 != EOF && ch2 != '\"' && ch2 != '\n') |
| 318 | ch2 = getc(yyin); |
| 319 | if (ch2 == '\"') { |
| 320 | /* Read file name */ |
| 321 | fptr = fname; |
| 322 | ch2 = getc(yyin); |
| 323 | while (ch2 != '\"' && ch2 != EOF && ch2 != EOF) { |
| 324 | *fptr++ = ch2; |
| 325 | ch2 = getc(yyin); |
| 326 | } |
| 327 | *fptr = '\0'; |
| 328 | if (fname[0]) { |
| 329 | log("Setting filename to \"%s\"", fname); |
| 330 | /*if (filename) free(filename);*/ |
| 331 | filename = strdup(fname); |
| 332 | } |
| 333 | } |
| 334 | while (ch2 != '\n' && ch2 != EOF) |
| 335 | ch2 = getc(yyin); |
| 336 | } else do { |
| 337 | ch2 = getc(yyin); |
| 338 | } while (ch2 != '\n' && ch2 != EOF); |
| 339 | if (ch2 == '\n') { |
| 340 | nextch = '\n'; |
| 341 | return ch2; |
| 342 | } |
| 343 | } else if (ch == '/') { |
| 344 | ch2 = getc(yyin); |
| 345 | if (ch2 == '/') { |
| 346 | /* C++ style comment */ |
| 347 | do { |
| 348 | ch2 = getc(yyin); |
| 349 | } while (ch2 != '\n' && ch2 != EOF); |
| 350 | if (ch2 == '\n') { |
| 351 | nextch = '\n'; |
| 352 | return ch2; |
| 353 | } |
| 354 | } else if (ch2 == '*') { |
| 355 | c_comment = 1; |
| 356 | continue; |
| 357 | } else { |
| 358 | xunput(ch2); |
| 359 | return ch; |
| 360 | } |
| 361 | } else { |
| 362 | return ch; |
| 363 | } |
| 364 | } while (ch2 != EOF); |
| 365 | error("End of file within comment"); |
| 366 | return 0; |
| 367 | } |
| 368 | |
| 369 | static void xunput(c) |
| 370 | int c; |
| 371 | { |
| 372 | if (c && c != EOF) { |
| 373 | if (iptr == ibuf + sizeof(ibuf) - 1) |
| 374 | fatal("Out of space in lexical pushback"); |
| 375 | *iptr++ = c; |
| 376 | } |
| 377 | } |