1 %{ 2 /* 3 * Copyright (c) 1989 Jan-Simon Pendry 4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. 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 8.1 (Berkeley) 06/06/93 14 * 15 * $Id: fsi_lex.l,v 5.2.2.1 1992/02/09 15:09:36 jsp beta $ 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 } 378