1 %{ 2 /* 3 * Copyright (c) 1992 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This software was developed by the Computer Systems Engineering group 7 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 8 * contributed to Berkeley. 9 * 10 * All advertising materials mentioning features or use of this software 11 * must display the following acknowledgement: 12 * This product includes software developed by the University of 13 * California, Lawrence Berkeley Laboratories. 14 * 15 * %sccs.include.redist.c% 16 * 17 * @(#)scan.l 5.1 (Berkeley) 01/12/93 18 * 19 * from: $Header: scan.l,v 1.5 93/01/12 10:13:42 torek Exp $ 20 */ 21 22 #include <sys/param.h> 23 #include <errno.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 #include "config.h" 29 #include "y.tab.h" 30 31 int yyline; 32 const char *yyfile; 33 const char *lastfile; 34 35 int include __P((const char *, int)); 36 37 /* 38 * Data for returning to previous files from include files. 39 */ 40 struct incl { 41 struct incl *in_prev; /* previous includes in effect, if any */ 42 YY_BUFFER_STATE in_buf; /* previous lex state */ 43 const char *in_fname; /* previous file name */ 44 int in_lineno; /* previous line number */ 45 int in_preveof; /* previous eoftoken */ 46 }; 47 static struct incl *incl; 48 static int eoftoken; /* current EOF token */ 49 static void endinclude __P((void)); 50 51 #define yywrap() 1 52 53 %} 54 55 PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* 56 WORD [A-Za-z_][-A-Za-z_0-9]* 57 58 %% 59 60 /* plain keywords */ 61 and { return AND; } 62 at { return AT; } 63 compile-with { return COMPILE_WITH; } 64 config { return CONFIG; } 65 define { return DEFINE; } 66 device { return DEVICE; } 67 dumps { return DUMPS; } 68 flags { return FLAGS; } 69 file { return XFILE; } 70 include { return INCLUDE; } 71 machine { return XMACHINE; } 72 major { return MAJOR; } 73 makeoptions { return MAKEOPTIONS; } 74 maxusers { return MAXUSERS; } 75 minor { return MINOR; } 76 on { return ON; } 77 options { return OPTIONS; } 78 "pseudo-device" { return PSEUDO_DEVICE; } 79 root { return ROOT; } 80 swap { return SWAP; } 81 vector { return VECTOR; } 82 83 /* keywords with values */ 84 config-dependent { yylval.val = FI_CONFIGDEP; return FFLAG; } 85 device-driver { yylval.val = FI_DRIVER; return FFLAG; } 86 needs-count { yylval.val = FI_NEEDSCOUNT; return FFLAG; } 87 needs-flag { yylval.val = FI_NEEDSFLAG; return FFLAG; } 88 89 /* all the rest */ 90 {PATH} { yylval.str = intern(yytext); return PATHNAME; } 91 {WORD} { yylval.str = intern(yytext); return WORD; } 92 93 \"[^"]+/\" { 94 yylval.str = intern(yytext + 1); 95 (void)input(); /* eat closing quote */ 96 return WORD; 97 } 98 0[0-7]* { 99 yylval.val = strtol(yytext, NULL, 8); 100 return NUMBER; 101 } 102 0[xX][0-9a-fA-F]+ { 103 yylval.val = strtol(yytext + 2, NULL, 16); 104 return NUMBER; 105 } 106 [1-9][0-9]* { 107 yylval.val = strtol(yytext, NULL, 10); 108 return NUMBER; 109 } 110 \n/[ \t] { 111 yyline++; 112 } 113 \n { 114 yyline++; 115 return '\n'; 116 } 117 #.* { /* ignored (comment) */; } 118 [ \t]* { /* ignored (white space) */; } 119 . { return yytext[0]; } 120 <<EOF>> { 121 int tok; 122 123 tok = eoftoken; 124 eoftoken = YY_NULL; 125 if (incl != NULL) 126 endinclude(); 127 return (tok); 128 } 129 130 %% 131 132 /* 133 * Open the "main" file (conffile). 134 */ 135 int 136 firstfile(fname) 137 const char *fname; 138 { 139 140 if ((yyin = fopen(fname, "r")) == NULL) 141 return (-1); 142 yyfile = conffile = fname; 143 yyline = 1; 144 eoftoken = YY_NULL; 145 return (0); 146 } 147 148 /* 149 * Open the named file for inclusion at the current point. Returns 0 on 150 * success (file opened and previous state pushed), nonzero on failure 151 * (fopen failed, complaint made). The `ateof' parameter controls the 152 * token to be returned at the end of the include file (typically '\n' 153 * or ENDFILE). 154 */ 155 int 156 include(fname, ateof) 157 const char *fname; 158 int ateof; 159 { 160 register FILE *fp; 161 register struct incl *in; 162 163 if ((fp = fopen(fname, "r")) == NULL) { 164 error("cannot open %s for reading: %s\n", 165 fname, strerror(errno)); 166 return (-1); 167 } 168 in = emalloc(sizeof *in); 169 in->in_prev = incl; 170 in->in_buf = YY_CURRENT_BUFFER; 171 in->in_fname = yyfile; 172 in->in_lineno = yyline; 173 in->in_preveof = eoftoken; 174 incl = in; 175 yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); 176 yyfile = intern(fname); 177 yyline = 1; 178 eoftoken = ateof; 179 return (0); 180 } 181 182 /* 183 * Terminate the most recent inclusion. 184 */ 185 static void 186 endinclude() 187 { 188 register struct incl *in; 189 190 if ((in = incl) == NULL) 191 panic("endinclude"); 192 incl = in->in_prev; 193 lastfile = yyfile; 194 yy_delete_buffer(YY_CURRENT_BUFFER); 195 (void)fclose(yyin); 196 yy_switch_to_buffer(in->in_buf); 197 yyfile = in->in_fname; 198 yyline = in->in_lineno; 199 eoftoken = in->in_preveof; 200 free(in); 201 } 202 203 /* 204 * Return the current line number. If yacc has looked ahead and caused 205 * us to consume a newline, we have to subtract one. yychar is yacc's 206 * token lookahead, so we can tell. 207 */ 208 int 209 currentline() 210 { 211 extern int yychar; 212 213 return (yyline - (yychar == '\n')); 214 } 215