Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/config PR/55057: Paul Goyette: Don't use % 6 arithme...
details: https://anonhg.NetBSD.org/src/rev/896fa674ac7c
branches: trunk
changeset: 1007996:896fa674ac7c
user: christos <christos%NetBSD.org@localhost>
date: Sat Mar 07 22:35:16 2020 +0000
description:
PR/55057: Paul Goyette: Don't use % 6 arithmetic that hurts the brain for
the ifdef state machine, use bits and shifts instead. Also don't forget to
restore the state once an include file ends.
diffstat:
usr.bin/config/scan.l | 124 +++++++++++++++++++++----------------------------
1 files changed, 54 insertions(+), 70 deletions(-)
diffs (234 lines):
diff -r 7b7c295e153c -r 896fa674ac7c usr.bin/config/scan.l
--- a/usr.bin/config/scan.l Sat Mar 07 22:26:16 2020 +0000
+++ b/usr.bin/config/scan.l Sat Mar 07 22:35:16 2020 +0000
@@ -1,5 +1,5 @@
%{
-/* $NetBSD: scan.l,v 1.27 2020/03/07 19:26:13 christos Exp $ */
+/* $NetBSD: scan.l,v 1.28 2020/03/07 22:35:16 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: scan.l,v 1.27 2020/03/07 19:26:13 christos Exp $");
+__RCSID("$NetBSD: scan.l,v 1.28 2020/03/07 22:35:16 christos Exp $");
#include <sys/param.h>
#include <errno.h>
@@ -62,34 +62,23 @@
const char *yyfile;
const char *lastfile;
char curinclpath[PATH_MAX];
-int ifdefstate = -1;
-int st;
-#define IDS_PARENT_DISABLED \
- ((ifdefstate > 6) && ((((ifdefstate/6)-1) & 1) == 1))
-#define IDS_MAX_DEPTH 362797056 /* 6^11 */
-/* States for ifdefstate:
-
- 0 -> matched ifdef
- 1 -> unmatched ifdef
- 2 -> matched elifdef
- 3 -> unmatched elifdef
- 4 -> matched else
- 5 -> unmatched else
+uint64_t ifdefstate;
+int ifdefshift = -1;
- Upon "ifdef", add one and multiply by 6.
- Upon "endif", divide by 6, remove 1.
+/*
+ * The state is represented by 3 bits.
+ */
+#define IDS_MATCH 1ll
+#define IDS_ELIF 2ll
+#define IDS_ELSE 4ll
- ifdef -> MATCH => continue
- MISMATCH => set to 1
- elifdef -> if (!1) -> MISMATCH
- MATCH => set to 2
- MISMATCH => if (2 || 3) set to 3, else set to 1
- else -> if (1) -> MATCH
- MATCH => set to 4
- MISMATCH => set to 5
+#define IDS_BITS 7
+#define IDS_SHIFT 3
- in each case, if parent & 1 == 1, MISMATCH
-*/
+#define IDS_ISMATCH(st) (((st) & IDS_MATCH) != 0)
+#define IDS_PARENT_DISABLED \
+ (ifdefshift > 0 && !IDS_ISMATCH(ifdefstate >> IDS_SHIFT))
+#define IDS_MAX_DEPTH 21 /* 64 / 3 */
/*
* Data for returning to previous files from include files.
@@ -100,7 +89,8 @@
struct where in_where;
int in_ateof; /* token to insert at EOF */
int in_interesting; /* previous value for "interesting" */
- int in_ifdefstate; /* conditional level */
+ uint64_t in_ifdefstate; /* conditional level */
+ int in_ifdefshift; /* conditional level */
};
static struct incl *incl;
static int endinclude(void);
@@ -180,97 +170,88 @@
:= return COLONEQ;
<*>ifdef[ \t]+{WORD}{RESTOFLINE} {
- ifdefstate = (ifdefstate + 1) * 6;
- if (ifdefstate >= IDS_MAX_DEPTH) {
+ ifdefstate <<= IDS_SHIFT;
+ if (++ifdefshift >= IDS_MAX_DEPTH) {
yyerror("too many levels of conditional");
}
- if (!IDS_PARENT_DISABLED && getcurifdef()) {
- BEGIN(INITIAL);
+ if (IDS_PARENT_DISABLED || !getcurifdef()) {
+ BEGIN(IGNORED);
} else {
- ifdefstate++;
- BEGIN(IGNORED);
+ ifdefstate |= IDS_MATCH;
+ BEGIN(INITIAL);
}
yyline++;
}
<*>ifndef[ \t]+{WORD}{RESTOFLINE} {
- ifdefstate = (ifdefstate + 1) * 6;
- if (ifdefstate >= IDS_MAX_DEPTH) {
+ ifdefstate <<= IDS_SHIFT;
+ if (++ifdefshift >= IDS_MAX_DEPTH) {
yyerror("too many levels of conditional");
}
- if (!IDS_PARENT_DISABLED && !getcurifdef()) {
- BEGIN(INITIAL);
+ if (IDS_PARENT_DISABLED || getcurifdef()) {
+ BEGIN(IGNORED);
} else {
- ifdefstate++;
- BEGIN(IGNORED);
+ ifdefstate |= IDS_MATCH;
+ BEGIN(INITIAL);
}
yyline++;
}
<*>elifdef[ \t]+{WORD}{RESTOFLINE} {
- st = ifdefstate % 6;
- if (ifdefstate < 0 || st > 3) {
+ int st = ifdefstate & IDS_BITS;
+ if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
yyerror("mismatched elifdef");
}
- if (IDS_PARENT_DISABLED ||
- st != 1 || !getcurifdef()) {
- if (st == 2 || st == 3) {
- ifdefstate += 3 - st;
- } else {
- ifdefstate += 1 - st;
- }
+ if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || !getcurifdef()) {
BEGIN(IGNORED);
} else {
- ifdefstate++;
+ ifdefstate |= IDS_MATCH;
BEGIN(INITIAL);
}
+ ifdefstate |= IDS_ELIF;
yyline++;
}
<*>elifndef[ \t]+{WORD}{RESTOFLINE} {
- st = ifdefstate % 6;
- if (ifdefstate < 0 || st > 3) {
+ int st = ifdefstate & IDS_BITS;
+ if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
yyerror("mismatched elifndef");
}
- if (IDS_PARENT_DISABLED ||
- st != 1 || getcurifdef()) {
- if (st == 2 || st == 3) {
- ifdefstate += 3 - st;
- } else {
- ifdefstate += 1 - st;
- }
+ if (IDS_PARENT_DISABLED || IDS_ISMATCH(st) || getcurifdef()) {
BEGIN(IGNORED);
} else {
- ifdefstate++;
+ ifdefstate |= IDS_MATCH;
BEGIN(INITIAL);
}
+ ifdefstate |= IDS_ELIF;
yyline++;
}
<*>else{RESTOFLINE} {
- st = ifdefstate % 6;
- if (ifdefstate < 0 || st > 3) {
+ int st = ifdefstate & IDS_BITS;
+ if (ifdefshift == -1 || (st & IDS_ELSE) != 0) {
yyerror("mismatched else");
}
- if (!IDS_PARENT_DISABLED && (st == 1)) {
- ifdefstate += 3;
- BEGIN(INITIAL);
+ if (IDS_PARENT_DISABLED || IDS_ISMATCH(st)) {
+ BEGIN(IGNORED);
} else {
- ifdefstate += 5 - st;
- BEGIN(IGNORED);
+ ifdefstate |= IDS_MATCH;
+ BEGIN(INITIAL);
}
+ ifdefstate |= IDS_ELSE;
yyline++;
}
<*>endif{RESTOFLINE} {
- if (ifdefstate < 0) {
+ if (ifdefshift == -1) {
yyerror("mismatched endif");
}
if (!IDS_PARENT_DISABLED) {
BEGIN(INITIAL);
}
- ifdefstate = (ifdefstate/6) - 1;
+ ifdefshift--;
+ ifdefstate >>= IDS_SHIFT;
yyline++;
}
@@ -369,7 +350,7 @@
[ \t]+ { /* ignored (white space) */; }
. { return yytext[0]; }
<*><<EOF>> {
- if (ifdefstate > (incl == NULL ? -1 : incl->in_ifdefstate)) {
+ if (ifdefshift > (incl == NULL ? -1 : incl->in_ifdefshift)) {
yyerror("reached EOF while looking for endif");
}
if (incl == NULL)
@@ -530,6 +511,7 @@
in->in_ateof = ateof;
in->in_interesting = interesting;
in->in_ifdefstate = ifdefstate;
+ in->in_ifdefshift = ifdefshift;
interesting = direct & interesting;
if (interesting)
logconfig_include(fp, fname);
@@ -600,6 +582,8 @@
yyline = in->in_where.w_srcline;
ateof = in->in_ateof;
interesting = in->in_interesting;
+ ifdefstate = in->in_ifdefstate;
+ ifdefshift = in->in_ifdefshift;
free(in);
includedepth--;
Home |
Main Index |
Thread Index |
Old Index