Mon Mar 9 17:27:03 2020 UTC ()
Add an enabled bit to keep track of the parent state (if we are ignoring
or parsing). Idea from uwe.


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

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

--- src/usr.bin/config/scan.l 2020/03/08 17:38:37 1.30
+++ src/usr.bin/config/scan.l 2020/03/09 17:27:03 1.31
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1%{ 1%{
2/* $NetBSD: scan.l,v 1.30 2020/03/08 17:38:37 christos Exp $ */ 2/* $NetBSD: scan.l,v 1.31 2020/03/09 17:27:03 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.
@@ -32,80 +32,82 @@ @@ -32,80 +32,82 @@
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.30 2020/03/08 17:38:37 christos Exp $"); 45__RCSID("$NetBSD: scan.l,v 1.31 2020/03/09 17:27:03 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_ENABLED 1ll
72#define IDS_ELIF 2ll 72#define IDS_MATCH 2ll
73#define IDS_ELSE 4ll 73#define IDS_ELIF 4ll
74 74#define IDS_ELSE 8ll
75#define IDS_BITS 7 75
76#define IDS_SHIFT 3 76#define IDS_BITS 0xf
77 77#define IDS_SHIFT 4
78#define IDS_ISMATCH(st) (((st) & IDS_MATCH) != 0) 78
79#define IDS_PARENT_DISABLED \ 79#define IDS_ISMATCH(st) (((st) & IDS_MATCH) != 0)
80 (ifdefshift > 0 && !IDS_ISMATCH(ifdefstate >> IDS_SHIFT)) 80#define IDS_ISENABLED(st) (((st) & IDS_ENABLED) != 0)
81#define IDS_MAX_DEPTH 21 /* 64 / 3 */ 81#define IDS_PARENT_DISABLED \
 82 (ifdefshift > 0 && !IDS_ISENABLED(ifdefstate >> IDS_SHIFT))
 83#define IDS_MAX_DEPTH 16 /* 64 / 4 */
82 84
83#ifdef IDS_DEBUG 85#ifdef IDS_DEBUG
84# define IDS_PRINT(s, st, x) \ 86# define IDS_PRINT(s, st, x) \
85 do { \ 87 do { \
86 for (int i = 0; i < ifdefshift + 1; i++) \ 88 for (int i = 0; i < ifdefshift + 1; i++) \
87 fprintf(stderr, " "); \ 89 fprintf(stderr, " "); \
88 printf("%s%s [%d,%d,%d] %#" PRIx64 "\n", x, # s, \ 90 printf("%s%s [%d,%d,%d] %#" PRIx64 "\n", x, # s, \
89 IDS_PARENT_DISABLED, IDS_ISMATCH(st), getcurifdef(), \ 91 IDS_PARENT_DISABLED, IDS_ISMATCH(st), getcurifdef(), \
90 ifdefstate); \ 92 ifdefstate); \
91 } while (/*CONSTCOND*/0) 93 } while (/*CONSTCOND*/0)
92#else 94#else
93# define IDS_PRINT(s, st, x) __nothing 95# define IDS_PRINT(s, st, x) ((void)0)
94#endif 96#endif
95 97
96#define IDS_ENTER(s, st) \ 98#define IDS_ENTER(s, st) \
97 IDS_PRINT(s, st, ">") 99 IDS_PRINT(s, st, ">")
98#define IDS_EXIT(s, st) \ 100#define IDS_EXIT(s, st) \
99 IDS_PRINT(s, st, "<") 101 IDS_PRINT(s, st, "<")
100 102
101/* 103/*
102 * Data for returning to previous files from include files. 104 * Data for returning to previous files from include files.
103 */ 105 */
104struct incl { 106struct incl {
105 struct incl *in_prev; /* previous includes in effect, if any */ 107 struct incl *in_prev; /* previous includes in effect, if any */
106 YY_BUFFER_STATE in_buf; /* previous lex state */ 108 YY_BUFFER_STATE in_buf; /* previous lex state */
107 struct where in_where; 109 struct where in_where;
108 int in_ateof; /* token to insert at EOF */ 110 int in_ateof; /* token to insert at EOF */
109 int in_interesting; /* previous value for "interesting" */ 111 int in_interesting; /* previous value for "interesting" */
110 uint64_t in_ifdefstate; /* conditional level */ 112 uint64_t in_ifdefstate; /* conditional level */
111 int in_ifdefshift; /* conditional level */ 113 int in_ifdefshift; /* conditional level */
@@ -185,96 +187,101 @@ vector return VECTOR; @@ -185,96 +187,101 @@ vector return VECTOR;
185version return VERSION; 187version return VERSION;
186with return WITH; 188with return WITH;
187 189
188\+= return PLUSEQ; 190\+= return PLUSEQ;
189:= return COLONEQ; 191:= return COLONEQ;
190 192
191<*>{WS}ifdef[ \t]+{WORD}{RESTOFLINE} { 193<*>{WS}ifdef[ \t]+{WORD}{RESTOFLINE} {
192 ifdefstate <<= IDS_SHIFT; 194 ifdefstate <<= IDS_SHIFT;
193 if (++ifdefshift >= IDS_MAX_DEPTH) { 195 if (++ifdefshift >= IDS_MAX_DEPTH) {
194 yyerror("too many levels of conditional"); 196 yyerror("too many levels of conditional");
195 } 197 }
196 IDS_ENTER(ifdef, 0); 198 IDS_ENTER(ifdef, 0);
197 if (IDS_PARENT_DISABLED || !getcurifdef()) { 199 if (IDS_PARENT_DISABLED || !getcurifdef()) {
 200 ifdefstate &= (uint64_t)~IDS_ENABLED;
198 BEGIN(IGNORED); 201 BEGIN(IGNORED);
199 } else { 202 } else {
200 ifdefstate |= IDS_MATCH; 203 ifdefstate |= IDS_MATCH|IDS_ENABLED;
201 BEGIN(INITIAL); 204 BEGIN(INITIAL);
202 } 205 }
203 IDS_EXIT(ifdef, 0); 206 IDS_EXIT(ifdef, 0);
204 yyline++; 207 yyline++;
205 } 208 }
206 209
207<*>{WS}ifndef[ \t]+{WORD}{RESTOFLINE} { 210<*>{WS}ifndef[ \t]+{WORD}{RESTOFLINE} {
208 ifdefstate <<= IDS_SHIFT; 211 ifdefstate <<= IDS_SHIFT;
209 if (++ifdefshift >= IDS_MAX_DEPTH) { 212 if (++ifdefshift >= IDS_MAX_DEPTH) {
210 yyerror("too many levels of conditional"); 213 yyerror("too many levels of conditional");
211 } 214 }
212 IDS_ENTER(ifndef, 0); 215 IDS_ENTER(ifndef, 0);
213 if (IDS_PARENT_DISABLED || getcurifdef()) { 216 if (IDS_PARENT_DISABLED || getcurifdef()) {
 217 ifdefstate &= (uint64_t)~IDS_ENABLED;
214 BEGIN(IGNORED); 218 BEGIN(IGNORED);
215 } else { 219 } else {
216 ifdefstate |= IDS_MATCH; 220 ifdefstate |= IDS_MATCH|IDS_ENABLED;
217 BEGIN(INITIAL); 221 BEGIN(INITIAL);
218 } 222 }
219 IDS_EXIT(ifndef, 0); 223 IDS_EXIT(ifndef, 0);
220 yyline++; 224 yyline++;
221 } 225 }
222 226
223 227
224<*>{WS}elifdef[ \t]+{WORD}{RESTOFLINE} { 228<*>{WS}elifdef[ \t]+{WORD}{RESTOFLINE} {
225 int st = ifdefstate & IDS_BITS; 229 int st = ifdefstate & IDS_BITS;
226 IDS_ENTER(elifdef, st); 230 IDS_ENTER(elifdef, st);
227 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { 231 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
228 yyerror("mismatched elifdef"); 232 yyerror("mismatched elifdef");
229 } 233 }
230 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || !getcurifdef()) { 234 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || !getcurifdef()) {
 235 ifdefstate &= (uint64_t)~IDS_ENABLED;
231 BEGIN(IGNORED); 236 BEGIN(IGNORED);
232 } else { 237 } else {
233 ifdefstate |= IDS_MATCH; 238 ifdefstate |= IDS_MATCH|IDS_ENABLED;
234 BEGIN(INITIAL); 239 BEGIN(INITIAL);
235 } 240 }
236 ifdefstate |= IDS_ELIF; 241 ifdefstate |= IDS_ELIF;
237 IDS_EXIT(elifdef, st); 242 IDS_EXIT(elifdef, st);
238 yyline++; 243 yyline++;
239 } 244 }
240 245
241<*>{WS}elifndef[ \t]+{WORD}{RESTOFLINE} { 246<*>{WS}elifndef[ \t]+{WORD}{RESTOFLINE} {
242 int st = ifdefstate & IDS_BITS; 247 int st = ifdefstate & IDS_BITS;
243 IDS_ENTER(elifndef, st); 248 IDS_ENTER(elifndef, st);
244 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { 249 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
245 yyerror("mismatched elifndef"); 250 yyerror("mismatched elifndef");
246 } 251 }
247 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || getcurifdef()) { 252 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || getcurifdef()) {
 253 ifdefstate &= (uint64_t)~IDS_ENABLED;
248 BEGIN(IGNORED); 254 BEGIN(IGNORED);
249 } else { 255 } else {
250 ifdefstate |= IDS_MATCH; 256 ifdefstate |= IDS_MATCH|IDS_ENABLED;
251 BEGIN(INITIAL); 257 BEGIN(INITIAL);
252 } 258 }
253 ifdefstate |= IDS_ELIF; 259 ifdefstate |= IDS_ELIF;
254 IDS_EXIT(elifndef, st); 260 IDS_EXIT(elifndef, st);
255 yyline++; 261 yyline++;
256 } 262 }
257 263
258<*>{WS}else{RESTOFLINE} { 264<*>{WS}else{RESTOFLINE} {
259 int st = ifdefstate & IDS_BITS; 265 int st = ifdefstate & IDS_BITS;
260 IDS_ENTER(else, st); 266 IDS_ENTER(else, st);
261 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) { 267 if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
262 yyerror("mismatched else"); 268 yyerror("mismatched else");
263 } 269 }
264 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st)) { 270 if (IDS_PARENT_DISABLED || IDS_ISMATCH(st)) {
 271 ifdefstate &= (uint64_t)~IDS_ENABLED;
265 BEGIN(IGNORED); 272 BEGIN(IGNORED);
266 } else { 273 } else {
267 ifdefstate |= IDS_MATCH; 274 ifdefstate |= IDS_MATCH|IDS_ENABLED;
268 BEGIN(INITIAL); 275 BEGIN(INITIAL);
269 } 276 }
270 ifdefstate |= IDS_ELSE; 277 ifdefstate |= IDS_ELSE;
271 IDS_ENTER(else, st); 278 IDS_ENTER(else, st);
272 yyline++; 279 yyline++;
273 } 280 }
274 281
275<*>{WS}endif{RESTOFLINE} { 282<*>{WS}endif{RESTOFLINE} {
276 IDS_ENTER(endif, 0); 283 IDS_ENTER(endif, 0);
277 if (ifdefshift == -1) { 284 if (ifdefshift == -1) {
278 yyerror("mismatched endif"); 285 yyerror("mismatched endif");
279 } 286 }
280 if (!IDS_PARENT_DISABLED) { 287 if (!IDS_PARENT_DISABLED) {