Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make(1): add more detailed debug logging for va...



details:   https://anonhg.NetBSD.org/src/rev/f45196a14467
branches:  trunk
changeset: 937073:f45196a14467
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sat Aug 08 13:50:23 2020 +0000

description:
make(1): add more detailed debug logging for variable modifiers

Before a modifier is applied to a variable, it is not yet parsed,
therefore it is only possible to log a rough estimate of the modifier.
But after applying it, the parsing position has advanced, and the full
modifier can be logged.

In addition, to fully understand how the modifiers work, it's not enough
to just know the variable names and values, there are also some flags
that influence how the modifiers behave.  The most influential is
VARE_WANTRES.

Thanks to sjg for the extensive review and valuable feedback on the
first drafts.

diffstat:

 usr.bin/make/Makefile                |   4 +-
 usr.bin/make/enum.c                  |  83 ++++++++++++++++++++++++++++++++
 usr.bin/make/enum.h                  |  93 ++++++++++++++++++++++++++++++++++++
 usr.bin/make/unit-tests/counter.exp  |  60 +++++++++++-----------
 usr.bin/make/unit-tests/vardebug.exp |  56 ++++++++++----------
 usr.bin/make/var.c                   |  53 ++++++++++++++++++-
 6 files changed, 285 insertions(+), 64 deletions(-)

diffs (truncated from 509 to 300 lines):

diff -r 0228e149b305 -r f45196a14467 usr.bin/make/Makefile
--- a/usr.bin/make/Makefile     Sat Aug 08 13:31:24 2020 +0000
+++ b/usr.bin/make/Makefile     Sat Aug 08 13:50:23 2020 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.82 2020/08/07 05:13:04 rillig Exp $
+#      $NetBSD: Makefile,v 1.83 2020/08/08 13:50:23 rillig Exp $
 #      @(#)Makefile    5.2 (Berkeley) 12/28/90
 
 PROG=  make
@@ -7,6 +7,7 @@
 SRCS+=  compat.c
 SRCS+=  cond.c
 SRCS+=  dir.c
+SRCS+=  enum.c
 SRCS+=  for.c
 SRCS+=  hash.c
 SRCS+=  job.c
@@ -26,6 +27,7 @@
 HDRS=   buf.h
 HDRS+=  config.h
 HDRS+=  dir.h
+HDRS+=  enum.h
 HDRS+=  hash.h
 HDRS+=  job.h
 HDRS+=  lst.h
diff -r 0228e149b305 -r f45196a14467 usr.bin/make/enum.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/enum.c       Sat Aug 08 13:50:23 2020 +0000
@@ -0,0 +1,83 @@
+/*     $NetBSD: enum.c,v 1.1 2020/08/08 13:50:23 rillig Exp $  */
+
+/*
+ Copyright (c) 2020 Roland Illig <rillig%NetBSD.org@localhost>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: enum.c,v 1.1 2020/08/08 13:50:23 rillig Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: enum.c,v 1.1 2020/08/08 13:50:23 rillig Exp $");
+#endif
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "enum.h"
+
+/* Convert a bitset into a string representation showing the names of the
+ * individual bits, or optionally shortcuts for groups of bits. */
+const char *
+Enum_ToString(char *buf, size_t buf_size, int value,
+             const EnumToStringSpec *spec)
+{
+       const char *buf_start = buf;
+       const char *sep = "";
+       size_t sep_len = 0;
+
+       for (; spec->es_value != 0; spec++) {
+               size_t name_len;
+
+               if ((value & spec->es_value) != spec->es_value)
+                           continue;
+               value &= ~spec->es_value;
+
+               assert(buf_size >= sep_len + 1);
+               memcpy(buf, sep, sep_len);
+               buf += sep_len;
+               buf_size -= sep_len;
+
+               name_len = strlen(spec->es_name);
+               assert(buf_size >= name_len + 1);
+               memcpy(buf, spec->es_name, name_len);
+               buf += name_len;
+               buf_size -= name_len;
+
+               sep = ENUM__SEP;
+               sep_len = sizeof ENUM__SEP - 1;
+       }
+       assert(value == 0);
+
+       if (buf == buf_start)
+                   return "none";
+
+       assert(buf_size >= 1);
+       buf[0] = '\0';
+       return buf_start;
+}
diff -r 0228e149b305 -r f45196a14467 usr.bin/make/enum.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/enum.h       Sat Aug 08 13:50:23 2020 +0000
@@ -0,0 +1,93 @@
+/*     $NetBSD: enum.h,v 1.1 2020/08/08 13:50:23 rillig Exp $  */
+
+/*
+ Copyright (c) 2020 Roland Illig <rillig%NetBSD.org@localhost>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAKE_ENUM_H
+#define MAKE_ENUM_H
+
+/*
+ * Generate string representation for bitmasks.
+ */
+
+typedef struct {
+       int es_value;
+       const char *es_name;
+} EnumToStringSpec;
+
+const char *Enum_ToString(char *, size_t, int, const EnumToStringSpec *);
+
+#define ENUM__SEP "|"
+
+#define ENUM__JOIN_1(v1) \
+       #v1
+#define ENUM__JOIN_2(v1, v2) \
+       #v1 ENUM__SEP ENUM__JOIN_1(v2)
+#define ENUM__JOIN_3(v1, v2, v3) \
+       #v1 ENUM__SEP ENUM__JOIN_2(v2, v3)
+#define ENUM__JOIN_4(v1, v2, v3, v4) \
+       #v1 ENUM__SEP ENUM__JOIN_3(v2, v3, v4)
+#define ENUM__JOIN_5(v1, v2, v3, v4, v5) \
+       #v1 ENUM__SEP ENUM__JOIN_4(v2, v3, v4, v5)
+#define ENUM__JOIN_6(v1, v2, v3, v4, v5, v6) \
+       #v1 ENUM__SEP ENUM__JOIN_5(v2, v3, v4, v5, v6)
+#define ENUM__JOIN_7(v1, v2, v3, v4, v5, v6, v7) \
+       #v1 ENUM__SEP ENUM__JOIN_6(v2, v3, v4, v5, v6, v7)
+
+#define ENUM__RTTI(typnam, specs, joined) \
+       static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
+       static const size_t typnam ## _ ## ToStringSize = sizeof joined
+
+#define ENUM__SPEC(v) { v, #v }
+
+#define ENUM__SPEC_3(v1, v2, v3) { \
+       ENUM__SPEC(v1), \
+       ENUM__SPEC(v2), \
+       ENUM__SPEC(v3), \
+       { 0, "" } }
+
+#define ENUM__SPEC_7(v1, v2, v3, v4, v5, v6, v7) { \
+       ENUM__SPEC(v1), \
+       ENUM__SPEC(v2), \
+       ENUM__SPEC(v3), \
+       ENUM__SPEC(v4), \
+       ENUM__SPEC(v5), \
+       ENUM__SPEC(v6), \
+       ENUM__SPEC(v7), \
+       { 0, "" } }
+
+#define ENUM_RTTI_3(typnam, v1, v2, v3) \
+       ENUM__RTTI(typnam, \
+                 ENUM__SPEC_3(v1, v2, v3), \
+                 ENUM__JOIN_3(v1, v2, v3))
+
+#define ENUM_RTTI_7(typnam, v1, v2, v3, v4, v5, v6, v7) \
+       ENUM__RTTI(typnam, \
+                 ENUM__SPEC_7(v1, v2, v3, v4, v5, v6, v7), \
+                 ENUM__JOIN_7(v1, v2, v3, v4, v5, v6, v7))
+
+#endif
diff -r 0228e149b305 -r f45196a14467 usr.bin/make/unit-tests/counter.exp
--- a/usr.bin/make/unit-tests/counter.exp       Sat Aug 08 13:31:24 2020 +0000
+++ b/usr.bin/make/unit-tests/counter.exp       Sat Aug 08 13:50:23 2020 +0000
@@ -2,64 +2,64 @@
 Global:COUNTER = 
 Global:NEXT = ${COUNTER::=${COUNTER} a}${COUNTER:[#]}
 Global:A = 
-Applying[COUNTER] :: to ""
+Applying ${COUNTER::...} to "" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Modifier part: " a"
 Global:COUNTER =  a
-Result[COUNTER] of :: is ""
-Applying[COUNTER] :[ to " a"
+Result of ${COUNTER::=${COUNTER} a} is "" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
+Applying ${COUNTER:[...} to " a" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Modifier part: "#"
-Result[COUNTER] of :[ is "1"
+Result of ${COUNTER:[#]} is "1" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Global:A = ${COUNTER::= a a}1
 Global:B = 
-Applying[COUNTER] :: to " a"
+Applying ${COUNTER::...} to " a" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Modifier part: " a a"
 Global:COUNTER =  a a
-Result[COUNTER] of :: is ""
-Applying[COUNTER] :[ to " a a"
+Result of ${COUNTER::=${COUNTER} a} is "" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
+Applying ${COUNTER:[...} to " a a" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Modifier part: "#"
-Result[COUNTER] of :[ is "2"
+Result of ${COUNTER:[#]} is "2" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Global:B = ${COUNTER::= a a a}2
 Global:C = 
-Applying[COUNTER] :: to " a a"
+Applying ${COUNTER::...} to " a a" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Modifier part: " a a a"
 Global:COUNTER =  a a a
-Result[COUNTER] of :: is ""
-Applying[COUNTER] :[ to " a a a"
+Result of ${COUNTER::=${COUNTER} a} is "" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
+Applying ${COUNTER:[...} to " a a a" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Modifier part: "#"
-Result[COUNTER] of :[ is "3"
+Result of ${COUNTER:[#]} is "3" (eflags = VARE_WANTRES|VARE_ASSIGN, vflags = none)
 Global:C = ${COUNTER::= a a a a}3
 Global:RELEVANT = no
 Global:RELEVANT = yes (run-time part)
-Result[RELEVANT] of :: is ""
-Applying[COUNTER] :: to " a a a"
+Result of ${RELEVANT::=yes (run-time part)} is "" (eflags = VARE_WANTRES, vflags = none)
+Applying ${COUNTER::...} to " a a a" (eflags = VARE_WANTRES, vflags = none)
 Modifier part: " a a"
 Global:COUNTER =  a a
-Result[COUNTER] of :: is ""
-Applying[A] :Q to "1"
+Result of ${COUNTER::= a a} is "" (eflags = VARE_WANTRES, vflags = none)
+Applying ${A:Q} to "1" (eflags = VARE_WANTRES, vflags = none)
 QuoteMeta: [1]
-Result[A] of :Q is "1"
-Applying[COUNTER] :: to " a a"
+Result of ${A:Q} is "1" (eflags = VARE_WANTRES, vflags = none)
+Applying ${COUNTER::...} to " a a" (eflags = VARE_WANTRES, vflags = none)
 Modifier part: " a a a"
 Global:COUNTER =  a a a
-Result[COUNTER] of :: is ""
-Applying[B] :Q to "2"
+Result of ${COUNTER::= a a a} is "" (eflags = VARE_WANTRES, vflags = none)
+Applying ${B:Q} to "2" (eflags = VARE_WANTRES, vflags = none)
 QuoteMeta: [2]
-Result[B] of :Q is "2"
-Applying[COUNTER] :: to " a a a"
+Result of ${B:Q} is "2" (eflags = VARE_WANTRES, vflags = none)
+Applying ${COUNTER::...} to " a a a" (eflags = VARE_WANTRES, vflags = none)
 Modifier part: " a a a a"
 Global:COUNTER =  a a a a
-Result[COUNTER] of :: is ""
-Applying[C] :Q to "3"
+Result of ${COUNTER::= a a a a} is "" (eflags = VARE_WANTRES, vflags = none)
+Applying ${C:Q} to "3" (eflags = VARE_WANTRES, vflags = none)
 QuoteMeta: [3]
-Result[C] of :Q is "3"
-Applying[COUNTER] :[ to " a a a a"
+Result of ${C:Q} is "3" (eflags = VARE_WANTRES, vflags = none)
+Applying ${COUNTER:[...} to " a a a a" (eflags = VARE_WANTRES, vflags = none)
 Modifier part: "#"
-Result[COUNTER] of :[ is "4"
-Applying[COUNTER] :Q to "4"
+Result of ${COUNTER:[#]} is "4" (eflags = VARE_WANTRES, vflags = none)
+Applying ${COUNTER:Q} to "4" (eflags = VARE_WANTRES, vflags = none)
 QuoteMeta: [4]
-Result[COUNTER] of :Q is "4"



Home | Main Index | Thread Index | Old Index