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