Module Name: src Committed By: rillig Date: Sat Jan 11 21:21:34 UTC 2025
Modified Files: src/usr.bin/make: cond.c make.h var.c src/usr.bin/make/unit-tests: cond-op-and.exp cond-op-and.mk cond-op-or.exp cond-op-or.mk cond-token-var.exp cond-token-var.mk cond-undef-lint.exp cond-undef-lint.mk dep-var.exp deptgt-makeflags.exp directive-export-impl.exp directive-include-fatal.exp directive-include-fatal.mk opt-debug-var.exp opt-debug-var.mk var-op-shell.exp var-op-shell.mk vardebug.exp vardebug.mk varmod-assign-shell.exp varmod-assign-shell.mk varmod-assign.exp varmod-match-escape.exp varname-dot-shell.exp varname-dot-suffixes.exp varname.exp varparse-dynamic.exp varparse-dynamic.mk Log Message: make: replace "Malformed conditional" with "Variable is undefined" Evaluating a conditional such as ".if ${UNDEF}" produced a "Malformed conditional" error, even though the form of the conditional was correct, it was the content of the variable that was wrong. Replace this message with the more accurate "Variable is undefined", revealing which of the possibly many variables is actually undefined. To generate a diff of this commit: cvs rdiff -u -r1.370 -r1.371 src/usr.bin/make/cond.c cvs rdiff -u -r1.347 -r1.348 src/usr.bin/make/make.h cvs rdiff -u -r1.1143 -r1.1144 src/usr.bin/make/var.c cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/cond-op-and.exp \ src/usr.bin/make/unit-tests/cond-token-var.exp cvs rdiff -u -r1.11 -r1.12 src/usr.bin/make/unit-tests/cond-op-and.mk cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/cond-op-or.exp \ src/usr.bin/make/unit-tests/cond-undef-lint.mk \ src/usr.bin/make/unit-tests/var-op-shell.exp cvs rdiff -u -r1.13 -r1.14 src/usr.bin/make/unit-tests/cond-op-or.mk cvs rdiff -u -r1.10 -r1.11 src/usr.bin/make/unit-tests/cond-token-var.mk \ src/usr.bin/make/unit-tests/var-op-shell.mk \ src/usr.bin/make/unit-tests/varmod-assign-shell.exp \ src/usr.bin/make/unit-tests/varmod-assign-shell.mk cvs rdiff -u -r1.8 -r1.9 src/usr.bin/make/unit-tests/cond-undef-lint.exp \ src/usr.bin/make/unit-tests/dep-var.exp \ src/usr.bin/make/unit-tests/deptgt-makeflags.exp \ src/usr.bin/make/unit-tests/varname-dot-suffixes.exp cvs rdiff -u -r1.19 -r1.20 \ src/usr.bin/make/unit-tests/directive-export-impl.exp cvs rdiff -u -r1.5 -r1.6 \ src/usr.bin/make/unit-tests/directive-include-fatal.exp \ src/usr.bin/make/unit-tests/directive-include-fatal.mk cvs rdiff -u -r1.4 -r1.5 src/usr.bin/make/unit-tests/opt-debug-var.exp \ src/usr.bin/make/unit-tests/opt-debug-var.mk \ src/usr.bin/make/unit-tests/varparse-dynamic.exp cvs rdiff -u -r1.39 -r1.40 src/usr.bin/make/unit-tests/vardebug.exp cvs rdiff -u -r1.15 -r1.16 src/usr.bin/make/unit-tests/vardebug.mk cvs rdiff -u -r1.29 -r1.30 src/usr.bin/make/unit-tests/varmod-assign.exp cvs rdiff -u -r1.25 -r1.26 \ src/usr.bin/make/unit-tests/varmod-match-escape.exp cvs rdiff -u -r1.22 -r1.23 src/usr.bin/make/unit-tests/varname-dot-shell.exp \ src/usr.bin/make/unit-tests/varname.exp cvs rdiff -u -r1.9 -r1.10 src/usr.bin/make/unit-tests/varparse-dynamic.mk 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/cond.c diff -u src/usr.bin/make/cond.c:1.370 src/usr.bin/make/cond.c:1.371 --- src/usr.bin/make/cond.c:1.370 Sat Jan 11 20:54:45 2025 +++ src/usr.bin/make/cond.c Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: cond.c,v 1.370 2025/01/11 20:54:45 rillig Exp $ */ +/* $NetBSD: cond.c,v 1.371 2025/01/11 21:21:33 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -91,7 +91,7 @@ #include "dir.h" /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: cond.c,v 1.370 2025/01/11 20:54:45 rillig Exp $"); +MAKE_RCSID("$NetBSD: cond.c,v 1.371 2025/01/11 21:21:33 rillig Exp $"); /* * Conditional expressions conform to this grammar: @@ -221,13 +221,7 @@ ParseWord(const char **pp, bool doEval) if ((ch == '&' || ch == '|') && depth == 0) break; if (ch == '$') { - VarEvalMode emode = doEval - ? VARE_EVAL_DEFINED - : VARE_PARSE; - /* - * TODO: make Var_Parse complain about undefined - * variables. - */ + VarEvalMode emode = doEval ? VARE_EVAL : VARE_PARSE; FStr nestedVal = Var_Parse(&p, SCOPE_CMDLINE, emode); /* TODO: handle errors */ Buf_AddStr(&word, nestedVal.str); @@ -399,7 +393,7 @@ CondParser_StringExpr(CondParser *par, c bool atStart; /* true means an expression outside quotes */ emode = doEval && quoted ? VARE_EVAL - : doEval ? VARE_EVAL_DEFINED + : doEval ? VARE_EVAL_DEFINED_LOUD : VARE_PARSE; p = par->p; Index: src/usr.bin/make/make.h diff -u src/usr.bin/make/make.h:1.347 src/usr.bin/make/make.h:1.348 --- src/usr.bin/make/make.h:1.347 Thu Aug 29 20:20:35 2024 +++ src/usr.bin/make/make.h Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.347 2024/08/29 20:20:35 rillig Exp $ */ +/* $NetBSD: make.h,v 1.348 2025/01/11 21:21:33 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -693,7 +693,7 @@ typedef struct CmdOpts { */ DebugFlags debug; - /* -df: debug output is written here - default stderr */ + /* -dF: debug output is written here - default stderr */ FILE *debug_file; /* @@ -962,6 +962,12 @@ typedef enum VarEvalMode { * Parse and evaluate the expression. It is an error if a * subexpression evaluates to undefined. */ + VARE_EVAL_DEFINED_LOUD, + + /* + * Parse and evaluate the expression. It is a silent error if a + * subexpression evaluates to undefined. + */ VARE_EVAL_DEFINED, /* Index: src/usr.bin/make/var.c diff -u src/usr.bin/make/var.c:1.1143 src/usr.bin/make/var.c:1.1144 --- src/usr.bin/make/var.c:1.1143 Sat Jan 11 20:54:45 2025 +++ src/usr.bin/make/var.c Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1143 2025/01/11 20:54:45 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1144 2025/01/11 21:21:33 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -128,7 +128,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1143 2025/01/11 20:54:45 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1144 2025/01/11 21:21:33 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -338,6 +338,7 @@ static const char VarEvalMode_Name[][32] "parse", "parse-balanced", "eval", + "eval-defined-loud", "eval-defined", "eval-keep-undefined", "eval-keep-dollar-and-undefined", @@ -1324,12 +1325,6 @@ VarEvalMode_WithoutKeepDollar(VarEvalMod ? VARE_EVAL_KEEP_UNDEFINED : emode; } -static VarEvalMode -VarEvalMode_UndefOk(VarEvalMode emode) -{ - return emode == VARE_EVAL_DEFINED ? VARE_EVAL : emode; -} - static bool VarEvalMode_ShouldEval(VarEvalMode emode) { @@ -3794,7 +3789,9 @@ ApplyModifier_SunShell(const char **pp, static bool ShouldLogInSimpleFormat(const Expr *expr) { - return (expr->emode == VARE_EVAL || expr->emode == VARE_EVAL_DEFINED) + return (expr->emode == VARE_EVAL + || expr->emode == VARE_EVAL_DEFINED + || expr->emode == VARE_EVAL_DEFINED_LOUD) && expr->defined == DEF_REGULAR; } @@ -4279,9 +4276,12 @@ ParseVarnameShort(char varname, const ch val = UndefinedShortVarValue(varname, scope); if (val == NULL) - val = emode == VARE_EVAL_DEFINED ? var_Error : varUndefined; + val = emode == VARE_EVAL_DEFINED + || emode == VARE_EVAL_DEFINED_LOUD + ? var_Error : varUndefined; - if (opts.strict && val == var_Error) { + if ((opts.strict || emode == VARE_EVAL_DEFINED_LOUD) + && val == var_Error) { Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined", name); } @@ -4324,7 +4324,8 @@ EvalUndefined(bool dynamic, const char * if (dynamic) return FStr_InitOwn(bmake_strsedup(start, p)); - if (emode == VARE_EVAL_DEFINED && opts.strict) { + if (emode == VARE_EVAL_DEFINED_LOUD + || (emode == VARE_EVAL_DEFINED && opts.strict)) { Parse_Error(PARSE_FATAL, "Variable \"%.*s\" is undefined", (int)Substring_Length(varname), varname.start); @@ -4332,7 +4333,8 @@ EvalUndefined(bool dynamic, const char * } return FStr_InitRefer( - emode == VARE_EVAL_DEFINED ? var_Error : varUndefined); + emode == VARE_EVAL_DEFINED_LOUD || emode == VARE_EVAL_DEFINED + ? var_Error : varUndefined); } /* @@ -4347,6 +4349,7 @@ ParseVarnameLong( char startc, GNode *scope, VarEvalMode emode, + VarEvalMode nested_emode, const char **out_false_pp, FStr *out_false_val, @@ -4370,7 +4373,7 @@ ParseVarnameLong( char endc = startc == '(' ? ')' : '}'; p += 2; /* skip "${" or "$(" or "y(" */ - ParseVarname(&p, startc, endc, scope, emode, &varname); + ParseVarname(&p, startc, endc, scope, nested_emode, &varname); name = LazyBuf_Get(&varname); if (*p == ':') @@ -4523,8 +4526,6 @@ Var_Parse_U(const char **pp, VarEvalMode * was undefined, emode was not VARE_EVAL_DEFINED, * and none of the modifiers turned the undefined * expression into a defined expression. - * XXX: It is not guaranteed that an error message has - * been printed. */ FStr Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) @@ -4542,7 +4543,9 @@ Var_Parse(const char **pp, GNode *scope, bool dynamic; const char *extramodifiers; Var *v; - Expr expr = Expr_Init(NULL, FStr_InitRefer(NULL), emode, + Expr expr = Expr_Init(NULL, FStr_InitRefer(NULL), + emode == VARE_EVAL_DEFINED || emode == VARE_EVAL_DEFINED_LOUD + ? VARE_EVAL : emode, scope, DEF_REGULAR); FStr val; @@ -4566,7 +4569,7 @@ Var_Parse(const char **pp, GNode *scope, haveModifier = false; p++; } else { - if (!ParseVarnameLong(&p, startc, scope, emode, + if (!ParseVarnameLong(&p, startc, scope, emode, expr.emode, pp, &val, &endc, &v, &haveModifier, &extramodifiers, &dynamic, &expr.defined)) @@ -4618,11 +4621,8 @@ Var_Parse(const char **pp, GNode *scope, if (VarEvalMode_ShouldEval(emode) && strchr(Expr_Str(&expr), '$') != NULL) { char *expanded; - VarEvalMode nested_emode = emode; - if (opts.strict) - nested_emode = VarEvalMode_UndefOk(nested_emode); v->inUse = true; - expanded = Var_Subst(Expr_Str(&expr), scope, nested_emode); + expanded = Var_Subst(Expr_Str(&expr), scope, expr.emode); v->inUse = false; /* TODO: handle errors */ Expr_SetValueOwn(&expr, expanded); @@ -4647,13 +4647,9 @@ Var_Parse(const char **pp, GNode *scope, if (dynamic) Expr_SetValueOwn(&expr, bmake_strsedup(start, p)); else { - /* - * The expression is still undefined, therefore - * discard the actual value and return an error marker - * instead. - */ Expr_SetValueRefer(&expr, emode == VARE_EVAL_DEFINED + || emode == VARE_EVAL_DEFINED_LOUD ? var_Error : varUndefined); } } Index: src/usr.bin/make/unit-tests/cond-op-and.exp diff -u src/usr.bin/make/unit-tests/cond-op-and.exp:1.6 src/usr.bin/make/unit-tests/cond-op-and.exp:1.7 --- src/usr.bin/make/unit-tests/cond-op-and.exp:1.6 Tue Aug 6 18:00:16 2024 +++ src/usr.bin/make/unit-tests/cond-op-and.exp Sat Jan 11 21:21:33 2025 @@ -1,6 +1,6 @@ -make: "cond-op-and.mk" line 36: Malformed conditional '0 || (${DEF} && ${UNDEF})' -make: "cond-op-and.mk" line 41: Malformed conditional '0 || (${UNDEF} && ${UNDEF})' -make: "cond-op-and.mk" line 44: Malformed conditional '0 || (!${UNDEF} && ${UNDEF})' +make: "cond-op-and.mk" line 36: Variable "UNDEF" is undefined +make: "cond-op-and.mk" line 41: Variable "UNDEF" is undefined +make: "cond-op-and.mk" line 44: Variable "UNDEF" is undefined make: "cond-op-and.mk" line 60: Unknown operator '&' make: "cond-op-and.mk" line 66: Unknown operator '&' make: "cond-op-and.mk" line 72: Unknown operator '&' Index: src/usr.bin/make/unit-tests/cond-token-var.exp diff -u src/usr.bin/make/unit-tests/cond-token-var.exp:1.6 src/usr.bin/make/unit-tests/cond-token-var.exp:1.7 --- src/usr.bin/make/unit-tests/cond-token-var.exp:1.6 Fri Jan 10 23:00:38 2025 +++ src/usr.bin/make/unit-tests/cond-token-var.exp Sat Jan 11 21:21:33 2025 @@ -1,16 +1,19 @@ make: "cond-token-var.mk" line 23: ok -make: "cond-token-var.mk" line 30: Malformed conditional '${UNDEF} == ${DEF}' -make: "cond-token-var.mk" line 36: Malformed conditional '${DEF} == ${UNDEF}' -make: "cond-token-var.mk" line 46: Malformed conditional '${UNDEF}' -make: "cond-token-var.mk" line 65: Malformed conditional '$U == $D' -make: "cond-token-var.mk" line 71: Malformed conditional '$D == $U' -make: "cond-token-var.mk" line 81: Malformed conditional '$U' -Var_Parse: ${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3} (eval-defined) -make: "cond-token-var.mk" line 109: Malformed conditional 'x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}' -Var_Parse: ${DEF}y == "${UNDEF2}" || 0x${UNDEF3} (eval-defined) -make: "cond-token-var.mk" line 114: Malformed conditional 'x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}' -Var_Parse: ${DEF}y == "${DEF}" || 0x${UNDEF3} (eval-defined) -make: "cond-token-var.mk" line 119: Malformed conditional 'x${DEF}y == "${DEF}" || 0x${UNDEF3}' +make: "cond-token-var.mk" line 30: Variable "UNDEF" is undefined +make: "cond-token-var.mk" line 36: Variable "UNDEF" is undefined +make: "cond-token-var.mk" line 46: Variable "UNDEF" is undefined +make: "cond-token-var.mk" line 64: Variable "U" is undefined +make: "cond-token-var.mk" line 69: Variable "U" is undefined +make: "cond-token-var.mk" line 78: Variable "U" is undefined +Var_Parse: ${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3} (eval) +make: "cond-token-var.mk" line 106: Malformed conditional 'x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}' +Var_Parse: ${DEF}y == "${UNDEF2}" || 0x${UNDEF3} (eval) +make: "cond-token-var.mk" line 111: Malformed conditional 'x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}' +Var_Parse: ${DEF}y == "${DEF}" || 0x${UNDEF3} (eval) +make: "cond-token-var.mk" line 116: Malformed conditional 'x${DEF}y == "${DEF}" || 0x${UNDEF3}' +Global: VAR.param = value of VAR.param +Var_Parse: ${VAR.param$U} (eval-defined-loud) +Var_Parse: $U} (eval) Global: .MAKEFLAGS = -r -k -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 make: Fatal errors encountered -- cannot continue Index: src/usr.bin/make/unit-tests/cond-op-and.mk diff -u src/usr.bin/make/unit-tests/cond-op-and.mk:1.11 src/usr.bin/make/unit-tests/cond-op-and.mk:1.12 --- src/usr.bin/make/unit-tests/cond-op-and.mk:1.11 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/cond-op-and.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-and.mk,v 1.11 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-op-and.mk,v 1.12 2025/01/11 21:21:33 rillig Exp $ # # Tests for the && operator in .if conditions. @@ -32,15 +32,15 @@ # Test combinations of outer '||' with inner '&&', to ensure that the operands # of the inner '&&' are only evaluated if necessary. DEF= defined -# expect+1: Malformed conditional '0 || (${DEF} && ${UNDEF})' +# expect+1: Variable "UNDEF" is undefined .if 0 || (${DEF} && ${UNDEF}) .endif .if 0 || (!${DEF} && ${UNDEF}) .endif -# expect+1: Malformed conditional '0 || (${UNDEF} && ${UNDEF})' +# expect+1: Variable "UNDEF" is undefined .if 0 || (${UNDEF} && ${UNDEF}) .endif -# expect+1: Malformed conditional '0 || (!${UNDEF} && ${UNDEF})' +# expect+1: Variable "UNDEF" is undefined .if 0 || (!${UNDEF} && ${UNDEF}) .endif .if 1 || (${DEF} && ${UNDEF}) Index: src/usr.bin/make/unit-tests/cond-op-or.exp diff -u src/usr.bin/make/unit-tests/cond-op-or.exp:1.7 src/usr.bin/make/unit-tests/cond-op-or.exp:1.8 --- src/usr.bin/make/unit-tests/cond-op-or.exp:1.7 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/cond-op-or.exp Sat Jan 11 21:21:33 2025 @@ -1,6 +1,6 @@ -make: "cond-op-or.mk" line 36: Malformed conditional '1 && (!${DEF} || ${UNDEF})' -make: "cond-op-or.mk" line 41: Malformed conditional '1 && (!${UNDEF} || ${UNDEF})' -make: "cond-op-or.mk" line 44: Malformed conditional '1 && (${UNDEF} || ${UNDEF})' +make: "cond-op-or.mk" line 36: Variable "UNDEF" is undefined +make: "cond-op-or.mk" line 41: Variable "UNDEF" is undefined +make: "cond-op-or.mk" line 44: Variable "UNDEF" is undefined make: "cond-op-or.mk" line 60: Unknown operator '|' make: "cond-op-or.mk" line 66: Unknown operator '|' make: "cond-op-or.mk" line 72: Unknown operator '|' Index: src/usr.bin/make/unit-tests/cond-undef-lint.mk diff -u src/usr.bin/make/unit-tests/cond-undef-lint.mk:1.7 src/usr.bin/make/unit-tests/cond-undef-lint.mk:1.8 --- src/usr.bin/make/unit-tests/cond-undef-lint.mk:1.7 Sat Jan 11 20:54:45 2025 +++ src/usr.bin/make/unit-tests/cond-undef-lint.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: cond-undef-lint.mk,v 1.7 2025/01/11 20:54:45 rillig Exp $ +# $NetBSD: cond-undef-lint.mk,v 1.8 2025/01/11 21:21:33 rillig Exp $ # # Tests for defined and undefined variables in .if conditions, in lint mode. # @@ -31,12 +31,6 @@ DEF= defined # mistake. The variable UNDEF, as used here, can be easily turned into # an expression that is always defined, using the :U modifier. # -# The outer expression does not generate an error message since there was -# already an error evaluating this variable's name. -# -# TODO: Suppress the error message "Variable VAR. is undefined". That part -# of the expression must not be evaluated at all. -# expect+2: Variable "UNDEF" is undefined # expect+1: Variable "VAR." is undefined .if ${VAR.${UNDEF}} . error @@ -44,11 +38,9 @@ DEF= defined . error .endif -# The variable VAR.defined is not defined and thus generates an error message. +# The inner variable DEF is defined, but the resulting name VAR.defined +# refers to an undefined variable, thus an error message. # -# TODO: This pattern looks a lot like CFLAGS.${OPSYS}, which is at least -# debatable. Or would any practical use of CFLAGS.${OPSYS} be via an indirect -# expression, as in the next example? # expect+1: Variable "VAR.defined" is undefined .if ${VAR.${DEF}} . error Index: src/usr.bin/make/unit-tests/var-op-shell.exp diff -u src/usr.bin/make/unit-tests/var-op-shell.exp:1.7 src/usr.bin/make/unit-tests/var-op-shell.exp:1.8 --- src/usr.bin/make/unit-tests/var-op-shell.exp:1.7 Sun Jun 30 11:37:21 2024 +++ src/usr.bin/make/unit-tests/var-op-shell.exp Sat Jan 11 21:21:33 2025 @@ -8,4 +8,10 @@ Capturing the output of command "echo '$ Global: OUTPUT = $$$$ Global: .MAKEFLAGS = -r -k -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 +Var_Parse: ${UNDEF}y (eval-defined) +Capturing the output of command "echo xy" +Global: OUTPUT_OF_UNDEF = xy +Var_Parse: ${OUTPUT_OF_UNDEF} != "xy" (eval-defined-loud) +Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d +Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 exit status 0 Index: src/usr.bin/make/unit-tests/cond-op-or.mk diff -u src/usr.bin/make/unit-tests/cond-op-or.mk:1.13 src/usr.bin/make/unit-tests/cond-op-or.mk:1.14 --- src/usr.bin/make/unit-tests/cond-op-or.mk:1.13 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/cond-op-or.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-or.mk,v 1.13 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-op-or.mk,v 1.14 2025/01/11 21:21:33 rillig Exp $ # # Tests for the || operator in .if conditions. @@ -32,15 +32,15 @@ # Test combinations of outer '&&' with inner '||', to ensure that the operands # of the inner '||' are only evaluated if necessary. DEF= defined -# expect+1: Malformed conditional '1 && (!${DEF} || ${UNDEF})' +# expect+1: Variable "UNDEF" is undefined .if 1 && (!${DEF} || ${UNDEF}) .endif .if 1 && (${DEF} || ${UNDEF}) .endif -# expect+1: Malformed conditional '1 && (!${UNDEF} || ${UNDEF})' +# expect+1: Variable "UNDEF" is undefined .if 1 && (!${UNDEF} || ${UNDEF}) .endif -# expect+1: Malformed conditional '1 && (${UNDEF} || ${UNDEF})' +# expect+1: Variable "UNDEF" is undefined .if 1 && (${UNDEF} || ${UNDEF}) .endif .if 0 && (!${DEF} || ${UNDEF}) Index: src/usr.bin/make/unit-tests/cond-token-var.mk diff -u src/usr.bin/make/unit-tests/cond-token-var.mk:1.10 src/usr.bin/make/unit-tests/cond-token-var.mk:1.11 --- src/usr.bin/make/unit-tests/cond-token-var.mk:1.10 Fri Jan 10 23:00:38 2025 +++ src/usr.bin/make/unit-tests/cond-token-var.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: cond-token-var.mk,v 1.10 2025/01/10 23:00:38 rillig Exp $ +# $NetBSD: cond-token-var.mk,v 1.11 2025/01/11 21:21:33 rillig Exp $ # # Tests for expressions in .if conditions. # @@ -26,13 +26,13 @@ DEF= defined .endif # A variable that appears on the left-hand side must be defined. -# expect+1: Malformed conditional '${UNDEF} == ${DEF}' +# expect+1: Variable "UNDEF" is undefined .if ${UNDEF} == ${DEF} . error .endif # A variable that appears on the right-hand side must be defined. -# expect+1: Malformed conditional '${DEF} == ${UNDEF}' +# expect+1: Variable "UNDEF" is undefined .if ${DEF} == ${UNDEF} . error .endif @@ -42,7 +42,7 @@ DEF= defined .endif # An undefined variable on its own generates a parse error. -# expect+1: Malformed conditional '${UNDEF}' +# expect+1: Variable "UNDEF" is undefined .if ${UNDEF} .endif @@ -60,14 +60,12 @@ DEF= defined .endif # A variable on the left-hand side must be defined. -# FIXME: Replace "Malformed" with "Undefined variable". -# expect+1: Malformed conditional '$U == $D' +# expect+1: Variable "U" is undefined .if $U == $D .endif # A variable on the right-hand side must be defined. -# FIXME: Replace "Malformed" with "Undefined variable". -# expect+1: Malformed conditional '$D == $U' +# expect+1: Variable "U" is undefined .if $D == $U .endif @@ -76,8 +74,7 @@ DEF= defined .endif # An undefined variable without a comparison operator generates a parse error. -# FIXME: Replace "Malformed" with "Undefined variable". -# expect+1: Malformed conditional '$U' +# expect+1: Variable "U" is undefined .if $U .endif @@ -104,18 +101,28 @@ DEF= defined .endif .MAKEFLAGS: -dv -# FIXME: Replace "Malformed" with "Undefined variable". +# The left-hand side of a comparison must not be an unquoted word. # expect+1: Malformed conditional 'x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}' .if x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3} .endif -# FIXME: Replace "Malformed" with "Undefined variable". +# The left-hand side of a comparison must not be an unquoted word. # expect+1: Malformed conditional 'x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}' .if x${DEF}y == "${UNDEF2}" || 0x${UNDEF3} .endif -# FIXME: Replace "Malformed" with "Undefined variable". +# The left-hand side of a comparison must not be an unquoted word. # expect+1: Malformed conditional 'x${DEF}y == "${DEF}" || 0x${UNDEF3}' .if x${DEF}y == "${DEF}" || 0x${UNDEF3} .endif + +# An expression in a condition must not be based on an undefined variable, +# but undefined variables may occur in the variable name or in modifiers. +# +# expect: Var_Parse: ${VAR.param$U} (eval-defined-loud) +# expect: Var_Parse: $U} (eval) +VAR.param= value of VAR.param +.if ${VAR.param$U} +.endif + .MAKEFLAGS: -d0 Index: src/usr.bin/make/unit-tests/var-op-shell.mk diff -u src/usr.bin/make/unit-tests/var-op-shell.mk:1.10 src/usr.bin/make/unit-tests/var-op-shell.mk:1.11 --- src/usr.bin/make/unit-tests/var-op-shell.mk:1.10 Thu Jul 11 20:09:16 2024 +++ src/usr.bin/make/unit-tests/var-op-shell.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: var-op-shell.mk,v 1.10 2024/07/11 20:09:16 sjg Exp $ +# $NetBSD: var-op-shell.mk,v 1.11 2025/01/11 21:21:33 rillig Exp $ # # Tests for the != variable assignment operator, which runs its right-hand # side through the shell. @@ -109,4 +109,13 @@ OUTPUT_LONG!= echo "$$0" || : ${:U:range .endif +# An undefined expression results in an empty string. +.MAKEFLAGS: -dv +OUTPUT_OF_UNDEF!= echo x${UNDEF}y +.if ${OUTPUT_OF_UNDEF} != "xy" +. error +.endif +.MAKEFLAGS: -d0 + + all: Index: src/usr.bin/make/unit-tests/varmod-assign-shell.exp diff -u src/usr.bin/make/unit-tests/varmod-assign-shell.exp:1.10 src/usr.bin/make/unit-tests/varmod-assign-shell.exp:1.11 --- src/usr.bin/make/unit-tests/varmod-assign-shell.exp:1.10 Fri Jan 10 23:00:38 2025 +++ src/usr.bin/make/unit-tests/varmod-assign-shell.exp Sat Jan 11 21:21:33 2025 @@ -4,7 +4,7 @@ Var_Parse: ${ASSIGNED::!=echo output; ${ Evaluating modifier ${ASSIGNED::...} on value "previous" (eval-keep-dollar-and-undefined, regular) Modifier part: "echo output; (exit 13)" Capturing the output of command "echo output; (exit 13)" -make: "varmod-assign-shell.mk" line 32: warning: Command "echo output; (exit 13)" exited with status 13 +make: "varmod-assign-shell.mk" line 26: warning: Command "echo output; (exit 13)" exited with status 13 Result of ${ASSIGNED::!=echo output; ${:U(exit 13)}} is "" (eval-keep-dollar-and-undefined, regular) Global: _ = # (empty) Global: .MAKEFLAGS = -r -k -d v -d Index: src/usr.bin/make/unit-tests/varmod-assign-shell.mk diff -u src/usr.bin/make/unit-tests/varmod-assign-shell.mk:1.10 src/usr.bin/make/unit-tests/varmod-assign-shell.mk:1.11 --- src/usr.bin/make/unit-tests/varmod-assign-shell.mk:1.10 Fri Jan 10 23:00:38 2025 +++ src/usr.bin/make/unit-tests/varmod-assign-shell.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: varmod-assign-shell.mk,v 1.10 2025/01/10 23:00:38 rillig Exp $ +# $NetBSD: varmod-assign-shell.mk,v 1.11 2025/01/11 21:21:33 rillig Exp $ # # Tests for the variable modifier '::!=', which assigns the output of a shell # command to the variable, but only if the command exited successfully. This @@ -20,12 +20,6 @@ DIRECT= previous # expect+1: warning: Command "echo output; (exit 13)" exited with status 13 DIRECT!= echo output; (exit 13) -# An undefined expression results in an empty string. -OUTPUT_OF_UNDEF!= echo x${UNDEF}y -.if ${OUTPUT_OF_UNDEF} != "xy" -. error -.endif - ASSIGNED= previous .MAKEFLAGS: -dv # to see the "Capturing" debug output # expect+1: warning: Command "echo output; (exit 13)" exited with status 13 Index: src/usr.bin/make/unit-tests/cond-undef-lint.exp diff -u src/usr.bin/make/unit-tests/cond-undef-lint.exp:1.8 src/usr.bin/make/unit-tests/cond-undef-lint.exp:1.9 --- src/usr.bin/make/unit-tests/cond-undef-lint.exp:1.8 Sat Jan 11 20:54:45 2025 +++ src/usr.bin/make/unit-tests/cond-undef-lint.exp Sat Jan 11 21:21:33 2025 @@ -1,7 +1,6 @@ make: "cond-undef-lint.mk" line 24: Variable "UNDEF" is undefined -make: "cond-undef-lint.mk" line 41: Variable "UNDEF" is undefined -make: "cond-undef-lint.mk" line 41: Variable "VAR." is undefined -make: "cond-undef-lint.mk" line 53: Variable "VAR.defined" is undefined +make: "cond-undef-lint.mk" line 35: Variable "VAR." is undefined +make: "cond-undef-lint.mk" line 45: Variable "VAR.defined" is undefined make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 Index: src/usr.bin/make/unit-tests/dep-var.exp diff -u src/usr.bin/make/unit-tests/dep-var.exp:1.8 src/usr.bin/make/unit-tests/dep-var.exp:1.9 --- src/usr.bin/make/unit-tests/dep-var.exp:1.8 Tue Jul 9 19:43:01 2024 +++ src/usr.bin/make/unit-tests/dep-var.exp Sat Jan 11 21:21:33 2025 @@ -11,8 +11,8 @@ Global: UNDEF1 = undef1 Global: DEF2 = def2 Global: .ALLTARGETS = all ${DEF2} a-${DEF2}-b ${UNDEF3} 1-${INDIRECT_1}-1 $$) Var_Parse: ${:U\$)}: (eval-defined) -Evaluating modifier ${:U...} on value "" (eval-defined, undefined) -Result of ${:U\$)} is "$)" (eval-defined, defined) +Evaluating modifier ${:U...} on value "" (eval, undefined) +Result of ${:U\$)} is "$)" (eval, defined) Global: .ALLTARGETS = all ${DEF2} a-${DEF2}-b ${UNDEF3} 1-${INDIRECT_1}-1 $$) undef1 Global: .ALLTARGETS = all ${DEF2} a-${DEF2}-b ${UNDEF3} 1-${INDIRECT_1}-1 $$) undef1 def2 Global: .ALLTARGETS = all ${DEF2} a-${DEF2}-b ${UNDEF3} 1-${INDIRECT_1}-1 $$) undef1 def2 a-def2-b Index: src/usr.bin/make/unit-tests/deptgt-makeflags.exp diff -u src/usr.bin/make/unit-tests/deptgt-makeflags.exp:1.8 src/usr.bin/make/unit-tests/deptgt-makeflags.exp:1.9 --- src/usr.bin/make/unit-tests/deptgt-makeflags.exp:1.8 Wed Dec 20 08:50:10 2023 +++ src/usr.bin/make/unit-tests/deptgt-makeflags.exp Sat Jan 11 21:21:33 2025 @@ -2,7 +2,7 @@ Global: ignoring delete 'DOLLAR' as it i Command: DOLLAR = $$$$ Global: .MAKEOVERRIDES = VAR DOLLAR CondParser_Eval: ${DOLLAR} != "\$\$" -Var_Parse: ${DOLLAR} != "\$\$" (eval-defined) +Var_Parse: ${DOLLAR} != "\$\$" (eval-defined-loud) Comparing "$$" != "$$" Global: .MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d Global: .MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d 0 Index: src/usr.bin/make/unit-tests/varname-dot-suffixes.exp diff -u src/usr.bin/make/unit-tests/varname-dot-suffixes.exp:1.8 src/usr.bin/make/unit-tests/varname-dot-suffixes.exp:1.9 --- src/usr.bin/make/unit-tests/varname-dot-suffixes.exp:1.8 Fri Dec 29 14:57:00 2023 +++ src/usr.bin/make/unit-tests/varname-dot-suffixes.exp Sat Jan 11 21:21:34 2025 @@ -19,21 +19,21 @@ Result of ${preserve:_=.SUFFIXES} is "pr Global: _ = preserve Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 -Var_Parse: ${1 2:L:@.SUFFIXES@${.SUFFIXES}@} != ".c .o .1 .err .tar.gz .c .o .1 .err .tar.gz" (eval-defined) -Evaluating modifier ${1 2:L} on value "" (eval-defined, undefined) -Result of ${1 2:L} is "1 2" (eval-defined, defined) -Evaluating modifier ${1 2:@...} on value "1 2" (eval-defined, defined) +Var_Parse: ${1 2:L:@.SUFFIXES@${.SUFFIXES}@} != ".c .o .1 .err .tar.gz .c .o .1 .err .tar.gz" (eval-defined-loud) +Evaluating modifier ${1 2:L} on value "" (eval, undefined) +Result of ${1 2:L} is "1 2" (eval, defined) +Evaluating modifier ${1 2:@...} on value "1 2" (eval, defined) Modifier part: ".SUFFIXES" Modifier part: "${.SUFFIXES}" ModifyWords: split "1 2" into 2 words Command: ignoring '.SUFFIXES = 1' as it is read-only -Var_Parse: ${.SUFFIXES} (eval-defined) +Var_Parse: ${.SUFFIXES} (eval) ModifyWord_Loop: expand "${.SUFFIXES}" to ".c .o .1 .err .tar.gz" Command: ignoring '.SUFFIXES = 2' as it is read-only -Var_Parse: ${.SUFFIXES} (eval-defined) +Var_Parse: ${.SUFFIXES} (eval) ModifyWord_Loop: expand "${.SUFFIXES}" to ".c .o .1 .err .tar.gz" Command: ignoring delete '.SUFFIXES' as it is not found -Result of ${1 2:@.SUFFIXES@${.SUFFIXES}@} is ".c .o .1 .err .tar.gz .c .o .1 .err .tar.gz" (eval-defined, defined) +Result of ${1 2:@.SUFFIXES@${.SUFFIXES}@} is ".c .o .1 .err .tar.gz .c .o .1 .err .tar.gz" (eval, defined) Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 -d v -d 0 exit status 0 Index: src/usr.bin/make/unit-tests/directive-export-impl.exp diff -u src/usr.bin/make/unit-tests/directive-export-impl.exp:1.19 src/usr.bin/make/unit-tests/directive-export-impl.exp:1.20 --- src/usr.bin/make/unit-tests/directive-export-impl.exp:1.19 Thu Oct 31 09:12:13 2024 +++ src/usr.bin/make/unit-tests/directive-export-impl.exp Sat Jan 11 21:21:33 2025 @@ -4,7 +4,7 @@ Parsing directive-export-impl.mk:28: .ex Global: .MAKE.EXPORTED = UT_VAR Parsing directive-export-impl.mk:32: : ${UT_VAR:N*} Var_Parse: ${UT_VAR:N*} (eval-defined) -Var_Parse: ${REF}> (eval-defined) +Var_Parse: ${REF}> (eval) Evaluating modifier ${UT_VAR:N...} on value "<>" Pattern for ':N' is "*" ModifyWords: split "<>" into 1 word @@ -12,8 +12,8 @@ Result of ${UT_VAR:N*} is "" ParseDependency(: ) Parsing directive-export-impl.mk:42: .if ${:!echo "\$UT_VAR"!} != "<>" CondParser_Eval: ${:!echo "\$UT_VAR"!} != "<>" -Var_Parse: ${:!echo "\$UT_VAR"!} != "<>" (eval-defined) -Evaluating modifier ${:!...} on value "" (eval-defined, undefined) +Var_Parse: ${:!echo "\$UT_VAR"!} != "<>" (eval-defined-loud) +Evaluating modifier ${:!...} on value "" (eval, undefined) Modifier part: "echo "$UT_VAR"" Capturing the output of command "echo "$UT_VAR"" Var_Parse: ${.MAKE.EXPORTED:O:u} (eval) @@ -23,11 +23,11 @@ Evaluating modifier ${.MAKE.EXPORTED:u} Result of ${.MAKE.EXPORTED:u} is "UT_VAR" Var_Parse: ${UT_VAR} (eval) Var_Parse: ${REF}> (eval) -Result of ${:!echo "\$UT_VAR"!} is "<>" (eval-defined, defined) +Result of ${:!echo "\$UT_VAR"!} is "<>" (eval, defined) Comparing "<>" != "<>" Parsing directive-export-impl.mk:50: : ${UT_VAR:N*} Var_Parse: ${UT_VAR:N*} (eval-defined) -Var_Parse: ${REF}> (eval-defined) +Var_Parse: ${REF}> (eval) Evaluating modifier ${UT_VAR:N...} on value "<>" Pattern for ':N' is "*" ModifyWords: split "<>" into 1 word @@ -37,8 +37,8 @@ Parsing directive-export-impl.mk:54: REF Global: REF = defined Parsing directive-export-impl.mk:58: .if ${:!echo "\$UT_VAR"!} != "<defined>" CondParser_Eval: ${:!echo "\$UT_VAR"!} != "<defined>" -Var_Parse: ${:!echo "\$UT_VAR"!} != "<defined>" (eval-defined) -Evaluating modifier ${:!...} on value "" (eval-defined, undefined) +Var_Parse: ${:!echo "\$UT_VAR"!} != "<defined>" (eval-defined-loud) +Evaluating modifier ${:!...} on value "" (eval, undefined) Modifier part: "echo "$UT_VAR"" Capturing the output of command "echo "$UT_VAR"" Var_Parse: ${.MAKE.EXPORTED:O:u} (eval) @@ -48,7 +48,7 @@ Evaluating modifier ${.MAKE.EXPORTED:u} Result of ${.MAKE.EXPORTED:u} is "UT_VAR" Var_Parse: ${UT_VAR} (eval) Var_Parse: ${REF}> (eval) -Result of ${:!echo "\$UT_VAR"!} is "<defined>" (eval-defined, defined) +Result of ${:!echo "\$UT_VAR"!} is "<defined>" (eval, defined) Comparing "<defined>" != "<defined>" Parsing directive-export-impl.mk:62: all: ParseDependency(all:) Index: src/usr.bin/make/unit-tests/directive-include-fatal.exp diff -u src/usr.bin/make/unit-tests/directive-include-fatal.exp:1.5 src/usr.bin/make/unit-tests/directive-include-fatal.exp:1.6 --- src/usr.bin/make/unit-tests/directive-include-fatal.exp:1.5 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/directive-include-fatal.exp Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -make: "directive-include-fatal.mk" line 14: Malformed conditional '${UNDEF}' +make: "directive-include-fatal.mk" line 14: Variable "UNDEF" is undefined make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 Index: src/usr.bin/make/unit-tests/directive-include-fatal.mk diff -u src/usr.bin/make/unit-tests/directive-include-fatal.mk:1.5 src/usr.bin/make/unit-tests/directive-include-fatal.mk:1.6 --- src/usr.bin/make/unit-tests/directive-include-fatal.mk:1.5 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/directive-include-fatal.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: directive-include-fatal.mk,v 1.5 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: directive-include-fatal.mk,v 1.6 2025/01/11 21:21:33 rillig Exp $ # # Test for the .include directive combined with fatal errors. # @@ -10,7 +10,7 @@ # the "fatals" counter. # Using an undefined variable in a condition generates a fatal error. -# expect+1: Malformed conditional '${UNDEF}' +# expect+1: Variable "UNDEF" is undefined .if ${UNDEF} .endif Index: src/usr.bin/make/unit-tests/opt-debug-var.exp diff -u src/usr.bin/make/unit-tests/opt-debug-var.exp:1.4 src/usr.bin/make/unit-tests/opt-debug-var.exp:1.5 --- src/usr.bin/make/unit-tests/opt-debug-var.exp:1.4 Fri Jan 10 23:00:38 2025 +++ src/usr.bin/make/unit-tests/opt-debug-var.exp Sat Jan 11 21:21:33 2025 @@ -2,10 +2,10 @@ Global: ASSIGNED = value Global: SUBST = # (empty) Global: SUBST = value Var_Parse: y(ASSIGNED) (eval) -Var_Parse: $U (eval-defined) -make: "opt-debug-var.mk" line 35: Malformed conditional '$U' -Var_Parse: $< (eval-defined) -make: "opt-debug-var.mk" line 42: Malformed conditional '$<' +Var_Parse: $U (eval-defined-loud) +make: "opt-debug-var.mk" line 34: Variable "U" is undefined +Var_Parse: $< (eval-defined-loud) +make: "opt-debug-var.mk" line 40: Variable "<" is undefined Global: .MAKEFLAGS = -r -k -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 make: Fatal errors encountered -- cannot continue Index: src/usr.bin/make/unit-tests/opt-debug-var.mk diff -u src/usr.bin/make/unit-tests/opt-debug-var.mk:1.4 src/usr.bin/make/unit-tests/opt-debug-var.mk:1.5 --- src/usr.bin/make/unit-tests/opt-debug-var.mk:1.4 Fri Jan 10 23:00:38 2025 +++ src/usr.bin/make/unit-tests/opt-debug-var.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: opt-debug-var.mk,v 1.4 2025/01/10 23:00:38 rillig Exp $ +# $NetBSD: opt-debug-var.mk,v 1.5 2025/01/11 21:21:33 rillig Exp $ # # Tests for the -dv command line option, which adds debug logging about # variable assignment and evaluation. @@ -29,16 +29,14 @@ SUBST:= value # An expression for a variable with a single-character ordinary name. -# expect: Var_Parse: $U (eval-defined) -# FIXME: Replace "Malformed" with "Undefined variable". -# expect+1: Malformed conditional '$U' +# expect: Var_Parse: $U (eval-defined-loud) +# expect+1: Variable "U" is undefined .if $U .endif # An expression for a target-specific variable with a single-character name. -# expect: Var_Parse: $< (eval-defined) -# FIXME: Replace "Malformed" with "Undefined variable". -# expect+1: Malformed conditional '$<' +# expect: Var_Parse: $< (eval-defined-loud) +# expect+1: Variable "<" is undefined .if $< .endif Index: src/usr.bin/make/unit-tests/varparse-dynamic.exp diff -u src/usr.bin/make/unit-tests/varparse-dynamic.exp:1.4 src/usr.bin/make/unit-tests/varparse-dynamic.exp:1.5 --- src/usr.bin/make/unit-tests/varparse-dynamic.exp:1.4 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/varparse-dynamic.exp Sat Jan 11 21:21:34 2025 @@ -1,5 +1,5 @@ -make: "varparse-dynamic.mk" line 9: Malformed conditional '${.TARGEX}' -make: "varparse-dynamic.mk" line 12: Malformed conditional '${.TARGXX}' +make: "varparse-dynamic.mk" line 9: Variable ".TARGEX" is undefined +make: "varparse-dynamic.mk" line 12: Variable ".TARGXX" is undefined make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 Index: src/usr.bin/make/unit-tests/vardebug.exp diff -u src/usr.bin/make/unit-tests/vardebug.exp:1.39 src/usr.bin/make/unit-tests/vardebug.exp:1.40 --- src/usr.bin/make/unit-tests/vardebug.exp:1.39 Sat Jan 11 20:54:45 2025 +++ src/usr.bin/make/unit-tests/vardebug.exp Sat Jan 11 21:21:33 2025 @@ -11,57 +11,66 @@ Global: ignoring 'FROM_CMDLINE = overwri Global: VAR = 1 Global: VAR = 1 2 Global: VAR = 1 2 3 -Var_Parse: ${VAR:M[2]} (eval-defined) +Var_Parse: ${VAR:M[2]} (eval-defined-loud) Evaluating modifier ${VAR:M...} on value "1 2 3" Pattern for ':M' is "[2]" ModifyWords: split "1 2 3" into 3 words Result of ${VAR:M[2]} is "2" -Var_Parse: ${VAR:N[2]} (eval-defined) +Var_Parse: ${VAR:N[2]} (eval-defined-loud) Evaluating modifier ${VAR:N...} on value "1 2 3" Pattern for ':N' is "[2]" ModifyWords: split "1 2 3" into 3 words Result of ${VAR:N[2]} is "1 3" -Var_Parse: ${VAR:S,2,two,} (eval-defined) +Var_Parse: ${VAR:S,2,two,} (eval-defined-loud) Evaluating modifier ${VAR:S...} on value "1 2 3" Modifier part: "2" Modifier part: "two" ModifyWords: split "1 2 3" into 3 words Result of ${VAR:S,2,two,} is "1 two 3" -Var_Parse: ${VAR:Q} (eval-defined) +Var_Parse: ${VAR:Q} (eval-defined-loud) Evaluating modifier ${VAR:Q} on value "1 2 3" Result of ${VAR:Q} is "1\ 2\ 3" -Var_Parse: ${VAR:tu:tl:Q} (eval-defined) +Var_Parse: ${VAR:tu:tl:Q} (eval-defined-loud) Evaluating modifier ${VAR:t...} on value "1 2 3" Result of ${VAR:tu} is "1 2 3" Evaluating modifier ${VAR:t...} on value "1 2 3" Result of ${VAR:tl} is "1 2 3" Evaluating modifier ${VAR:Q} on value "1 2 3" Result of ${VAR:Q} is "1\ 2\ 3" -Var_Parse: ${:Uvalue:${:UM*e}:Mvalu[e]} (eval-defined) -Evaluating modifier ${:U...} on value "" (eval-defined, undefined) -Result of ${:Uvalue} is "value" (eval-defined, defined) +Var_Parse: ${:Uvalue:${:UM*e}:Mvalu[e]} (eval-defined-loud) +Evaluating modifier ${:U...} on value "" (eval, undefined) +Result of ${:Uvalue} is "value" (eval, defined) Indirect modifier "M*e" from "${:UM*e}" -Evaluating modifier ${:M...} on value "value" (eval-defined, defined) +Evaluating modifier ${:M...} on value "value" (eval, defined) Pattern for ':M' is "*e" ModifyWords: split "value" into 1 word -Result of ${:M*e} is "value" (eval-defined, defined) -Evaluating modifier ${:M...} on value "value" (eval-defined, defined) +Result of ${:M*e} is "value" (eval, defined) +Evaluating modifier ${:M...} on value "value" (eval, defined) Pattern for ':M' is "valu[e]" ModifyWords: split "value" into 1 word -Result of ${:Mvalu[e]} is "value" (eval-defined, defined) +Result of ${:Mvalu[e]} is "value" (eval, defined) Global: delete VAR -Var_Parse: ${:Uvariable:unknown} (eval-defined) -Evaluating modifier ${:U...} on value "" (eval-defined, undefined) -Result of ${:Uvariable} is "variable" (eval-defined, defined) -Evaluating modifier ${:u...} on value "variable" (eval-defined, defined) +Var_Parse: ${:Uvariable:unknown} (eval-defined-loud) +Evaluating modifier ${:U...} on value "" (eval, undefined) +Result of ${:Uvariable} is "variable" (eval, defined) +Evaluating modifier ${:u...} on value "variable" (eval, defined) make: "vardebug.mk" line 62: Unknown modifier "unknown" while evaluating "${:Uvariable:unknown}" with value "variable" -Result of ${:unknown} is error (eval-defined, defined) -Var_Parse: ${UNDEFINED} (eval-defined) -make: "vardebug.mk" line 72: Malformed conditional '${UNDEFINED}' +Result of ${:unknown} is error (eval, defined) +Var_Parse: ${UNDEFINED} (eval-defined-loud) +make: "vardebug.mk" line 66: Variable "UNDEFINED" is undefined Global: ignoring delete '.SHELL' as it is not found Command: .SHELL = </path/to/shell> Command: ignoring '.SHELL = overwritten' as it is read-only +Global: DYN = ${:U$@} $@ ${@} +Var_Parse: ${DYN} (eval-keep-dollar-and-undefined) +Var_Parse: ${:U$@} $@ ${@} (eval-keep-dollar-and-undefined) +Evaluating modifier ${:U...} on value "" (eval-keep-dollar-and-undefined, undefined) +Var_Parse: $@} $@ ${@} (eval-keep-dollar-and-undefined) +Result of ${:U$@} is "$(.TARGET)" (eval-keep-dollar-and-undefined, defined) +Var_Parse: $@ ${@} (eval-keep-dollar-and-undefined) +Var_Parse: ${@} (eval-keep-dollar-and-undefined) +Global: DYN = $(.TARGET) $(.TARGET) ${@} Global: .MAKEFLAGS = -r -k -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 make: Fatal errors encountered -- cannot continue Index: src/usr.bin/make/unit-tests/vardebug.mk diff -u src/usr.bin/make/unit-tests/vardebug.mk:1.15 src/usr.bin/make/unit-tests/vardebug.mk:1.16 --- src/usr.bin/make/unit-tests/vardebug.mk:1.15 Sat Jan 11 20:54:45 2025 +++ src/usr.bin/make/unit-tests/vardebug.mk Sat Jan 11 21:21:33 2025 @@ -1,4 +1,4 @@ -# $NetBSD: vardebug.mk,v 1.15 2025/01/11 20:54:45 rillig Exp $ +# $NetBSD: vardebug.mk,v 1.16 2025/01/11 21:21:33 rillig Exp $ # # Demonstrates the debugging output for var.c. @@ -48,7 +48,7 @@ VAR+= 3 .endif # ApplyModifiers, "Got ..." -# expect: Result of ${:Mvalu[e]} is "value" (eval-defined, defined) +# expect: Result of ${:Mvalu[e]} is "value" (eval, defined) .if ${:Uvalue:${:UM*e}:Mvalu[e]} .endif @@ -57,18 +57,12 @@ VAR+= 3 # When ApplyModifiers results in an error, this appears in the debug log # as "is error", without surrounding quotes. -# expect: Result of ${:unknown} is error (eval-defined, defined) +# expect: Result of ${:unknown} is error (eval, defined) # expect+1: Unknown modifier "unknown" .if ${:Uvariable:unknown} .endif -# XXX: The error message is "Malformed conditional", which is wrong. -# The condition is syntactically fine, it just contains an undefined variable. -# -# There is a specialized error message for "Undefined variable", but as of -# 2020-08-08, that is not covered by any unit tests. It might even be -# unreachable. -# expect+1: Malformed conditional '${UNDEFINED}' +# expect+1: Variable "UNDEFINED" is undefined .if ${UNDEFINED} .endif @@ -78,4 +72,8 @@ VAR+= 3 # expect: Command: ignoring '.SHELL = overwritten' as it is read-only .MAKEFLAGS: .SHELL=overwritten +DYN = ${:U$@} $@ ${@} +# expect: Global: DYN = $(.TARGET) $(.TARGET) ${@} +DYN := ${DYN} + .MAKEFLAGS: -d0 Index: src/usr.bin/make/unit-tests/varmod-assign.exp diff -u src/usr.bin/make/unit-tests/varmod-assign.exp:1.29 src/usr.bin/make/unit-tests/varmod-assign.exp:1.30 --- src/usr.bin/make/unit-tests/varmod-assign.exp:1.29 Thu Aug 29 20:20:36 2024 +++ src/usr.bin/make/unit-tests/varmod-assign.exp Sat Jan 11 21:21:34 2025 @@ -2,28 +2,28 @@ Global: param = twice Global: VARNAME = VAR.$${param} Var_Parse: ${VARNAME} (eval) Global: VAR.${param} = initial-value -Var_Parse: ${${VARNAME}::=assigned-value} (eval-defined) -Var_Parse: ${VARNAME}::=assigned-value} (eval-defined) +Var_Parse: ${${VARNAME}::=assigned-value} (eval-defined-loud) +Var_Parse: ${VARNAME}::=assigned-value} (eval) Evaluating modifier ${VAR.${param}::...} on value "initial-value" Modifier part: "assigned-value" Global: VAR.${param} = assigned-value Result of ${VAR.${param}::=assigned-value} is "" -Var_Parse: ${${VARNAME}} != "assigned-value" (eval-defined) -Var_Parse: ${VARNAME}} != "assigned-value" (eval-defined) +Var_Parse: ${${VARNAME}} != "assigned-value" (eval-defined-loud) +Var_Parse: ${VARNAME}} != "assigned-value" (eval) Global: .MAKEFLAGS = -r -k -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 -Var_Parse: ${CMD_CMD_VAR::=new-value} || ${CMD_GLOBAL_VAR::=new-value} || ${CMD_ENV_VAR::=new-value} || "${CMD_NEW_VAR::=new-value}" (eval-defined) +Var_Parse: ${CMD_CMD_VAR::=new-value} || ${CMD_GLOBAL_VAR::=new-value} || ${CMD_ENV_VAR::=new-value} || "${CMD_NEW_VAR::=new-value}" (eval-defined-loud) Evaluating modifier ${CMD_CMD_VAR::...} on value "cmd-value" Modifier part: "new-value" Command: CMD_CMD_VAR = new-value Global: .MAKEOVERRIDES = FIRST LAST LAST LAST APPENDED RAN RAN RAN IT1 THEN1 IE2 ELSE2 CMD_CMD_VAR CMD_CMD_VAR Result of ${CMD_CMD_VAR::=new-value} is "" -Var_Parse: ${CMD_GLOBAL_VAR::=new-value} || ${CMD_ENV_VAR::=new-value} || "${CMD_NEW_VAR::=new-value}" (eval-defined) +Var_Parse: ${CMD_GLOBAL_VAR::=new-value} || ${CMD_ENV_VAR::=new-value} || "${CMD_NEW_VAR::=new-value}" (eval-defined-loud) Evaluating modifier ${CMD_GLOBAL_VAR::...} on value "global-value" Modifier part: "new-value" Global: CMD_GLOBAL_VAR = new-value Result of ${CMD_GLOBAL_VAR::=new-value} is "" -Var_Parse: ${CMD_ENV_VAR::=new-value} || "${CMD_NEW_VAR::=new-value}" (eval-defined) +Var_Parse: ${CMD_ENV_VAR::=new-value} || "${CMD_NEW_VAR::=new-value}" (eval-defined-loud) Evaluating modifier ${CMD_ENV_VAR::...} on value "env-value" Modifier part: "new-value" Global: CMD_ENV_VAR = new-value Index: src/usr.bin/make/unit-tests/varmod-match-escape.exp diff -u src/usr.bin/make/unit-tests/varmod-match-escape.exp:1.25 src/usr.bin/make/unit-tests/varmod-match-escape.exp:1.26 --- src/usr.bin/make/unit-tests/varmod-match-escape.exp:1.25 Thu Aug 29 20:20:36 2024 +++ src/usr.bin/make/unit-tests/varmod-match-escape.exp Sat Jan 11 21:21:34 2025 @@ -1,11 +1,11 @@ Global: SPECIALS = \: : \\ * \* CondParser_Eval: ${SPECIALS:M${:U}\:} != ${SPECIALS:M\:${:U}} -Var_Parse: ${SPECIALS:M${:U}\:} != ${SPECIALS:M\:${:U}} (eval-defined) +Var_Parse: ${SPECIALS:M${:U}\:} != ${SPECIALS:M\:${:U}} (eval-defined-loud) Evaluating modifier ${SPECIALS:M...} on value "\: : \\ * \*" Pattern for ':M' is "\:" ModifyWords: split "\: : \\ * \*" into 5 words Result of ${SPECIALS:M${:U}\:} is ":" -Var_Parse: ${SPECIALS:M\:${:U}} (eval-defined) +Var_Parse: ${SPECIALS:M\:${:U}} (eval-defined-loud) Evaluating modifier ${SPECIALS:M...} on value "\: : \\ * \*" Pattern for ':M' is ":" ModifyWords: split "\: : \\ * \*" into 5 words @@ -13,19 +13,19 @@ Result of ${SPECIALS:M\:${:U}} is ":" Comparing ":" != ":" Global: VALUES = : :: :\: CondParser_Eval: ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:} -Var_Parse: ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:} (eval-defined) +Var_Parse: ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:} (eval-defined-loud) Evaluating modifier ${VALUES:M...} on value ": :: :\:" -Var_Parse: ${:U:} (eval-defined) -Evaluating modifier ${:U} on value "" (eval-defined, undefined) -Result of ${:U} is "" (eval-defined, defined) +Var_Parse: ${:U:} (eval) +Evaluating modifier ${:U} on value "" (eval, undefined) +Result of ${:U} is "" (eval, defined) Pattern for ':M' is ":" ModifyWords: split ": :: :\:" into 3 words Result of ${VALUES:M\:${:U\:}} is ":" -Var_Parse: ${VALUES:M${:U\:}\:} (eval-defined) +Var_Parse: ${VALUES:M${:U\:}\:} (eval-defined-loud) Evaluating modifier ${VALUES:M...} on value ": :: :\:" -Var_Parse: ${:U\:}\: (eval-defined) -Evaluating modifier ${:U...} on value "" (eval-defined, undefined) -Result of ${:U\:} is ":" (eval-defined, defined) +Var_Parse: ${:U\:}\: (eval) +Evaluating modifier ${:U...} on value "" (eval, undefined) +Result of ${:U\:} is ":" (eval, defined) Pattern for ':M' is ":\:" ModifyWords: split ": :: :\:" into 3 words Result of ${VALUES:M${:U\:}\:} is "::" Index: src/usr.bin/make/unit-tests/varname-dot-shell.exp diff -u src/usr.bin/make/unit-tests/varname-dot-shell.exp:1.22 src/usr.bin/make/unit-tests/varname-dot-shell.exp:1.23 --- src/usr.bin/make/unit-tests/varname-dot-shell.exp:1.22 Thu Oct 31 09:12:13 2024 +++ src/usr.bin/make/unit-tests/varname-dot-shell.exp Sat Jan 11 21:21:34 2025 @@ -8,16 +8,16 @@ Parsing varname-dot-shell.mk:12: .SHELL= Global: ignoring '.SHELL = overwritten' due to a command line variable of the same name Parsing varname-dot-shell.mk:13: .if ${.SHELL} != ${ORIG_SHELL} CondParser_Eval: ${.SHELL} != ${ORIG_SHELL} -Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined) -Var_Parse: ${ORIG_SHELL} (eval-defined) +Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined-loud) +Var_Parse: ${ORIG_SHELL} (eval-defined-loud) Comparing "(details omitted)" != "(details omitted)" Parsing varname-dot-shell.mk:19: .MAKEFLAGS: .SHELL+=appended ParseDependency(.MAKEFLAGS: .SHELL+=appended) Command: ignoring '.SHELL += appended' as it is read-only Parsing varname-dot-shell.mk:20: .if ${.SHELL} != ${ORIG_SHELL} CondParser_Eval: ${.SHELL} != ${ORIG_SHELL} -Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined) -Var_Parse: ${ORIG_SHELL} (eval-defined) +Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined-loud) +Var_Parse: ${ORIG_SHELL} (eval-defined-loud) Comparing "(details omitted)" != "(details omitted)" Parsing varname-dot-shell.mk:27: .undef .SHELL Global: ignoring delete '.SHELL' as it is not found @@ -25,8 +25,8 @@ Parsing varname-dot-shell.mk:28: .SHELL= Global: ignoring '.SHELL = newly overwritten' due to a command line variable of the same name Parsing varname-dot-shell.mk:29: .if ${.SHELL} != ${ORIG_SHELL} CondParser_Eval: ${.SHELL} != ${ORIG_SHELL} -Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined) -Var_Parse: ${ORIG_SHELL} (eval-defined) +Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined-loud) +Var_Parse: ${ORIG_SHELL} (eval-defined-loud) Comparing "(details omitted)" != "(details omitted)" Parsing varname-dot-shell.mk:33: .MAKEFLAGS: -d0 ParseDependency(.MAKEFLAGS: -d0) Index: src/usr.bin/make/unit-tests/varname.exp diff -u src/usr.bin/make/unit-tests/varname.exp:1.22 src/usr.bin/make/unit-tests/varname.exp:1.23 --- src/usr.bin/make/unit-tests/varname.exp:1.22 Tue Aug 6 17:46:01 2024 +++ src/usr.bin/make/unit-tests/varname.exp Sat Jan 11 21:21:34 2025 @@ -8,8 +8,8 @@ Global: .ALLTARGETS = VAR(((=) make: "varname.mk" line 32: Missing ')' in archive specification make: "varname.mk" line 32: Error in archive specification: "VAR" Var_Parse: ${:UVAR\(\(\(}= try2 (eval-defined) -Evaluating modifier ${:U...} on value "" (eval-defined, undefined) -Result of ${:UVAR\(\(\(} is "VAR\(\(\(" (eval-defined, defined) +Evaluating modifier ${:U...} on value "" (eval, undefined) +Result of ${:UVAR\(\(\(} is "VAR\(\(\(" (eval, defined) Global: .ALLTARGETS = VAR(((=) VAR\(\(\(= make: "varname.mk" line 38: Invalid line '${:UVAR\(\(\(}= try2', expanded to 'VAR\(\(\(= try2' Var_Parse: ${VARNAME} (eval) Index: src/usr.bin/make/unit-tests/varparse-dynamic.mk diff -u src/usr.bin/make/unit-tests/varparse-dynamic.mk:1.9 src/usr.bin/make/unit-tests/varparse-dynamic.mk:1.10 --- src/usr.bin/make/unit-tests/varparse-dynamic.mk:1.9 Tue Aug 6 18:00:17 2024 +++ src/usr.bin/make/unit-tests/varparse-dynamic.mk Sat Jan 11 21:21:34 2025 @@ -1,14 +1,14 @@ -# $NetBSD: varparse-dynamic.mk,v 1.9 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: varparse-dynamic.mk,v 1.10 2025/01/11 21:21:34 rillig Exp $ # Before 2020-07-27, there was an off-by-one error in Var_Parse that skipped # the last character in the variable name. # To trigger the bug, the variable had to be undefined. .if ${.TARGET} # exact match, may be undefined .endif -# expect+1: Malformed conditional '${.TARGEX}' +# expect+1: Variable ".TARGEX" is undefined .if ${.TARGEX} # 1 character difference, must be defined .endif -# expect+1: Malformed conditional '${.TARGXX}' +# expect+1: Variable ".TARGXX" is undefined .if ${.TARGXX} # 2 characters difference, must be defined .endif