Module Name:    src
Committed By:   rillig
Date:           Tue Sep 22 06:13:39 UTC 2020

Modified Files:
        src/usr.bin/make: enum.h var.c
        src/usr.bin/make/unit-tests: counter.exp vardebug.exp
            varname-dot-shell.exp

Log Message:
make(1): move VAR_JUNK and VAR_KEEP away from VarFlags

These two flags have nothing to do with a variable.  They are only used
while evaluating a variable expression.

While here, rename the flags and make their documentation more precise.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/make/enum.h
cvs rdiff -u -r1.526 -r1.527 src/usr.bin/make/var.c
cvs rdiff -u -r1.5 -r1.6 src/usr.bin/make/unit-tests/counter.exp
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/vardebug.exp
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/varname-dot-shell.exp

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.10 src/usr.bin/make/enum.h:1.11
--- src/usr.bin/make/enum.h:1.10	Sat Sep 12 14:41:00 2020
+++ src/usr.bin/make/enum.h	Tue Sep 22 06:13:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: enum.h,v 1.10 2020/09/12 14:41:00 rillig Exp $	*/
+/*	$NetBSD: enum.h,v 1.11 2020/09/22 06:13:38 rillig Exp $	*/
 
 /*
  Copyright (c) 2020 Roland Illig <ril...@netbsd.org>
@@ -108,6 +108,17 @@ const char *Enum_ValueToString(int, cons
 	enum { typnam ## _ ## ToStringSize = sizeof joined }
 
 /* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 2 flags. */
+#define ENUM_FLAGS_RTTI_2(typnam, v1, v2) \
+	ENUM__FLAGS_RTTI(typnam, \
+	    ENUM__SPECS_2( \
+		ENUM__SPEC_1(v1), \
+		ENUM__SPEC_1(v2)), \
+	    ENUM__JOIN_2( \
+		ENUM__JOIN_STR_1(v1), \
+		ENUM__JOIN_STR_1(v2)))
+
+/* 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, \
@@ -119,6 +130,17 @@ const char *Enum_ValueToString(int, cons
 		ENUM__JOIN_STR_1(v3)))
 
 /* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 6 flags. */
+#define ENUM_FLAGS_RTTI_6(typnam, v1, v2, v3, v4, v5, v6) \
+	ENUM__FLAGS_RTTI(typnam, \
+	    ENUM__SPECS_2( \
+		ENUM__SPEC_4(v1, v2, v3, v4), \
+		ENUM__SPEC_2(v5, v6)), \
+	    ENUM__JOIN_2( \
+		ENUM__JOIN_STR_4(v1, v2, v3, v4), \
+		ENUM__JOIN_STR_2(v5, v6)))
+
+/* 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, \

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.526 src/usr.bin/make/var.c:1.527
--- src/usr.bin/make/var.c:1.526	Tue Sep 22 06:06:18 2020
+++ src/usr.bin/make/var.c	Tue Sep 22 06:13:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.526 2020/09/22 06:06:18 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.527 2020/09/22 06:13:38 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -121,7 +121,7 @@
 #include    "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.526 2020/09/22 06:06:18 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.527 2020/09/22 06:13:38 rillig Exp $");
 
 #define VAR_DEBUG_IF(cond, fmt, ...)	\
     if (!(DEBUG(VAR) && (cond)))	\
@@ -199,12 +199,6 @@ typedef enum {
      * These variables are not registered in any GNode, therefore they must
      * be freed as soon as they are not used anymore. */
     VAR_FROM_ENV = 0x02,
-    /* The variable is a junk variable that should be destroyed when done with
-     * it.  Used by Var_Parse for undefined, modified variables. */
-    VAR_JUNK = 0x04,
-    /* Variable is VAR_JUNK, but we found a use for it in some modifier and
-     * the value is therefore valid. */
-    VAR_KEEP = 0x08,
     /* The variable is exported to the environment, to be used by child
      * processes. */
     VAR_EXPORTED = 0x10,
@@ -218,8 +212,8 @@ typedef enum {
     VAR_READONLY = 0x80
 } VarFlags;
 
-ENUM_FLAGS_RTTI_8(VarFlags,
-		  VAR_IN_USE, VAR_FROM_ENV, VAR_JUNK, VAR_KEEP,
+ENUM_FLAGS_RTTI_6(VarFlags,
+		  VAR_IN_USE, VAR_FROM_ENV,
 		  VAR_EXPORTED, VAR_REEXPORT, VAR_FROM_CMD, VAR_READONLY);
 
 typedef struct Var {
@@ -1892,6 +1886,19 @@ VarStrftime(const char *fmt, Boolean zul
  * Some modifiers need to free some memory.
  */
 
+typedef enum VarExprFlags {
+    /* The variable expression is based on an undefined variable. */
+    VEF_UNDEF = 0x01,
+    /* The variable expression started as an undefined expression, but one
+     * of the modifiers (such as :D or :U) has turned the expression from
+     * undefined to defined. */
+    VEF_DEF = 0x02
+} VarExprFlags;
+
+ENUM_FLAGS_RTTI_2(VarExprFlags,
+		  VEF_UNDEF, VEF_DEF);
+
+
 typedef struct {
     const char startc;		/* '\0' or '{' or '(' */
     const char endc;		/* '\0' or '}' or ')' */
@@ -1911,13 +1918,14 @@ typedef struct {
 				 * the variable value into words, like :S and
 				 * :C, treat the variable value as a single big
 				 * word, possibly containing spaces. */
+    VarExprFlags exprFlags;
 } ApplyModifiersState;
 
 static void
-ApplyModifiersState_Keep(ApplyModifiersState *st)
+ApplyModifiersState_Define(ApplyModifiersState *st)
 {
-    if (st->v->flags & VAR_JUNK)
-        st->v->flags |= VAR_KEEP;
+    if (st->exprFlags & VEF_UNDEF)
+        st->exprFlags |= VEF_DEF;
 }
 
 typedef enum {
@@ -2001,7 +2009,7 @@ ApplyModifier_Defined(const char **pp, A
 
     VarEvalFlags eflags = st->eflags & ~(unsigned)VARE_WANTRES;
     if (st->eflags & VARE_WANTRES) {
-	if ((**pp == 'D') == !(st->v->flags & VAR_JUNK))
+	if ((**pp == 'D') == !(st->exprFlags & VEF_UNDEF))
 	    eflags |= VARE_WANTRES;
     }
 
@@ -2038,7 +2046,7 @@ ApplyModifier_Defined(const char **pp, A
     }
     *pp = p;
 
-    ApplyModifiersState_Keep(st);
+    ApplyModifiersState_Define(st);
 
     if (eflags & VARE_WANTRES) {
 	st->newVal = Buf_Destroy(&buf, FALSE);
@@ -2112,7 +2120,7 @@ ApplyModifier_Path(const char **pp, Appl
     GNode *gn;
     char *path;
 
-    ApplyModifiersState_Keep(st);
+    ApplyModifiersState_Define(st);
 
     gn = Targ_FindNode(st->v->name, TARG_NOCREATE);
     if (gn == NULL || gn->type & OP_NOPATH) {
@@ -2158,7 +2166,7 @@ ApplyModifier_ShellCommand(const char **
     if (errfmt != NULL)
 	Error(errfmt, st->val);	/* XXX: why still return AMR_OK? */
 
-    ApplyModifiersState_Keep(st);
+    ApplyModifiersState_Define(st);
     return AMR_OK;
 }
 
@@ -2754,7 +2762,7 @@ ApplyModifier_IfElse(const char **pp, Ap
 	st->newVal = else_expr;
 	free(then_expr);
     }
-    ApplyModifiersState_Keep(st);
+    ApplyModifiersState_Define(st);
     return AMR_OK;
 }
 
@@ -2802,7 +2810,7 @@ ApplyModifier_Assign(const char **pp, Ap
 
     v_ctxt = st->ctxt;		/* context where v belongs */
     sv_name = NULL;
-    if (st->v->flags & VAR_JUNK) {
+    if (st->exprFlags & VEF_UNDEF) {
 	/*
 	 * We need to bmake_strdup() it in case ParseModifierPart() recurses.
 	 */
@@ -2829,7 +2837,7 @@ ApplyModifier_Assign(const char **pp, Ap
 
     delim = st->startc == '(' ? ')' : '}';
     val = ParseModifierPart(pp, delim, st->eflags, st->ctxt, NULL, NULL, NULL);
-    if (st->v->flags & VAR_JUNK) {
+    if (st->exprFlags & VEF_UNDEF) {
 	/* restore original name */
 	free(st->v->name);
 	st->v->name = sv_name;
@@ -2857,7 +2865,7 @@ ApplyModifier_Assign(const char **pp, Ap
 	    break;
 	}
 	case '?':
-	    if (!(st->v->flags & VAR_JUNK))
+	    if (!(st->exprFlags & VEF_UNDEF))
 		break;
 	    /* FALLTHROUGH */
 	default:
@@ -2981,7 +2989,8 @@ ApplyModifiers(
     char *val,			/* the current value of the variable */
     char const startc,		/* '(' or '{', or '\0' for indirect modifiers */
     char const endc,		/* ')' or '}', or '\0' for indirect modifiers */
-    Var * const v,		/* the variable may have its flags changed */
+    Var * const v,
+    VarExprFlags *exprFlags,
     GNode * const ctxt,		/* for looking up and modifying variables */
     VarEvalFlags const eflags,
     void ** const freePtr	/* free this after using the return value */
@@ -2991,7 +3000,8 @@ ApplyModifiers(
 	var_Error,		/* .newVal */
 	'\0',			/* .missing_delim */
 	' ',			/* .sep */
-	FALSE			/* .oneBigWord */
+	FALSE,			/* .oneBigWord */
+	*exprFlags		/* .exprFlags */
     };
     const char *p;
     const char *mod;
@@ -3035,7 +3045,7 @@ ApplyModifiers(
 	    if (rval[0] != '\0') {
 		const char *rval_pp = rval;
 		st.val = ApplyModifiers(&rval_pp, st.val, '\0', '\0', v,
-					ctxt, eflags, freePtr);
+					exprFlags, ctxt, eflags, freePtr);
 		if (st.val == var_Error
 		    || (st.val == varNoError && !(st.eflags & VARE_UNDEFERR))
 		    || *rval_pp != '\0') {
@@ -3061,17 +3071,21 @@ ApplyModifiers(
 	if (DEBUG(VAR)) {
 	    char eflags_str[VarEvalFlags_ToStringSize];
 	    char vflags_str[VarFlags_ToStringSize];
+	    char exprflags_str[VarExprFlags_ToStringSize];
 	    Boolean is_single_char = mod[0] != '\0' &&
-		(mod[1] == endc || mod[1] == ':');
+				     (mod[1] == endc || mod[1] == ':');
 
 	    /* At this point, only the first character of the modifier can
 	     * be used since the end of the modifier is not yet known. */
-	    VAR_DEBUG("Applying ${%s:%c%s} to \"%s\" (%s, %s)\n",
+	    VAR_DEBUG("Applying ${%s:%c%s} to \"%s\" (%s, %s, %s)\n",
 		      st.v->name, mod[0], is_single_char ? "" : "...", st.val,
 		      Enum_FlagsToString(eflags_str, sizeof eflags_str,
 					 st.eflags, VarEvalFlags_ToStringSpecs),
 		      Enum_FlagsToString(vflags_str, sizeof vflags_str,
-					 st.v->flags, VarFlags_ToStringSpecs));
+					 st.v->flags, VarFlags_ToStringSpecs),
+		      Enum_FlagsToString(exprflags_str, sizeof exprflags_str,
+					 st.exprFlags,
+					 VarExprFlags_ToStringSpecs));
 	}
 
 	switch (*mod) {
@@ -3089,7 +3103,7 @@ ApplyModifiers(
 	    res = ApplyModifier_Defined(&p, &st);
 	    break;
 	case 'L':
-	    ApplyModifiersState_Keep(&st);
+	    ApplyModifiersState_Define(&st);
 	    st.newVal = bmake_strdup(st.v->name);
 	    p++;
 	    res = AMR_OK;
@@ -3206,15 +3220,19 @@ ApplyModifiers(
 	if (DEBUG(VAR)) {
 	    char eflags_str[VarEvalFlags_ToStringSize];
 	    char vflags_str[VarFlags_ToStringSize];
+	    char exprflags_str[VarExprFlags_ToStringSize];
 	    const char *quot = st.newVal == var_Error ? "" : "\"";
 	    const char *newVal = st.newVal == var_Error ? "error" : st.newVal;
 
-	    VAR_DEBUG("Result of ${%s:%.*s} is %s%s%s (%s, %s)\n",
+	    VAR_DEBUG("Result of ${%s:%.*s} is %s%s%s (%s, %s, %s)\n",
 		      st.v->name, (int)(p - mod), mod, quot, newVal, quot,
 		      Enum_FlagsToString(eflags_str, sizeof eflags_str,
 					 st.eflags, VarEvalFlags_ToStringSpecs),
 		      Enum_FlagsToString(vflags_str, sizeof vflags_str,
-					 st.v->flags, VarFlags_ToStringSpecs));
+					 st.v->flags, VarFlags_ToStringSpecs),
+		      Enum_FlagsToString(exprflags_str, sizeof exprflags_str,
+					 st.exprFlags,
+					 VarExprFlags_ToStringSpecs));
 	}
 
 	if (st.newVal != st.val) {
@@ -3239,6 +3257,7 @@ ApplyModifiers(
 out:
     *pp = p;
     assert(st.val != NULL);	/* Use var_Error or varNoError instead. */
+    *exprFlags = st.exprFlags;
     return st.val;
 
 bad_modifier:
@@ -3252,6 +3271,7 @@ cleanup:
 	      st.v->name, st.missing_delim);
     free(*freePtr);
     *freePtr = NULL;
+    *exprFlags = st.exprFlags;
     return var_Error;
 }
 
@@ -3452,6 +3472,7 @@ Var_Parse(const char **pp, GNode *ctxt, 
     Var *v;
     char *nstr;
     char eflags_str[VarEvalFlags_ToStringSize];
+    VarExprFlags exprFlags = 0;
 
     VAR_DEBUG("%s: %s with %s\n", __func__, start,
 	      Enum_FlagsToString(eflags_str, sizeof eflags_str, eflags,
@@ -3595,7 +3616,8 @@ Var_Parse(const char **pp, GNode *ctxt, 
 	    v = bmake_malloc(sizeof(Var));
 	    v->name = varname;
 	    Buf_Init(&v->val, 1);
-	    v->flags = VAR_JUNK;
+	    v->flags = 0;
+	    exprFlags = VEF_UNDEF;
 	} else
 	    free(varname);
     }
@@ -3634,7 +3656,7 @@ Var_Parse(const char **pp, GNode *ctxt, 
 	if (extramodifiers != NULL) {
 	    const char *em = extramodifiers;
 	    nstr = ApplyModifiers(&em, nstr, '(', ')',
-				  v, ctxt, eflags, &extraFree);
+				  v, &exprFlags, ctxt, eflags, &extraFree);
 	}
 
 	if (haveModifier) {
@@ -3642,7 +3664,7 @@ Var_Parse(const char **pp, GNode *ctxt, 
 	    p++;
 
 	    nstr = ApplyModifiers(&p, nstr, startc, endc,
-				  v, ctxt, eflags, freePtr);
+				  v, &exprFlags, ctxt, eflags, freePtr);
 	    free(extraFree);
 	} else {
 	    *freePtr = extraFree;
@@ -3662,13 +3684,13 @@ Var_Parse(const char **pp, GNode *ctxt, 
 	    *freePtr = nstr;
 	(void)VarFreeEnv(v, !keepValue);
 
-    } else if (v->flags & VAR_JUNK) {
+    } else if (exprFlags & VEF_UNDEF) {
 	/*
 	 * Perform any freeing needed and set *freePtr to NULL so the caller
 	 * doesn't try to free a static pointer.
 	 * If VAR_KEEP is also set then we want to keep str(?) as is.
 	 */
-	if (!(v->flags & VAR_KEEP)) {
+	if (!(exprFlags & VEF_DEF)) {
 	    if (*freePtr != NULL) {
 		free(*freePtr);
 		*freePtr = NULL;

Index: src/usr.bin/make/unit-tests/counter.exp
diff -u src/usr.bin/make/unit-tests/counter.exp:1.5 src/usr.bin/make/unit-tests/counter.exp:1.6
--- src/usr.bin/make/unit-tests/counter.exp:1.5	Sun Sep 13 16:47:24 2020
+++ src/usr.bin/make/unit-tests/counter.exp	Tue Sep 22 06:13:39 2020
@@ -4,85 +4,85 @@ Global:NEXT = ${COUNTER::=${COUNTER} a}$
 Global:A = 
 Var_Parse: ${NEXT} with VARE_WANTRES|VARE_ASSIGN
 Var_Parse: ${COUNTER::=${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
-Applying ${COUNTER::...} to "" (VARE_WANTRES|VARE_ASSIGN, none)
+Applying ${COUNTER::...} to "" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Var_Parse: ${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES
 Modifier part: " a"
 Global:COUNTER =  a
-Result of ${COUNTER::=${COUNTER} a} is "" (VARE_WANTRES|VARE_ASSIGN, none)
+Result of ${COUNTER::=${COUNTER} a} is "" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Var_Parse: ${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
 Var_Parse: ${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
-Applying ${COUNTER:[...} to " a" (VARE_WANTRES|VARE_ASSIGN, none)
+Applying ${COUNTER:[...} to " a" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Modifier part: "#"
-Result of ${COUNTER:[#]} is "1" (VARE_WANTRES|VARE_ASSIGN, none)
+Result of ${COUNTER:[#]} is "1" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Global:A = ${COUNTER::= a a}1
 Global:B = 
 Var_Parse: ${NEXT} with VARE_WANTRES|VARE_ASSIGN
 Var_Parse: ${COUNTER::=${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
-Applying ${COUNTER::...} to " a" (VARE_WANTRES|VARE_ASSIGN, none)
+Applying ${COUNTER::...} to " a" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Var_Parse: ${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES
 Modifier part: " a a"
 Global:COUNTER =  a a
-Result of ${COUNTER::=${COUNTER} a} is "" (VARE_WANTRES|VARE_ASSIGN, none)
+Result of ${COUNTER::=${COUNTER} a} is "" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Var_Parse: ${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
 Var_Parse: ${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
-Applying ${COUNTER:[...} to " a a" (VARE_WANTRES|VARE_ASSIGN, none)
+Applying ${COUNTER:[...} to " a a" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Modifier part: "#"
-Result of ${COUNTER:[#]} is "2" (VARE_WANTRES|VARE_ASSIGN, none)
+Result of ${COUNTER:[#]} is "2" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Global:B = ${COUNTER::= a a a}2
 Global:C = 
 Var_Parse: ${NEXT} with VARE_WANTRES|VARE_ASSIGN
 Var_Parse: ${COUNTER::=${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
-Applying ${COUNTER::...} to " a a" (VARE_WANTRES|VARE_ASSIGN, none)
+Applying ${COUNTER::...} to " a a" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Var_Parse: ${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES
 Modifier part: " a a a"
 Global:COUNTER =  a a a
-Result of ${COUNTER::=${COUNTER} a} is "" (VARE_WANTRES|VARE_ASSIGN, none)
+Result of ${COUNTER::=${COUNTER} a} is "" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Var_Parse: ${COUNTER} a}${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
 Var_Parse: ${COUNTER:[#]} with VARE_WANTRES|VARE_ASSIGN
-Applying ${COUNTER:[...} to " a a a" (VARE_WANTRES|VARE_ASSIGN, none)
+Applying ${COUNTER:[...} to " a a a" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Modifier part: "#"
-Result of ${COUNTER:[#]} is "3" (VARE_WANTRES|VARE_ASSIGN, none)
+Result of ${COUNTER:[#]} is "3" (VARE_WANTRES|VARE_ASSIGN, none, none)
 Global:C = ${COUNTER::= a a a a}3
 Global:RELEVANT = no
 Global:RELEVANT = yes (run-time part)
-Result of ${RELEVANT::=yes (run-time part)} is "" (VARE_WANTRES, none)
+Result of ${RELEVANT::=yes (run-time part)} is "" (VARE_WANTRES, none, none)
 Var_Parse: ${A:Q} B=${B:Q} C=${C:Q} COUNTER=${COUNTER:[#]:Q} with VARE_WANTRES
 Var_Parse: ${COUNTER::= a a}1 with VARE_WANTRES
-Applying ${COUNTER::...} to " a a a" (VARE_WANTRES, none)
+Applying ${COUNTER::...} to " a a a" (VARE_WANTRES, none, none)
 Modifier part: " a a"
 Global:COUNTER =  a a
-Result of ${COUNTER::= a a} is "" (VARE_WANTRES, none)
-Applying ${A:Q} to "1" (VARE_WANTRES, none)
+Result of ${COUNTER::= a a} is "" (VARE_WANTRES, none, none)
+Applying ${A:Q} to "1" (VARE_WANTRES, none, none)
 QuoteMeta: [1]
-Result of ${A:Q} is "1" (VARE_WANTRES, none)
+Result of ${A:Q} is "1" (VARE_WANTRES, none, none)
 Var_Parse: ${B:Q} C=${C:Q} COUNTER=${COUNTER:[#]:Q} with VARE_WANTRES
 Var_Parse: ${COUNTER::= a a a}2 with VARE_WANTRES
-Applying ${COUNTER::...} to " a a" (VARE_WANTRES, none)
+Applying ${COUNTER::...} to " a a" (VARE_WANTRES, none, none)
 Modifier part: " a a a"
 Global:COUNTER =  a a a
-Result of ${COUNTER::= a a a} is "" (VARE_WANTRES, none)
-Applying ${B:Q} to "2" (VARE_WANTRES, none)
+Result of ${COUNTER::= a a a} is "" (VARE_WANTRES, none, none)
+Applying ${B:Q} to "2" (VARE_WANTRES, none, none)
 QuoteMeta: [2]
-Result of ${B:Q} is "2" (VARE_WANTRES, none)
+Result of ${B:Q} is "2" (VARE_WANTRES, none, none)
 Var_Parse: ${C:Q} COUNTER=${COUNTER:[#]:Q} with VARE_WANTRES
 Var_Parse: ${COUNTER::= a a a a}3 with VARE_WANTRES
-Applying ${COUNTER::...} to " a a a" (VARE_WANTRES, none)
+Applying ${COUNTER::...} to " a a a" (VARE_WANTRES, none, none)
 Modifier part: " a a a a"
 Global:COUNTER =  a a a a
-Result of ${COUNTER::= a a a a} is "" (VARE_WANTRES, none)
-Applying ${C:Q} to "3" (VARE_WANTRES, none)
+Result of ${COUNTER::= a a a a} is "" (VARE_WANTRES, none, none)
+Applying ${C:Q} to "3" (VARE_WANTRES, none, none)
 QuoteMeta: [3]
-Result of ${C:Q} is "3" (VARE_WANTRES, none)
+Result of ${C:Q} is "3" (VARE_WANTRES, none, none)
 Var_Parse: ${COUNTER:[#]:Q} with VARE_WANTRES
-Applying ${COUNTER:[...} to " a a a a" (VARE_WANTRES, none)
+Applying ${COUNTER:[...} to " a a a a" (VARE_WANTRES, none, none)
 Modifier part: "#"
-Result of ${COUNTER:[#]} is "4" (VARE_WANTRES, none)
-Applying ${COUNTER:Q} to "4" (VARE_WANTRES, none)
+Result of ${COUNTER:[#]} is "4" (VARE_WANTRES, none, none)
+Applying ${COUNTER:Q} to "4" (VARE_WANTRES, none, none)
 QuoteMeta: [4]
-Result of ${COUNTER:Q} is "4" (VARE_WANTRES, none)
+Result of ${COUNTER:Q} is "4" (VARE_WANTRES, none, none)
 A=1 B=2 C=3 COUNTER=4
 Var_Parse: ${RELEVANT::=no} with VARE_WANTRES
-Applying ${RELEVANT::...} to "yes (run-time part)" (VARE_WANTRES, none)
+Applying ${RELEVANT::...} to "yes (run-time part)" (VARE_WANTRES, none, none)
 Modifier part: "no"
 Global:RELEVANT = no
 exit status 0

Index: src/usr.bin/make/unit-tests/vardebug.exp
diff -u src/usr.bin/make/unit-tests/vardebug.exp:1.7 src/usr.bin/make/unit-tests/vardebug.exp:1.8
--- src/usr.bin/make/unit-tests/vardebug.exp:1.7	Sun Sep 13 16:47:24 2020
+++ src/usr.bin/make/unit-tests/vardebug.exp	Tue Sep 22 06:13:39 2020
@@ -4,75 +4,75 @@ Global:VAR = overwritten
 Global:delete VAR
 Global:delete VAR (not found)
 Var_Parse: ${:U} with VARE_WANTRES
-Applying ${:U} to "" (VARE_WANTRES, VAR_JUNK)
-Result of ${:U} is "" (VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:U} to "" (VARE_WANTRES, none, VEF_UNDEF)
+Result of ${:U} is "" (VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Var_Set("${:U}", "empty name", ...) name expands to empty string - ignored
 Var_Parse: ${:U} with VARE_WANTRES
-Applying ${:U} to "" (VARE_WANTRES, VAR_JUNK)
-Result of ${:U} is "" (VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:U} to "" (VARE_WANTRES, none, VEF_UNDEF)
+Result of ${:U} is "" (VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Var_Append("${:U}", "empty name", ...) name expands to empty string - ignored
 Global:FROM_CMDLINE = overwritten ignored!
 Global:VAR = 1
 Global:VAR = 1 2
 Global:VAR = 1 2 3
 Var_Parse: ${VAR:M[2]} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${VAR:M...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Applying ${VAR:M...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Pattern[VAR] for [1 2 3] is [[2]]
 ModifyWords: split "1 2 3" into 3 words
 VarMatch [1] [[2]]
 VarMatch [2] [[2]]
 VarMatch [3] [[2]]
-Result of ${VAR:M[2]} is "2" (VARE_UNDEFERR|VARE_WANTRES, none)
+Result of ${VAR:M[2]} is "2" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Var_Parse: ${VAR:N[2]} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${VAR:N...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Applying ${VAR:N...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Pattern[VAR] for [1 2 3] is [[2]]
 ModifyWords: split "1 2 3" into 3 words
-Result of ${VAR:N[2]} is "1 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Result of ${VAR:N[2]} is "1 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Var_Parse: ${VAR:S,2,two,} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${VAR:S...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Applying ${VAR:S...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Modifier part: "2"
 Modifier part: "two"
 ModifyWords: split "1 2 3" into 3 words
-Result of ${VAR:S,2,two,} is "1 two 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Result of ${VAR:S,2,two,} is "1 two 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Var_Parse: ${VAR:Q} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${VAR:Q} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Applying ${VAR:Q} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 QuoteMeta: [1\ 2\ 3]
-Result of ${VAR:Q} is "1\ 2\ 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Result of ${VAR:Q} is "1\ 2\ 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Var_Parse: ${VAR:tu:tl:Q} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${VAR:t...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
-Result of ${VAR:tu} is "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
-Applying ${VAR:t...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
-Result of ${VAR:tl} is "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
-Applying ${VAR:Q} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Applying ${VAR:t...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
+Result of ${VAR:tu} is "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
+Applying ${VAR:t...} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
+Result of ${VAR:tl} is "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
+Applying ${VAR:Q} to "1 2 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 QuoteMeta: [1\ 2\ 3]
-Result of ${VAR:Q} is "1\ 2\ 3" (VARE_UNDEFERR|VARE_WANTRES, none)
+Result of ${VAR:Q} is "1\ 2\ 3" (VARE_UNDEFERR|VARE_WANTRES, none, none)
 Var_Parse: ${:Uvalue:${:UM*e}:Mvalu[e]} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK)
-Result of ${:Uvalue} is "value" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
+Result of ${:Uvalue} is "value" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Var_Parse: ${:UM*e}:Mvalu[e]} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK)
-Result of ${:UM*e} is "M*e" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
+Result of ${:UM*e} is "M*e" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Indirect modifier "M*e" from "${:UM*e}"
-Applying ${:M...} to "value" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:M...} to "value" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
 Pattern[] for [value] is [*e]
 ModifyWords: split "value" into 1 words
 VarMatch [value] [*e]
-Result of ${:M*e} is "value" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
-Applying ${:M...} to "value" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Result of ${:M*e} is "value" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
+Applying ${:M...} to "value" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Pattern[] for [value] is [valu[e]]
 ModifyWords: split "value" into 1 words
 VarMatch [value] [valu[e]]
-Result of ${:Mvalu[e]} is "value" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Result of ${:Mvalu[e]} is "value" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Var_Parse: ${:UVAR} with VARE_WANTRES
-Applying ${:U...} to "" (VARE_WANTRES, VAR_JUNK)
-Result of ${:UVAR} is "VAR" (VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:U...} to "" (VARE_WANTRES, none, VEF_UNDEF)
+Result of ${:UVAR} is "VAR" (VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Global:delete VAR
 Var_Parse: ${:Uvariable:unknown} with VARE_UNDEFERR|VARE_WANTRES
-Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK)
-Result of ${:Uvariable} is "variable" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
-Applying ${:u...} to "variable" (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
+Result of ${:Uvariable} is "variable" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
+Applying ${:u...} to "variable" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 make: Unknown modifier 'u'
-Result of ${:unknown} is error (VARE_UNDEFERR|VARE_WANTRES, VAR_JUNK|VAR_KEEP)
+Result of ${:unknown} is error (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 make: "vardebug.mk" line 44: Malformed conditional (${:Uvariable:unknown})
 Var_Parse: ${UNDEFINED} with VARE_UNDEFERR|VARE_WANTRES
 make: "vardebug.mk" line 53: Malformed conditional (${UNDEFINED})

Index: src/usr.bin/make/unit-tests/varname-dot-shell.exp
diff -u src/usr.bin/make/unit-tests/varname-dot-shell.exp:1.3 src/usr.bin/make/unit-tests/varname-dot-shell.exp:1.4
--- src/usr.bin/make/unit-tests/varname-dot-shell.exp:1.3	Sun Sep 13 16:47:24 2020
+++ src/usr.bin/make/unit-tests/varname-dot-shell.exp	Tue Sep 22 06:13:39 2020
@@ -13,7 +13,7 @@ Var_Parse: ${.SHELL} != ${ORIG_SHELL} wi
 ParseReadLine (24): 'all:'
 ParseReadLine (25): '	@echo ${.SHELL:M*}'
 Var_Parse: ${.SHELL:M*} with VARE_WANTRES
-Applying ${.SHELL:M...} to "(details omitted)" (VARE_WANTRES, VAR_READONLY)
+Applying ${.SHELL:M...} to "(details omitted)" (VARE_WANTRES, VAR_READONLY, none)
 Pattern[.SHELL] for [(details omitted)] is [*]
-Result of ${.SHELL:M*} is "(details omitted)" (VARE_WANTRES, VAR_READONLY)
+Result of ${.SHELL:M*} is "(details omitted)" (VARE_WANTRES, VAR_READONLY, none)
 exit status 0

Reply via email to