%{ /* * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry at Imperial College, London. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)fsi_lex.l 8.2 (Berkeley) 2/17/94 * $Id: fsi_lex.l,v 1.3 1994/06/13 20:50:15 mycroft Exp $ */ /* * Lexical analyzer for fsinfo. * TODO: Needs rewriting. */ static int xinput(); static void xunput(); #ifdef FLEX_SCANNER static int yylineno; /* Flex support with help from Vern Paxson */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ { \ int i; \ for (i = 0; i < max_size; i++) { \ int ch = xinput(i == 0); \ if (ch == 0) \ break; \ buf[i] = ch; \ } \ result = i; \ } #define INIT_STATE { \ switch ((yy_start - 1) / 2) { \ case 0: \ BEGIN F; \ break; \ } \ } #else /* * Using old lex... */ #undef unput #define unput(ch) xunput(ch) #undef input #define input() xinput(1) #define INIT_STATE { \ switch (yybgin - yysvec - 1) { \ case 0: \ BEGIN F; \ break; \ } \ } #endif /* FLEX_SCANNER */ #include "../fsinfo/fsinfo.h" #include "fsi_gram.h" #include static char *filename; static char *optr; static char ostr[1024]; static find_resword(); static unsigned char ibuf[64]; static unsigned char *iptr = ibuf; static int quoted; static int lastch, nextch = '\n'; YYSTYPE yylval; struct r { char *rw; int tok; } rr[] = { { "->", tEQ }, { "arch", tARCH }, { "as", tAS }, { "automount", tAUTOMOUNT }, { "cluster", tCLUSTER }, { "config", tCONFIG }, { "dumpset", tDUMPSET }, { "exportfs", tEXPORTFS }, { "freq", tFREQ }, { "from", tFROM }, { "fs", tFS }, { "fstype", tFSTYPE }, { "host", tHOST }, { "hwaddr", tHWADDR }, { "inaddr", tINADDR }, { "localhost", tLOCALHOST }, { "log", tLOG }, { "mount", tMOUNT }, { "netif", tNETIF }, { "netmask", tNETMASK }, { "opts", tOPTS }, { "os", tOS }, { "passno", tPASSNO }, { "sel", tSEL }, { "volname", tVOLNAME }, { 0, 0 }, }; #define NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1) %} %start F Q %% INIT_STATE; /* witchcraft */ [^ \t\n"={}]+ { return find_resword(yytext); } [ \t] ; "\n" { yylineno++; } [={}] { return *yytext; } \" { BEGIN Q; optr = ostr; quoted = 1; } \n { yylineno++; yyerror("\" expected"); BEGIN F; } \\b { *optr++ = '\b'; /* escape */ } \\t { *optr++ = '\t'; /* escape */ } \\\" { *optr++ = '\"'; /* escape */ } \\\\ { *optr++ = '\\'; /* escape */ } \\\n { yylineno++; /* continue */ } \\r { *optr++ = '\r'; /* escape */ } \\n { *optr++ = '\n'; /* escape */ } \\f { *optr++ = '\f'; /* escape */ } "\\ " { *optr++ = ' '; /* force space */ } \\. { yyerror("Unknown \\ sequence"); } ([ \t]|"\\\n"){2,} { char *p = yytext-1; while (p = strchr(p+1, '\n')) yylineno++; } \" { BEGIN F; quoted = 0; *optr = '\0'; yylval.s = strdup(ostr); return tSTR; } . { *optr++ = *yytext; } %% static int find_resword(s) char *s; { int tok = 0; int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1; int rc = 0; m = NRES_WORDS/2; #define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q)) while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) { /*fprintf(stderr, "failed to cmp(%s, %s), %d, %d, %d\n", s, rr[m].rw, l, m, h);*/ if (rc < 0) h = m - 1; else l = m + 1; m = (h + l) / 2; } if (rc == 0) tok = rr[m].tok; switch (tok) { case tLOCALHOST: s = "${host}"; /* fall through... */ case 0: yylval.s = strdup(s); tok = tSTR; /* fall through... */ default: return tok; } } int yyerror(s, s1, s2, s3, s4) char *s; char *s1, *s2, *s3, *s4; { col_cleanup(0); fprintf(stderr, "%s:%d: ", filename ? filename : "/dev/stdin", yylineno); fprintf(stderr, s, s1, s2, s3, s4); fputc('\n', stderr); parse_errors++; } ioloc *current_location() { ioloc *ip = ALLOC(ioloc); ip->i_line = yylineno; ip->i_file = filename; return ip; } #ifdef FLEX_SCANNER #undef yywrap #endif int yywrap() { static int first = 1; if (first) { char prog[16*1024]; strcpy(prog, "for file in "); while (*++g_argv) { if (access(*g_argv, 4) < 0) { error("\"%s\": Cannot open for reading", *g_argv); file_io_errors++; } else { strcat(prog, *g_argv); strcat(prog, " "); } } strcat(prog, "; do /lib/cpp "); strcat(prog, idvbuf); strcat(prog, " -DHOSTNAME=\'"); strcat(prog, hostname); strcat(prog, "\' \"$file\"; done"); yyin = popen(prog, "r"); if (yyin) { /*if (filename) free(filename);*/ filename = strdup("unknown"); yylineno = 1; first = 0; return 0; } else { perror(prog); } } if (!first && yyin && pclose(yyin) != 0) parse_errors++; return 1; } #define xgetc(fp) ((iptr > ibuf) ? (*--iptr) : (lastch = nextch, nextch = getc(fp), (nextch == EOF ? nextch = lastch, EOF : nextch))) static int xinput(need) int need; { static int c_comment = 0; int ch, ch2; do { ch = xgetc(yyin); /* fprintf(stderr, "ch = %c, %#x, %d\n", ch, ibuf,iptr-ibuf); */ if (ch == EOF) return 0; if (quoted) return ch; if (c_comment) { ch2 = ch; do { if (ch2 == '\n') { nextch = '\n'; return ch2; } /* C style comment */ do { ch2 = getc(yyin); if (ch2 == '\n') { nextch = '\n'; return ch2; } } while (ch2 != '*' && ch2 != EOF); while (ch2 == '*') ch2 = getc(yyin); } while (ch2 != '/' && ch2 != EOF); c_comment = 0; if (ch2 == EOF) break; continue; } if (ch == '#') { /*log("lastch = '%c' (%#x)", lastch, lastch);*/ if (lastch == '\n') { char fname[MAXPATHLEN]; char *fptr; if (!need) { xunput('#'); nextch = '\n'; return 0; } fname[0] = '\0'; /* Skip past space */ do { ch2 = getc(yyin); } while (ch2 != EOF && ch2 != '\n' && !isdigit(ch2)); if (isdigit(ch2)) { /* Read in line number */ fptr = fname; do { *fptr++ = ch2; ch2 = getc(yyin); } while (isdigit(ch2)); *fptr = '\0'; if (fptr != fname) yylineno = atoi(fname) - 1; } /* Skip past space */ while (ch2 != EOF && ch2 != '\"' && ch2 != '\n') ch2 = getc(yyin); if (ch2 == '\"') { /* Read file name */ fptr = fname; ch2 = getc(yyin); while (ch2 != '\"' && ch2 != EOF && ch2 != EOF) { *fptr++ = ch2; ch2 = getc(yyin); } *fptr = '\0'; if (fname[0]) { log("Setting filename to \"%s\"", fname); /*if (filename) free(filename);*/ filename = strdup(fname); } } while (ch2 != '\n' && ch2 != EOF) ch2 = getc(yyin); } else do { ch2 = getc(yyin); } while (ch2 != '\n' && ch2 != EOF); if (ch2 == '\n') { nextch = '\n'; return ch2; } } else if (ch == '/') { ch2 = getc(yyin); if (ch2 == '/') { /* C++ style comment */ do { ch2 = getc(yyin); } while (ch2 != '\n' && ch2 != EOF); if (ch2 == '\n') { nextch = '\n'; return ch2; } } else if (ch2 == '*') { c_comment = 1; continue; } else { xunput(ch2); return ch; } } else { return ch; } } while (ch2 != EOF); error("End of file within comment"); return 0; } static void xunput(c) int c; { if (c && c != EOF) { if (iptr == ibuf + sizeof(ibuf) - 1) fatal("Out of space in lexical pushback"); *iptr++ = c; } }