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