aboutsummaryrefslogtreecommitdiff
path: root/unit-tests
diff options
context:
space:
mode:
Diffstat (limited to 'unit-tests')
-rw-r--r--unit-tests/Makefile23
-rw-r--r--unit-tests/archive.exp12
-rw-r--r--unit-tests/archive.mk20
-rw-r--r--unit-tests/cmd-errors-jobs.exp76
-rw-r--r--unit-tests/cmd-errors-jobs.mk115
-rw-r--r--unit-tests/cmd-errors-lint.exp14
-rw-r--r--unit-tests/cmd-errors-lint.mk17
-rw-r--r--unit-tests/cmd-errors.exp14
-rw-r--r--unit-tests/cmd-errors.mk17
-rwxr-xr-xunit-tests/cmd-interrupt.exp1
-rwxr-xr-xunit-tests/cmd-interrupt.mk24
-rw-r--r--unit-tests/cmdline.exp4
-rw-r--r--unit-tests/cmdline.mk8
-rw-r--r--unit-tests/cond-cmp-numeric-eq.exp4
-rwxr-xr-xunit-tests/cond-cmp-numeric-eq.mk6
-rw-r--r--unit-tests/cond-cmp-numeric.exp2
-rw-r--r--unit-tests/cond-cmp-numeric.mk4
-rw-r--r--unit-tests/cond-cmp-string.exp8
-rw-r--r--unit-tests/cond-cmp-string.mk10
-rw-r--r--unit-tests/cond-eof.exp6
-rw-r--r--unit-tests/cond-eof.mk8
-rw-r--r--unit-tests/cond-func-commands.mk7
-rw-r--r--unit-tests/cond-func-defined.exp4
-rw-r--r--unit-tests/cond-func-defined.mk11
-rw-r--r--unit-tests/cond-func-empty.exp3
-rw-r--r--unit-tests/cond-func-empty.mk9
-rw-r--r--unit-tests/cond-func-exists.mk7
-rw-r--r--unit-tests/cond-func-make.mk7
-rw-r--r--unit-tests/cond-func-target.mk7
-rw-r--r--unit-tests/cond-func.exp9
-rw-r--r--unit-tests/cond-func.mk17
-rw-r--r--unit-tests/cond-late.exp4
-rw-r--r--unit-tests/cond-late.mk4
-rw-r--r--unit-tests/cond-op-and.exp6
-rw-r--r--unit-tests/cond-op-and.mk8
-rw-r--r--unit-tests/cond-op-not.exp2
-rw-r--r--unit-tests/cond-op-not.mk4
-rw-r--r--unit-tests/cond-op-or.exp6
-rw-r--r--unit-tests/cond-op-or.mk8
-rw-r--r--unit-tests/cond-op-parentheses.exp6
-rw-r--r--unit-tests/cond-op-parentheses.mk8
-rw-r--r--unit-tests/cond-op.exp14
-rw-r--r--unit-tests/cond-op.mk16
-rw-r--r--unit-tests/cond-token-number.exp8
-rw-r--r--unit-tests/cond-token-number.mk10
-rw-r--r--unit-tests/cond-token-plain.exp12
-rw-r--r--unit-tests/cond-token-plain.mk14
-rw-r--r--unit-tests/cond-token-string.exp20
-rw-r--r--unit-tests/cond-token-string.mk7
-rw-r--r--unit-tests/cond-token-var.exp22
-rw-r--r--unit-tests/cond-token-var.mk65
-rwxr-xr-xunit-tests/cond-undef-lint.exp10
-rwxr-xr-xunit-tests/cond-undef-lint.mk21
-rwxr-xr-xunit-tests/dep-var.exp8
-rwxr-xr-xunit-tests/dep-var.mk20
-rw-r--r--unit-tests/deptgt-makeflags.exp2
-rw-r--r--unit-tests/deptgt-order.exp4
-rw-r--r--unit-tests/deptgt.exp28
-rw-r--r--unit-tests/deptgt.mk12
-rw-r--r--unit-tests/directive-export-impl.exp38
-rw-r--r--unit-tests/directive-for-errors.exp3
-rw-r--r--unit-tests/directive-for-errors.mk4
-rw-r--r--unit-tests/directive-for-escape.exp12
-rw-r--r--unit-tests/directive-for-escape.mk6
-rwxr-xr-xunit-tests/directive-for.exp3
-rwxr-xr-xunit-tests/directive-for.mk4
-rw-r--r--unit-tests/directive-if-nested.mk4
-rw-r--r--unit-tests/directive-if.exp2
-rw-r--r--unit-tests/directive-if.mk4
-rwxr-xr-xunit-tests/directive-include-fatal.exp2
-rwxr-xr-xunit-tests/directive-include-fatal.mk4
-rw-r--r--unit-tests/directive-include-guard.exp6
-rw-r--r--unit-tests/directive-include-guard.mk26
-rwxr-xr-xunit-tests/directive-include.exp3
-rwxr-xr-xunit-tests/directive-include.mk6
-rw-r--r--unit-tests/directive-undef.exp3
-rw-r--r--unit-tests/directive-undef.mk4
-rw-r--r--unit-tests/include-main.exp4
-rwxr-xr-xunit-tests/lint.exp6
-rw-r--r--unit-tests/moderrs.exp233
-rw-r--r--unit-tests/moderrs.mk175
-rw-r--r--unit-tests/opt-debug-lint.exp15
-rw-r--r--unit-tests/opt-debug-lint.mk10
-rw-r--r--unit-tests/opt-debug-parse.exp14
-rw-r--r--unit-tests/opt-debug-var.exp8
-rw-r--r--unit-tests/opt-debug-var.mk19
-rw-r--r--unit-tests/suff-incomplete.exp12
-rw-r--r--unit-tests/suff-main-several.exp30
-rw-r--r--unit-tests/suff-rebuild.exp22
-rw-r--r--unit-tests/suff.exp146
-rw-r--r--unit-tests/suff.mk41
-rw-r--r--unit-tests/var-eval-short.exp12
-rw-r--r--unit-tests/var-eval-short.mk5
-rw-r--r--unit-tests/var-op-expand.exp8
-rw-r--r--unit-tests/var-op-expand.mk6
-rw-r--r--unit-tests/var-op-shell.exp6
-rw-r--r--unit-tests/var-op-shell.mk11
-rw-r--r--unit-tests/var-recursive.exp41
-rw-r--r--unit-tests/var-recursive.mk77
-rw-r--r--unit-tests/vardebug.exp51
-rw-r--r--unit-tests/vardebug.mk21
-rw-r--r--unit-tests/varmisc.exp45
-rw-r--r--unit-tests/varmisc.mk30
-rw-r--r--unit-tests/varmod-assign-shell.exp2
-rw-r--r--unit-tests/varmod-assign-shell.mk4
-rw-r--r--unit-tests/varmod-assign.exp38
-rw-r--r--unit-tests/varmod-assign.mk27
-rw-r--r--unit-tests/varmod-edge.exp29
-rw-r--r--unit-tests/varmod-edge.mk20
-rw-r--r--unit-tests/varmod-gmtime.exp20
-rw-r--r--unit-tests/varmod-gmtime.mk17
-rw-r--r--unit-tests/varmod-hash.exp15
-rw-r--r--unit-tests/varmod-hash.mk9
-rw-r--r--unit-tests/varmod-ifelse.exp63
-rw-r--r--unit-tests/varmod-ifelse.mk28
-rw-r--r--unit-tests/varmod-indirect.exp22
-rw-r--r--unit-tests/varmod-indirect.mk10
-rw-r--r--unit-tests/varmod-localtime.exp20
-rw-r--r--unit-tests/varmod-localtime.mk17
-rw-r--r--unit-tests/varmod-loop-delete.exp4
-rw-r--r--unit-tests/varmod-loop-delete.mk4
-rw-r--r--unit-tests/varmod-loop-varname.exp16
-rw-r--r--unit-tests/varmod-loop-varname.mk14
-rw-r--r--unit-tests/varmod-loop.exp10
-rwxr-xr-xunit-tests/varmod-match-escape.exp29
-rwxr-xr-xunit-tests/varmod-match-escape.mk8
-rw-r--r--unit-tests/varmod-match.exp31
-rw-r--r--unit-tests/varmod-match.mk23
-rw-r--r--unit-tests/varmod-mtime.exp23
-rw-r--r--unit-tests/varmod-mtime.mk19
-rw-r--r--unit-tests/varmod-order.exp49
-rw-r--r--unit-tests/varmod-order.mk43
-rw-r--r--unit-tests/varmod-range.exp22
-rw-r--r--unit-tests/varmod-range.mk19
-rw-r--r--unit-tests/varmod-select-words.exp60
-rw-r--r--unit-tests/varmod-select-words.mk66
-rw-r--r--unit-tests/varmod-shell.exp6
-rw-r--r--unit-tests/varmod-shell.mk8
-rw-r--r--unit-tests/varmod-subst-regex.exp73
-rw-r--r--unit-tests/varmod-subst-regex.mk16
-rw-r--r--unit-tests/varmod-subst.exp5
-rw-r--r--unit-tests/varmod-subst.mk3
-rw-r--r--unit-tests/varmod-sun-shell.exp4
-rw-r--r--unit-tests/varmod-sun-shell.mk6
-rw-r--r--unit-tests/varmod-sysv.exp8
-rw-r--r--unit-tests/varmod-sysv.mk8
-rw-r--r--unit-tests/varmod-to-separator.exp52
-rw-r--r--unit-tests/varmod-to-separator.mk41
-rw-r--r--unit-tests/varmod.exp65
-rw-r--r--unit-tests/varmod.mk48
-rw-r--r--unit-tests/varname-dot-make-level.exp10
-rw-r--r--unit-tests/varname-dot-make-level.mk9
-rwxr-xr-xunit-tests/varname-dot-shell.exp30
-rw-r--r--unit-tests/varname-dot-suffixes.exp14
-rw-r--r--unit-tests/varname.exp8
-rw-r--r--unit-tests/varname.mk6
-rw-r--r--unit-tests/varparse-dynamic.exp4
-rw-r--r--unit-tests/varparse-dynamic.mk6
-rw-r--r--unit-tests/varparse-errors.exp64
-rw-r--r--unit-tests/varparse-errors.mk44
160 files changed, 2019 insertions, 1305 deletions
diff --git a/unit-tests/Makefile b/unit-tests/Makefile
index 319643b135a0..e83758871bba 100644
--- a/unit-tests/Makefile
+++ b/unit-tests/Makefile
@@ -1,6 +1,6 @@
-# $Id: Makefile,v 1.224 2024/07/13 05:27:35 sjg Exp $
+# $Id: Makefile,v 1.230 2025/01/30 18:04:20 sjg Exp $
#
-# $NetBSD: Makefile,v 1.350 2024/07/07 09:37:00 rillig Exp $
+# $NetBSD: Makefile,v 1.355 2025/01/25 22:46:30 sjg Exp $
#
# Unit tests for make(1)
#
@@ -46,6 +46,11 @@ TMPDIR:= /tmp/uid${.MAKE.UID}
.if !exist(${TMPDIR})
_!= mkdir -p ${TMPDIR}
.endif
+# and clean it up - outside the context of
+# any target that might be using it.
+.END: rm-tmpdir
+rm-tmpdir: .NOMETA
+ @rm -rf ${TMPDIR}
# Each test is in a sub-makefile.
# Keep the list sorted.
@@ -314,6 +319,7 @@ TESTS+= shell-custom
TESTS+= shell-ksh
.endif
TESTS+= shell-sh
+TESTS+= suff
TESTS+= suff-add-later
TESTS+= suff-clear-regular
TESTS+= suff-clear-single
@@ -575,7 +581,7 @@ SED_CMDS.deptgt-phony= ${STD_SED_CMDS.dd}
SED_CMDS.dir= ${STD_SED_CMDS.dd}
SED_CMDS.directive-include-guard= \
-e '/\.MAKEFLAGS/d' \
- -e '/^Parsing line/d' \
+ -e '/^Parsing .*:[1-9][0-9]*:/d' \
-e '/^SetFilenameVars:/d' \
-e '/^ParseDependency/d' \
-e '/^ParseEOF:/d'
@@ -857,11 +863,12 @@ SED_CMDS.opt-debug-jobs+= -e 's,Command: <shell> -v,Command: <shell>,'
.rawout.out:
@${TOOL_SED} ${_SED_CMDS} ${SED_CMDS.${.PREFIX:T}} \
- < ${.IMPSRC} > ${.TARGET}.tmp1
- @${POSTPROC.${.PREFIX:T}:Ucat} < ${.TARGET}.tmp1 > ${.TARGET}.tmp2
- @rm ${.TARGET}.tmp1
- @echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp2
- @mv ${.TARGET}.tmp2 ${.TARGET}
+ < ${.IMPSRC} > ${.TARGET}.tmp
+ @${POSTPROC.${.PREFIX:T}:D \
+ ${POSTPROC.${.PREFIX:T}} < ${.TARGET}.tmp > ${.TARGET}.post \
+ && mv ${.TARGET}.post ${.TARGET}.tmp}
+ @echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp
+ @mv ${.TARGET}.tmp ${.TARGET}
.if empty(DIFF_FLAGS)
DIFF_ECHO= echo
diff --git a/unit-tests/archive.exp b/unit-tests/archive.exp
index 5cf847388544..89e7b7878b4e 100644
--- a/unit-tests/archive.exp
+++ b/unit-tests/archive.exp
@@ -18,6 +18,18 @@ list-archive-wildcard: archive-suffix.mk
list-archive-wildcard: archive.mk
list-archive-wildcard: ternary.mk
+make: "archive.mk" line 61: Error in source archive spec "libprog.a${UNDEF}(archive.mk) pre post"
+ in directory <curdir>
+make: Fatal errors encountered -- cannot continue
+make: stopped making "list-archive-undef-archive" in unit-tests
+exit 1
+
+make: "archive.mk" line 68: Error in source archive spec "libprog.a"
+ in directory <curdir>
+make: Fatal errors encountered -- cannot continue
+make: stopped making "list-archive-undef-member" in unit-tests
+exit 1
+
Making depend-on-existing-member out-of-date archive.mk
depend-on-existing-member
diff --git a/unit-tests/archive.mk b/unit-tests/archive.mk
index eef64396f419..f19c63f29632 100644
--- a/unit-tests/archive.mk
+++ b/unit-tests/archive.mk
@@ -1,4 +1,4 @@
-# $NetBSD: archive.mk,v 1.13 2024/04/27 20:23:22 rillig Exp $
+# $NetBSD: archive.mk,v 1.14 2025/01/10 23:00:38 rillig Exp $
#
# Very basic demonstration of handling archives, based on the description
# in PSD.doc/tutorial.ms.
@@ -21,6 +21,10 @@ all:
@${MAKE} -f ${MAKEFILE} create-archive
@${MAKE} -f ${MAKEFILE} list-archive
@${MAKE} -f ${MAKEFILE} list-archive-wildcard
+ @${MAKE} -f ${MAKEFILE} list-archive-undef-archive || echo "exit $$?"
+ @echo
+ @${MAKE} -f ${MAKEFILE} list-archive-undef-member || echo "exit $$?"
+ @echo
@${MAKE} -f ${MAKEFILE} depend-on-existing-member
@${MAKE} -f ${MAKEFILE} depend-on-nonexistent-member
@${MAKE} -f ${MAKEFILE} remove-archive
@@ -51,6 +55,20 @@ list-archive: ${ARCHIVE} pre post
list-archive-wildcard: ${ARCHIVE}([at]*.mk) pre post
@printf '%s\n' ${.ALLSRC:O:@member@${.TARGET:Q}': '${member:Q}@}
+.if make(list-archive-undef-archive)
+# TODO: Be more specific: mention that the variable "UNDEF" is not defined.
+# expect+1: Error in source archive spec "libprog.a${UNDEF}(archive.mk) pre post"
+list-archive-undef-archive: ${ARCHIVE}$${UNDEF}(archive.mk) pre post
+ @printf '%s\n' ${.ALLSRC:O:@member@${.TARGET:Q}': '${member:Q}@}
+.endif
+
+.if make(list-archive-undef-member)
+# TODO: Be more specific: mention that the variable "UNDEF" is not defined.
+# expect+1: Error in source archive spec "libprog.a"
+list-archive-undef-member: ${ARCHIVE}(archive$${UNDEF}.mk) pre post
+ @printf '%s\n' ${.ALLSRC:O:@member@${.TARGET:Q}': '${member:Q}@}
+.endif
+
depend-on-existing-member: ${ARCHIVE}(archive.mk) pre post
@echo $@
diff --git a/unit-tests/cmd-errors-jobs.exp b/unit-tests/cmd-errors-jobs.exp
index 074ceb3bcf28..7177cd4d18f8 100644
--- a/unit-tests/cmd-errors-jobs.exp
+++ b/unit-tests/cmd-errors-jobs.exp
@@ -1,9 +1,67 @@
-: undefined--eol
-make: in target "unclosed-expression": Unclosed variable "UNCLOSED"
-: unclosed-expression-
-make: in target "unclosed-modifier": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}'
-: unclosed-modifier-
-make: in target "unknown-modifier": while evaluating variable "UNKNOWN" with value "": Unknown modifier "Z"
-: unknown-modifier--eol
-: end-eol
-exit status 2
+begin undefined-direct
+: undefined-direct--eol
+end undefined-direct with status 0
+
+begin undefined-indirect
+: undefined-direct--eol
+end undefined-indirect with status 0
+
+begin parse-error-direct
+make: Unclosed variable "UNCLOSED"
+ in target "parse-error-unclosed-expression"
+make: Unclosed expression, expecting '}'
+ while evaluating variable "UNCLOSED" with value ""
+ in target "parse-error-unclosed-modifier"
+make: Unknown modifier "Z"
+ while evaluating variable "UNKNOWN" with value ""
+ in target "parse-error-unknown-modifier"
+end parse-error-direct with status 2
+
+begin parse-error-indirect
+make: Unclosed variable "UNCLOSED"
+ in target "parse-error-unclosed-expression"
+make: Unclosed expression, expecting '}'
+ while evaluating variable "UNCLOSED" with value ""
+ in target "parse-error-unclosed-modifier"
+make: Unknown modifier "Z"
+ while evaluating variable "UNKNOWN" with value ""
+ in target "parse-error-unknown-modifier"
+end parse-error-indirect with status 2
+
+begin begin-direct
+(exit 13) # .BEGIN
+*** Error code 13 (continuing)
+
+
+Stop.
+make: stopped making "begin-direct" in unit-tests
+end begin-direct with status 1
+
+begin begin-indirect
+(exit 13) # before-begin
+*** Error code 13 (continuing)
+
+
+Stop.
+make: stopped making "begin-indirect" in unit-tests
+end begin-indirect with status 1
+
+begin end-direct
+(exit 13) # .END
+*** Error code 13 (continuing)
+
+
+Stop.
+make: stopped making "end-direct" in unit-tests
+end end-direct with status 1
+
+begin end-indirect
+(exit 13) # before-end
+*** Error code 13 (continuing)
+
+
+Stop.
+make: stopped making "end-indirect" in unit-tests
+end end-indirect with status 1
+
+exit status 0
diff --git a/unit-tests/cmd-errors-jobs.mk b/unit-tests/cmd-errors-jobs.mk
index c24aa51907a2..471f2cbb327c 100644
--- a/unit-tests/cmd-errors-jobs.mk
+++ b/unit-tests/cmd-errors-jobs.mk
@@ -1,38 +1,105 @@
-# $NetBSD: cmd-errors-jobs.mk,v 1.8 2024/07/09 19:43:01 rillig Exp $
+# $NetBSD: cmd-errors-jobs.mk,v 1.13 2024/08/29 20:20:35 rillig Exp $
#
# Demonstrate how errors in expressions affect whether the commands
# are actually executed in jobs mode.
-.MAKEFLAGS: -j1
+RUN= @ run() { \
+ echo "begin $$*" \
+ && ${MAKE} -f ${MAKEFILE} -j1 "$$*" \
+ && echo "end $$* with status $$?" \
+ || echo "end $$* with status $$?" \
+ && echo; \
+ } && run
+
+all:
+ ${RUN} undefined-direct
+ ${RUN} undefined-indirect
+ ${RUN} parse-error-direct
+ ${RUN} parse-error-indirect
+ ${RUN} begin-direct
+ ${RUN} begin-indirect
+ ${RUN} end-direct
+ ${RUN} end-indirect
-all: undefined unclosed-expression unclosed-modifier unknown-modifier end
# Undefined variables in expressions are not an error. They expand to empty
# strings.
-# expect: : undefined--eol
-undefined:
+# expect: : undefined-direct--eol
+# expect: end undefined-direct with status 0
+# expect: : undefined-direct--eol
+# expect: end undefined-indirect with status 0
+undefined-indirect: undefined-direct
+undefined-direct:
: $@-${UNDEFINED}-eol
-unclosed-expression:
-# expect: make: in target "unclosed-expression": Unclosed variable "UNCLOSED"
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unclosed-expression-
- : $@-${UNCLOSED
-unclosed-modifier:
-# expect: make: in target "unclosed-modifier": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}'
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unclosed-modifier-
- : $@-${UNCLOSED:
+parse-error-indirect: parse-error-direct
+parse-error-direct: parse-error-unclosed-expression
+parse-error-direct: parse-error-unclosed-modifier
+parse-error-direct: parse-error-unknown-modifier
+
+parse-error-unclosed-expression:
+ : unexpected $@-${UNCLOSED
+
+parse-error-unclosed-modifier:
+ : unexpected $@-${UNCLOSED:
+
+parse-error-unknown-modifier:
+ : unexpected $@-${UNKNOWN:Z}-eol
+
+# expect-not: : unexpected
+# expect: make: Unclosed variable "UNCLOSED"
+# expect: make: Unclosed expression, expecting '}'
+# expect: make: Unknown modifier "Z"
+# expect: end parse-error-direct with status 2
+# expect: make: Unclosed variable "UNCLOSED"
+# expect: make: Unclosed expression, expecting '}'
+# expect: make: Unknown modifier "Z"
+# expect: end parse-error-indirect with status 2
+
+
+.if make(begin-direct)
+begin-direct:
+.BEGIN:
+ (exit 13) # $@
+.endif
+# expect: begin begin-direct
+# expect: make: stopped making "begin-direct" in unit-tests
+# expect: end begin-direct with status 1
+
+
+.if make(begin-indirect)
+begin-indirect:
+.BEGIN: before-begin
+ : Making $@
+before-begin:
+ (exit 13) # $@
+.endif
+# expect: begin begin-indirect
+# expect: *** Error code 13 (continuing)
+# expect: make: stopped making "begin-indirect" in unit-tests
+# expect: end begin-indirect with status 1
-unknown-modifier:
-# expect: make: in target "unknown-modifier": while evaluating variable "UNKNOWN" with value "": Unknown modifier "Z"
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unknown-modifier--eol
- : $@-${UNKNOWN:Z}-eol
-# expect: : end-eol
-end:
- : $@-eol
+.if make(end-direct)
+end-direct:
+.END:
+ (exit 13) # $@
+.endif
+# expect: begin end-direct
+# expect: *** Error code 13 (continuing)
+# expect: Stop.
+# expect: make: stopped making "end-direct" in unit-tests
+# expect: end end-direct with status 1
-# expect: exit status 2
+.if make(end-indirect)
+end-indirect:
+.END: before-end
+ : Making $@
+before-end:
+ (exit 13) # $@
+.endif
+# expect: begin end-indirect
+# expect: *** Error code 13 (continuing)
+# expect: make: stopped making "end-indirect" in unit-tests
+# expect: end end-indirect with status 1
diff --git a/unit-tests/cmd-errors-lint.exp b/unit-tests/cmd-errors-lint.exp
index a5b129c78f92..116e9957a2c5 100644
--- a/unit-tests/cmd-errors-lint.exp
+++ b/unit-tests/cmd-errors-lint.exp
@@ -1,9 +1,11 @@
: undefined
-make: in target "unclosed-expression": Unclosed variable "UNCLOSED"
-: unclosed-expression
-make: in target "unclosed-modifier": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}'
-: unclosed-modifier
-make: in target "unknown-modifier": while evaluating variable "UNKNOWN" with value "": Unknown modifier "Z"
-: unknown-modifier
+make: Unclosed variable "UNCLOSED"
+ in target "unclosed-expression"
+make: Unclosed expression, expecting '}'
+ while evaluating variable "UNCLOSED" with value ""
+ in target "unclosed-modifier"
+make: Unknown modifier "Z"
+ while evaluating variable "UNKNOWN" with value ""
+ in target "unknown-modifier"
: end
exit status 2
diff --git a/unit-tests/cmd-errors-lint.mk b/unit-tests/cmd-errors-lint.mk
index f870fceaa5cb..873f05c6186f 100644
--- a/unit-tests/cmd-errors-lint.mk
+++ b/unit-tests/cmd-errors-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cmd-errors-lint.mk,v 1.4 2024/07/05 18:59:33 rillig Exp $
+# $NetBSD: cmd-errors-lint.mk,v 1.6 2024/08/29 20:20:35 rillig Exp $
#
# Demonstrate how errors in expressions affect whether the commands
# are actually executed.
@@ -14,21 +14,18 @@ undefined:
: $@ ${UNDEFINED}
unclosed-expression:
-# expect: make: in target "unclosed-expression": Unclosed variable "UNCLOSED"
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unclosed-expression
+# expect: make: Unclosed variable "UNCLOSED"
+# expect-not: : unclosed-expression
: $@ ${UNCLOSED
unclosed-modifier:
-# expect: make: in target "unclosed-modifier": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}'
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unclosed-modifier
+# expect: make: Unclosed expression, expecting '}'
+# expect-not: : unclosed-modifier
: $@ ${UNCLOSED:
unknown-modifier:
-# expect: make: in target "unknown-modifier": while evaluating variable "UNKNOWN" with value "": Unknown modifier "Z"
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unknown-modifier
+# expect: make: Unknown modifier "Z"
+# expect-not: : unknown-modifier
: $@ ${UNKNOWN:Z}
end:
diff --git a/unit-tests/cmd-errors.exp b/unit-tests/cmd-errors.exp
index 074ceb3bcf28..865072ecbf86 100644
--- a/unit-tests/cmd-errors.exp
+++ b/unit-tests/cmd-errors.exp
@@ -1,9 +1,11 @@
: undefined--eol
-make: in target "unclosed-expression": Unclosed variable "UNCLOSED"
-: unclosed-expression-
-make: in target "unclosed-modifier": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}'
-: unclosed-modifier-
-make: in target "unknown-modifier": while evaluating variable "UNKNOWN" with value "": Unknown modifier "Z"
-: unknown-modifier--eol
+make: Unclosed variable "UNCLOSED"
+ in target "unclosed-expression"
+make: Unclosed expression, expecting '}'
+ while evaluating variable "UNCLOSED" with value ""
+ in target "unclosed-modifier"
+make: Unknown modifier "Z"
+ while evaluating variable "UNKNOWN" with value ""
+ in target "unknown-modifier"
: end-eol
exit status 2
diff --git a/unit-tests/cmd-errors.mk b/unit-tests/cmd-errors.mk
index d9525df6064e..0acc811d43bc 100644
--- a/unit-tests/cmd-errors.mk
+++ b/unit-tests/cmd-errors.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cmd-errors.mk,v 1.9 2024/07/09 19:43:01 rillig Exp $
+# $NetBSD: cmd-errors.mk,v 1.11 2024/08/29 20:20:35 rillig Exp $
#
# Demonstrate how errors in expressions affect whether the commands
# are actually executed in compat mode.
@@ -12,21 +12,18 @@ undefined:
: $@-${UNDEFINED}-eol
unclosed-expression:
-# expect: make: in target "unclosed-expression": Unclosed variable "UNCLOSED"
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unclosed-expression-
+# expect: make: Unclosed variable "UNCLOSED"
+# expect-not: : unclosed-expression-
: $@-${UNCLOSED
unclosed-modifier:
-# expect: make: in target "unclosed-modifier": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}'
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unclosed-modifier-
+# expect: make: Unclosed expression, expecting '}'
+# expect-not: : unclosed-modifier-
: $@-${UNCLOSED:
unknown-modifier:
-# expect: make: in target "unknown-modifier": while evaluating variable "UNKNOWN" with value "": Unknown modifier "Z"
-# XXX: This command is executed even though it contains parse errors.
-# expect: : unknown-modifier--eol
+# expect: make: Unknown modifier "Z"
+# expect-not: : unknown-modifier--eol
: $@-${UNKNOWN:Z}-eol
end:
diff --git a/unit-tests/cmd-interrupt.exp b/unit-tests/cmd-interrupt.exp
index 242db1d9507d..e03b64870fa3 100755
--- a/unit-tests/cmd-interrupt.exp
+++ b/unit-tests/cmd-interrupt.exp
@@ -5,4 +5,5 @@ interrupt-ordinary: ok
interrupt-phony: ok
> cmd-interrupt-precious
interrupt-precious: ok
+interrupt-compat expected-fail
exit status 0
diff --git a/unit-tests/cmd-interrupt.mk b/unit-tests/cmd-interrupt.mk
index 140651b55c62..7ee53c6c2105 100755
--- a/unit-tests/cmd-interrupt.mk
+++ b/unit-tests/cmd-interrupt.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cmd-interrupt.mk,v 1.4 2023/03/18 22:20:12 sjg Exp $
+# $NetBSD: cmd-interrupt.mk,v 1.5 2024/07/13 15:10:06 rillig Exp $
#
# Tests for interrupting a command.
#
@@ -17,10 +17,16 @@
# See also:
# CompatDeleteTarget
-all: clean-before interrupt-ordinary interrupt-phony interrupt-precious clean-after
+all: clean-before
+all: interrupt-ordinary
+all: interrupt-phony
+all: interrupt-precious
+all: interrupt-compat
+all: clean-after
clean-before clean-after: .PHONY
- @rm -f cmd-interrupt-ordinary cmd-interrupt-phony cmd-interrupt-precious
+ @rm -f cmd-interrupt-ordinary cmd-interrupt-phony
+ @rm -f cmd-interrupt-precious cmd-interrupt-compat
interrupt-ordinary:
@${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-ordinary || true
@@ -37,6 +43,10 @@ interrupt-precious: .PRECIOUS
# The ././ is necessary to work around the file cache.
@echo ${.TARGET}: ${exists(././cmd-interrupt-precious) :? ok : error }
+interrupt-compat:
+ @${MAKE} -f ${MAKEFILE} cmd-interrupt-compat || true
+ @echo ${.TARGET} ${exists(././cmd-interrupt-compat) :? expected-fail : unexpected-ok }
+
cmd-interrupt-ordinary:
> ${.TARGET}
@kill -INT ${.MAKE.PID}
@@ -48,3 +58,11 @@ cmd-interrupt-phony: .PHONY
cmd-interrupt-precious: .PRECIOUS
> ${.TARGET}
@kill -INT ${.MAKE.PID}
+
+# When the make process (and not the process group) is interrupted in compat
+# mode, it first tries to interrupt the process group of the currently running
+# child command, but that fails since there is no such process group, rather
+# the child command runs in the same process group as make itself. The child
+# command then continues, and after sleeping a bit creates the target file.
+cmd-interrupt-compat:
+ @kill -INT ${.MAKE.PID} && sleep 1 && > ${.TARGET}
diff --git a/unit-tests/cmdline.exp b/unit-tests/cmdline.exp
index 5700da3295fb..063be7e83afe 100644
--- a/unit-tests/cmdline.exp
+++ b/unit-tests/cmdline.exp
@@ -1,7 +1,7 @@
makeobjdir-direct:
-show-objdir: <tmpdir>/6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5
+show-objdir: <tmpdir>/cmdline/6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5
makeobjdir-indirect:
-show-objdir: <tmpdir>/a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45/
+show-objdir: <tmpdir>/cmdline/a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45/
space-and-comment:
value # no comment $
value # no comment $
diff --git a/unit-tests/cmdline.mk b/unit-tests/cmdline.mk
index 40a0d7ccddbb..c0c4ee287f2f 100644
--- a/unit-tests/cmdline.mk
+++ b/unit-tests/cmdline.mk
@@ -1,8 +1,8 @@
-# $NetBSD: cmdline.mk,v 1.5 2024/04/23 22:51:28 rillig Exp $
+# $NetBSD: cmdline.mk,v 1.7 2024/08/29 17:56:37 sjg Exp $
#
# Tests for command line parsing and related special variables.
-TMPBASE?= ${TMPDIR:U/tmp/uid${.MAKE.UID}}
+TMPBASE?= ${TMPDIR:U/tmp/uid${.MAKE.UID}}/cmdline
SUB1= a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45 # just a random UUID
SUB2= 6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5 # just a random UUID
MAKE_CMD= env TMPBASE=${TMPBASE}/${SUB1} ${.MAKE} -f ${MAKEFILE} -r
@@ -12,6 +12,7 @@ DIR12= ${TMPBASE}/${SUB1}/${SUB2}
all: prepare-dirs
all: makeobjdir-direct makeobjdir-indirect
all: space-and-comment
+all: cleanup
prepare-dirs:
@rm -rf ${DIR2} ${DIR12}
@@ -56,3 +57,6 @@ space-and-comment: .PHONY
@env -i MAKEFLAGS="' VAR= value # no comment '" \
${MAKE} -r -f /dev/null -v VAR \
| sed 's,$$,$$,'
+
+cleanup:
+ @rm -rf ${TMPBASE}
diff --git a/unit-tests/cond-cmp-numeric-eq.exp b/unit-tests/cond-cmp-numeric-eq.exp
index 059007f00c84..e05961f14f87 100644
--- a/unit-tests/cond-cmp-numeric-eq.exp
+++ b/unit-tests/cond-cmp-numeric-eq.exp
@@ -1,5 +1,5 @@
-make: "cond-cmp-numeric-eq.mk" line 68: Malformed conditional (!(12345 = 12345))
-make: "cond-cmp-numeric-eq.mk" line 76: Malformed conditional (!(12345 === 12345))
+make: "cond-cmp-numeric-eq.mk" line 68: Malformed conditional '!(12345 = 12345)'
+make: "cond-cmp-numeric-eq.mk" line 76: Malformed conditional '!(12345 === 12345)'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/cond-cmp-numeric-eq.mk b/unit-tests/cond-cmp-numeric-eq.mk
index 1d0ade26087e..a8630cb37f1f 100755
--- a/unit-tests/cond-cmp-numeric-eq.mk
+++ b/unit-tests/cond-cmp-numeric-eq.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-cmp-numeric-eq.mk,v 1.7 2023/09/07 05:36:33 rillig Exp $
+# $NetBSD: cond-cmp-numeric-eq.mk,v 1.8 2024/08/06 18:00:16 rillig Exp $
#
# Tests for numeric comparisons with the == operator in .if conditions.
@@ -64,7 +64,7 @@
.endif
# There is no = operator for numbers.
-# expect+1: Malformed conditional (!(12345 = 12345))
+# expect+1: Malformed conditional '!(12345 = 12345)'
.if !(12345 = 12345)
. error
.else
@@ -72,7 +72,7 @@
.endif
# There is no === operator for numbers either.
-# expect+1: Malformed conditional (!(12345 === 12345))
+# expect+1: Malformed conditional '!(12345 === 12345)'
.if !(12345 === 12345)
. error
.else
diff --git a/unit-tests/cond-cmp-numeric.exp b/unit-tests/cond-cmp-numeric.exp
index 77c0154ca29b..8bec6ed55216 100644
--- a/unit-tests/cond-cmp-numeric.exp
+++ b/unit-tests/cond-cmp-numeric.exp
@@ -5,7 +5,7 @@ make: "cond-cmp-numeric.mk" line 21: Comparison with '>' requires both operands
CondParser_Eval: !(${:UNaN} == NaN)
Comparing "NaN" == "NaN"
CondParser_Eval: 123 ! 123
-make: "cond-cmp-numeric.mk" line 38: Malformed conditional (123 ! 123)
+make: "cond-cmp-numeric.mk" line 38: Malformed conditional '123 ! 123'
CondParser_Eval: ${:U 123} < 124
Comparing 123.000000 < 124.000000
CondParser_Eval: ${:U123 } < 124
diff --git a/unit-tests/cond-cmp-numeric.mk b/unit-tests/cond-cmp-numeric.mk
index e025b99b27cd..63a3bff8d560 100644
--- a/unit-tests/cond-cmp-numeric.mk
+++ b/unit-tests/cond-cmp-numeric.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-cmp-numeric.mk,v 1.7 2023/03/04 08:07:29 rillig Exp $
+# $NetBSD: cond-cmp-numeric.mk,v 1.8 2024/08/06 18:00:16 rillig Exp $
#
# Tests for numeric comparisons in .if conditions.
#
@@ -34,7 +34,7 @@
# whether the operator is valid, leaving the rest of the work to the
# evaluation functions EvalCompareNum and EvalCompareStr. Ensure that this
# parse error is properly reported.
-# expect+1: Malformed conditional (123 ! 123)
+# expect+1: Malformed conditional '123 ! 123'
.if 123 ! 123
. error
.else
diff --git a/unit-tests/cond-cmp-string.exp b/unit-tests/cond-cmp-string.exp
index e0aabfdadca4..ce58422afd7e 100644
--- a/unit-tests/cond-cmp-string.exp
+++ b/unit-tests/cond-cmp-string.exp
@@ -1,7 +1,7 @@
-make: "cond-cmp-string.mk" line 19: Malformed conditional (str != str)
-make: "cond-cmp-string.mk" line 44: Malformed conditional ("string" != "str""ing")
-make: "cond-cmp-string.mk" line 52: Malformed conditional (!("value" = "value"))
-make: "cond-cmp-string.mk" line 60: Malformed conditional (!("value" === "value"))
+make: "cond-cmp-string.mk" line 19: Malformed conditional 'str != str'
+make: "cond-cmp-string.mk" line 44: Malformed conditional '"string" != "str""ing"'
+make: "cond-cmp-string.mk" line 52: Malformed conditional '!("value" = "value")'
+make: "cond-cmp-string.mk" line 60: Malformed conditional '!("value" === "value")'
make: "cond-cmp-string.mk" line 118: Comparison with '<' requires both operands 'string' and 'string' to be numeric
make: "cond-cmp-string.mk" line 126: Comparison with '<=' requires both operands 'string' and 'string' to be numeric
make: "cond-cmp-string.mk" line 134: Comparison with '>' requires both operands 'string' and 'string' to be numeric
diff --git a/unit-tests/cond-cmp-string.mk b/unit-tests/cond-cmp-string.mk
index e3346e08b5a0..a913750a017f 100644
--- a/unit-tests/cond-cmp-string.mk
+++ b/unit-tests/cond-cmp-string.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-cmp-string.mk,v 1.19 2024/04/23 22:51:28 rillig Exp $
+# $NetBSD: cond-cmp-string.mk,v 1.20 2024/08/06 18:00:16 rillig Exp $
#
# Tests for string comparisons in .if conditions.
@@ -15,7 +15,7 @@
# The left-hand side of the comparison must be enclosed in quotes.
# This one is not enclosed in quotes and thus generates an error message.
-# expect+1: Malformed conditional (str != str)
+# expect+1: Malformed conditional 'str != str'
.if str != str
. error
.endif
@@ -40,7 +40,7 @@
# It is not possible to concatenate two string literals to form a single
# string. In C, Python and the shell this is possible, but not in make.
-# expect+1: Malformed conditional ("string" != "str""ing")
+# expect+1: Malformed conditional '"string" != "str""ing"'
.if "string" != "str""ing"
. error
.else
@@ -48,7 +48,7 @@
.endif
# There is no = operator for strings.
-# expect+1: Malformed conditional (!("value" = "value"))
+# expect+1: Malformed conditional '!("value" = "value")'
.if !("value" = "value")
. error
.else
@@ -56,7 +56,7 @@
.endif
# There is no === operator for strings either.
-# expect+1: Malformed conditional (!("value" === "value"))
+# expect+1: Malformed conditional '!("value" === "value")'
.if !("value" === "value")
. error
.else
diff --git a/unit-tests/cond-eof.exp b/unit-tests/cond-eof.exp
index 58a74d854d91..9e19dca175bd 100644
--- a/unit-tests/cond-eof.exp
+++ b/unit-tests/cond-eof.exp
@@ -1,6 +1,6 @@
-make: "cond-eof.mk" line 17: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
-make: "cond-eof.mk" line 20: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
-make: "cond-eof.mk" line 23: Malformed conditional ((0) ${SIDE_EFFECT} ${SIDE_EFFECT2})
+make: "cond-eof.mk" line 17: Malformed conditional '0 ${SIDE_EFFECT} ${SIDE_EFFECT2}'
+make: "cond-eof.mk" line 20: Malformed conditional '1 ${SIDE_EFFECT} ${SIDE_EFFECT2}'
+make: "cond-eof.mk" line 23: Malformed conditional '(0) ${SIDE_EFFECT} ${SIDE_EFFECT2}'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/cond-eof.mk b/unit-tests/cond-eof.mk
index a5f7ce95f89e..706a7deebd1a 100644
--- a/unit-tests/cond-eof.mk
+++ b/unit-tests/cond-eof.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-eof.mk,v 1.6 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: cond-eof.mk,v 1.7 2024/08/06 18:00:16 rillig Exp $
#
# Tests for parsing the end of '.if' conditions, which are represented as the
# token TOK_EOF.
@@ -13,12 +13,12 @@ SIDE_EFFECT2= ${:!echo 'side effect 2' 1>&2!}
# These syntax errors are an edge case that does not occur during normal
# operation. Still, it is easy to avoid evaluating these expressions, just in
# case they have side effects.
-# expect+1: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
+# expect+1: Malformed conditional '0 ${SIDE_EFFECT} ${SIDE_EFFECT2}'
.if 0 ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
-# expect+1: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
+# expect+1: Malformed conditional '1 ${SIDE_EFFECT} ${SIDE_EFFECT2}'
.if 1 ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
-# expect+1: Malformed conditional ((0) ${SIDE_EFFECT} ${SIDE_EFFECT2})
+# expect+1: Malformed conditional '(0) ${SIDE_EFFECT} ${SIDE_EFFECT2}'
.if (0) ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
diff --git a/unit-tests/cond-func-commands.mk b/unit-tests/cond-func-commands.mk
index e127a8ebdc03..d193587cd2c1 100644
--- a/unit-tests/cond-func-commands.mk
+++ b/unit-tests/cond-func-commands.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-commands.mk,v 1.5 2020/11/15 14:07:53 rillig Exp $
+# $NetBSD: cond-func-commands.mk,v 1.6 2025/01/10 23:00:38 rillig Exp $
#
# Tests for the commands() function in .if conditions.
@@ -33,5 +33,10 @@ target:
. error
.endif
+# Expressions in the argument of a function call don't have to be defined.
+.if commands(${UNDEF})
+. error
+.endif
+
all:
@:;
diff --git a/unit-tests/cond-func-defined.exp b/unit-tests/cond-func-defined.exp
index b9563ac1fa91..0b48906ce83f 100644
--- a/unit-tests/cond-func-defined.exp
+++ b/unit-tests/cond-func-defined.exp
@@ -1,5 +1,5 @@
-make: "cond-func-defined.mk" line 24: Missing closing parenthesis for defined()
-make: "cond-func-defined.mk" line 34: Missing closing parenthesis for defined()
+make: "cond-func-defined.mk" line 24: Missing ')' after argument 'A' for 'defined'
+make: "cond-func-defined.mk" line 34: Missing ')' after argument 'DEF' for 'defined'
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/cond-func-defined.mk b/unit-tests/cond-func-defined.mk
index 6b24182c11c1..66f95f3380c1 100644
--- a/unit-tests/cond-func-defined.mk
+++ b/unit-tests/cond-func-defined.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-defined.mk,v 1.12 2024/04/23 22:51:28 rillig Exp $
+# $NetBSD: cond-func-defined.mk,v 1.14 2025/01/10 23:00:38 rillig Exp $
#
# Tests for the defined() function in .if conditions.
@@ -20,7 +20,7 @@ ${:UA B}= variable name with spaces
.endif
# The argument of a function must not directly contain whitespace.
-# expect+1: Missing closing parenthesis for defined()
+# expect+1: Missing ')' after argument 'A' for 'defined'
.if !defined(A B)
. error
.endif
@@ -30,7 +30,7 @@ ${:UA B}= variable name with spaces
. error
.endif
-# expect+1: Missing closing parenthesis for defined()
+# expect+1: Missing ')' after argument 'DEF' for 'defined'
.if defined(DEF
. error
.else
@@ -49,6 +49,11 @@ ${:UA B}= variable name with spaces
. endif
.endfor
+# Expressions in the argument of a function call don't have to be defined.
+.if defined(${UNDEF})
+. error
+.endif
+
# Neither of the conditions is true. Before July 2020, the right-hand
# condition was evaluated even though it was irrelevant.
.if defined(UNDEF) && ${UNDEF:Mx} != ""
diff --git a/unit-tests/cond-func-empty.exp b/unit-tests/cond-func-empty.exp
index 1d955124d1c6..9102d4a35ae4 100644
--- a/unit-tests/cond-func-empty.exp
+++ b/unit-tests/cond-func-empty.exp
@@ -1,5 +1,4 @@
-make: "cond-func-empty.mk" line 168: Unclosed variable "WORD"
-make: "cond-func-empty.mk" line 168: Malformed conditional (empty(WORD)
+make: "cond-func-empty.mk" line 167: Unclosed variable "WORD"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/cond-func-empty.mk b/unit-tests/cond-func-empty.mk
index d377a84ff574..17e76a63f2e8 100644
--- a/unit-tests/cond-func-empty.mk
+++ b/unit-tests/cond-func-empty.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-empty.mk,v 1.25 2024/06/02 15:31:26 rillig Exp $
+# $NetBSD: cond-func-empty.mk,v 1.28 2025/01/11 20:54:45 rillig Exp $
#
# Tests for the empty() function in .if conditions, which tests an
# expression for emptiness.
@@ -163,8 +163,7 @@ ${:U WORD }= variable name with spaces
. error
.endif
-# expect+2: Unclosed variable "WORD"
-# expect+1: Malformed conditional (empty(WORD)
+# expect+1: Unclosed variable "WORD"
.if empty(WORD
. error
.else
@@ -207,6 +206,10 @@ VARNAME= ${VARNAME${:U1}}
.if defined(VARNAME${:U2}) && !empty(VARNAME${:U2})
.endif
+# Expressions in the argument of a function call don't have to be defined.
+.if !empty(${UNDEF})
+. error
+.endif
# If the word 'empty' is not followed by '(', it is not a function call but an
# ordinary bare word. This bare word is interpreted as 'defined(empty)', and
diff --git a/unit-tests/cond-func-exists.mk b/unit-tests/cond-func-exists.mk
index 40228cd44902..c68507ca1ab9 100644
--- a/unit-tests/cond-func-exists.mk
+++ b/unit-tests/cond-func-exists.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-exists.mk,v 1.7 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: cond-func-exists.mk,v 1.8 2025/01/10 23:00:38 rillig Exp $
#
# Tests for the exists() function in .if conditions.
@@ -38,6 +38,11 @@
. error
.endif
+# Expressions in the argument of a function call don't have to be defined.
+.if exists(${UNDEF})
+. error
+.endif
+
# The exists function does not really look up the file in the file system,
# instead it uses a cache that is preloaded very early, before parsing the
# first makefile. At that time, the file did not exist yet.
diff --git a/unit-tests/cond-func-make.mk b/unit-tests/cond-func-make.mk
index 15bc9f04d4e0..1a14fd320a3c 100644
--- a/unit-tests/cond-func-make.mk
+++ b/unit-tests/cond-func-make.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-make.mk,v 1.5 2023/06/23 04:56:54 rillig Exp $
+# $NetBSD: cond-func-make.mk,v 1.6 2025/01/10 23:00:38 rillig Exp $
#
# Tests for the make() function in .if conditions, which tests whether
# the argument has been passed as a target via the command line or later
@@ -25,5 +25,10 @@
. error
.endif
+# Expressions in the argument of a function call don't have to be defined.
+.if make(${UNDEF})
+. error
+.endif
+
via-cmdline via-dot-makeflags:
: $@
diff --git a/unit-tests/cond-func-target.mk b/unit-tests/cond-func-target.mk
index 62266839df9e..2216997e4393 100644
--- a/unit-tests/cond-func-target.mk
+++ b/unit-tests/cond-func-target.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-target.mk,v 1.4 2020/10/24 08:46:08 rillig Exp $
+# $NetBSD: cond-func-target.mk,v 1.5 2025/01/10 23:00:38 rillig Exp $
#
# Tests for the target() function in .if conditions.
@@ -34,5 +34,10 @@ target:
. error
.endif
+# Expressions in the argument of a function call don't have to be defined.
+.if target(${UNDEF})
+. error
+.endif
+
all:
@:;
diff --git a/unit-tests/cond-func.exp b/unit-tests/cond-func.exp
index c2c5e94fe7e2..0570a1c4fabc 100644
--- a/unit-tests/cond-func.exp
+++ b/unit-tests/cond-func.exp
@@ -1,12 +1,13 @@
-make: "cond-func.mk" line 37: Missing closing parenthesis for defined()
-make: "cond-func.mk" line 53: Missing closing parenthesis for defined()
-make: "cond-func.mk" line 57: Missing closing parenthesis for defined()
+make: "cond-func.mk" line 37: Missing ')' after argument 'A' for 'defined'
+make: "cond-func.mk" line 53: Missing ')' after argument 'A' for 'defined'
+make: "cond-func.mk" line 57: Missing ')' after argument 'A' for 'defined'
make: "cond-func.mk" line 91: Unknown operator '&'
make: "cond-func.mk" line 107: A plain function name is parsed as defined(...).
make: "cond-func.mk" line 115: A plain function name is parsed as defined(...).
make: "cond-func.mk" line 126: Symbols may start with a function name.
make: "cond-func.mk" line 132: Symbols may start with a function name.
-make: "cond-func.mk" line 138: Missing closing parenthesis for defined()
+make: "cond-func.mk" line 138: Missing ')' after argument '' for 'defined'
+make: "cond-func.mk" line 145: Missing ')' after argument '${:UVARNAME}.param' for 'defined'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/cond-func.mk b/unit-tests/cond-func.mk
index 7ed6f6f5570d..3e4f8a9f151f 100644
--- a/unit-tests/cond-func.mk
+++ b/unit-tests/cond-func.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func.mk,v 1.15 2024/07/06 21:21:10 rillig Exp $
+# $NetBSD: cond-func.mk,v 1.18 2024/08/07 05:48:45 rillig Exp $
#
# Tests for those parts of the functions in .if conditions that are common
# among several functions.
@@ -33,7 +33,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
.endif
# The argument of a function must not directly contain whitespace.
-# expect+1: Missing closing parenthesis for defined()
+# expect+1: Missing ')' after argument 'A' for 'defined'
.if !defined(A B)
. error
.endif
@@ -49,11 +49,11 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
#
# It's not entirely clear why these characters are forbidden.
# The most plausible reason seems to be typo detection.
-# expect+1: Missing closing parenthesis for defined()
+# expect+1: Missing ')' after argument 'A' for 'defined'
.if !defined(A&B)
. error
.endif
-# expect+1: Missing closing parenthesis for defined()
+# expect+1: Missing ')' after argument 'A' for 'defined'
.if !defined(A|B)
. error
.endif
@@ -134,9 +134,16 @@ defined-var= # defined but empty
. error
.endif
-# expect+1: Missing closing parenthesis for defined()
+# expect+1: Missing ')' after argument '' for 'defined'
.if defined(
. error
.else
. error
.endif
+
+# expect+1: Missing ')' after argument '${:UVARNAME}.param' for 'defined'
+.if defined(${:UVARNAME}.param extra)
+. error
+.else
+. error
+.endif
diff --git a/unit-tests/cond-late.exp b/unit-tests/cond-late.exp
index e97fd3789381..d8a24143c2b9 100644
--- a/unit-tests/cond-late.exp
+++ b/unit-tests/cond-late.exp
@@ -1,4 +1,6 @@
-make: "cond-late.mk" line 38: while evaluating variable "VAR" with value "${${UNDEF} != "no":?:}": while evaluating condition " != "no"": Bad condition
+make: "cond-late.mk" line 38: Bad condition
+ while evaluating condition " != "no""
+ while evaluating variable "VAR" with value "${${UNDEF} != "no":?:}"
in directory <curdir>
make: Fatal errors encountered -- cannot continue
make: stopped making "do-parse-time" in unit-tests
diff --git a/unit-tests/cond-late.mk b/unit-tests/cond-late.mk
index 4d8c4fbd5d98..a8f381590a6e 100644
--- a/unit-tests/cond-late.mk
+++ b/unit-tests/cond-late.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-late.mk,v 1.8 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: cond-late.mk,v 1.9 2024/08/29 20:20:35 rillig Exp $
#
# Using the :? modifier, expressions can contain conditional
# expressions that are evaluated late, at expansion time.
@@ -34,7 +34,7 @@ cond-literal:
.if make(do-parse-time)
VAR= ${${UNDEF} != "no":?:}
-# expect+1: while evaluating variable "VAR" with value "${${UNDEF} != "no":?:}": while evaluating condition " != "no"": Bad condition
+# expect+1: Bad condition
. if empty(VAR:Mpattern)
. endif
.endif
diff --git a/unit-tests/cond-op-and.exp b/unit-tests/cond-op-and.exp
index 6d2263dc5d56..ac085e77ce74 100644
--- a/unit-tests/cond-op-and.exp
+++ b/unit-tests/cond-op-and.exp
@@ -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 '&'
diff --git a/unit-tests/cond-op-and.mk b/unit-tests/cond-op-and.mk
index b49fb079b3cf..5d7f8a06800a 100644
--- a/unit-tests/cond-op-and.mk
+++ b/unit-tests/cond-op-and.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-and.mk,v 1.10 2024/07/06 21:21:10 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})
diff --git a/unit-tests/cond-op-not.exp b/unit-tests/cond-op-not.exp
index 86d8289d9233..747720159906 100644
--- a/unit-tests/cond-op-not.exp
+++ b/unit-tests/cond-op-not.exp
@@ -3,7 +3,7 @@ make: "cond-op-not.mk" line 39: Not space evaluates to false.
make: "cond-op-not.mk" line 44: Not 0 evaluates to true.
make: "cond-op-not.mk" line 53: Not 1 evaluates to false.
make: "cond-op-not.mk" line 60: Not word evaluates to false.
-make: "cond-op-not.mk" line 65: Malformed conditional (!)
+make: "cond-op-not.mk" line 65: Malformed conditional '!'
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/cond-op-not.mk b/unit-tests/cond-op-not.mk
index 28f835fa3cbd..4565b60b115d 100644
--- a/unit-tests/cond-op-not.mk
+++ b/unit-tests/cond-op-not.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-not.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
+# $NetBSD: cond-op-not.mk,v 1.9 2024/08/06 18:00:17 rillig Exp $
#
# Tests for the ! operator in .if conditions, which negates its argument.
@@ -61,7 +61,7 @@
.endif
# A single exclamation mark is a parse error.
-# expect+1: Malformed conditional (!)
+# expect+1: Malformed conditional '!'
.if !
. error
.else
diff --git a/unit-tests/cond-op-or.exp b/unit-tests/cond-op-or.exp
index dddd29d5bca0..f8b6de761755 100644
--- a/unit-tests/cond-op-or.exp
+++ b/unit-tests/cond-op-or.exp
@@ -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 '|'
diff --git a/unit-tests/cond-op-or.mk b/unit-tests/cond-op-or.mk
index b01fcaf04a28..381516499093 100644
--- a/unit-tests/cond-op-or.mk
+++ b/unit-tests/cond-op-or.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-or.mk,v 1.12 2024/07/06 21:21:10 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})
diff --git a/unit-tests/cond-op-parentheses.exp b/unit-tests/cond-op-parentheses.exp
index f14e62b6d4e3..c11c9eb1be1d 100644
--- a/unit-tests/cond-op-parentheses.exp
+++ b/unit-tests/cond-op-parentheses.exp
@@ -1,7 +1,7 @@
make: "cond-op-parentheses.mk" line 22: Comparison with '>' requires both operands '3' and '(2' to be numeric
-make: "cond-op-parentheses.mk" line 25: Malformed conditional ((3) > 2)
-make: "cond-op-parentheses.mk" line 44: Malformed conditional (()
-make: "cond-op-parentheses.mk" line 58: Malformed conditional ())
+make: "cond-op-parentheses.mk" line 25: Malformed conditional '(3) > 2'
+make: "cond-op-parentheses.mk" line 44: Malformed conditional '('
+make: "cond-op-parentheses.mk" line 58: Malformed conditional ')'
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/cond-op-parentheses.mk b/unit-tests/cond-op-parentheses.mk
index b6c9bd3c0e9d..17d5d767cd41 100644
--- a/unit-tests/cond-op-parentheses.mk
+++ b/unit-tests/cond-op-parentheses.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-parentheses.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
+# $NetBSD: cond-op-parentheses.mk,v 1.8 2024/08/06 18:00:17 rillig Exp $
#
# Tests for parentheses in .if conditions, which group expressions to override
# the precedence of the operators '!', '&&' and '||'. Parentheses cannot be
@@ -21,7 +21,7 @@
# expect+1: Comparison with '>' requires both operands '3' and '(2' to be numeric
.if 3 > (2)
.endif
-# expect+1: Malformed conditional ((3) > 2)
+# expect+1: Malformed conditional '(3) > 2'
.if (3) > 2
.endif
@@ -40,7 +40,7 @@
.endif
# An unbalanced opening parenthesis is a parse error.
-# expect+1: Malformed conditional (()
+# expect+1: Malformed conditional '('
.if (
. error
.else
@@ -54,7 +54,7 @@
# TOK_TRUE, TOK_FALSE or TOK_ERROR. In cond.c 1.241, the return type of that
# function was changed to a properly restricted enum type, to prevent this bug
# from occurring again.
-# expect+1: Malformed conditional ())
+# expect+1: Malformed conditional ')'
.if )
. error
.else
diff --git a/unit-tests/cond-op.exp b/unit-tests/cond-op.exp
index 1ce5436f023a..3747557789a7 100644
--- a/unit-tests/cond-op.exp
+++ b/unit-tests/cond-op.exp
@@ -1,7 +1,7 @@
-make: "cond-op.mk" line 51: Malformed conditional ("!word" == !word)
-make: "cond-op.mk" line 72: Malformed conditional (0 ${ERR::=evaluated})
+make: "cond-op.mk" line 51: Malformed conditional '"!word" == !word'
+make: "cond-op.mk" line 72: Malformed conditional '0 ${ERR::=evaluated}'
make: "cond-op.mk" line 77: A misplaced expression after 0 is not evaluated.
-make: "cond-op.mk" line 82: Malformed conditional (1 ${ERR::=evaluated})
+make: "cond-op.mk" line 82: Malformed conditional '1 ${ERR::=evaluated}'
make: "cond-op.mk" line 87: A misplaced expression after 1 is not evaluated.
make: "cond-op.mk" line 93: A B C => (A || B) && C A || B && C A || (B && C)
make: "cond-op.mk" line 108: 0 0 0 => 0 0 0
@@ -12,10 +12,10 @@ make: "cond-op.mk" line 108: 1 0 0 => 0 1 1
make: "cond-op.mk" line 108: 1 0 1 => 1 1 1
make: "cond-op.mk" line 108: 1 1 0 => 0 1 1
make: "cond-op.mk" line 108: 1 1 1 => 1 1 1
-make: "cond-op.mk" line 120: Malformed conditional (1 &&)
-make: "cond-op.mk" line 129: Malformed conditional (0 &&)
-make: "cond-op.mk" line 138: Malformed conditional (1 ||)
-make: "cond-op.mk" line 148: Malformed conditional (0 ||)
+make: "cond-op.mk" line 120: Malformed conditional '1 &&'
+make: "cond-op.mk" line 129: Malformed conditional '0 &&'
+make: "cond-op.mk" line 138: Malformed conditional '1 ||'
+make: "cond-op.mk" line 148: Malformed conditional '0 ||'
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/cond-op.mk b/unit-tests/cond-op.mk
index 6371e4db0594..6493d887c806 100644
--- a/unit-tests/cond-op.mk
+++ b/unit-tests/cond-op.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op.mk,v 1.16 2023/06/01 20:56:35 rillig Exp $
+# $NetBSD: cond-op.mk,v 1.17 2024/08/06 18:00:17 rillig Exp $
#
# Tests for operators like &&, ||, ! in .if conditions.
#
@@ -47,7 +47,7 @@
# appear unquoted. If any, it must be enclosed in quotes.
# In any case, it is not interpreted as a negation of an unquoted string.
# See CondParser_String.
-# expect+1: Malformed conditional ("!word" == !word)
+# expect+1: Malformed conditional '"!word" == !word'
.if "!word" == !word
. error
.endif
@@ -68,7 +68,7 @@
# next token, even though in this position of the condition, only comparison
# operators, TOK_AND, TOK_OR or TOK_RPAREN are allowed.
.undef ERR
-# expect+1: Malformed conditional (0 ${ERR::=evaluated})
+# expect+1: Malformed conditional '0 ${ERR::=evaluated}'
.if 0 ${ERR::=evaluated}
. error
.endif
@@ -78,7 +78,7 @@
.endif
.undef ERR
-# expect+1: Malformed conditional (1 ${ERR::=evaluated})
+# expect+1: Malformed conditional '1 ${ERR::=evaluated}'
.if 1 ${ERR::=evaluated}
. error
.endif
@@ -116,7 +116,7 @@
# This condition is obviously malformed. It is properly detected and also
# was properly detected before 2021-01-19, but only because the left hand
# side of the '&&' evaluated to true.
-# expect+1: Malformed conditional (1 &&)
+# expect+1: Malformed conditional '1 &&'
.if 1 &&
. error
.else
@@ -125,7 +125,7 @@
# This obviously malformed condition was not detected as such before cond.c
# 1.238 from 2021-01-19.
-# expect+1: Malformed conditional (0 &&)
+# expect+1: Malformed conditional '0 &&'
.if 0 &&
. error
.else
@@ -134,7 +134,7 @@
# This obviously malformed condition was not detected as such before cond.c
# 1.238 from 2021-01-19.
-# expect+1: Malformed conditional (1 ||)
+# expect+1: Malformed conditional '1 ||'
.if 1 ||
. error
.else
@@ -144,7 +144,7 @@
# This condition is obviously malformed. It is properly detected and also
# was properly detected before 2021-01-19, but only because the left hand
# side of the '||' evaluated to false.
-# expect+1: Malformed conditional (0 ||)
+# expect+1: Malformed conditional '0 ||'
.if 0 ||
. error
.else
diff --git a/unit-tests/cond-token-number.exp b/unit-tests/cond-token-number.exp
index aaa4ec7fe184..eb0870521af1 100644
--- a/unit-tests/cond-token-number.exp
+++ b/unit-tests/cond-token-number.exp
@@ -1,7 +1,7 @@
-make: "cond-token-number.mk" line 16: Malformed conditional (-0)
-make: "cond-token-number.mk" line 27: Malformed conditional (+0)
-make: "cond-token-number.mk" line 38: Malformed conditional (!-1)
-make: "cond-token-number.mk" line 49: Malformed conditional (!+1)
+make: "cond-token-number.mk" line 16: Malformed conditional '-0'
+make: "cond-token-number.mk" line 27: Malformed conditional '+0'
+make: "cond-token-number.mk" line 38: Malformed conditional '!-1'
+make: "cond-token-number.mk" line 49: Malformed conditional '!+1'
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/cond-token-number.mk b/unit-tests/cond-token-number.mk
index 7e73f8b76f94..329a51d73b2a 100644
--- a/unit-tests/cond-token-number.mk
+++ b/unit-tests/cond-token-number.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-number.mk,v 1.10 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: cond-token-number.mk,v 1.11 2024/08/06 18:00:17 rillig Exp $
#
# Tests for number tokens in .if conditions.
#
@@ -12,7 +12,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
-# expect+1: Malformed conditional (-0)
+# expect+1: Malformed conditional '-0'
.if -0
. error
.else
@@ -23,7 +23,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
-# expect+1: Malformed conditional (+0)
+# expect+1: Malformed conditional '+0'
.if +0
. error
.else
@@ -34,7 +34,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
-# expect+1: Malformed conditional (!-1)
+# expect+1: Malformed conditional '!-1'
.if !-1
. error
.else
@@ -45,7 +45,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
-# expect+1: Malformed conditional (!+1)
+# expect+1: Malformed conditional '!+1'
.if !+1
. error
.else
diff --git a/unit-tests/cond-token-plain.exp b/unit-tests/cond-token-plain.exp
index 8044f3bac826..f3425e7f899d 100644
--- a/unit-tests/cond-token-plain.exp
+++ b/unit-tests/cond-token-plain.exp
@@ -41,7 +41,7 @@ make: "cond-token-plain.mk" line 144: Numbers can be composed from literals and
CondParser_Eval: "" ==
make: "cond-token-plain.mk" line 151: Missing right-hand side of operator '=='
CondParser_Eval: == ""
-make: "cond-token-plain.mk" line 160: Malformed conditional (== "")
+make: "cond-token-plain.mk" line 160: Malformed conditional '== ""'
CondParser_Eval: \\
make: "cond-token-plain.mk" line 176: The variable '\\' is not defined.
CondParser_Eval: \\
@@ -49,15 +49,15 @@ make: "cond-token-plain.mk" line 182: Now the variable '\\' is defined.
CondParser_Eval: "unquoted\"quoted" != unquoted"quoted
Comparing "unquoted"quoted" != "unquoted"quoted"
CondParser_Eval: $$$$$$$$ != ""
-make: "cond-token-plain.mk" line 197: Malformed conditional ($$$$$$$$ != "")
+make: "cond-token-plain.mk" line 197: Malformed conditional '$$$$$$$$ != ""'
CondParser_Eval: left == right
-make: "cond-token-plain.mk" line 206: Malformed conditional (left == right)
+make: "cond-token-plain.mk" line 206: Malformed conditional 'left == right'
CondParser_Eval: ${0:?:} || left == right
CondParser_Eval: 0
-make: "cond-token-plain.mk" line 212: Malformed conditional (${0:?:} || left == right)
+make: "cond-token-plain.mk" line 212: Malformed conditional '${0:?:} || left == right'
CondParser_Eval: left == right || ${0:?:}
-make: "cond-token-plain.mk" line 217: Malformed conditional (left == right || ${0:?:})
-make: "cond-token-plain.mk" line 236: Malformed conditional (VAR.${IF_COUNT::+=1} != "")
+make: "cond-token-plain.mk" line 217: Malformed conditional 'left == right || ${0:?:}'
+make: "cond-token-plain.mk" line 236: Malformed conditional 'VAR.${IF_COUNT::+=1} != ""'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/cond-token-plain.mk b/unit-tests/cond-token-plain.mk
index 79fcc771a855..4509c1feca80 100644
--- a/unit-tests/cond-token-plain.mk
+++ b/unit-tests/cond-token-plain.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-plain.mk,v 1.19 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: cond-token-plain.mk,v 1.20 2024/08/06 18:00:17 rillig Exp $
#
# Tests for plain tokens (that is, string literals without quotes)
# in .if conditions. These are also called bare words.
@@ -156,7 +156,7 @@ VAR= defined
# If the left-hand side is missing, it's a parse error as well, but without
# a specific error message.
-# expect+1: Malformed conditional (== "")
+# expect+1: Malformed conditional '== ""'
.if == ""
. error
.else
@@ -193,7 +193,7 @@ ${:U\\\\}= backslash
# FIXME: In CondParser_String, Var_Parse returns var_Error without a
# corresponding error message.
-# expect+1: Malformed conditional ($$$$$$$$ != "")
+# expect+1: Malformed conditional '$$$$$$$$ != ""'
.if $$$$$$$$ != ""
. error
.else
@@ -202,18 +202,18 @@ ${:U\\\\}= backslash
# In a condition in an .if directive, the left-hand side must not be an
# unquoted string literal.
-# expect+1: Malformed conditional (left == right)
+# expect+1: Malformed conditional 'left == right'
.if left == right
.endif
# Before cond.c 1.276 from 2021-09-21, an expression containing the
# modifier ':?:' allowed unquoted string literals for the rest of the
# condition. This was an unintended implementation mistake.
-# expect+1: Malformed conditional (${0:?:} || left == right)
+# expect+1: Malformed conditional '${0:?:} || left == right'
.if ${0:?:} || left == right
.endif
# This affected only the comparisons after the expression, so the following
# was still a syntax error.
-# expect+1: Malformed conditional (left == right || ${0:?:})
+# expect+1: Malformed conditional 'left == right || ${0:?:}'
.if left == right || ${0:?:}
.endif
@@ -232,7 +232,7 @@ ${:U\\\\}= backslash
# for the second time. The right-hand side of a comparison may be a bare
# word, but that side has no risk of being parsed more than once.
#
-# expect+1: Malformed conditional (VAR.${IF_COUNT::+=1} != "")
+# expect+1: Malformed conditional 'VAR.${IF_COUNT::+=1} != ""'
.if VAR.${IF_COUNT::+=1} != ""
. error
.else
diff --git a/unit-tests/cond-token-string.exp b/unit-tests/cond-token-string.exp
index f970a21bf69f..e48244a457e9 100644
--- a/unit-tests/cond-token-string.exp
+++ b/unit-tests/cond-token-string.exp
@@ -1,18 +1,18 @@
-make: "cond-token-string.mk" line 15: while evaluating "${:Uvalue:Z}"" with value "value": Unknown modifier "Z"
-make: "cond-token-string.mk" line 15: Malformed conditional ("" != "${:Uvalue:Z}")
-make: "cond-token-string.mk" line 25: xvalue is not defined.
-make: "cond-token-string.mk" line 32: Malformed conditional (x${:Uvalue} == "")
-make: "cond-token-string.mk" line 42: Expected.
+make: "cond-token-string.mk" line 14: Unknown modifier "Z"
+ while evaluating "${:Uvalue:Z}"" with value "value"
+make: "cond-token-string.mk" line 24: xvalue is not defined.
+make: "cond-token-string.mk" line 31: Malformed conditional 'x${:Uvalue} == ""'
+make: "cond-token-string.mk" line 41: Expected.
CondParser_Eval: "UNDEF"
-make: "cond-token-string.mk" line 52: The string literal "UNDEF" is not empty.
+make: "cond-token-string.mk" line 51: The string literal "UNDEF" is not empty.
CondParser_Eval: " "
-make: "cond-token-string.mk" line 61: The string literal " " is not empty, even though it consists of whitespace only.
+make: "cond-token-string.mk" line 60: The string literal " " is not empty, even though it consists of whitespace only.
CondParser_Eval: "${UNDEF}"
-make: "cond-token-string.mk" line 71: An undefined variable in quotes expands to an empty string, which then evaluates to false.
+make: "cond-token-string.mk" line 70: An undefined variable in quotes expands to an empty string, which then evaluates to false.
CondParser_Eval: "${:Uvalue}"
-make: "cond-token-string.mk" line 77: A nonempty expression evaluates to true.
+make: "cond-token-string.mk" line 76: A nonempty expression evaluates to true.
CondParser_Eval: "${:U}"
-make: "cond-token-string.mk" line 86: An empty variable evaluates to false.
+make: "cond-token-string.mk" line 85: An empty variable evaluates to false.
CondParser_Eval: ("${VAR}")
CondParser_Eval: "quoted" == quoted
Comparing "quoted" == "quoted"
diff --git a/unit-tests/cond-token-string.mk b/unit-tests/cond-token-string.mk
index d24645748233..45e9cf8a8469 100644
--- a/unit-tests/cond-token-string.mk
+++ b/unit-tests/cond-token-string.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-string.mk,v 1.11 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: cond-token-string.mk,v 1.15 2025/01/11 20:54:45 rillig Exp $
#
# Tests for quoted string literals in .if conditions.
#
@@ -10,8 +10,7 @@
# Cover the code in CondParser_String that frees the memory after parsing
# an expression based on an undefined variable.
-# expect+2: Malformed conditional ("" != "${:Uvalue:Z}")
-# expect+1: while evaluating "${:Uvalue:Z}"" with value "value": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
.if "" != "${:Uvalue:Z}"
. error
.else
@@ -28,7 +27,7 @@
# The 'x' produces a "Malformed conditional" since the left-hand side of a
# comparison in an .if directive must be either an expression, a
# quoted string literal or a number that starts with a digit.
-# expect+1: Malformed conditional (x${:Uvalue} == "")
+# expect+1: Malformed conditional 'x${:Uvalue} == ""'
.if x${:Uvalue} == ""
. error
.else
diff --git a/unit-tests/cond-token-var.exp b/unit-tests/cond-token-var.exp
index d84ca56e981b..a7e5c8ab5531 100644
--- a/unit-tests/cond-token-var.exp
+++ b/unit-tests/cond-token-var.exp
@@ -1,7 +1,21 @@
-make: "cond-token-var.mk" line 21: ok
-make: "cond-token-var.mk" line 28: Malformed conditional (${UNDEF} == ${DEF})
-make: "cond-token-var.mk" line 34: Malformed conditional (${DEF} == ${UNDEF})
-make: "cond-token-var.mk" line 44: Malformed conditional (${UNDEF})
+make: "cond-token-var.mk" line 23: ok
+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
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/cond-token-var.mk b/unit-tests/cond-token-var.mk
index c6471756a3dd..972a6b3c3d4b 100644
--- a/unit-tests/cond-token-var.mk
+++ b/unit-tests/cond-token-var.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-var.mk,v 1.8 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: cond-token-var.mk,v 1.11 2025/01/11 21:21:33 rillig Exp $
#
# Tests for expressions in .if conditions.
#
@@ -13,8 +13,10 @@
# Well, except for the assignment modifiers, these do indeed change the value
# of the variable.
+D= defined
DEF= defined
+
# A defined variable may appear on either side of the comparison.
.if ${DEF} == ${DEF}
# expect+1: ok
@@ -24,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
@@ -40,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
@@ -49,6 +51,34 @@ DEF= defined
.if ${UNDEF:U}
.endif
+
+# The same as above, for single-letter variables without braces or
+# parentheses.
+
+# A defined variable may appear on either side of the comparison.
+.if $D == $D
+.endif
+
+# A variable on the left-hand side must be defined.
+# expect+1: Variable "U" is undefined
+.if $U == $D
+.endif
+
+# A variable on the right-hand side must be defined.
+# expect+1: Variable "U" is undefined
+.if $D == $U
+.endif
+
+# A defined variable may appear as an expression of its own.
+.if $D
+.endif
+
+# An undefined variable without a comparison operator generates a parse error.
+# expect+1: Variable "U" is undefined
+.if $U
+.endif
+
+
# If the value of the expression is a number, it is compared against
# zero.
.if ${:U0}
@@ -69,3 +99,30 @@ DEF= defined
.if !${:Uanything}
. error
.endif
+
+.MAKEFLAGS: -dv
+# 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
+
+# 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
+
+# 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
diff --git a/unit-tests/cond-undef-lint.exp b/unit-tests/cond-undef-lint.exp
index efab46113f67..ce619293a35b 100755
--- a/unit-tests/cond-undef-lint.exp
+++ b/unit-tests/cond-undef-lint.exp
@@ -1,10 +1,6 @@
-make: "cond-undef-lint.mk" line 25: Variable "UNDEF" is undefined
-make: "cond-undef-lint.mk" line 25: Malformed conditional (${UNDEF})
-make: "cond-undef-lint.mk" line 43: Variable "UNDEF" is undefined
-make: "cond-undef-lint.mk" line 43: Variable "VAR." is undefined
-make: "cond-undef-lint.mk" line 43: Malformed conditional (${VAR.${UNDEF}})
-make: "cond-undef-lint.mk" line 56: Variable "VAR.defined" is undefined
-make: "cond-undef-lint.mk" line 56: Malformed conditional (${VAR.${DEF}})
+make: "cond-undef-lint.mk" line 24: Variable "UNDEF" 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
diff --git a/unit-tests/cond-undef-lint.mk b/unit-tests/cond-undef-lint.mk
index 6fd353dc60e2..1b4d19636c41 100755
--- a/unit-tests/cond-undef-lint.mk
+++ b/unit-tests/cond-undef-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-undef-lint.mk,v 1.4 2023/06/01 20:56:35 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.
#
@@ -20,7 +20,6 @@ DEF= defined
.endif
# Since the condition fails to evaluate, neither of the branches is taken.
-# expect+2: Malformed conditional (${UNDEF})
# expect+1: Variable "UNDEF" is undefined
.if ${UNDEF}
. error
@@ -32,27 +31,17 @@ 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+3: Variable "UNDEF" is undefined
-# expect+2: Variable "VAR." is undefined
-# expect+1: Malformed conditional (${VAR.${UNDEF}})
+# expect+1: Variable "VAR." is undefined
.if ${VAR.${UNDEF}}
. error
.else
. 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+2: Variable "VAR.defined" is undefined
-# expect+1: Malformed conditional (${VAR.${DEF}})
+# expect+1: Variable "VAR.defined" is undefined
.if ${VAR.${DEF}}
. error
.else
diff --git a/unit-tests/dep-var.exp b/unit-tests/dep-var.exp
index 194c723fc1a8..4a570206b300 100755
--- a/unit-tests/dep-var.exp
+++ b/unit-tests/dep-var.exp
@@ -1,4 +1,4 @@
-Var_Parse: ${UNDEF1} (eval-defined)
+Var_Parse: ${UNDEF1} (eval)
Global: .ALLTARGETS = all
Global: .ALLTARGETS = all ${DEF2}
Global: .ALLTARGETS = all ${DEF2} a-${DEF2}-b
@@ -10,9 +10,9 @@ Global: INDIRECT_3 = indirect
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)
+Var_Parse: ${:U\$)}: (eval)
+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
diff --git a/unit-tests/dep-var.mk b/unit-tests/dep-var.mk
index fa720c3af610..ed8549583b82 100755
--- a/unit-tests/dep-var.mk
+++ b/unit-tests/dep-var.mk
@@ -1,4 +1,4 @@
-# $NetBSD: dep-var.mk,v 1.12 2024/06/02 15:31:26 rillig Exp $
+# $NetBSD: dep-var.mk,v 1.13 2025/01/14 21:23:17 rillig Exp $
#
# Tests for variable references in dependency declarations.
#
@@ -7,10 +7,8 @@
.MAKEFLAGS: -dv
-# expect: Var_Parse: ${UNDEF1} (eval-defined)
-# Even though undefined expressions should lead to errors, no error message is
-# generated for this line. The expression ${UNDEF1} simply expands
-# to an empty string.
+# In a dependency line, an undefined expressions expands to an empty string.
+# expect: Var_Parse: ${UNDEF1} (eval)
all: ${UNDEF1}
# Using a double dollar in order to circumvent immediate expression expansion
@@ -21,11 +19,7 @@ all: ${UNDEF1}
# is defined, so everything's fine.
all: $${DEF2} a-$${DEF2}-b
-# This variable is not defined at all.
-# XXX: The -dv log says later when expanding the sources of 'all':
-# Var_Parse: ${UNDEF3} (eval-defined)
-# but no error message is generated for this line, just like for UNDEF1.
-# The expression ${UNDEF3} simply expands to an empty string.
+# This variable is neither defined now nor later.
all: $${UNDEF3}
# Try out how many levels of indirection are really expanded in dependency
@@ -83,14 +77,10 @@ all: $$$$)
# Since 2020-09-13, this generates a parse error in lint mode (-dL), but not
# in normal mode since ParseDependency does not handle any errors after
# calling Var_Parse.
-# expect: Var_Parse: ${:U\$)}: (eval-defined)
+# expect: Var_Parse: ${:U\$)}: (eval)
# expect: Var_Parse: $INDIRECT_2-2-1 $): (parse)
# expect: Var_Parse: $): (parse)
undef1 def2 a-def2-b 1-2-$$INDIRECT_2-2-1 ${:U\$)}:
@echo ${.TARGET:Q}
.MAKEFLAGS: -d0
-
-# XXX: The exit status is still 0, even though Parse_Error is called with
-# PARSE_FATAL in SuffExpandChildren. The exit status is only affected by
-# parse errors when they occur in the parsing phase, see Parse_File.
diff --git a/unit-tests/deptgt-makeflags.exp b/unit-tests/deptgt-makeflags.exp
index ea29f76ad464..099ce8e15ed5 100644
--- a/unit-tests/deptgt-makeflags.exp
+++ b/unit-tests/deptgt-makeflags.exp
@@ -2,7 +2,7 @@ Global: ignoring delete 'DOLLAR' as it is not found
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
diff --git a/unit-tests/deptgt-order.exp b/unit-tests/deptgt-order.exp
index ecbf03fcc572..c5cdaa4cbe2b 100644
--- a/unit-tests/deptgt-order.exp
+++ b/unit-tests/deptgt-order.exp
@@ -1,9 +1,9 @@
-Parsing line 15: .ORDER: three one
+Parsing deptgt-order.mk:15: .ORDER: three one
ParseDependency(.ORDER: three one)
# .ORDER forces 'three' to be made before 'one'
# three, unmade, type OP_DEPENDS|OP_PHONY|OP_HAS_COMMANDS, flags none
# one, unmade, type OP_DEPENDS|OP_PHONY, flags none
-Parsing line 16: .MAKEFLAGS: -d0
+Parsing deptgt-order.mk:16: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
: 'Making two out of one.'
: 'Making three out of two.'
diff --git a/unit-tests/deptgt.exp b/unit-tests/deptgt.exp
index ae7315716d8c..8a70e2495038 100644
--- a/unit-tests/deptgt.exp
+++ b/unit-tests/deptgt.exp
@@ -1,18 +1,26 @@
make: "deptgt.mk" line 11: warning: Extra target '.PHONY' ignored
make: "deptgt.mk" line 30: Unassociated shell command ": command3 # parse error, since targets == NULL"
-Parsing line 36: ${:U}: empty-source
+Parsing deptgt.mk:36: ${:U}: empty-source
ParseDependency(: empty-source)
-Parsing line 37: : command for empty targets list
-Parsing line 38: : empty-source
+Parsing deptgt.mk:37: : command for empty targets list
+Parsing deptgt.mk:38: : empty-source
ParseDependency(: empty-source)
-Parsing line 39: : command for empty targets list
-Parsing line 40: .MAKEFLAGS: -d0
+Parsing deptgt.mk:39: : command for empty targets list
+Parsing deptgt.mk:40: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
-make: "deptgt.mk" line 45: while evaluating "${:U:Z}:" with value "": Unknown modifier "Z"
-make: "deptgt.mk" line 49: while parsing "${:U:Z}:": Unknown modifier "Z"
-make: "deptgt.mk" line 52: warning: Extra target 'ordinary' ignored
-make: "deptgt.mk" line 55: warning: Extra target (ordinary) ignored
-make: "deptgt.mk" line 58: warning: Special and mundane targets don't mix. Mundane ones ignored
+Var_Parse: ${UNDEF}: depsrc-${UNDEF} (eval)
+Var_Parse: ${UNDEF} (eval)
+Global: .ALLTARGETS = target1 target2 sources empty-source deptgt-
+Global: .ALLTARGETS = target1 target2 sources empty-source deptgt- depsrc-
+Global: .MAKEFLAGS = -r -k -d p -d 0 -d v -d
+Global: .MAKEFLAGS = -r -k -d p -d 0 -d v -d 0
+make: "deptgt.mk" line 51: Unknown modifier "Z"
+ while evaluating "${:U:Z}:" with value ""
+make: "deptgt.mk" line 55: Unknown modifier "Z"
+ while parsing "${:U:Z}:"
+make: "deptgt.mk" line 58: warning: Extra target 'ordinary' ignored
+make: "deptgt.mk" line 61: warning: Extra target (ordinary) ignored
+make: "deptgt.mk" line 64: warning: Special and mundane targets don't mix. Mundane ones ignored
make: Fatal errors encountered -- cannot continue
make: stopped making "target1" in unit-tests
exit status 1
diff --git a/unit-tests/deptgt.mk b/unit-tests/deptgt.mk
index 2e6845b88038..f841f24e8984 100644
--- a/unit-tests/deptgt.mk
+++ b/unit-tests/deptgt.mk
@@ -1,4 +1,4 @@
-# $NetBSD: deptgt.mk,v 1.20 2024/07/06 10:14:35 rillig Exp $
+# $NetBSD: deptgt.mk,v 1.22 2025/01/10 23:00:38 rillig Exp $
#
# Tests for special targets like .BEGIN or .SUFFIXES in dependency
# declarations.
@@ -39,13 +39,19 @@ ${:U}: empty-source
: command for empty targets list
.MAKEFLAGS: -d0
+# An expression based on an undefined variable is allowed on both sides of
+# the dependency declaration.
+.MAKEFLAGS: -dv
+deptgt-${UNDEF}: depsrc-${UNDEF}
+.MAKEFLAGS: -d0
+
# In a dependency declaration, the whole line is expanded before interpreting
# the line.
-# expect+1: while evaluating "${:U:Z}:" with value "": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
${:U:Z}:
# After expanding the line as a whole, each target is parsed but not
# evaluated, separately, in ParseDependencyTargetWord.
-# expect+1: while parsing "${:U:Z}:": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
$${:U:Z}:
# expect+1: warning: Extra target 'ordinary' ignored
diff --git a/unit-tests/directive-export-impl.exp b/unit-tests/directive-export-impl.exp
index 7daf1f45b0cb..ff5f1663e160 100644
--- a/unit-tests/directive-export-impl.exp
+++ b/unit-tests/directive-export-impl.exp
@@ -1,19 +1,19 @@
-Parsing line 21: UT_VAR= <${REF}>
+Parsing directive-export-impl.mk:21: UT_VAR= <${REF}>
Global: UT_VAR = <${REF}>
-Parsing line 28: .export UT_VAR
+Parsing directive-export-impl.mk:28: .export UT_VAR
Global: .MAKE.EXPORTED = UT_VAR
-Parsing line 32: : ${UT_VAR:N*}
-Var_Parse: ${UT_VAR:N*} (eval-defined)
-Var_Parse: ${REF}> (eval-defined)
+Parsing directive-export-impl.mk:32: : ${UT_VAR:N*}
+Var_Parse: ${UT_VAR:N*} (eval)
+Var_Parse: ${REF}> (eval)
Evaluating modifier ${UT_VAR:N...} on value "<>"
Pattern for ':N' is "*"
ModifyWords: split "<>" into 1 word
Result of ${UT_VAR:N*} is ""
ParseDependency(: )
-Parsing line 42: .if ${:!echo "\$UT_VAR"!} != "<>"
+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,22 +23,22 @@ Evaluating modifier ${.MAKE.EXPORTED:u} on value "UT_VAR"
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 line 50: : ${UT_VAR:N*}
-Var_Parse: ${UT_VAR:N*} (eval-defined)
-Var_Parse: ${REF}> (eval-defined)
+Parsing directive-export-impl.mk:50: : ${UT_VAR:N*}
+Var_Parse: ${UT_VAR:N*} (eval)
+Var_Parse: ${REF}> (eval)
Evaluating modifier ${UT_VAR:N...} on value "<>"
Pattern for ':N' is "*"
ModifyWords: split "<>" into 1 word
Result of ${UT_VAR:N*} is ""
ParseDependency(: )
-Parsing line 54: REF= defined
+Parsing directive-export-impl.mk:54: REF= defined
Global: REF = defined
-Parsing line 58: .if ${:!echo "\$UT_VAR"!} != "<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,12 +48,12 @@ Evaluating modifier ${.MAKE.EXPORTED:u} on value "UT_VAR"
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 line 62: all:
+Parsing directive-export-impl.mk:62: all:
ParseDependency(all:)
Global: .ALLTARGETS = all
-Parsing line 63: .MAKEFLAGS: -d0
+Parsing directive-export-impl.mk:63: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
Global: .MAKEFLAGS = -r -k -d cpv -d
Global: .MAKEFLAGS = -r -k -d cpv -d 0
diff --git a/unit-tests/directive-for-errors.exp b/unit-tests/directive-for-errors.exp
index 463f5a376997..e5d5cd158e8e 100644
--- a/unit-tests/directive-for-errors.exp
+++ b/unit-tests/directive-for-errors.exp
@@ -8,7 +8,8 @@ make: "directive-for-errors.mk" line 44: invalid character '$' in .for loop vari
make: "directive-for-errors.mk" line 52: no iteration variables in for
make: "directive-for-errors.mk" line 64: Wrong number of words (5) in .for substitution list with 3 variables
make: "directive-for-errors.mk" line 78: missing `in' in for
-make: "directive-for-errors.mk" line 89: while evaluating "${:U3:Z} 4" with value "3": Unknown modifier "Z"
+make: "directive-for-errors.mk" line 89: Unknown modifier "Z"
+ while evaluating "${:U3:Z} 4" with value "3"
make: "directive-for-errors.mk" line 93: warning: Should not be reached.
make: "directive-for-errors.mk" line 93: warning: Should not be reached.
make: "directive-for-errors.mk" line 93: warning: Should not be reached.
diff --git a/unit-tests/directive-for-errors.mk b/unit-tests/directive-for-errors.mk
index 3cbf457622e8..0fb556ec8ec3 100644
--- a/unit-tests/directive-for-errors.mk
+++ b/unit-tests/directive-for-errors.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-errors.mk,v 1.13 2024/07/06 10:14:35 rillig Exp $
+# $NetBSD: directive-for-errors.mk,v 1.14 2024/08/29 20:20:36 rillig Exp $
#
# Tests for error handling in .for loops.
@@ -85,7 +85,7 @@ ${:U\\}= backslash # see whether the "variable" '\' is local
#
# XXX: As of 2020-12-31, Var_Subst doesn't report any errors, therefore
# the loop body is expanded as if no error had happened.
-# expect+1: while evaluating "${:U3:Z} 4" with value "3": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
.for i in 1 2 ${:U3:Z} 4
# expect+3: warning: Should not be reached.
# expect+2: warning: Should not be reached.
diff --git a/unit-tests/directive-for-escape.exp b/unit-tests/directive-for-escape.exp
index 6dfea5e79bb6..be6c2b2a41bf 100644
--- a/unit-tests/directive-for-escape.exp
+++ b/unit-tests/directive-for-escape.exp
@@ -1,13 +1,15 @@
For: end for 1
For: loop body with chars = !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~:
. info ${:U!"#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
-make: "directive-for-escape.mk" line 21: while evaluating "${:U!"" with value "!"": Unclosed expression, expecting '}' for modifier "U!""
+make: "directive-for-escape.mk" line 21: Unclosed expression, expecting '}' for modifier "U!""
+ while evaluating "${:U!"" with value "!""
in .for loop from directive-for-escape.mk:20 with chars = !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
make: "directive-for-escape.mk" line 21: !"
For: end for 1
For: loop body with chars = !"\\#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~:
. info ${:U!"\\\\#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
-make: "directive-for-escape.mk" line 33: while evaluating "${:U!"\\\\" with value "!"\\": Unclosed expression, expecting '}' for modifier "U!"\\\\"
+make: "directive-for-escape.mk" line 33: Unclosed expression, expecting '}' for modifier "U!"\\\\"
+ while evaluating "${:U!"\\\\" with value "!"\\"
in .for loop from directive-for-escape.mk:32 with chars = !"\\#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
make: "directive-for-escape.mk" line 33: !"\\
For: end for 1
@@ -104,7 +106,7 @@ make: "directive-for-escape.mk" line 223: short: " ", long: " "
For: end for 1
For: loop body with i = "
":
-Parsing line 236: .for i in "${.newline}"
+Parsing directive-for-escape.mk:236: .for i in "${.newline}"
For: end for 1
Parse_PushInput: .for loop in directive-for-escape.mk, line 236
make: "directive-for-escape.mk" line 236: newline in .for value
@@ -114,11 +116,11 @@ For: loop body with i = "
":
: ${:U" "}
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
-Parsing line 237: : ${:U" "}
+Parsing directive-for-escape.mk:237: : ${:U" "}
ParseDependency(: " ")
ParseEOF: returning to file directive-for-escape.mk, line 239
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
-Parsing line 239: .MAKEFLAGS: -d0
+Parsing directive-for-escape.mk:239: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
For: end for 1
For: loop body with i = #:
diff --git a/unit-tests/directive-for-escape.mk b/unit-tests/directive-for-escape.mk
index dcd13e1392c0..e688ce98f258 100644
--- a/unit-tests/directive-for-escape.mk
+++ b/unit-tests/directive-for-escape.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-escape.mk,v 1.28 2024/07/07 11:20:10 rillig Exp $
+# $NetBSD: directive-for-escape.mk,v 1.29 2024/08/29 20:20:36 rillig Exp $
#
# Test escaping of special characters in the iteration values of a .for loop.
# These values get expanded later using the :U variable modifier, and this
@@ -15,7 +15,7 @@ ASCII= !"\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
# XXX: As of 2020-12-31, the '#' is not preserved in the expanded body of
# the loop. Not only would it need the escaping for the variable modifier
# ':U' but also the escaping for the line-end comment.
-# expect+3: while evaluating "${:U!"" with value "!"": Unclosed expression, expecting '}' for modifier "U!""
+# expect+3: Unclosed expression, expecting '}' for modifier "U!""
# expect+2: !"
.for chars in ${ASCII}
. info ${chars}
@@ -27,7 +27,7 @@ ASCII= !"\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
# This means that a '#' sign cannot be passed in the value of a .for loop
# at all.
ASCII.2020-12-31= !"\\\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
-# expect+3: while evaluating "${:U!"\\\\" with value "!"\\": Unclosed expression, expecting '}' for modifier "U!"\\\\"
+# expect+3: Unclosed expression, expecting '}' for modifier "U!"\\\\"
# expect+2: !"\\
.for chars in ${ASCII.2020-12-31}
. info ${chars}
diff --git a/unit-tests/directive-for.exp b/unit-tests/directive-for.exp
index 62b51aa406bf..b76a62bc81a2 100755
--- a/unit-tests/directive-for.exp
+++ b/unit-tests/directive-for.exp
@@ -17,7 +17,8 @@ make: "directive-for.mk" line 158: }{ }{ }{
make: "directive-for.mk" line 166: invalid character ':' in .for loop variable name
make: "directive-for.mk" line 173: invalid character '$' in .for loop variable name
make: "directive-for.mk" line 185: invalid character '$' in .for loop variable name
-make: "directive-for.mk" line 210: while evaluating "${:Uword2:Z}-after word3" with value "word2": Unknown modifier "Z"
+make: "directive-for.mk" line 210: Unknown modifier "Z"
+ while evaluating "${:Uword2:Z}-after word3" with value "word2"
make: "directive-for.mk" line 214: XXX: Should not reach word1
make: "directive-for.mk" line 214: XXX: Should not reach before--after
make: "directive-for.mk" line 214: XXX: Should not reach word3
diff --git a/unit-tests/directive-for.mk b/unit-tests/directive-for.mk
index 96c1a492a5f7..cf24e282f730 100755
--- a/unit-tests/directive-for.mk
+++ b/unit-tests/directive-for.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for.mk,v 1.27 2024/07/06 10:14:35 rillig Exp $
+# $NetBSD: directive-for.mk,v 1.28 2024/08/29 20:20:36 rillig Exp $
#
# Tests for the .for directive.
#
@@ -206,7 +206,7 @@ INDIRECT= ${DIRECT}
# XXX: A parse error or evaluation error in the items of the .for loop
# should skip the whole loop. As of 2023-05-09, the loop is expanded as
# usual.
-# expect+1: while evaluating "${:Uword2:Z}-after word3" with value "word2": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
.for var in word1 before-${:Uword2:Z}-after word3
# expect+3: XXX: Should not reach word1
# expect+2: XXX: Should not reach before--after
diff --git a/unit-tests/directive-if-nested.mk b/unit-tests/directive-if-nested.mk
index 19c8e9452660..93fce90b5d52 100644
--- a/unit-tests/directive-if-nested.mk
+++ b/unit-tests/directive-if-nested.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-if-nested.mk,v 1.1 2020/11/10 22:23:37 rillig Exp $
+# $NetBSD: directive-if-nested.mk,v 1.2 2025/01/03 05:00:37 rillig Exp $
#
# Tests for deeply nested .if directives. By default, memory for 128 nested
# .if directives is pre-allocated, any deeper nesting is reallocated.
@@ -13,7 +13,7 @@ all: set-up test tear-down
set-up: .PHONY
@{ printf '.if %s\n' ${:U:range=1000}; \
printf '.info deeply nested .if directives\n'; \
- printf '.endif # %s\n' ${:U:range=1000}; \
+ printf '.endif # %s\n' ${:U:range=1000:[-1..1]}; \
printf '\n'; \
printf 'all:\n'; \
} > ${GEN}
diff --git a/unit-tests/directive-if.exp b/unit-tests/directive-if.exp
index 34ba63d034dd..56c8dfda5e30 100644
--- a/unit-tests/directive-if.exp
+++ b/unit-tests/directive-if.exp
@@ -5,7 +5,7 @@ make: "directive-if.mk" line 45: This is not conditional.
make: "directive-if.mk" line 47: if-less else
make: "directive-if.mk" line 49: This is not conditional.
make: "directive-if.mk" line 51: if-less endif
-make: "directive-if.mk" line 55: Malformed conditional ()
+make: "directive-if.mk" line 55: Malformed conditional ''
make: "directive-if.mk" line 66: Quotes in plain words are probably a mistake.
make: "directive-if.mk" line 76: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 81: Don't do this, always put a space after a directive.
diff --git a/unit-tests/directive-if.mk b/unit-tests/directive-if.mk
index 7a68c0041415..7ff04da0755b 100644
--- a/unit-tests/directive-if.mk
+++ b/unit-tests/directive-if.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-if.mk,v 1.12 2023/06/01 20:56:35 rillig Exp $
+# $NetBSD: directive-if.mk,v 1.13 2024/08/06 18:00:17 rillig Exp $
#
# Tests for the .if directive.
#
@@ -51,7 +51,7 @@
.endif
# Missing condition.
-# expect+1: Malformed conditional ()
+# expect+1: Malformed conditional ''
.if
. error
.else
diff --git a/unit-tests/directive-include-fatal.exp b/unit-tests/directive-include-fatal.exp
index edb32df1a59b..35706336c1dd 100755
--- a/unit-tests/directive-include-fatal.exp
+++ b/unit-tests/directive-include-fatal.exp
@@ -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
diff --git a/unit-tests/directive-include-fatal.mk b/unit-tests/directive-include-fatal.mk
index d4ed26f2a4aa..ecda6f1982c4 100755
--- a/unit-tests/directive-include-fatal.mk
+++ b/unit-tests/directive-include-fatal.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-include-fatal.mk,v 1.4 2023/06/01 20:56:35 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
diff --git a/unit-tests/directive-include-guard.exp b/unit-tests/directive-include-guard.exp
index 70d23a19fe7c..d7d2789681af 100644
--- a/unit-tests/directive-include-guard.exp
+++ b/unit-tests/directive-include-guard.exp
@@ -95,8 +95,10 @@ Parse_PushInput: file target-already-defined.tmp, line 1
Skipping 'target-already-defined.tmp' because 'target-already-defined' is defined
Parse_PushInput: file target-name-exclamation.tmp, line 1
Parse_PushInput: file target-name-exclamation.tmp, line 1
-Parse_PushInput: file target-name-parenthesized.tmp, line 1
-Parse_PushInput: file target-name-parenthesized.tmp, line 1
+Parse_PushInput: file target-name-leading-space.tmp, line 1
+Parse_PushInput: file target-name-leading-space.tmp, line 1
+Parse_PushInput: file target-name-trailing-space.tmp, line 1
+Parse_PushInput: file target-name-trailing-space.tmp, line 1
Parse_PushInput: file target-call-parenthesized.tmp, line 1
Parse_PushInput: file target-call-parenthesized.tmp, line 1
Parse_PushInput: file multiline.tmp, line 1
diff --git a/unit-tests/directive-include-guard.mk b/unit-tests/directive-include-guard.mk
index 85c0242c2009..4c4194be4c36 100644
--- a/unit-tests/directive-include-guard.mk
+++ b/unit-tests/directive-include-guard.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-include-guard.mk,v 1.16 2023/12/17 14:07:22 rillig Exp $
+# $NetBSD: directive-include-guard.mk,v 1.18 2024/08/07 05:48:45 rillig Exp $
#
# Tests for multiple-inclusion guards in makefiles.
#
@@ -581,15 +581,25 @@ LINES.target-name-exclamation= \
# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
-# If the guard target name is enclosed in spaces, it does not have an effect,
+# If the guard target name has leading spaces, it does not have an effect,
# as that form is not common in practice.
-CASES+= target-name-parenthesized
-LINES.target-name-parenthesized= \
- '.if !target( target-name-parenthesized )' \
- 'target-name-parenthesized: .NOTMAIN' \
+CASES+= target-name-leading-space
+LINES.target-name-leading-space= \
+ '.if !target( target-name-leading-space)' \
+ 'target-name-leading-space: .NOTMAIN' \
'.endif'
-# expect: Parse_PushInput: file target-name-parenthesized.tmp, line 1
-# expect: Parse_PushInput: file target-name-parenthesized.tmp, line 1
+# expect: Parse_PushInput: file target-name-leading-space.tmp, line 1
+# expect: Parse_PushInput: file target-name-leading-space.tmp, line 1
+
+# If the guard target name has trailing spaces, it does not have an effect,
+# as that form is not common in practice.
+CASES+= target-name-trailing-space
+LINES.target-name-trailing-space= \
+ '.if !target(target-name-trailing-space )' \
+ 'target-name-trailing-space: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-name-trailing-space.tmp, line 1
+# expect: Parse_PushInput: file target-name-trailing-space.tmp, line 1
# If the guard target condition is enclosed in parentheses, it does not have
# an effect, as that form is not common in practice.
diff --git a/unit-tests/directive-include.exp b/unit-tests/directive-include.exp
index 4c395d7532aa..11a6ab8bc88a 100755
--- a/unit-tests/directive-include.exp
+++ b/unit-tests/directive-include.exp
@@ -4,7 +4,8 @@ CondParser_Eval: ${.MAKE.MAKEFILES:T} != "${.PARSEFILE} null"
Comparing "directive-include.mk null" != "directive-include.mk null"
make: "directive-include.mk" line 26: Could not find nonexistent.mk
make: "directive-include.mk" line 49: Could not find "
-make: "directive-include.mk" line 56: while evaluating "${:U123:Z}.mk" with value "123": Unknown modifier "Z"
+make: "directive-include.mk" line 56: Unknown modifier "Z"
+ while evaluating "${:U123:Z}.mk" with value "123"
make: "directive-include.mk" line 56: Could not find nonexistent.mk
make: "directive-include.mk" line 61: Cannot open /nonexistent
make: "directive-include.mk" line 66: Invalid line 'include'
diff --git a/unit-tests/directive-include.mk b/unit-tests/directive-include.mk
index e2ef8dc55e3c..bf3dd158b2ad 100755
--- a/unit-tests/directive-include.mk
+++ b/unit-tests/directive-include.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-include.mk,v 1.15 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: directive-include.mk,v 1.17 2025/01/11 20:16:40 rillig Exp $
#
# Tests for the .include directive, which includes another file.
@@ -51,8 +51,8 @@ DQUOT= "
# When the expression in a filename cannot be evaluated, the failing
# expression is skipped and the file is included nevertheless.
# FIXME: Add proper error handling, no file must be included here.
-# expect+2: Could not find nonexistent.mk
-# expect+1: while evaluating "${:U123:Z}.mk" with value "123": Unknown modifier "Z"
+# expect+2: Unknown modifier "Z"
+# expect+1: Could not find nonexistent.mk
.include "nonexistent${:U123:Z}.mk"
# The traditional include directive is seldom used.
diff --git a/unit-tests/directive-undef.exp b/unit-tests/directive-undef.exp
index c3d01fc480c6..c62452abe2ba 100644
--- a/unit-tests/directive-undef.exp
+++ b/unit-tests/directive-undef.exp
@@ -1,5 +1,6 @@
make: "directive-undef.mk" line 30: The .undef directive requires an argument
-make: "directive-undef.mk" line 88: while evaluating variable "VARNAMES" with value "VARNAMES": Unknown modifier "Z"
+make: "directive-undef.mk" line 88: Unknown modifier "Z"
+ while evaluating variable "VARNAMES" with value "VARNAMES"
make: "directive-undef.mk" line 105: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore.
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
diff --git a/unit-tests/directive-undef.mk b/unit-tests/directive-undef.mk
index 43938e3170ea..167bb79ad07f 100644
--- a/unit-tests/directive-undef.mk
+++ b/unit-tests/directive-undef.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-undef.mk,v 1.15 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: directive-undef.mk,v 1.16 2024/08/29 20:20:36 rillig Exp $
#
# Tests for the .undef directive.
#
@@ -84,7 +84,7 @@ ${DOLLAR}= dollar
#
# As of var.c 1.762, this doesn't happen though because the error handling
# in Var_Parse and Var_Subst is not done properly.
-# expect+1: while evaluating variable "VARNAMES" with value "VARNAMES": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
.undef ${VARNAMES:L:Z}
diff --git a/unit-tests/include-main.exp b/unit-tests/include-main.exp
index fcc38247109f..f2b4263fccc4 100644
--- a/unit-tests/include-main.exp
+++ b/unit-tests/include-main.exp
@@ -2,13 +2,13 @@ make: "include-main.mk" line 15: main-before-ok
make: "include-main.mk" line 23: main-before-for-ok
make: "include-sub.inc" line 4: sub-before-ok
make: "include-sub.inc" line 14: sub-before-for-ok
-Parsing line 5: . info subsub-ok
+Parsing include-subsub.inc:5: . info subsub-ok
make: "include-subsub.inc" line 5: subsub-ok
in .for loop from include-sub.inc:31 with i = include
in .for loop from include-sub.inc:30 with i = nested
in .for loop from include-sub.inc:29 with i = deeply
in include-main.mk:29
-Parsing line 6: .MAKEFLAGS: -d0
+Parsing include-subsub.inc:6: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
make: "include-sub.inc" line 38: sub-after-ok
make: "include-sub.inc" line 45: sub-after-for-ok
diff --git a/unit-tests/lint.exp b/unit-tests/lint.exp
index 714093ca2b7d..ded93d192b14 100755
--- a/unit-tests/lint.exp
+++ b/unit-tests/lint.exp
@@ -1,4 +1,4 @@
-make: in target "mod-loop-varname": while evaluating variable "VAR" with value "value": In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar
-y@:Q}
-xvaluey
+make: In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar
+ while evaluating variable "VAR" with value "value"
+ in target "mod-loop-varname"
exit status 2
diff --git a/unit-tests/moderrs.exp b/unit-tests/moderrs.exp
index 05a5108935cd..06c305c83e4f 100644
--- a/unit-tests/moderrs.exp
+++ b/unit-tests/moderrs.exp
@@ -1,115 +1,140 @@
-make: in target "mod-unknown-direct": while evaluating variable "VAR" with value "TheVariable": Unknown modifier "Z"
-VAR:Z=before--after
-
-make: in target "mod-unknown-indirect": while evaluating variable "VAR" with value "TheVariable": Unknown modifier "Z"
-VAR:Z=before-inner}-after
-
-unclosed-direct:
-make: in target "unclosed-direct": while evaluating variable "VAR" with value "Thevariable": Unclosed expression, expecting '}' for modifier "S,V,v,"
-VAR:S,V,v,=Thevariable
-
-unclosed-indirect:
-make: in target "unclosed-indirect": while evaluating variable "VAR" with value "Thevariable": Unclosed expression after indirect modifier, expecting '}'
-VAR:S,V,v,=Thevariable
-
-make: in target "unfinished-indirect": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-VAR:S,V,v=
-
-make: in target "unfinished-loop": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier ('@' missing)
-
-make: in target "unfinished-loop": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier ('@' missing)
-
+make: Unknown modifier "Z"
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-unknown-direct"
+make: Unknown modifier "Z"
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-unknown-indirect"
+make: Unclosed expression, expecting '}' for modifier "S,V,v,"
+ while evaluating variable "VAR" with value "Thevariable"
+ in target "unclosed-direct"
+make: Unclosed expression after indirect modifier, expecting '}'
+ while evaluating variable "VAR" with value "Thevariable"
+ in target "unclosed-indirect"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "unfinished-indirect"
+make: Unfinished modifier ('@' missing)
+ while evaluating variable "UNDEF" with value "1 2 3"
+ in target "unfinished-loop-1"
+make: Unfinished modifier ('@' missing)
+ while evaluating variable "UNDEF" with value "1 2 3"
+ in target "unfinished-loop-2"
1 2 3
-
-loop-close:
-make: in target "loop-close": while evaluating variable "UNDEF" with value "1}... 2}... 3}...": Unclosed expression, expecting '}' for modifier "@var@${var}}...@"
+make: Unclosed expression, expecting '}' for modifier "@var@${var}}...@"
+ while evaluating variable "UNDEF" with value "1}... 2}... 3}..."
+ in target "loop-close-1"
1}... 2}... 3}...
-1}... 2}... 3}...
-
-make: in target "words": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier (']' missing)
-
-make: in target "words": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier (']' missing)
-
+make: Unfinished modifier (']' missing)
+ while evaluating variable "UNDEF" with value "1 2 3"
+ in target "words-1"
+make: Unfinished modifier (']' missing)
+ while evaluating variable "UNDEF" with value "1 2 3"
+ in target "words-2"
13=
-make: in target "words": while evaluating variable "UNDEF" with value "1 2 3": Bad modifier ":[123451234512345123451234512345]"
-12345=S,^ok,:S,^3ok,}
-
-make: in target "exclam": while evaluating variable "VARNAME" with value "": Unfinished modifier ('!' missing)
-
-make: in target "exclam": while evaluating variable "!" with value "!": Unfinished modifier ('!' missing)
-
-
-make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Missing delimiter for modifier ':S'
-1:
-make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-2:
-make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-3:
-make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-4:
-make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-5:
-make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unclosed expression, expecting '}' for modifier "S,from,to,"
-6: TheVariable
+make: Bad modifier ":[123451234512345123451234512345]"
+ while evaluating variable "UNDEF" with value "1 2 3"
+ in target "words-3"
+make: Unfinished modifier ('!' missing)
+ while evaluating variable "VARNAME" with value ""
+ in target "exclam-1"
+make: Unfinished modifier ('!' missing)
+ while evaluating variable "!" with value "!"
+ in target "exclam-2"
+make: Missing delimiter for modifier ':S'
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-subst-delimiter-1"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-subst-delimiter-2"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-subst-delimiter-3"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-subst-delimiter-4"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-subst-delimiter-5"
+make: Unclosed expression, expecting '}' for modifier "S,from,to,"
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-subst-delimiter-6"
7: TheVariable
-
-make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Missing delimiter for modifier ':C'
-1:
-make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-2:
-make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-3:
-make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-4:
-make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
-5:
-make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unclosed expression, expecting '}' for modifier "C,from,to,"
-6: TheVariable
+make: Missing delimiter for modifier ':C'
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-regex-delimiter-1"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-regex-delimiter-2"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-regex-delimiter-3"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-regex-delimiter-4"
+make: Unfinished modifier (',' missing)
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-regex-delimiter-5"
+make: Unclosed expression, expecting '}' for modifier "C,from,to,"
+ while evaluating variable "VAR" with value "TheVariable"
+ in target "mod-regex-delimiter-6"
7: TheVariable
-
-mod-ts-parse:
112358132134
15152535558513521534
-make: in target "mod-ts-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":ts\65oct"
-65oct}
-make: in target "mod-ts-parse": while evaluating "${:U${FIB}:ts\65oct} # bad modifier, variable name is """ with value "1 1 2 3 5 8 13 21 34": Bad modifier ":ts\65oct"
-65oct}
-make: in target "mod-ts-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":tsxy"
-xy}
-
-mod-t-parse:
-make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":t"
-
-make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":txy"
-y}
-make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":t"
-
-make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":t"
-M*}
-
-make: in target "mod-ifelse-parse": while evaluating then-branch of condition "FIB": Unfinished modifier (':' missing)
-
-make: in target "mod-ifelse-parse": while evaluating then-branch of condition "FIB": Unfinished modifier (':' missing)
-
-make: in target "mod-ifelse-parse": while evaluating else-branch of condition "FIB": Unfinished modifier ('}' missing)
-
-make: in target "mod-ifelse-parse": while evaluating else-branch of condition "FIB": Unfinished modifier ('}' missing)
-
+make: Bad modifier ":ts\65oct"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-ts-parse-3"
+make: Bad modifier ":ts\65oct"
+ while evaluating "${:U${FIB}:ts\65oct} # bad modifier, variable name is """ with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-ts-parse-4"
+make: Bad modifier ":tsxy"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-ts-parse-5"
+make: Bad modifier ":t"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-t-parse-1"
+make: Bad modifier ":txy"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-t-parse-2"
+make: Bad modifier ":t"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-t-parse-3"
+make: Bad modifier ":t"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-t-parse-4"
+make: Unfinished modifier (':' missing)
+ while evaluating then-branch of condition "FIB"
+ in target "mod-ifelse-parse-1"
+make: Unfinished modifier (':' missing)
+ while evaluating then-branch of condition "FIB"
+ in target "mod-ifelse-parse-2"
+make: Unfinished modifier ('}' missing)
+ while evaluating else-branch of condition "FIB"
+ in target "mod-ifelse-parse-3"
+make: Unfinished modifier ('}' missing)
+ while evaluating else-branch of condition "FIB"
+ in target "mod-ifelse-parse-4"
then
-
1 1 2 3 5 8 13 21 34
-make: in target "mod-remember-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "__"
-
-
-make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "3"
-make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "": Unclosed expression, expecting '}' for modifier "3"
-
-make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "3="
-make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "": Unclosed expression, expecting '}' for modifier "3="
-
-make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "3=x3"
-make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "": Unclosed expression, expecting '}' for modifier "3=x3"
-
+make: Unknown modifier "__"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-remember-parse"
+make: Unknown modifier "3"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-sysv-parse-1"
+make: Unclosed expression, expecting '}' for modifier "3"
+ while evaluating variable "FIB" with value ""
+ in target "mod-sysv-parse-1"
+make: Unknown modifier "3="
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-sysv-parse-2"
+make: Unclosed expression, expecting '}' for modifier "3="
+ while evaluating variable "FIB" with value ""
+ in target "mod-sysv-parse-2"
+make: Unknown modifier "3=x3"
+ while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
+ in target "mod-sysv-parse-3"
+make: Unclosed expression, expecting '}' for modifier "3=x3"
+ while evaluating variable "FIB" with value ""
+ in target "mod-sysv-parse-3"
1 1 2 x3 5 8 1x3 21 34
-
exit status 2
diff --git a/unit-tests/moderrs.mk b/unit-tests/moderrs.mk
index 66af52c14a65..ad9333dcfb1d 100644
--- a/unit-tests/moderrs.mk
+++ b/unit-tests/moderrs.mk
@@ -1,4 +1,4 @@
-# $NetBSD: moderrs.mk,v 1.38 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: moderrs.mk,v 1.41 2024/08/29 20:20:36 rillig Exp $
#
# various modifier error tests
@@ -12,43 +12,45 @@ FIB= 1 1 2 3 5 8 13 21 34
all: mod-unknown-direct mod-unknown-indirect
all: unclosed-direct unclosed-indirect
-all: unfinished-indirect unfinished-loop
-all: loop-close
-all: words
-all: exclam
-all: mod-subst-delimiter
-all: mod-regex-delimiter
-all: mod-ts-parse
-all: mod-t-parse
-all: mod-ifelse-parse
+all: unfinished-indirect unfinished-loop-{1,2,3}
+all: loop-close-{1,2}
+all: words-{1,2,3}
+all: exclam-{1,2}
+all: mod-subst-delimiter-{1,2,3,4,5,6,7}
+all: mod-regex-delimiter-{1,2,3,4,5,6,7}
+all: mod-ts-parse-{1,2,3,4,5}
+all: mod-t-parse-{1,2,3,4}
+all: mod-ifelse-parse-{1,2,3,4,5}
all: mod-remember-parse
-all: mod-sysv-parse
+all: mod-sysv-parse-{1,2,3,4}
-mod-unknown-direct: print-footer
-# expect: make: in target "mod-unknown-direct": while evaluating variable "VAR" with value "TheVariable": Unknown modifier "Z"
+mod-unknown-direct:
+# expect: make: Unknown modifier "Z"
@echo 'VAR:Z=before-${VAR:Z}-after'
-mod-unknown-indirect: print-footer
-# expect: make: in target "mod-unknown-indirect": while evaluating variable "VAR" with value "TheVariable": Unknown modifier "Z"
+mod-unknown-indirect:
+# expect: make: Unknown modifier "Z"
@echo 'VAR:${MOD_UNKN}=before-${VAR:${MOD_UNKN}:inner}-after'
-unclosed-direct: print-header print-footer
-# expect: make: in target "unclosed-direct": while evaluating variable "VAR" with value "Thevariable": Unclosed expression, expecting '}' for modifier "S,V,v,"
+unclosed-direct:
+# expect: make: Unclosed expression, expecting '}' for modifier "S,V,v,"
@echo VAR:S,V,v,=${VAR:S,V,v,
-unclosed-indirect: print-header print-footer
-# expect: make: in target "unclosed-indirect": while evaluating variable "VAR" with value "Thevariable": Unclosed expression after indirect modifier, expecting '}'
+unclosed-indirect:
+# expect: make: Unclosed expression after indirect modifier, expecting '}'
@echo VAR:${MOD_TERM},=${VAR:${MOD_S}
-unfinished-indirect: print-footer
-# expect: make: in target "unfinished-indirect": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+unfinished-indirect:
+# expect: make: Unfinished modifier (',' missing)
-@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}"
-unfinished-loop: print-footer
-# expect: make: in target "unfinished-loop": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier ('@' missing)
+unfinished-loop-1:
+# expect: make: Unfinished modifier ('@' missing)
@echo ${UNDEF:U1 2 3:@var}
-# expect: make: in target "unfinished-loop": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier ('@' missing)
+unfinished-loop-2:
+# expect: make: Unfinished modifier ('@' missing)
@echo ${UNDEF:U1 2 3:@var@...}
+unfinished-loop-3:
@echo ${UNDEF:U1 2 3:@var@${var}@}
# The closing brace after the ${var} is part of the replacement string.
@@ -57,17 +59,20 @@ unfinished-loop: print-footer
# braces must be balanced.
# This is also contrary to the SysV modifier, where only the actually
# used delimiter (either braces or parentheses) must be balanced.
-loop-close: print-header print-footer
-# expect: make: in target "loop-close": while evaluating variable "UNDEF" with value "1}... 2}... 3}...": Unclosed expression, expecting '}' for modifier "@var@${var}}...@"
+loop-close-1:
+# expect: make: Unclosed expression, expecting '}' for modifier "@var@${var}}...@"
@echo ${UNDEF:U1 2 3:@var@${var}}...@
+loop-close-2:
@echo ${UNDEF:U1 2 3:@var@${var}}...@}
-words: print-footer
-# expect: make: in target "words": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier (']' missing)
+words-1:
+# expect: make: Unfinished modifier (']' missing)
@echo ${UNDEF:U1 2 3:[}
-# expect: make: in target "words": while evaluating variable "UNDEF" with value "1 2 3": Unfinished modifier (']' missing)
+words-2:
+# expect: make: Unfinished modifier (']' missing)
@echo ${UNDEF:U1 2 3:[#}
+words-3:
# out of bounds => empty
@echo 13=${UNDEF:U1 2 3:[13]}
@@ -90,95 +95,117 @@ words: print-footer
# That variable is undefined, resulting in an empty string.
@echo 12345=${UNDEF:U1 2 3:[123451234512345123451234512345]:S,^$,ok,:S,^3$,ok,}
-exclam: print-footer
-# expect: make: in target "exclam": while evaluating variable "VARNAME" with value "": Unfinished modifier ('!' missing)
+exclam-1:
+# expect: make: Unfinished modifier ('!' missing)
@echo ${VARNAME:!echo}
# When the final exclamation mark is missing, there is no
# fallback to the SysV substitution modifier.
# If there were a fallback, the output would be "exclam",
# and the above would have produced an "Unknown modifier '!'".
-# expect: make: in target "exclam": while evaluating variable "!" with value "!": Unfinished modifier ('!' missing)
+exclam-2:
+# expect: make: Unfinished modifier ('!' missing)
@echo ${!:L:!=exclam}
-mod-subst-delimiter: print-footer
-# expect: make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Missing delimiter for modifier ':S'
+mod-subst-delimiter-1:
+# expect: make: Missing delimiter for modifier ':S'
@echo 1: ${VAR:S
-# expect: make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-subst-delimiter-2:
+# expect: make: Unfinished modifier (',' missing)
@echo 2: ${VAR:S,
-# expect: make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-subst-delimiter-3:
+# expect: make: Unfinished modifier (',' missing)
@echo 3: ${VAR:S,from
-# expect: make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-subst-delimiter-4:
+# expect: make: Unfinished modifier (',' missing)
@echo 4: ${VAR:S,from,
-# expect: make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-subst-delimiter-5:
+# expect: make: Unfinished modifier (',' missing)
@echo 5: ${VAR:S,from,to
-# expect: make: in target "mod-subst-delimiter": while evaluating variable "VAR" with value "TheVariable": Unclosed expression, expecting '}' for modifier "S,from,to,"
+mod-subst-delimiter-6:
+# expect: make: Unclosed expression, expecting '}' for modifier "S,from,to,"
@echo 6: ${VAR:S,from,to,
+mod-subst-delimiter-7:
@echo 7: ${VAR:S,from,to,}
-mod-regex-delimiter: print-footer
-# expect: make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Missing delimiter for modifier ':C'
+mod-regex-delimiter-1:
+# expect: make: Missing delimiter for modifier ':C'
@echo 1: ${VAR:C
-# expect: make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-regex-delimiter-2:
+# expect: make: Unfinished modifier (',' missing)
@echo 2: ${VAR:C,
-# expect: make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-regex-delimiter-3:
+# expect: make: Unfinished modifier (',' missing)
@echo 3: ${VAR:C,from
-# expect: make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-regex-delimiter-4:
+# expect: make: Unfinished modifier (',' missing)
@echo 4: ${VAR:C,from,
-# expect: make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unfinished modifier (',' missing)
+mod-regex-delimiter-5:
+# expect: make: Unfinished modifier (',' missing)
@echo 5: ${VAR:C,from,to
-# expect: make: in target "mod-regex-delimiter": while evaluating variable "VAR" with value "TheVariable": Unclosed expression, expecting '}' for modifier "C,from,to,"
+mod-regex-delimiter-6:
+# expect: make: Unclosed expression, expecting '}' for modifier "C,from,to,"
@echo 6: ${VAR:C,from,to,
+mod-regex-delimiter-7:
@echo 7: ${VAR:C,from,to,}
-mod-ts-parse: print-header print-footer
+mod-ts-parse-1:
@echo ${FIB:ts}
+mod-ts-parse-2:
@echo ${FIB:ts\65} # octal 065 == U+0035 == '5'
-# expect: make: in target "mod-ts-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":ts\65oct"
+mod-ts-parse-3:
+# expect: make: Bad modifier ":ts\65oct"
@echo ${FIB:ts\65oct} # bad modifier
-# expect: make: in target "mod-ts-parse": while evaluating "${:U${FIB}:ts\65oct} # bad modifier, variable name is """ with value "1 1 2 3 5 8 13 21 34": Bad modifier ":ts\65oct"
+mod-ts-parse-4:
+# expect: make: Bad modifier ":ts\65oct"
@echo ${:U${FIB}:ts\65oct} # bad modifier, variable name is ""
-# expect: make: in target "mod-ts-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":tsxy"
+mod-ts-parse-5:
+# expect: make: Bad modifier ":tsxy"
@echo ${FIB:tsxy} # modifier too long
-mod-t-parse: print-header print-footer
-# expect: make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":t"
+mod-t-parse-1:
+# expect: make: Bad modifier ":t"
@echo ${FIB:t
-# expect: make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":txy"
+mod-t-parse-2:
+# expect: make: Bad modifier ":txy"
@echo ${FIB:txy}
-# expect: make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":t"
+mod-t-parse-3:
+# expect: make: Bad modifier ":t"
@echo ${FIB:t}
-# expect: make: in target "mod-t-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Bad modifier ":t"
+mod-t-parse-4:
+# expect: make: Bad modifier ":t"
@echo ${FIB:t:M*}
-mod-ifelse-parse: print-footer
-# expect: make: in target "mod-ifelse-parse": while evaluating then-branch of condition "FIB": Unfinished modifier (':' missing)
+mod-ifelse-parse-1:
+# expect: make: Unfinished modifier (':' missing)
@echo ${FIB:?
-# expect: make: in target "mod-ifelse-parse": while evaluating then-branch of condition "FIB": Unfinished modifier (':' missing)
+mod-ifelse-parse-2:
+# expect: make: Unfinished modifier (':' missing)
@echo ${FIB:?then
-# expect: make: in target "mod-ifelse-parse": while evaluating else-branch of condition "FIB": Unfinished modifier ('}' missing)
+mod-ifelse-parse-3:
+# expect: make: Unfinished modifier ('}' missing)
@echo ${FIB:?then:
-# expect: make: in target "mod-ifelse-parse": while evaluating else-branch of condition "FIB": Unfinished modifier ('}' missing)
+mod-ifelse-parse-4:
+# expect: make: Unfinished modifier ('}' missing)
@echo ${FIB:?then:else
+mod-ifelse-parse-5:
@echo ${FIB:?then:else}
-mod-remember-parse: print-footer
+mod-remember-parse:
@echo ${FIB:_} # ok
-# expect: make: in target "mod-remember-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "__"
+# expect: make: Unknown modifier "__"
@echo ${FIB:__} # modifier name too long
-mod-sysv-parse: print-footer
-# expect: make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "3"
-# expect: make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "": Unclosed expression, expecting '}' for modifier "3"
+mod-sysv-parse-1:
+# expect: make: Unknown modifier "3"
+# expect: make: Unclosed expression, expecting '}' for modifier "3"
@echo ${FIB:3
-# expect: make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "3="
-# expect: make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "": Unclosed expression, expecting '}' for modifier "3="
+mod-sysv-parse-2:
+# expect: make: Unknown modifier "3="
+# expect: make: Unclosed expression, expecting '}' for modifier "3="
@echo ${FIB:3=
-# expect: make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34": Unknown modifier "3=x3"
-# expect: make: in target "mod-sysv-parse": while evaluating variable "FIB" with value "": Unclosed expression, expecting '}' for modifier "3=x3"
+mod-sysv-parse-3:
+# expect: make: Unknown modifier "3=x3"
+# expect: make: Unclosed expression, expecting '}' for modifier "3=x3"
@echo ${FIB:3=x3
+mod-sysv-parse-4:
@echo ${FIB:3=x3} # ok
-
-print-header: .USEBEFORE
- @echo $@:
-print-footer: .USE
- @echo
diff --git a/unit-tests/opt-debug-lint.exp b/unit-tests/opt-debug-lint.exp
index eea6c8db5a49..7274a06333ee 100644
--- a/unit-tests/opt-debug-lint.exp
+++ b/unit-tests/opt-debug-lint.exp
@@ -1,10 +1,11 @@
-make: "opt-debug-lint.mk" line 21: Variable "X" is undefined
-make: "opt-debug-lint.mk" line 21: Malformed conditional ($X)
-make: "opt-debug-lint.mk" line 45: Variable "UNDEF" is undefined
-make: "opt-debug-lint.mk" line 45: Malformed conditional (${UNDEF})
-make: "opt-debug-lint.mk" line 67: while evaluating variable "value" with value "value": Missing delimiter ':' after modifier "L"
-make: "opt-debug-lint.mk" line 67: while evaluating variable "value" with value "value": Missing delimiter ':' after modifier "P"
-make: "opt-debug-lint.mk" line 76: while evaluating variable "value" with value "": Unknown modifier "${"
+make: "opt-debug-lint.mk" line 20: Variable "X" is undefined
+make: "opt-debug-lint.mk" line 43: Variable "UNDEF" is undefined
+make: "opt-debug-lint.mk" line 65: Missing delimiter ':' after modifier "L"
+ while evaluating variable "value" with value "value"
+make: "opt-debug-lint.mk" line 65: Missing delimiter ':' after modifier "P"
+ while evaluating variable "value" with value "value"
+make: "opt-debug-lint.mk" line 74: Unknown modifier "${"
+ while evaluating variable "value" with value ""
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/opt-debug-lint.mk b/unit-tests/opt-debug-lint.mk
index cc20694e268c..7918490b3f1a 100644
--- a/unit-tests/opt-debug-lint.mk
+++ b/unit-tests/opt-debug-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-lint.mk,v 1.18 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: opt-debug-lint.mk,v 1.22 2025/01/11 20:54:45 rillig Exp $
#
# Tests for the -dL command line option, which runs additional checks
# to catch common mistakes, such as unclosed expressions.
@@ -16,7 +16,6 @@
#
# See also:
# cond-undef-lint.mk
-# expect+2: Malformed conditional ($X)
# expect+1: Variable "X" is undefined
.if $X
. error
@@ -40,7 +39,6 @@
# hoping for the caller to print an error message. This resulted in the
# well-known "Malformed conditional" error message, even though the
# conditional was well-formed and the only error was an undefined variable.
-# expect+2: Malformed conditional (${UNDEF})
# expect+1: Variable "UNDEF" is undefined
.if ${UNDEF}
. error
@@ -62,8 +60,8 @@ ${UNDEF}: ${UNDEF}
# Since 2020-10-03, in lint mode the variable modifier must be separated
# by colons. See varparse-mod.mk.
-# expect+2: while evaluating variable "value" with value "value": Missing delimiter ':' after modifier "L"
-# expect+1: while evaluating variable "value" with value "value": Missing delimiter ':' after modifier "P"
+# expect+2: Missing delimiter ':' after modifier "L"
+# expect+1: Missing delimiter ':' after modifier "P"
.if ${value:LPL} != "value"
. error
.endif
@@ -72,7 +70,7 @@ ${UNDEF}: ${UNDEF}
# variable modifier had to be separated by colons. This was wrong though
# since make always fell back trying to parse the indirect modifier as a
# SysV modifier.
-# expect+1: while evaluating variable "value" with value "": Unknown modifier "${"
+# expect+1: Unknown modifier "${"
.if ${value:${:UL}PL} != "LPL}" # FIXME: "LPL}" is unexpected here.
. error ${value:${:UL}PL}
.endif
diff --git a/unit-tests/opt-debug-parse.exp b/unit-tests/opt-debug-parse.exp
index a19a58bcc965..f0b57f2a703b 100644
--- a/unit-tests/opt-debug-parse.exp
+++ b/unit-tests/opt-debug-parse.exp
@@ -1,28 +1,28 @@
-Parsing line 16: .for var in value
+Parsing opt-debug-parse.mk:16: .for var in value
Parse_PushInput: .for loop in opt-debug-parse.mk, line 16
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 21: .info trace with multi-line .for loop head
+Parsing opt-debug-parse.mk:21: .info trace with multi-line .for loop head
make: "opt-debug-parse.mk" line 21: trace with multi-line .for loop head
in .for loop from opt-debug-parse.mk:16 with var = value
ParseEOF: returning to file opt-debug-parse.mk, line 23
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 26: .include "/dev/null"
+Parsing opt-debug-parse.mk:26: .include "/dev/null"
Parse_PushInput: file /dev/null, line 1
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `null'
SetFilenameVars: ${.INCLUDEDFROMDIR} = <some-dir> ${.INCLUDEDFROMFILE} = `opt-debug-parse.mk'
ParseEOF: returning to file opt-debug-parse.mk, line 27
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 31: .for a b c in 1 2 3 ${:U4 5 6}
+Parsing opt-debug-parse.mk:31: .for a b c in 1 2 3 ${:U4 5 6}
Parse_PushInput: .for loop in opt-debug-parse.mk, line 31
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 34: .info trace
+Parsing opt-debug-parse.mk:34: .info trace
make: "opt-debug-parse.mk" line 34: trace
in .for loop from opt-debug-parse.mk:31 with a = 1, b = 2, c = 3
-Parsing line 34: .info trace
+Parsing opt-debug-parse.mk:34: .info trace
make: "opt-debug-parse.mk" line 34: trace
in .for loop from opt-debug-parse.mk:31 with a = 4, b = 5, c = 6
ParseEOF: returning to file opt-debug-parse.mk, line 36
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 38: .MAKEFLAGS: -d0
+Parsing opt-debug-parse.mk:38: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
exit status 0
diff --git a/unit-tests/opt-debug-var.exp b/unit-tests/opt-debug-var.exp
index 5e9d10c671f1..e113e66f26fe 100644
--- a/unit-tests/opt-debug-var.exp
+++ b/unit-tests/opt-debug-var.exp
@@ -2,6 +2,12 @@ Global: ASSIGNED = value
Global: SUBST = # (empty)
Global: SUBST = value
Var_Parse: y(ASSIGNED) (eval)
+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
-exit status 0
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
diff --git a/unit-tests/opt-debug-var.mk b/unit-tests/opt-debug-var.mk
index 9017f18e81d3..7a3a80f11432 100644
--- a/unit-tests/opt-debug-var.mk
+++ b/unit-tests/opt-debug-var.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-var.mk,v 1.3 2023/11/19 21:47:52 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.
@@ -9,6 +9,7 @@
ASSIGNED= value
# TODO: Explain why the empty assignment "Global: SUBST = " is needed.
+# expect: Global: SUBST = # (empty)
# expect: Global: SUBST = value
SUBST:= value
@@ -26,6 +27,18 @@ SUBST:= value
.if !empty(ASSIGNED)
.endif
-.MAKEFLAGS: -d0
-all: .PHONY
+# An expression for a variable with a single-character ordinary name.
+# 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-loud)
+# expect+1: Variable "<" is undefined
+.if $<
+.endif
+
+
+.MAKEFLAGS: -d0
diff --git a/unit-tests/suff-incomplete.exp b/unit-tests/suff-incomplete.exp
index a0603de34f11..e5e4a770b26d 100644
--- a/unit-tests/suff-incomplete.exp
+++ b/unit-tests/suff-incomplete.exp
@@ -1,17 +1,17 @@
-Parsing line 9: .SUFFIXES:
+Parsing suff-incomplete.mk:9: .SUFFIXES:
ParseDependency(.SUFFIXES:)
Clearing all suffixes
-Parsing line 11: .SUFFIXES: .a .b .c
+Parsing suff-incomplete.mk:11: .SUFFIXES: .a .b .c
ParseDependency(.SUFFIXES: .a .b .c)
Adding suffix ".a"
Adding suffix ".b"
Adding suffix ".c"
-Parsing line 17: .a.b:
+Parsing suff-incomplete.mk:17: .a.b:
ParseDependency(.a.b:)
defining transformation from `.a' to `.b'
inserting ".a" (1) at end of list
inserting ".b" (2) at end of list
-Parsing line 21: .a.c: ${.PREFIX}.dependency
+Parsing suff-incomplete.mk:21: .a.c: ${.PREFIX}.dependency
deleting incomplete transformation from `.a' to `.b'
ParseDependency(.a.c: ${.PREFIX}.dependency)
defining transformation from `.a' to `.c'
@@ -20,10 +20,10 @@ inserting ".c" (3) at end of list
Target ".a.c" depends on "${.PREFIX}.dependency"
# .a.c, unmade, type OP_DEPENDS|OP_TRANSFORM, flags none
# ${.PREFIX}.dependency, unmade, type none, flags none
-Parsing line 23: .DEFAULT:
+Parsing suff-incomplete.mk:23: .DEFAULT:
transformation .a.c complete
ParseDependency(.DEFAULT:)
-Parsing line 24: : Making ${.TARGET} from ${.IMPSRC} all ${.ALLSRC} by default.
+Parsing suff-incomplete.mk:24: : Making ${.TARGET} from ${.IMPSRC} all ${.ALLSRC} by default.
transformation .DEFAULT complete
Wildcard expanding "all"...
SuffFindDeps "all"
diff --git a/unit-tests/suff-main-several.exp b/unit-tests/suff-main-several.exp
index 99585102029e..c06fb0cf88b9 100644
--- a/unit-tests/suff-main-several.exp
+++ b/unit-tests/suff-main-several.exp
@@ -1,11 +1,11 @@
-Parsing line 8: .1.2 .1.3 .1.4:
+Parsing suff-main-several.mk:8: .1.2 .1.3 .1.4:
ParseDependency(.1.2 .1.3 .1.4:)
Setting main node to ".1.2"
-Parsing line 9: : Making ${.TARGET} from ${.IMPSRC}.
-Parsing line 14: next-main:
+Parsing suff-main-several.mk:9: : Making ${.TARGET} from ${.IMPSRC}.
+Parsing suff-main-several.mk:14: next-main:
ParseDependency(next-main:)
-Parsing line 15: : Making ${.TARGET}
-Parsing line 19: .SUFFIXES: .1 .2 .3 .4
+Parsing suff-main-several.mk:15: : Making ${.TARGET}
+Parsing suff-main-several.mk:19: .SUFFIXES: .1 .2 .3 .4
ParseDependency(.SUFFIXES: .1 .2 .3 .4)
Adding suffix ".1"
Adding suffix ".2"
@@ -26,42 +26,42 @@ defining transformation from `.1' to `.4'
inserting ".1" (1) at end of list
inserting ".4" (4) at end of list
Setting main node to "next-main"
-Parsing line 24: .SUFFIXES:
+Parsing suff-main-several.mk:24: .SUFFIXES:
ParseDependency(.SUFFIXES:)
Clearing all suffixes
-Parsing line 32: .SUFFIXES: .4 .3 .2 .1
+Parsing suff-main-several.mk:32: .SUFFIXES: .4 .3 .2 .1
ParseDependency(.SUFFIXES: .4 .3 .2 .1)
Adding suffix ".4"
Adding suffix ".3"
Adding suffix ".2"
Adding suffix ".1"
-Parsing line 33: .SUFFIXES:
+Parsing suff-main-several.mk:33: .SUFFIXES:
ParseDependency(.SUFFIXES:)
Clearing all suffixes
-Parsing line 34: .SUFFIXES: .1 .2 .3 .4
+Parsing suff-main-several.mk:34: .SUFFIXES: .1 .2 .3 .4
ParseDependency(.SUFFIXES: .1 .2 .3 .4)
Adding suffix ".1"
Adding suffix ".2"
Adding suffix ".3"
Adding suffix ".4"
-Parsing line 35: .SUFFIXES:
+Parsing suff-main-several.mk:35: .SUFFIXES:
ParseDependency(.SUFFIXES:)
Clearing all suffixes
-Parsing line 36: .SUFFIXES: .4 .3 .2 .1
+Parsing suff-main-several.mk:36: .SUFFIXES: .4 .3 .2 .1
ParseDependency(.SUFFIXES: .4 .3 .2 .1)
Adding suffix ".4"
Adding suffix ".3"
Adding suffix ".2"
Adding suffix ".1"
-Parsing line 38: suff-main-several.1:
+Parsing suff-main-several.mk:38: suff-main-several.1:
ParseDependency(suff-main-several.1:)
-Parsing line 39: : Making ${.TARGET} out of nothing.
-Parsing line 40: next-main: suff-main-several.{2,3,4}
+Parsing suff-main-several.mk:39: : Making ${.TARGET} out of nothing.
+Parsing suff-main-several.mk:40: next-main: suff-main-several.{2,3,4}
ParseDependency(next-main: suff-main-several.{2,3,4})
Target "next-main" depends on "suff-main-several.{2,3,4}"
# next-main, unmade, type OP_DEPENDS|OP_HAS_COMMANDS, flags none
# suff-main-several.{2,3,4}, unmade, type none, flags none
-Parsing line 42: .MAKEFLAGS: -d0 -dg1
+Parsing suff-main-several.mk:42: .MAKEFLAGS: -d0 -dg1
ParseDependency(.MAKEFLAGS: -d0 -dg1)
#*** Input graph:
# .1.2, unmade, type OP_TRANSFORM, flags none
diff --git a/unit-tests/suff-rebuild.exp b/unit-tests/suff-rebuild.exp
index 8c0979537524..e44fa0fe9893 100644
--- a/unit-tests/suff-rebuild.exp
+++ b/unit-tests/suff-rebuild.exp
@@ -1,36 +1,36 @@
-Parsing line 10: .SUFFIXES:
+Parsing suff-rebuild.mk:10: .SUFFIXES:
ParseDependency(.SUFFIXES:)
Clearing all suffixes
-Parsing line 12: .SUFFIXES: .a .b .c
+Parsing suff-rebuild.mk:12: .SUFFIXES: .a .b .c
ParseDependency(.SUFFIXES: .a .b .c)
Adding suffix ".a"
Adding suffix ".b"
Adding suffix ".c"
-Parsing line 14: suff-rebuild-example.a:
+Parsing suff-rebuild.mk:14: suff-rebuild-example.a:
ParseDependency(suff-rebuild-example.a:)
Adding "suff-rebuild-example.a" to all targets.
-Parsing line 15: : Making ${.TARGET} out of nothing.
-Parsing line 17: .a.b:
+Parsing suff-rebuild.mk:15: : Making ${.TARGET} out of nothing.
+Parsing suff-rebuild.mk:17: .a.b:
ParseDependency(.a.b:)
defining transformation from `.a' to `.b'
inserting ".a" (1) at end of list
inserting ".b" (2) at end of list
-Parsing line 18: : Making ${.TARGET} from ${.IMPSRC}.
-Parsing line 19: .b.c:
+Parsing suff-rebuild.mk:18: : Making ${.TARGET} from ${.IMPSRC}.
+Parsing suff-rebuild.mk:19: .b.c:
transformation .a.b complete
ParseDependency(.b.c:)
defining transformation from `.b' to `.c'
inserting ".b" (2) at end of list
inserting ".c" (3) at end of list
-Parsing line 20: : Making ${.TARGET} from ${.IMPSRC}.
-Parsing line 21: .c:
+Parsing suff-rebuild.mk:20: : Making ${.TARGET} from ${.IMPSRC}.
+Parsing suff-rebuild.mk:21: .c:
transformation .b.c complete
ParseDependency(.c:)
defining transformation from `.c' to `'
inserting ".c" (3) at end of list
inserting "" (0) at end of list
-Parsing line 22: : Making ${.TARGET} from ${.IMPSRC}.
-Parsing line 44: .SUFFIXES: .c .b .a
+Parsing suff-rebuild.mk:22: : Making ${.TARGET} from ${.IMPSRC}.
+Parsing suff-rebuild.mk:44: .SUFFIXES: .c .b .a
transformation .c complete
ParseDependency(.SUFFIXES: .c .b .a)
Adding ".END" to all targets.
diff --git a/unit-tests/suff.exp b/unit-tests/suff.exp
new file mode 100644
index 000000000000..adf646850d6e
--- /dev/null
+++ b/unit-tests/suff.exp
@@ -0,0 +1,146 @@
+Adding suffix ".from"
+Adding suffix ".to"
+defining transformation from `.from' to `.to'
+inserting ".from" (1) at end of list
+inserting ".to" (2) at end of list
+transformation .from.to complete
+Var_Parse: ${.PREFIX}${.ARCHIVE}.additional (eval)
+Var_Parse: ${.ARCHIVE}.additional (eval)
+Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional
+Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional edge-case.from
+Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional edge-case.from edge-case.additional
+Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional edge-case.from edge-case.additional a*.mk
+Global: delete .PARSEDIR
+Global: delete .PARSEFILE
+Global: ignoring delete '.INCLUDEDFROMDIR' as it is not found
+Global: ignoring delete '.INCLUDEDFROMFILE' as it is not found
+Var_Parse: ${.MAKE.DEPENDFILE} (eval)
+Var_Parse: ${.MAKE.MODE:tl} (eval)
+Evaluating modifier ${.MAKE.MODE:t...} on value "" (eval, undefined)
+Result of ${.MAKE.MODE:tl} is "" (eval, undefined)
+Global: MFLAGS = -r -k -d sv
+Var_Parse: ${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@} (eval)
+Var_Parse: ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@} (eval)
+Evaluating modifier ${.MAKEOVERRIDES:O} on value ""
+Result of ${.MAKEOVERRIDES:O} is ""
+Evaluating modifier ${.MAKEOVERRIDES:u} on value ""
+Result of ${.MAKEOVERRIDES:u} is ""
+Evaluating modifier ${.MAKEOVERRIDES:@...} on value ""
+Modifier part: "v"
+Modifier part: "$v=${$v:Q}"
+ModifyWords: split "" into 1 word
+Command: ignoring delete 'v' as it is not found
+Result of ${.MAKEOVERRIDES:@v@$v=${$v:Q}@} is ""
+Global: .INCLUDES = # (empty)
+Global: .LIBS = # (empty)
+Global: ignoring delete '.SHELL' as it is not found
+Command: .SHELL = /bin/sh
+Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional edge-case.from edge-case.additional a*.mk .END
+step1: @ = step1
+step1: @ = step1
+step1: * = step1
+SuffFindDeps "step1"
+step1: @ = step1
+step1: * = step1
+ No valid suffix on step1
+Wildcard expanding "edge-case.to"...suffix is ".to"...
+edge-case.to: @ = edge-case.to
+edge-case.to: @ = edge-case.to
+edge-case.to: * = edge-case.to
+SuffFindDeps "edge-case.to"
+ trying edge-case.from...got it
+edge-case.to: @ = edge-case.to
+edge-case.to: * = edge-case
+Expanding "${.PREFIX}${.ARCHIVE}.additional"...Var_Parse: ${.PREFIX}${.ARCHIVE}.additional (eval)
+Var_Parse: ${.ARCHIVE}.additional (eval)
+edge-case.additional...
+ applying .from -> .to to "edge-case.to"
+everything: @ = everything
+everything: @ = everything
+everything: * = everything
+SuffFindDeps "everything"
+everything: @ = everything
+everything: * = everything
+Wildcard expanding "a*.mk"...
+archive-suffix.mk...Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional edge-case.from edge-case.additional a*.mk .END archive-suffix.mk
+archive.mk...Global: .ALLTARGETS = step1 edge-case.to everything ${.PREFIX}${.ARCHIVE}.additional edge-case.from edge-case.additional a*.mk .END archive-suffix.mk archive.mk
+
+ No valid suffix on everything
+Wildcard expanding "edge-case.additional"...
+edge-case.additional: @ = edge-case.additional
+edge-case.additional: @ = edge-case.additional
+edge-case.additional: * = edge-case.additional
+SuffFindDeps "edge-case.additional"
+ No known suffix on edge-case.additional. Using .NULL suffix
+not adding suffix rules
+edge-case.additional: @ = edge-case.additional
+edge-case.additional: * = edge-case.additional
+suffix is ".from"...
+edge-case.from: @ = edge-case.from
+edge-case.from: @ = edge-case.from
+edge-case.from: * = edge-case.from
+SuffFindDeps "edge-case.from"
+edge-case.from: @ = edge-case.from
+edge-case.from: * = edge-case
+Wildcard expanding "archive-suffix.mk"...
+archive-suffix.mk: @ = archive-suffix.mk
+archive-suffix.mk: @ = archive-suffix.mk
+archive-suffix.mk: * = archive-suffix.mk
+SuffFindDeps "archive-suffix.mk"
+ No known suffix on archive-suffix.mk. Using .NULL suffix
+adding suffix rules
+archive-suffix.mk: @ = archive-suffix.mk
+archive-suffix.mk: * = archive-suffix.mk
+archive-suffix.mk: @ = archive-suffix.mk
+archive-suffix.mk: * = archive-suffix.mk
+Wildcard expanding "archive.mk"...
+archive.mk: @ = archive.mk
+archive.mk: @ = archive.mk
+archive.mk: * = archive.mk
+SuffFindDeps "archive.mk"
+ No known suffix on archive.mk. Using .NULL suffix
+adding suffix rules
+archive.mk: @ = archive.mk
+archive.mk: * = archive.mk
+archive.mk: @ = archive.mk
+archive.mk: * = archive.mk
+Wildcard expanding "edge-case.additional"...
+edge-case.additional: ? = # (empty)
+edge-case.additional: > = # (empty)
+Var_Parse: ${.TARGET} out of nothing. (eval)
+: Making edge-case.additional out of nothing.
+edge-case.to: < = edge-case.from
+suffix is ".from"...
+edge-case.from: ? = # (empty)
+edge-case.from: > = # (empty)
+Var_Parse: ${.TARGET} out of nothing. (eval)
+: Making edge-case.from out of nothing.
+edge-case.to: > = edge-case.additional
+edge-case.to: ? = edge-case.additional
+edge-case.to: > = edge-case.additional edge-case.from
+edge-case.to: ? = edge-case.additional edge-case.from
+Var_Parse: ${.TARGET} from ${.ALLSRC}. (eval)
+Var_Parse: ${.ALLSRC}. (eval)
+: Making edge-case.to from edge-case.additional edge-case.from.
+everything: > = archive-suffix.mk
+everything: ? = archive-suffix.mk
+everything: > = archive-suffix.mk archive.mk
+everything: ? = archive-suffix.mk archive.mk
+Var_Parse: ${.TARGET} from ${.ALLSRC}. (eval)
+Var_Parse: ${.ALLSRC}. (eval)
+: Making everything from archive-suffix.mk archive.mk.
+step1: > = edge-case.to
+step1: ? = edge-case.to
+step1: > = edge-case.to everything
+step1: ? = edge-case.to everything
+.END: @ = .END
+.END: * = .END
+SuffFindDeps ".END"
+ No known suffix on .END. Using .NULL suffix
+adding suffix rules
+.END: @ = .END
+.END: * = .END
+Wildcard expanding ".END"...
+.END: ? = # (empty)
+.END: > = # (empty)
+exit status 0
diff --git a/unit-tests/suff.mk b/unit-tests/suff.mk
new file mode 100644
index 000000000000..53f6eb82b224
--- /dev/null
+++ b/unit-tests/suff.mk
@@ -0,0 +1,41 @@
+# $NetBSD: suff.mk,v 1.3 2025/01/14 21:39:25 rillig Exp $
+#
+# Demonstrate suffix rules and dependency resolution.
+
+
+# Circumvent the file system cache.
+.if !make(init) && !make(step*)
+all:
+ @${MAKE} -f ${MAKEFILE} init
+ @${MAKE} -f ${MAKEFILE} step1
+.endif
+
+
+.if make(init)
+init:
+. if ${.PARSEDIR:tA} != ${.CURDIR:tA}
+${:U}!= cd ${MAKEFILE:H} && cp a*.mk ${.CURDIR}
+. endif
+.endif
+
+
+.if make(step1)
+step1: .PHONY edge-case.to everything
+
+.MAKEFLAGS: -dsv
+
+.SUFFIXES: .from .to
+
+.from.to:
+ : Making ${.TARGET} from ${.ALLSRC}.
+
+# When making this target, ${.ARCHIVE} is undefined, but there's no warning.
+# expect: Var_Parse: ${.ARCHIVE}.additional (eval)
+edge-case.to: ${.PREFIX}${.ARCHIVE}.additional
+
+edge-case.from edge-case.additional:
+ : Making ${.TARGET} out of nothing.
+
+everything: .PHONY a*.mk
+ : Making ${.TARGET} from ${.ALLSRC}.
+.endif
diff --git a/unit-tests/var-eval-short.exp b/unit-tests/var-eval-short.exp
index 12e2b78d7a3d..2b2e95750a1c 100644
--- a/unit-tests/var-eval-short.exp
+++ b/unit-tests/var-eval-short.exp
@@ -1,6 +1,6 @@
-make: "var-eval-short.mk" line 46: while parsing "${:Uword:@${FAIL}@expr@}": In the :@ modifier, the variable name "${FAIL}" must not contain a dollar
-make: "var-eval-short.mk" line 46: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
-Parsing line 159: .if 0 && ${0:?${FAIL}then:${FAIL}else}
+make: "var-eval-short.mk" line 45: In the :@ modifier, the variable name "${FAIL}" must not contain a dollar
+ while parsing "${:Uword:@${FAIL}@expr@}"
+Parsing var-eval-short.mk:158: .if 0 && ${0:?${FAIL}then:${FAIL}else}
CondParser_Eval: 0 && ${0:?${FAIL}then:${FAIL}else}
Var_Parse: ${0:?${FAIL}then:${FAIL}else} (parse)
Parsing modifier ${0:?...}
@@ -9,9 +9,9 @@ Modifier part: "${FAIL}then"
Var_Parse: ${FAIL}else} (parse)
Modifier part: "${FAIL}else"
Result of ${0:?${FAIL}then:${FAIL}else} is "" (parse, defined)
-Parsing line 167: DEFINED= defined
+Parsing var-eval-short.mk:166: DEFINED= defined
Global: DEFINED = defined
-Parsing line 168: .if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
+Parsing var-eval-short.mk:167: .if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
CondParser_Eval: 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
Var_Parse: ${DEFINED:L:?${FAIL}then:${FAIL}else} (parse)
Parsing modifier ${DEFINED:L}
@@ -22,7 +22,7 @@ Modifier part: "${FAIL}then"
Var_Parse: ${FAIL}else} (parse)
Modifier part: "${FAIL}else"
Result of ${DEFINED:?${FAIL}then:${FAIL}else} is "defined" (parse, regular)
-Parsing line 170: .MAKEFLAGS: -d0
+Parsing var-eval-short.mk:169: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
Global: .MAKEFLAGS = -r -k -d cpv -d
Global: .MAKEFLAGS = -r -k -d cpv -d 0
diff --git a/unit-tests/var-eval-short.mk b/unit-tests/var-eval-short.mk
index d6872d158e32..d6dc36254851 100644
--- a/unit-tests/var-eval-short.mk
+++ b/unit-tests/var-eval-short.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-eval-short.mk,v 1.14 2024/07/05 20:01:52 rillig Exp $
+# $NetBSD: var-eval-short.mk,v 1.17 2025/01/11 20:54:45 rillig Exp $
#
# Tests for each variable modifier to ensure that they only do the minimum
# necessary computations. If the result of the expression is irrelevant,
@@ -41,8 +41,7 @@ FAIL= ${:!echo unexpected 1>&2!}
# after the loop, when undefining the temporary global loop variable.
# Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the
# variable name.
-# expect+2: while parsing "${:Uword:@${FAIL}@expr@}": In the :@ modifier, the variable name "${FAIL}" must not contain a dollar
-# expect+1: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
+# expect+1: In the :@ modifier, the variable name "${FAIL}" must not contain a dollar
.if 0 && ${:Uword:@${FAIL}@expr@}
.endif
diff --git a/unit-tests/var-op-expand.exp b/unit-tests/var-op-expand.exp
index 63d74f313737..655a46023a11 100644
--- a/unit-tests/var-op-expand.exp
+++ b/unit-tests/var-op-expand.exp
@@ -1,6 +1,10 @@
-make: "var-op-expand.mk" line 274: while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}": while evaluating variable "later" with value "": Unknown modifier "s,value,replaced,"
+make: "var-op-expand.mk" line 274: Unknown modifier "s,value,replaced,"
+ while evaluating variable "later" with value ""
+ while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}"
make: "var-op-expand.mk" line 278: warning: XXX Neither branch should be taken.
-make: "var-op-expand.mk" line 283: while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}": while evaluating variable "later" with value "lowercase-value": Unknown modifier "s,value,replaced,"
+make: "var-op-expand.mk" line 283: Unknown modifier "s,value,replaced,"
+ while evaluating variable "later" with value "lowercase-value"
+ while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}"
make: "var-op-expand.mk" line 285: warning: XXX Neither branch should be taken.
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
diff --git a/unit-tests/var-op-expand.mk b/unit-tests/var-op-expand.mk
index a2ae8b0e22d1..a8e64bf45424 100644
--- a/unit-tests/var-op-expand.mk
+++ b/unit-tests/var-op-expand.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-expand.mk,v 1.21 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: var-op-expand.mk,v 1.22 2024/08/29 20:20:36 rillig Exp $
#
# Tests for the := variable assignment operator, which expands its
# right-hand side.
@@ -270,7 +270,7 @@ later= lowercase-value
.undef later
INDIRECT:= ${LATER:S,value,replaced,} OK ${LATER:value=sysv}
indirect:= ${INDIRECT:tl}
-# expect+1: while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}": while evaluating variable "later" with value "": Unknown modifier "s,value,replaced,"
+# expect+1: Unknown modifier "s,value,replaced,"
.if ${indirect} != " ok "
. error
.else
@@ -279,7 +279,7 @@ indirect:= ${INDIRECT:tl}
.endif
LATER= uppercase-value
later= lowercase-value
-# expect+1: while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}": while evaluating variable "later" with value "lowercase-value": Unknown modifier "s,value,replaced,"
+# expect+1: Unknown modifier "s,value,replaced,"
.if ${indirect} != "uppercase-replaced ok uppercase-sysv"
# expect+1: warning: XXX Neither branch should be taken.
. warning XXX Neither branch should be taken.
diff --git a/unit-tests/var-op-shell.exp b/unit-tests/var-op-shell.exp
index 952af6df5518..9117001d40a7 100644
--- a/unit-tests/var-op-shell.exp
+++ b/unit-tests/var-op-shell.exp
@@ -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)
+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
diff --git a/unit-tests/var-op-shell.mk b/unit-tests/var-op-shell.mk
index bfc2e4f1361d..f9c7c717b8f1 100644
--- a/unit-tests/var-op-shell.mk
+++ b/unit-tests/var-op-shell.mk
@@ -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=1000}
.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:
diff --git a/unit-tests/var-recursive.exp b/unit-tests/var-recursive.exp
index c92c22b125dc..59812e0e71ff 100644
--- a/unit-tests/var-recursive.exp
+++ b/unit-tests/var-recursive.exp
@@ -1,22 +1,27 @@
-make: "var-recursive.mk" line 21: still there
-make: Variable DIRECT is recursive.
- in var-recursive.mk:22
+make: "var-recursive.mk" line 11: Variable DIRECT is recursive.
+ while evaluating variable "DIRECT" with value "${DIRECT}"
in directory <curdir>
-
-make: stopped in unit-tests
-make: Variable INDIRECT1 is recursive.
- in var-recursive.mk:29
+make: "var-recursive.mk" line 11: <>
+make: "var-recursive.mk" line 19: Variable INDIRECT1 is recursive.
+ while evaluating variable "INDIRECT2" with value "${INDIRECT1}"
+ while evaluating variable "INDIRECT1" with value "${INDIRECT2}"
in directory <curdir>
-
-make: stopped in unit-tests
-make: "var-recursive.mk" line 37: ok
-make: Variable V is recursive.
- in var-recursive.mk:45
+make: "var-recursive.mk" line 19: <>
+make: "var-recursive.mk" line 26: <ok>
+make: "var-recursive.mk" line 34: Variable MODIFIERS is recursive.
+ while evaluating variable "MODIFIERS" with value "${MODIFIERS:Mpattern}"
in directory <curdir>
-
-make: stopped in unit-tests
-: OK
-In a command near "var-recursive.mk" line 57: make[1]: Variable VAR is recursive.
-
-make: stopped making "target" in unit-tests
+make: "var-recursive.mk" line 34: <Mpattern}>
+make: "var-recursive.mk" line 43: Variable V is recursive.
+ while evaluating variable "V" with value "$V"
+ in directory <curdir>
+make: "var-recursive.mk" line 43: <>
+make: Fatal errors encountered -- cannot continue
+make: stopped making "loadtime" in unit-tests
+sub-exit status 1
+: before-recursive
+make: Variable VAR is recursive.
+ while evaluating variable "VAR" with value "${VAR}"
+ in target "runtime"
+sub-exit status 2
exit status 0
diff --git a/unit-tests/var-recursive.mk b/unit-tests/var-recursive.mk
index 72231656673c..e2951c900b11 100644
--- a/unit-tests/var-recursive.mk
+++ b/unit-tests/var-recursive.mk
@@ -1,63 +1,64 @@
-# $NetBSD: var-recursive.mk,v 1.6 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: var-recursive.mk,v 1.10 2024/08/29 20:20:36 rillig Exp $
#
-# Tests for expressions that refer to themselves and thus
-# cannot be evaluated.
+# Tests for expressions that refer to themselves and thus cannot be
+# evaluated, as that would lead to an endless loop.
-TESTS= direct indirect conditional short target
+.if make(loadtime)
-# Since make exits immediately when it detects a recursive expression,
-# the actual tests are run in sub-makes.
-TEST?= # none
-.if ${TEST} == ""
-all:
-.for test in ${TESTS}
- @${.MAKE} -f ${MAKEFILE} TEST=${test} || :
-.endfor
-
-.elif ${TEST} == direct
+DIRECT= ${DIRECT} # Defining a recursive variable is not an error.
+# expect+2: Variable DIRECT is recursive.
+# expect+1: <>
+. info <${DIRECT}> # But expanding such a variable is an error.
-DIRECT= ${DIRECT} # Defining a recursive variable is not yet an error.
-# expect+1: still there
-. info still there # Therefore this line is printed.
-. info ${DIRECT} # But expanding the variable is an error.
-
-.elif ${TEST} == indirect
# The chain of variables that refer to each other may be long.
INDIRECT1= ${INDIRECT2}
INDIRECT2= ${INDIRECT1}
-. info ${INDIRECT1}
+# expect+2: Variable INDIRECT1 is recursive.
+# expect+1: <>
+. info <${INDIRECT1}>
-.elif ${TEST} == conditional
# The variable refers to itself, but only in the branch of a condition that
-# is never satisfied and is thus not evaluated.
+# is not satisfied and is thus not evaluated.
CONDITIONAL= ${1:?ok:${CONDITIONAL}}
-# expect+1: ok
-. info ${CONDITIONAL}
+# expect+1: <ok>
+. info <${CONDITIONAL}>
+
+
+# An expression with modifiers is skipped halfway. This can lead to wrong
+# follow-up error messages, but recursive variables occur seldom.
+MODIFIERS= ${MODIFIERS:Mpattern}
+# expect+2: Variable MODIFIERS is recursive.
+# expect+1: <Mpattern}>
+. info <${MODIFIERS}>
-.elif ${TEST} == short
# Short variable names can be expanded using the short-hand $V notation,
# which takes a different code path in Var_Parse for parsing the variable
# name. Ensure that these are checked as well.
V= $V
-. info $V
+# expect+2: Variable V is recursive.
+# expect+1: <>
+. info <$V>
-.elif ${TEST} == target
+.elif make(runtime)
-# If a recursive variable is accessed in a command of a target, the makefiles
-# are not parsed anymore, so there is no location information from the
-# .includes and .for directives. In such a case, use the location of the last
-# command of the target to provide at least a hint to the location.
VAR= ${VAR}
-target:
- : OK
- : ${VAR}
- : OK
+runtime:
+# expect: : before-recursive
+ : before-recursive
+# expect: make: Variable VAR is recursive.
+# expect-not: recursive-line-before
+# expect-not: recursive-line-after
+ : recursive-line-before <${VAR}> recursive-line-after
+# expect-not: after-recursive
+ : after-recursive
.else
-. error Unknown test "${TEST}"
-.endif
all:
+ @${MAKE} -f ${MAKEFILE} loadtime || echo "sub-exit status $$?"
+ @${MAKE} -f ${MAKEFILE} runtime || echo "sub-exit status $$?"
+
+.endif
diff --git a/unit-tests/vardebug.exp b/unit-tests/vardebug.exp
index 9937185ae807..5e220f24df74 100644
--- a/unit-tests/vardebug.exp
+++ b/unit-tests/vardebug.exp
@@ -11,57 +11,66 @@ Global: ignoring 'FROM_CMDLINE = overwritten' due to a command line variable of
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)
-make: "vardebug.mk" line 63: while evaluating "${:Uvariable:unknown}" with value "variable": Unknown modifier "unknown"
-Result of ${:unknown} is error (eval-defined, defined)
-make: "vardebug.mk" line 63: Malformed conditional (${:Uvariable:unknown})
-Var_Parse: ${UNDEFINED} (eval-defined)
-make: "vardebug.mk" line 73: Malformed conditional (${UNDEFINED})
+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)
+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
diff --git a/unit-tests/vardebug.mk b/unit-tests/vardebug.mk
index 7e6154d7e52c..975f32b62286 100644
--- a/unit-tests/vardebug.mk
+++ b/unit-tests/vardebug.mk
@@ -1,4 +1,4 @@
-# $NetBSD: vardebug.mk,v 1.11 2024/07/05 19:47:22 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,19 +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+2: Malformed conditional (${:Uvariable:unknown})
-# expect+1: while evaluating "${:Uvariable:unknown}" with value "variable": Unknown modifier "unknown"
+# 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
@@ -79,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
diff --git a/unit-tests/varmisc.exp b/unit-tests/varmisc.exp
index 5e63f9f6563a..79d2c19e4d1b 100644
--- a/unit-tests/varmisc.exp
+++ b/unit-tests/varmisc.exp
@@ -43,29 +43,30 @@ export-appended: env mk
parse-dynamic: parse-dynamic parse-dynamic before
parse-dynamic: parse-dynamic parse-dynamic after
parse-dynamic: parse-dynamic parse-dynamic after
-varerror-unclosed:begin
-make: in target "varerror-unclosed": Unclosed variable ""
+varerror-unclosed-1:begin
+make: Unclosed variable ""
+ in target "varerror-unclosed-2"
+make: Unclosed variable "UNCLOSED"
+ in target "varerror-unclosed-3"
+make: Unclosed variable "UNCLOSED"
+ in target "varerror-unclosed-4"
+make: Unclosed variable "PATTERN"
+ while evaluating variable "UNCLOSED" with value ""
+ in target "varerror-unclosed-5"
+make: Unclosed expression, expecting '}' for modifier "M${PATTERN"
+ while evaluating variable "UNCLOSED" with value ""
+ in target "varerror-unclosed-5"
+make: Unclosed variable "param"
+ in target "varerror-unclosed-6"
+make: Unclosed variable "UNCLOSED."
+ in target "varerror-unclosed-6"
-make: in target "varerror-unclosed": Unclosed variable "UNCLOSED"
-
-make: in target "varerror-unclosed": Unclosed variable "UNCLOSED"
-
-make: in target "varerror-unclosed": while evaluating variable "UNCLOSED" with value "": Unclosed variable "PATTERN"
-make: in target "varerror-unclosed": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}' for modifier "M${PATTERN"
-
-make: in target "varerror-unclosed": Unclosed variable "param"
-make: in target "varerror-unclosed": Unclosed variable "UNCLOSED."
-
-
-make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.1"
-
-make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.2"
-
-make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.3"
-
-make: in target "varerror-unclosed": while evaluating variable "UNCLOSED_INDIR_2" with value "${UNCLOSED_INDIR_1}": while evaluating variable "UNCLOSED_INDIR_1" with value "${UNCLOSED_ORIG": Unclosed variable "UNCLOSED_ORIG"
-
-varerror-unclosed:end
+make: Unclosed variable "UNCLOSED.1"
+ in target "varerror-unclosed-7"
+make: Unclosed variable "UNCLOSED_ORIG"
+ while evaluating variable "UNCLOSED_INDIR_1" with value "${UNCLOSED_ORIG"
+ while evaluating variable "UNCLOSED_INDIR_2" with value "${UNCLOSED_INDIR_1}"
+ in target "varerror-unclosed-8"
target1-flags: we have: one two
target2-flags: we have: one two three four
exit status 2
diff --git a/unit-tests/varmisc.mk b/unit-tests/varmisc.mk
index 94ac32812d87..b067742e9ac4 100644
--- a/unit-tests/varmisc.mk
+++ b/unit-tests/varmisc.mk
@@ -1,5 +1,4 @@
-# $Id: varmisc.mk,v 1.27 2024/07/06 18:23:18 sjg Exp $
-# $NetBSD: varmisc.mk,v 1.35 2024/07/05 18:59:33 rillig Exp $
+# $NetBSD: varmisc.mk,v 1.37 2024/08/29 20:20:36 rillig Exp $
#
# Miscellaneous variable tests.
@@ -8,7 +7,7 @@ all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \
all: save-dollars
all: export-appended
all: parse-dynamic
-all: varerror-unclosed
+all: varerror-unclosed-{1,2,3,4,5,6,7,8}
unmatched_var_paren:
@echo ${foo::=foo-text}
@@ -189,25 +188,30 @@ target1-flags: target1.c
target2-flags: target2.c
@echo $@: we have: ${FLAGS}
-varerror-unclosed:
+varerror-unclosed-1:
@echo $@:begin
-# expect: make: in target "varerror-unclosed": Unclosed variable ""
+varerror-unclosed-2:
+# expect: make: Unclosed variable ""
@echo $(
-# expect: make: in target "varerror-unclosed": Unclosed variable "UNCLOSED"
+varerror-unclosed-3:
+# expect: make: Unclosed variable "UNCLOSED"
@echo $(UNCLOSED
-# expect: make: in target "varerror-unclosed": Unclosed variable "UNCLOSED"
+varerror-unclosed-4:
+# expect: make: Unclosed variable "UNCLOSED"
@echo ${UNCLOSED
-# expect: make: in target "varerror-unclosed": while evaluating variable "UNCLOSED" with value "": Unclosed expression, expecting '}' for modifier "M${PATTERN"
+varerror-unclosed-5:
+# expect: make: Unclosed expression, expecting '}' for modifier "M${PATTERN"
@echo ${UNCLOSED:M${PATTERN
-# expect: make: in target "varerror-unclosed": Unclosed variable "param"
-# expect: make: in target "varerror-unclosed": Unclosed variable "UNCLOSED."
+varerror-unclosed-6:
+# expect: make: Unclosed variable "param"
+# expect: make: Unclosed variable "UNCLOSED."
@echo ${UNCLOSED.${param
+varerror-unclosed-7:
@echo $
.for i in 1 2 3
-# expect: make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.1"
-# expect: make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.2"
-# expect: make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.3"
+# expect: make: Unclosed variable "UNCLOSED.1"
@echo ${UNCLOSED.${i}
.endfor
+varerror-unclosed-8:
@echo ${UNCLOSED_INDIR_2}
@echo $@:end
diff --git a/unit-tests/varmod-assign-shell.exp b/unit-tests/varmod-assign-shell.exp
index 819fa6a5f304..712636491fc1 100644
--- a/unit-tests/varmod-assign-shell.exp
+++ b/unit-tests/varmod-assign-shell.exp
@@ -4,7 +4,7 @@ Var_Parse: ${ASSIGNED::!=echo output; ${:U(exit 13)}} (eval-keep-dollar-and-unde
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 26: warning: while evaluating variable "ASSIGNED" with value "previous": 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
diff --git a/unit-tests/varmod-assign-shell.mk b/unit-tests/varmod-assign-shell.mk
index 0b3e553055b3..7bbea0ff9463 100644
--- a/unit-tests/varmod-assign-shell.mk
+++ b/unit-tests/varmod-assign-shell.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-assign-shell.mk,v 1.8 2024/07/04 17:47:54 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
@@ -22,7 +22,7 @@ DIRECT!= echo output; (exit 13)
ASSIGNED= previous
.MAKEFLAGS: -dv # to see the "Capturing" debug output
-# expect+1: warning: while evaluating variable "ASSIGNED" with value "previous": Command "echo output; (exit 13)" exited with status 13
+# expect+1: warning: Command "echo output; (exit 13)" exited with status 13
_:= ${ASSIGNED::!=echo output; ${:U(exit 13)}}
.MAKEFLAGS: -d0
diff --git a/unit-tests/varmod-assign.exp b/unit-tests/varmod-assign.exp
index 6c8bfb5cd6e8..4a7dc509642a 100644
--- a/unit-tests/varmod-assign.exp
+++ b/unit-tests/varmod-assign.exp
@@ -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
@@ -37,18 +37,22 @@ Global: .MAKEOVERRIDES = FIRST LAST LAST LAST APPENDED RAN RAN RAN IT1 THEN1 IE
Result of ${CMD_NEW_VAR::=new-value} is "" (eval, undefined)
Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0
-make: in target "mod-assign-empty": while evaluating "${::=value}" with value "": Bad modifier ":"
-mod-assign-empty: value}
-make: in target "mod-assign-empty": while evaluating "${:Uvalue::=overwritten}" with value "value": Bad modifier ":"
-mod-assign-empty: overwritten}
-mod-assign-empty: VAR=overwritten
-make: in target "mod-assign-parse": while evaluating variable "ASSIGN" with value "": Unknown modifier ":x"
-
+make: Bad modifier ":"
+ while evaluating "${::=value}" with value ""
+ in target "mod-assign-empty-1"
+make: Bad modifier ":"
+ while evaluating "${:Uvalue::=overwritten}" with value "value"
+ in target "mod-assign-empty-2"
+mod-assign-empty-3: VAR=overwritten
+make: Unknown modifier ":x"
+ while evaluating variable "ASSIGN" with value ""
+ in target "mod-assign-parse-1"
sysv:y
-make: in target "mod-assign-parse": while evaluating variable "ASSIGN" with value "": Unfinished modifier ('}' missing)
-
+make: Unfinished modifier ('}' missing)
+ while evaluating variable "ASSIGN" with value ""
+ in target "mod-assign-parse-3"
ok=word
-make: warning: in target "mod-assign-shell-error": while evaluating variable "SH_ERR" with value "previous": Command " echo word; (exit 13) " exited with status 13
+make: warning: Command " echo word; (exit 13) " exited with status 13
err=previous
Command: TARGET_CMD_VAR = cmd-value
Global: TARGET_GLOBAL_VAR = global-value
diff --git a/unit-tests/varmod-assign.mk b/unit-tests/varmod-assign.mk
index ee1c86c039f5..237198faf254 100644
--- a/unit-tests/varmod-assign.mk
+++ b/unit-tests/varmod-assign.mk
@@ -1,12 +1,12 @@
-# $NetBSD: varmod-assign.mk,v 1.23 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: varmod-assign.mk,v 1.25 2024/08/29 20:20:36 rillig Exp $
#
# Tests for the obscure ::= variable modifiers, which perform variable
# assignments during evaluation, just like the = operator in C.
.if !make(target)
-all: mod-assign-empty
-all: mod-assign-parse
+all: mod-assign-empty-{1,2,3}
+all: mod-assign-parse-{1,2,3}
all: mod-assign-shell-error
# In the following loop expression,
@@ -71,33 +71,38 @@ SINK4:= ${0:?${THEN4::=then4${IT4::=t4}}:${ELSE4::=else4${IE4::=e4}}} ${THEN4}${
. error
.endif
-mod-assign-empty:
+mod-assign-empty-1:
# Assigning to the empty variable would obviously not work since that
- # variable is write-protected. Therefore it is rejected early with a
- # "Bad modifier" message.
+ # variable is write-protected.
+# expect: make: Bad modifier ":"
@echo $@: ${::=value}
+mod-assign-empty-2:
# In this variant, it is not as obvious that the name of the
- # expression is empty. Assigning to it is rejected as well, with the
- # same "Bad modifier" message.
+ # expression is empty.
+# expect: make: Bad modifier ":"
@echo $@: ${:Uvalue::=overwritten}
+mod-assign-empty-3:
# The :L modifier sets the value of the expression to its variable
# name. The name of the expression is "VAR", therefore assigning to
# that variable works.
+# expect: mod-assign-empty-3: VAR=overwritten
@echo $@: ${VAR:L::=overwritten} VAR=${VAR}
-mod-assign-parse:
+mod-assign-parse-1:
# The modifier for assignment operators starts with a ':'.
# An 'x' after that is an invalid modifier.
- # expect: make: in target "mod-assign-parse": while evaluating variable "ASSIGN" with value "": Unknown modifier ":x"
+# expect: make: Unknown modifier ":x"
@echo ${ASSIGN::x}
+mod-assign-parse-2:
# When parsing an assignment operator fails because the operator is
# incomplete, make falls back to the SysV modifier.
@echo ${SYSV::=sysv\:x}${SYSV::x=:y}
-# expect: make: in target "mod-assign-parse": while evaluating variable "ASSIGN" with value "": Unfinished modifier ('}' missing)
+mod-assign-parse-3:
+# expect: make: Unfinished modifier ('}' missing)
@echo ${ASSIGN::=value # missing closing brace
mod-assign-shell-error:
diff --git a/unit-tests/varmod-edge.exp b/unit-tests/varmod-edge.exp
index ff4f73d30939..2b3b038373b3 100644
--- a/unit-tests/varmod-edge.exp
+++ b/unit-tests/varmod-edge.exp
@@ -1,12 +1,23 @@
-make: "varmod-edge.mk" line 60: while evaluating variable "MOD" with value "${INP:M${:U*)}}": while evaluating variable "INP" with value "(parentheses)": while evaluating "${:U*)" with value "*)": Unclosed expression, expecting '}' for modifier "U*)"
-make: "varmod-edge.mk" line 88: while evaluating variable "MOD" with value "${INP:M${:U[[}}": while evaluating variable "INP" with value "[ [[ [[[": Unfinished character list in pattern '[[' of modifier ':M'
-make: "varmod-edge.mk" line 178: while evaluating variable "MOD" with value "${INP:a\=b}": while evaluating variable "INP" with value "file.c file...": Unfinished modifier ('=' missing)
-make: "varmod-edge.mk" line 194: while evaluating variable "MOD" with value "${INP::::}": while evaluating variable "INP" with value "value": Unknown modifier ":"
-make: "varmod-edge.mk" line 194: while evaluating variable "MOD" with value "${INP::::}": while evaluating variable "INP" with value "": Unknown modifier ":"
-make: "varmod-edge.mk" line 203: while evaluating "${:Z}" with value "": Unknown modifier "Z"
-make: "varmod-edge.mk" line 203: Malformed conditional (${:Z})
-make: "varmod-edge.mk" line 217: while evaluating "${:S,}" with value "": Unfinished modifier (',' missing)
-make: "varmod-edge.mk" line 217: Malformed conditional (${:S,})
+make: "varmod-edge.mk" line 60: Unclosed expression, expecting '}' for modifier "U*)"
+ while evaluating "${:U*)" with value "*)"
+ while evaluating variable "INP" with value "(parentheses)"
+ while evaluating variable "MOD" with value "${INP:M${:U*)}}"
+make: "varmod-edge.mk" line 88: Unfinished character list in pattern '[[' of modifier ':M'
+ while evaluating variable "INP" with value "[ [[ [[["
+ while evaluating variable "MOD" with value "${INP:M${:U[[}}"
+make: "varmod-edge.mk" line 178: Unfinished modifier ('=' missing)
+ while evaluating variable "INP" with value "file.c file..."
+ while evaluating variable "MOD" with value "${INP:a\=b}"
+make: "varmod-edge.mk" line 194: Unknown modifier ":"
+ while evaluating variable "INP" with value "value"
+ while evaluating variable "MOD" with value "${INP::::}"
+make: "varmod-edge.mk" line 194: Unknown modifier ":"
+ while evaluating variable "INP" with value ""
+ while evaluating variable "MOD" with value "${INP::::}"
+make: "varmod-edge.mk" line 200: Unknown modifier "Z"
+ while evaluating "${:Z}" with value ""
+make: "varmod-edge.mk" line 213: Unfinished modifier (',' missing)
+ while evaluating "${:S,}" with value ""
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varmod-edge.mk b/unit-tests/varmod-edge.mk
index 77c080ef3e5f..ee21b44e00f2 100644
--- a/unit-tests/varmod-edge.mk
+++ b/unit-tests/varmod-edge.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-edge.mk,v 1.29 2024/07/09 17:07:23 rillig Exp $
+# $NetBSD: varmod-edge.mk,v 1.33 2025/01/11 20:54:45 rillig Exp $
#
# Tests for edge cases in variable modifiers.
#
@@ -56,7 +56,7 @@ EXP= \(\{}\):
INP= (parentheses)
MOD= ${INP:M${:U*)}}
EXP= (parentheses)}
-# expect+1: while evaluating variable "MOD" with value "${INP:M${:U*)}}": while evaluating variable "INP" with value "(parentheses)": while evaluating "${:U*)" with value "*)": Unclosed expression, expecting '}' for modifier "U*)"
+# expect+1: Unclosed expression, expecting '}' for modifier "U*)"
.if ${MOD} != ${EXP}
. warning expected "${EXP}", got "${MOD}"
.endif
@@ -84,7 +84,7 @@ EXP= [
INP= [ [[ [[[
MOD= ${INP:M${:U[[}}
EXP= [
-# expect+1: while evaluating variable "MOD" with value "${INP:M${:U[[}}": while evaluating variable "INP" with value "[ [[ [[[": Unfinished character list in pattern '[[' of modifier ':M'
+# expect+1: Unfinished character list in pattern '[[' of modifier ':M'
.if ${MOD} != ${EXP}
. warning expected "${EXP}", got "${MOD}"
.endif
@@ -174,7 +174,7 @@ EXP= file.c file.ext
INP= file.c file...
MOD= ${INP:a\=b}
EXP= # empty
-# expect+1: while evaluating variable "MOD" with value "${INP:a\=b}": while evaluating variable "INP" with value "file.c file...": Unfinished modifier ('=' missing)
+# expect+1: Unfinished modifier ('=' missing)
.if ${MOD} != ${EXP}
. warning expected "${EXP}", got "${MOD}"
.endif
@@ -189,17 +189,14 @@ EXP= value
INP= value
MOD= ${INP::::}
EXP= # empty
-# expect+2: while evaluating variable "MOD" with value "${INP::::}": while evaluating variable "INP" with value "value": Unknown modifier ":"
-# expect+1: while evaluating variable "MOD" with value "${INP::::}": while evaluating variable "INP" with value "": Unknown modifier ":"
+# expect+2: Unknown modifier ":"
+# expect+1: Unknown modifier ":"
.if ${MOD} != ${EXP}
. warning expected "${EXP}", got "${MOD}"
.endif
# Even in expressions based on an unnamed variable, there may be errors.
-# XXX: The error message should mention the variable name of the expression,
-# even though that name is empty in this case.
-# expect+2: Malformed conditional (${:Z})
-# expect+1: while evaluating "${:Z}" with value "": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
.if ${:Z}
. error
.else
@@ -212,8 +209,7 @@ EXP= # empty
# variable name with quotes, leading to the rather confusing "Unfinished
# modifier for (',' missing)", having two spaces in a row.
#
-# expect+2: while evaluating "${:S,}" with value "": Unfinished modifier (',' missing)
-# expect+1: Malformed conditional (${:S,})
+# expect+1: Unfinished modifier (',' missing)
.if ${:S,}
. error
.else
diff --git a/unit-tests/varmod-gmtime.exp b/unit-tests/varmod-gmtime.exp
index c41e96723f65..d34cb5c6a93f 100644
--- a/unit-tests/varmod-gmtime.exp
+++ b/unit-tests/varmod-gmtime.exp
@@ -1,13 +1,13 @@
-make: "varmod-gmtime.mk" line 61: while evaluating "${:L:gmtime=-1} != """ with value "": Invalid time value "-1"
-make: "varmod-gmtime.mk" line 61: Malformed conditional (${:L:gmtime=-1} != "")
-make: "varmod-gmtime.mk" line 72: while evaluating "${:L:gmtime= 1} != """ with value "": Invalid time value " 1"
-make: "varmod-gmtime.mk" line 72: Malformed conditional (${:L:gmtime= 1} != "")
-make: "varmod-gmtime.mk" line 120: while evaluating "${:L:gmtime=10000000000000000000000000000000} != """ with value "": Invalid time value "10000000000000000000000000000000"
-make: "varmod-gmtime.mk" line 120: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "")
-make: "varmod-gmtime.mk" line 133: while evaluating "${:L:gmtime=error} != """ with value "": Invalid time value "error"
-make: "varmod-gmtime.mk" line 133: Malformed conditional (${:L:gmtime=error} != "")
-make: "varmod-gmtime.mk" line 144: while evaluating variable "%Y" with value "%Y": Invalid time value "100000S,1970,bad,"
-make: "varmod-gmtime.mk" line 144: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad")
+make: "varmod-gmtime.mk" line 60: Invalid time value "-1"
+ while evaluating "${:L:gmtime=-1} != """ with value ""
+make: "varmod-gmtime.mk" line 70: Invalid time value " 1"
+ while evaluating "${:L:gmtime= 1} != """ with value ""
+make: "varmod-gmtime.mk" line 117: Invalid time value "10000000000000000000000000000000"
+ while evaluating "${:L:gmtime=10000000000000000000000000000000} != """ with value ""
+make: "varmod-gmtime.mk" line 129: Invalid time value "error"
+ while evaluating "${:L:gmtime=error} != """ with value ""
+make: "varmod-gmtime.mk" line 139: Invalid time value "100000S,1970,bad,"
+ while evaluating variable "%Y" with value "%Y"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-gmtime.mk b/unit-tests/varmod-gmtime.mk
index a2b983508be5..610aa2d76fd1 100644
--- a/unit-tests/varmod-gmtime.mk
+++ b/unit-tests/varmod-gmtime.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-gmtime.mk,v 1.24 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-gmtime.mk,v 1.27 2025/01/11 20:54:45 rillig Exp $
#
# Tests for the :gmtime variable modifier, which formats a timestamp
# using strftime(3) in UTC.
@@ -56,8 +56,7 @@
# 1970. Going back 50 years in the past is not a practical use case for
# make. Therefore, since var.c 1.631, negative time stamps produce a
# parse error.
-# expect+2: while evaluating "${:L:gmtime=-1} != """ with value "": Invalid time value "-1"
-# expect+1: Malformed conditional (${:L:gmtime=-1} != "")
+# expect+1: Invalid time value "-1"
.if ${:L:gmtime=-1} != ""
. error
.else
@@ -67,8 +66,7 @@
# Spaces were allowed before var.c 1.631 from 2020-10-31 21:40:20, not
# because it would make sense but just as a side-effect from using strtoul.
-# expect+2: while evaluating "${:L:gmtime= 1} != """ with value "": Invalid time value " 1"
-# expect+1: Malformed conditional (${:L:gmtime= 1} != "")
+# expect+1: Invalid time value " 1"
.if ${:L:gmtime= 1} != ""
. error
.else
@@ -115,8 +113,7 @@
#
# Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a
# parse error.
-# expect+2: while evaluating "${:L:gmtime=10000000000000000000000000000000} != """ with value "": Invalid time value "10000000000000000000000000000000"
-# expect+1: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "")
+# expect+1: Invalid time value "10000000000000000000000000000000"
.if ${:L:gmtime=10000000000000000000000000000000} != ""
. error
.else
@@ -128,8 +125,7 @@
# stopped after the '=', and the remaining string was parsed for more variable
# modifiers. Because of the unknown modifier 'e' from the 'error', the whole
# variable value was discarded and thus not printed.
-# expect+2: while evaluating "${:L:gmtime=error} != """ with value "": Invalid time value "error"
-# expect+1: Malformed conditional (${:L:gmtime=error} != "")
+# expect+1: Invalid time value "error"
.if ${:L:gmtime=error} != ""
. error
.else
@@ -139,8 +135,7 @@
# Before var.c 1.1050 from 2023-05-09, the timestamp could be directly
# followed by the next modifier, without a ':' separator. This was the same
# bug as for the ':L' and ':P' modifiers.
-# expect+2: while evaluating variable "%Y" with value "%Y": Invalid time value "100000S,1970,bad,"
-# expect+1: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad")
+# expect+1: Invalid time value "100000S,1970,bad,"
.if ${%Y:L:gmtime=100000S,1970,bad,} != "bad"
. error
.endif
diff --git a/unit-tests/varmod-hash.exp b/unit-tests/varmod-hash.exp
index 55f43dbb56d8..030923cf09d6 100644
--- a/unit-tests/varmod-hash.exp
+++ b/unit-tests/varmod-hash.exp
@@ -1,9 +1,12 @@
-make: in target "all": while evaluating variable "12345" with value "12345": Unknown modifier "has"
-
+make: Unknown modifier "has"
+ while evaluating variable "12345" with value "12345"
+ in target "step-1"
26bb0f5f
12345
-make: in target "all": while evaluating variable "12345" with value "12345": Unknown modifier "hasX"
-
-make: in target "all": while evaluating variable "12345" with value "12345": Unknown modifier "hashed"
-
+make: Unknown modifier "hasX"
+ while evaluating variable "12345" with value "12345"
+ in target "step-4"
+make: Unknown modifier "hashed"
+ while evaluating variable "12345" with value "12345"
+ in target "step-5"
exit status 2
diff --git a/unit-tests/varmod-hash.mk b/unit-tests/varmod-hash.mk
index 5407e8299f9e..7b34b74226f2 100644
--- a/unit-tests/varmod-hash.mk
+++ b/unit-tests/varmod-hash.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-hash.mk,v 1.5 2020/09/04 06:54:07 rillig Exp $
+# $NetBSD: varmod-hash.mk,v 1.6 2024/07/20 11:05:12 rillig Exp $
#
# Tests for the :hash variable modifier, which computes a 32-bit hash from
# the value of the expression.
@@ -56,9 +56,14 @@ VECTORS+= de41416c abcdefghijklmnopqrstuvwxyz
. endif
.endfor
-all:
+all: step-{1,2,3,4,5}
+step-1:
@echo ${12345:L:has} # modifier name too short
+step-2:
@echo ${12345:L:hash} # ok
+step-3:
@echo ${12345:L:hash=SHA-256} # :hash does not accept '='
+step-4:
@echo ${12345:L:hasX} # misspelled
+step-5:
@echo ${12345:L:hashed} # modifier name too long
diff --git a/unit-tests/varmod-ifelse.exp b/unit-tests/varmod-ifelse.exp
index c93a9ec71716..02f434f1d411 100644
--- a/unit-tests/varmod-ifelse.exp
+++ b/unit-tests/varmod-ifelse.exp
@@ -1,32 +1,37 @@
-make: "varmod-ifelse.mk" line 29: while evaluating condition "bare words == "literal"": Bad condition
-make: "varmod-ifelse.mk" line 29: Malformed conditional (${${:Ubare words} == "literal":?bad:bad})
-make: "varmod-ifelse.mk" line 40: while evaluating condition " == """: Bad condition
-make: "varmod-ifelse.mk" line 49: while evaluating condition " == """: Bad condition
-make: "varmod-ifelse.mk" line 49: Malformed conditional (${${UNDEF} == "":?bad-cond:bad-cond})
-make: "varmod-ifelse.mk" line 73: while evaluating condition "1 == == 2": Bad condition
-make: "varmod-ifelse.mk" line 73: Malformed conditional (${1 == == 2:?yes:no} != "")
+make: "varmod-ifelse.mk" line 28: Bad condition
+ while evaluating condition "bare words == "literal""
+make: "varmod-ifelse.mk" line 39: Bad condition
+ while evaluating condition " == """
+make: "varmod-ifelse.mk" line 47: Bad condition
+ while evaluating condition " == """
+make: "varmod-ifelse.mk" line 70: Bad condition
+ while evaluating condition "1 == == 2"
CondParser_Eval: "${1 == == 2:?yes:no}" != ""
CondParser_Eval: 1 == == 2
Comparing 1.000000 == 0.000000
-make: "varmod-ifelse.mk" line 97: while evaluating condition "1 == == 2": Bad condition
+make: "varmod-ifelse.mk" line 94: Bad condition
+ while evaluating condition "1 == == 2"
Comparing "" != ""
-make: "varmod-ifelse.mk" line 101: warning: Oops, the parse error should have been propagated.
+make: "varmod-ifelse.mk" line 98: warning: Oops, the parse error should have been propagated.
CondParser_Eval: ${ ${:U\$}{VAR} == value:?ok:bad} != "ok"
CondParser_Eval: ${VAR} == value
Comparing "value" == "value"
Comparing "ok" != "ok"
-make: "varmod-ifelse.mk" line 163: no.
-make: "varmod-ifelse.mk" line 167: while evaluating condition "string == "literal" || no >= 10": Comparison with '>=' requires both operands 'no' and '10' to be numeric
-make: "varmod-ifelse.mk" line 167: while evaluating condition "string == "literal" || no >= 10": Bad condition
-make: "varmod-ifelse.mk" line 167: .
-make: "varmod-ifelse.mk" line 174: while evaluating condition "string == "literal" && >= 10": Bad condition
-make: "varmod-ifelse.mk" line 174: .
-make: "varmod-ifelse.mk" line 177: while evaluating condition "string == "literal" || >= 10": Bad condition
-make: "varmod-ifelse.mk" line 177: .
-make: "varmod-ifelse.mk" line 185: <true>
-make: "varmod-ifelse.mk" line 188: <false>
-make: "varmod-ifelse.mk" line 192: while evaluating condition " ": Bad condition
-make: "varmod-ifelse.mk" line 192: <>
+make: "varmod-ifelse.mk" line 160: no.
+make: "varmod-ifelse.mk" line 163: Comparison with '>=' requires both operands 'no' and '10' to be numeric
+ while evaluating condition "string == "literal" || no >= 10"
+make: "varmod-ifelse.mk" line 163: .
+make: "varmod-ifelse.mk" line 170: Bad condition
+ while evaluating condition "string == "literal" && >= 10"
+make: "varmod-ifelse.mk" line 170: .
+make: "varmod-ifelse.mk" line 173: Bad condition
+ while evaluating condition "string == "literal" || >= 10"
+make: "varmod-ifelse.mk" line 173: .
+make: "varmod-ifelse.mk" line 181: <true>
+make: "varmod-ifelse.mk" line 184: <false>
+make: "varmod-ifelse.mk" line 188: Bad condition
+ while evaluating condition " "
+make: "varmod-ifelse.mk" line 188: <>
CondParser_Eval: 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated"
CondParser_Eval: 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1"
CondParser_Eval: 0
@@ -36,18 +41,22 @@ CondParser_Eval: 1
Comparing "then2" != "then2"
CondParser_Eval: ${DELAYED} == "one"
Comparing "two" == "one"
-make: "varmod-ifelse.mk" line 288: no
+make: "varmod-ifelse.mk" line 284: no
CondParser_Eval: ${DELAYED} == "two"
Comparing "two" == "two"
-make: "varmod-ifelse.mk" line 290: yes
+make: "varmod-ifelse.mk" line 286: yes
CondParser_Eval: ${DELAYED} == "one"
Comparing "two" == "one"
-make: "varmod-ifelse.mk" line 293: no
+make: "varmod-ifelse.mk" line 289: no
CondParser_Eval: ${DELAYED} == "two"
Comparing "two" == "two"
-make: "varmod-ifelse.mk" line 296: yes
-make: "varmod-ifelse.mk" line 318: while evaluating then-branch of condition "1": while evaluating "${:X-then}:${:X-else}}" with value "": Unknown modifier "X-then"
-make: "varmod-ifelse.mk" line 318: while evaluating else-branch of condition "1": while parsing "${:X-else}}": Unknown modifier "X-else"
+make: "varmod-ifelse.mk" line 292: yes
+make: "varmod-ifelse.mk" line 314: Unknown modifier "X-then"
+ while evaluating "${:X-then}:${:X-else}}" with value ""
+ while evaluating then-branch of condition "1"
+make: "varmod-ifelse.mk" line 314: Unknown modifier "X-else"
+ while parsing "${:X-else}}"
+ while evaluating else-branch of condition "1"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varmod-ifelse.mk b/unit-tests/varmod-ifelse.mk
index 292bc076366e..b2f5419e65ad 100644
--- a/unit-tests/varmod-ifelse.mk
+++ b/unit-tests/varmod-ifelse.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-ifelse.mk,v 1.32 2024/07/05 20:01:52 rillig Exp $
+# $NetBSD: varmod-ifelse.mk,v 1.35 2025/01/11 20:54:45 rillig Exp $
#
# Tests for the ${cond:?then:else} variable modifier, which evaluates either
# the then-expression or the else-expression, depending on the condition.
@@ -24,8 +24,7 @@
# Evaluating the variable name lazily would require additional code in
# Var_Parse and ParseVarname, it would be more useful and predictable
# though.
-# expect+2: while evaluating condition "bare words == "literal"": Bad condition
-# expect+1: Malformed conditional (${${:Ubare words} == "literal":?bad:bad})
+# expect+1: Bad condition
.if ${${:Ubare words} == "literal":?bad:bad}
. error
.else
@@ -36,7 +35,7 @@
# Because of the early expansion, the whole condition evaluates to
# ' == ""' though, which cannot be parsed because the left-hand side looks
# empty.
-# expect+1: while evaluating condition " == """: Bad condition
+# expect+1: Bad condition
COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
# In a condition, undefined variables generate a "Malformed conditional"
@@ -44,8 +43,7 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
# "Undefined variable" error message is generated.
# The difference to the ':=' variable assignment is the additional
# "Malformed conditional" error message.
-# expect+2: while evaluating condition " == """: Bad condition
-# expect+1: Malformed conditional (${${UNDEF} == "":?bad-cond:bad-cond})
+# expect+1: Bad condition
.if ${${UNDEF} == "":?bad-cond:bad-cond}
. error
.else
@@ -68,8 +66,7 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
# conditional therefore returns a parse error from Var_Parse, and this parse
# error propagates to CondEvalExpression, where the "Malformed conditional"
# comes from.
-# expect+2: while evaluating condition "1 == == 2": Bad condition
-# expect+1: Malformed conditional (${1 == == 2:?yes:no} != "")
+# expect+1: Bad condition
.if ${1 == == 2:?yes:no} != ""
. error
.else
@@ -93,7 +90,7 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
# condition should be detected as being malformed before any comparison is
# done since there is no well-formed comparison in the condition at all.
.MAKEFLAGS: -dc
-# expect+1: while evaluating condition "1 == == 2": Bad condition
+# expect+1: Bad condition
.if "${1 == == 2:?yes:no}" != ""
. error
.else
@@ -161,18 +158,17 @@ STRING= string
NUMBER= no # not really a number
# expect+1: no.
.info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}.
-# expect+3: while evaluating condition "string == "literal" || no >= 10": Comparison with '>=' requires both operands 'no' and '10' to be numeric
-# expect+2: while evaluating condition "string == "literal" || no >= 10": Bad condition
+# expect+2: Comparison with '>=' requires both operands 'no' and '10' to be numeric
# expect+1: .
.info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}.
# The following situation occasionally occurs with MKINET6 or similar
# variables.
NUMBER= # empty, not really a number either
-# expect+2: while evaluating condition "string == "literal" && >= 10": Bad condition
+# expect+2: Bad condition
# expect+1: .
.info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}.
-# expect+2: while evaluating condition "string == "literal" || >= 10": Bad condition
+# expect+2: Bad condition
# expect+1: .
.info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}.
@@ -187,7 +183,7 @@ EMPTY= # empty
# expect+1: <false>
.info <${${ASTERISK} :?true:false}>
# syntax error since the condition is completely blank.
-# expect+2: while evaluating condition " ": Bad condition
+# expect+2: Bad condition
# expect+1: <>
.info <${${EMPTY} :?true:false}>
@@ -313,7 +309,7 @@ BOTH= <${YES}> <${NO}>
.endif
-# expect+2: while evaluating then-branch of condition "1": while evaluating "${:X-then}:${:X-else}}" with value "": Unknown modifier "X-then"
-# expect+1: while evaluating else-branch of condition "1": while parsing "${:X-else}}": Unknown modifier "X-else"
+# expect+2: Unknown modifier "X-then"
+# expect+1: Unknown modifier "X-else"
.if ${1:?${:X-then}:${:X-else}}
.endif
diff --git a/unit-tests/varmod-indirect.exp b/unit-tests/varmod-indirect.exp
index 360cec21e291..b572e34fcf8d 100644
--- a/unit-tests/varmod-indirect.exp
+++ b/unit-tests/varmod-indirect.exp
@@ -1,5 +1,7 @@
-make: "varmod-indirect.mk" line 19: while evaluating variable "value" with value "value": Unknown modifier "${"
-make: "varmod-indirect.mk" line 52: while evaluating variable "value" with value "value": Unknown modifier "${"
+make: "varmod-indirect.mk" line 19: Unknown modifier "${"
+ while evaluating variable "value" with value "value"
+make: "varmod-indirect.mk" line 52: Unknown modifier "${"
+ while evaluating variable "value" with value "value"
make: "varmod-indirect.mk" line 54: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression.
make: "varmod-indirect.mk" line 143: before
make: "varmod-indirect.mk" line 143: after
@@ -7,14 +9,15 @@ make: "varmod-indirect.mk" line 151: before
make: "varmod-indirect.mk" line 151: after
make: "varmod-indirect.mk" line 159: before
make: "varmod-indirect.mk" line 159: after
-make: "varmod-indirect.mk" line 164: while evaluating variable "UNDEF" with value "": Unknown modifier "Z"
+make: "varmod-indirect.mk" line 164: Unknown modifier "Z"
+ while evaluating variable "UNDEF" with value ""
make: "varmod-indirect.mk" line 167: before
make: "varmod-indirect.mk" line 167: after
-Parsing line 176: _:= before ${UNDEF} after
+Parsing varmod-indirect.mk:176: _:= before ${UNDEF} after
Global: _ = # (empty)
Var_Parse: ${UNDEF} after (eval-keep-dollar-and-undefined)
Global: _ = before ${UNDEF} after
-Parsing line 179: _:= before ${UNDEF:${:US,a,a,}} after
+Parsing varmod-indirect.mk:179: _:= before ${UNDEF:${:US,a,a,}} after
Var_Parse: ${UNDEF:${:US,a,a,}} after (eval-keep-dollar-and-undefined)
Indirect modifier "S,a,a," from "${:US,a,a,}"
Evaluating modifier ${UNDEF:S...} on value "" (eval-keep-dollar-and-undefined, undefined)
@@ -23,18 +26,19 @@ Modifier part: "a"
ModifyWords: split "" into 1 word
Result of ${UNDEF:S,a,a,} is "" (eval-keep-dollar-and-undefined, undefined)
Global: _ = before ${UNDEF:S,a,a,} after
-Parsing line 189: _:= before ${UNDEF:${:U}} after
+Parsing varmod-indirect.mk:189: _:= before ${UNDEF:${:U}} after
Var_Parse: ${UNDEF:${:U}} after (eval-keep-dollar-and-undefined)
Indirect modifier "" from "${:U}"
Global: _ = before ${UNDEF:} after
-Parsing line 195: _:= before ${UNDEF:${:UZ}} after
+Parsing varmod-indirect.mk:195: _:= before ${UNDEF:${:UZ}} after
Var_Parse: ${UNDEF:${:UZ}} after (eval-keep-dollar-and-undefined)
Indirect modifier "Z" from "${:UZ}"
Evaluating modifier ${UNDEF:Z} on value "" (eval-keep-dollar-and-undefined, undefined)
-make: "varmod-indirect.mk" line 195: while evaluating variable "UNDEF" with value "": Unknown modifier "Z"
+make: "varmod-indirect.mk" line 195: Unknown modifier "Z"
+ while evaluating variable "UNDEF" with value ""
Result of ${UNDEF:Z} is error (eval-keep-dollar-and-undefined, undefined)
Global: _ = before ${UNDEF:Z} after
-Parsing line 197: .MAKEFLAGS: -d0
+Parsing varmod-indirect.mk:197: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
Global: .MAKEFLAGS = -r -k -d 0 -d pv -d
Global: .MAKEFLAGS = -r -k -d 0 -d pv -d 0
diff --git a/unit-tests/varmod-indirect.mk b/unit-tests/varmod-indirect.mk
index a58cb870aac8..f54c0e232d2a 100644
--- a/unit-tests/varmod-indirect.mk
+++ b/unit-tests/varmod-indirect.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-indirect.mk,v 1.20 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: varmod-indirect.mk,v 1.21 2024/08/29 20:20:36 rillig Exp $
#
# Tests for indirect variable modifiers, such as in ${VAR:${M_modifiers}}.
# These can be used for very basic purposes like converting a string to either
@@ -15,7 +15,7 @@
# The following expression generates a parse error since its indirect
# modifier contains more than a sole expression.
#
-# expect+1: while evaluating variable "value" with value "value": Unknown modifier "${"
+# expect+1: Unknown modifier "${"
.if ${value:L:${:US}${:U,value,replacement,}} != "S,value,replacement,}"
. warning unexpected
.endif
@@ -47,7 +47,7 @@
# error. Because of this parse error, this feature cannot be used reasonably
# in practice.
#
-# expect+2: while evaluating variable "value" with value "value": Unknown modifier "${"
+# expect+2: Unknown modifier "${"
#.MAKEFLAGS: -dvc
.if ${value:L:${:UM*}S,value,replaced,} == "M*S,value,replaced,}"
# expect+1: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression.
@@ -160,7 +160,7 @@ M_NoPrimes= ${PRIMES:${M_ListToSkip}}
.endfor
# An error in an indirect modifier.
-# expect+1: while evaluating variable "UNDEF" with value "": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
.for var in before ${UNDEF:${:UZ}} after
# expect+2: before
# expect+1: after
@@ -191,7 +191,7 @@ _:= before ${UNDEF:${:U}} after
# XXX: This expands to ${UNDEF:Z}, which will behave differently if the
# variable '_' is used in a context where the expression ${_} is
# parsed but not evaluated.
-# expect+1: while evaluating variable "UNDEF" with value "": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
_:= before ${UNDEF:${:UZ}} after
.MAKEFLAGS: -d0
diff --git a/unit-tests/varmod-localtime.exp b/unit-tests/varmod-localtime.exp
index 0183ae6dcc2f..b22bfe479227 100644
--- a/unit-tests/varmod-localtime.exp
+++ b/unit-tests/varmod-localtime.exp
@@ -1,13 +1,13 @@
-make: "varmod-localtime.mk" line 61: while evaluating "${:L:localtime=-1} != """ with value "": Invalid time value "-1"
-make: "varmod-localtime.mk" line 61: Malformed conditional (${:L:localtime=-1} != "")
-make: "varmod-localtime.mk" line 72: while evaluating "${:L:localtime= 1} != """ with value "": Invalid time value " 1"
-make: "varmod-localtime.mk" line 72: Malformed conditional (${:L:localtime= 1} != "")
-make: "varmod-localtime.mk" line 120: while evaluating "${:L:localtime=10000000000000000000000000000000} != """ with value "": Invalid time value "10000000000000000000000000000000"
-make: "varmod-localtime.mk" line 120: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "")
-make: "varmod-localtime.mk" line 133: while evaluating "${:L:localtime=error} != """ with value "": Invalid time value "error"
-make: "varmod-localtime.mk" line 133: Malformed conditional (${:L:localtime=error} != "")
-make: "varmod-localtime.mk" line 144: while evaluating variable "%Y" with value "%Y": Invalid time value "100000S,1970,bad,"
-make: "varmod-localtime.mk" line 144: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad")
+make: "varmod-localtime.mk" line 60: Invalid time value "-1"
+ while evaluating "${:L:localtime=-1} != """ with value ""
+make: "varmod-localtime.mk" line 70: Invalid time value " 1"
+ while evaluating "${:L:localtime= 1} != """ with value ""
+make: "varmod-localtime.mk" line 117: Invalid time value "10000000000000000000000000000000"
+ while evaluating "${:L:localtime=10000000000000000000000000000000} != """ with value ""
+make: "varmod-localtime.mk" line 129: Invalid time value "error"
+ while evaluating "${:L:localtime=error} != """ with value ""
+make: "varmod-localtime.mk" line 139: Invalid time value "100000S,1970,bad,"
+ while evaluating variable "%Y" with value "%Y"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-localtime.mk b/unit-tests/varmod-localtime.mk
index b6295965ddb8..41c99c86df6e 100644
--- a/unit-tests/varmod-localtime.mk
+++ b/unit-tests/varmod-localtime.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-localtime.mk,v 1.17 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-localtime.mk,v 1.20 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the :localtime variable modifier, which formats a timestamp
# using strftime(3) in local time.
@@ -56,8 +56,7 @@
# 1970. Going back 50 years in the past is not a practical use case for
# make. Therefore, since var.c 1.631, negative time stamps produce a
# parse error.
-# expect+2: while evaluating "${:L:localtime=-1} != """ with value "": Invalid time value "-1"
-# expect+1: Malformed conditional (${:L:localtime=-1} != "")
+# expect+1: Invalid time value "-1"
.if ${:L:localtime=-1} != ""
. error
.else
@@ -67,8 +66,7 @@
# Spaces were allowed before var.c 1.631 from 2020-10-31 21:40:20, not
# because it would make sense but just as a side-effect from using strtoul.
-# expect+2: while evaluating "${:L:localtime= 1} != """ with value "": Invalid time value " 1"
-# expect+1: Malformed conditional (${:L:localtime= 1} != "")
+# expect+1: Invalid time value " 1"
.if ${:L:localtime= 1} != ""
. error
.else
@@ -115,8 +113,7 @@
#
# Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a
# parse error.
-# expect+2: while evaluating "${:L:localtime=10000000000000000000000000000000} != """ with value "": Invalid time value "10000000000000000000000000000000"
-# expect+1: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "")
+# expect+1: Invalid time value "10000000000000000000000000000000"
.if ${:L:localtime=10000000000000000000000000000000} != ""
. error
.else
@@ -128,8 +125,7 @@
# stopped after the '=', and the remaining string was parsed for more variable
# modifiers. Because of the unknown modifier 'e' from the 'error', the whole
# variable value was discarded and thus not printed.
-# expect+2: while evaluating "${:L:localtime=error} != """ with value "": Invalid time value "error"
-# expect+1: Malformed conditional (${:L:localtime=error} != "")
+# expect+1: Invalid time value "error"
.if ${:L:localtime=error} != ""
. error
.else
@@ -139,8 +135,7 @@
# Before var.c 1.1050 from 2023-05-09, the timestamp could be directly
# followed by the next modifier, without a ':' separator. This was the same
# bug as for the ':L' and ':P' modifiers.
-# expect+2: while evaluating variable "%Y" with value "%Y": Invalid time value "100000S,1970,bad,"
-# expect+1: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad")
+# expect+1: Invalid time value "100000S,1970,bad,"
.if ${%Y:L:localtime=100000S,1970,bad,} != "bad"
. error
.endif
diff --git a/unit-tests/varmod-loop-delete.exp b/unit-tests/varmod-loop-delete.exp
index eb3124a9adfd..874dce4495c1 100644
--- a/unit-tests/varmod-loop-delete.exp
+++ b/unit-tests/varmod-loop-delete.exp
@@ -1,4 +1,6 @@
-make: "varmod-loop-delete.mk" line 20: while evaluating variable "VAR" with value "${:U:@VAR@@} rest of the value": while evaluating "${:U:@VAR@@} rest of the value" with value "": Cannot delete variable "VAR" while it is used
+make: "varmod-loop-delete.mk" line 20: Cannot delete variable "VAR" while it is used
+ while evaluating "${:U:@VAR@@} rest of the value" with value ""
+ while evaluating variable "VAR" with value "${:U:@VAR@@} rest of the value"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-loop-delete.mk b/unit-tests/varmod-loop-delete.mk
index 5a4b273afcaf..478a25e91f6e 100644
--- a/unit-tests/varmod-loop-delete.mk
+++ b/unit-tests/varmod-loop-delete.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop-delete.mk,v 1.6 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-loop-delete.mk,v 1.7 2024/08/29 20:20:36 rillig Exp $
#
# Tests for the variable modifier ':@', which as a side effect allows to
# delete an arbitrary variable.
@@ -16,7 +16,7 @@ VAR= ${:U:@VAR@@} rest of the value
# In an assignment, the scope is 'Global'. Since the variable 'VAR' is
# defined in the global scope, it deletes itself.
-# expect+1: while evaluating variable "VAR" with value "${:U:@VAR@@} rest of the value": while evaluating "${:U:@VAR@@} rest of the value" with value "": Cannot delete variable "VAR" while it is used
+# expect+1: Cannot delete variable "VAR" while it is used
EVAL:= ${VAR}
.if ${EVAL} != " rest of the value"
. error
diff --git a/unit-tests/varmod-loop-varname.exp b/unit-tests/varmod-loop-varname.exp
index 8ad1842c4d09..442f9bb6d684 100644
--- a/unit-tests/varmod-loop-varname.exp
+++ b/unit-tests/varmod-loop-varname.exp
@@ -1,11 +1,11 @@
-make: "varmod-loop-varname.mk" line 18: while evaluating "${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"" with value "one two three": In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar
-make: "varmod-loop-varname.mk" line 18: Malformed conditional (${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+")
-make: "varmod-loop-varname.mk" line 89: while evaluating variable "1 2 3" with value "1 2 3": In the :@ modifier, the variable name "v$" must not contain a dollar
-make: "varmod-loop-varname.mk" line 89: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)")
-make: "varmod-loop-varname.mk" line 96: while evaluating variable "1 2 3" with value "1 2 3": In the :@ modifier, the variable name "v$$" must not contain a dollar
-make: "varmod-loop-varname.mk" line 96: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()")
-make: "varmod-loop-varname.mk" line 103: while evaluating variable "1 2 3" with value "1 2 3": In the :@ modifier, the variable name "v$$$" must not contain a dollar
-make: "varmod-loop-varname.mk" line 103: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()")
+make: "varmod-loop-varname.mk" line 17: In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar
+ while evaluating "${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"" with value "one two three"
+make: "varmod-loop-varname.mk" line 87: In the :@ modifier, the variable name "v$" must not contain a dollar
+ while evaluating variable "1 2 3" with value "1 2 3"
+make: "varmod-loop-varname.mk" line 93: In the :@ modifier, the variable name "v$$" must not contain a dollar
+ while evaluating variable "1 2 3" with value "1 2 3"
+make: "varmod-loop-varname.mk" line 99: In the :@ modifier, the variable name "v$$$" must not contain a dollar
+ while evaluating variable "1 2 3" with value "1 2 3"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-loop-varname.mk b/unit-tests/varmod-loop-varname.mk
index a41d1d30d019..703e81941c59 100644
--- a/unit-tests/varmod-loop-varname.mk
+++ b/unit-tests/varmod-loop-varname.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop-varname.mk,v 1.9 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-loop-varname.mk,v 1.12 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the first part of the variable modifier ':@var@...@', which
# contains the variable name to use during the loop.
@@ -13,8 +13,7 @@
# dynamically. There was no practical use-case for this.
# Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the
# variable name.
-# expect+2: while evaluating "${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"" with value "one two three": In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar
-# expect+1: Malformed conditional (${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+")
+# expect+1: In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar
.if ${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"
. error
.else
@@ -84,22 +83,19 @@ RES3= 3
# There's no point in allowing a dollar sign in that position.
# Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the
# variable name.
-# expect+2: while evaluating variable "1 2 3" with value "1 2 3": In the :@ modifier, the variable name "v$" must not contain a dollar
-# expect+1: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)")
+# expect+1: In the :@ modifier, the variable name "v$" must not contain a dollar
.if ${1 2 3:L:@v$@($v)@} != "(1) (2) (3)"
. error
.else
. error
.endif
-# expect+2: while evaluating variable "1 2 3" with value "1 2 3": In the :@ modifier, the variable name "v$$" must not contain a dollar
-# expect+1: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()")
+# expect+1: In the :@ modifier, the variable name "v$$" must not contain a dollar
.if ${1 2 3:L:@v$$@($v)@} != "() () ()"
. error
.else
. error
.endif
-# expect+2: while evaluating variable "1 2 3" with value "1 2 3": In the :@ modifier, the variable name "v$$$" must not contain a dollar
-# expect+1: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()")
+# expect+1: In the :@ modifier, the variable name "v$$$" must not contain a dollar
.if ${1 2 3:L:@v$$$@($v)@} != "() () ()"
. error
.else
diff --git a/unit-tests/varmod-loop.exp b/unit-tests/varmod-loop.exp
index ccfcd0b2dc06..510b151957f8 100644
--- a/unit-tests/varmod-loop.exp
+++ b/unit-tests/varmod-loop.exp
@@ -1,12 +1,12 @@
-Parsing line 89: USE_8_DOLLARS= ${:U1:@var@${8_DOLLARS}@} ${8_DOLLARS} $$$$$$$$
-Parsing line 90: .if ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$"
+Parsing varmod-loop.mk:89: USE_8_DOLLARS= ${:U1:@var@${8_DOLLARS}@} ${8_DOLLARS} $$$$$$$$
+Parsing varmod-loop.mk:90: .if ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$"
CondParser_Eval: ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$"
Comparing "$$$$ $$$$ $$$$" != "$$$$ $$$$ $$$$"
-Parsing line 94: SUBST_CONTAINING_LOOP:= ${USE_8_DOLLARS}
-Parsing line 116: .if ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$"
+Parsing varmod-loop.mk:94: SUBST_CONTAINING_LOOP:= ${USE_8_DOLLARS}
+Parsing varmod-loop.mk:116: .if ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$"
CondParser_Eval: ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$"
Comparing "$$ $$$$ $$$$" != "$$ $$$$ $$$$"
-Parsing line 119: .MAKEFLAGS: -d0
+Parsing varmod-loop.mk:119: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
:varname-overwriting-target: :x1y x2y x3y: ::
mod-loop-dollar:1:
diff --git a/unit-tests/varmod-match-escape.exp b/unit-tests/varmod-match-escape.exp
index e15445de356b..a972b14816bd 100755
--- a/unit-tests/varmod-match-escape.exp
+++ b/unit-tests/varmod-match-escape.exp
@@ -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 "::"
@@ -33,10 +33,13 @@ Comparing ":" != "::"
make: "varmod-match-escape.mk" line 43: warning: XXX: Oops
Global: .MAKEFLAGS = -r -k -d cv -d
Global: .MAKEFLAGS = -r -k -d cv -d 0
-make: "varmod-match-escape.mk" line 69: while evaluating "${:U\$:M\$} != """ with value "$": Dollar followed by nothing
-make: "varmod-match-escape.mk" line 110: while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]": Unfinished character list in pattern '[A-]' of modifier ':M'
+make: "varmod-match-escape.mk" line 69: Dollar followed by nothing
+ while evaluating "${:U\$:M\$} != """ with value "$"
+make: "varmod-match-escape.mk" line 110: Unfinished character list in pattern '[A-]' of modifier ':M'
+ while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]"
in .for loop from varmod-match-escape.mk:107 with pattern = [A-]
-make: "varmod-match-escape.mk" line 110: while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]": Unfinished character list in pattern '[^A-]' of modifier ':M'
+make: "varmod-match-escape.mk" line 110: Unfinished character list in pattern '[^A-]' of modifier ':M'
+ while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]"
in .for loop from varmod-match-escape.mk:107 with pattern = [^A-]
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
diff --git a/unit-tests/varmod-match-escape.mk b/unit-tests/varmod-match-escape.mk
index eb5730d3e5a1..d9e2009f9b60 100755
--- a/unit-tests/varmod-match-escape.mk
+++ b/unit-tests/varmod-match-escape.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match-escape.mk,v 1.17 2024/07/09 17:07:23 rillig Exp $
+# $NetBSD: varmod-match-escape.mk,v 1.18 2024/08/29 20:20:36 rillig Exp $
#
# As of 2020-08-01, the :M and :N modifiers interpret backslashes differently,
# depending on whether there was an expression somewhere before the
@@ -65,7 +65,7 @@ VALUES= : :: :\:
# In lint mode, the case of a lonely '$' is covered with an error message.
.MAKEFLAGS: -dL
-# expect+1: while evaluating "${:U\$:M\$} != """ with value "$": Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${:U\$:M\$} != ""
. error
.endif
@@ -105,8 +105,8 @@ EXP.[^A-]]= a
EXP.[^A-]]]= a]
.for pattern in [A-] [A-]] [A-]]] [^A-] [^A-]] [^A-]]]
-# expect+2: while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]": Unfinished character list in pattern '[A-]' of modifier ':M'
-# expect+1: while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]": Unfinished character list in pattern '[^A-]' of modifier ':M'
+# expect+2: Unfinished character list in pattern '[A-]' of modifier ':M'
+# expect+1: Unfinished character list in pattern '[^A-]' of modifier ':M'
. if ${WORDS:M${pattern}} != ${EXP.${pattern}}
. warning ${pattern}: ${WORDS:M${pattern}} != ${EXP.${pattern}}
. endif
diff --git a/unit-tests/varmod-match.exp b/unit-tests/varmod-match.exp
index 377a43082fed..fdc76c3ae83a 100644
--- a/unit-tests/varmod-match.exp
+++ b/unit-tests/varmod-match.exp
@@ -1,14 +1,23 @@
-make: "varmod-match.mk" line 289: while evaluating variable "WORDS" with value "a a[": Unfinished character list in pattern 'a[' of modifier ':M'
-make: "varmod-match.mk" line 297: while evaluating variable "WORDS" with value "a a[ aX": Unfinished character list in pattern 'a[^' of modifier ':M'
-make: "varmod-match.mk" line 305: while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3": Unfinished character list in pattern '[-x1-3' of modifier ':M'
-make: "varmod-match.mk" line 313: while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3": Unfinished character list in pattern '*[-x1-3' of modifier ':M'
-make: "varmod-match.mk" line 322: while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3": Unfinished character list in pattern '[^-x1-3' of modifier ':M'
-make: "varmod-match.mk" line 336: while evaluating variable "WORDS" with value "\\ \a x\": Unfinished character list in pattern '?[\' of modifier ':M'
-make: "varmod-match.mk" line 344: while evaluating variable "WORDS" with value "[x- x x- y": Unfinished character range in pattern '[x-' of modifier ':M'
-make: "varmod-match.mk" line 356: while evaluating variable "WORDS" with value "[x- x x- y yyyyy": Unfinished character range in pattern '[^x-' of modifier ':M'
-make: "varmod-match.mk" line 364: while evaluating variable " : :: " with value " : :: ": Unfinished character list in pattern '[' of modifier ':M'
-make: "varmod-match.mk" line 364: while evaluating variable " : :: " with value "": Unknown modifier "]"
-make: "varmod-match.mk" line 364: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+make: "varmod-match.mk" line 289: Unfinished character list in pattern 'a[' of modifier ':M'
+ while evaluating variable "WORDS" with value "a a["
+make: "varmod-match.mk" line 297: Unfinished character list in pattern 'a[^' of modifier ':M'
+ while evaluating variable "WORDS" with value "a a[ aX"
+make: "varmod-match.mk" line 305: Unfinished character list in pattern '[-x1-3' of modifier ':M'
+ while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3"
+make: "varmod-match.mk" line 313: Unfinished character list in pattern '*[-x1-3' of modifier ':M'
+ while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3"
+make: "varmod-match.mk" line 322: Unfinished character list in pattern '[^-x1-3' of modifier ':M'
+ while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3"
+make: "varmod-match.mk" line 336: Unfinished character list in pattern '?[\' of modifier ':M'
+ while evaluating variable "WORDS" with value "\\ \a x\"
+make: "varmod-match.mk" line 344: Unfinished character range in pattern '[x-' of modifier ':M'
+ while evaluating variable "WORDS" with value "[x- x x- y"
+make: "varmod-match.mk" line 356: Unfinished character range in pattern '[^x-' of modifier ':M'
+ while evaluating variable "WORDS" with value "[x- x x- y yyyyy"
+make: "varmod-match.mk" line 363: Unfinished character list in pattern '[' of modifier ':M'
+ while evaluating variable " : :: " with value " : :: "
+make: "varmod-match.mk" line 363: Unknown modifier "]"
+ while evaluating variable " : :: " with value ""
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varmod-match.mk b/unit-tests/varmod-match.mk
index ce2bbab7eb53..3e9ada78231e 100644
--- a/unit-tests/varmod-match.mk
+++ b/unit-tests/varmod-match.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match.mk,v 1.26 2024/07/09 17:07:23 rillig Exp $
+# $NetBSD: varmod-match.mk,v 1.29 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the ':M' modifier, which keeps only those words that match the
# given pattern.
@@ -285,7 +285,7 @@ ${:U*}= asterisk
# [ Incomplete empty character list, never matches.
WORDS= a a[
-# expect+1: while evaluating variable "WORDS" with value "a a[": Unfinished character list in pattern 'a[' of modifier ':M'
+# expect+1: Unfinished character list in pattern 'a[' of modifier ':M'
.if ${WORDS:Ma[} != ""
. error
.endif
@@ -293,7 +293,7 @@ WORDS= a a[
# [^ Incomplete negated empty character list, matches any single
# character.
WORDS= a a[ aX
-# expect+1: while evaluating variable "WORDS" with value "a a[ aX": Unfinished character list in pattern 'a[^' of modifier ':M'
+# expect+1: Unfinished character list in pattern 'a[^' of modifier ':M'
.if ${WORDS:Ma[^} != "a[ aX"
. error
.endif
@@ -301,7 +301,7 @@ WORDS= a a[ aX
# [-x1-3 Incomplete character list, matches those elements that can be
# parsed without lookahead.
WORDS= - + x xx 0 1 2 3 4 [x1-3
-# expect+1: while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3": Unfinished character list in pattern '[-x1-3' of modifier ':M'
+# expect+1: Unfinished character list in pattern '[-x1-3' of modifier ':M'
.if ${WORDS:M[-x1-3} != "- x 1 2 3"
. error
.endif
@@ -309,7 +309,7 @@ WORDS= - + x xx 0 1 2 3 4 [x1-3
# *[-x1-3 Incomplete character list after a wildcard, matches those
# words that end with one of the characters from the list.
WORDS= - + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3
-# expect+1: while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3": Unfinished character list in pattern '*[-x1-3' of modifier ':M'
+# expect+1: Unfinished character list in pattern '*[-x1-3' of modifier ':M'
.if ${WORDS:M*[-x1-3} != "- x xx 1 2 3 01 11 001 011 101 111 [x1-3"
. warning ${WORDS:M*[-x1-3}
.endif
@@ -318,7 +318,7 @@ WORDS= - + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3
# Incomplete negated character list, matches any character
# except those elements that can be parsed without lookahead.
WORDS= - + x xx 0 1 2 3 4 [x1-3
-# expect+1: while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3": Unfinished character list in pattern '[^-x1-3' of modifier ':M'
+# expect+1: Unfinished character list in pattern '[^-x1-3' of modifier ':M'
.if ${WORDS:M[^-x1-3} != "+ 0 4"
. error
.endif
@@ -332,7 +332,7 @@ WORDS= - + x xx 0 1 2 3 4 [x1-3
# '\', as there is no following space that could be escaped.
WORDS= \\ \a ${:Ux\\}
PATTERN= ${:U?[\\}
-# expect+1: while evaluating variable "WORDS" with value "\\ \a x\": Unfinished character list in pattern '?[\' of modifier ':M'
+# expect+1: Unfinished character list in pattern '?[\' of modifier ':M'
.if ${WORDS:M${PATTERN}} != "\\\\ x\\"
. error
.endif
@@ -340,7 +340,7 @@ PATTERN= ${:U?[\\}
# [x- Incomplete character list containing an incomplete character
# range, matches only the 'x'.
WORDS= [x- x x- y
-# expect+1: while evaluating variable "WORDS" with value "[x- x x- y": Unfinished character range in pattern '[x-' of modifier ':M'
+# expect+1: Unfinished character range in pattern '[x-' of modifier ':M'
.if ${WORDS:M[x-} != "x"
. error
.endif
@@ -352,15 +352,14 @@ WORDS= [x- x x- y
# XXX: Even matches strings that are longer than a single
# character.
WORDS= [x- x x- y yyyyy
-# expect+1: while evaluating variable "WORDS" with value "[x- x x- y yyyyy": Unfinished character range in pattern '[^x-' of modifier ':M'
+# expect+1: Unfinished character range in pattern '[^x-' of modifier ':M'
.if ${WORDS:M[^x-} != "[x- y yyyyy"
. error
.endif
# [:] matches never since the ':' starts the next modifier
-# expect+3: while evaluating variable " : :: " with value " : :: ": Unfinished character list in pattern '[' of modifier ':M'
-# expect+2: while evaluating variable " : :: " with value "": Unknown modifier "]"
-# expect+1: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+# expect+2: Unfinished character list in pattern '[' of modifier ':M'
+# expect+1: Unknown modifier "]"
.if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":"
. error
.else
diff --git a/unit-tests/varmod-mtime.exp b/unit-tests/varmod-mtime.exp
index 153b7ff79f08..160bfcdd6cf8 100644
--- a/unit-tests/varmod-mtime.exp
+++ b/unit-tests/varmod-mtime.exp
@@ -1,14 +1,15 @@
-make: "varmod-mtime.mk" line 47: while evaluating variable "no/such/file" with value "no/such/file": Invalid argument '123x' for modifier ':mtime'
-make: "varmod-mtime.mk" line 47: Malformed conditional (${no/such/file:L:mtime=123x})
-make: "varmod-mtime.mk" line 70: while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file1': <ENOENT>
-make: "varmod-mtime.mk" line 70: while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file2': <ENOENT>
-make: "varmod-mtime.mk" line 70: Malformed conditional (${no/such/file1 no/such/file2:L:mtime=error})
-make: "varmod-mtime.mk" line 81: while evaluating variable "MAKEFILE" with value "varmod-mtime.mk": Invalid argument 'errorhandler-no' for modifier ':mtime'
-make: "varmod-mtime.mk" line 81: Malformed conditional (${MAKEFILE:mtime=errorhandler-no} > 0)
-make: "varmod-mtime.mk" line 90: while evaluating variable "MAKEFILE" with value "varmod-mtime.mk": Invalid argument 'warn' for modifier ':mtime'
-make: "varmod-mtime.mk" line 90: Malformed conditional (${MAKEFILE:mtime=warn} > 0)
-make: "varmod-mtime.mk" line 115: while evaluating variable "anything" with value "anything": Unknown modifier "mtim"
-make: "varmod-mtime.mk" line 115: Malformed conditional (${anything:L:mtim})
+make: "varmod-mtime.mk" line 46: Invalid argument '123x' for modifier ':mtime'
+ while evaluating variable "no/such/file" with value "no/such/file"
+make: "varmod-mtime.mk" line 68: Cannot determine mtime for 'no/such/file1': <ENOENT>
+ while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2"
+make: "varmod-mtime.mk" line 68: Cannot determine mtime for 'no/such/file2': <ENOENT>
+ while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2"
+make: "varmod-mtime.mk" line 78: Invalid argument 'errorhandler-no' for modifier ':mtime'
+ while evaluating variable "MAKEFILE" with value "varmod-mtime.mk"
+make: "varmod-mtime.mk" line 86: Invalid argument 'warn' for modifier ':mtime'
+ while evaluating variable "MAKEFILE" with value "varmod-mtime.mk"
+make: "varmod-mtime.mk" line 110: Unknown modifier "mtim"
+ while evaluating variable "anything" with value "anything"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varmod-mtime.mk b/unit-tests/varmod-mtime.mk
index be627fcfe040..0d0ddfc26b52 100644
--- a/unit-tests/varmod-mtime.mk
+++ b/unit-tests/varmod-mtime.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-mtime.mk,v 1.11 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: varmod-mtime.mk,v 1.14 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the ':mtime' variable modifier, which maps each word of the
# expression to that file's modification time.
@@ -42,8 +42,7 @@ not_found_mtime:= ${no/such/file:L:mtime}
# The fallback timestamp must only be an integer, without trailing characters.
-# expect+2: while evaluating variable "no/such/file" with value "no/such/file": Invalid argument '123x' for modifier ':mtime'
-# expect+1: Malformed conditional (${no/such/file:L:mtime=123x})
+# expect+1: Invalid argument '123x' for modifier ':mtime'
.if ${no/such/file:L:mtime=123x}
. error
.else
@@ -64,9 +63,8 @@ _!= rm -f ${COOKIE}
# If the optional argument of the ':mtime' modifier is the word 'error', the
# modifier fails with an error message, once for each affected file.
#
-# expect+3: while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file1': <ENOENT>
-# expect+2: while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file2': <ENOENT>
-# expect+1: Malformed conditional (${no/such/file1 no/such/file2:L:mtime=error})
+# expect+2: Cannot determine mtime for 'no/such/file1': <ENOENT>
+# expect+1: Cannot determine mtime for 'no/such/file2': <ENOENT>
.if ${no/such/file1 no/such/file2:L:mtime=error}
. error
.else
@@ -76,8 +74,7 @@ _!= rm -f ${COOKIE}
# Only the word 'error' is a special argument to the ':mtime' modifier, all
# other words result in a parse error.
-# expect+2: while evaluating variable "MAKEFILE" with value "varmod-mtime.mk": Invalid argument 'errorhandler-no' for modifier ':mtime'
-# expect+1: Malformed conditional (${MAKEFILE:mtime=errorhandler-no} > 0)
+# expect+1: Invalid argument 'errorhandler-no' for modifier ':mtime'
.if ${MAKEFILE:mtime=errorhandler-no} > 0
.else
. error
@@ -85,8 +82,7 @@ _!= rm -f ${COOKIE}
# Only the word 'error' can be used as a fallback argument to the modifier.
-# expect+2: while evaluating variable "MAKEFILE" with value "varmod-mtime.mk": Invalid argument 'warn' for modifier ':mtime'
-# expect+1: Malformed conditional (${MAKEFILE:mtime=warn} > 0)
+# expect+1: Invalid argument 'warn' for modifier ':mtime'
.if ${MAKEFILE:mtime=warn} > 0
. error
.else
@@ -110,8 +106,7 @@ end:= ${%s:L:gmtime}
# If there is a typo in the modifier name, it does not match.
-# expect+2: while evaluating variable "anything" with value "anything": Unknown modifier "mtim"
-# expect+1: Malformed conditional (${anything:L:mtim})
+# expect+1: Unknown modifier "mtim"
.if ${anything:L:mtim}
. error
.else
diff --git a/unit-tests/varmod-order.exp b/unit-tests/varmod-order.exp
index 591e1f160f61..2b955c123412 100644
--- a/unit-tests/varmod-order.exp
+++ b/unit-tests/varmod-order.exp
@@ -1,26 +1,29 @@
-make: "varmod-order.mk" line 17: while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten": Bad modifier ":OX"
-make: "varmod-order.mk" line 17: Undefined variable "${WORDS:OX"
-make: "varmod-order.mk" line 23: while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten": Bad modifier ":OxXX"
-make: "varmod-order.mk" line 23: Undefined variable "${WORDS:Ox"
-make: "varmod-order.mk" line 27: while evaluating variable "WORDS" with value "eight five four nine one seven six ten three two": Unclosed expression, expecting '}' for modifier "O"
-make: "varmod-order.mk" line 29: while evaluating variable "NUMBERS" with value "1 2 3 4 5 6 7 8 9 10": Unclosed expression, expecting '}' for modifier "On"
-make: "varmod-order.mk" line 31: while evaluating variable "NUMBERS" with value "10 9 8 7 6 5 4 3 2 1": Unclosed expression, expecting '}' for modifier "Onr"
-make: "varmod-order.mk" line 38: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Oxn"
-make: "varmod-order.mk" line 38: Malformed conditional (${NUMBERS:Oxn})
-make: "varmod-order.mk" line 48: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":On_typo"
-make: "varmod-order.mk" line 48: Malformed conditional (${NUMBERS:On_typo})
-make: "varmod-order.mk" line 58: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Onr_typo"
-make: "varmod-order.mk" line 58: Malformed conditional (${NUMBERS:Onr_typo})
-make: "varmod-order.mk" line 68: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Orn_typo"
-make: "varmod-order.mk" line 68: Malformed conditional (${NUMBERS:Orn_typo})
-make: "varmod-order.mk" line 80: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Onn"
-make: "varmod-order.mk" line 80: Malformed conditional (${NUMBERS:Onn})
-make: "varmod-order.mk" line 90: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Onrr"
-make: "varmod-order.mk" line 90: Malformed conditional (${NUMBERS:Onrr})
-make: "varmod-order.mk" line 100: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Orrn"
-make: "varmod-order.mk" line 100: Malformed conditional (${NUMBERS:Orrn})
-make: "varmod-order.mk" line 115: while evaluating variable "SWITCH" with value "On": Bad modifier ":On=Off"
-make: "varmod-order.mk" line 115: Malformed conditional (${SWITCH:On=Off} != "Off")
+make: "varmod-order.mk" line 14: Bad modifier ":OX"
+ while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten"
+make: "varmod-order.mk" line 17: Bad modifier ":OxXX"
+ while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten"
+make: "varmod-order.mk" line 20: Unclosed expression, expecting '}' for modifier "O"
+ while evaluating variable "WORDS" with value "eight five four nine one seven six ten three two"
+make: "varmod-order.mk" line 22: Unclosed expression, expecting '}' for modifier "On"
+ while evaluating variable "NUMBERS" with value "1 2 3 4 5 6 7 8 9 10"
+make: "varmod-order.mk" line 24: Unclosed expression, expecting '}' for modifier "Onr"
+ while evaluating variable "NUMBERS" with value "10 9 8 7 6 5 4 3 2 1"
+make: "varmod-order.mk" line 30: Bad modifier ":Oxn"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 39: Bad modifier ":On_typo"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 48: Bad modifier ":Onr_typo"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 57: Bad modifier ":Orn_typo"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 68: Bad modifier ":Onn"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 77: Bad modifier ":Onrr"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 86: Bad modifier ":Orrn"
+ while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2"
+make: "varmod-order.mk" line 100: Bad modifier ":On=Off"
+ while evaluating variable "SWITCH" with value "On"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-order.mk b/unit-tests/varmod-order.mk
index b8a631857e6f..0389b3f023af 100644
--- a/unit-tests/varmod-order.mk
+++ b/unit-tests/varmod-order.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-order.mk,v 1.14 2024/07/05 18:59:33 rillig Exp $
+# $NetBSD: varmod-order.mk,v 1.18 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the :O variable modifier and its variants, which either sort the
# words of the value or shuffle them.
@@ -10,31 +10,23 @@ NUMBERS= 8 5 4 9 1 7 6 10 3 2 # in English alphabetical order
. error ${WORDS:O}
.endif
-# Unknown modifier "OX"
-# FIXME: The error message "Undefined variable" is wrong.
-# expect+2: Undefined variable "${WORDS:OX"
-# expect+1: while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten": Bad modifier ":OX"
+# expect+1: Bad modifier ":OX"
_:= ${WORDS:OX}
-# Unknown modifier "OxXX"
-# FIXME: The error message "Undefined variable" is wrong.
-# expect+2: Undefined variable "${WORDS:Ox"
-# expect+1: while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten": Bad modifier ":OxXX"
+# expect+1: Bad modifier ":OxXX"
_:= ${WORDS:OxXX}
-# Missing closing brace, to cover the error handling code.
-# expect+1: while evaluating variable "WORDS" with value "eight five four nine one seven six ten three two": Unclosed expression, expecting '}' for modifier "O"
+# expect+1: Unclosed expression, expecting '}' for modifier "O"
_:= ${WORDS:O
-# expect+1: while evaluating variable "NUMBERS" with value "1 2 3 4 5 6 7 8 9 10": Unclosed expression, expecting '}' for modifier "On"
+# expect+1: Unclosed expression, expecting '}' for modifier "On"
_:= ${NUMBERS:On
-# expect+1: while evaluating variable "NUMBERS" with value "10 9 8 7 6 5 4 3 2 1": Unclosed expression, expecting '}' for modifier "Onr"
+# expect+1: Unclosed expression, expecting '}' for modifier "Onr"
_:= ${NUMBERS:Onr
# Shuffling numerically doesn't make sense, so don't allow 'x' and 'n' to be
# combined.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Oxn"
-# expect+1: Malformed conditional (${NUMBERS:Oxn})
+# expect+1: Bad modifier ":Oxn"
.if ${NUMBERS:Oxn}
. error
.else
@@ -43,8 +35,7 @@ _:= ${NUMBERS:Onr
# Extra characters after ':On' are detected and diagnosed.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":On_typo"
-# expect+1: Malformed conditional (${NUMBERS:On_typo})
+# expect+1: Bad modifier ":On_typo"
.if ${NUMBERS:On_typo}
. error
.else
@@ -53,8 +44,7 @@ _:= ${NUMBERS:Onr
# Extra characters after ':Onr' are detected and diagnosed.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Onr_typo"
-# expect+1: Malformed conditional (${NUMBERS:Onr_typo})
+# expect+1: Bad modifier ":Onr_typo"
.if ${NUMBERS:Onr_typo}
. error
.else
@@ -63,8 +53,7 @@ _:= ${NUMBERS:Onr
# Extra characters after ':Orn' are detected and diagnosed.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Orn_typo"
-# expect+1: Malformed conditional (${NUMBERS:Orn_typo})
+# expect+1: Bad modifier ":Orn_typo"
.if ${NUMBERS:Orn_typo}
. error
.else
@@ -75,8 +64,7 @@ _:= ${NUMBERS:Onr
# criteria are fixed, not computed, therefore allowing this redundancy does
# not make sense.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Onn"
-# expect+1: Malformed conditional (${NUMBERS:Onn})
+# expect+1: Bad modifier ":Onn"
.if ${NUMBERS:Onn}
. error
.else
@@ -85,8 +73,7 @@ _:= ${NUMBERS:Onr
# Repeating the 'r' is not supported as well, for the same reasons as above.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Onrr"
-# expect+1: Malformed conditional (${NUMBERS:Onrr})
+# expect+1: Bad modifier ":Onrr"
.if ${NUMBERS:Onrr}
. error
.else
@@ -95,8 +82,7 @@ _:= ${NUMBERS:Onr
# Repeating the 'r' is not supported as well, for the same reasons as above.
#
-# expect+2: while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2": Bad modifier ":Orrn"
-# expect+1: Malformed conditional (${NUMBERS:Orrn})
+# expect+1: Bad modifier ":Orrn"
.if ${NUMBERS:Orrn}
. error
.else
@@ -110,8 +96,7 @@ _:= ${NUMBERS:Onr
# ':H' modifier but instead replaces a trailing 'H' with 'new' in each word.
# There is no such fallback for the ':O' modifiers.
SWITCH= On
-# expect+2: while evaluating variable "SWITCH" with value "On": Bad modifier ":On=Off"
-# expect+1: Malformed conditional (${SWITCH:On=Off} != "Off")
+# expect+1: Bad modifier ":On=Off"
.if ${SWITCH:On=Off} != "Off"
. error
.else
diff --git a/unit-tests/varmod-range.exp b/unit-tests/varmod-range.exp
index 2848193e0db1..dbd50c6def80 100644
--- a/unit-tests/varmod-range.exp
+++ b/unit-tests/varmod-range.exp
@@ -1,14 +1,14 @@
-make: "varmod-range.mk" line 43: Malformed conditional (${:range=5} != "")
-make: "varmod-range.mk" line 67: while evaluating "${:U:range=x}Rest" != "Rest"" with value "": Invalid number "x}Rest" != "Rest"" for ':range' modifier
-make: "varmod-range.mk" line 67: Malformed conditional ("${:U:range=x}Rest" != "Rest")
-make: "varmod-range.mk" line 78: while evaluating "${:U:range=0x0}Rest" != "Rest"" with value "1": Unknown modifier "x0"
-make: "varmod-range.mk" line 78: Malformed conditional ("${:U:range=0x0}Rest" != "Rest")
-make: "varmod-range.mk" line 96: while evaluating variable "a b c" with value "a b c": Unknown modifier "rang"
-make: "varmod-range.mk" line 96: Malformed conditional ("${a b c:L:rang}Rest" != "Rest")
-make: "varmod-range.mk" line 105: while evaluating variable "a b c" with value "a b c": Unknown modifier "rango"
-make: "varmod-range.mk" line 105: Malformed conditional ("${a b c:L:rango}Rest" != "Rest")
-make: "varmod-range.mk" line 114: while evaluating variable "a b c" with value "a b c": Unknown modifier "ranger"
-make: "varmod-range.mk" line 114: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest")
+make: "varmod-range.mk" line 43: Malformed conditional '${:range=5} != ""'
+make: "varmod-range.mk" line 66: Invalid number "x}Rest" != "Rest"" for ':range' modifier
+ while evaluating "${:U:range=x}Rest" != "Rest"" with value ""
+make: "varmod-range.mk" line 76: Unknown modifier "x0"
+ while evaluating "${:U:range=0x0}Rest" != "Rest"" with value "1"
+make: "varmod-range.mk" line 93: Unknown modifier "rang"
+ while evaluating variable "a b c" with value "a b c"
+make: "varmod-range.mk" line 101: Unknown modifier "rango"
+ while evaluating variable "a b c" with value "a b c"
+make: "varmod-range.mk" line 109: Unknown modifier "ranger"
+ while evaluating variable "a b c" with value "a b c"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-range.mk b/unit-tests/varmod-range.mk
index 4b07b659489c..277935dc8bc7 100644
--- a/unit-tests/varmod-range.mk
+++ b/unit-tests/varmod-range.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-range.mk,v 1.13 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-range.mk,v 1.16 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the :range variable modifier, which generates sequences
# of integers from the given range.
@@ -39,7 +39,7 @@
# XXX: As of 2023-12-17, the ':range=n' modifier does not turn the undefined
# expression into a defined one, even though it does not depend on the value
# of the expression. This looks like an oversight.
-# expect+1: Malformed conditional (${:range=5} != "")
+# expect+1: Malformed conditional '${:range=5} != ""'
.if ${:range=5} != ""
. error
.else
@@ -62,8 +62,7 @@
#
# Since 2020-11-01, the parser issues a more precise "Invalid number" error
# instead.
-# expect+2: while evaluating "${:U:range=x}Rest" != "Rest"" with value "": Invalid number "x}Rest" != "Rest"" for ':range' modifier
-# expect+1: Malformed conditional ("${:U:range=x}Rest" != "Rest")
+# expect+1: Invalid number "x}Rest" != "Rest"" for ':range' modifier
.if "${:U:range=x}Rest" != "Rest"
. error
.else
@@ -73,8 +72,7 @@
# The upper limit of the range must always be given in decimal.
# This parse error stops at the 'x', trying to parse it as a variable
# modifier.
-# expect+2: while evaluating "${:U:range=0x0}Rest" != "Rest"" with value "1": Unknown modifier "x0"
-# expect+1: Malformed conditional ("${:U:range=0x0}Rest" != "Rest")
+# expect+1: Unknown modifier "x0"
.if "${:U:range=0x0}Rest" != "Rest"
. error
.else
@@ -91,8 +89,7 @@
#.endif
# modifier name too short
-# expect+2: while evaluating variable "a b c" with value "a b c": Unknown modifier "rang"
-# expect+1: Malformed conditional ("${a b c:L:rang}Rest" != "Rest")
+# expect+1: Unknown modifier "rang"
.if "${a b c:L:rang}Rest" != "Rest"
. error
.else
@@ -100,8 +97,7 @@
.endif
# misspelled modifier name
-# expect+2: while evaluating variable "a b c" with value "a b c": Unknown modifier "rango"
-# expect+1: Malformed conditional ("${a b c:L:rango}Rest" != "Rest")
+# expect+1: Unknown modifier "rango"
.if "${a b c:L:rango}Rest" != "Rest"
. error
.else
@@ -109,8 +105,7 @@
.endif
# modifier name too long
-# expect+2: while evaluating variable "a b c" with value "a b c": Unknown modifier "ranger"
-# expect+1: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest")
+# expect+1: Unknown modifier "ranger"
.if "${a b c:L:ranger}Rest" != "Rest"
. error
.else
diff --git a/unit-tests/varmod-select-words.exp b/unit-tests/varmod-select-words.exp
index c503e57b384b..7877837744ea 100644
--- a/unit-tests/varmod-select-words.exp
+++ b/unit-tests/varmod-select-words.exp
@@ -1,5 +1,6 @@
-make: in target "mod-squarebrackets-0-star-at": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[]"
-LIST:[]="" is an error
+make: Bad modifier ":[]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-empty"
LIST:[0]="one two three four five six"
LIST:[0x0]="one two three four five six"
LIST:[000]="one two three four five six"
@@ -37,18 +38,22 @@ REALLYSPACE=" "
REALLYSPACE:[1]="" == "" ?
REALLYSPACE:[*]:[1]=" " == " " ?
LIST:[1]="one"
-make: in target "mod-squarebrackets-n": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[1.]"
-LIST:[1.]="" is an error
-make: in target "mod-squarebrackets-n": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[1]."
-LIST:[1].="}" is an error
+make: Bad modifier ":[1.]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-n-error-1"
+make: Bad modifier ":[1]."
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-n-error-2"
LIST:[2]="two"
LIST:[6]="six"
LIST:[7]=""
LIST:[999]=""
-make: in target "mod-squarebrackets-n": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[-]"
-LIST:[-]="" is an error
-make: in target "mod-squarebrackets-n": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[--]"
-LIST:[--]="" is an error
+make: Bad modifier ":[-]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-n-error-3"
+make: Bad modifier ":[--]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-n-error-4"
LIST:[-1]="six"
LIST:[-2]="five"
LIST:[-6]="one"
@@ -67,23 +72,29 @@ LIST:[*]:C/ /,/:[2]=""
LIST:[*]:C/ /,/:[*]:[2]=""
LIST:[*]:C/ /,/:[@]:[2]="three"
LONGLIST:[012..0x12]="10 11 12 13 14 15 16 17 18"
-make: in target "mod-squarebrackets-start-end": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[1.]"
-LIST:[1.]="" is an error
-make: in target "mod-squarebrackets-start-end": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[1..]"
-LIST:[1..]="" is an error
-make: in target "mod-squarebrackets-start-end": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[1.. ]"
-LIST:[1.. ]="" is an error
+make: Bad modifier ":[1.]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-start-end-error-1"
+make: Bad modifier ":[1..]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-start-end-error-2"
+make: Bad modifier ":[1.. ]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-start-end-error-3"
LIST:[1..1]="one"
-make: in target "mod-squarebrackets-start-end": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[1..1.]"
-LIST:[1..1.]="" is an error
+make: Bad modifier ":[1..1.]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-start-end-error-4"
LIST:[1..2]="one two"
LIST:[2..1]="two one"
LIST:[3..-2]="three four five"
LIST:[-4..4]="three four"
-make: in target "mod-squarebrackets-start-end": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[0..1]"
-LIST:[0..1]="" is an error
-make: in target "mod-squarebrackets-start-end": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[-1..0]"
-LIST:[-1..0]="" is an error
+make: Bad modifier ":[0..1]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-start-end-error-5"
+make: Bad modifier ":[-1..0]"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-start-end-error-6"
LIST:[-1..1]="six five four three two one"
LIST:[0..0]="one two three four five six"
LIST:[3..99]="three four five six"
@@ -97,8 +108,9 @@ LIST:[${ONE}]="one"
LIST:[${MINUSONE}]="six"
LIST:[${STAR}]="one two three four five six"
LIST:[${AT}]="one two three four five six"
-make: in target "mod-squarebrackets-nested": while evaluating variable "LIST" with value "one two three four five six": Bad modifier ":[${EMPTY"
-LIST:[${EMPTY}]="" is an error
+make: Bad modifier ":[${EMPTY"
+ while evaluating variable "LIST" with value "one two three four five six"
+ in target "mod-squarebrackets-nested-error-1"
LIST:[${LONGLIST:[21]:S/2//}]="one"
LIST:[${LIST:[#]}]="six"
LIST:[${LIST:[${HASH}]}]="six"
diff --git a/unit-tests/varmod-select-words.mk b/unit-tests/varmod-select-words.mk
index 910b67a24e39..25a085891c0a 100644
--- a/unit-tests/varmod-select-words.mk
+++ b/unit-tests/varmod-select-words.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-select-words.mk,v 1.4 2022/01/23 16:09:38 rillig Exp $
+# $NetBSD: varmod-select-words.mk,v 1.6 2024/08/29 20:20:36 rillig Exp $
#
# Tests for the :[...] variable modifier, which selects a single word
# or a range of words from a variable.
@@ -24,15 +24,36 @@ ZERO= 0
ONE= 1
MINUSONE= -1
-mod-squarebrackets: mod-squarebrackets-0-star-at \
+mod-squarebrackets: \
+ mod-squarebrackets-empty \
+ mod-squarebrackets-0-star-at \
mod-squarebrackets-hash \
- mod-squarebrackets-n \
- mod-squarebrackets-start-end \
- mod-squarebrackets-nested \
+ mod-squarebrackets-n-ok-1 \
+ mod-squarebrackets-n-error-1 \
+ mod-squarebrackets-n-error-2 \
+ mod-squarebrackets-n-ok-2 \
+ mod-squarebrackets-n-error-3 \
+ mod-squarebrackets-n-error-4 \
+ mod-squarebrackets-n-ok-3 \
+ mod-squarebrackets-start-end-error-1 \
+ mod-squarebrackets-start-end-error-2 \
+ mod-squarebrackets-start-end-error-3 \
+ mod-squarebrackets-start-end-ok-1 \
+ mod-squarebrackets-start-end-error-4 \
+ mod-squarebrackets-start-end-ok-2 \
+ mod-squarebrackets-start-end-error-5 \
+ mod-squarebrackets-start-end-error-6 \
+ mod-squarebrackets-start-end-ok-3 \
+ mod-squarebrackets-nested-ok-1 \
+ mod-squarebrackets-nested-error-1 \
+ mod-squarebrackets-nested-ok-2 \
mod-squarebrackets-space
-mod-squarebrackets-0-star-at:
+mod-squarebrackets-empty:
+# expect: make: Bad modifier ":[]"
@echo 'LIST:[]="${LIST:[]}" is an error'
+
+mod-squarebrackets-0-star-at:
@echo 'LIST:[0]="${LIST:[0]}"'
@echo 'LIST:[0x0]="${LIST:[0x0]}"'
@echo 'LIST:[000]="${LIST:[000]}"'
@@ -66,7 +87,7 @@ mod-squarebrackets-hash:
@echo 'LIST:[1]:[#]="${LIST:[1]:[#]}"'
@echo 'LIST:[1..3]:[#]="${LIST:[1..3]:[#]}"'
-mod-squarebrackets-n:
+mod-squarebrackets-n-ok-1:
@echo 'EMPTY:[1]="${EMPTY:[1]}"'
@echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
@echo 'ESCAPEDSPACE:[1]="${ESCAPEDSPACE:[1]}"'
@@ -74,14 +95,24 @@ mod-squarebrackets-n:
@echo 'REALLYSPACE:[1]="${REALLYSPACE:[1]}" == "" ?'
@echo 'REALLYSPACE:[*]:[1]="${REALLYSPACE:[*]:[1]}" == " " ?'
@echo 'LIST:[1]="${LIST:[1]}"'
+mod-squarebrackets-n-error-1:
+# expect: make: Bad modifier ":[1.]"
@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+mod-squarebrackets-n-error-2:
+# expect: make: Bad modifier ":[1]."
@echo 'LIST:[1].="${LIST:[1].}" is an error'
+mod-squarebrackets-n-ok-2:
@echo 'LIST:[2]="${LIST:[2]}"'
@echo 'LIST:[6]="${LIST:[6]}"'
@echo 'LIST:[7]="${LIST:[7]}"'
@echo 'LIST:[999]="${LIST:[999]}"'
+mod-squarebrackets-n-error-3:
+# expect: make: Bad modifier ":[-]"
@echo 'LIST:[-]="${LIST:[-]}" is an error'
+mod-squarebrackets-n-error-4:
+# expect: make: Bad modifier ":[--]"
@echo 'LIST:[--]="${LIST:[--]}" is an error'
+mod-squarebrackets-n-ok-3:
@echo 'LIST:[-1]="${LIST:[-1]}"'
@echo 'LIST:[-2]="${LIST:[-2]}"'
@echo 'LIST:[-6]="${LIST:[-6]}"'
@@ -101,25 +132,39 @@ mod-squarebrackets-n:
@echo 'LIST:[*]:C/ /,/:[@]:[2]="${LIST:[*]:C/ /,/:[@]:[2]}"'
@echo 'LONGLIST:[012..0x12]="${LONGLIST:[012..0x12]}"'
-mod-squarebrackets-start-end:
+mod-squarebrackets-start-end-error-1:
+# expect: make: Bad modifier ":[1.]"
@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+mod-squarebrackets-start-end-error-2:
+# expect: make: Bad modifier ":[1..]"
@echo 'LIST:[1..]="${LIST:[1..]}" is an error'
+mod-squarebrackets-start-end-error-3:
+# expect: make: Bad modifier ":[1.. ]"
@echo 'LIST:[1.. ]="${LIST:[1.. ]}" is an error'
+mod-squarebrackets-start-end-ok-1:
@echo 'LIST:[1..1]="${LIST:[1..1]}"'
+mod-squarebrackets-start-end-error-4:
+# expect: make: Bad modifier ":[1..1.]"
@echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'
+mod-squarebrackets-start-end-ok-2:
@echo 'LIST:[1..2]="${LIST:[1..2]}"'
@echo 'LIST:[2..1]="${LIST:[2..1]}"'
@echo 'LIST:[3..-2]="${LIST:[3..-2]}"'
@echo 'LIST:[-4..4]="${LIST:[-4..4]}"'
+mod-squarebrackets-start-end-error-5:
+# expect: make: Bad modifier ":[0..1]"
@echo 'LIST:[0..1]="${LIST:[0..1]}" is an error'
+mod-squarebrackets-start-end-error-6:
+# expect: make: Bad modifier ":[-1..0]"
@echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error'
+mod-squarebrackets-start-end-ok-3:
@echo 'LIST:[-1..1]="${LIST:[-1..1]}"'
@echo 'LIST:[0..0]="${LIST:[0..0]}"'
@echo 'LIST:[3..99]="${LIST:[3..99]}"'
@echo 'LIST:[-3..-99]="${LIST:[-3..-99]}"'
@echo 'LIST:[-99..-3]="${LIST:[-99..-3]}"'
-mod-squarebrackets-nested:
+mod-squarebrackets-nested-ok-1:
@echo 'HASH="${HASH}" == "#" ?'
@echo 'LIST:[$${HASH}]="${LIST:[${HASH}]}"'
@echo 'LIST:[$${ZERO}]="${LIST:[${ZERO}]}"'
@@ -128,7 +173,10 @@ mod-squarebrackets-nested:
@echo 'LIST:[$${MINUSONE}]="${LIST:[${MINUSONE}]}"'
@echo 'LIST:[$${STAR}]="${LIST:[${STAR}]}"'
@echo 'LIST:[$${AT}]="${LIST:[${AT}]}"'
+mod-squarebrackets-nested-error-1:
+# expect: make: Bad modifier ":[${EMPTY"
@echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error'
+mod-squarebrackets-nested-ok-2:
@echo 'LIST:[$${LONGLIST:[21]:S/2//}]="${LIST:[${LONGLIST:[21]:S/2//}]}"'
@echo 'LIST:[$${LIST:[#]}]="${LIST:[${LIST:[#]}]}"'
@echo 'LIST:[$${LIST:[$${HASH}]}]="${LIST:[${LIST:[${HASH}]}]}"'
diff --git a/unit-tests/varmod-shell.exp b/unit-tests/varmod-shell.exp
index 6ada8f74d75e..b2c6c59eea40 100644
--- a/unit-tests/varmod-shell.exp
+++ b/unit-tests/varmod-shell.exp
@@ -1,11 +1,11 @@
-make: "varmod-shell.mk" line 25: warning: while evaluating "${:!echo word; (exit 13)!} != "word"" with value "word": Command "echo word; (exit 13)" exited with status 13
-make: "varmod-shell.mk" line 29: warning: while evaluating "${:Uprevious value:!echo word; (exit 13)!} != "word"" with value "word": Command "echo word; (exit 13)" exited with status 13
+make: "varmod-shell.mk" line 25: warning: Command "echo word; (exit 13)" exited with status 13
+make: "varmod-shell.mk" line 29: warning: Command "echo word; (exit 13)" exited with status 13
Global: _ = # (empty)
Var_Parse: ${:!echo word; ${:U(exit 13)}!} (eval-keep-dollar-and-undefined)
Evaluating modifier ${:!...} on value "" (eval-keep-dollar-and-undefined, undefined)
Modifier part: "echo word; (exit 13)"
Capturing the output of command "echo word; (exit 13)"
-make: "varmod-shell.mk" line 36: warning: while evaluating "${:!echo word; ${:U(exit 13)}!}" with value "word": Command "echo word; (exit 13)" exited with status 13
+make: "varmod-shell.mk" line 36: warning: Command "echo word; (exit 13)" exited with status 13
Result of ${:!echo word; ${:U(exit 13)}!} is "word" (eval-keep-dollar-and-undefined, defined)
Global: _ = word
Global: .MAKEFLAGS = -r -k -d v -d
diff --git a/unit-tests/varmod-shell.mk b/unit-tests/varmod-shell.mk
index 87918c5bbbf6..5f614d0c7f3c 100644
--- a/unit-tests/varmod-shell.mk
+++ b/unit-tests/varmod-shell.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-shell.mk,v 1.10 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-shell.mk,v 1.11 2024/08/29 20:20:37 rillig Exp $
#
# Tests for the ':!cmd!' variable modifier, which runs the shell command
# given by the variable modifier and returns its output.
@@ -21,18 +21,18 @@
# Between 2000-04-29 and 2020-11-17, the error message mentioned the previous
# value of the expression (which is usually an empty string) instead of the
# command that was executed.
-# expect+1: warning: while evaluating "${:!echo word; (exit 13)!} != "word"" with value "word": Command "echo word; (exit 13)" exited with status 13
+# expect+1: warning: Command "echo word; (exit 13)" exited with status 13
.if ${:!echo word; (exit 13)!} != "word"
. error
.endif
-# expect+1: warning: while evaluating "${:Uprevious value:!echo word; (exit 13)!} != "word"" with value "word": Command "echo word; (exit 13)" exited with status 13
+# expect+1: warning: Command "echo word; (exit 13)" exited with status 13
.if ${:Uprevious value:!echo word; (exit 13)!} != "word"
. error
.endif
.MAKEFLAGS: -dv # to see the "Capturing" debug output
-# expect+1: warning: while evaluating "${:!echo word; ${:U(exit 13)}!}" with value "word": Command "echo word; (exit 13)" exited with status 13
+# expect+1: warning: Command "echo word; (exit 13)" exited with status 13
_:= ${:!echo word; ${:U(exit 13)}!}
.MAKEFLAGS: -d0
diff --git a/unit-tests/varmod-subst-regex.exp b/unit-tests/varmod-subst-regex.exp
index 722abdff5813..98c37f6fd8e7 100644
--- a/unit-tests/varmod-subst-regex.exp
+++ b/unit-tests/varmod-subst-regex.exp
@@ -1,27 +1,52 @@
-make: in target "mod-regex-compile-error": while evaluating "${:Uword1 word2:C,****,____,g:C,word,____,:Q}." with value "word1 word2": Regex compilation error: (details omitted)
-mod-regex-compile-error: C,word,____,:Q}.
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456": No subexpression \1
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456": No subexpression \1
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456": No subexpression \1
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456": No subexpression \1
-mod-regex-limits:11-missing:1 6
-mod-regex-limits:11-ok:1 22 446
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456": No subexpression \2
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456": No subexpression \2
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456": No subexpression \2
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456": No subexpression \2
-mod-regex-limits:22-missing:1 6
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456": No subexpression \2
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456": No subexpression \2
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456": No subexpression \2
-make: in target "mod-regex-limits": while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456": No subexpression \2
-mod-regex-limits:22-missing:1 6
-mod-regex-limits:22-ok:1 33 556
-mod-regex-limits:capture:ihgfedcbaabcdefghijABCDEFGHIJa0a1a2rest
-make: in target "mod-regex-errors": while evaluating variable "UNDEF" with value "value": Regex compilation error: (details omitted)
-mod-regex-errors:
-make: in target "mod-regex-errors": while evaluating variable "word" with value "word": while evaluating "${:U:Z}y,W}" with value "": Unknown modifier "Z"
-mod-regex-errors: xy
+make: Regex compilation error: (details omitted)
+ while evaluating "${:Uword1 word2:C,****,____,g:C,word,____,:Q}." with value "word1 word2"
+ in target "mod-regex-compile-error"
+make: No subexpression \1
+ while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-1"
+make: No subexpression \1
+ while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-1"
+make: No subexpression \1
+ while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-1"
+make: No subexpression \1
+ while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-1"
+mod-regex-limits-2:11-ok:1 22 446
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-3"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-3"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-3"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-3"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-4"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-4"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-4"
+make: No subexpression \2
+ while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456"
+ in target "mod-regex-limits-4"
+mod-regex-limits-5:22-ok:1 33 556
+mod-regex-limits-6:capture:ihgfedcbaabcdefghijABCDEFGHIJa0a1a2rest
+make: Regex compilation error: (details omitted)
+ while evaluating variable "UNDEF" with value "value"
+ in target "mod-regex-errors-1"
+make: Unknown modifier "Z"
+ while evaluating "${:U:Z}y,W}" with value ""
+ while evaluating variable "word" with value "word"
+ in target "mod-regex-errors-2"
unmatched-subexpression.ok: one one 2 3 5 8 one3 2one 34
make: No match for subexpression \2
unmatched-subexpression.1: ()()
diff --git a/unit-tests/varmod-subst-regex.mk b/unit-tests/varmod-subst-regex.mk
index c1ffc4580d3a..bc04bc5fffb9 100644
--- a/unit-tests/varmod-subst-regex.mk
+++ b/unit-tests/varmod-subst-regex.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-subst-regex.mk,v 1.11 2023/12/18 11:13:51 rillig Exp $
+# $NetBSD: varmod-subst-regex.mk,v 1.12 2024/07/20 11:05:12 rillig Exp $
#
# Tests for the :C,from,to, variable modifier.
@@ -6,8 +6,8 @@
.MAKEFLAGS: -dL
all: mod-regex-compile-error
-all: mod-regex-limits
-all: mod-regex-errors
+all: mod-regex-limits-{1,2,3,4,5,6}
+all: mod-regex-errors-{1,2}
all: unmatched-subexpression
# The expression expands to 4 words. Of these words, none matches
@@ -139,19 +139,25 @@ mod-regex-compile-error:
# These tests generate error messages but as of 2020-08-28 just continue
# parsing and execution as if nothing bad had happened.
-mod-regex-limits:
+mod-regex-limits-1:
@echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q}
+mod-regex-limits-2:
@echo $@:11-ok:${:U1 23 456:C,(.).,\1\1,:Q}
+mod-regex-limits-3:
@echo $@:22-missing:${:U1 23 456:C,..,\2\2,:Q}
+mod-regex-limits-4:
@echo $@:22-missing:${:U1 23 456:C,(.).,\2\2,:Q}
+mod-regex-limits-5:
@echo $@:22-ok:${:U1 23 456:C,(.)(.),\2\2,:Q}
+mod-regex-limits-6:
# The :C modifier only handles single-digit capturing groups,
# which is enough for all practical use cases.
@echo $@:capture:${:UabcdefghijABCDEFGHIJrest:C,(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.),\9\8\7\6\5\4\3\2\1\0\10\11\12,}
-mod-regex-errors:
+mod-regex-errors-1:
@echo $@: ${UNDEF:Uvalue:C,[,,}
+mod-regex-errors-2:
# If the replacement pattern produces a parse error because of an
# unknown modifier, the parse error is ignored in ParseModifierPart
# and the faulty expression expands to "".
diff --git a/unit-tests/varmod-subst.exp b/unit-tests/varmod-subst.exp
index 9b91c0e50857..1547201bb404 100644
--- a/unit-tests/varmod-subst.exp
+++ b/unit-tests/varmod-subst.exp
@@ -45,8 +45,9 @@ mod-subst-delimiter:
1 two 3 tilde
mod-subst-chain:
A B c.
-make: in target "mod-subst-chain": while evaluating "${:Uvalue:S,a,x,i}." with value "vxlue": Unknown modifier "i"
-.
+make: Unknown modifier "i"
+ while evaluating "${:Uvalue:S,a,x,i}." with value "vxlue"
+ in target "mod-subst-chain"
mod-subst-dollar:$1:
mod-subst-dollar:$2:
mod-subst-dollar:$3:
diff --git a/unit-tests/varmod-subst.mk b/unit-tests/varmod-subst.mk
index 2903d36445f8..34f20a5f96f2 100644
--- a/unit-tests/varmod-subst.mk
+++ b/unit-tests/varmod-subst.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-subst.mk,v 1.14 2023/12/18 11:13:51 rillig Exp $
+# $NetBSD: varmod-subst.mk,v 1.16 2024/08/29 20:20:37 rillig Exp $
#
# Tests for the :S,from,to, variable modifier.
@@ -252,6 +252,7 @@ mod-subst-chain:
# The error message is "make: Unknown modifier 'i'", which is
# kind of correct, although it is mixing the terms for variable
# modifiers with the matching modifiers.
+# expect: make: Unknown modifier "i"
@echo ${:Uvalue:S,a,x,i}.
# No matter how many dollar signs there are, they all get merged
diff --git a/unit-tests/varmod-sun-shell.exp b/unit-tests/varmod-sun-shell.exp
index 80dec0935f28..5a557b97cec8 100644
--- a/unit-tests/varmod-sun-shell.exp
+++ b/unit-tests/varmod-sun-shell.exp
@@ -1,11 +1,11 @@
-make: "varmod-sun-shell.mk" line 17: warning: while evaluating variable "echo word; (exit 13)" with value "echo word; (exit 13)": Command "echo word; (exit 13)" exited with status 13
+make: "varmod-sun-shell.mk" line 17: warning: Command "echo word; (exit 13)" exited with status 13
Global: _ = # (empty)
Var_Parse: ${echo word; ${:U(exit 13)}:L:sh} (eval-keep-dollar-and-undefined)
Evaluating modifier ${echo word; (exit 13):L} on value "" (eval-keep-dollar-and-undefined, undefined)
Result of ${echo word; (exit 13):L} is "echo word; (exit 13)" (eval-keep-dollar-and-undefined, defined)
Evaluating modifier ${echo word; (exit 13):s...} on value "echo word; (exit 13)" (eval-keep-dollar-and-undefined, defined)
Capturing the output of command "echo word; (exit 13)"
-make: "varmod-sun-shell.mk" line 24: warning: while evaluating variable "echo word; (exit 13)" with value "echo word; (exit 13)": Command "echo word; (exit 13)" exited with status 13
+make: "varmod-sun-shell.mk" line 24: warning: Command "echo word; (exit 13)" exited with status 13
Result of ${echo word; (exit 13):sh} is "word" (eval-keep-dollar-and-undefined, defined)
Global: _ = word
Global: .MAKEFLAGS = -r -k -d v -d
diff --git a/unit-tests/varmod-sun-shell.mk b/unit-tests/varmod-sun-shell.mk
index 4a37a271eced..8f6a5bc4cc05 100644
--- a/unit-tests/varmod-sun-shell.mk
+++ b/unit-tests/varmod-sun-shell.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-sun-shell.mk,v 1.5 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: varmod-sun-shell.mk,v 1.6 2024/08/29 20:20:37 rillig Exp $
#
# Tests for the :sh variable modifier, which runs the shell command
# given by the variable value and returns its output.
@@ -13,14 +13,14 @@
.endif
# If the command exits with non-zero, a warning is printed.
-# expect+1: warning: while evaluating variable "echo word; (exit 13)" with value "echo word; (exit 13)": Command "echo word; (exit 13)" exited with status 13
+# expect+1: warning: Command "echo word; (exit 13)" exited with status 13
.if ${echo word; (exit 13):L:sh} != "word"
. error
.endif
.MAKEFLAGS: -dv # to see the "Capturing" debug output
-# expect+1: warning: while evaluating variable "echo word; (exit 13)" with value "echo word; (exit 13)": Command "echo word; (exit 13)" exited with status 13
+# expect+1: warning: Command "echo word; (exit 13)" exited with status 13
_:= ${echo word; ${:U(exit 13)}:L:sh}
.MAKEFLAGS: -d0
diff --git a/unit-tests/varmod-sysv.exp b/unit-tests/varmod-sysv.exp
index be87193b4066..ecda358758e1 100644
--- a/unit-tests/varmod-sysv.exp
+++ b/unit-tests/varmod-sysv.exp
@@ -1,5 +1,5 @@
-make: "varmod-sysv.mk" line 216: while evaluating variable "word216" with value "word216": Unfinished modifier ('=' missing)
-make: "varmod-sysv.mk" line 216: Malformed conditional (${word216:L:from${:D=}to})
+make: "varmod-sysv.mk" line 215: Unfinished modifier ('=' missing)
+ while evaluating variable "word216" with value "word216"
word modifier result
'' = ""
suffix = "suffix"
@@ -145,8 +145,8 @@ pre-middle-suffix pre%ffix=NPre% "NPre-middle-su"
suffix pre%ffix=NPre%NS "suffix"
prefix pre%ffix=NPre%NS "prefix"
pre-middle-suffix pre%ffix=NPre%NS "NPre-middle-suNS"
-make: "varmod-sysv.mk" line 261: while evaluating variable "error" with value "error": Unfinished modifier ('}' missing)
-make: "varmod-sysv.mk" line 261: Malformed conditional (${error:L:from=$(}))
+make: "varmod-sysv.mk" line 259: Unfinished modifier ('}' missing)
+ while evaluating variable "error" with value "error"
make: Fatal errors encountered -- cannot continue
make: stopped making "all" in unit-tests
exit status 1
diff --git a/unit-tests/varmod-sysv.mk b/unit-tests/varmod-sysv.mk
index 8db41d7fb364..f7d7a1ffe81a 100644
--- a/unit-tests/varmod-sysv.mk
+++ b/unit-tests/varmod-sysv.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-sysv.mk,v 1.19 2024/07/04 17:47:54 rillig Exp $
+# $NetBSD: varmod-sysv.mk,v 1.22 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the variable modifier ':from=to', which replaces the suffix
# "from" with "to". It can also use '%' as a wildcard.
@@ -211,8 +211,7 @@
# XXX: As of 2024-06-30, this expression generates an "Unfinished modifier"
# error, while the correct error message would be "Unknown modifier" since
# there is no modifier named "fromto".
-# expect+2: while evaluating variable "word216" with value "word216": Unfinished modifier ('=' missing)
-# expect+1: Malformed conditional (${word216:L:from${:D=}to})
+# expect+1: Unfinished modifier ('=' missing)
.if ${word216:L:from${:D=}to}
. error
.endif
@@ -256,8 +255,7 @@ INDIRECT= 1:${VALUE} 2:$${VALUE} 4:$$$${VALUE}
# The error case of an unfinished ':from=to' modifier after the '=' requires
# an expression that is missing the closing '}'.
-# expect+2: while evaluating variable "error" with value "error": Unfinished modifier ('}' missing)
-# expect+1: Malformed conditional (${error:L:from=$(}))
+# expect+1: Unfinished modifier ('}' missing)
.if ${error:L:from=$(})
.endif
diff --git a/unit-tests/varmod-to-separator.exp b/unit-tests/varmod-to-separator.exp
index fe61ada505df..368def5f7ffe 100644
--- a/unit-tests/varmod-to-separator.exp
+++ b/unit-tests/varmod-to-separator.exp
@@ -1,29 +1,29 @@
-make: "varmod-to-separator.mk" line 155: while evaluating variable "WORDS" with value "one two three": Invalid character number at "400:tu}"
-make: "varmod-to-separator.mk" line 155: Malformed conditional (${WORDS:[1..3]:ts\400:tu})
-make: "varmod-to-separator.mk" line 171: while evaluating variable "WORDS" with value "one two three": Invalid character number at "100:tu}"
-make: "varmod-to-separator.mk" line 171: Malformed conditional (${WORDS:[1..3]:ts\x100:tu})
-make: "varmod-to-separator.mk" line 180: while evaluating variable "word" with value "word": Invalid character number at ",}"
-make: "varmod-to-separator.mk" line 180: Malformed conditional (${word:L:ts\x,})
-make: "varmod-to-separator.mk" line 187: while evaluating variable "word" with value "word": Invalid character number at "112233445566778899}"
-make: "varmod-to-separator.mk" line 187: Malformed conditional (${word:L:ts\x112233445566778899})
-make: "varmod-to-separator.mk" line 193: while evaluating variable "WORDS" with value "one two three": Bad modifier ":ts\-300"
-make: "varmod-to-separator.mk" line 193: Malformed conditional (${WORDS:[1..3]:ts\-300:tu})
-make: "varmod-to-separator.mk" line 203: while evaluating variable "1 2 3" with value "1 2 3": Bad modifier ":ts\8"
-make: "varmod-to-separator.mk" line 203: Malformed conditional (${1 2 3:L:ts\8:tu})
-make: "varmod-to-separator.mk" line 212: while evaluating variable "1 2 3" with value "1 2 3": Bad modifier ":ts\100L"
-make: "varmod-to-separator.mk" line 212: Malformed conditional (${1 2 3:L:ts\100L})
-make: "varmod-to-separator.mk" line 221: while evaluating variable "1 2 3" with value "1 2 3": Bad modifier ":ts\x40g"
-make: "varmod-to-separator.mk" line 221: Malformed conditional (${1 2 3:L:ts\x40g})
-make: "varmod-to-separator.mk" line 231: while evaluating variable "WORDS" with value "one two three four five six": Bad modifier ":tx"
-make: "varmod-to-separator.mk" line 231: Malformed conditional (${WORDS:tx})
-make: "varmod-to-separator.mk" line 240: while evaluating variable "WORDS" with value "one two three four five six": Bad modifier ":ts\X"
-make: "varmod-to-separator.mk" line 240: Malformed conditional (${WORDS:ts\X})
-make: "varmod-to-separator.mk" line 250: while evaluating variable "WORDS" with value "one two three four five six": Bad modifier ":t\X"
-make: "varmod-to-separator.mk" line 250: Malformed conditional (${WORDS:t\X} != "anything")
-make: "varmod-to-separator.mk" line 267: while evaluating "${:Ua b:ts\69}" with value "a b": Bad modifier ":ts\69"
-make: "varmod-to-separator.mk" line 267: Malformed conditional (${:Ua b:ts\69})
-make: "varmod-to-separator.mk" line 276: while evaluating "${:Ua b:ts\x1F60E}" with value "a b": Invalid character number at "1F60E}"
-make: "varmod-to-separator.mk" line 276: Malformed conditional (${:Ua b:ts\x1F60E})
+make: "varmod-to-separator.mk" line 154: Invalid character number at "400:tu}"
+ while evaluating variable "WORDS" with value "one two three"
+make: "varmod-to-separator.mk" line 169: Invalid character number at "100:tu}"
+ while evaluating variable "WORDS" with value "one two three"
+make: "varmod-to-separator.mk" line 177: Invalid character number at ",}"
+ while evaluating variable "word" with value "word"
+make: "varmod-to-separator.mk" line 183: Invalid character number at "112233445566778899}"
+ while evaluating variable "word" with value "word"
+make: "varmod-to-separator.mk" line 188: Bad modifier ":ts\-300"
+ while evaluating variable "WORDS" with value "one two three"
+make: "varmod-to-separator.mk" line 197: Bad modifier ":ts\8"
+ while evaluating variable "1 2 3" with value "1 2 3"
+make: "varmod-to-separator.mk" line 205: Bad modifier ":ts\100L"
+ while evaluating variable "1 2 3" with value "1 2 3"
+make: "varmod-to-separator.mk" line 213: Bad modifier ":ts\x40g"
+ while evaluating variable "1 2 3" with value "1 2 3"
+make: "varmod-to-separator.mk" line 222: Bad modifier ":tx"
+ while evaluating variable "WORDS" with value "one two three four five six"
+make: "varmod-to-separator.mk" line 230: Bad modifier ":ts\X"
+ while evaluating variable "WORDS" with value "one two three four five six"
+make: "varmod-to-separator.mk" line 239: Bad modifier ":t\X"
+ while evaluating variable "WORDS" with value "one two three four five six"
+make: "varmod-to-separator.mk" line 255: Bad modifier ":ts\69"
+ while evaluating "${:Ua b:ts\69}" with value "a b"
+make: "varmod-to-separator.mk" line 263: Invalid character number at "1F60E}"
+ while evaluating "${:Ua b:ts\x1F60E}" with value "a b"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varmod-to-separator.mk b/unit-tests/varmod-to-separator.mk
index b4c6839a0a2b..5cb838bf5bb7 100644
--- a/unit-tests/varmod-to-separator.mk
+++ b/unit-tests/varmod-to-separator.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-to-separator.mk,v 1.18 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod-to-separator.mk,v 1.21 2025/01/11 20:54:46 rillig Exp $
#
# Tests for the :ts variable modifier, which joins the words of the variable
# using an arbitrary character as word separator.
@@ -150,8 +150,7 @@ WORDS= one two three four five six
# for an unsigned character though.
#
# Since 2020-11-01, these out-of-bounds values are rejected.
-# expect+2: while evaluating variable "WORDS" with value "one two three": Invalid character number at "400:tu}"
-# expect+1: Malformed conditional (${WORDS:[1..3]:ts\400:tu})
+# expect+1: Invalid character number at "400:tu}"
.if ${WORDS:[1..3]:ts\400:tu}
. warning The separator \400 is accepted even though it is out of bounds.
.else
@@ -166,8 +165,7 @@ WORDS= one two three four five six
# The hexadecimal number must be in the range of an unsigned char.
#
# Since 2020-11-01, these out-of-bounds values are rejected.
-# expect+2: while evaluating variable "WORDS" with value "one two three": Invalid character number at "100:tu}"
-# expect+1: Malformed conditional (${WORDS:[1..3]:ts\x100:tu})
+# expect+1: Invalid character number at "100:tu}"
.if ${WORDS:[1..3]:ts\x100:tu}
. warning The separator \x100 is accepted even though it is out of bounds.
.else
@@ -175,21 +173,18 @@ WORDS= one two three four five six
.endif
# The number after ':ts\x' must be hexadecimal.
-# expect+2: while evaluating variable "word" with value "word": Invalid character number at ",}"
-# expect+1: Malformed conditional (${word:L:ts\x,})
+# expect+1: Invalid character number at ",}"
.if ${word:L:ts\x,}
.endif
# The hexadecimal number must be in the range of 'unsigned long' on all
# supported platforms.
-# expect+2: while evaluating variable "word" with value "word": Invalid character number at "112233445566778899}"
-# expect+1: Malformed conditional (${word:L:ts\x112233445566778899})
+# expect+1: Invalid character number at "112233445566778899}"
.if ${word:L:ts\x112233445566778899}
.endif
# Negative numbers are not allowed for the separator character.
-# expect+2: while evaluating variable "WORDS" with value "one two three": Bad modifier ":ts\-300"
-# expect+1: Malformed conditional (${WORDS:[1..3]:ts\-300:tu})
+# expect+1: Bad modifier ":ts\-300"
.if ${WORDS:[1..3]:ts\-300:tu}
. warning The separator \-300 is accepted even though it is negative.
.else
@@ -198,8 +193,7 @@ WORDS= one two three four five six
# The character number is interpreted as octal number by default.
# The digit '8' is not an octal digit though.
-# expect+2: while evaluating variable "1 2 3" with value "1 2 3": Bad modifier ":ts\8"
-# expect+1: Malformed conditional (${1 2 3:L:ts\8:tu})
+# expect+1: Bad modifier ":ts\8"
.if ${1 2 3:L:ts\8:tu}
. warning The separator \8 is accepted even though it is not octal.
.else
@@ -207,8 +201,7 @@ WORDS= one two three four five six
.endif
# Trailing characters after the octal character number are rejected.
-# expect+2: while evaluating variable "1 2 3" with value "1 2 3": Bad modifier ":ts\100L"
-# expect+1: Malformed conditional (${1 2 3:L:ts\100L})
+# expect+1: Bad modifier ":ts\100L"
.if ${1 2 3:L:ts\100L}
. warning The separator \100L is accepted even though it contains an 'L'.
.else
@@ -216,8 +209,7 @@ WORDS= one two three four five six
.endif
# Trailing characters after the hexadecimal character number are rejected.
-# expect+2: while evaluating variable "1 2 3" with value "1 2 3": Bad modifier ":ts\x40g"
-# expect+1: Malformed conditional (${1 2 3:L:ts\x40g})
+# expect+1: Bad modifier ":ts\x40g"
.if ${1 2 3:L:ts\x40g}
. warning The separator \x40g is accepted even though it contains a 'g'.
.else
@@ -226,8 +218,7 @@ WORDS= one two three four five six
# In the :t modifier, the :t must be followed by any of A, l, s, u.
-# expect+2: while evaluating variable "WORDS" with value "one two three four five six": Bad modifier ":tx"
-# expect+1: Malformed conditional (${WORDS:tx})
+# expect+1: Bad modifier ":tx"
.if ${WORDS:tx}
. error
.else
@@ -235,8 +226,7 @@ WORDS= one two three four five six
.endif
# The word separator can only be a single character.
-# expect+2: while evaluating variable "WORDS" with value "one two three four five six": Bad modifier ":ts\X"
-# expect+1: Malformed conditional (${WORDS:ts\X})
+# expect+1: Bad modifier ":ts\X"
.if ${WORDS:ts\X}
. error
.else
@@ -245,8 +235,7 @@ WORDS= one two three four five six
# After the backslash, only n, t, an octal number, or x and a hexadecimal
# number are allowed.
-# expect+2: while evaluating variable "WORDS" with value "one two three four five six": Bad modifier ":t\X"
-# expect+1: Malformed conditional (${WORDS:t\X} != "anything")
+# expect+1: Bad modifier ":t\X"
.if ${WORDS:t\X} != "anything"
. info This line is not reached.
.endif
@@ -262,8 +251,7 @@ WORDS= one two three four five six
# happens for non-octal digits. From 2003.07.23.18.06.46 to
# 2016.02.27.16.20.06, the result was '1E2', since 2016.03.07.20.20.35 make no
# longer accepts this escape and complains.
-# expect+2: while evaluating "${:Ua b:ts\69}" with value "a b": Bad modifier ":ts\69"
-# expect+1: Malformed conditional (${:Ua b:ts\69})
+# expect+1: Bad modifier ":ts\69"
.if ${:Ua b:ts\69}
. error
.else
@@ -271,8 +259,7 @@ WORDS= one two three four five six
.endif
# Try whether bmake is Unicode-ready.
-# expect+2: while evaluating "${:Ua b:ts\x1F60E}" with value "a b": Invalid character number at "1F60E}"
-# expect+1: Malformed conditional (${:Ua b:ts\x1F60E})
+# expect+1: Invalid character number at "1F60E}"
.if ${:Ua b:ts\x1F60E} # U+1F60E "smiling face with sunglasses"
. error
.else
diff --git a/unit-tests/varmod.exp b/unit-tests/varmod.exp
index 0948b585a477..91968a7f310f 100644
--- a/unit-tests/varmod.exp
+++ b/unit-tests/varmod.exp
@@ -1,33 +1,44 @@
make: "varmod.mk" line 101: To escape a dollar, use \$, not $$, at "$$:L} != """
make: "varmod.mk" line 101: Invalid variable name ':', at "$:L} != """
-make: "varmod.mk" line 107: while evaluating "${:Uword:@word@${word}$@} != "word"" with value "word": Dollar followed by nothing
-make: "varmod.mk" line 117: while evaluating variable "VAR" with value "VAR": Missing delimiter ':' after modifier "P"
+make: "varmod.mk" line 107: Dollar followed by nothing
+ while evaluating "${:Uword:@word@${word}$@} != "word"" with value "word"
+make: "varmod.mk" line 117: Missing delimiter ':' after modifier "P"
+ while evaluating variable "VAR" with value "VAR"
make: "varmod.mk" line 119: Missing argument for ".error"
-make: "varmod.mk" line 126: while evaluating variable "word" with value "word": Bad modifier ":[99333000222000111000]"
-make: "varmod.mk" line 126: Malformed conditional (${word:L:[99333000222000111000]})
-make: "varmod.mk" line 130: while evaluating variable "word" with value "word": Bad modifier ":[2147483648]"
-make: "varmod.mk" line 130: Malformed conditional (${word:L:[2147483648]})
-make: "varmod.mk" line 137: while evaluating variable "word" with value "word": Invalid number "99333000222000111000}" for ':range' modifier
-make: "varmod.mk" line 137: Malformed conditional (${word:L:range=99333000222000111000})
-make: "varmod.mk" line 145: while evaluating "${:${:Ugmtime=\\}}" with value "": Invalid time value "\"
-make: "varmod.mk" line 145: Malformed conditional (${:${:Ugmtime=\\}})
-make: "varmod.mk" line 160: while evaluating variable "VAR" with value "value$": Dollar followed by nothing
-make: "varmod.mk" line 166: while evaluating variable "VAR" with value "value$": Dollar followed by nothing
-make: "varmod.mk" line 166: while evaluating variable "VAR" with value "value$ appended$": Dollar followed by nothing
-make: "varmod.mk" line 176: while evaluating variable "word" with value "word": Dollar followed by nothing
-make: "varmod.mk" line 181: while evaluating variable "word" with value "": Bad modifier ":[$]"
-make: "varmod.mk" line 181: Malformed conditional (${word:[$]})
-make: "varmod.mk" line 198: while evaluating variable "VAR" with value "value$ appended$": Dollar followed by nothing
-make: "varmod.mk" line 198: while evaluating variable "VAR" with value "value<space>appended": Invalid variable name '}', at "$} != "set""
-make: "varmod.mk" line 202: while evaluating "${:Ufallback$} != "fallback"" with value "": Invalid variable name '}', at "$} != "fallback""
-make: "varmod.mk" line 207: while evaluating variable "%y" with value "%y": Invalid time value "1000$"
-make: "varmod.mk" line 207: Malformed conditional (${%y:L:gmtime=1000$})
-make: "varmod.mk" line 214: while evaluating variable "%y" with value "%y": Invalid time value "1000$"
-make: "varmod.mk" line 214: Malformed conditional (${%y:L:localtime=1000$})
-make: "varmod.mk" line 220: while evaluating variable "word" with value "word": Dollar followed by nothing
-make: "varmod.mk" line 224: while evaluating variable "word" with value "word": Dollar followed by nothing
-make: "varmod.mk" line 229: while evaluating variable "." with value ".": Invalid argument 'fallback$' for modifier ':mtime'
-make: "varmod.mk" line 229: Malformed conditional (${.:L:mtime=fallback$})
+make: "varmod.mk" line 125: Bad modifier ":[99333000222000111000]"
+ while evaluating variable "word" with value "word"
+make: "varmod.mk" line 128: Bad modifier ":[2147483648]"
+ while evaluating variable "word" with value "word"
+make: "varmod.mk" line 134: Invalid number "99333000222000111000}" for ':range' modifier
+ while evaluating variable "word" with value "word"
+make: "varmod.mk" line 141: Invalid time value "\"
+ while evaluating "${:${:Ugmtime=\\}}" with value ""
+make: "varmod.mk" line 156: Dollar followed by nothing
+ while evaluating variable "VAR" with value "value$"
+make: "varmod.mk" line 162: Dollar followed by nothing
+ while evaluating variable "VAR" with value "value$"
+make: "varmod.mk" line 162: Dollar followed by nothing
+ while evaluating variable "VAR" with value "value$ appended$"
+make: "varmod.mk" line 172: Dollar followed by nothing
+ while evaluating variable "word" with value "word"
+make: "varmod.mk" line 176: Bad modifier ":[$]"
+ while evaluating variable "word" with value ""
+make: "varmod.mk" line 193: Dollar followed by nothing
+ while evaluating variable "VAR" with value "value$ appended$"
+make: "varmod.mk" line 193: Invalid variable name '}', at "$} != "set""
+ while evaluating variable "VAR" with value "value<space>appended"
+make: "varmod.mk" line 197: Invalid variable name '}', at "$} != "fallback""
+ while evaluating "${:Ufallback$} != "fallback"" with value ""
+make: "varmod.mk" line 201: Invalid time value "1000$"
+ while evaluating variable "%y" with value "%y"
+make: "varmod.mk" line 207: Invalid time value "1000$"
+ while evaluating variable "%y" with value "%y"
+make: "varmod.mk" line 213: Dollar followed by nothing
+ while evaluating variable "word" with value "word"
+make: "varmod.mk" line 217: Dollar followed by nothing
+ while evaluating variable "word" with value "word"
+make: "varmod.mk" line 221: Invalid argument 'fallback$' for modifier ':mtime'
+ while evaluating variable "." with value "."
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varmod.mk b/unit-tests/varmod.mk
index fbb60d80680f..e0398965229b 100644
--- a/unit-tests/varmod.mk
+++ b/unit-tests/varmod.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod.mk,v 1.18 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varmod.mk,v 1.22 2025/01/11 20:54:46 rillig Exp $
#
# Tests for variable modifiers, such as :Q, :S,from,to or :Ufallback.
#
@@ -103,7 +103,7 @@ DOLLAR2= ${:U\$}
.endif
# A '$' followed by nothing is an error as well.
-# expect+1: while evaluating "${:Uword:@word@${word}$@} != "word"" with value "word": Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${:Uword:@word@${word}$@} != "word"
. error
.endif
@@ -113,7 +113,7 @@ DOLLAR2= ${:U\$}
# XXX: The .error should not be reached since the expression is
# malformed, and this error should be propagated up to Cond_EvalLine.
VAR= STOP
-# expect+1: while evaluating variable "VAR" with value "VAR": Missing delimiter ':' after modifier "P"
+# expect+1: Missing delimiter ':' after modifier "P"
.if ${VAR:P=RE} != "STORE"
# expect+1: Missing argument for ".error"
. error
@@ -121,27 +121,23 @@ VAR= STOP
# Test the word selection modifier ':[n]' with a very large number that is
# larger than ULONG_MAX for any supported platform.
-# expect+2: while evaluating variable "word" with value "word": Bad modifier ":[99333000222000111000]"
-# expect+1: Malformed conditional (${word:L:[99333000222000111000]})
+# expect+1: Bad modifier ":[99333000222000111000]"
.if ${word:L:[99333000222000111000]}
.endif
-# expect+2: while evaluating variable "word" with value "word": Bad modifier ":[2147483648]"
-# expect+1: Malformed conditional (${word:L:[2147483648]})
+# expect+1: Bad modifier ":[2147483648]"
.if ${word:L:[2147483648]}
.endif
# Test the range generation modifier ':range=n' with a very large number that
# is larger than SIZE_MAX for any supported platform.
-# expect+2: Malformed conditional (${word:L:range=99333000222000111000})
-# expect+1: while evaluating variable "word" with value "word": Invalid number "99333000222000111000}" for ':range' modifier
+# expect+1: Invalid number "99333000222000111000}" for ':range' modifier
.if ${word:L:range=99333000222000111000}
.endif
# In an indirect modifier, the delimiter is '\0', which at the same time marks
# the end of the string. The sequence '\\' '\0' is not an escaped delimiter,
# as it would be wrong to skip past the end of the string.
-# expect+2: while evaluating "${:${:Ugmtime=\\}}" with value "": Invalid time value "\"
-# expect+1: Malformed conditional (${:${:Ugmtime=\\}})
+# expect+1: Invalid time value "\"
.if ${:${:Ugmtime=\\}}
. error
.endif
@@ -156,13 +152,13 @@ VAR= STOP
.if ${:U:!printf '%s\n' $!} != "\$"
. error
.endif
-# expect+1: while evaluating variable "VAR" with value "value$": Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${VAR::=value$} != "" || ${VAR} != "value"
. error
.endif
${:U }= <space>
-# expect+2: while evaluating variable "VAR" with value "value$": Dollar followed by nothing
-# expect+1: while evaluating variable "VAR" with value "value$ appended$": Dollar followed by nothing
+# expect+2: Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${VAR::+=appended$} != "" || ${VAR} != "value<space>appended"
. error
.endif
@@ -172,12 +168,11 @@ ${:U }= <space>
.if ${0:?then$:else$} != "else\$"
. error
.endif
-# expect+1: while evaluating variable "word" with value "word": Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${word:L:@w@$w$@} != "word"
. error
.endif
-# expect+2: while evaluating variable "word" with value "": Bad modifier ":[$]"
-# expect+1: Malformed conditional (${word:[$]})
+# expect+1: Bad modifier ":[$]"
.if ${word:[$]}
. error
.else
@@ -193,39 +188,36 @@ VAR_DOLLAR= VAR$$
.if ${word:L:C,d,$,} != "wor\$"
. error
.endif
-# expect+2: while evaluating variable "VAR" with value "value$ appended$": Dollar followed by nothing
-# expect+1: while evaluating variable "VAR" with value "value<space>appended": Invalid variable name '}', at "$} != "set""
+# expect+2: Dollar followed by nothing
+# expect+1: Invalid variable name '}', at "$} != "set""
.if ${VAR:Dset$} != "set"
. error
.endif
-# expect+1: while evaluating "${:Ufallback$} != "fallback"" with value "": Invalid variable name '}', at "$} != "fallback""
+# expect+1: Invalid variable name '}', at "$} != "fallback""
.if ${:Ufallback$} != "fallback"
. error
.endif
-# expect+2: Malformed conditional (${%y:L:gmtime=1000$})
-# expect+1: while evaluating variable "%y" with value "%y": Invalid time value "1000$"
+# expect+1: Invalid time value "1000$"
.if ${%y:L:gmtime=1000$}
. error
.else
. error
.endif
-# expect+2: Malformed conditional (${%y:L:localtime=1000$})
-# expect+1: while evaluating variable "%y" with value "%y": Invalid time value "1000$"
+# expect+1: Invalid time value "1000$"
.if ${%y:L:localtime=1000$}
. error
.else
. error
.endif
-# expect+1: while evaluating variable "word" with value "word": Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${word:L:Mw*$} != "word"
. error
.endif
-# expect+1: while evaluating variable "word" with value "word": Dollar followed by nothing
+# expect+1: Dollar followed by nothing
.if ${word:L:NX*$} != "word"
. error
.endif
-# expect+2: while evaluating variable "." with value ".": Invalid argument 'fallback$' for modifier ':mtime'
-# expect+1: Malformed conditional (${.:L:mtime=fallback$})
+# expect+1: Invalid argument 'fallback$' for modifier ':mtime'
.if ${.:L:mtime=fallback$}
. error
.else
diff --git a/unit-tests/varname-dot-make-level.exp b/unit-tests/varname-dot-make-level.exp
index 963b6a3a4f96..005bc85bed0f 100644
--- a/unit-tests/varname-dot-make-level.exp
+++ b/unit-tests/varname-dot-make-level.exp
@@ -1,4 +1,12 @@
level 1: variable 0, env 1
level 2: variable 1, env 2
level 3: variable 2, env 3
-exit status 0
+make: Cannot override read-only global variable ".MAKE.LEVEL.ENV" with a command line variable
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+*** Error code 1 (continuing)
+`all' not remade because of errors.
+
+Stop.
+make: stopped making "all" in unit-tests
+exit status 1
diff --git a/unit-tests/varname-dot-make-level.mk b/unit-tests/varname-dot-make-level.mk
index 246890b23171..c4b6dc90028e 100644
--- a/unit-tests/varname-dot-make-level.mk
+++ b/unit-tests/varname-dot-make-level.mk
@@ -1,9 +1,11 @@
-# $NetBSD: varname-dot-make-level.mk,v 1.3 2024/06/01 18:44:05 rillig Exp $
+# $NetBSD: varname-dot-make-level.mk,v 1.5 2024/11/23 22:59:51 rillig Exp $
#
# Tests for the special .MAKE.LEVEL variable, which informs about the
# recursion level. It is related to the environment variable MAKELEVEL,
# even though they don't have the same value.
+all: level_1 set-env
+
level_1: .PHONY
@printf 'level 1: variable %s, env %s\n' ${.MAKE.LEVEL} "$$${.MAKE.LEVEL.ENV}"
@${MAKE} -f ${MAKEFILE} level_2
@@ -20,3 +22,8 @@ level_3: .PHONY
.if make(level_2)
.unexport-env
.endif
+
+
+# expect: make: Cannot override read-only global variable ".MAKE.LEVEL.ENV" with a command line variable
+set-env:
+ @${MAKE} -f /dev/null .MAKE.LEVEL.ENV=MAKELEVEL
diff --git a/unit-tests/varname-dot-shell.exp b/unit-tests/varname-dot-shell.exp
index 7d481fdf6ff1..7cc17435895b 100755
--- a/unit-tests/varname-dot-shell.exp
+++ b/unit-tests/varname-dot-shell.exp
@@ -1,34 +1,34 @@
-Parsing line 10: ORIG_SHELL:= ${.SHELL}
+Parsing varname-dot-shell.mk:10: ORIG_SHELL:= ${.SHELL}
Global: ORIG_SHELL = # (empty)
Var_Parse: ${.SHELL} (eval-keep-dollar-and-undefined)
Global: ignoring delete '.SHELL' as it is not found
Command: .SHELL = (details omitted)
Global: ORIG_SHELL = (details omitted)
-Parsing line 12: .SHELL= overwritten
+Parsing varname-dot-shell.mk:12: .SHELL= overwritten
Global: ignoring '.SHELL = overwritten' due to a command line variable of the same name
-Parsing line 13: .if ${.SHELL} != ${ORIG_SHELL}
+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 line 19: .MAKEFLAGS: .SHELL+=appended
+Parsing varname-dot-shell.mk:19: .MAKEFLAGS: .SHELL+=appended
ParseDependency(.MAKEFLAGS: .SHELL+=appended)
Command: ignoring '.SHELL += appended' as it is read-only
-Parsing line 20: .if ${.SHELL} != ${ORIG_SHELL}
+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 line 27: .undef .SHELL
+Parsing varname-dot-shell.mk:27: .undef .SHELL
Global: ignoring delete '.SHELL' as it is not found
-Parsing line 28: .SHELL= newly overwritten
+Parsing varname-dot-shell.mk:28: .SHELL= newly overwritten
Global: ignoring '.SHELL = newly overwritten' due to a command line variable of the same name
-Parsing line 29: .if ${.SHELL} != ${ORIG_SHELL}
+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 line 33: .MAKEFLAGS: -d0
+Parsing varname-dot-shell.mk:33: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
Global: .MAKEFLAGS = -r -k -d cpv -d
Global: .MAKEFLAGS = -r -k -d cpv -d 0
diff --git a/unit-tests/varname-dot-suffixes.exp b/unit-tests/varname-dot-suffixes.exp
index 230ba36d56ed..96f68d245d54 100644
--- a/unit-tests/varname-dot-suffixes.exp
+++ b/unit-tests/varname-dot-suffixes.exp
@@ -19,21 +19,21 @@ Result of ${preserve:_=.SUFFIXES} is "preserve" (eval-keep-dollar-and-undefined,
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
diff --git a/unit-tests/varname.exp b/unit-tests/varname.exp
index 9351b0761e98..46e6d13d41bd 100644
--- a/unit-tests/varname.exp
+++ b/unit-tests/varname.exp
@@ -5,11 +5,11 @@ Var_Parse: ${VARNAME} (eval)
Global: VAR((( = 3 open parentheses
Var_Parse: ${VAR(((}}}}" != "3 open parentheses}}}" (eval)
Global: .ALLTARGETS = VAR(((=)
-make: "varname.mk" line 32: No closing parenthesis in archive specification
+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)
+Var_Parse: ${:UVAR\(\(\(}= try2 (eval)
+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)
diff --git a/unit-tests/varname.mk b/unit-tests/varname.mk
index cad0a10fe563..d2c36afb3aa2 100644
--- a/unit-tests/varname.mk
+++ b/unit-tests/varname.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varname.mk,v 1.14 2023/11/19 21:47:52 rillig Exp $
+# $NetBSD: varname.mk,v 1.16 2025/01/11 20:16:40 rillig Exp $
#
# Tests for special variables, such as .MAKE or .PARSEDIR.
# And for variable names in general.
@@ -27,8 +27,8 @@ ${VARNAME}= 3 open parentheses
# This is not a variable assignment since the parentheses and braces are not
# balanced. At the end of the line, there are still 3 levels open, which
# means the variable name is not finished.
-# expect+2: Error in archive specification: "VAR"
-# expect+1: No closing parenthesis in archive specification
+# expect+2: Missing ')' in archive specification
+# expect+1: Error in archive specification: "VAR"
${:UVAR(((}= try1
# On the left-hand side of a variable assignments, the backslash is not parsed
# as an escape character, therefore the parentheses still count to the nesting
diff --git a/unit-tests/varparse-dynamic.exp b/unit-tests/varparse-dynamic.exp
index caf8424fa91a..940c61163b9c 100644
--- a/unit-tests/varparse-dynamic.exp
+++ b/unit-tests/varparse-dynamic.exp
@@ -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
diff --git a/unit-tests/varparse-dynamic.mk b/unit-tests/varparse-dynamic.mk
index 40f43b049b13..aafe3cca5329 100644
--- a/unit-tests/varparse-dynamic.mk
+++ b/unit-tests/varparse-dynamic.mk
@@ -1,14 +1,14 @@
-# $NetBSD: varparse-dynamic.mk,v 1.8 2023/11/19 22:32:44 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
diff --git a/unit-tests/varparse-errors.exp b/unit-tests/varparse-errors.exp
index 9ca443c6fd67..b2212cb8baf0 100644
--- a/unit-tests/varparse-errors.exp
+++ b/unit-tests/varparse-errors.exp
@@ -1,25 +1,45 @@
-make: "varparse-errors.mk" line 38: while evaluating "${:U:Z}" with value "": Unknown modifier "Z"
-make: "varparse-errors.mk" line 47: while evaluating "${:U:Z}post" with value "": Unknown modifier "Z"
-make: "varparse-errors.mk" line 75: while evaluating "${:U:OX:U${IND}} ${:U:OX:U${IND}}" with value "": Bad modifier ":OX"
-make: "varparse-errors.mk" line 75: Undefined variable "${:U:OX"
-make: "varparse-errors.mk" line 75: while evaluating variable "IND" with value "${:OX}": while evaluating "${:OX}" with value "": Bad modifier ":OX"
-make: "varparse-errors.mk" line 75: while evaluating "${:U:OX:U${IND}}" with value "": Bad modifier ":OX"
-make: "varparse-errors.mk" line 75: Undefined variable "${:U:OX"
-make: "varparse-errors.mk" line 75: while evaluating variable "IND" with value "${:OX}": while evaluating "${:OX}" with value "": Bad modifier ":OX"
-make: "varparse-errors.mk" line 83: while evaluating "${:U:Q" with value "": Unclosed expression, expecting '}' for modifier "Q"
-make: "varparse-errors.mk" line 85: while evaluating "${:U:sh" with value "": Unclosed expression, expecting '}' for modifier "sh"
-make: "varparse-errors.mk" line 87: while evaluating "${:U:tA" with value "": Unclosed expression, expecting '}' for modifier "tA"
-make: "varparse-errors.mk" line 89: while evaluating "${:U:tsX" with value "": Unclosed expression, expecting '}' for modifier "tsX"
-make: "varparse-errors.mk" line 91: while evaluating "${:U:ts" with value "": Unclosed expression, expecting '}' for modifier "ts"
-make: "varparse-errors.mk" line 93: while evaluating "${:U:ts\040" with value "": Unclosed expression, expecting '}' for modifier "ts\040"
-make: "varparse-errors.mk" line 95: while evaluating "${:U:u" with value "": Unclosed expression, expecting '}' for modifier "u"
-make: "varparse-errors.mk" line 97: while evaluating "${:U:H" with value ".": Unclosed expression, expecting '}' for modifier "H"
-make: "varparse-errors.mk" line 99: while evaluating "${:U:[1]" with value "": Unclosed expression, expecting '}' for modifier "[1]"
-make: "varparse-errors.mk" line 101: while evaluating "${:U:hash" with value "b2af338b": Unclosed expression, expecting '}' for modifier "hash"
-make: "varparse-errors.mk" line 103: while evaluating "${:U:range" with value "1": Unclosed expression, expecting '}' for modifier "range"
-make: "varparse-errors.mk" line 105: while evaluating "${:U:_" with value "": Unclosed expression, expecting '}' for modifier "_"
-make: "varparse-errors.mk" line 107: while evaluating "${:U:gmtime" with value "<timestamp>": Unclosed expression, expecting '}' for modifier "gmtime"
-make: "varparse-errors.mk" line 109: while evaluating "${:U:localtime" with value "<timestamp>": Unclosed expression, expecting '}' for modifier "localtime"
+make: "varparse-errors.mk" line 38: Unknown modifier "Z"
+ while evaluating "${:U:Z}" with value ""
+make: "varparse-errors.mk" line 47: Unknown modifier "Z"
+ while evaluating "${:U:Z}post" with value ""
+make: "varparse-errors.mk" line 73: Bad modifier ":OX"
+ while evaluating "${:U:OX:U${IND}} ${:U:OX:U${IND}}" with value ""
+make: "varparse-errors.mk" line 73: Bad modifier ":OX"
+ while evaluating "${:OX}" with value ""
+ while evaluating variable "IND" with value "${:OX}"
+make: "varparse-errors.mk" line 73: Bad modifier ":OX"
+ while evaluating "${:U:OX:U${IND}}" with value ""
+make: "varparse-errors.mk" line 73: Bad modifier ":OX"
+ while evaluating "${:OX}" with value ""
+ while evaluating variable "IND" with value "${:OX}"
+make: "varparse-errors.mk" line 81: Unclosed expression, expecting '}' for modifier "Q"
+ while evaluating "${:U:Q" with value ""
+make: "varparse-errors.mk" line 83: Unclosed expression, expecting '}' for modifier "sh"
+ while evaluating "${:U:sh" with value ""
+make: "varparse-errors.mk" line 85: Unclosed expression, expecting '}' for modifier "tA"
+ while evaluating "${:U:tA" with value ""
+make: "varparse-errors.mk" line 87: Unclosed expression, expecting '}' for modifier "tsX"
+ while evaluating "${:U:tsX" with value ""
+make: "varparse-errors.mk" line 89: Unclosed expression, expecting '}' for modifier "ts"
+ while evaluating "${:U:ts" with value ""
+make: "varparse-errors.mk" line 91: Unclosed expression, expecting '}' for modifier "ts\040"
+ while evaluating "${:U:ts\040" with value ""
+make: "varparse-errors.mk" line 93: Unclosed expression, expecting '}' for modifier "u"
+ while evaluating "${:U:u" with value ""
+make: "varparse-errors.mk" line 95: Unclosed expression, expecting '}' for modifier "H"
+ while evaluating "${:U:H" with value "."
+make: "varparse-errors.mk" line 97: Unclosed expression, expecting '}' for modifier "[1]"
+ while evaluating "${:U:[1]" with value ""
+make: "varparse-errors.mk" line 99: Unclosed expression, expecting '}' for modifier "hash"
+ while evaluating "${:U:hash" with value "b2af338b"
+make: "varparse-errors.mk" line 101: Unclosed expression, expecting '}' for modifier "range"
+ while evaluating "${:U:range" with value "1"
+make: "varparse-errors.mk" line 103: Unclosed expression, expecting '}' for modifier "_"
+ while evaluating "${:U:_" with value ""
+make: "varparse-errors.mk" line 105: Unclosed expression, expecting '}' for modifier "gmtime"
+ while evaluating "${:U:gmtime" with value "<timestamp>"
+make: "varparse-errors.mk" line 107: Unclosed expression, expecting '}' for modifier "localtime"
+ while evaluating "${:U:localtime" with value "<timestamp>"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/unit-tests/varparse-errors.mk b/unit-tests/varparse-errors.mk
index d10160b816e5..b28ac1ec5dc1 100644
--- a/unit-tests/varparse-errors.mk
+++ b/unit-tests/varparse-errors.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varparse-errors.mk,v 1.17 2024/07/05 19:47:22 rillig Exp $
+# $NetBSD: varparse-errors.mk,v 1.19 2024/08/29 20:20:37 rillig Exp $
# Tests for parsing and evaluating all kinds of expressions.
#
@@ -34,7 +34,7 @@ ERR_EVAL= An evaluation error ${:Uvalue:C,.,\3,}.
# As of 2020-12-01, errors in the variable name are silently ignored.
# Since var.c 1.754 from 2020-12-20, unknown modifiers at parse time result
# in an error message and a non-zero exit status.
-# expect+1: while evaluating "${:U:Z}" with value "": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
VAR.${:U:Z}= unknown modifier in the variable name
.if ${VAR.} != "unknown modifier in the variable name"
. error
@@ -43,7 +43,7 @@ VAR.${:U:Z}= unknown modifier in the variable name
# As of 2020-12-01, errors in the variable name are silently ignored.
# Since var.c 1.754 from 2020-12-20, unknown modifiers at parse time result
# in an error message and a non-zero exit status.
-# expect+1: while evaluating "${:U:Z}post" with value "": Unknown modifier "Z"
+# expect+1: Unknown modifier "Z"
VAR.${:U:Z}post= unknown modifier with text in the variable name
.if ${VAR.post} != "unknown modifier with text in the variable name"
. error
@@ -66,12 +66,10 @@ VAR.${:U:Z}post= unknown modifier with text in the variable name
#
#.MAKEFLAGS: -dv
IND= ${:OX}
-# expect+6: while evaluating "${:U:OX:U${IND}} ${:U:OX:U${IND}}" with value "": Bad modifier ":OX"
-# expect+5: while evaluating "${:U:OX:U${IND}}" with value "": Bad modifier ":OX"
-# expect+4: Undefined variable "${:U:OX"
-# expect+3: while evaluating variable "IND" with value "${:OX}": while evaluating "${:OX}" with value "": Bad modifier ":OX"
-# expect+2: Undefined variable "${:U:OX"
-# expect+1: while evaluating variable "IND" with value "${:OX}": while evaluating "${:OX}" with value "": Bad modifier ":OX"
+# expect+4: Bad modifier ":OX"
+# expect+3: Bad modifier ":OX"
+# expect+2: Bad modifier ":OX"
+# expect+1: Bad modifier ":OX"
_:= ${:U:OX:U${IND}} ${:U:OX:U${IND}}
#.MAKEFLAGS: -d0
@@ -79,31 +77,31 @@ _:= ${:U:OX:U${IND}} ${:U:OX:U${IND}}
# Before var.c 1.032 from 2022-08-24, make complained about 'Unknown modifier'
# or 'Bad modifier' when in fact the modifier was entirely correct, it was
# just not delimited by either ':' or '}' but instead by '\0'.
-# expect+1: while evaluating "${:U:Q" with value "": Unclosed expression, expecting '}' for modifier "Q"
+# expect+1: Unclosed expression, expecting '}' for modifier "Q"
UNCLOSED:= ${:U:Q
-# expect+1: while evaluating "${:U:sh" with value "": Unclosed expression, expecting '}' for modifier "sh"
+# expect+1: Unclosed expression, expecting '}' for modifier "sh"
UNCLOSED:= ${:U:sh
-# expect+1: while evaluating "${:U:tA" with value "": Unclosed expression, expecting '}' for modifier "tA"
+# expect+1: Unclosed expression, expecting '}' for modifier "tA"
UNCLOSED:= ${:U:tA
-# expect+1: while evaluating "${:U:tsX" with value "": Unclosed expression, expecting '}' for modifier "tsX"
+# expect+1: Unclosed expression, expecting '}' for modifier "tsX"
UNCLOSED:= ${:U:tsX
-# expect+1: while evaluating "${:U:ts" with value "": Unclosed expression, expecting '}' for modifier "ts"
+# expect+1: Unclosed expression, expecting '}' for modifier "ts"
UNCLOSED:= ${:U:ts
-# expect+1: while evaluating "${:U:ts\040" with value "": Unclosed expression, expecting '}' for modifier "ts\040"
+# expect+1: Unclosed expression, expecting '}' for modifier "ts\040"
UNCLOSED:= ${:U:ts\040
-# expect+1: while evaluating "${:U:u" with value "": Unclosed expression, expecting '}' for modifier "u"
+# expect+1: Unclosed expression, expecting '}' for modifier "u"
UNCLOSED:= ${:U:u
-# expect+1: while evaluating "${:U:H" with value ".": Unclosed expression, expecting '}' for modifier "H"
+# expect+1: Unclosed expression, expecting '}' for modifier "H"
UNCLOSED:= ${:U:H
-# expect+1: while evaluating "${:U:[1]" with value "": Unclosed expression, expecting '}' for modifier "[1]"
+# expect+1: Unclosed expression, expecting '}' for modifier "[1]"
UNCLOSED:= ${:U:[1]
-# expect+1: while evaluating "${:U:hash" with value "b2af338b": Unclosed expression, expecting '}' for modifier "hash"
+# expect+1: Unclosed expression, expecting '}' for modifier "hash"
UNCLOSED:= ${:U:hash
-# expect+1: while evaluating "${:U:range" with value "1": Unclosed expression, expecting '}' for modifier "range"
+# expect+1: Unclosed expression, expecting '}' for modifier "range"
UNCLOSED:= ${:U:range
-# expect+1: while evaluating "${:U:_" with value "": Unclosed expression, expecting '}' for modifier "_"
+# expect+1: Unclosed expression, expecting '}' for modifier "_"
UNCLOSED:= ${:U:_
-# expect+1: while evaluating "${:U:gmtime" with value "<timestamp>": Unclosed expression, expecting '}' for modifier "gmtime"
+# expect+1: Unclosed expression, expecting '}' for modifier "gmtime"
UNCLOSED:= ${:U:gmtime
-# expect+1: while evaluating "${:U:localtime" with value "<timestamp>": Unclosed expression, expecting '}' for modifier "localtime"
+# expect+1: Unclosed expression, expecting '}' for modifier "localtime"
UNCLOSED:= ${:U:localtime