diff options
Diffstat (limited to 'unit-tests')
45 files changed, 429 insertions, 198 deletions
diff --git a/unit-tests/Makefile b/unit-tests/Makefile index 63671a6d9b74..b12ef7decb4d 100644 --- a/unit-tests/Makefile +++ b/unit-tests/Makefile @@ -1,6 +1,6 @@ -# $Id: Makefile,v 1.251 2025/11/15 17:17:18 sjg Exp $ +# $Id: Makefile,v 1.260 2026/03/10 15:45:51 sjg Exp $ # -# $NetBSD: Makefile,v 1.373 2025/11/12 22:14:08 sjg Exp $ +# $NetBSD: Makefile,v 1.383 2026/03/10 15:38:26 sjg Exp $ # # Unit tests for make(1) # @@ -629,6 +629,9 @@ SED_CMDS.opt-chdir= -e 's,\(nonexistent\).[1-9][0-9]*,\1,' \ -e 's,no such,No such,' \ -e 's,Filename,File name,' +SED_CMDS.gnode-submake= ${STD_SED_CMDS.dj} +SED_CMDS.gnode-submake= ${STD_SED_CMDS.dg2} + # meta line numbers can vary based on filemon implementation SED_CMDS.meta-ignore= -e 's,\(\.meta:\)[1-9][0-9]*:,\1<line>:,' @@ -642,6 +645,7 @@ SED_CMDS.opt-debug-lint+= ${STD_SED_CMDS.regex} SED_CMDS.opt-jobs-no-action= ${STD_SED_CMDS.hide-from-output} SED_CMDS.opt-no-action-runflags= ${STD_SED_CMDS.hide-from-output} SED_CMDS.opt-where-am-i= -e '/usr.obj/d' +SED_CMDS.opt-where-am-i+= -e '/\/\//d' # For Compat_RunCommand, useShell == false. SED_CMDS.sh-dots= -e 's,^.*\.\.\.:.*,<not found: ...>,' # For Compat_RunCommand, useShell == true. @@ -662,6 +666,7 @@ SED_CMDS.var-op-shell+= -e '/command/s,No such.*,not found,' SED_CMDS.var-op-shell+= ${STD_SED_CMDS.white-space} SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,' SED_CMDS.varmod-mtime+= -e "s,\(mtime for .*\): .*,\1: <ENOENT>," +SED_CMDS.varmod-subst+= ${STD_SED_CMDS.regex} SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex} SED_CMDS.varparse-errors+= ${STD_SED_CMDS.timestamp} SED_CMDS.varname-dot-make-meta-ignore_filter+= ${SED_CMDS.meta-ignore} @@ -677,7 +682,10 @@ SED_CMDS.varname-empty= ${.OBJDIR .PARSEDIR .PATH .SHELL .SYSPATH:L:@v@-e '/\\$ # Some tests need an additional round of postprocessing. POSTPROC.depsrc-wait= sed -e '/^---/d' -e 's,^\(: Making 3[abc]\)[123]$$,\1,' POSTPROC.deptgt-suffixes= awk '/^\#\*\*\* Suffixes/,/^never-stop/' -POSTPROC.gnode-submake= awk '/Begin input graph/, /^$$/' +POSTPROC.gnode-submake= \ + awk '/Begin input graph/, /^\# \.END/ { \ + if (/made,/) print $$0 \ + }' POSTPROC.varname-dot-make-mode= sed 's,^\(: Making [abc]\)[123]$$,\1,' # Some tests reuse other tests, which makes them unnecessarily fragile. @@ -700,6 +708,7 @@ STD_SED_CMDS.dg1= -e '/\#.* \.$$/d' STD_SED_CMDS.dg1+= -e '/\.MAKE.PATH_FILEMON/d' STD_SED_CMDS.dg1+= -e '/^\#.*\/mk/d' STD_SED_CMDS.dg1+= -e 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,' +STD_SED_CMDS.dg1+= -e '/^\.MAKE\.PATH_FILEMON/d' STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.JOBS\.C *=\) .*,\1 <details omitted>,' @@ -710,6 +719,7 @@ STD_SED_CMDS.dg1+= -e '/\.SYSPATH/d' STD_SED_CMDS.dg2= ${STD_SED_CMDS.dg1} STD_SED_CMDS.dg2+= -e 's,\(last modified\) ..:..:.. ... ..\, ....,\1 <timestamp>,' + STD_SED_CMDS.dg3= ${STD_SED_CMDS.dg2} # Omit details such as process IDs from the output of the -dj option. @@ -792,6 +802,16 @@ clean: rm -f ${CLEANFILES} TEST_MAKE?= ${.MAKE} +.if ${TEST_MAKE:M/*} == "" +# we want an absolute path for TEST_MAKE +tm!= for d in ${PATH:S,:, ,g:M/*}; do \ + test -x $$d/${TEST_MAKE} || continue; \ + echo $$d/${TEST_MAKE}; break; done +.if ${tm:M/*} +TEST_MAKE:= ${tm} +.endif +.endif + TOOL_SED?= sed TOOL_TR?= tr TOOL_DIFF?= diff @@ -831,7 +851,7 @@ LIMIT_RESOURCES?= : # each other, and because they use different environment variables and # command line options. .SUFFIXES: .mk .rawout .out -.mk.rawout: +.mk.rawout: .META @${_MKMSG_TEST:Uecho '# test '} ${.PREFIX} @set -eu; \ ${LIMIT_RESOURCES}; \ @@ -873,7 +893,8 @@ _SED_CMDS+= -e 's,^usage: ${TEST_MAKE:T:S,.,\\.,g} ,usage: make ,' _SED_CMDS+= -e 's,${TEST_MAKE:T:S,.,\\.,g}\(\[[1-9][0-9]*\][: ]\),make\1,' _SED_CMDS+= -e 's,<curdir>/,,g' _SED_CMDS+= -e 's,${UNIT_TESTS:S,.,\\.,g}/,,g' -_SED_CMDS+= -e '/MAKE_VERSION/d' +_SED_CMDS+= -e 's,\(\.make\)[1-9][0-9]*,\1,g' +_SED_CMDS+= -e '/MAKE.VERSION/d' _SED_CMDS+= -e '/EGREP=/d' # on AT&T derived systems: false exits 255 not 1 @@ -886,7 +907,7 @@ SED_CMDS.opt-debug-jobs+= -e 's,Command: ksh -v,Command: <shell>,' SED_CMDS.opt-debug-jobs+= -e 's,Command: <shell> -v,Command: <shell>,' .endif -.rawout.out: +.rawout.out: .META @${TOOL_SED} ${_SED_CMDS} ${SED_CMDS.${.PREFIX:T}} ${_SED_CMDS_LAST} \ < ${.IMPSRC} > ${.TARGET}.tmp @${POSTPROC.${.PREFIX:T}:D \ diff --git a/unit-tests/cmd-errors-jobs.exp b/unit-tests/cmd-errors-jobs.exp index 3be1bb9b0773..3846f9eef260 100644 --- a/unit-tests/cmd-errors-jobs.exp +++ b/unit-tests/cmd-errors-jobs.exp @@ -9,34 +9,34 @@ end undefined-indirect with status 0 begin parse-error-direct make: Unclosed variable "UNCLOSED" in command ": unexpected $@-${UNCLOSED" - in target "parse-error-unclosed-expression" + in target "parse-error-unclosed-expression" from cmd-errors-jobs.mk:42 in make[1] in directory "<curdir>" make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": unexpected $@-${UNCLOSED:" - in target "parse-error-unclosed-modifier" + in target "parse-error-unclosed-modifier" from cmd-errors-jobs.mk:45 in make[1] in directory "<curdir>" make: Unknown modifier ":Z" while evaluating variable "UNKNOWN" with value "" in command ": unexpected $@-${UNKNOWN:Z}-eol" - in target "parse-error-unknown-modifier" + in target "parse-error-unknown-modifier" from cmd-errors-jobs.mk:48 in make[1] in directory "<curdir>" end parse-error-direct with status 2 begin parse-error-indirect make: Unclosed variable "UNCLOSED" in command ": unexpected $@-${UNCLOSED" - in target "parse-error-unclosed-expression" + in target "parse-error-unclosed-expression" from cmd-errors-jobs.mk:42 in make[1] in directory "<curdir>" make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": unexpected $@-${UNCLOSED:" - in target "parse-error-unclosed-modifier" + in target "parse-error-unclosed-modifier" from cmd-errors-jobs.mk:45 in make[1] in directory "<curdir>" make: Unknown modifier ":Z" while evaluating variable "UNKNOWN" with value "" in command ": unexpected $@-${UNKNOWN:Z}-eol" - in target "parse-error-unknown-modifier" + in target "parse-error-unknown-modifier" from cmd-errors-jobs.mk:48 in make[1] in directory "<curdir>" end parse-error-indirect with status 2 diff --git a/unit-tests/cmd-errors-lint.exp b/unit-tests/cmd-errors-lint.exp index b08a65ff96dc..4b010732f8b2 100644 --- a/unit-tests/cmd-errors-lint.exp +++ b/unit-tests/cmd-errors-lint.exp @@ -1,14 +1,14 @@ : undefined make: Unclosed variable "UNCLOSED" in command ": $@ ${UNCLOSED" - in target "unclosed-expression" + in target "unclosed-expression" from cmd-errors-lint.mk:19 make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": $@ ${UNCLOSED:" - in target "unclosed-modifier" + in target "unclosed-modifier" from cmd-errors-lint.mk:24 make: Unknown modifier ":Z" while evaluating variable "UNKNOWN" with value "" in command ": $@ ${UNKNOWN:Z}" - in target "unknown-modifier" + in target "unknown-modifier" from cmd-errors-lint.mk:29 : end exit status 2 diff --git a/unit-tests/cmd-errors.exp b/unit-tests/cmd-errors.exp index 2916d423029e..8936c0a671ae 100644 --- a/unit-tests/cmd-errors.exp +++ b/unit-tests/cmd-errors.exp @@ -1,14 +1,14 @@ : undefined--eol make: Unclosed variable "UNCLOSED" in command ": $@-${UNCLOSED" - in target "unclosed-expression" + in target "unclosed-expression" from cmd-errors.mk:17 make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": $@-${UNCLOSED:" - in target "unclosed-modifier" + in target "unclosed-modifier" from cmd-errors.mk:22 make: Unknown modifier ":Z" while evaluating variable "UNKNOWN" with value "" in command ": $@-${UNKNOWN:Z}-eol" - in target "unknown-modifier" + in target "unknown-modifier" from cmd-errors.mk:27 : end-eol exit status 2 diff --git a/unit-tests/cond-func-exists.mk b/unit-tests/cond-func-exists.mk index c68507ca1ab9..360c4741f9c0 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.8 2025/01/10 23:00:38 rillig Exp $ +# $NetBSD: cond-func-exists.mk,v 1.9 2026/03/02 21:49:37 rillig Exp $ # # Tests for the exists() function in .if conditions. @@ -52,5 +52,17 @@ _!= > cond-func-exists.just-created .endif _!= rm cond-func-exists.just-created + +# The exists function aims at source and target files, but not at makefiles. +# In particular, the file is not searched in ${.PARSEDIR}. +_!= mkdir -p cond-func-exists && \ + printf '%s\n' \ + '.if exists(file.inc)' \ + '. error' \ + '.endif' \ + > cond-func-exists/file.inc +.include "cond-func-exists/file.inc" +_!= rm -f cond-func-exists/file.inc + + all: - @:; diff --git a/unit-tests/cond-undef-lint.mk b/unit-tests/cond-undef-lint.mk index 1b4d19636c41..27e42d208aa3 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.8 2025/01/11 21:21:33 rillig Exp $ +# $NetBSD: cond-undef-lint.mk,v 1.9 2026/02/13 03:16:15 lukem Exp $ # # Tests for defined and undefined variables in .if conditions, in lint mode. # @@ -51,7 +51,7 @@ DEF= defined # Variables that are referenced indirectly may be undefined in a condition. # -# A practical example for this is CFLAGS, which consists of CWARNS, COPTS +# A practical example for this is CFLAGS, which consists of CWARNFLAGS, COPTS # and a few others. Just because these nested variables are not defined, # this does not make the condition invalid. # diff --git a/unit-tests/directive-dinclude.mk b/unit-tests/directive-dinclude.mk index c05d1a55f51b..40fcb5306bb8 100755 --- a/unit-tests/directive-dinclude.mk +++ b/unit-tests/directive-dinclude.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-dinclude.mk,v 1.5 2025/06/28 22:39:28 rillig Exp $ +# $NetBSD: directive-dinclude.mk,v 1.6 2025/11/16 16:43:56 sjg Exp $ # # Tests for the .dinclude directive, which includes another file, # silently skipping it if it cannot be opened. This is primarily used for diff --git a/unit-tests/directive-export-gmake.mk b/unit-tests/directive-export-gmake.mk index 6e1d57c6a62d..36efc96e5114 100644 --- a/unit-tests/directive-export-gmake.mk +++ b/unit-tests/directive-export-gmake.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-export-gmake.mk,v 1.10 2025/06/28 22:39:28 rillig Exp $ +# $NetBSD: directive-export-gmake.mk,v 1.11 2026/01/02 14:21:46 rillig Exp $ # # Tests for the export directive (without leading dot), as in GNU make. @@ -104,3 +104,12 @@ export ${INDIRECT_NAME}=${INDIRECT_VALUE} .if ${:!env!:MI_NAME=*} . error .endif + + +# Quotes and other special characters are preserved. +export DQUOT="dquot" +export SQUOT='squot' +export PLAIN=plain +.if ${:!echo "\$DQUOT \$SQUOT \$PLAIN"!} != "\"dquot\" 'squot' plain" +. error +.endif diff --git a/unit-tests/directive-hyphen-include.mk b/unit-tests/directive-hyphen-include.mk index e3817ef15539..e3cc48238eff 100755 --- a/unit-tests/directive-hyphen-include.mk +++ b/unit-tests/directive-hyphen-include.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-hyphen-include.mk,v 1.5 2025/06/28 22:39:28 rillig Exp $ +# $NetBSD: directive-hyphen-include.mk,v 1.6 2025/11/16 16:43:57 sjg Exp $ # # Tests for the .-include directive, which includes another file, # silently skipping it if it cannot be opened. diff --git a/unit-tests/directive-include-guard.mk b/unit-tests/directive-include-guard.mk index 5dc7f1aac178..acbe61d66d41 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.19 2025/04/11 17:21:31 rillig Exp $ +# $NetBSD: directive-include-guard.mk,v 1.20 2025/11/16 16:43:57 sjg Exp $ # # Tests for multiple-inclusion guards in makefiles. # diff --git a/unit-tests/directive-include.mk b/unit-tests/directive-include.mk index a694b9ca4e91..eedb9ce220e0 100755 --- a/unit-tests/directive-include.mk +++ b/unit-tests/directive-include.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-include.mk,v 1.20 2025/06/28 22:39:28 rillig Exp $ +# $NetBSD: directive-include.mk,v 1.21 2025/11/16 16:43:57 sjg Exp $ # # Tests for the .include directive, which includes another file. diff --git a/unit-tests/directive-sinclude.mk b/unit-tests/directive-sinclude.mk index 3c2ffbdc9f6c..d995d315518b 100755 --- a/unit-tests/directive-sinclude.mk +++ b/unit-tests/directive-sinclude.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-sinclude.mk,v 1.7 2025/06/28 22:39:28 rillig Exp $ +# $NetBSD: directive-sinclude.mk,v 1.8 2025/11/16 16:43:57 sjg Exp $ # # Tests for the .sinclude directive, which includes another file, # silently skipping it if it cannot be opened. diff --git a/unit-tests/gnode-submake.exp b/unit-tests/gnode-submake.exp index c9cfada91c69..7ed8335bf73d 100644 --- a/unit-tests/gnode-submake.exp +++ b/unit-tests/gnode-submake.exp @@ -1,11 +1,11 @@ -#*** Begin input graph for pass 1 in <curdir>: -# all, unmade, type OP_DEPENDS, flags none -# makeinfo, unmade, type OP_DEPENDS|OP_HAS_COMMANDS, flags none -# make-index, unmade, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS, flags none -# braces-dot, unmade, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS, flags none -# braces-no-dot, unmade, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS, flags none -# braces-no-dot-modifier, unmade, type OP_DEPENDS|OP_HAS_COMMANDS, flags none -# parentheses-dot, unmade, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS, flags none -# parentheses-no-dot, unmade, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS, flags none - +# .MAIN, made, type OP_DEPENDS|OP_PHONY, flags REMAKE|CHILDMADE|FORCE|DONE_WAIT|DONE_ALLSRC +# all, made, type OP_DEPENDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|CHILDMADE|FORCE|DONE_WAIT|DONE_ALLSRC|DONECYCLE +# makeinfo, made, type OP_DEPENDS|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# make-index, made, type OP_DEPENDS|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# braces-dot, made, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# braces-no-dot, made, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# braces-no-dot-modifier, made, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# parentheses-dot, made, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# parentheses-no-dot, made, type OP_DEPENDS|OP_SUBMAKE|OP_HAS_COMMANDS|OP_DEPS_FOUND|OP_MARK, flags REMAKE|DONE_WAIT|DONE_ALLSRC|DONE_SUBMAKE +# .END, unmade, type OP_SPECIAL, flags none exit status 0 diff --git a/unit-tests/gnode-submake.mk b/unit-tests/gnode-submake.mk index 40ff20276df9..2cd7fac81f72 100644 --- a/unit-tests/gnode-submake.mk +++ b/unit-tests/gnode-submake.mk @@ -1,4 +1,4 @@ -# $NetBSD: gnode-submake.mk,v 1.1 2020/11/07 23:25:06 rillig Exp $ +# $NetBSD: gnode-submake.mk,v 1.2 2026/02/10 18:53:34 sjg Exp $ # # Test whether OP_SUBMAKE is determined correctly. If it is, this node's # shell commands are connected to the make process via pipes, to coordinate @@ -8,7 +8,7 @@ # parsed. This information is only used in parallel mode, but the result # from parsing is available in compat mode as well. -.MAKEFLAGS: -n -dg1 +.MAKEFLAGS: -dg2 -j1 all: makeinfo make-index all: braces-dot braces-no-dot diff --git a/unit-tests/lint.exp b/unit-tests/lint.exp index 61188d6d5c29..6c08bdcbe01b 100755 --- a/unit-tests/lint.exp +++ b/unit-tests/lint.exp @@ -1,5 +1,5 @@ make: In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar while evaluating variable "VAR" with value "value" in command "@echo ${VAR:Uvalue:@${:Ubar:S,b,v,}@x${var}y@:Q}" - in target "mod-loop-varname" + in target "mod-loop-varname" from lint.mk:22 exit status 2 diff --git a/unit-tests/moderrs.exp b/unit-tests/moderrs.exp index 4758294f0993..1fa7dd57f52a 100644 --- a/unit-tests/moderrs.exp +++ b/unit-tests/moderrs.exp @@ -1,173 +1,173 @@ make: Unknown modifier ":Z" while evaluating variable "VAR" with value "TheVariable" in command "@echo 'VAR:Z=before-${VAR:Z}-after'" - in target "mod-unknown-direct" + in target "mod-unknown-direct" from moderrs.mk:29 make: Unknown modifier ":Z" while evaluating indirect modifiers "Z" while evaluating variable "VAR" with value "TheVariable" in command "@echo 'VAR:${MOD_UNKN}=before-${VAR:${MOD_UNKN}:inner}-after'" - in target "mod-unknown-indirect" + in target "mod-unknown-indirect" from moderrs.mk:33 make: Unclosed expression, expecting "}" for modifier "S,V,v," while evaluating variable "VAR" with value "Thevariable" in command "@echo VAR:S,V,v,=${VAR:S,V,v," - in target "unclosed-direct" + in target "unclosed-direct" from moderrs.mk:37 make: Unclosed expression after indirect modifier, expecting "}" while evaluating variable "VAR" with value "Thevariable" in command "@echo VAR:${MOD_TERM},=${VAR:${MOD_S}" - in target "unclosed-indirect" + in target "unclosed-indirect" from moderrs.mk:41 make: Unfinished modifier after "v", expecting "," while evaluating indirect modifiers "S,V,v" while evaluating variable "VAR" with value "TheVariable" in command "-@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}"" - in target "unfinished-indirect" + in target "unfinished-indirect" from moderrs.mk:45 make: Unfinished modifier after "var}", expecting "@" while evaluating variable "UNDEF" with value "1 2 3" in command "@echo ${UNDEF:U1 2 3:@var}" - in target "unfinished-loop-1" + in target "unfinished-loop-1" from moderrs.mk:49 make: Unfinished modifier after "...}", expecting "@" while evaluating variable "UNDEF" with value "1 2 3" in command "@echo ${UNDEF:U1 2 3:@var@...}" - in target "unfinished-loop-2" + in target "unfinished-loop-2" from moderrs.mk:52 1 2 3 make: Unclosed expression, expecting "}" for modifier "@var@${var}}...@" while evaluating variable "UNDEF" with value "1}... 2}... 3}..." in command "@echo ${UNDEF:U1 2 3:@var@${var}}...@" - in target "loop-close-1" + in target "loop-close-1" from moderrs.mk:64 1}... 2}... 3}... make: Unfinished modifier after "}", expecting "]" while evaluating variable "UNDEF" with value "1 2 3" in command "@echo ${UNDEF:U1 2 3:[}" - in target "words-1" + in target "words-1" from moderrs.mk:70 make: Unfinished modifier after "#}", expecting "]" while evaluating variable "UNDEF" with value "1 2 3" in command "@echo ${UNDEF:U1 2 3:[#}" - in target "words-2" + in target "words-2" from moderrs.mk:73 13= make: Invalid modifier ":[123451234512345123451234512345]" while evaluating variable "UNDEF" with value "1 2 3" in command "@echo 12345=${UNDEF:U1 2 3:[123451234512345123451234512345]:S,^$,ok,:S,^3$,ok,}" - in target "words-3" + in target "words-3" from moderrs.mk:96 make: Unfinished modifier after "echo}", expecting "!" while evaluating variable "VARNAME" with value "" in command "@echo ${VARNAME:!echo}" - in target "exclam-1" + in target "exclam-1" from moderrs.mk:100 make: Unfinished modifier after "=exclam}", expecting "!" while evaluating variable "!" with value "!" in command "@echo ${!:L:!=exclam}" - in target "exclam-2" + in target "exclam-2" from moderrs.mk:107 make: Missing delimiter for modifier ":S" while evaluating variable "VAR" with value "TheVariable" in command "@echo 1: ${VAR:S" - in target "mod-subst-delimiter-1" + in target "mod-subst-delimiter-1" from moderrs.mk:111 make: Unfinished modifier after "", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 2: ${VAR:S," - in target "mod-subst-delimiter-2" + in target "mod-subst-delimiter-2" from moderrs.mk:114 make: Unfinished modifier after "from", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 3: ${VAR:S,from" - in target "mod-subst-delimiter-3" + in target "mod-subst-delimiter-3" from moderrs.mk:117 make: Unfinished modifier after "", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 4: ${VAR:S,from," - in target "mod-subst-delimiter-4" + in target "mod-subst-delimiter-4" from moderrs.mk:120 make: Unfinished modifier after "to", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 5: ${VAR:S,from,to" - in target "mod-subst-delimiter-5" + in target "mod-subst-delimiter-5" from moderrs.mk:123 make: Unclosed expression, expecting "}" for modifier "S,from,to," while evaluating variable "VAR" with value "TheVariable" in command "@echo 6: ${VAR:S,from,to," - in target "mod-subst-delimiter-6" + in target "mod-subst-delimiter-6" from moderrs.mk:126 7: TheVariable make: Missing delimiter for modifier ":C" while evaluating variable "VAR" with value "TheVariable" in command "@echo 1: ${VAR:C" - in target "mod-regex-delimiter-1" + in target "mod-regex-delimiter-1" from moderrs.mk:132 make: Unfinished modifier after "", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 2: ${VAR:C," - in target "mod-regex-delimiter-2" + in target "mod-regex-delimiter-2" from moderrs.mk:135 make: Unfinished modifier after "from", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 3: ${VAR:C,from" - in target "mod-regex-delimiter-3" + in target "mod-regex-delimiter-3" from moderrs.mk:138 make: Unfinished modifier after "", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 4: ${VAR:C,from," - in target "mod-regex-delimiter-4" + in target "mod-regex-delimiter-4" from moderrs.mk:141 make: Unfinished modifier after "to", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 5: ${VAR:C,from,to" - in target "mod-regex-delimiter-5" + in target "mod-regex-delimiter-5" from moderrs.mk:144 make: Unclosed expression, expecting "}" for modifier "C,from,to," while evaluating variable "VAR" with value "TheVariable" in command "@echo 6: ${VAR:C,from,to," - in target "mod-regex-delimiter-6" + in target "mod-regex-delimiter-6" from moderrs.mk:147 7: TheVariable 112358132134 15152535558513521534 make: Unknown modifier ":ts\65oct" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:ts\65oct} # bad modifier" - in target "mod-ts-parse-3" + in target "mod-ts-parse-3" from moderrs.mk:157 make: Unknown 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 command "@echo ${:U${FIB}:ts\65oct} # bad modifier, variable name is """ - in target "mod-ts-parse-4" + in target "mod-ts-parse-4" from moderrs.mk:160 make: Unknown modifier ":tsxy" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:tsxy} # modifier too long" - in target "mod-ts-parse-5" + in target "mod-ts-parse-5" from moderrs.mk:163 make: Unknown modifier ":t" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:t" - in target "mod-t-parse-1" + in target "mod-t-parse-1" from moderrs.mk:167 make: Unknown modifier ":txy" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:txy}" - in target "mod-t-parse-2" + in target "mod-t-parse-2" from moderrs.mk:170 make: Unknown modifier ":t" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:t}" - in target "mod-t-parse-3" + in target "mod-t-parse-3" from moderrs.mk:173 make: Unknown modifier ":t" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:t:M*}" - in target "mod-t-parse-4" + in target "mod-t-parse-4" from moderrs.mk:176 make: Unfinished modifier after "", expecting ":" while evaluating then-branch of condition "FIB" in command "@echo ${FIB:?" - in target "mod-ifelse-parse-1" + in target "mod-ifelse-parse-1" from moderrs.mk:180 make: Unfinished modifier after "then", expecting ":" while evaluating then-branch of condition "FIB" in command "@echo ${FIB:?then" - in target "mod-ifelse-parse-2" + in target "mod-ifelse-parse-2" from moderrs.mk:183 make: Unfinished modifier after "", expecting "}" while evaluating else-branch of condition "FIB" in command "@echo ${FIB:?then:" - in target "mod-ifelse-parse-3" + in target "mod-ifelse-parse-3" from moderrs.mk:186 make: Unfinished modifier after "else", expecting "}" while evaluating else-branch of condition "FIB" in command "@echo ${FIB:?then:else" - in target "mod-ifelse-parse-4" + in target "mod-ifelse-parse-4" from moderrs.mk:189 then 1 1 2 3 5 8 13 21 34 make: Unknown modifier ":__" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:__} # modifier name too long" - in target "mod-remember-parse" + in target "mod-remember-parse" from moderrs.mk:196 make: Unknown modifier ":3" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:3" - in target "mod-sysv-parse-1" + in target "mod-sysv-parse-1" from moderrs.mk:200 make: Unfinished modifier after "", expecting "}" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:3=" - in target "mod-sysv-parse-2" + in target "mod-sysv-parse-2" from moderrs.mk:203 make: Unfinished modifier after "x3", expecting "}" while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34" in command "@echo ${FIB:3=x3" - in target "mod-sysv-parse-3" + in target "mod-sysv-parse-3" from moderrs.mk:206 1 1 2 x3 5 8 1x3 21 34 exit status 2 diff --git a/unit-tests/opt-chdir.mk b/unit-tests/opt-chdir.mk index e94b8799af2e..19055aba0824 100644 --- a/unit-tests/opt-chdir.mk +++ b/unit-tests/opt-chdir.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-chdir.mk,v 1.7 2024/04/02 11:11:00 rillig Exp $ +# $NetBSD: opt-chdir.mk,v 1.8 2026/02/10 21:22:13 sjg Exp $ # # Tests for the -C command line option, which changes the directory at the # beginning. @@ -13,8 +13,10 @@ all: chdir-nonexistent # Changing to another directory is possible via the command line. # In this test, it is the root directory since almost any other directory # is not guaranteed to exist on every platform. +# Force MAKEOBJDIRPREFIX=/ to avoid looking elsewhere for .OBJDIR chdir-root: .PHONY .IGNORE - @MAKE_OBJDIR_CHECK_WRITABLE=no ${MAKE} -C / -V 'cwd: $${.CURDIR}' + @MAKE_OBJDIR_CHECK_WRITABLE=no MAKEOBJDIRPREFIX=/ \ + ${MAKE} -C / -V 'cwd: $${.CURDIR}' # Trying to change to a nonexistent directory exits immediately. # Note: just because the whole point of /nonexistent is that it should diff --git a/unit-tests/opt-debug-graph1.exp b/unit-tests/opt-debug-graph1.exp index 9dae95302318..43c49a957ebb 100644 --- a/unit-tests/opt-debug-graph1.exp +++ b/unit-tests/opt-debug-graph1.exp @@ -29,6 +29,7 @@ .MAKE.OS = <details omitted> .MAKE.PID = <details omitted> .MAKE.PPID = <details omitted> +.MAKE.SAVE_DOLLARS = <details omitted> .MAKE.UID = <details omitted> .MAKEFLAGS = -r -k -d g1 .MAKEOVERRIDES = # (empty) diff --git a/unit-tests/opt-debug-graph2.exp b/unit-tests/opt-debug-graph2.exp index e4160e413787..6fd8de68fd98 100644 --- a/unit-tests/opt-debug-graph2.exp +++ b/unit-tests/opt-debug-graph2.exp @@ -63,6 +63,7 @@ all : made-target error-target aborted-target .MAKE.OS = <details omitted> .MAKE.PID = <details omitted> .MAKE.PPID = <details omitted> +.MAKE.SAVE_DOLLARS = <details omitted> .MAKE.UID = <details omitted> .MAKEFLAGS = -r -k -d g2 .MAKEOVERRIDES = # (empty) diff --git a/unit-tests/opt-debug-graph3.exp b/unit-tests/opt-debug-graph3.exp index ccebfd7b16bc..8ce5d2e5cfa5 100644 --- a/unit-tests/opt-debug-graph3.exp +++ b/unit-tests/opt-debug-graph3.exp @@ -63,6 +63,7 @@ all : made-target error-target aborted-target .MAKE.OS = <details omitted> .MAKE.PID = <details omitted> .MAKE.PPID = <details omitted> +.MAKE.SAVE_DOLLARS = <details omitted> .MAKE.UID = <details omitted> .MAKEFLAGS = -r -k -d g3 .MAKEOVERRIDES = # (empty) diff --git a/unit-tests/opt-debug-jobs.exp b/unit-tests/opt-debug-jobs.exp index 6cda45107702..0e818245246f 100644 --- a/unit-tests/opt-debug-jobs.exp +++ b/unit-tests/opt-debug-jobs.exp @@ -1,6 +1,7 @@ job_pipe -1 -1, maxjobs 1, tokens 1, compat 0 TokenPool_Take: pid <pid>, aborting NONE, running 0 TokenPool_Take: pid <pid> took a token +MaybeSubMake: Looking for "make" echo ": expanded expression" { : expanded expression } || exit $? diff --git a/unit-tests/opt-jobs-internal.exp b/unit-tests/opt-jobs-internal.exp index 61c96256a2e4..a13d44bb38ed 100644 --- a/unit-tests/opt-jobs-internal.exp +++ b/unit-tests/opt-jobs-internal.exp @@ -3,12 +3,12 @@ make: error: invalid internal option "-J garbage" in "<curdir>" make: warning: Invalid internal option "-J" in "<curdir>"; see the manual page in make[2] in directory "<curdir>" direct-open: mode=compat -make: warning: Invalid internal option "-J" in "<curdir>"; see the manual page - in make[2] in directory "<curdir>" +.make[2]: warning: Invalid internal option "-J" in "<curdir>"; see the manual page + in .make[2] in directory "<curdir>" indirect-open: mode=compat indirect-expr: mode=parallel -make: warning: Invalid internal option "-J" in "<curdir>"; see the manual page - in make[2] in directory "<curdir>" +.make[2]: warning: Invalid internal option "-J" in "<curdir>"; see the manual page + in .make[2] in directory "<curdir>" indirect-comment: mode=compat indirect-silent-comment: mode=parallel indirect-expr-empty: mode=parallel diff --git a/unit-tests/opt-jobs-internal.mk b/unit-tests/opt-jobs-internal.mk index 13db820f86c1..4a1c39c75cd7 100644 --- a/unit-tests/opt-jobs-internal.mk +++ b/unit-tests/opt-jobs-internal.mk @@ -1,9 +1,12 @@ -# $NetBSD: opt-jobs-internal.mk,v 1.6 2025/05/23 21:05:56 rillig Exp $ +# $NetBSD: opt-jobs-internal.mk,v 1.10 2026/03/10 05:02:00 sjg Exp $ # # Tests for the (intentionally undocumented) internal -J command line option. +.if ${DEBUG_TEST:U:M${.PARSEFILE:R}} != "" +.MAKEFLAGS: -djg2 +.endif -# This test expects -.MAKE.ALWAYS_PASS_JOB_QUEUE= no +_make ?= .make${.MAKE.PID} +.export _make all: .PHONY @${MAKE} -f ${MAKEFILE} -j1 direct @@ -14,6 +17,7 @@ all: .PHONY @${MAKE} -f ${MAKEFILE} -j1 indirect-comment @${MAKE} -f ${MAKEFILE} -j1 indirect-silent-comment @${MAKE} -f ${MAKEFILE} -j1 indirect-expr-empty + @rm -f ${_make} detect-mode: .PHONY @mode=parallel @@ -33,8 +37,8 @@ direct-open: .PHONY @${MAKE} -f ${MAKEFILE} -J 31,32 detect-mode HEADING=${.TARGET} # expect: indirect-open: mode=compat -indirect-open: .PHONY - @${MAKE:U} -f ${MAKEFILE} detect-mode HEADING=${.TARGET} +indirect-open: .PHONY ${_make} + @./${_make} -f ${MAKEFILE} detect-mode HEADING=${.TARGET} # When a command in its unexpanded form contains the expression "${MAKE}" # without any modifiers, the file descriptors get passed around. @@ -45,9 +49,9 @@ indirect-expr: .PHONY # The "# make" comment starts directly after the leading tab and is thus not # considered a shell command line. No file descriptors are passed around. # expect: indirect-comment: mode=compat -indirect-comment: .PHONY +indirect-comment: .PHONY ${_make} # make - @${MAKE:U} -f ${MAKEFILE} detect-mode HEADING=${.TARGET} + @./${_make} -f ${MAKEFILE} detect-mode HEADING=${.TARGET} # When the "# make" comment is prefixed with "@", it becomes a shell command. # As that shell command contains the plain word "make", the file descriptors @@ -57,9 +61,12 @@ indirect-silent-comment: .PHONY @# make @${MAKE:U} -f ${MAKEFILE} detect-mode HEADING=${.TARGET} -# When a command in its unexpanded form contains the plain word "make", the -# file descriptors get passed around. # expect: indirect-expr-empty: mode=parallel indirect-expr-empty: .PHONY - @${:D make} @${MAKE:U} -f ${MAKEFILE} detect-mode HEADING=${.TARGET} + +${_make}: + @ln -s ${MAKE} ${.TARGET} + +# This test expects +.MAKE.ALWAYS_PASS_JOB_QUEUE= no diff --git a/unit-tests/opt-where-am-i.mk b/unit-tests/opt-where-am-i.mk index f1eeca920a32..1d849b8d8047 100644 --- a/unit-tests/opt-where-am-i.mk +++ b/unit-tests/opt-where-am-i.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-where-am-i.mk,v 1.4 2022/01/27 02:24:46 sjg Exp $ +# $NetBSD: opt-where-am-i.mk,v 1.5 2026/02/10 22:33:36 sjg Exp $ # # Tests for the -w command line option, which outputs the current directory # at the beginning and end of running make. This is useful when building @@ -6,9 +6,11 @@ # The first "Entering directory" is missing since the below .MAKEFLAGS comes # too late for it. +# We force MAKEOBJDIRPREFIX=/ to avoid looking elsewhere for .OBJDIR .MAKEFLAGS: -w all: .if ${.CURDIR} != "/" - @MAKE_OBJDIR_CHECK_WRITABLE=no ${MAKE} -r -f ${MAKEFILE:tA} -C / + @MAKE_OBJDIR_CHECK_WRITABLE=no MAKEOBJDIRPREFIX=/ \ + ${MAKE} -r -f ${MAKEFILE:tA} -C / .endif diff --git a/unit-tests/opt.exp b/unit-tests/opt.exp index daeecc8ca726..0680cbc2761f 100644 --- a/unit-tests/opt.exp +++ b/unit-tests/opt.exp @@ -1,11 +1,12 @@ -make -r -f /dev/null -V MAKEFLAGS - -r -k -d 0 +make -r -f /dev/null -V 'begin ${MAKEFLAGS} end' +begin -r -k -d 0 end make -: usage: make [-BeikNnqrSstWwX] [-C directory] [-D variable] [-d flags] [-f makefile] - [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file] - [-V variable] [-v variable] [variable=value] [target ...] + [-I directory] [-J private] [-j max_jobs] [-m directory] + [-T file] [-V variable] [-v variable] + [variable=value ...] [target ...] *** Error code 2 (ignored) make -r -f /dev/null -- -VAR=value -f /dev/null @@ -19,8 +20,9 @@ make: stopped making "-f /dev/null" in unit-tests make -? usage: make [-BeikNnqrSstWwX] [-C directory] [-D variable] [-d flags] [-f makefile] - [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file] - [-V variable] [-v variable] [variable=value] [target ...] + [-I directory] [-J private] [-j max_jobs] [-m directory] + [-T file] [-V variable] [-v variable] + [variable=value ...] [target ...] *** Error code 2 (ignored) exit status 0 diff --git a/unit-tests/opt.mk b/unit-tests/opt.mk index 939d5ec35aeb..e7861fffbf84 100644 --- a/unit-tests/opt.mk +++ b/unit-tests/opt.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt.mk,v 1.7 2023/02/25 00:07:08 rillig Exp $ +# $NetBSD: opt.mk,v 1.8 2026/02/08 11:02:03 rillig Exp $ # # Tests for the command line options. @@ -8,7 +8,7 @@ all: .IGNORE # The options from the top-level make are passed to the sub-makes via # the environment variable MAKEFLAGS. This is where the " -r -k -d 0" # comes from. See MainParseOption. - ${MAKE} -r -f /dev/null -V MAKEFLAGS + ${MAKE} -r -f /dev/null -V 'begin $${MAKEFLAGS} end' @echo # Just to see how the custom argument parsing code reacts to a syntax diff --git a/unit-tests/sh-errctl.exp b/unit-tests/sh-errctl.exp index 8419d215fe38..6dfa3fafc85f 100644 --- a/unit-tests/sh-errctl.exp +++ b/unit-tests/sh-errctl.exp @@ -1,6 +1,7 @@ job_pipe -1 -1, maxjobs 1, tokens 1, compat 0 TokenPool_Take: pid <pid>, aborting NONE, running 0 TokenPool_Take: pid <pid> took a token +MaybeSubMake: Looking for "make" # echo off echo silent # echo on diff --git a/unit-tests/suff-main-several.exp b/unit-tests/suff-main-several.exp index bb1fc91ea21d..a7bf6eb088e9 100644 --- a/unit-tests/suff-main-several.exp +++ b/unit-tests/suff-main-several.exp @@ -94,6 +94,7 @@ ParseDependency(.MAKEFLAGS: -d0 -dg1) .MAKE.OS = <details omitted> .MAKE.PID = <details omitted> .MAKE.PPID = <details omitted> +.MAKE.SAVE_DOLLARS = <details omitted> .MAKE.UID = <details omitted> .MAKEFLAGS = -r -k -d mps -d 0 -d g1 .MAKEOVERRIDES = # (empty) diff --git a/unit-tests/suff-transform-debug.exp b/unit-tests/suff-transform-debug.exp index ad0584f204d1..14d8b9050a08 100644 --- a/unit-tests/suff-transform-debug.exp +++ b/unit-tests/suff-transform-debug.exp @@ -20,6 +20,7 @@ .MAKE.OS = <details omitted> .MAKE.PID = <details omitted> .MAKE.PPID = <details omitted> +.MAKE.SAVE_DOLLARS = <details omitted> .MAKE.UID = <details omitted> .MAKEFLAGS = -r -k -d g1 .MAKEOVERRIDES = # (empty) diff --git a/unit-tests/var-recursive.exp b/unit-tests/var-recursive.exp index 97568873bf1b..768b41c4b0ff 100644 --- a/unit-tests/var-recursive.exp +++ b/unit-tests/var-recursive.exp @@ -23,7 +23,7 @@ sub-exit status 1 make: Variable VAR is recursive. while evaluating variable "VAR" with value "${VAR}" in command ": recursive-line-before <${VAR}> recursive-line-after" - in target "runtime" + in target "runtime" from var-recursive.mk:56 in make[1] in directory "<curdir>" sub-exit status 2 exit status 0 diff --git a/unit-tests/var-scope-local.exp b/unit-tests/var-scope-local.exp index eddf5985a0ed..dbf3f474d69e 100644 --- a/unit-tests/var-scope-local.exp +++ b/unit-tests/var-scope-local.exp @@ -67,5 +67,15 @@ Making var-scope-local-default.o with make 'global' and env 'global'. Making var-scope-local-subst.o with make 'global+local' and env 'global+local'. Making var-scope-local-shell.o with make 'output' and env 'output'. Making .USE var-scope-local-use.o with make 'global' and env 'global'. +begin pr-59073 compat +$@ is pr-59073/file.o59703 +$< is pr-59073/file.c59703 +$* is pr-59073/file +end pr-59073 compat +begin pr-59073 parallel +$@ is pr-59073/file.o59703 +$< is pr-59073/file.c59703 +$* is file +end pr-59073 parallel : all overwritten exit status 0 diff --git a/unit-tests/var-scope-local.mk b/unit-tests/var-scope-local.mk index 7a031373e7da..be10c4c9f7da 100644 --- a/unit-tests/var-scope-local.mk +++ b/unit-tests/var-scope-local.mk @@ -1,4 +1,4 @@ -# $NetBSD: var-scope-local.mk,v 1.11 2024/03/05 23:07:58 rillig Exp $ +# $NetBSD: var-scope-local.mk,v 1.12 2026/01/05 22:44:14 rillig Exp $ # # Tests for target-local variables, such as ${.TARGET} or $@. These variables # are relatively short-lived as they are created just before making the @@ -138,7 +138,9 @@ dir/subdir/inference-rule-chain.ir-gen-from: .PHONY # Custom local variables # # Additional target-local variables may be defined in dependency lines. +.if !make(pr-59703-mode) .MAKEFLAGS: -dv +.endif # In the following line, the ':=' may either be interpreted as an assignment # operator or as the dependency operator ':', followed by an empty variable # name and the assignment operator '='. It is the latter since in an @@ -154,7 +156,9 @@ one two:=three # word. # expect: Global: one two = three ${:Uone two}:=three +.if !make(pr-59703-mode) .MAKEFLAGS: -d0 +.endif .SUFFIXES: .c .o @@ -268,3 +272,44 @@ a_use: .USE VAR=use all: var-scope-local-use.o var-scope-local-use.o: a_use + + +# begin https://gnats.netbsd.org/59073 +# make(1) sets $* / $(.PREFIX) wrong in -j mode + +all: pr-59073 + +# expect: begin pr-59073 compat +# expect: $@ is pr-59073/file.o59703 +# expect: $< is pr-59073/file.c59703 +# expect: $* is pr-59073/file +# expect: end pr-59073 compat +# expect: begin pr-59073 parallel +# expect: $@ is pr-59073/file.o59703 +# expect: $< is pr-59073/file.c59703 +# FIXME: The subdirectory is missing. +# expect: $* is file +# expect: end pr-59073 parallel + +pr-59073: .PHONY + # This has to be an actual file; using a memory-only target + # generates the correct value for "$*". + @mkdir -p pr-59073 && touch pr-59073/file.c59703 + @echo begin pr-59073 compat + @MAKEFLAGS= ${MAKE} -r -f ${MAKEFILE} pr-59703-mode + @echo end pr-59073 compat + @echo begin pr-59073 parallel + @MAKEFLAGS= ${MAKE} -r -f ${MAKEFILE} -j1 pr-59703-mode + @echo end pr-59073 parallel + @rm -rf pr-59073 + +pr-59703-mode: pr-59073/file.o59703 + +.SUFFIXES: .c59703 .o59703 + +.c59703.o59703: + @echo '$$@ is $@' + @echo '$$< is $<' + @echo '$$* is $*' + +# end https://gnats.netbsd.org/59073 diff --git a/unit-tests/varmisc.exp b/unit-tests/varmisc.exp index 44b3c8e759cb..4d09e691de42 100644 --- a/unit-tests/varmisc.exp +++ b/unit-tests/varmisc.exp @@ -46,36 +46,36 @@ parse-dynamic: parse-dynamic parse-dynamic after varerror-unclosed-1:begin make: Unclosed variable "" in command "@echo $(" - in target "varerror-unclosed-2" + in target "varerror-unclosed-2" from varmisc.mk:195 make: Unclosed variable "UNCLOSED" in command "@echo $(UNCLOSED" - in target "varerror-unclosed-3" + in target "varerror-unclosed-3" from varmisc.mk:198 make: Unclosed variable "UNCLOSED" in command "@echo ${UNCLOSED" - in target "varerror-unclosed-4" + in target "varerror-unclosed-4" from varmisc.mk:201 make: Unclosed variable "PATTERN" while evaluating variable "UNCLOSED" with value "" in command "@echo ${UNCLOSED:M${PATTERN" - in target "varerror-unclosed-5" + in target "varerror-unclosed-5" from varmisc.mk:204 make: Unclosed expression, expecting "}" for modifier "M${PATTERN" while evaluating variable "UNCLOSED" with value "" in command "@echo ${UNCLOSED:M${PATTERN" - in target "varerror-unclosed-5" + in target "varerror-unclosed-5" from varmisc.mk:204 make: Unclosed variable "param" in command "@echo ${UNCLOSED.${param" - in target "varerror-unclosed-6" + in target "varerror-unclosed-6" from varmisc.mk:208 make: Unclosed variable "UNCLOSED." in command "@echo ${UNCLOSED.${param" - in target "varerror-unclosed-6" + in target "varerror-unclosed-6" from varmisc.mk:208 make: Unclosed variable "UNCLOSED.1" in command "@echo ${UNCLOSED.${:U1}" - in target "varerror-unclosed-7" + in target "varerror-unclosed-7" from varmisc.mk:213 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 command "@echo ${UNCLOSED_INDIR_2}" - in target "varerror-unclosed-8" + in target "varerror-unclosed-8" from varmisc.mk:217 target1-flags: we have: one two target2-flags: we have: one two three four exit status 2 diff --git a/unit-tests/varmod-assign.exp b/unit-tests/varmod-assign.exp index ae7f6787d124..2cbd7e525449 100644 --- a/unit-tests/varmod-assign.exp +++ b/unit-tests/varmod-assign.exp @@ -40,30 +40,30 @@ Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 make: Invalid attempt to assign "value" to variable "" via modifier "::=" while evaluating "${::=value}" with value "" in command "@echo $@: ${::=value}" - in target "mod-assign-empty-1" + in target "mod-assign-empty-1" from varmod-assign.mk:78 make: Invalid attempt to assign "overwritten" to variable "" via modifier "::=" while evaluating "${:Uvalue::=overwritten}" with value "value" in command "@echo $@: ${:Uvalue::=overwritten}" - in target "mod-assign-empty-2" + in target "mod-assign-empty-2" from varmod-assign.mk:84 make: Invalid attempt to assign "appended" to variable "" via modifier "::+=" while evaluating "${:Uvalue::+=appended}" with value "value" in command "@echo $@: ${:Uvalue::+=appended}" - in target "mod-assign-empty-3" + in target "mod-assign-empty-3" from varmod-assign.mk:90 mod-assign-empty-4: VAR=overwritten make: Unknown modifier "::x" while evaluating variable "ASSIGN" with value "" in command "@echo ${ASSIGN::x}" - in target "mod-assign-parse-1" + in target "mod-assign-parse-1" from varmod-assign.mk:103 sysv:y make: Unfinished modifier after "value # missing closing brace", expecting "}" while evaluating variable "ASSIGN" with value "" in command "@echo ${ASSIGN::=value # missing closing brace" - in target "mod-assign-parse-3" + in target "mod-assign-parse-3" from varmod-assign.mk:112 ok=word make: warning: Command " echo word; (exit 13) " exited with status 13 while evaluating variable "SH_ERR" with value "previous" in command "@${SH_ERR::!= echo word; (exit 13) } echo err=${SH_ERR}" - in target "mod-assign-shell-error" + in target "mod-assign-shell-error" from varmod-assign.mk:120 err=previous Command: TARGET_CMD_VAR = cmd-value Global: TARGET_GLOBAL_VAR = global-value diff --git a/unit-tests/varmod-hash.exp b/unit-tests/varmod-hash.exp index 1abc6bc92a9f..eb2490d27c3f 100644 --- a/unit-tests/varmod-hash.exp +++ b/unit-tests/varmod-hash.exp @@ -1,15 +1,15 @@ make: Unknown modifier ":has" while evaluating variable "12345" with value "12345" in command "@echo ${12345:L:has} # modifier name too short" - in target "step-1" + in target "step-1" from varmod-hash.mk:61 26bb0f5f 12345 make: Unknown modifier ":hasX" while evaluating variable "12345" with value "12345" in command "@echo ${12345:L:hasX} # misspelled" - in target "step-4" + in target "step-4" from varmod-hash.mk:67 make: Unknown modifier ":hashed" while evaluating variable "12345" with value "12345" in command "@echo ${12345:L:hashed} # modifier name too long" - in target "step-5" + in target "step-5" from varmod-hash.mk:69 exit status 2 diff --git a/unit-tests/varmod-loop-delete.exp b/unit-tests/varmod-loop-delete.exp index daacafc35561..7f31a606c10c 100644 --- a/unit-tests/varmod-loop-delete.exp +++ b/unit-tests/varmod-loop-delete.exp @@ -1,6 +1,12 @@ -make: varmod-loop-delete.mk:20: Cannot delete variable "VAR" while it is used +make -f varmod-loop-delete.mk delete-active-variable || true +make: varmod-loop-delete.mk:31: 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" + in make[1] in directory "<curdir>" make: Fatal errors encountered -- cannot continue -make: stopped making "all" in unit-tests -exit status 1 +make: stopped making "delete-active-variable" in unit-tests + +make -f varmod-loop-delete.mk delete-active-variable-in-target || true +: delete-active-variable-in-target: ' rest of the value' + +exit status 0 diff --git a/unit-tests/varmod-loop-delete.mk b/unit-tests/varmod-loop-delete.mk index 478a25e91f6e..7b7dc0a77b25 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.7 2024/08/29 20:20:36 rillig Exp $ +# $NetBSD: varmod-loop-delete.mk,v 1.9 2026/02/09 22:04:54 rillig Exp $ # # Tests for the variable modifier ':@', which as a side effect allows to # delete an arbitrary variable. @@ -11,6 +11,17 @@ # # See Var_Parse, comment 'the value of the variable must not change'. +all: .PHONY + ${MAKE} -f ${MAKEFILE} delete-active-variable || true + @echo + ${MAKE} -f ${MAKEFILE} delete-active-variable-in-target || true + @echo + # Disabled since the details of the crash depend on the execution + # environment. + #${MAKE} -f ${MAKEFILE} use-after-free + +delete-active-variable: .PHONY +.if make(delete-active-variable) # Set up the variable that deletes itself when it is evaluated. VAR= ${:U:@VAR@@} rest of the value @@ -18,12 +29,16 @@ VAR= ${:U:@VAR@@} rest of the value # defined in the global scope, it deletes itself. # expect+1: Cannot delete variable "VAR" while it is used EVAL:= ${VAR} -.if ${EVAL} != " rest of the value" -. error +. if ${EVAL} != " rest of the value" +. error +. endif .endif +delete-active-variable-in-target: .PHONY +.if make(delete-active-variable-in-target) VAR= ${:U:@VAR@@} rest of the value -all: .PHONY + +delete-active-variable-in-target: # In the command that is associated with a target, the scope is the # one from the target. That scope only contains a few variables like # '.TARGET', '.ALLSRC', '.IMPSRC'. Make does not expect that these @@ -32,3 +47,28 @@ all: .PHONY # There is no variable named 'VAR' in the local scope, so nothing # happens. : $@: '${VAR}' +# expect: : delete-active-variable-in-target: ' rest of the value' +.endif + + +# On NetBSD 11.99.x with jemalloc and MALLOC_CONF=junk:true, the output is: +# make: varmod-loop-delete.mk:72: Unknown modifier ":Z2" +# while evaluating "${:U 333 :@v@...${:Z1}@:Z2}" with value "...${:Z1}" +# while evaluating variable "INNER.1" with value "${:U 333 :@v@...${:Z1}@:Z2}" +# while evaluating variable "ZZZZZZZZZZZZ...${:Z1}" with value "ZZZZZZZZ" +# while evaluating "${:U 111 222 :@v@${v:S,^,${INNER.1},}@}" with value " 111 222 " +# while evaluating variable "OUTER" with value "${:U 111 222 :@v@${v:S,^,${INNER.1},}@}" +# in make in directory "<curdir>" +# Modifier part: "" +# ModifyWords: split "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" into 1 word +# Result of ${ZZZZZZZZZZZZ:S,^,${INNER.1},} is "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" (eval-keep-undefined, regular) +# Segmentation fault (core dumped) +use-after-free: .PHONY +.if make(use-after-free) +OUTER= ${:U 111 222 :@v@${v:S,^,${INNER.1},}@} +INNER.1= ${:U 333 :@v@...${:Z1}@:Z2} + +.MAKEFLAGS: -dcpv +_:= ${OUTER} +.MAKEFLAGS: -d0 +.endif diff --git a/unit-tests/varmod-select-words.exp b/unit-tests/varmod-select-words.exp index 4ac95ead0852..b731baf8869f 100644 --- a/unit-tests/varmod-select-words.exp +++ b/unit-tests/varmod-select-words.exp @@ -1,7 +1,7 @@ make: Invalid modifier ":[]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[]="${LIST:[]}" is an error'" - in target "mod-squarebrackets-empty" + in target "mod-squarebrackets-empty" from varmod-select-words.mk:54 LIST:[0]="one two three four five six" LIST:[0x0]="one two three four five six" LIST:[000]="one two three four five six" @@ -42,11 +42,11 @@ LIST:[1]="one" make: Invalid modifier ":[1.]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[1.]="${LIST:[1.]}" is an error'" - in target "mod-squarebrackets-n-error-1" + in target "mod-squarebrackets-n-error-1" from varmod-select-words.mk:100 make: Extra text after "[1]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[1].="${LIST:[1].}" is an error'" - in target "mod-squarebrackets-n-error-2" + in target "mod-squarebrackets-n-error-2" from varmod-select-words.mk:103 LIST:[2]="two" LIST:[6]="six" LIST:[7]="" @@ -54,11 +54,11 @@ LIST:[999]="" make: Invalid modifier ":[-]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[-]="${LIST:[-]}" is an error'" - in target "mod-squarebrackets-n-error-3" + in target "mod-squarebrackets-n-error-3" from varmod-select-words.mk:111 make: Invalid modifier ":[--]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[--]="${LIST:[--]}" is an error'" - in target "mod-squarebrackets-n-error-4" + in target "mod-squarebrackets-n-error-4" from varmod-select-words.mk:114 LIST:[-1]="six" LIST:[-2]="five" LIST:[-6]="one" @@ -80,20 +80,20 @@ LONGLIST:[012..0x12]="10 11 12 13 14 15 16 17 18" make: Invalid modifier ":[1.]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[1.]="${LIST:[1.]}" is an error'" - in target "mod-squarebrackets-start-end-error-1" + in target "mod-squarebrackets-start-end-error-1" from varmod-select-words.mk:137 make: Invalid modifier ":[1..]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[1..]="${LIST:[1..]}" is an error'" - in target "mod-squarebrackets-start-end-error-2" + in target "mod-squarebrackets-start-end-error-2" from varmod-select-words.mk:140 make: Invalid modifier ":[1.. ]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[1.. ]="${LIST:[1.. ]}" is an error'" - in target "mod-squarebrackets-start-end-error-3" + in target "mod-squarebrackets-start-end-error-3" from varmod-select-words.mk:143 LIST:[1..1]="one" make: Invalid modifier ":[1..1.]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'" - in target "mod-squarebrackets-start-end-error-4" + in target "mod-squarebrackets-start-end-error-4" from varmod-select-words.mk:148 LIST:[1..2]="one two" LIST:[2..1]="two one" LIST:[3..-2]="three four five" @@ -101,11 +101,11 @@ LIST:[-4..4]="three four" make: Invalid modifier ":[0..1]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[0..1]="${LIST:[0..1]}" is an error'" - in target "mod-squarebrackets-start-end-error-5" + in target "mod-squarebrackets-start-end-error-5" from varmod-select-words.mk:156 make: Invalid modifier ":[-1..0]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error'" - in target "mod-squarebrackets-start-end-error-6" + in target "mod-squarebrackets-start-end-error-6" from varmod-select-words.mk:159 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" @@ -122,7 +122,7 @@ LIST:[${AT}]="one two three four five six" make: Invalid modifier ":[]" while evaluating variable "LIST" with value "one two three four five six" in command "@echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error'" - in target "mod-squarebrackets-nested-error-1" + in target "mod-squarebrackets-nested-error-1" from varmod-select-words.mk:178 LIST:[${LONGLIST:[21]:S/2//}]="one" LIST:[${LIST:[#]}]="six" LIST:[${LIST:[${HASH}]}]="six" diff --git a/unit-tests/varmod-subst-regex.exp b/unit-tests/varmod-subst-regex.exp index 816b02248591..c8bc2ac035ea 100644 --- a/unit-tests/varmod-subst-regex.exp +++ b/unit-tests/varmod-subst-regex.exp @@ -1,67 +1,67 @@ make: Regex compilation error: (details omitted) while evaluating "${:Uword1 word2:C,****,____,g:C,word,____,:Q}." with value "word1 word2" in command "@echo $@: ${:Uword1 word2:C,****,____,g:C,word,____,:Q}." - in target "mod-regex-compile-error" + in target "mod-regex-compile-error" from varmod-subst-regex.mk:154 make: No subexpression \1 while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456" in command "@echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q}" - in target "mod-regex-limits-1" + in target "mod-regex-limits-1" from varmod-subst-regex.mk:159 make: No subexpression \1 while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456" in command "@echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q}" - in target "mod-regex-limits-1" + in target "mod-regex-limits-1" from varmod-subst-regex.mk:159 make: No subexpression \1 while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456" in command "@echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q}" - in target "mod-regex-limits-1" + in target "mod-regex-limits-1" from varmod-subst-regex.mk:159 make: No subexpression \1 while evaluating "${:U1 23 456:C,..,\1\1,:Q}" with value "1 23 456" in command "@echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q}" - in target "mod-regex-limits-1" + in target "mod-regex-limits-1" from varmod-subst-regex.mk:159 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 command "@echo $@:22-missing:${:U1 23 456:C,..,\2\2,:Q}" - in target "mod-regex-limits-3" + in target "mod-regex-limits-3" from varmod-subst-regex.mk:163 make: No subexpression \2 while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,..,\2\2,:Q}" - in target "mod-regex-limits-3" + in target "mod-regex-limits-3" from varmod-subst-regex.mk:163 make: No subexpression \2 while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,..,\2\2,:Q}" - in target "mod-regex-limits-3" + in target "mod-regex-limits-3" from varmod-subst-regex.mk:163 make: No subexpression \2 while evaluating "${:U1 23 456:C,..,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,..,\2\2,:Q}" - in target "mod-regex-limits-3" + in target "mod-regex-limits-3" from varmod-subst-regex.mk:163 make: No subexpression \2 while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,(.).,\2\2,:Q}" - in target "mod-regex-limits-4" + in target "mod-regex-limits-4" from varmod-subst-regex.mk:165 make: No subexpression \2 while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,(.).,\2\2,:Q}" - in target "mod-regex-limits-4" + in target "mod-regex-limits-4" from varmod-subst-regex.mk:165 make: No subexpression \2 while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,(.).,\2\2,:Q}" - in target "mod-regex-limits-4" + in target "mod-regex-limits-4" from varmod-subst-regex.mk:165 make: No subexpression \2 while evaluating "${:U1 23 456:C,(.).,\2\2,:Q}" with value "1 23 456" in command "@echo $@:22-missing:${:U1 23 456:C,(.).,\2\2,:Q}" - in target "mod-regex-limits-4" + in target "mod-regex-limits-4" from varmod-subst-regex.mk:165 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 command "@echo $@: ${UNDEF:Uvalue:C,[,,}" - in target "mod-regex-errors-1" + in target "mod-regex-errors-1" from varmod-subst-regex.mk:174 make: Unknown modifier ":Z" while evaluating "${:U:Z}y,W}" with value "" while evaluating variable "word" with value "word" in command "@echo $@: ${word:L:C,.*,x${:U:Z}y,W}" - in target "mod-regex-errors-2" + in target "mod-regex-errors-2" from varmod-subst-regex.mk:179 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 bc04bc5fffb9..5af0236975bb 100644 --- a/unit-tests/varmod-subst-regex.mk +++ b/unit-tests/varmod-subst-regex.mk @@ -1,6 +1,6 @@ -# $NetBSD: varmod-subst-regex.mk,v 1.12 2024/07/20 11:05:12 rillig Exp $ +# $NetBSD: varmod-subst-regex.mk,v 1.13 2026/01/03 22:40:38 rillig Exp $ # -# Tests for the :C,from,to, variable modifier. +# Tests for the :C,from,to, modifier. # report unmatched subexpressions .MAKEFLAGS: -dL @@ -23,7 +23,7 @@ all: unmatched-subexpression . error .endif -# The 'W' modifier treats the whole variable value as a single big word, +# The 'W' modifier treats the whole expression value as a single big word, # containing whitespace. This big word matches the regular expression, # therefore it gets replaced. Whitespace is preserved after replacing. .if ${:Ua b b c:C,a b,,W} != " b c" @@ -60,14 +60,16 @@ all: unmatched-subexpression # The modifier '1' applies the replacement at most once, across the whole # expression value, no matter whether it is a single big word or many small # words. -# -# Up to 2020-08-28, the manual page said that the modifiers '1' and 'g' -# were orthogonal, which was wrong. It doesn't make sense to specify both -# 'g' and '1' at the same time. .if ${:U12345 12345:C,.,\0\0,1} != "112345 12345" . error .endif +# When both '1' and 'g' are given, this means to replace all occurrences, +# but only in the first word where they are found, not in any remaining words. +.if ${:U 11111 22222 22222 :C,2,0,g1} != "11111 00000 22222" +. error +.endif + # A regular expression that matches the empty string applies before every # single character of the word. # XXX: Most other places where regular expression are used match at the end @@ -129,16 +131,30 @@ all: unmatched-subexpression .endif +# Just as in the ":S" modifier and the sed(1) utility, an "&" in the +# replacement part stands for the whole matched string. It can be escaped +# using a backslash. +.if ${:U 123 234 345 :C,2,&\&&,} != "12&23 2&234 345" +. error +.endif + +# When the ":C" modifier uses "&" as the delimiter for its parts, the "&" +# needs to be escaped. To get a literal "&" in the replacement, it needs +# to be written as "\\\&". When parsing the modifier part, the "\\" and "\&" +# result in "\" and "&", which then form the replacement "\&", and that is +# interpreted as a literal "&". +.if ${:U 123 234 345 :C&2&\&\\\&\&&} != "12&23 2&234 345" +. error +.endif + + # Multiple asterisks form an invalid regular expression. This produces an -# error message and (as of 2020-08-28) stops parsing in the middle of the -# expression. The unparsed part of the expression is then copied -# verbatim to the output, which is unexpected and can lead to strange shell -# commands being run. +# error message, and due to this error message, the shell command is not run. mod-regex-compile-error: @echo $@: ${:Uword1 word2:C,****,____,g:C,word,____,:Q}. -# These tests generate error messages but as of 2020-08-28 just continue -# parsing and execution as if nothing bad had happened. +# These tests generate error messages for the missing capturing groups. +# Due to these error messages, the echo commands are not executed. mod-regex-limits-1: @echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q} mod-regex-limits-2: @@ -158,9 +174,8 @@ 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 "". + # If the replacement pattern produces a parse error due to an + # unknown modifier, the faulty expression expands to "". @echo $@: ${word:L:C,.*,x${:U:Z}y,W} # In regular expressions with alternatives, not all capturing groups are diff --git a/unit-tests/varmod-subst.exp b/unit-tests/varmod-subst.exp index 8eec26e33ef5..fcd5ab4cd856 100644 --- a/unit-tests/varmod-subst.exp +++ b/unit-tests/varmod-subst.exp @@ -43,12 +43,17 @@ mod-subst-delimiter: 1 two 3 vertical line 1 two 3 right curly bracket 1 two 3 tilde +123 two34 345 circumflex accent +make: Regex compilation error: (details omitted) + while evaluating "${:U 123 234 345 :C^^2^two^:Q} circumflex accent" with value " 123 234 345 " + in command "@echo ${:U 123 234 345 :C^^2^two^:Q} circumflex accent" + in target "mod-subst-delimiter-circumflex" from varmod-subst.mk:250 mod-subst-chain: A B c. make: Unknown modifier ":i" while evaluating "${:Uvalue:S,a,x,i}." with value "vxlue" in command "@echo ${:Uvalue:S,a,x,i}." - in target "mod-subst-chain" + in target "mod-subst-chain" from varmod-subst.mk:268 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 e9da303515b2..ef7ad2358951 100644 --- a/unit-tests/varmod-subst.mk +++ b/unit-tests/varmod-subst.mk @@ -1,9 +1,10 @@ -# $NetBSD: varmod-subst.mk,v 1.17 2025/03/29 19:08:53 rillig Exp $ +# $NetBSD: varmod-subst.mk,v 1.18 2026/01/03 20:48:35 rillig Exp $ # # Tests for the :S,from,to, variable modifier. all: mod-subst all: mod-subst-delimiter +all: mod-subst-delimiter-circumflex all: mod-subst-chain all: mod-subst-dollar @@ -237,11 +238,22 @@ mod-subst-delimiter: @echo ${:U1 2 3:S}2}two}:Q} right curly bracket @echo ${:U1 2 3:S~2~two~:Q} tilde + +# When the ":S" modifier uses "^" to separate its parts, and when the first +# part starts with another "^", that "^" is interpreted as an anchor, not as +# the delimiter between the parts. +mod-subst-delimiter-circumflex: .PHONY + @echo ${:U 123 234 345 :S^^2^two^:Q} circumflex accent + # In the ":C" modifier, the "^" is not interpreted as an anchor, + # instead it is interpreted as the delimiter of the regular + # expression, thus making the regular expression empty and invalid. + @echo ${:U 123 234 345 :C^^2^two^:Q} circumflex accent + + # The :S and :C modifiers can be chained without a separating ':'. # This is not documented in the manual page. # It works because ApplyModifier_Subst scans for the known modifiers g1W -# and then just returns to ApplyModifiers. There, the colon is optionally -# skipped (see the *st.next == ':' at the end of the loop). +# and then just returns to ApplySingleModifier. There, the colon is skipped. # # Most other modifiers cannot be chained since their parsers skip until # the next ':' or '}' or ')'. diff --git a/unit-tests/varname-dot-make-save_dollars.mk b/unit-tests/varname-dot-make-save_dollars.mk index 31f228c220b2..a2134af51330 100644 --- a/unit-tests/varname-dot-make-save_dollars.mk +++ b/unit-tests/varname-dot-make-save_dollars.mk @@ -1,4 +1,4 @@ -# $NetBSD: varname-dot-make-save_dollars.mk,v 1.7 2021/12/03 18:43:52 rillig Exp $ +# $NetBSD: varname-dot-make-save_dollars.mk,v 1.8 2026/03/13 04:22:03 sjg Exp $ # # Tests for the special .MAKE.SAVE_DOLLARS variable, which controls whether # the assignment operator ':=' converts '$$' to a single '$' or keeps it @@ -8,11 +8,11 @@ # var-op-expand.mk for ':=' in general # varmisc.mk for parsing the boolean values -# Initially, the variable .MAKE.SAVE_DOLLARS is undefined. At this point the -# behavior of the assignment operator ':=' depends. NetBSD's usr.bin/make -# preserves the '$$' as-is, while the bmake distribution replaces '$$' with -# '$'. -.if ${.MAKE.SAVE_DOLLARS:Uundefined} != "undefined" +# The variable .MAKE.SAVE_DOLLARS is a boolean that controls the handling +# of '$$' during ':=' +# If "yes" (default for NetBSD's usr.bin/make) '$$' is left as-is. +# If "no" (default for bmake), '$$' is replaced with '$'. +.if ${.MAKE.SAVE_DOLLARS:Uundefined} == "undefined" . error .endif diff --git a/unit-tests/varname-make_stack_trace.exp b/unit-tests/varname-make_stack_trace.exp index c0f46cc5aa1e..5de66aa8bb8f 100644 --- a/unit-tests/varname-make_stack_trace.exp +++ b/unit-tests/varname-make_stack_trace.exp @@ -1,7 +1,7 @@ make: Unknown modifier ":Z" while evaluating "${:Z}" with value "" in command "@echo ${:Z}" - in target "provoke-error" + in target "provoke-error" from varname-make_stack_trace.mk:42 in make[2] in directory "<curdir>" *** Error code 2 (continuing) @@ -10,7 +10,7 @@ make: stopped making "disabled-compat" in unit-tests make: Unknown modifier ":Z" while evaluating "${:Z}" with value "" in command "@echo ${:Z}" - in target "provoke-error" + in target "provoke-error" from varname-make_stack_trace.mk:42 in make[2] in directory "<curdir>" *** [disabled-parallel] Error code 2 @@ -18,10 +18,10 @@ make: stopped making "disabled-parallel" in unit-tests make: Unknown modifier ":Z" while evaluating "${:Z}" with value "" in command "@echo ${:Z}" - in target "provoke-error" + in target "provoke-error" from varname-make_stack_trace.mk:42 in make[2] in directory "<curdir>" in command "make -f varname-make_stack_trace.mk provoke-error" - in target "enabled-compat" + in target "enabled-compat" from varname-make_stack_trace.mk:35 in make[1] in directory "<curdir>" *** Error code 2 (continuing) @@ -30,11 +30,21 @@ make: stopped making "enabled-compat" in unit-tests make: Unknown modifier ":Z" while evaluating "${:Z}" with value "" in command "@echo ${:Z}" - in target "provoke-error" + in target "provoke-error" from varname-make_stack_trace.mk:42 in make[2] in directory "<curdir>" - in target "enabled-parallel" + in target "enabled-parallel" from varname-make_stack_trace.mk:39 in make[1] in directory "<curdir>" *** [enabled-parallel] Error code 2 make: stopped making "enabled-parallel" in unit-tests +.make[5]: warning: Invalid internal option "-J" in "<curdir>"; see the manual page + in .make[5] in directory "<curdir>" + in target "multi-stage-4" from varname-make_stack_trace.mk:56 + in make[4] in directory "<curdir>" + in target "multi-stage-3" from varname-make_stack_trace.mk:54 + in make[3] in directory "<curdir>" + in target "multi-stage-2" from varname-make_stack_trace.mk:52 + in make[2] in directory "<curdir>" + in target "multi-stage-1" from varname-make_stack_trace.mk:50 + in make[1] in directory "<curdir>" exit status 0 diff --git a/unit-tests/varname-make_stack_trace.mk b/unit-tests/varname-make_stack_trace.mk index cba02559bafe..26b06448d583 100644 --- a/unit-tests/varname-make_stack_trace.mk +++ b/unit-tests/varname-make_stack_trace.mk @@ -1,4 +1,4 @@ -# $NetBSD: varname-make_stack_trace.mk,v 1.1 2025/06/13 03:51:18 rillig Exp $ +# $NetBSD: varname-make_stack_trace.mk,v 1.8 2026/03/10 05:02:00 sjg Exp $ # # Tests for the MAKE_STACK_TRACE environment variable, which controls whether # to print inter-process stack traces that are useful to narrow down where an @@ -11,27 +11,53 @@ # with the space for the command line arguments, and long command lines are # already written to a temporary file by Cmd_Exec to not overwhelm this space. +_make ?= .make${.MAKE.PID} +.export _make + all: .PHONY @${MAKE} -f ${MAKEFILE} disabled-compat || : @${MAKE} -f ${MAKEFILE} -j1 disabled-parallel || : @MAKE_STACK_TRACE=yes ${MAKE} -f ${MAKEFILE} enabled-compat || : @MAKE_STACK_TRACE=yes ${MAKE} -f ${MAKEFILE} -j1 enabled-parallel || : + @MAKE_STACK_TRACE=yes ${MAKE} -f ${MAKEFILE} -j1 multi-stage-1 + @rm -f ${_make} -# expect-not: in target "disabled-compat" +# expect-not-matches: in target "disabled%-compat" disabled-compat: .PHONY @${MAKE} -f ${MAKEFILE} provoke-error -# expect-not: in target "disabled-parallel" +# expect-not-matches: in target "disabled%-parallel" disabled-parallel: .PHONY @${MAKE} -f ${MAKEFILE} provoke-error -# expect: in target "enabled-compat" +# expect: in target "enabled-compat" from varname-make_stack_trace.mk:35 enabled-compat: .PHONY @${MAKE} -f ${MAKEFILE} provoke-error -# expect: in target "enabled-parallel" +# expect: in target "enabled-parallel" from varname-make_stack_trace.mk:39 enabled-parallel: .PHONY @${MAKE} -f ${MAKEFILE} provoke-error provoke-error: .PHONY @echo ${:Z} + +# The stack trace must be printed exactly once. +# expect: in target "multi-stage-4" from varname-make_stack_trace.mk:56 +# expect: in target "multi-stage-1" from varname-make_stack_trace.mk:50 +# expect-not-matches: in target "multi%-stage%-4" +# expect-not-matches: in target "multi%-stage%-1" +multi-stage-1: .PHONY ${_make} + @${MAKE} -f ${MAKEFILE} -j1 multi-stage-2 +multi-stage-2: .PHONY + @${MAKE} -f ${MAKEFILE} -j1 multi-stage-3 +multi-stage-3: .PHONY + @${MAKE} -f ${MAKEFILE} -j1 multi-stage-4 +multi-stage-4: .PHONY + @./${_make} -f ${MAKEFILE} -j1 multi-stage-5 +multi-stage-5: .PHONY + +${_make}: + @ln -s ${MAKE} ${.TARGET} + +# for FreeBSD and similar make sure we get the expected errors. +.MAKE.ALWAYS_PASS_JOB_QUEUE= no |
