1 %{ 2 /* $OpenBSD: scan.l,v 1.21 2012/09/17 17:36:13 espie Exp $ */ 3 /* $NetBSD: scan.l,v 1.13 1997/02/02 21:12:37 thorpej Exp $ */ 4 5 /* 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This software was developed by the Computer Systems Engineering group 10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 11 * contributed to Berkeley. 12 * 13 * All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Lawrence Berkeley Laboratories. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 3. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 * from: @(#)scan.l 8.1 (Berkeley) 6/6/93 43 */ 44 45 #include <sys/param.h> 46 #include <errno.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <unistd.h> 51 #include "config.h" 52 #include "y.tab.h" 53 54 int yyline; 55 const char *yyfile; 56 const char *lastfile; 57 58 /* 59 * Data for returning to previous files from include files. 60 */ 61 struct incl { 62 struct incl *in_prev; /* previous includes in effect, if any */ 63 YY_BUFFER_STATE in_buf; /* previous lex state */ 64 const char *in_fname; /* previous file name */ 65 int in_lineno; /* previous line number */ 66 int in_ateof; /* token to insert at EOF */ 67 }; 68 static struct incl *incl; 69 static int endinclude(void); 70 71 #define yywrap() 1 72 73 %} 74 75 PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./\$\{\}]* 76 WORD [A-Za-z_][-A-Za-z_0-9]* 77 78 %% 79 /* Local variables for yylex() */ 80 int tok; 81 82 and return AND; 83 at return AT; 84 attach return ATTACH; 85 build return BUILD; 86 compile-with return COMPILE_WITH; 87 config return CONFIG; 88 define return DEFINE; 89 defopt return DEFOPT; 90 device return DEVICE; 91 disable return DISABLE; 92 enable return ENABLE; 93 dumps return DUMPS; 94 file return XFILE; 95 flags return FLAGS; 96 include return INCLUDE; 97 machine return XMACHINE; 98 major return MAJOR; 99 makeoptions return MAKEOPTIONS; 100 makeoption return MAKEOPTIONS; 101 maxpartitions return MAXPARTITIONS; 102 maxusers return MAXUSERS; 103 minor return MINOR; 104 needs-count return NEEDS_COUNT; 105 needs-flag return NEEDS_FLAG; 106 object return XOBJECT; 107 on return ON; 108 options return OPTIONS; 109 option return OPTIONS; 110 pseudo-device return PSEUDO_DEVICE; 111 root return ROOT; 112 source return SOURCE; 113 swap return SWAP; 114 with return WITH; 115 rmoption return RMOPTIONS; 116 rmoptions return RMOPTIONS; 117 118 {PATH} { 119 yylval.str = intern(yytext); 120 return PATHNAME; 121 } 122 {WORD} { 123 yylval.str = intern(yytext); 124 return WORD; 125 } 126 127 \"\" { 128 yylval.str = intern(""); 129 return EMPTY; 130 } 131 \"([^"\n]|\\\")+ { 132 tok = input(); /* eat closing quote */ 133 yylval.str = intern(yytext + 1); 134 if (tok != '"') { 135 error("closing quote missing"); 136 unput(tok); 137 } 138 return WORD; 139 } 140 0[0-7]* { 141 yylval.val = strtol(yytext, NULL, 8); 142 return NUMBER; 143 } 144 0[xX][0-9a-fA-F]+ { 145 yylval.val = strtoul(yytext + 2, NULL, 16); 146 return NUMBER; 147 } 148 [1-9][0-9]* { 149 yylval.val = strtol(yytext, NULL, 10); 150 return NUMBER; 151 } 152 \n[ \t] { 153 /* 154 * Note: newline followed by whitespace is always a 155 * continuation of the previous line, so do NOT 156 * return a token in this case. 157 */ 158 yyline++; 159 } 160 \n { 161 yyline++; 162 return '\n'; 163 } 164 #.* { /* ignored (comment) */; } 165 [ \t]+ { /* ignored (white space) */; } 166 . { return yytext[0]; } 167 <<EOF>> { 168 if (incl == NULL) 169 return YY_NULL; 170 tok = endinclude(); 171 if (tok) 172 return tok; 173 /* otherwise continue scanning */ 174 } 175 176 %% 177 178 /* 179 * Open the "main" file (conffile). 180 */ 181 int 182 firstfile(fname) 183 const char *fname; 184 { 185 186 if ((yyin = fopen(fname, "r")) == NULL) 187 return (-1); 188 yyfile = conffile = fname; 189 yyline = 1; 190 return (0); 191 } 192 193 /* 194 * Open the named file for inclusion at the current point. Returns 0 on 195 * success (file opened and previous state pushed), nonzero on failure 196 * (fopen failed, complaint made). The `ateof' parameter controls the 197 * token to be inserted at the end of the include file (i.e. ENDFILE). 198 * If ateof == 0 then nothing is inserted. 199 */ 200 int 201 include(fname, ateof) 202 const char *fname; 203 int ateof; 204 { 205 FILE *fp; 206 struct incl *in; 207 char *s; 208 static int havedirs; 209 210 if (havedirs == 0) { 211 havedirs = 1; 212 setupdirs(); 213 } 214 215 /* Kludge until files.* files are fixed. */ 216 if (strncmp(fname, "../../../", 9) == 0) 217 fname += 9; 218 219 s = (*fname == '/') ? strdup(fname) : sourcepath(fname); 220 if ((fp = fopen(s, "r")) == NULL) { 221 error("cannot open %s for reading: %s\n", s, strerror(errno)); 222 free(s); 223 return (-1); 224 } 225 in = emalloc(sizeof *in); 226 in->in_prev = incl; 227 in->in_buf = YY_CURRENT_BUFFER; 228 in->in_fname = yyfile; 229 in->in_lineno = yyline; 230 in->in_ateof = ateof; 231 incl = in; 232 yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); 233 yyfile = intern(s); 234 yyline = 1; 235 free(s); 236 return (0); 237 } 238 239 /* 240 * Terminate the most recent inclusion. 241 */ 242 static int 243 endinclude() 244 { 245 struct incl *in; 246 int ateof; 247 248 if ((in = incl) == NULL) 249 panic("endinclude"); 250 incl = in->in_prev; 251 lastfile = yyfile; 252 yy_delete_buffer(YY_CURRENT_BUFFER); 253 (void)fclose(yyin); 254 yy_switch_to_buffer(in->in_buf); 255 yyfile = in->in_fname; 256 yyline = in->in_lineno; 257 ateof = in->in_ateof; 258 free(in); 259 260 return (ateof); 261 } 262 263 /* 264 * Return the current line number. If yacc has looked ahead and caused 265 * us to consume a newline, we have to subtract one. yychar is yacc's 266 * token lookahead, so we can tell. 267 */ 268 int 269 currentline() 270 { 271 extern int yychar; 272 273 return (yyline - (yychar == '\n')); 274 } 275