Sun Mar 8 17:38:37 2020 UTC ()
Add debugging, no functional change.


(christos)
diff -r1.29 -r1.30 src/usr.bin/config/scan.l

cvs diff -r1.29 -r1.30 src/usr.bin/config/scan.l (switch to unified diff)

--- src/usr.bin/config/scan.l 2020/03/08 00:04:11 1.29
+++ src/usr.bin/config/scan.l 2020/03/08 17:38:37 1.30
@@ -1,623 +1,653 @@ @@ -1,623 +1,653 @@
1%{ 1%{
2/* $NetBSD: scan.l,v 1.29 2020/03/08 00:04:11 christos Exp $ */ 2/* $NetBSD: scan.l,v 1.30 2020/03/08 17:38:37 christos Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1992, 1993 5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved. 6 * The Regents of the University of California. All rights reserved.
7 * 7 *
8 * This software was developed by the Computer Systems Engineering group 8 * This software was developed by the Computer Systems Engineering group
9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10 * contributed to Berkeley. 10 * contributed to Berkeley.
11 * 11 *
12 * All advertising materials mentioning features or use of this software 12 * All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement: 13 * must display the following acknowledgement:
14 * This product includes software developed by the University of 14 * This product includes software developed by the University of
15 * California, Lawrence Berkeley Laboratories. 15 * California, Lawrence Berkeley Laboratories.
16 * 16 *
17 * Redistribution and use in source and binary forms, with or without 17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions 18 * modification, are permitted provided that the following conditions
19 * are met: 19 * are met:
20 * 1. Redistributions of source code must retain the above copyright 20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer. 21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright 22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the 23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution. 24 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the University nor the names of its contributors 25 * 3. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software 26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission. 27 * without specific prior written permission.
28 * 28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE. 39 * SUCH DAMAGE.
40 * 40 *
41 * from: @(#)scan.l 8.1 (Berkeley) 6/6/93 41 * from: @(#)scan.l 8.1 (Berkeley) 6/6/93
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__RCSID("$NetBSD: scan.l,v 1.29 2020/03/08 00:04:11 christos Exp $"); 45__RCSID("$NetBSD: scan.l,v 1.30 2020/03/08 17:38:37 christos Exp $");
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <errno.h> 48#include <errno.h>
49#include <libgen.h> 49#include <libgen.h>
50#include <stdio.h> 50#include <stdio.h>
51#include <stdlib.h> 51#include <stdlib.h>
52#include <string.h> 52#include <string.h>
53#include <unistd.h> 53#include <unistd.h>
54#include <stddef.h> 54#include <stddef.h>
55#include <ctype.h> 55#include <ctype.h>
56#include <util.h> 56#include <util.h>
57#undef ECHO 57#undef ECHO
58#include "defs.h" 58#include "defs.h"
59#include "gram.h" 59#include "gram.h"
60 60
61int yyline; 61int yyline;
62const char *yyfile; 62const char *yyfile;
63const char *lastfile; 63const char *lastfile;
64char curinclpath[PATH_MAX]; 64char curinclpath[PATH_MAX];
65uint64_t ifdefstate; 65uint64_t ifdefstate;
66int ifdefshift = -1; 66int ifdefshift = -1;
67 67
68/* 68/*
69 * The state is represented by 3 bits. 69 * The state is represented by 3 bits.
70 */ 70 */
71#define IDS_MATCH 1ll 71#define IDS_MATCH 1ll
72#define IDS_ELIF 2ll 72#define IDS_ELIF 2ll
73#define IDS_ELSE 4ll 73#define IDS_ELSE 4ll
74 74
75#define IDS_BITS 7 75#define IDS_BITS 7
76#define IDS_SHIFT 3 76#define IDS_SHIFT 3
77 77
78#define IDS_ISMATCH(st) (((st) & IDS_MATCH) != 0) 78#define IDS_ISMATCH(st) (((st) & IDS_MATCH) != 0)
79#define IDS_PARENT_DISABLED \ 79#define IDS_PARENT_DISABLED \
80 (ifdefshift > 0 && !IDS_ISMATCH(ifdefstate >> IDS_SHIFT)) 80 (ifdefshift > 0 && !IDS_ISMATCH(ifdefstate >> IDS_SHIFT))
81#define IDS_MAX_DEPTH 21 /* 64 / 3 */ 81#define IDS_MAX_DEPTH 21 /* 64 / 3 */
82  82
 83#ifdef IDS_DEBUG
 84# define IDS_PRINT(s, st, x) \
 85 do { \
 86 for (int i = 0; i < ifdefshift + 1; i++) \
 87 fprintf(stderr, " "); \
 88 printf("%s%s [%d,%d,%d] %#" PRIx64 "\n", x, # s, \
 89 IDS_PARENT_DISABLED, IDS_ISMATCH(st), getcurifdef(), \
 90 ifdefstate); \
 91 } while (/*CONSTCOND*/0)
 92#else
 93# define IDS_PRINT(s, st, x) __nothing
 94#endif
 95
 96#define IDS_ENTER(s, st) \
 97 IDS_PRINT(s, st, ">")
 98#define IDS_EXIT(s, st) \
 99 IDS_PRINT(s, st, "<")
 100
83/* 101/*
84 * Data for returning to previous files from include files. 102 * Data for returning to previous files from include files.
85 */ 103 */
86struct incl { 104struct incl {
87 struct incl *in_prev; /* previous includes in effect, if any */ 105 struct incl *in_prev; /* previous includes in effect, if any */
88 YY_BUFFER_STATE in_buf; /* previous lex state */ 106 YY_BUFFER_STATE in_buf; /* previous lex state */
89 struct where in_where; 107 struct where in_where;
90 int in_ateof; /* token to insert at EOF */ 108 int in_ateof; /* token to insert at EOF */
91 int in_interesting; /* previous value for "interesting" */ 109 int in_interesting; /* previous value for "interesting" */
92 uint64_t in_ifdefstate; /* conditional level */ 110 uint64_t in_ifdefstate; /* conditional level */
93 int in_ifdefshift; /* conditional level */ 111 int in_ifdefshift; /* conditional level */
94}; 112};
95static struct incl *incl; 113static struct incl *incl;
96static int endinclude(void); 114static int endinclude(void);
97static int getincludepath(void); 115static int getincludepath(void);
98static int getcurifdef(void); 116static int getcurifdef(void);
99 117
100 118
101%} 119%}
102 120
103%option noyywrap nounput noinput 121%option noyywrap nounput noinput
104 122
105PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./]* 123PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./]*
106QCHARS \"(\\.|[^\\"])*\"  124QCHARS \"(\\.|[^\\"])*\"
107WORD [A-Za-z_][-A-Za-z_0-9]* 125WORD [A-Za-z_][-A-Za-z_0-9]*
108FILENAME ({PATH}|{QCHARS}) 126FILENAME ({PATH}|{QCHARS})
109RESTOFLINE [ \t]*(#[^\n]*)?\n 127RESTOFLINE [ \t]*(#[^\n]*)?\n
110WS ^[ \t]* 128WS ^[ \t]*
111 129
112%x IGNORED 130%x IGNORED
113 131
114%% 132%%
115 /* Local variables for yylex() */ 133 /* Local variables for yylex() */
116 int tok; 134 int tok;
117 135
118and return AND; 136and return AND;
119at return AT; 137at return AT;
120attach return ATTACH; 138attach return ATTACH;
121block return BLOCK; 139block return BLOCK;
122build return BUILD; 140build return BUILD;
123char return CHAR; 141char return CHAR;
124compile-with return COMPILE_WITH; 142compile-with return COMPILE_WITH;
125config return CONFIG; 143config return CONFIG;
126deffs return DEFFS; 144deffs return DEFFS;
127define return DEFINE; 145define return DEFINE;
128defflag return DEFFLAG; 146defflag return DEFFLAG;
129defopt return DEFOPT; 147defopt return DEFOPT;
130defparam return DEFPARAM; 148defparam return DEFPARAM;
131defpseudo return DEFPSEUDO; 149defpseudo return DEFPSEUDO;
132defpseudodev return DEFPSEUDODEV; 150defpseudodev return DEFPSEUDODEV;
133devclass return DEVCLASS; 151devclass return DEVCLASS;
134device return DEVICE; 152device return DEVICE;
135device-major return DEVICE_MAJOR; 153device-major return DEVICE_MAJOR;
136dumps return DUMPS; 154dumps return DUMPS;
137file return XFILE; 155file return XFILE;
138file-system return FILE_SYSTEM; 156file-system return FILE_SYSTEM;
139flags return FLAGS; 157flags return FLAGS;
140ident return IDENT; 158ident return IDENT;
141ioconf return IOCONF; 159ioconf return IOCONF;
142linkzero return LINKZERO; 160linkzero return LINKZERO;
143machine return XMACHINE; 161machine return XMACHINE;
144major return MAJOR; 162major return MAJOR;
145makeoptions return MAKEOPTIONS; 163makeoptions return MAKEOPTIONS;
146maxpartitions return MAXPARTITIONS; 164maxpartitions return MAXPARTITIONS;
147maxusers return MAXUSERS; 165maxusers return MAXUSERS;
148minor return MINOR; 166minor return MINOR;
149needs-count return NEEDS_COUNT; 167needs-count return NEEDS_COUNT;
150needs-flag return NEEDS_FLAG; 168needs-flag return NEEDS_FLAG;
151no return NO; 169no return NO;
152-no return CNO; 170-no return CNO;
153object return XOBJECT; 171object return XOBJECT;
154obsolete return OBSOLETE; 172obsolete return OBSOLETE;
155on return ON; 173on return ON;
156options return OPTIONS; 174options return OPTIONS;
157prefix return PREFIX; 175prefix return PREFIX;
158buildprefix return BUILDPREFIX; 176buildprefix return BUILDPREFIX;
159pseudo-device return PSEUDO_DEVICE; 177pseudo-device return PSEUDO_DEVICE;
160pseudo-root return PSEUDO_ROOT; 178pseudo-root return PSEUDO_ROOT;
161root return ROOT; 179root return ROOT;
162select return SELECT; 180select return SELECT;
163single return SINGLE; 181single return SINGLE;
164source return SOURCE; 182source return SOURCE;
165type return TYPE; 183type return TYPE;
166vector return VECTOR; 184vector return VECTOR;
167version return VERSION; 185version return VERSION;
168with return WITH; 186with return WITH;
169 187
170\+= return PLUSEQ; 188\+= return PLUSEQ;
171:= return COLONEQ; 189:= return COLONEQ;
172 190
173<*>{WS}ifdef[ \t]+{WORD}{RESTOFLINE} { 191<*>{WS}ifdef[ \t]+{WORD}{RESTOFLINE} {
174 ifdefstate <<= IDS_SHIFT; 192 ifdefstate <<= IDS_SHIFT;
175 if (++ifdefshift >= IDS_MAX_DEPTH) { 193 if (++ifdefshift >= IDS_MAX_DEPTH) {
176 yyerror("too many levels of conditional"); 194 yyerror("too many levels of conditional");
177 } 195 }
 196 IDS_ENTER(ifdef, 0);
178 if (IDS_PARENT_DISABLED || !getcurifdef()) { 197 if (IDS_PARENT_DISABLED || !getcurifdef()) {
179 BEGIN(IGNORED); 198 BEGIN(IGNORED);
180 } else { 199 } else {
181 ifdefstate |= IDS_MATCH; 200 ifdefstate |= IDS_MATCH;
182 BEGIN(INITIAL); 201 BEGIN(INITIAL);
183 } 202 }
 203 IDS_EXIT(ifdef, 0);
184 yyline++; 204 yyline++;
185 } 205 }
186 206
187<*>{WS}ifndef[ \t]+{WORD}{RESTOFLINE} { 207<*>{WS}ifndef[ \t]+{WORD}{RESTOFLINE} {
188 ifdefstate <<= IDS_SHIFT; 208 ifdefstate <<= IDS_SHIFT;
189 if (++ifdefshift >= IDS_MAX_DEPTH) { 209 if (++ifdefshift >= IDS_MAX_DEPTH) {
190 yyerror("too many levels of conditional"); 210 yyerror("too many levels of conditional");
191 } 211 }
 212 IDS_ENTER(ifndef, 0);
192 if (IDS_PARENT_DISABLED || getcurifdef()) { 213 if (IDS_PARENT_DISABLED || getcurifdef()) {
193 BEGIN(IGNORED); 214 BEGIN(IGNORED);
194 } else { 215 } else {
195 ifdefstate |= IDS_MATCH; 216 ifdefstate |= IDS_MATCH;
196 BEGIN(INITIAL); 217 BEGIN(INITIAL);
197 } 218 }
 219 IDS_EXIT(ifndef, 0);
198 yyline++; 220 yyline++;
199 } 221 }
200 222
201 223
202<*>{WS}elifdef[ \t]+{WORD}{RESTOFLINE} { 224<*>{WS}elifdef[ \t]+{WORD}{RESTOFLINE} {
203 int st = ifdefstate & IDS_BITS; 225 int st = ifdefstate & IDS_BITS;
 226 IDS_ENTER(elifdef, st);
204 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { 227 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
205 yyerror("mismatched elifdef"); 228 yyerror("mismatched elifdef");
206 } 229 }
207 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || !getcurifdef()) { 230 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || !getcurifdef()) {
208 BEGIN(IGNORED); 231 BEGIN(IGNORED);
209 } else { 232 } else {
210 ifdefstate |= IDS_MATCH; 233 ifdefstate |= IDS_MATCH;
211 BEGIN(INITIAL); 234 BEGIN(INITIAL);
212 } 235 }
213 ifdefstate |= IDS_ELIF; 236 ifdefstate |= IDS_ELIF;
 237 IDS_EXIT(elifdef, st);
214 yyline++; 238 yyline++;
215 } 239 }
216 240
217<*>{WS}elifndef[ \t]+{WORD}{RESTOFLINE} { 241<*>{WS}elifndef[ \t]+{WORD}{RESTOFLINE} {
218 int st = ifdefstate & IDS_BITS; 242 int st = ifdefstate & IDS_BITS;
 243 IDS_ENTER(elifndef, st);
219 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { 244 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
220 yyerror("mismatched elifndef"); 245 yyerror("mismatched elifndef");
221 } 246 }
222 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || getcurifdef()) { 247 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || getcurifdef()) {
223 BEGIN(IGNORED); 248 BEGIN(IGNORED);
224 } else { 249 } else {
225 ifdefstate |= IDS_MATCH; 250 ifdefstate |= IDS_MATCH;
226 BEGIN(INITIAL); 251 BEGIN(INITIAL);
227 } 252 }
228 ifdefstate |= IDS_ELIF; 253 ifdefstate |= IDS_ELIF;
 254 IDS_EXIT(elifndef, st);
229 yyline++; 255 yyline++;
230 } 256 }
231 257
232<*>{WS}else{RESTOFLINE} { 258<*>{WS}else{RESTOFLINE} {
233 int st = ifdefstate & IDS_BITS; 259 int st = ifdefstate & IDS_BITS;
 260 IDS_ENTER(else, st);
234 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { 261 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
235 yyerror("mismatched else"); 262 yyerror("mismatched else");
236 } 263 }
237 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st)) { 264 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st)) {
238 BEGIN(IGNORED); 265 BEGIN(IGNORED);
239 } else { 266 } else {
240 ifdefstate |= IDS_MATCH; 267 ifdefstate |= IDS_MATCH;
241 BEGIN(INITIAL); 268 BEGIN(INITIAL);
242 } 269 }
243 ifdefstate |= IDS_ELSE; 270 ifdefstate |= IDS_ELSE;
 271 IDS_ENTER(else, st);
244 yyline++; 272 yyline++;
245 } 273 }
246 274
247<*>{WS}endif{RESTOFLINE} { 275<*>{WS}endif{RESTOFLINE} {
 276 IDS_ENTER(endif, 0);
248 if (ifdefshift == -1) { 277 if (ifdefshift == -1) {
249 yyerror("mismatched endif"); 278 yyerror("mismatched endif");
250 } 279 }
251 if (!IDS_PARENT_DISABLED) { 280 if (!IDS_PARENT_DISABLED) {
252 BEGIN(INITIAL); 281 BEGIN(INITIAL);
253 } 282 }
 283 IDS_EXIT(endif, 0);
254 ifdefshift--; 284 ifdefshift--;
255 ifdefstate >>= IDS_SHIFT; 285 ifdefstate >>= IDS_SHIFT;
256 yyline++; 286 yyline++;
257 } 287 }
258 288
259<IGNORED>\n { 289<IGNORED>\n {
260 yyline++; 290 yyline++;
261 } 291 }
262 292
263<IGNORED>. /* ignore */ 293<IGNORED>. /* ignore */
264 294
265include[ \t]+{FILENAME}{RESTOFLINE} { 295include[ \t]+{FILENAME}{RESTOFLINE} {
266 yyline++; 296 yyline++;
267 if (getincludepath()) { 297 if (getincludepath()) {
268 include(curinclpath, 0, 0, 1); 298 include(curinclpath, 0, 0, 1);
269 } else { 299 } else {
270 yyerror("bad include path-name"); 300 yyerror("bad include path-name");
271 } 301 }
272 } 302 }
273 303
274cinclude[ \t]+{FILENAME}{RESTOFLINE} { 304cinclude[ \t]+{FILENAME}{RESTOFLINE} {
275 yyline++; 305 yyline++;
276 if (getincludepath()) { 306 if (getincludepath()) {
277 include(curinclpath, 0, 1, 1); 307 include(curinclpath, 0, 1, 1);
278 } else { 308 } else {
279 yyerror("bad cinclude path-name"); 309 yyerror("bad cinclude path-name");
280 } 310 }
281 } 311 }
282 312
283package[ \t]+{FILENAME}{RESTOFLINE} { 313package[ \t]+{FILENAME}{RESTOFLINE} {
284 yyline++; 314 yyline++;
285 if (!oktopackage) { 315 if (!oktopackage) {
286 yyerror("package not allowed here"); 316 yyerror("package not allowed here");
287 } else if (getincludepath()) { 317 } else if (getincludepath()) {
288 package(curinclpath); 318 package(curinclpath);
289 } else { 319 } else {
290 yyerror("bad package path-name"); 320 yyerror("bad package path-name");
291 } 321 }
292 } 322 }
293 323
294{PATH} { 324{PATH} {
295 yylval.str = intern(yytext); 325 yylval.str = intern(yytext);
296 return PATHNAME; 326 return PATHNAME;
297 } 327 }
298 328
299{WORD} { 329{WORD} {
300 yylval.str = intern(yytext); 330 yylval.str = intern(yytext);
301 return WORD; 331 return WORD;
302 } 332 }
303 333
304\"\" { 334\"\" {
305 yylval.str = intern(""); 335 yylval.str = intern("");
306 return EMPTYSTRING; 336 return EMPTYSTRING;
307 } 337 }
308 338
309{QCHARS} { 339{QCHARS} {
310 size_t l = strlen(yytext); 340 size_t l = strlen(yytext);
311 if (l > 1 && yytext[l - 1] == '"') 341 if (l > 1 && yytext[l - 1] == '"')
312 yytext[l - 1] = '\0'; 342 yytext[l - 1] = '\0';
313 343
314 yylval.str = intern(yytext + 1); 344 yylval.str = intern(yytext + 1);
315 return QSTRING; 345 return QSTRING;
316 } 346 }
3170[0-7]* { 3470[0-7]* {
318 yylval.num.fmt = 8; 348 yylval.num.fmt = 8;
319 yylval.num.val = strtoll(yytext, NULL, 8); 349 yylval.num.val = strtoll(yytext, NULL, 8);
320 return NUMBER; 350 return NUMBER;
321 } 351 }
3220[xX][0-9a-fA-F]+ { 3520[xX][0-9a-fA-F]+ {
323 yylval.num.fmt = 16; 353 yylval.num.fmt = 16;
324 yylval.num.val = (long long)strtoull(yytext + 2, NULL, 16); 354 yylval.num.val = (long long)strtoull(yytext + 2, NULL, 16);
325 return NUMBER; 355 return NUMBER;
326 } 356 }
327[1-9][0-9]* { 357[1-9][0-9]* {
328 yylval.num.fmt = 10; 358 yylval.num.fmt = 10;
329 yylval.num.val = strtoll(yytext, NULL, 10); 359 yylval.num.val = strtoll(yytext, NULL, 10);
330 return NUMBER; 360 return NUMBER;
331 } 361 }
332\n[ \t] { 362\n[ \t] {
333 /* 363 /*
334 * Note: newline followed by whitespace is always a 364 * Note: newline followed by whitespace is always a
335 * continuation of the previous line, so do NOT 365 * continuation of the previous line, so do NOT
336 * return a token in this case. 366 * return a token in this case.
337 */ 367 */
338 yyline++; 368 yyline++;
339 } 369 }
340\n { 370\n {
341 yyline++; 371 yyline++;
342 return '\n'; 372 return '\n';
343 } 373 }
344\00 { 374\00 {
345 /* Detect NUL characters in the config file and 375 /* Detect NUL characters in the config file and
346 * error out. 376 * error out.
347 */ 377 */
348 cfgerror("NUL character detected at line %i", yyline); 378 cfgerror("NUL character detected at line %i", yyline);
349 } 379 }
350#.* { /* ignored (comment) */; } 380#.* { /* ignored (comment) */; }
351[ \t]+ { /* ignored (white space) */; } 381[ \t]+ { /* ignored (white space) */; }
352. { return yytext[0]; } 382. { return yytext[0]; }
353<*><<EOF>> { 383<*><<EOF>> {
354 if (ifdefshift > (incl == NULL ? -1 : incl->in_ifdefshift)) { 384 if (ifdefshift > (incl == NULL ? -1 : incl->in_ifdefshift)) {
355 yyerror("reached EOF while looking for endif"); 385 yyerror("reached EOF while looking for endif");
356 } 386 }
357 if (incl == NULL) 387 if (incl == NULL)
358 return YY_NULL; 388 return YY_NULL;
359 tok = endinclude(); 389 tok = endinclude();
360 if (tok) 390 if (tok)
361 return tok; 391 return tok;
362 /* otherwise continue scanning */ 392 /* otherwise continue scanning */
363 } 393 }
364 394
365%% 395%%
366 396
367int interesting = 1; 397int interesting = 1;
368 398
369static int 399static int
370curdir_push(const char *fname) 400curdir_push(const char *fname)
371{ 401{
372 struct prefix *pf; 402 struct prefix *pf;
373 char *p, *d, *f; 403 char *p, *d, *f;
374 404
375 /* Set up the initial "current directory" for include directives. */ 405 /* Set up the initial "current directory" for include directives. */
376 d = dirname(f = estrdup(fname)); 406 d = dirname(f = estrdup(fname));
377 if (*d == '/') 407 if (*d == '/')
378 p = estrdup(d); 408 p = estrdup(d);
379 else { 409 else {
380 char *cwd, buf[PATH_MAX]; 410 char *cwd, buf[PATH_MAX];
381 411
382 if ((cwd = getcwd(buf, sizeof(buf))) == NULL) { 412 if ((cwd = getcwd(buf, sizeof(buf))) == NULL) {
383 free(f); 413 free(f);
384 return (-1); 414 return (-1);
385 } 415 }
386 easprintf(&p, "%s/%s", cwd, d); 416 easprintf(&p, "%s/%s", cwd, d);
387 } 417 }
388 free(f); 418 free(f);
389 pf = ecalloc(1, sizeof(*pf)); 419 pf = ecalloc(1, sizeof(*pf));
390 pf->pf_prefix = p; 420 pf->pf_prefix = p;
391 SLIST_INSERT_HEAD(&curdirs, pf, pf_next); 421 SLIST_INSERT_HEAD(&curdirs, pf, pf_next);
392 422
393 return (0); 423 return (0);
394} 424}
395 425
396static void 426static void
397curdir_pop(void) 427curdir_pop(void)
398{ 428{
399 struct prefix *pf; 429 struct prefix *pf;
400 430
401 pf = SLIST_FIRST(&curdirs); 431 pf = SLIST_FIRST(&curdirs);
402 SLIST_REMOVE_HEAD(&curdirs, pf_next); 432 SLIST_REMOVE_HEAD(&curdirs, pf_next);
403 if (SLIST_EMPTY(&curdirs)) 433 if (SLIST_EMPTY(&curdirs))
404 panic("curdirs is empty"); 434 panic("curdirs is empty");
405 /* LINTED cast away const (pf_prefix is malloc'd for curdirs) */ 435 /* LINTED cast away const (pf_prefix is malloc'd for curdirs) */
406 free((void *)__UNCONST(pf->pf_prefix)); 436 free((void *)__UNCONST(pf->pf_prefix));
407 free(pf); 437 free(pf);
408} 438}
409 439
410/* 440/*
411 * Open the "main" file (conffile). 441 * Open the "main" file (conffile).
412 */ 442 */
413int 443int
414firstfile(const char *fname) 444firstfile(const char *fname)
415{ 445{
416 446
417#if defined(__NetBSD__) 447#if defined(__NetBSD__)
418 if ((yyin = fopen(fname, "rf")) == NULL) 448 if ((yyin = fopen(fname, "rf")) == NULL)
419#else 449#else
420 if ((yyin = fopen(fname, "r")) == NULL) 450 if ((yyin = fopen(fname, "r")) == NULL)
421#endif 451#endif
422 return (-1); 452 return (-1);
423 453
424 if (curdir_push(fname) == -1) 454 if (curdir_push(fname) == -1)
425 return (-1); 455 return (-1);
426 456
427 yyfile = conffile = fname; 457 yyfile = conffile = fname;
428 yyline = 1; 458 yyline = 1;
429 return (0); 459 return (0);
430} 460}
431 461
432/* 462/*
433 * Add a "package" to the configuration. This is essentially 463 * Add a "package" to the configuration. This is essentially
434 * syntactic sugar around the sequence: 464 * syntactic sugar around the sequence:
435 * 465 *
436 * prefix ../some/directory 466 * prefix ../some/directory
437 * include "files.package" 467 * include "files.package"
438 * prefix 468 * prefix
439 */ 469 */
440void 470void
441package(const char *fname) 471package(const char *fname)
442{ 472{
443 char *fname1 = estrdup(fname); 473 char *fname1 = estrdup(fname);
444 char *fname2 = estrdup(fname); 474 char *fname2 = estrdup(fname);
445 char *dir = dirname(fname1); 475 char *dir = dirname(fname1);
446 char *file = basename(fname2); 476 char *file = basename(fname2);
447 477
448 /* 478 /*
449 * Push the prefix on to the prefix stack and process the include 479 * Push the prefix on to the prefix stack and process the include
450 * file. When we reach the end of the include file, inserting 480 * file. When we reach the end of the include file, inserting
451 * the PREFIX token into the input stream will pop the prefix off 481 * the PREFIX token into the input stream will pop the prefix off
452 * of the prefix stack. 482 * of the prefix stack.
453 */ 483 */
454 prefix_push(dir); 484 prefix_push(dir);
455 (void) include(file, PREFIX, 0, 1); 485 (void) include(file, PREFIX, 0, 1);
456 486
457 free(fname1); 487 free(fname1);
458 free(fname2); 488 free(fname2);
459} 489}
460 490
461int includedepth; 491int includedepth;
462 492
463/* 493/*
464 * Open the named file for inclusion at the current point. Returns 0 on 494 * Open the named file for inclusion at the current point. Returns 0 on
465 * success (file opened and previous state pushed), nonzero on failure 495 * success (file opened and previous state pushed), nonzero on failure
466 * (fopen failed, complaint made). The `ateof' parameter controls the 496 * (fopen failed, complaint made). The `ateof' parameter controls the
467 * token to be inserted at the end of the include file (i.e. ENDFILE). 497 * token to be inserted at the end of the include file (i.e. ENDFILE).
468 * If ateof == 0 then nothing is inserted. 498 * If ateof == 0 then nothing is inserted.
469 */ 499 */
470int 500int
471include(const char *fname, int ateof, int conditional, int direct) 501include(const char *fname, int ateof, int conditional, int direct)
472{ 502{
473 FILE *fp; 503 FILE *fp;
474 struct incl *in; 504 struct incl *in;
475 char *s; 505 char *s;
476 static int havedirs; 506 static int havedirs;
477 extern int vflag; 507 extern int vflag;
478 508
479 if (havedirs == 0) { 509 if (havedirs == 0) {
480 havedirs = 1; 510 havedirs = 1;
481 setupdirs(); 511 setupdirs();
482 } 512 }
483 513
484 if (fname[0] == '/') 514 if (fname[0] == '/')
485 s = estrdup(fname); 515 s = estrdup(fname);
486 else if (fname[0] == '.' && fname[1] == '/') { 516 else if (fname[0] == '.' && fname[1] == '/') {
487 struct prefix *pf = SLIST_FIRST(&curdirs); 517 struct prefix *pf = SLIST_FIRST(&curdirs);
488 easprintf(&s, "%s/%s", pf->pf_prefix, fname + 2); 518 easprintf(&s, "%s/%s", pf->pf_prefix, fname + 2);
489 } else 519 } else
490 s = sourcepath(fname); 520 s = sourcepath(fname);
491 if ((fp = fopen(s, "r")) == NULL) { 521 if ((fp = fopen(s, "r")) == NULL) {
492 if (conditional == 0) 522 if (conditional == 0)
493 cfgerror("cannot open %s for reading: %s", s, 523 cfgerror("cannot open %s for reading: %s", s,
494 strerror(errno)); 524 strerror(errno));
495 else if (vflag) 525 else if (vflag)
496 cfgwarn("cannot open conditional include file %s: %s", 526 cfgwarn("cannot open conditional include file %s: %s",
497 s, strerror(errno)); 527 s, strerror(errno));
498 free(s); 528 free(s);
499 return (-1); 529 return (-1);
500 } 530 }
501 if (curdir_push(s) == -1) { 531 if (curdir_push(s) == -1) {
502 cfgerror("cannot record current working directory for %s", s); 532 cfgerror("cannot record current working directory for %s", s);
503 fclose(fp); 533 fclose(fp);
504 free(s); 534 free(s);
505 return (-1); 535 return (-1);
506 } 536 }
507 in = ecalloc(1, sizeof *in); 537 in = ecalloc(1, sizeof *in);
508 in->in_prev = incl; 538 in->in_prev = incl;
509 in->in_buf = YY_CURRENT_BUFFER; 539 in->in_buf = YY_CURRENT_BUFFER;
510 in->in_where.w_srcfile = yyfile; 540 in->in_where.w_srcfile = yyfile;
511 in->in_where.w_srcline = (u_short)yyline; 541 in->in_where.w_srcline = (u_short)yyline;
512 in->in_ateof = ateof; 542 in->in_ateof = ateof;
513 in->in_interesting = interesting; 543 in->in_interesting = interesting;
514 in->in_ifdefstate = ifdefstate; 544 in->in_ifdefstate = ifdefstate;
515 in->in_ifdefshift = ifdefshift; 545 in->in_ifdefshift = ifdefshift;
516 interesting = direct & interesting; 546 interesting = direct & interesting;
517 if (interesting) 547 if (interesting)
518 logconfig_include(fp, fname); 548 logconfig_include(fp, fname);
519 incl = in; 549 incl = in;
520 CFGDBG(1, "include `%s' from `%s' line %d", fname, yyfile, yyline); 550 CFGDBG(1, "include `%s' from `%s' line %d", fname, yyfile, yyline);
521 yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); 551 yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
522 yyfile = intern(s); 552 yyfile = intern(s);
523 yyline = 1; 553 yyline = 1;
524 free(s); 554 free(s);
525 includedepth++; 555 includedepth++;
526 return (0); 556 return (0);
527} 557}
528 558
529/* 559/*
530 * Extract the pathname from a include/cinclude/package into curinclpath 560 * Extract the pathname from a include/cinclude/package into curinclpath
531 */ 561 */
532static int 562static int
533getincludepath(void) 563getincludepath(void)
534{ 564{
535 const char *p = yytext; 565 const char *p = yytext;
536 ptrdiff_t len; 566 ptrdiff_t len;
537 const char *e; 567 const char *e;
538 568
539 while (*p && isascii((unsigned int)*p) && !isspace((unsigned int)*p)) 569 while (*p && isascii((unsigned int)*p) && !isspace((unsigned int)*p))
540 p++; 570 p++;
541 while (*p && isascii((unsigned int)*p) && isspace((unsigned int)*p)) 571 while (*p && isascii((unsigned int)*p) && isspace((unsigned int)*p))
542 p++; 572 p++;
543 if (!*p) 573 if (!*p)
544 return 0; 574 return 0;
545 if (*p == '"') { 575 if (*p == '"') {
546 p++; 576 p++;
547 e = strchr(p, '"'); 577 e = strchr(p, '"');
548 if (!e) return 0; 578 if (!e) return 0;
549 } else { 579 } else {
550 e = p; 580 e = p;
551 while (*e && isascii((unsigned int)*e) 581 while (*e && isascii((unsigned int)*e)
552 && !isspace((unsigned int)*e)) 582 && !isspace((unsigned int)*e))
553 e++; 583 e++;
554 } 584 }
555 585
556 len = e-p; 586 len = e-p;
557 if (len > (ptrdiff_t)sizeof(curinclpath)-1) 587 if (len > (ptrdiff_t)sizeof(curinclpath)-1)
558 len = sizeof(curinclpath)-1; 588 len = sizeof(curinclpath)-1;
559 strncpy(curinclpath, p, sizeof(curinclpath)); 589 strncpy(curinclpath, p, sizeof(curinclpath));
560 curinclpath[len] = '\0'; 590 curinclpath[len] = '\0';
561 591
562 return 1; 592 return 1;
563} 593}
564 594
565/* 595/*
566 * Terminate the most recent inclusion. 596 * Terminate the most recent inclusion.
567 */ 597 */
568static int 598static int
569endinclude(void) 599endinclude(void)
570{ 600{
571 struct incl *in; 601 struct incl *in;
572 int ateof; 602 int ateof;
573 603
574 curdir_pop(); 604 curdir_pop();
575 if ((in = incl) == NULL) 605 if ((in = incl) == NULL)
576 panic("endinclude"); 606 panic("endinclude");
577 incl = in->in_prev; 607 incl = in->in_prev;
578 lastfile = yyfile; 608 lastfile = yyfile;
579 yy_delete_buffer(YY_CURRENT_BUFFER); 609 yy_delete_buffer(YY_CURRENT_BUFFER);
580 (void)fclose(yyin); 610 (void)fclose(yyin);
581 yy_switch_to_buffer(in->in_buf); 611 yy_switch_to_buffer(in->in_buf);
582 yyfile = in->in_where.w_srcfile; 612 yyfile = in->in_where.w_srcfile;
583 yyline = in->in_where.w_srcline; 613 yyline = in->in_where.w_srcline;
584 ateof = in->in_ateof; 614 ateof = in->in_ateof;
585 interesting = in->in_interesting; 615 interesting = in->in_interesting;
586 ifdefstate = in->in_ifdefstate; 616 ifdefstate = in->in_ifdefstate;
587 ifdefshift = in->in_ifdefshift; 617 ifdefshift = in->in_ifdefshift;
588 free(in); 618 free(in);
589 619
590 includedepth--; 620 includedepth--;
591 621
592 return (ateof); 622 return (ateof);
593} 623}
594 624
595/* 625/*
596 * Return the current line number. If yacc has looked ahead and caused 626 * Return the current line number. If yacc has looked ahead and caused
597 * us to consume a newline, we have to subtract one. yychar is yacc's 627 * us to consume a newline, we have to subtract one. yychar is yacc's
598 * token lookahead, so we can tell. 628 * token lookahead, so we can tell.
599 */ 629 */
600u_short 630u_short
601currentline(void) 631currentline(void)
602{ 632{
603 extern int yychar; 633 extern int yychar;
604 634
605 return (u_short)(yyline - (yychar == '\n')); 635 return (u_short)(yyline - (yychar == '\n'));
606} 636}
607 637
608static int 638static int
609getcurifdef(void) 639getcurifdef(void)
610{ 640{
611 char *p = yytext, *q; 641 char *p = yytext, *q;
612 642
613 while (*p && isascii((unsigned int)*p) && !isspace((unsigned int)*p)) 643 while (*p && isascii((unsigned int)*p) && !isspace((unsigned int)*p))
614 p++; 644 p++;
615 while (*p && isascii((unsigned int)*p) && isspace((unsigned int)*p)) 645 while (*p && isascii((unsigned int)*p) && isspace((unsigned int)*p))
616 p++; 646 p++;
617 q = p; 647 q = p;
618 while (*q && isascii((unsigned int)*q) && !isspace((unsigned int)*q)) 648 while (*q && isascii((unsigned int)*q) && !isspace((unsigned int)*q))
619 q++; 649 q++;
620 *q = '\0'; 650 *q = '\0';
621 651
622 return ht_lookup(attrtab, intern(p)) != NULL; 652 return ht_lookup(attrtab, intern(p)) != NULL;
623} 653}