Module Name:    src
Committed By:   rillig
Date:           Tue Aug 25 16:27:24 UTC 2020

Modified Files:
        src/usr.bin/make: enum.h make.c var.c

Log Message:
make(1): distinguish enum flags and values in debugging mode

When printing an enum value in debugging mode, distinguish between
bitsets containing flags and ordinary enums that just contain different
values.

Make the macros in enum.h more uniform.  Provide a simple scheme for
defining the run-time type information of enums whose number of values
is a number with more than 2 bits set in the binary representation.
This case was not obvious before, and it was pure luck that the current
interesting enum types only had 3, 10 or 32 different values.

The type with the 32 different values actually only has 31 significant
bits since the enum constant OP_OPMASK is only used when querying the
enum, not for defining or describing the possible values.  For this
reason, it was unavoidable to refactor the rtti macros, to support even
this case.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/enum.h
cvs rdiff -u -r1.122 -r1.123 src/usr.bin/make/make.c
cvs rdiff -u -r1.470 -r1.471 src/usr.bin/make/var.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/enum.h
diff -u src/usr.bin/make/enum.h:1.7 src/usr.bin/make/enum.h:1.8
--- src/usr.bin/make/enum.h:1.7	Mon Aug 24 20:15:51 2020
+++ src/usr.bin/make/enum.h	Tue Aug 25 16:27:24 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: enum.h,v 1.7 2020/08/24 20:15:51 rillig Exp $	*/
+/*	$NetBSD: enum.h,v 1.8 2020/08/25 16:27:24 rillig Exp $	*/
 
 /*
  Copyright (c) 2020 Roland Illig <[email protected]>
@@ -44,36 +44,39 @@ typedef struct {
 const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
 const char *Enum_ValueToString(int, const EnumToStringSpec *);
 
+/* For Enum_FlagsToString, the separator between flags. */
 #define ENUM__SEP "|"
 
-#define ENUM__JOIN_1(v1) \
+/* Generate the string that joins all possible flags, to see how large the
+ * buffer must be. */
+#define ENUM__JOIN_STR_1(v1) \
 	#v1
-#define ENUM__JOIN_2(v1, v2) \
-	#v1 ENUM__SEP #v2
-#define ENUM__JOIN_4(v1, v2, v3, v4) \
-	ENUM__JOIN_2(v1, v2) ENUM__SEP ENUM__JOIN_2(v3, v4)
-#define ENUM__JOIN_8(v1, v2, v3, v4, v5, v6, v7, v8) \
-	ENUM__JOIN_4(v1, v2, v3, v4) ENUM__SEP ENUM__JOIN_4(v5, v6, v7, v8)
-#define ENUM__JOIN_16(v01, v02, v03, v04, v05, v06, v07, v08, \
-		      v09, v10, v11, v12, v13, v14, v15, v16) \
-	ENUM__JOIN_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \
-	ENUM__JOIN_8(v09, v10, v11, v12, v13, v14, v15, v16)
-#define ENUM__JOIN_32(v01, v02, v03, v04, v05, v06, v07, v08, \
-		      v09, v10, v11, v12, v13, v14, v15, v16, \
-		      v17, v18, v19, v20, v21, v22, v23, v24, \
-		      v25, v26, v27, v28, v29, v30, v31, v32) \
-	ENUM__JOIN_16(v01, v02, v03, v04, v05, v06, v07, v08, \
-		      v09, v10, v11, v12, v13, v14, v15, v16) ENUM__SEP \
-	ENUM__JOIN_16(v17, v18, v19, v20, v21, v22, v23, v24, \
-		      v25, v26, v27, v28, v29, v30, v31, v32)
-#define ENUM__JOIN(part1, part2) \
-	part1 ENUM__SEP part2
-
-#define ENUM__RTTI(typnam, specs, joined) \
-	static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
-	enum { typnam ## _ ## ToStringSize = sizeof joined }
+#define ENUM__JOIN_STR_2(v1, v2) \
+	ENUM__JOIN_STR_1(v1) ENUM__SEP \
+	ENUM__JOIN_STR_1(v2)
+#define ENUM__JOIN_STR_4(v1, v2, v3, v4) \
+	ENUM__JOIN_STR_2(v1, v2) ENUM__SEP \
+	ENUM__JOIN_STR_2(v3, v4)
+#define ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8) \
+	ENUM__JOIN_STR_4(v1, v2, v3, v4) ENUM__SEP \
+	ENUM__JOIN_STR_4(v5, v6, v7, v8)
+#define ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+			  v09, v10, v11, v12, v13, v14, v15, v16) \
+	ENUM__JOIN_STR_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \
+	ENUM__JOIN_STR_8(v09, v10, v11, v12, v13, v14, v15, v16)
 
-#define ENUM__SPEC_1(v1) { v1, #v1 }
+#define ENUM__JOIN_2(part1, part2) \
+	part1 ENUM__SEP part2
+#define ENUM__JOIN_3(part1, part2, part3) \
+	part1 ENUM__SEP part2 ENUM__SEP part3
+#define ENUM__JOIN_4(part1, part2, part3, part4) \
+	part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4
+#define ENUM__JOIN_5(part1, part2, part3, part4, part5) \
+	part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4 ENUM__SEP part5
+
+/* List the pairs of enum value and corresponding name. */
+#define ENUM__SPEC_1(v1) \
+	{ v1, #v1 }
 #define ENUM__SPEC_2(v1, v2) \
 	ENUM__SPEC_1(v1), \
 	ENUM__SPEC_1(v2)
@@ -87,49 +90,106 @@ const char *Enum_ValueToString(int, cons
 		      v09, v10, v11, v12, v13, v14, v15, v16) \
 	ENUM__SPEC_8(v01, v02, v03, v04, v05, v06, v07, v08), \
 	ENUM__SPEC_8(v09, v10, v11, v12, v13, v14, v15, v16)
-#define ENUM__SPEC(part1, part2) \
+
+#define ENUM__SPECS_2(part1, part2) \
 	{ part1, part2, { 0, "" } }
+#define ENUM__SPECS_3(part1, part2, part3) \
+	{ part1, part2, part3, { 0, "" } }
+#define ENUM__SPECS_4(part1, part2, part3, part4) \
+	{ part1, part2, part3, part4, { 0, "" } }
+#define ENUM__SPECS_5(part1, part2, part3, part4, part5) \
+	{ part1, part2, part3, part4, part5, { 0, "" } }
+
+/* Declare the necessary data structures for calling Enum_ValueToString. */
+#define ENUM__VALUE_RTTI(typnam, specs) \
+	static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs
+
+/* Declare the necessary data structures for calling Enum_FlagsToString. */
+#define ENUM__FLAGS_RTTI(typnam, specs, joined) \
+	static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
+	enum { typnam ## _ ## ToStringSize = sizeof joined }
 
-#define ENUM_RTTI_3(typnam, v1, v2, v3) \
-	ENUM__RTTI(typnam, \
-	    ENUM__SPEC(ENUM__SPEC_2(v1, v2), ENUM__SPEC_1(v3)), \
-	    ENUM__JOIN_2(ENUM__JOIN_2(v1, v2), ENUM__JOIN_1(v3)))
-
-#define ENUM_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
-	ENUM__RTTI(typnam, \
-	    ENUM__SPEC( \
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 3 flags. */
+#define ENUM_FLAGS_RTTI_3(typnam, v1, v2, v3) \
+	ENUM__FLAGS_RTTI(typnam, \
+	    ENUM__SPECS_2( \
+	    	ENUM__SPEC_2(v1, v2), \
+	    	ENUM__SPEC_1(v3)), \
+	    ENUM__JOIN_2( \
+	    	ENUM__JOIN_STR_2(v1, v2), \
+	    	ENUM__JOIN_STR_1(v3)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 8 flags. */
+#define ENUM_FLAGS_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
+	ENUM__FLAGS_RTTI(typnam, \
+	    ENUM__SPECS_2( \
 		ENUM__SPEC_4(v1, v2, v3, v4), \
 		ENUM__SPEC_4(v5, v6, v7, v8)), \
-	    ENUM__JOIN( \
-		ENUM__JOIN_4(v1, v2, v3, v4), \
-		ENUM__JOIN_4(v5, v6, v7, v8)))
-
-#define ENUM_RTTI_10(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) \
-	ENUM__RTTI(typnam, \
-	    ENUM__SPEC( \
+	    ENUM__JOIN_2( \
+		ENUM__JOIN_STR_4(v1, v2, v3, v4), \
+		ENUM__JOIN_STR_4(v5, v6, v7, v8)))
+
+/* Declare the necessary data structures for calling Enum_ValueToString
+ * for an enum with 8 constants. */
+#define ENUM_VALUE_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
+	ENUM__VALUE_RTTI(typnam, \
+	    ENUM__SPECS_2( \
+		ENUM__SPEC_4(v1, v2, v3, v4), \
+		ENUM__SPEC_4(v5, v6, v7, v8)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 10 flags. */
+#define ENUM_FLAGS_RTTI_10(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) \
+	ENUM__FLAGS_RTTI(typnam, \
+	    ENUM__SPECS_2( \
 		ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \
 		ENUM__SPEC_2(v9, v10)), \
-	    ENUM__JOIN( \
-		ENUM__JOIN_8(v1, v2, v3, v4, v5, v6, v7, v8), \
-		ENUM__JOIN_2(v9, v10)))
-
-#define ENUM_RTTI_32( \
-    typnam, \
-    v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, \
-    v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, \
-    v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, \
-    v31, v32) \
-    ENUM__RTTI( \
-	typnam, \
-        ENUM__SPEC( \
-        ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
-		      v09, v10, v11, v12, v13, v14, v15, v16), \
-        ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \
-        	      v25, v26, v27, v28, v29, v30, v31, v32)), \
-	ENUM__JOIN_32( \
-	    v01, v02, v03, v04, v05, v06, v07, v08, \
-	    v09, v10, v11, v12, v13, v14, v15, v16, \
-	    v17, v18, v19, v20, v21, v22, v23, v24, \
-	    v25, v26, v27, v28, v29, v30, v31, v32))
+	    ENUM__JOIN_2( \
+		ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8), \
+		ENUM__JOIN_STR_2(v9, v10)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 31 flags. */
+#define ENUM_FLAGS_RTTI_31(typnam, \
+		     v01, v02, v03, v04, v05, v06, v07, v08, \
+		     v09, v10, v11, v12, v13, v14, v15, v16, \
+		     v17, v18, v19, v20, v21, v22, v23, v24, \
+		     v25, v26, v27, v28, v29, v30, v31) \
+    ENUM__FLAGS_RTTI(typnam, \
+        ENUM__SPECS_5( \
+            ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+			  v09, v10, v11, v12, v13, v14, v15, v16), \
+	    ENUM__SPEC_8(v17, v18, v19, v20, v21, v22, v23, v24), \
+	    ENUM__SPEC_4(v25, v26, v27, v28), \
+	    ENUM__SPEC_2(v29, v30), \
+	    ENUM__SPEC_1(v31)), \
+	ENUM__JOIN_5( \
+	    ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+			      v09, v10, v11, v12, v13, v14, v15, v16), \
+	    ENUM__JOIN_STR_8(v17, v18, v19, v20, v21, v22, v23, v24), \
+	    ENUM__JOIN_STR_4(v25, v26, v27, v28), \
+	    ENUM__JOIN_STR_2(v29, v30), \
+	    ENUM__JOIN_STR_1(v31)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 32 flags. */
+#define ENUM_FLAGS_RTTI_32(typnam, \
+		     v01, v02, v03, v04, v05, v06, v07, v08, \
+		     v09, v10, v11, v12, v13, v14, v15, v16, \
+		     v17, v18, v19, v20, v21, v22, v23, v24, \
+		     v25, v26, v27, v28, v29, v30, v31, v32) \
+    ENUM__FLAGS_RTTI(typnam, \
+        ENUM__SPECS_2( \
+            ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+			  v09, v10, v11, v12, v13, v14, v15, v16), \
+	    ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \
+			  v25, v26, v27, v28, v29, v30, v31, v32)), \
+	ENUM__JOIN_2( \
+	    ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+			      v09, v10, v11, v12, v13, v14, v15, v16), \
+	    ENUM__JOIN_STR_16(v17, v18, v19, v20, v21, v22, v23, v24, \
+	    		      v25, v26, v27, v28, v29, v30, v31, v32)))
 
 #endif

Index: src/usr.bin/make/make.c
diff -u src/usr.bin/make/make.c:1.122 src/usr.bin/make/make.c:1.123
--- src/usr.bin/make/make.c:1.122	Mon Aug 24 20:15:51 2020
+++ src/usr.bin/make/make.c	Tue Aug 25 16:27:24 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.c,v 1.122 2020/08/24 20:15:51 rillig Exp $	*/
+/*	$NetBSD: make.c,v 1.123 2020/08/25 16:27:24 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: make.c,v 1.122 2020/08/24 20:15:51 rillig Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.123 2020/08/25 16:27:24 rillig Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)make.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: make.c,v 1.122 2020/08/24 20:15:51 rillig Exp $");
+__RCSID("$NetBSD: make.c,v 1.123 2020/08/25 16:27:24 rillig Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -151,24 +151,25 @@ make_abort(GNode *gn, int line)
     abort();
 }
 
-ENUM_RTTI_8(GNodeMade,
-	    UNMADE, DEFERRED, REQUESTED, BEINGMADE,
-	    MADE, UPTODATE, ERROR, ABORTED);
-
-ENUM_RTTI_32(GNodeType,
-	     OP_DEPENDS, OP_FORCE, OP_DOUBLEDEP, OP_OPMASK,
-	     OP_OPTIONAL, OP_USE, OP_EXEC, OP_IGNORE,
-	     OP_PRECIOUS, OP_SILENT, OP_MAKE, OP_JOIN,
-	     OP_MADE, OP_SPECIAL, OP_USEBEFORE, OP_INVISIBLE,
-	     OP_NOTMAIN, OP_PHONY, OP_NOPATH, OP_WAIT,
-	     OP_NOMETA, OP_META, OP_NOMETA_CMP, OP_SUBMAKE,
-	     OP_TRANSFORM, OP_MEMBER, OP_LIB, OP_ARCHV,
-	     OP_HAS_COMMANDS, OP_SAVE_CMDS, OP_DEPS_FOUND, OP_MARK);
-
-ENUM_RTTI_10(GNodeFlags,
-	     REMAKE, CHILDMADE, FORCE, DONE_WAIT,
-	     DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE,
-	     DONECYCLE, INTERNAL);
+ENUM_VALUE_RTTI_8(GNodeMade,
+		  UNMADE, DEFERRED, REQUESTED, BEINGMADE,
+		  MADE, UPTODATE, ERROR, ABORTED);
+
+ENUM_FLAGS_RTTI_31(GNodeType,
+		   OP_DEPENDS, OP_FORCE, OP_DOUBLEDEP,
+		   /* OP_OPMASK is omitted since it combines other flags */
+		   OP_OPTIONAL, OP_USE, OP_EXEC, OP_IGNORE,
+		   OP_PRECIOUS, OP_SILENT, OP_MAKE, OP_JOIN,
+		   OP_MADE, OP_SPECIAL, OP_USEBEFORE, OP_INVISIBLE,
+		   OP_NOTMAIN, OP_PHONY, OP_NOPATH, OP_WAIT,
+		   OP_NOMETA, OP_META, OP_NOMETA_CMP, OP_SUBMAKE,
+		   OP_TRANSFORM, OP_MEMBER, OP_LIB, OP_ARCHV,
+		   OP_HAS_COMMANDS, OP_SAVE_CMDS, OP_DEPS_FOUND, OP_MARK);
+
+ENUM_FLAGS_RTTI_10(GNodeFlags,
+		   REMAKE, CHILDMADE, FORCE, DONE_WAIT,
+		   DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE,
+		   DONECYCLE, INTERNAL);
 
 void
 GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.470 src/usr.bin/make/var.c:1.471
--- src/usr.bin/make/var.c:1.470	Mon Aug 24 20:15:51 2020
+++ src/usr.bin/make/var.c	Tue Aug 25 16:27:24 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.470 2020/08/24 20:15:51 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.471 2020/08/25 16:27:24 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.470 2020/08/24 20:15:51 rillig Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.471 2020/08/25 16:27:24 rillig Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)var.c	8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: var.c,v 1.470 2020/08/24 20:15:51 rillig Exp $");
+__RCSID("$NetBSD: var.c,v 1.471 2020/08/25 16:27:24 rillig Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -142,10 +142,8 @@ __RCSID("$NetBSD: var.c,v 1.470 2020/08/
 
 #define VAR_DEBUG(fmt, ...) VAR_DEBUG_IF(TRUE, fmt, __VA_ARGS__)
 
-ENUM_RTTI_3(VarEvalFlags,
-	   VARE_UNDEFERR,
-	   VARE_WANTRES,
-	   VARE_ASSIGN);
+ENUM_FLAGS_RTTI_3(VarEvalFlags,
+		  VARE_UNDEFERR, VARE_WANTRES, VARE_ASSIGN);
 
 /*
  * This lets us tell if we have replaced the original environ
@@ -231,15 +229,9 @@ typedef enum {
     VAR_READONLY = 0x80
 } VarFlags;
 
-ENUM_RTTI_8(VarFlags,
-	    VAR_IN_USE,
-	    VAR_FROM_ENV,
-	    VAR_JUNK,
-	    VAR_KEEP,
-	    VAR_EXPORTED,
-	    VAR_REEXPORT,
-	    VAR_FROM_CMD,
-	    VAR_READONLY);
+ENUM_FLAGS_RTTI_8(VarFlags,
+		  VAR_IN_USE, VAR_FROM_ENV, VAR_JUNK, VAR_KEEP,
+		  VAR_EXPORTED, VAR_REEXPORT, VAR_FROM_CMD, VAR_READONLY);
 
 typedef struct Var {
     char          *name;	/* the variable's name; it is allocated for

Reply via email to