aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2023-06-27 20:38:02 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2023-06-27 20:57:58 +0000
commit148ee84570001f46b7b667c86573d378101c3801 (patch)
tree2c9bcc97572cccafbff92de13acf1ebf147a061d
parentb374a3921d97bdb20b103aaeb91988c3d355ea71 (diff)
parent3e39ce563b9ba25883e5aa37d9799eda9e57c1e0 (diff)
downloadsrc-148ee84570001f46b7b667c86573d378101c3801.tar.gz
src-148ee84570001f46b7b667c86573d378101c3801.zip
Merge bmake-20230622
Merge commit '3e39ce563b9ba25883e5aa37d9799eda9e57c1e0'
-rw-r--r--contrib/bmake/ChangeLog71
-rw-r--r--contrib/bmake/FILES6
-rw-r--r--contrib/bmake/Makefile6
-rw-r--r--contrib/bmake/VERSION2
-rwxr-xr-xcontrib/bmake/boot-strap2
-rw-r--r--contrib/bmake/buf.c6
-rw-r--r--contrib/bmake/buf.h4
-rw-r--r--contrib/bmake/cond.c101
-rw-r--r--contrib/bmake/dir.c14
-rw-r--r--contrib/bmake/for.c40
-rw-r--r--contrib/bmake/make.h19
-rw-r--r--contrib/bmake/mk/ChangeLog46
-rw-r--r--contrib/bmake/mk/dirdeps.mk73
-rw-r--r--contrib/bmake/mk/host-target.mk31
-rw-r--r--contrib/bmake/mk/install-mk4
-rw-r--r--contrib/bmake/mk/meta.autodep.mk5
-rw-r--r--contrib/bmake/mk/sys.dirdeps.mk46
-rw-r--r--contrib/bmake/mk/sys.vars.mk11
-rw-r--r--[-rwxr-xr-x]contrib/bmake/os.sh16
-rw-r--r--contrib/bmake/parse.c106
-rw-r--r--contrib/bmake/str.c116
-rw-r--r--contrib/bmake/str.h9
-rw-r--r--contrib/bmake/unit-tests/Makefile17
-rw-r--r--contrib/bmake/unit-tests/cmdline-undefined.exp24
-rw-r--r--contrib/bmake/unit-tests/cmdline-undefined.mk14
-rw-r--r--contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp4
-rwxr-xr-xcontrib/bmake/unit-tests/cond-cmp-numeric-eq.mk4
-rwxr-xr-xcontrib/bmake/unit-tests/cond-cmp-unary.exp2
-rwxr-xr-xcontrib/bmake/unit-tests/cond-cmp-unary.mk11
-rw-r--r--contrib/bmake/unit-tests/cond-eof.exp6
-rw-r--r--contrib/bmake/unit-tests/cond-eof.mk10
-rw-r--r--contrib/bmake/unit-tests/cond-func-defined.exp10
-rw-r--r--contrib/bmake/unit-tests/cond-func-defined.mk8
-rw-r--r--contrib/bmake/unit-tests/cond-func-empty.exp4
-rw-r--r--contrib/bmake/unit-tests/cond-func-empty.mk7
-rw-r--r--contrib/bmake/unit-tests/cond-func-make.exp1
-rw-r--r--contrib/bmake/unit-tests/cond-func-make.mk7
-rw-r--r--contrib/bmake/unit-tests/cond-func.exp18
-rw-r--r--contrib/bmake/unit-tests/cond-func.mk12
-rw-r--r--contrib/bmake/unit-tests/cond-op-and-lint.exp2
-rw-r--r--contrib/bmake/unit-tests/cond-op-and-lint.mk3
-rw-r--r--contrib/bmake/unit-tests/cond-op-and.exp8
-rw-r--r--contrib/bmake/unit-tests/cond-op-and.mk6
-rw-r--r--contrib/bmake/unit-tests/cond-op-not.exp12
-rw-r--r--contrib/bmake/unit-tests/cond-op-not.mk8
-rw-r--r--contrib/bmake/unit-tests/cond-op-or-lint.exp2
-rw-r--r--contrib/bmake/unit-tests/cond-op-or-lint.mk3
-rw-r--r--contrib/bmake/unit-tests/cond-op-or.exp8
-rw-r--r--contrib/bmake/unit-tests/cond-op-or.mk6
-rw-r--r--contrib/bmake/unit-tests/cond-op-parentheses.exp4
-rw-r--r--contrib/bmake/unit-tests/cond-op-parentheses.mk4
-rw-r--r--contrib/bmake/unit-tests/cond-op.exp37
-rw-r--r--contrib/bmake/unit-tests/cond-op.mk28
-rw-r--r--contrib/bmake/unit-tests/cond-token-number.exp8
-rw-r--r--contrib/bmake/unit-tests/cond-token-number.mk6
-rw-r--r--contrib/bmake/unit-tests/cond-token-plain.exp30
-rw-r--r--contrib/bmake/unit-tests/cond-token-plain.mk13
-rw-r--r--contrib/bmake/unit-tests/cond-token-string.exp20
-rw-r--r--contrib/bmake/unit-tests/cond-token-string.mk14
-rw-r--r--contrib/bmake/unit-tests/cond-token-var.exp8
-rw-r--r--contrib/bmake/unit-tests/cond-token-var.mk8
-rwxr-xr-xcontrib/bmake/unit-tests/cond-undef-lint.exp14
-rwxr-xr-xcontrib/bmake/unit-tests/cond-undef-lint.mk9
-rw-r--r--contrib/bmake/unit-tests/dep-colon-bug-cross-file.exp4
-rw-r--r--contrib/bmake/unit-tests/dep-colon-bug-cross-file.mk4
-rw-r--r--contrib/bmake/unit-tests/dep-wildcards.mk8
-rw-r--r--contrib/bmake/unit-tests/dep.mk14
-rw-r--r--contrib/bmake/unit-tests/deptgt-begin.exp4
-rw-r--r--contrib/bmake/unit-tests/deptgt-begin.mk4
-rw-r--r--contrib/bmake/unit-tests/deptgt-delete_on_error.mk2
-rw-r--r--contrib/bmake/unit-tests/deptgt.exp22
-rw-r--r--contrib/bmake/unit-tests/deptgt.mk5
-rw-r--r--contrib/bmake/unit-tests/directive-elif.exp36
-rw-r--r--contrib/bmake/unit-tests/directive-elif.mk25
-rw-r--r--contrib/bmake/unit-tests/directive-else.exp14
-rw-r--r--contrib/bmake/unit-tests/directive-else.mk12
-rw-r--r--contrib/bmake/unit-tests/directive-endfor.exp2
-rw-r--r--contrib/bmake/unit-tests/directive-endfor.mk3
-rw-r--r--contrib/bmake/unit-tests/directive-endif.exp8
-rw-r--r--contrib/bmake/unit-tests/directive-endif.mk28
-rw-r--r--contrib/bmake/unit-tests/directive-error.exp2
-rw-r--r--contrib/bmake/unit-tests/directive-error.mk3
-rw-r--r--contrib/bmake/unit-tests/directive-for-break.exp1
-rw-r--r--contrib/bmake/unit-tests/directive-for-break.mk8
-rw-r--r--contrib/bmake/unit-tests/directive-for-empty.exp10
-rw-r--r--contrib/bmake/unit-tests/directive-for-empty.mk6
-rw-r--r--contrib/bmake/unit-tests/directive-for-errors.exp28
-rw-r--r--contrib/bmake/unit-tests/directive-for-errors.mk4
-rw-r--r--contrib/bmake/unit-tests/directive-for-escape.exp151
-rw-r--r--contrib/bmake/unit-tests/directive-for-escape.mk10
-rwxr-xr-xcontrib/bmake/unit-tests/directive-for-generating-endif.exp8
-rwxr-xr-xcontrib/bmake/unit-tests/directive-for-generating-endif.mk6
-rw-r--r--contrib/bmake/unit-tests/directive-for-if.exp6
-rw-r--r--contrib/bmake/unit-tests/directive-for-if.mk5
-rw-r--r--contrib/bmake/unit-tests/directive-for-lines.exp12
-rw-r--r--contrib/bmake/unit-tests/directive-for-lines.mk8
-rwxr-xr-xcontrib/bmake/unit-tests/directive-for.exp60
-rwxr-xr-xcontrib/bmake/unit-tests/directive-for.mk10
-rw-r--r--contrib/bmake/unit-tests/directive-if.exp28
-rw-r--r--contrib/bmake/unit-tests/directive-if.mk10
-rw-r--r--contrib/bmake/unit-tests/directive-ifmake.exp14
-rw-r--r--contrib/bmake/unit-tests/directive-ifmake.mk9
-rw-r--r--contrib/bmake/unit-tests/directive-ifndef.exp2
-rw-r--r--contrib/bmake/unit-tests/directive-ifndef.mk33
-rwxr-xr-xcontrib/bmake/unit-tests/directive-include-fatal.exp2
-rwxr-xr-xcontrib/bmake/unit-tests/directive-include-fatal.mk3
-rw-r--r--contrib/bmake/unit-tests/directive-include-guard.exp88
-rw-r--r--contrib/bmake/unit-tests/directive-include-guard.mk552
-rwxr-xr-xcontrib/bmake/unit-tests/directive-include.exp12
-rwxr-xr-xcontrib/bmake/unit-tests/directive-include.mk6
-rw-r--r--contrib/bmake/unit-tests/directive-info.exp24
-rw-r--r--contrib/bmake/unit-tests/directive-info.mk19
-rw-r--r--contrib/bmake/unit-tests/directive-misspellings.exp84
-rw-r--r--contrib/bmake/unit-tests/directive-misspellings.mk46
-rw-r--r--contrib/bmake/unit-tests/directive-undef.exp6
-rw-r--r--contrib/bmake/unit-tests/directive-undef.mk5
-rw-r--r--contrib/bmake/unit-tests/directive-unexport-env.exp6
-rw-r--r--contrib/bmake/unit-tests/directive-unexport-env.mk5
-rw-r--r--contrib/bmake/unit-tests/directive-unexport.exp8
-rw-r--r--contrib/bmake/unit-tests/directive-unexport.mk5
-rw-r--r--contrib/bmake/unit-tests/directive-warning.exp14
-rw-r--r--contrib/bmake/unit-tests/directive-warning.mk9
-rw-r--r--contrib/bmake/unit-tests/doterror.mk3
-rw-r--r--contrib/bmake/unit-tests/error.exp6
-rw-r--r--contrib/bmake/unit-tests/error.mk5
-rw-r--r--contrib/bmake/unit-tests/export-env.mk6
-rw-r--r--contrib/bmake/unit-tests/forsubst.exp2
-rw-r--r--contrib/bmake/unit-tests/forsubst.mk22
-rw-r--r--contrib/bmake/unit-tests/include-main.exp10
-rw-r--r--contrib/bmake/unit-tests/include-main.mk6
-rw-r--r--contrib/bmake/unit-tests/modmatch.exp17
-rw-r--r--contrib/bmake/unit-tests/modmatch.mk30
-rw-r--r--contrib/bmake/unit-tests/modmisc.exp1
-rw-r--r--contrib/bmake/unit-tests/modmisc.mk10
-rw-r--r--contrib/bmake/unit-tests/opt-debug-file.exp6
-rw-r--r--contrib/bmake/unit-tests/opt-debug-file.mk5
-rw-r--r--contrib/bmake/unit-tests/opt-debug-for.exp12
-rw-r--r--contrib/bmake/unit-tests/opt-debug-hash.exp2
-rw-r--r--contrib/bmake/unit-tests/opt-debug-hash.mk3
-rw-r--r--contrib/bmake/unit-tests/opt-debug-lint.exp14
-rw-r--r--contrib/bmake/unit-tests/opt-debug-lint.mk9
-rw-r--r--contrib/bmake/unit-tests/opt-debug-parse.exp28
-rw-r--r--contrib/bmake/unit-tests/opt-debug-parse.mk5
-rw-r--r--contrib/bmake/unit-tests/opt-warnings-as-errors.exp4
-rw-r--r--contrib/bmake/unit-tests/opt-warnings-as-errors.mk4
-rw-r--r--contrib/bmake/unit-tests/parse.exp2
-rw-r--r--contrib/bmake/unit-tests/parse.mk3
-rw-r--r--contrib/bmake/unit-tests/recursive.exp4
-rw-r--r--contrib/bmake/unit-tests/recursive.mk4
-rw-r--r--contrib/bmake/unit-tests/var-eval-short.exp8
-rw-r--r--contrib/bmake/unit-tests/var-eval-short.mk4
-rw-r--r--contrib/bmake/unit-tests/var-op-append.mk19
-rw-r--r--contrib/bmake/unit-tests/var-op-assign.exp4
-rw-r--r--contrib/bmake/unit-tests/var-op-assign.mk4
-rw-r--r--contrib/bmake/unit-tests/var-op-expand.exp6
-rw-r--r--contrib/bmake/unit-tests/var-op-expand.mk4
-rw-r--r--contrib/bmake/unit-tests/var-op-shell.exp8
-rw-r--r--contrib/bmake/unit-tests/var-op-shell.mk6
-rw-r--r--contrib/bmake/unit-tests/var-readonly.mk9
-rw-r--r--contrib/bmake/unit-tests/var-recursive.exp12
-rw-r--r--contrib/bmake/unit-tests/var-recursive.mk4
-rw-r--r--contrib/bmake/unit-tests/var-scope-cmdline.exp4
-rw-r--r--contrib/bmake/unit-tests/var-scope-cmdline.mk4
-rw-r--r--contrib/bmake/unit-tests/vardebug.exp6
-rw-r--r--contrib/bmake/unit-tests/vardebug.mk5
-rw-r--r--contrib/bmake/unit-tests/varmod-assign-shell.exp2
-rw-r--r--contrib/bmake/unit-tests/varmod-assign-shell.mk3
-rw-r--r--contrib/bmake/unit-tests/varmod-edge.exp42
-rw-r--r--contrib/bmake/unit-tests/varmod-edge.mk23
-rw-r--r--contrib/bmake/unit-tests/varmod-gmtime.exp20
-rw-r--r--contrib/bmake/unit-tests/varmod-gmtime.mk12
-rw-r--r--contrib/bmake/unit-tests/varmod-ifelse.exp24
-rw-r--r--contrib/bmake/unit-tests/varmod-ifelse.mk13
-rw-r--r--contrib/bmake/unit-tests/varmod-indirect.exp32
-rw-r--r--contrib/bmake/unit-tests/varmod-indirect.mk13
-rw-r--r--contrib/bmake/unit-tests/varmod-localtime.exp20
-rw-r--r--contrib/bmake/unit-tests/varmod-localtime.mk12
-rw-r--r--contrib/bmake/unit-tests/varmod-loop-delete.exp2
-rw-r--r--contrib/bmake/unit-tests/varmod-loop-delete.mk3
-rw-r--r--contrib/bmake/unit-tests/varmod-loop-varname.exp16
-rw-r--r--contrib/bmake/unit-tests/varmod-loop-varname.mk10
-rwxr-xr-xcontrib/bmake/unit-tests/varmod-match-escape.exp6
-rwxr-xr-xcontrib/bmake/unit-tests/varmod-match-escape.mk37
-rw-r--r--contrib/bmake/unit-tests/varmod-match.exp12
-rw-r--r--contrib/bmake/unit-tests/varmod-match.mk25
-rw-r--r--contrib/bmake/unit-tests/varmod-order.exp20
-rw-r--r--contrib/bmake/unit-tests/varmod-order.mk13
-rw-r--r--contrib/bmake/unit-tests/varmod-range.exp20
-rw-r--r--contrib/bmake/unit-tests/varmod-range.mk12
-rw-r--r--contrib/bmake/unit-tests/varmod-subst.mk84
-rw-r--r--contrib/bmake/unit-tests/varmod-sysv.exp2
-rw-r--r--contrib/bmake/unit-tests/varmod-sysv.mk3
-rw-r--r--contrib/bmake/unit-tests/varmod-to-abs.exp4
-rw-r--r--contrib/bmake/unit-tests/varmod-to-abs.mk5
-rw-r--r--contrib/bmake/unit-tests/varmod-to-separator.exp28
-rw-r--r--contrib/bmake/unit-tests/varmod-to-separator.mk14
-rw-r--r--contrib/bmake/unit-tests/varmod.exp10
-rw-r--r--contrib/bmake/unit-tests/varmod.mk7
-rw-r--r--contrib/bmake/unit-tests/varname-dollar.exp8
-rw-r--r--contrib/bmake/unit-tests/varname-dollar.mk6
-rw-r--r--contrib/bmake/unit-tests/varname-dot-makeflags.exp12
-rw-r--r--contrib/bmake/unit-tests/varname-dot-makeflags.mk5
-rw-r--r--contrib/bmake/unit-tests/varname-dot-parsedir.exp6
-rw-r--r--contrib/bmake/unit-tests/varname-dot-parsedir.mk12
-rw-r--r--contrib/bmake/unit-tests/varname-dot-parsefile.exp6
-rw-r--r--contrib/bmake/unit-tests/varname-dot-parsefile.mk12
-rw-r--r--contrib/bmake/unit-tests/varname-makeflags.mk10
-rw-r--r--contrib/bmake/unit-tests/varname.exp6
-rw-r--r--contrib/bmake/unit-tests/varname.mk5
-rw-r--r--contrib/bmake/unit-tests/varparse-dynamic.exp4
-rw-r--r--contrib/bmake/unit-tests/varparse-dynamic.mk9
-rw-r--r--contrib/bmake/unit-tests/varparse-errors.exp8
-rw-r--r--contrib/bmake/unit-tests/varparse-errors.mk6
-rw-r--r--contrib/bmake/var.c115
-rw-r--r--usr.bin/bmake/Makefile6
-rw-r--r--usr.bin/bmake/Makefile.config2
-rw-r--r--usr.bin/bmake/unit-tests/Makefile17
217 files changed, 2692 insertions, 1119 deletions
diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog
index fbaf247d3848..dd1fdf110ab4 100644
--- a/contrib/bmake/ChangeLog
+++ b/contrib/bmake/ChangeLog
@@ -1,3 +1,74 @@
+2023-06-22 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230622
+ Merge with NetBSD make, pick up
+ o optimize string matching for ':M' and ':N'
+ o warn about malformed patterns in ':M', ':N' and '.if make(...)'
+
+2023-06-21 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230621
+ Merge with NetBSD make, pick up
+ o more extensive tests for include guards
+ o parse.c: if a guard is already defined a file that uses the same
+ guard is still guarded by it.
+
+2023-06-20 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230620
+ Merge with NetBSD make, pick up
+ o allow guards to be targets as well as variables
+ The guard targets may include variable references like
+ __${.PARSEDIR:tA}/${.PARSEFILE}__
+
+2023-06-19 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230619
+ Merge with NetBSD make, pick up
+ o unit test for .undef of readOnly vars
+ o optimization for makefiles protected from multiple-inclusion
+ skip even opening the file after first include.
+ Initially this only handles makefiles guarded by a variable
+ target guards are next.
+
+2023-06-16 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230616
+ Merge with NetBSD make, pick up
+ o var.c: do not allow delete of readOnly variable
+
+2023-06-03 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230601
+ Merge with NetBSD make, pick up
+ o parse.c: .break takes no args
+ o lots of unit test updates
+
+2023-05-29 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * unit-tests/Makefile: skip tests that require /dev/filemon
+ if it does not exists - issue a warning.
+
+2023-05-22 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230522
+ Fix building on darwin ppc
+
+ * os.sh (MACHINE): Darwin powerpc cannot use `uname -m`
+ also recent NetBSD uses x86_64 for MACHINE_ARCH so conform.
+
+2023-05-15 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230515
+
+ * Makefile (COPTS.filemon_ktrace.c): NetBSD 7 needs help to
+ compile filemon_ktrace.c
+
+2023-05-13 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20230512
+ o sys.dirdeps.mk - broke after-import target
+
2023-05-10 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230510
diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES
index 5ec98a096339..e557147c85b1 100644
--- a/contrib/bmake/FILES
+++ b/contrib/bmake/FILES
@@ -356,6 +356,8 @@ unit-tests/directive-ifnmake.exp
unit-tests/directive-ifnmake.mk
unit-tests/directive-include-fatal.exp
unit-tests/directive-include-fatal.mk
+unit-tests/directive-include-guard.exp
+unit-tests/directive-include-guard.mk
unit-tests/directive-include.exp
unit-tests/directive-include.mk
unit-tests/directive-info.exp
@@ -392,8 +394,6 @@ unit-tests/export-variants.exp
unit-tests/export-variants.mk
unit-tests/export.exp
unit-tests/export.mk
-unit-tests/forsubst.exp
-unit-tests/forsubst.mk
unit-tests/gnode-submake.exp
unit-tests/gnode-submake.mk
unit-tests/hanoi-include.exp
@@ -429,8 +429,6 @@ unit-tests/meta-cmd-cmp.mk
unit-tests/meta-ignore.inc
unit-tests/moderrs.exp
unit-tests/moderrs.mk
-unit-tests/modmatch.exp
-unit-tests/modmatch.mk
unit-tests/modmisc.exp
unit-tests/modmisc.mk
unit-tests/objdir-writable.exp
diff --git a/contrib/bmake/Makefile b/contrib/bmake/Makefile
index 212885f7b900..22e92b4da9ac 100644
--- a/contrib/bmake/Makefile
+++ b/contrib/bmake/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.124 2023/02/25 20:27:44 sjg Exp $
+# $Id: Makefile,v 1.125 2023/05/17 00:15:46 sjg Exp $
PROG= bmake
@@ -68,7 +68,9 @@ FILEMON_H ?= /usr/include/dev/filemon/filemon.h
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
.endif
-.endif # USE_FILEMON == dev
+.elif ${USE_FILEMON} == "ktrace"
+COPTS.filemon_ktrace.c += -Wno-error=unused-parameter
+.endif
.endif # USE_FILEMON
diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION
index b49eb8cc7f26..f82791fcbac8 100644
--- a/contrib/bmake/VERSION
+++ b/contrib/bmake/VERSION
@@ -1,2 +1,2 @@
# keep this compatible with sh and make
-_MAKE_VERSION=20230510
+_MAKE_VERSION=20230622
diff --git a/contrib/bmake/boot-strap b/contrib/bmake/boot-strap
index 40984edcbe62..8892f2b1c990 100755
--- a/contrib/bmake/boot-strap
+++ b/contrib/bmake/boot-strap
@@ -420,7 +420,7 @@ op_build() {
op_test() {
[ -x bmake ] || op_build
- Bmake test "$@" || exit 1
+ Bmake test "$@" TEST_MAKE=$objdir/bmake || exit 1
}
op_clean() {
diff --git a/contrib/bmake/buf.c b/contrib/bmake/buf.c
index 73b2eac17d4f..845a68c46330 100644
--- a/contrib/bmake/buf.c
+++ b/contrib/bmake/buf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.c,v 1.55 2022/01/08 17:25:19 rillig Exp $ */
+/* $NetBSD: buf.c,v 1.56 2023/06/01 07:44:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -75,7 +75,7 @@
#include "make.h"
/* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: buf.c,v 1.55 2022/01/08 17:25:19 rillig Exp $");
+MAKE_RCSID("$NetBSD: buf.c,v 1.56 2023/06/01 07:44:10 rillig Exp $");
/* Make space in the buffer for adding at least 16 more bytes. */
void
@@ -106,7 +106,7 @@ Buf_AddBytes(Buffer *buf, const char *bytes, size_t bytes_len)
/* Add the bytes between start and end to the buffer. */
void
-Buf_AddBytesBetween(Buffer *buf, const char *start, const char *end)
+Buf_AddRange(Buffer *buf, const char *start, const char *end)
{
Buf_AddBytes(buf, start, (size_t)(end - start));
}
diff --git a/contrib/bmake/buf.h b/contrib/bmake/buf.h
index 14d048bfa514..ccd7d513b211 100644
--- a/contrib/bmake/buf.h
+++ b/contrib/bmake/buf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.h,v 1.47 2022/01/08 17:25:19 rillig Exp $ */
+/* $NetBSD: buf.h,v 1.48 2023/06/01 07:44:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -116,7 +116,7 @@ Buf_EndsWith(const Buffer *buf, char ch)
}
void Buf_AddBytes(Buffer *, const char *, size_t);
-void Buf_AddBytesBetween(Buffer *, const char *, const char *);
+void Buf_AddRange(Buffer *, const char *, const char *);
void Buf_AddStr(Buffer *, const char *);
void Buf_AddInt(Buffer *, int);
void Buf_AddFlag(Buffer *, bool, const char *);
diff --git a/contrib/bmake/cond.c b/contrib/bmake/cond.c
index a7cd7e833f5d..9a389ae6a92d 100644
--- a/contrib/bmake/cond.c
+++ b/contrib/bmake/cond.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.344 2023/02/14 21:08:00 rillig Exp $ */
+/* $NetBSD: cond.c,v 1.353 2023/06/23 05:21:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -92,7 +92,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
-MAKE_RCSID("$NetBSD: cond.c,v 1.344 2023/02/14 21:08:00 rillig Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.353 2023/06/23 05:21:10 rillig Exp $");
/*
* Conditional expressions conform to this grammar:
@@ -136,10 +136,10 @@ typedef struct CondParser {
/*
* The plain '.if ${VAR}' evaluates to true if the value of the
- * expression has length > 0. The other '.if' variants delegate
- * to evalBare instead, for example '.ifdef ${VAR}' is equivalent to
- * '.if defined(${VAR})', checking whether the variable named by the
- * expression '${VAR}' is defined.
+ * expression has length > 0 and is not numerically zero. The other
+ * '.if' variants delegate to evalBare instead, for example '.ifdef
+ * ${VAR}' is equivalent to '.if defined(${VAR})', checking whether
+ * the variable named by the expression '${VAR}' is defined.
*/
bool plain;
@@ -173,7 +173,7 @@ typedef struct CondParser {
bool printedError;
} CondParser;
-static CondResult CondParser_Or(CondParser *par, bool);
+static CondResult CondParser_Or(CondParser *, bool);
unsigned int cond_depth = 0; /* current .if nesting level */
@@ -295,10 +295,19 @@ static bool
FuncMake(const char *targetPattern)
{
StringListNode *ln;
-
- for (ln = opts.create.first; ln != NULL; ln = ln->next)
- if (Str_Match(ln->datum, targetPattern))
+ bool warned = false;
+
+ for (ln = opts.create.first; ln != NULL; ln = ln->next) {
+ StrMatchResult res = Str_Match(ln->datum, targetPattern);
+ if (res.error != NULL && !warned) {
+ warned = true;
+ Parse_Error(PARSE_WARNING,
+ "%s in pattern argument '%s' to function 'make'",
+ res.error, targetPattern);
+ }
+ if (res.matched)
return true;
+ }
return false;
}
@@ -338,7 +347,7 @@ FuncCommands(const char *node)
}
/*
- * Convert the string into a floating-point number. Accepted formats are
+ * Convert the string to a floating point number. Accepted formats are
* base-10 integer, base-16 integer and finite floating point numbers.
*/
static bool
@@ -507,7 +516,7 @@ return_str:
* ".if 0".
*/
static bool
-EvalNotEmpty(CondParser *par, const char *value, bool quoted)
+EvalTruthy(CondParser *par, const char *value, bool quoted)
{
double num;
@@ -631,7 +640,7 @@ CondParser_Comparison(CondParser *par, bool doEval)
if (!CondParser_ComparisonOp(par, &op)) {
/* Unknown operator, compare against an empty string or 0. */
- t = ToToken(doEval && EvalNotEmpty(par, lhs.str, lhsQuoted));
+ t = ToToken(doEval && EvalTruthy(par, lhs.str, lhsQuoted));
goto done_lhs;
}
@@ -1123,6 +1132,7 @@ Cond_EvalLine(const char *line)
/* Return state for previous conditional */
cond_depth--;
+ Parse_GuardEndif();
return cond_states[cond_depth] & IFS_ACTIVE
? CR_TRUE : CR_FALSE;
}
@@ -1150,6 +1160,7 @@ Cond_EvalLine(const char *line)
Parse_Error(PARSE_FATAL, "if-less else");
return CR_TRUE;
}
+ Parse_GuardElse();
state = cond_states[cond_depth];
if (state == IFS_INITIAL) {
@@ -1185,6 +1196,7 @@ Cond_EvalLine(const char *line)
Parse_Error(PARSE_FATAL, "if-less elif");
return CR_TRUE;
}
+ Parse_GuardElse();
state = cond_states[cond_depth];
if (state & IFS_SEEN_ELSE) {
Parse_Error(PARSE_WARNING, "extra elif");
@@ -1234,6 +1246,69 @@ Cond_EvalLine(const char *line)
return res;
}
+static bool
+ParseVarnameGuard(const char **pp, const char **varname)
+{
+ const char *p = *pp;
+
+ if (ch_isalpha(*p) || *p == '_') {
+ while (ch_isalnum(*p) || *p == '_')
+ p++;
+ *varname = *pp;
+ *pp = p;
+ return true;
+ }
+ return false;
+}
+
+/* Extracts the multiple-inclusion guard from a conditional, if any. */
+Guard *
+Cond_ExtractGuard(const char *line)
+{
+ const char *p, *varname;
+ Substring dir;
+ enum GuardKind kind;
+ Guard *guard;
+
+ p = line + 1; /* skip the '.' */
+ cpp_skip_hspace(&p);
+
+ dir.start = p;
+ while (ch_isalpha(*p))
+ p++;
+ dir.end = p;
+ cpp_skip_hspace(&p);
+
+ if (Substring_Equals(dir, "if")) {
+ if (skip_string(&p, "!defined(")) {
+ if (ParseVarnameGuard(&p, &varname)
+ && strcmp(p, ")") == 0)
+ goto found_variable;
+ } else if (skip_string(&p, "!target(")) {
+ const char *arg_p = p;
+ free(ParseWord(&p, false));
+ if (strcmp(p, ")") == 0) {
+ char *target = ParseWord(&arg_p, true);
+ guard = bmake_malloc(sizeof(*guard));
+ guard->kind = GK_TARGET;
+ guard->name = target;
+ return guard;
+ }
+ }
+ } else if (Substring_Equals(dir, "ifndef")) {
+ if (ParseVarnameGuard(&p, &varname) && *p == '\0')
+ goto found_variable;
+ }
+ return NULL;
+
+found_variable:
+ kind = GK_VARIABLE;
+ guard = bmake_malloc(sizeof(*guard));
+ guard->kind = kind;
+ guard->name = bmake_strsedup(varname, p);
+ return guard;
+}
+
void
Cond_EndFile(void)
{
diff --git a/contrib/bmake/dir.c b/contrib/bmake/dir.c
index 71c344c06dba..1da9e7d8fc13 100644
--- a/contrib/bmake/dir.c
+++ b/contrib/bmake/dir.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.280 2023/01/24 00:24:02 sjg Exp $ */
+/* $NetBSD: dir.c,v 1.282 2023/06/23 04:56:54 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -138,7 +138,7 @@
#include "job.h"
/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
-MAKE_RCSID("$NetBSD: dir.c,v 1.280 2023/01/24 00:24:02 sjg Exp $");
+MAKE_RCSID("$NetBSD: dir.c,v 1.282 2023/06/23 04:56:54 rillig Exp $");
/*
* A search path is a list of CachedDir structures. A CachedDir has in it the
@@ -668,8 +668,10 @@ DirMatchFiles(const char *pattern, CachedDir *dir, StringList *expansions)
HashIter_InitSet(&hi, &dir->files);
while (HashIter_Next(&hi) != NULL) {
const char *base = hi.entry->key;
+ StrMatchResult res = Str_Match(base, pattern);
+ /* TODO: handle errors from res.error */
- if (!Str_Match(base, pattern))
+ if (!res.matched)
continue;
/*
@@ -822,14 +824,14 @@ DirExpandCurly(const char *word, const char *brace, SearchPath *path,
}
-/* Expand the word in each of the directories from the path. */
+/* Expand the pattern in each of the directories from the path. */
static void
-DirExpandPath(const char *word, SearchPath *path, StringList *expansions)
+DirExpandPath(const char *pattern, SearchPath *path, StringList *expansions)
{
SearchPathNode *ln;
for (ln = path->dirs.first; ln != NULL; ln = ln->next) {
CachedDir *dir = ln->datum;
- DirMatchFiles(word, dir, expansions);
+ DirMatchFiles(pattern, dir, expansions);
}
}
diff --git a/contrib/bmake/for.c b/contrib/bmake/for.c
index 7c090bab5e42..38fd1c447206 100644
--- a/contrib/bmake/for.c
+++ b/contrib/bmake/for.c
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.174 2023/05/09 19:43:12 rillig Exp $ */
+/* $NetBSD: for.c,v 1.176 2023/06/01 09:02:14 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: for.c,v 1.174 2023/05/09 19:43:12 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.176 2023/06/01 09:02:14 rillig Exp $");
typedef struct ForLoop {
@@ -115,7 +115,7 @@ ForLoop_Free(ForLoop *f)
}
char *
-ForLoop_Details(ForLoop *f)
+ForLoop_Details(const ForLoop *f)
{
size_t i, n;
const char **vars;
@@ -133,7 +133,7 @@ ForLoop_Details(ForLoop *f)
Buf_AddStr(&buf, ", ");
Buf_AddStr(&buf, vars[i]);
Buf_AddStr(&buf, " = ");
- Buf_AddBytesBetween(&buf, items[i].start, items[i].end);
+ Buf_AddRange(&buf, items[i].start, items[i].end);
}
return Buf_DoneData(&buf);
}
@@ -351,7 +351,7 @@ NeedsEscapes(Substring value, char endc)
}
/*
- * While expanding the body of a .for loop, write the item in the ${:U...}
+ * While expanding the body of a .for loop, write the item as a ${:U...}
* expression, escaping characters as needed. The result is later unescaped
* by ApplyModifier_Defined.
*/
@@ -362,7 +362,7 @@ AddEscaped(Buffer *cmds, Substring item, char endc)
char ch;
if (!NeedsEscapes(item, endc)) {
- Buf_AddBytesBetween(cmds, item.start, item.end);
+ Buf_AddRange(cmds, item.start, item.end);
return;
}
@@ -392,7 +392,7 @@ AddEscaped(Buffer *cmds, Substring item, char endc)
}
/*
- * When expanding the body of a .for loop, replace the variable name of an
+ * While expanding the body of a .for loop, replace the variable name of an
* expression like ${i} or ${i:...} or $(i) or $(i:...) with ":Uvalue".
*/
static void
@@ -401,12 +401,12 @@ ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body,
{
size_t i;
const char *start = *pp;
- const char **vars = Vector_Get(&f->vars, 0);
+ const char **varnames = Vector_Get(&f->vars, 0);
for (i = 0; i < f->vars.len; i++) {
const char *p = start;
- if (!cpp_skip_string(&p, vars[i]))
+ if (!cpp_skip_string(&p, varnames[i]))
continue;
/* XXX: why test for backslash here? */
if (*p != ':' && *p != endc && *p != '\\')
@@ -416,7 +416,7 @@ ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body,
* Found a variable match. Skip over the variable name and
* instead add ':U<value>' to the current body.
*/
- Buf_AddBytesBetween(body, *inout_mark, start);
+ Buf_AddRange(body, *inout_mark, start);
Buf_AddStr(body, ":U");
AddEscaped(body, f->items.words[firstItem + i], endc);
@@ -427,7 +427,7 @@ ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body,
}
/*
- * When expanding the body of a .for loop, replace single-character
+ * While expanding the body of a .for loop, replace single-character
* variable expressions like $i with their ${:U...} expansion.
*/
static void
@@ -451,7 +451,7 @@ ForLoop_SubstVarShort(ForLoop *f, unsigned int firstItem, Buffer *body,
return;
found:
- Buf_AddBytesBetween(body, *inout_mark, p);
+ Buf_AddRange(body, *inout_mark, p);
*inout_mark = p + 1;
/* Replace $<ch> with ${:U<value>} */
@@ -465,13 +465,14 @@ found:
* replacing the expressions for the iteration variables on the way.
*
* Using variable expressions ensures that the .for loop can't generate
- * syntax, and that the later parsing will still see a variable.
- * This code assumes that the variable with the empty name will never be
- * defined, see unit-tests/varname-empty.mk for more details.
+ * syntax, and that the later parsing will still see an expression.
+ * This code assumes that the variable with the empty name is never defined,
+ * see unit-tests/varname-empty.mk.
*
* The detection of substitutions of the loop control variables is naive.
* Many of the modifiers use '\$' instead of '$$' to escape '$', so it is
* possible to contrive a makefile where an unwanted substitution happens.
+ * See unit-tests/directive-for-escape.mk.
*/
static void
ForLoop_SubstBody(ForLoop *f, unsigned int firstItem, Buffer *body)
@@ -497,7 +498,7 @@ ForLoop_SubstBody(ForLoop *f, unsigned int firstItem, Buffer *body)
break;
}
- Buf_AddBytesBetween(body, mark, end);
+ Buf_AddRange(body, mark, end);
}
/*
@@ -512,7 +513,12 @@ For_NextIteration(ForLoop *f, Buffer *body)
f->nextItem += (unsigned int)f->vars.len;
ForLoop_SubstBody(f, f->nextItem - (unsigned int)f->vars.len, body);
- DEBUG1(FOR, "For: loop body:\n%s", body->data);
+ if (DEBUG(FOR)) {
+ char *details = ForLoop_Details(f);
+ debug_printf("For: loop body with %s:\n%s",
+ details, body->data);
+ free(details);
+ }
return true;
}
diff --git a/contrib/bmake/make.h b/contrib/bmake/make.h
index d2e6c28be1ff..50e590eb4c93 100644
--- a/contrib/bmake/make.h
+++ b/contrib/bmake/make.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.319 2023/03/28 14:39:31 rillig Exp $ */
+/* $NetBSD: make.h,v 1.323 2023/06/20 09:25:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -555,6 +555,14 @@ typedef enum CondResult {
CR_ERROR /* Unknown directive or parse error */
} CondResult;
+typedef struct {
+ enum GuardKind {
+ GK_VARIABLE,
+ GK_TARGET
+ } kind;
+ char *name;
+} Guard;
+
/* Names of the variables that are "local" to a specific target. */
#define TARGET "@" /* Target of dependency */
#define OODATE "?" /* All out-of-date sources */
@@ -794,8 +802,8 @@ void Arch_End(void);
bool Arch_ParseArchive(char **, GNodeList *, GNode *);
void Arch_Touch(GNode *);
void Arch_TouchLib(GNode *);
-void Arch_UpdateMTime(GNode *gn);
-void Arch_UpdateMemberMTime(GNode *gn);
+void Arch_UpdateMTime(GNode *);
+void Arch_UpdateMemberMTime(GNode *);
void Arch_FindLib(GNode *, SearchPath *);
bool Arch_LibOODate(GNode *) MAKE_ATTR_USE;
bool Arch_IsLib(GNode *) MAKE_ATTR_USE;
@@ -809,6 +817,7 @@ void Compat_Make(GNode *, GNode *);
extern unsigned int cond_depth;
CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE;
CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE;
+Guard *Cond_ExtractGuard(const char *) MAKE_ATTR_USE;
void Cond_EndFile(void);
/* dir.c; see also dir.h */
@@ -836,7 +845,7 @@ int For_Eval(const char *) MAKE_ATTR_USE;
bool For_Accum(const char *, int *) MAKE_ATTR_USE;
void For_Run(unsigned, unsigned);
bool For_NextIteration(struct ForLoop *, Buffer *);
-char *ForLoop_Details(struct ForLoop *);
+char *ForLoop_Details(const struct ForLoop *);
void ForLoop_Free(struct ForLoop *);
void For_Break(struct ForLoop *);
@@ -873,6 +882,8 @@ void Parse_PushInput(const char *, unsigned, unsigned, Buffer,
void Parse_MainName(GNodeList *);
int Parse_NumErrors(void) MAKE_ATTR_USE;
unsigned int CurFile_CondMinDepth(void) MAKE_ATTR_USE;
+void Parse_GuardElse(void);
+void Parse_GuardEndif(void);
/* suff.c */
diff --git a/contrib/bmake/mk/ChangeLog b/contrib/bmake/mk/ChangeLog
index 15c3861ea701..880b839fc860 100644
--- a/contrib/bmake/mk/ChangeLog
+++ b/contrib/bmake/mk/ChangeLog
@@ -1,3 +1,49 @@
+2023-05-25 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * meta.autodep.mk (beforegendirdeps): allow tasks to be done
+ at END but before gendirdeps
+
+2023-05-22 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * install-mk (MK_VERSION): 20230522
+
+ * host-target.mk: deal with garbage from uname -m on
+ Darwin ppc, also NetBSD appears to use x86_64 for MACHINE_ARCH
+ these days so just leave it be.
+ For Darwin arm and i386 use _HOST_MACHINE for _HOST_ARCH so we get
+ arm64 and x86_64 in HOST_TARGET.
+
+2023-05-15 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * sys.vars.mk: M_mtime use :mtime or 'stat -f %m' for older
+ versions of bmake.
+
+ * dirdeps.mk (TARGET_SPEC_VARS.host):
+ While *most* projects need only DEP_MACHINE for host,
+ there is always an exception. So we allow for
+ TARGET_SPEC_VARS.host to be a subset of TARGET_SPEC_VARS.
+ The default will *just work* for most projects.
+ We set DEP_TARGET_SPEC_VARS and hence DEP_TARGET_SPEC
+ based on DEP_MACHINE.
+ Allow for M_dep_qual_fixes.host to be different too
+ and take care to apply the right set.
+
+2023-05-14 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * sys.dirdeps.mk: we *do* want to override OBJTOP
+ and if MAKEOBJDIR was not in env as we want it;
+ put it there - carefully.
+ Ensure OBJROOT ends in / or - (/ preferred)
+ Add more comments to explain what/why.
+
+2023-05-13 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * install-mk (MK_VERSION): 20230512
+
+ * dirdeps.mk: take care not to qualify "host" dirdeps
+
+ * sys.dirdeps.mk (OBJTOP): must use ?=
+
2023-05-10 Simon J Gerraty <sjg@beast.crufty.net>
* meta.autodep.mk: if LOCAL_DEPENDS_GUARD is "no"
diff --git a/contrib/bmake/mk/dirdeps.mk b/contrib/bmake/mk/dirdeps.mk
index aafa5ab47557..2cf62bed3d9e 100644
--- a/contrib/bmake/mk/dirdeps.mk
+++ b/contrib/bmake/mk/dirdeps.mk
@@ -1,4 +1,4 @@
-# $Id: dirdeps.mk,v 1.160 2023/05/10 20:44:58 sjg Exp $
+# $Id: dirdeps.mk,v 1.162 2023/05/15 17:37:46 sjg Exp $
# SPDX-License-Identifier: BSD-2-Clause
#
@@ -212,12 +212,16 @@ _DEP_TARGET_SPEC =
# it should be set by sys.mk or similar by now.
# TARGET_SPEC must not contain any '.'s.
TARGET_SPEC_VARS ?= MACHINE
+# we allow for this to be a subset
+TARGET_SPEC_VARS.host ?= MACHINE
+TARGET_SPEC_VARS.host32 = ${TARGET_SPEC_VARS.host}
# this is what we started with
TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
# this is what we mostly use below
-DEP_TARGET_SPEC = ${TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,}
+DEP_TARGET_SPEC_VARS = ${TARGET_SPEC_VARS.${DEP_MACHINE}:U${TARGET_SPEC_VARS}}
+DEP_TARGET_SPEC = ${DEP_TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,}
# make sure we have defaults
-.for v in ${TARGET_SPEC_VARS}
+.for v in ${DEP_TARGET_SPEC_VARS}
DEP_$v ?= ${$v}
.endfor
@@ -227,12 +231,7 @@ DEP_$v ?= ${$v}
# we compute below are fully qualified wrt DEP_TARGET_SPEC.
# The makefiles may only partially specify (eg. MACHINE only),
# so we need to construct a set of modifiers to fill in the gaps.
-.if ${MAKE_VERSION} >= 20170130
-_tspec_x := ${TARGET_SPEC_VARS:range}
-.else
-# do it the hard way
-_tspec_x := ${TARGET_SPEC_VARS:[#]:@x@i=1;while [ $$i -le $x ]; do echo $$i; i=$$((i + 1)); done;@:sh}
-.endif
+_tspec_x := ${TARGET_SPEC_VARS:${M_RANGE:Urange}}
# this handles unqualified entries
M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC};
# there needs to be at least one item missing for these to make sense
@@ -242,10 +241,27 @@ _tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,}
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i};
.endfor
TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
+.if ${TARGET_SPEC_VARS.host} == ${TARGET_SPEC_VARS}
+M_dep_qual_fixes.host = ${M_dep_qual_fixes}
+.elif ${TARGET_SPEC_VARS.host:[#]} > 1
+_htspec_x := ${TARGET_SPEC_VARS.host:${M_RANGE:Urange}}
+# this handles unqualified entries
+M_dep_qual_fixes.host = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC};
+# there needs to be at least one item missing for these to make sense
+.for i in ${_htspec_x:[2..-1]}
+_htspec_m$i := ${TARGET_SPEC_VARS.host:[2..$i]:@w@[^,]+@:ts,}
+_htspec_a$i := ,${TARGET_SPEC_VARS.host:[$i..-1]:@v@$$$${DEP_$v}@:ts,}
+M_dep_qual_fixes.host += C;(\.${_htspec_m$i})$$;\1${_htspec_a$i};
+.endfor
+.else
+M_dep_qual_fixes.host = U
+.endif
.else
# A harmless? default.
M_dep_qual_fixes = U
.endif
+M_dep_qual_fixes.host ?= ${M_dep_qual_fixes}
+M_dep_qual_fixes.host32 = ${M_dep_qual_fixes.host}
.if !defined(.MAKE.DEPENDFILE_PREFERENCE)
# .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater?
@@ -328,7 +344,7 @@ _tspec := ${_DEP_TARGET_SPEC:S/,/ /g}
.for i in ${_tspec_x}
DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
.endfor
-.for v in ${TARGET_SPEC_VARS:O:u}
+.for v in ${DEP_TARGET_SPEC_VARS:O:u}
.if empty(DEP_$v)
.undef DEP_$v
.endif
@@ -337,14 +353,6 @@ DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
DEP_MACHINE := ${_DEP_TARGET_SPEC}
.endif
-# host is special
-.if ${DEP_MACHINE:Mhost*} != ""
-DEP_TARGET_SPEC = ${DEP_MACHINE}
-.for v in ${TARGET_SPEC_VARS:O:u:NMACHINE}
-.undef DEP_$v
-.endfor
-.endif
-
# reset each time through
_build_all_dirs =
_build_xtra_dirs =
@@ -651,7 +659,7 @@ _machines += host
_machines := ${_machines:O:u}
.endif
-.if ${TARGET_SPEC_VARS:[#]} > 1
+.if ${DEP_TARGET_SPEC_VARS:[#]} > 1
# we need to tweak _machines
_dm := ${DEP_MACHINE}
# apply the same filtering that we do when qualifying DIRDEPS.
@@ -659,7 +667,7 @@ _dm := ${DEP_MACHINE}
# Again we expect that any already qualified machines are fully qualified.
_machines := ${_machines:M*,*} ${_machines:N*,*:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:S,^.,,}
DEP_MACHINE := ${_dm}
-_machines := ${_machines:${M_dep_qual_fixes:ts:}:O:u}
+_machines := ${_machines:${M_dep_qual_fixes.${DEP_MACHINE}:U${M_dep_qual_fixes}:ts:}:O:u}
.endif
# reset each time through
@@ -717,7 +725,16 @@ _build_dirs += \
${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@}
# qualify everything now
-_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
+.if ${_debug_reldir}
+.info _build_dirs=${_build_dirs}
+.endif
+# make sure we do not mess with qualifying "host" entries
+_build_dirs := ${_build_dirs:M*.host*:${M_dep_qual_fixes.host:ts:}} \
+ ${_build_dirs:N*.host*:${M_dep_qual_fixes:ts:}}
+_build_dirs := ${_build_dirs:O:u}
+.if ${_debug_reldir}
+.info _build_dirs=${_build_dirs}
+.endif
.endif # empty DIRDEPS
@@ -767,9 +784,10 @@ _cache_script += echo; echo 'DIRDEPS.${_this_dir}.$m = \';
.endif
# it would be nice to do :N${.TARGET}
.if !empty(__qual_depdirs)
-.for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
+.for q in ${__qual_depdirs:M*.host*:${M_dep_qual_fixes.host:ts:}:E:O:u:N$m} \
+ ${__qual_depdirs:N*.host*:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
.if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
-.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
+.info ${DEP_RELDIR}.$m: q=$q graph: ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
.endif
.if ${BUILD_DIRDEPS_CACHE} == "yes"
_cache_deps += ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
@@ -816,14 +834,13 @@ _dr := ${d:S,^${SRCTOP}/,,}
_DEP_TARGET_SPEC := ${d:E}
# some makefiles may still look at this
_DEP_MACHINE := ${d:E:C/,.*//}
+DEP_MACHINE := ${_DEP_MACHINE}
# set these too in case Makefile.depend* uses them
-.if ${TARGET_SPEC_VARS:[#]} > 1
+.if ${DEP_TARGET_SPEC_VARS:[#]} > 1
_dtspec := ${_DEP_TARGET_SPEC:S/,/ /g}
.for i in ${_tspec_x}
-DEP_${TARGET_SPEC_VARS:[$i]} := ${_dtspec:[$i]}
+DEP_${DEP_TARGET_SPEC_VARS:[$i]} := ${_dtspec:[$i]}
.endfor
-.else
-DEP_MACHINE := ${_DEP_MACHINE}
.endif
# Warning: there is an assumption here that MACHINE is always
# the first entry in TARGET_SPEC_VARS.
@@ -831,7 +848,7 @@ DEP_MACHINE := ${_DEP_MACHINE}
_m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:C;${MACHINE}((,.+)?)$;${d:E:C/,.*//}\1;:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]}
.if !empty(_m)
# M_dep_qual_fixes isn't geared to Makefile.depend
-_qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}}
+_qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes.${d:E}:U${M_dep_qual_fixes}:ts:}}
.if ${_debug_search}
.info Looking for ${_qm}
.endif
diff --git a/contrib/bmake/mk/host-target.mk b/contrib/bmake/mk/host-target.mk
index 8d906e431779..f9f22027c00f 100644
--- a/contrib/bmake/mk/host-target.mk
+++ b/contrib/bmake/mk/host-target.mk
@@ -1,7 +1,10 @@
# RCSid:
-# $Id: host-target.mk,v 1.14 2022/02/04 18:05:22 sjg Exp $
+# $Id: host-target.mk,v 1.18 2023/05/22 23:08:31 sjg Exp $
# Host platform information; may be overridden
+.if !target(__${.PARSEFILE}__)
+__${.PARSEFILE}__: .NOTMAIN
+
.if !defined(_HOST_OSNAME)
# use .MAKE.OS if available
_HOST_OSNAME := ${.MAKE.OS:U${uname -s:L:sh}}
@@ -11,23 +14,27 @@ _HOST_OSNAME := ${.MAKE.OS:U${uname -s:L:sh}}
_HOST_OSREL != uname -r
.export _HOST_OSREL
.endif
-.if !defined(_HOST_MACHINE)
-_HOST_MACHINE != uname -m
-.export _HOST_MACHINE
-.endif
.if !defined(_HOST_ARCH)
-# for Darwin and NetBSD prefer $MACHINE (amd64 rather than x86_64)
-.if ${_HOST_OSNAME:NDarwin:NNetBSD} == ""
-_HOST_ARCH := ${_HOST_MACHINE}
-.else
_HOST_ARCH != uname -p 2> /dev/null || uname -m
# uname -p may produce garbage on linux
.if ${_HOST_ARCH:[\#]} > 1 || ${_HOST_ARCH:Nunknown} == ""
-_HOST_ARCH := ${_HOST_MACHINE}
-.endif
+_HOST_ARCH = ${_HOST_MACHINE}
+.elif ${_HOST_OSNAME:NDarwin} == "" && ${_HOST_ARCH:Narm:Ni386} == ""
+# _HOST_MACHINE is more explicit/useful
+_HOST_ARCH = ${_HOST_MACHINE}
.endif
.export _HOST_ARCH
.endif
+.if !defined(_HOST_MACHINE)
+_HOST_MACHINE != uname -m
+# just in case
+_HOST_ARCH := ${_HOST_ARCH}
+# uname -m may produce garbage on darwin ppc
+.if ${_HOST_MACHINE:[\#]} > 1
+_HOST_MACHINE := ${_HOST_ARCH}
+.endif
+.export _HOST_MACHINE
+.endif
.if !defined(HOST_MACHINE)
HOST_MACHINE := ${_HOST_MACHINE}
.export HOST_MACHINE
@@ -48,3 +55,5 @@ HOST_TARGET32 := ${host_os:S,/,,g}${HOST_OSMAJOR}-${_HOST_ARCH32}
TR ?= tr
toLower = ${TR} 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
toUpper = ${TR} 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+
+.endif
diff --git a/contrib/bmake/mk/install-mk b/contrib/bmake/mk/install-mk
index e198d52a8702..c056a39d1b1e 100644
--- a/contrib/bmake/mk/install-mk
+++ b/contrib/bmake/mk/install-mk
@@ -59,7 +59,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: install-mk,v 1.234 2023/05/13 15:52:24 sjg Exp $
+# $Id: install-mk,v 1.239 2023/05/29 18:04:48 sjg Exp $
#
# @(#) Copyright (c) 1994-2023 Simon J. Gerraty
#
@@ -74,7 +74,7 @@
# sjg@crufty.net
#
-MK_VERSION=20230510
+MK_VERSION=20230601
OWNER=
GROUP=
MODE=444
diff --git a/contrib/bmake/mk/meta.autodep.mk b/contrib/bmake/mk/meta.autodep.mk
index 5f012cdec003..851afce9f8b5 100644
--- a/contrib/bmake/mk/meta.autodep.mk
+++ b/contrib/bmake/mk/meta.autodep.mk
@@ -1,4 +1,4 @@
-# $Id: meta.autodep.mk,v 1.57 2023/05/13 15:52:24 sjg Exp $
+# $Id: meta.autodep.mk,v 1.58 2023/05/25 22:33:23 sjg Exp $
#
# @(#) Copyright (c) 2010, Simon J. Gerraty
@@ -210,7 +210,8 @@ _depend =
.endif
.if ${UPDATE_DEPENDFILE} == "yes"
-gendirdeps: ${_DEPENDFILE}
+gendirdeps: beforegendirdeps .WAIT ${_DEPENDFILE}
+beforegendirdeps:
.endif
.if !target(${_DEPENDFILE})
diff --git a/contrib/bmake/mk/sys.dirdeps.mk b/contrib/bmake/mk/sys.dirdeps.mk
index 2daf3681d8d0..a3d22d7c2e82 100644
--- a/contrib/bmake/mk/sys.dirdeps.mk
+++ b/contrib/bmake/mk/sys.dirdeps.mk
@@ -1,4 +1,4 @@
-# $Id: sys.dirdeps.mk,v 1.9 2023/05/11 20:05:42 sjg Exp $
+# $Id: sys.dirdeps.mk,v 1.12 2023/05/14 16:16:03 sjg Exp $
#
# @(#) Copyright (c) 2012-2023, Simon J. Gerraty
#
@@ -45,6 +45,7 @@ SRCTOP := ${SB_SRC:U${.PARSEDIR:tA:H:H}}
.endif
# fake SB if not using mk wrapper
+# SB documented at http://www.crufty.net/sjg/docs/sb-tools.htm
.if !defined(SB)
SB := ${SRCTOP:H}
.export SB
@@ -54,6 +55,10 @@ SB := ${SRCTOP:H}
OBJROOT := ${SB_OBJROOT:U${MAKEOBJDIRPREFIX:U${SB}/obj}/}
.export OBJROOT
.endif
+# we expect OBJROOT to end with / (- can work too)
+.if ${OBJROOT:M*[/-]} == ""
+OBJROOT := ${OBJROOT}/
+.endif
.if empty(STAGE_ROOT)
STAGE_ROOT ?= ${OBJROOT}stage
@@ -66,9 +71,6 @@ STAGE_ROOT ?= ${OBJROOT}stage
# TARGET_SPEC must not contain any '.'s.
TARGET_SPEC_VARS ?= MACHINE
-.if !target(_tspec_env_done_)
-_tspec_env_done_: .NOTMAIN
-
.if ${TARGET_SPEC:Uno:M*,*} != ""
# deal with TARGET_SPEC from env
_tspec := ${TARGET_SPEC:S/,/ /g}
@@ -86,7 +88,6 @@ TARGET_SPEC=
.endif
.endfor
.endif
-.endif
# Now make sure we know what TARGET_SPEC is
# as we may need it to find Makefile.depend*
@@ -98,6 +99,10 @@ TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
.endif
.if ${TARGET_SPEC_VARS:[#]} > 1
+TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
+# alternatives might be
+# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARSr:@v@${$v:U}@:ts/}
+# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts/}
TARGET_OBJ_SPEC ?= ${TARGET_SPEC_VARS:@v@${$v:U}@:ts.}
.else
TARGET_OBJ_SPEC ?= ${MACHINE}
@@ -113,22 +118,37 @@ MACHINE0 := ${MACHINE}
.export MACHINE0
.endif
+MACHINE_OBJ.host = ${HOST_TARGET}
+MACHINE_OBJ.host32 = ${HOST_TARGET32}
+MACHINE_OBJ.${MACHINE} ?= ${TARGET_OBJ_SPEC}
+MACHINE_OBJDIR = ${MACHINE_OBJ.${MACHINE}}
+
+# we likely want to override env for OBJTOP
.if ${MACHINE} == "host"
OBJTOP = ${HOST_OBJTOP}
.elif ${MACHINE} == "host32"
OBJTOP = ${HOST_OBJTOP32}
+.else
+OBJTOP = ${OBJROOT}${MACHINE_OBJDIR}
+.endif
+.if ${.MAKE.LEVEL} > 0
+# should not change from level 1 onwards
+# this only matters for cases like bmake/unit-tests
+# where we do ${MAKE} -r
+.export OBJTOP
.endif
-MACHINE_OBJ.host = ${HOST_TARGET}
-MACHINE_OBJ.host32 = ${HOST_TARGET32}
-MACHINE_OBJ.${MACHINE} ?= ${TARGET_OBJ_SPEC}
-MACHINE_OBJDIR = ${MACHINE_OBJ.${MACHINE}}
-OBJTOP ?= ${OBJROOT}/${MACHINE_OBJDIR}
-
+.if ${MAKEOBJDIR:U:M*/*} == ""
# we do not use MAKEOBJDIRPREFIX
+# though we may have used it above to initialize OBJROOT
.undef MAKEOBJDIRPREFIX
-# we use this
-MAKEOBJDIR ?= ${.CURDIR:S,${SRCTOP},${OBJTOP},}
+# this is what we expected in env
+MAKEOBJDIR = $${.CURDIR:S,^$${SRCTOP},$${OBJTOP},}
+# export that but do not track
+.export-env MAKEOBJDIR
+# this what we need here
+MAKEOBJDIR = ${.CURDIR:S,${SRCTOP},${OBJTOP},}
+.endif
STAGE_MACHINE ?= ${MACHINE_OBJDIR}
STAGE_OBJTOP ?= ${STAGE_ROOT}/${STAGE_MACHINE}
diff --git a/contrib/bmake/mk/sys.vars.mk b/contrib/bmake/mk/sys.vars.mk
index c3dcf6a7e7ef..974f24ca00b8 100644
--- a/contrib/bmake/mk/sys.vars.mk
+++ b/contrib/bmake/mk/sys.vars.mk
@@ -1,4 +1,4 @@
-# $Id: sys.vars.mk,v 1.14 2023/02/17 22:32:47 sjg Exp $
+# $Id: sys.vars.mk,v 1.15 2023/05/16 16:41:52 sjg Exp $
#
# @(#) Copyright (c) 2003-2023, Simon J. Gerraty
#
@@ -129,3 +129,12 @@ M_Onr = Onr
# index values use ${M_Index:S,K,key,}:[1] to select only the first.
M_Index = _:${M_RANGE}:@i@$${"$${_:[$$i]:MK}":?$$i:}@
+# mtime of each word - assumed to be a valid pathname
+.if ${.MAKE.LEVEL} < 20230510
+M_mtime = tW:S,^,${STAT:Ustat} -f %m ,:sh
+.else
+# M_mtime_fallback can be =error to throw an error
+# or =0 to use 0, default is to use current time
+M_mtime = mtime${M_mtime_fallback:U}
+.endif
+
diff --git a/contrib/bmake/os.sh b/contrib/bmake/os.sh
index 6bf52420c90f..78b2de95a679 100755..100644
--- a/contrib/bmake/os.sh
+++ b/contrib/bmake/os.sh
@@ -17,7 +17,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: os.sh,v 1.62 2023/01/17 18:30:21 sjg Exp $
+# $Id: os.sh,v 1.63 2023/05/22 20:44:47 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@@ -41,12 +41,16 @@ OSMAJOR=`IFS=.; set $OSREL; echo $1`
MACHINE=`uname -m`
MACHINE_ARCH=`uname -p 2>/dev/null || echo $MACHINE`
-# there is at least one case of `uname -p` outputting
-# a bunch of usless drivel
+# there is at least one case of `uname -p`
+# and even `uname -m` outputting usless info
+# fortunately not both together
+case "$MACHINE" in
+*[!A-Za-z0-9_-]*) MACHINE="$MACHINE_ARCH";;
+esac
case "$MACHINE_ARCH" in
unknown|*[!A-Za-z0-9_-]*) MACHINE_ARCH="$MACHINE";;
esac
-
+
# we need this here, and it is not always available...
Which() {
case "$1" in
@@ -87,7 +91,7 @@ AIX) # everyone loves to be different...
PS_AXC=-e
SHARE_ARCH=$OS/$OSMAJOR.X
;;
-Darwin) # a bit like BSD
+Darwin) # this is more explicit (arm64 vs arm)
HOST_ARCH=$MACHINE
;;
SunOS)
@@ -140,10 +144,10 @@ SunOS)
esac
# NetBSD at least has good backward compatibility
# so NetBSD/i386 is good enough
+ # recent NetBSD uses x86_64 for MACHINE_ARCH
case $OS in
NetBSD)
LOCALBASE=/usr/pkg
- HOST_ARCH=$MACHINE
SHARE_ARCH=$OS/$HOST_ARCH
;;
OpenBSD)
diff --git a/contrib/bmake/parse.c b/contrib/bmake/parse.c
index f0644ea67a14..c23e523fce58 100644
--- a/contrib/bmake/parse.c
+++ b/contrib/bmake/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.698 2023/05/10 16:10:02 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.704 2023/06/23 06:08:56 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -121,7 +121,15 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.698 2023/05/10 16:10:02 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.704 2023/06/23 06:08:56 rillig Exp $");
+
+/* Detects a multiple-inclusion guard in a makefile. */
+typedef enum {
+ GS_START, /* at the beginning of the file */
+ GS_COND, /* after the guard condition */
+ GS_DONE, /* after the closing .endif */
+ GS_NO /* the file is not guarded */
+} GuardState;
/*
* A file being read.
@@ -141,9 +149,12 @@ typedef struct IncludedFile {
Buffer buf; /* the file's content or the body of the .for
* loop; either empty or ends with '\n' */
- char *buf_ptr; /* next char to be read */
+ char *buf_ptr; /* next char to be read from buf */
char *buf_end; /* buf_end[-1] == '\n' */
+ GuardState guardState;
+ Guard *guard;
+
struct ForLoop *forLoop;
} IncludedFile;
@@ -315,6 +326,8 @@ static const struct {
enum PosixState posix_state = PS_NOT_YET;
+static HashTable /* full file name -> Guard */ guards;
+
static IncludedFile *
GetInclude(size_t i)
{
@@ -429,8 +442,8 @@ IsEscaped(const char *line, const char *p)
}
/*
- * Add the filename and lineno to the GNode so that we remember where it
- * was first defined.
+ * Add the filename and lineno to the GNode so that we remember where its
+ * last command was added or where it was mentioned in a .depend file.
*/
static void
RememberLocation(GNode *gn)
@@ -1213,6 +1226,24 @@ FindInQuotPath(const char *file)
return fullname;
}
+static bool
+SkipGuarded(const char *fullname)
+{
+ Guard *guard = HashTable_FindValue(&guards, fullname);
+ if (guard != NULL && guard->kind == GK_VARIABLE
+ && GNode_ValueDirect(SCOPE_GLOBAL, guard->name) != NULL)
+ goto skip;
+ if (guard != NULL && guard->kind == GK_TARGET
+ && Targ_FindNode(guard->name) != NULL)
+ goto skip;
+ return false;
+
+skip:
+ DEBUG2(PARSE, "Skipping '%s' because '%s' is defined\n",
+ fullname, guard->name);
+ return true;
+}
+
/*
* Handle one of the .[-ds]include directives by remembering the current file
* and pushing the included file on the stack. After the included file has
@@ -1247,6 +1278,9 @@ IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
return;
}
+ if (SkipGuarded(fullname))
+ return;
+
if ((fd = open(fullname, O_RDONLY)) == -1) {
if (!silent)
Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
@@ -2190,6 +2224,8 @@ Parse_PushInput(const char *name, unsigned lineno, unsigned readLines,
curFile->forBodyReadLines = readLines;
curFile->buf = buf;
curFile->depending = doing_depend; /* restore this on EOF */
+ curFile->guardState = forLoop == NULL ? GS_START : GS_NO;
+ curFile->guard = NULL;
curFile->forLoop = forLoop;
if (forLoop != NULL && !For_NextIteration(forLoop, &curFile->buf))
@@ -2332,6 +2368,13 @@ ParseEOF(void)
Cond_EndFile();
+ if (curFile->guardState == GS_DONE)
+ HashTable_Set(&guards, curFile->name.str, curFile->guard);
+ else if (curFile->guard != NULL) {
+ free(curFile->guard->name);
+ free(curFile->guard);
+ }
+
FStr_Done(&curFile->name);
Buf_Done(&curFile->buf);
if (curFile->forLoop != NULL)
@@ -2632,8 +2675,10 @@ static char *
ReadHighLevelLine(void)
{
char *line;
+ CondResult condResult;
for (;;) {
+ IncludedFile *curFile = CurFile();
line = ReadLowLevelLine(LK_NONEMPTY);
if (posix_state == PS_MAYBE_NEXT_LINE)
posix_state = PS_NOW_OR_NEVER;
@@ -2642,10 +2687,24 @@ ReadHighLevelLine(void)
if (line == NULL)
return NULL;
+ if (curFile->guardState != GS_NO
+ && ((curFile->guardState == GS_START && line[0] != '.')
+ || curFile->guardState == GS_DONE))
+ curFile->guardState = GS_NO;
if (line[0] != '.')
return line;
- switch (Cond_EvalLine(line)) {
+ condResult = Cond_EvalLine(line);
+ if (curFile->guardState == GS_START) {
+ Guard *guard;
+ if (condResult != CR_ERROR
+ && (guard = Cond_ExtractGuard(line)) != NULL) {
+ curFile->guardState = GS_COND;
+ curFile->guard = guard;
+ } else
+ curFile->guardState = GS_NO;
+ }
+ switch (condResult) {
case CR_FALSE: /* May also mean a syntax error. */
if (!SkipIrrelevantBranches())
return NULL;
@@ -2716,10 +2775,14 @@ ParseLine_ShellCommand(const char *p)
}
static void
-HandleBreak(void)
+HandleBreak(const char *arg)
{
IncludedFile *curFile = CurFile();
+ if (arg[0] != '\0')
+ Parse_Error(PARSE_FATAL,
+ "The .break directive does not take arguments");
+
if (curFile->forLoop != NULL) {
/* pretend we reached EOF */
For_Break(curFile->forLoop);
@@ -2758,7 +2821,7 @@ ParseDirective(char *line)
arg = cp;
if (Substring_Equals(dir, "break"))
- HandleBreak();
+ HandleBreak(arg);
else if (Substring_Equals(dir, "undef"))
Var_Undef(arg);
else if (Substring_Equals(dir, "export"))
@@ -2796,6 +2859,23 @@ Parse_VarAssign(const char *line, bool finishDependencyGroup, GNode *scope)
return true;
}
+void
+Parse_GuardElse(void)
+{
+ IncludedFile *curFile = CurFile();
+ if (cond_depth == curFile->condMinDepth + 1)
+ curFile->guardState = GS_NO;
+}
+
+void
+Parse_GuardEndif(void)
+{
+ IncludedFile *curFile = CurFile();
+ if (cond_depth == curFile->condMinDepth
+ && curFile->guardState == GS_COND)
+ curFile->guardState = GS_DONE;
+}
+
static char *
FindSemicolon(char *p)
{
@@ -2986,6 +3066,7 @@ Parse_Init(void)
sysIncPath = SearchPath_New();
defSysIncPath = SearchPath_New();
Vector_Init(&includes, sizeof(IncludedFile));
+ HashTable_Init(&guards);
}
/* Clean up the parsing module. */
@@ -2993,6 +3074,8 @@ void
Parse_End(void)
{
#ifdef CLEANUP
+ HashIter hi;
+
Lst_DoneCall(&targCmds, free);
assert(targets == NULL);
SearchPath_Free(defSysIncPath);
@@ -3000,6 +3083,13 @@ Parse_End(void)
SearchPath_Free(parseIncPath);
assert(includes.len == 0);
Vector_Done(&includes);
+ HashIter_Init(&hi, &guards);
+ while (HashIter_Next(&hi) != NULL) {
+ Guard *guard = hi.entry->value;
+ free(guard->name);
+ free(guard);
+ }
+ HashTable_Done(&guards);
#endif
}
diff --git a/contrib/bmake/str.c b/contrib/bmake/str.c
index 5bb9938296f5..2797e5567e92 100644
--- a/contrib/bmake/str.c
+++ b/contrib/bmake/str.c
@@ -1,4 +1,4 @@
-/* $NetBSD: str.c,v 1.94 2022/12/07 10:28:48 rillig Exp $ */
+/* $NetBSD: str.c,v 1.99 2023/06/23 05:03:04 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -71,7 +71,7 @@
#include "make.h"
/* "@(#)str.c 5.8 (Berkeley) 6/1/90" */
-MAKE_RCSID("$NetBSD: str.c,v 1.94 2022/12/07 10:28:48 rillig Exp $");
+MAKE_RCSID("$NetBSD: str.c,v 1.99 2023/06/23 05:03:04 rillig Exp $");
static HashTable interned_strings;
@@ -316,28 +316,26 @@ in_range(char e1, char c, char e2)
* Test if a string matches a pattern like "*.[ch]". The pattern matching
* characters are '*', '?' and '[]', as in fnmatch(3).
*
- * XXX: this function does not detect or report malformed patterns.
- *
* See varmod-match.mk for examples and edge cases.
*/
-bool
+StrMatchResult
Str_Match(const char *str, const char *pat)
{
- for (; *pat != '\0'; pat++, str++) {
- if (*pat == '*') { /* match any substring */
- pat++;
- while (*pat == '*')
- pat++;
- if (*pat == '\0')
- return true;
- for (; *str != '\0'; str++)
- if (Str_Match(str, pat))
- return true;
- return false;
- }
-
+ StrMatchResult res = { NULL, false };
+ const char *fixed_str, *fixed_pat;
+ bool asterisk, matched;
+
+ asterisk = false;
+ fixed_str = str;
+ fixed_pat = pat;
+
+match_fixed_length:
+ str = fixed_str;
+ pat = fixed_pat;
+ matched = false;
+ for (; *pat != '\0' && *pat != '*'; str++, pat++) {
if (*str == '\0')
- return false;
+ return res;
if (*pat == '?') /* match any single character */
continue;
@@ -346,25 +344,32 @@ Str_Match(const char *str, const char *pat)
bool neg = pat[1] == '^';
pat += neg ? 2 : 1;
- for (;;) {
- if (*pat == ']' || *pat == '\0') {
- if (neg)
- break;
- return false;
- }
- if (*pat == *str)
- break;
- if (pat[1] == '-') {
- if (pat[2] == '\0')
- return neg;
- if (in_range(pat[0], *str, pat[2]))
- break;
- pat += 2;
- }
- pat++;
+ next_char_in_list:
+ if (*pat == '\0')
+ res.error = "Unfinished character list";
+ if (*pat == ']' || *pat == '\0') {
+ if (neg)
+ goto end_of_char_list;
+ goto match_done;
+ }
+ if (*pat == *str)
+ goto end_of_char_list;
+ if (pat[1] == '-' && pat[2] == '\0') {
+ res.error = "Unfinished character range";
+ res.matched = neg;
+ return res;
}
+ if (pat[1] == '-') {
+ if (in_range(pat[0], *str, pat[2]))
+ goto end_of_char_list;
+ pat += 2;
+ }
+ pat++;
+ goto next_char_in_list;
+
+ end_of_char_list:
if (neg && *pat != ']' && *pat != '\0')
- return false;
+ goto match_done;
while (*pat != ']' && *pat != '\0')
pat++;
if (*pat == '\0')
@@ -374,11 +379,44 @@ Str_Match(const char *str, const char *pat)
if (*pat == '\\') /* match the next character exactly */
pat++;
-
if (*pat != *str)
- return false;
+ goto match_done;
+ }
+ matched = true;
+
+match_done:
+ if (!asterisk) {
+ if (!matched)
+ return res;
+ if (*pat == '\0') {
+ res.matched = *str == '\0';
+ return res;
+ }
+ asterisk = true;
+ } else {
+ if (!matched) {
+ fixed_str++;
+ goto match_fixed_length;
+ }
+ if (*pat == '\0') {
+ if (*str == '\0') {
+ res.matched = true;
+ return res;
+ }
+ fixed_str += strlen(str);
+ goto match_fixed_length;
+ }
+ }
+
+ while (*pat == '*')
+ pat++;
+ if (*pat == '\0') {
+ res.matched = true;
+ return res;
}
- return *str == '\0';
+ fixed_str = str;
+ fixed_pat = pat;
+ goto match_fixed_length;
}
void
diff --git a/contrib/bmake/str.h b/contrib/bmake/str.h
index 38fd2cf0da1a..71fd6bd15944 100644
--- a/contrib/bmake/str.h
+++ b/contrib/bmake/str.h
@@ -1,4 +1,4 @@
-/* $NetBSD: str.h,v 1.16 2022/12/05 23:41:24 rillig Exp $ */
+/* $NetBSD: str.h,v 1.17 2023/06/23 04:56:54 rillig Exp $ */
/*
Copyright (c) 2021 Roland Illig <rillig@NetBSD.org>
@@ -70,6 +70,11 @@ typedef struct SubstringWords {
void *freeIt;
} SubstringWords;
+typedef struct StrMatchResult {
+ const char *error;
+ bool matched;
+} StrMatchResult;
+
MAKE_INLINE FStr
FStr_Init(const char *str, void *freeIt)
@@ -336,7 +341,7 @@ SubstringWords_Free(SubstringWords w)
char *str_concat2(const char *, const char *);
char *str_concat3(const char *, const char *, const char *);
-bool Str_Match(const char *, const char *);
+StrMatchResult Str_Match(const char *, const char *);
void Str_Intern_Init(void);
void Str_Intern_End(void);
diff --git a/contrib/bmake/unit-tests/Makefile b/contrib/bmake/unit-tests/Makefile
index a3f069133739..9bad6ff073ef 100644
--- a/contrib/bmake/unit-tests/Makefile
+++ b/contrib/bmake/unit-tests/Makefile
@@ -1,6 +1,6 @@
-# $Id: Makefile,v 1.195 2023/05/10 18:26:24 sjg Exp $
+# $Id: Makefile,v 1.199 2023/06/20 17:27:20 sjg Exp $
#
-# $NetBSD: Makefile,v 1.335 2023/05/10 13:03:06 rillig Exp $
+# $NetBSD: Makefile,v 1.339 2023/06/20 09:25:34 rillig Exp $
#
# Unit tests for make(1)
#
@@ -195,6 +195,7 @@ TESTS+= directive-ifndef
TESTS+= directive-ifnmake
TESTS+= directive-include
TESTS+= directive-include-fatal
+TESTS+= directive-include-guard
TESTS+= directive-info
TESTS+= directive-misspellings
TESTS+= directive-sinclude
@@ -211,7 +212,6 @@ TESTS+= export
TESTS+= export-all
TESTS+= export-env
TESTS+= export-variants
-TESTS+= forsubst
TESTS+= gnode-submake
TESTS+= hanoi-include
TESTS+= impsrc
@@ -228,7 +228,6 @@ TESTS+= lint
TESTS+= make-exported
TESTS+= meta-cmd-cmp
TESTS+= moderrs
-TESTS+= modmatch
TESTS+= modmisc
.if ${.MAKE.UID} > 0
TESTS+= objdir-writable
@@ -424,10 +423,14 @@ TESTS+= varname-dot-make-meta-files
.if ${.MAKE.PATH_FILEMON:Uno:Nktrace:N/dev*} == "" && ${TMPDIR:N/tmp*:N/var/tmp*} != ""
# these tests will not work if TMPDIR is or is a subdir of
# /tmp or /var/tmp
+.if ${.MAKE.PATH_FILEMON:N/dev/*} != "" || exists(${.MAKE.PATH_FILEMON})
TESTS+= varname-dot-make-meta-ignore_filter
TESTS+= varname-dot-make-meta-ignore_paths
TESTS+= varname-dot-make-meta-ignore_patterns
TESTS+= varname-dot-make-path_filemon
+.else
+.warning Skipping tests that require ${.MAKE.PATH_FILEMON}
+.endif
.endif
TESTS+= varname-dot-make-meta-prefix
TESTS+= varname-dot-make-mode
@@ -538,6 +541,12 @@ FLAGS.varname-empty= -dv '$${:U}=cmdline-u' '=cmdline-plain'
# Some tests need extra postprocessing.
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 '/^SetFilenameVars:/d' \
+ -e '/^ParseDependency/d' \
+ -e '/^ParseEOF:/d'
SED_CMDS.export= -e '/^[^=_A-Za-z0-9]*=/d'
SED_CMDS.export-all= ${SED_CMDS.export}
SED_CMDS.export-env= ${SED_CMDS.export}
diff --git a/contrib/bmake/unit-tests/cmdline-undefined.exp b/contrib/bmake/unit-tests/cmdline-undefined.exp
index 977ceee6dbf5..197f6da60131 100644
--- a/contrib/bmake/unit-tests/cmdline-undefined.exp
+++ b/contrib/bmake/unit-tests/cmdline-undefined.exp
@@ -1,17 +1,17 @@
The = assignment operator
-make: "cmdline-undefined.mk" line 29: From the command line: Undefined is .
-make: "cmdline-undefined.mk" line 30: From .MAKEFLAGS '=': Undefined is .
-make: "cmdline-undefined.mk" line 31: From .MAKEFLAGS ':=': Undefined is .
-make: "cmdline-undefined.mk" line 35: From the command line: Undefined is now defined.
-make: "cmdline-undefined.mk" line 36: From .MAKEFLAGS '=': Undefined is now defined.
-make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is now defined.
+make: "cmdline-undefined.mk" line 31: From the command line: Undefined is .
+make: "cmdline-undefined.mk" line 34: From .MAKEFLAGS '=': Undefined is .
+make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is .
+make: "cmdline-undefined.mk" line 43: From the command line: Undefined is now defined.
+make: "cmdline-undefined.mk" line 46: From .MAKEFLAGS '=': Undefined is now defined.
+make: "cmdline-undefined.mk" line 49: From .MAKEFLAGS ':=': Undefined is now defined.
The := assignment operator
-make: "cmdline-undefined.mk" line 29: From the command line: Undefined is .
-make: "cmdline-undefined.mk" line 30: From .MAKEFLAGS '=': Undefined is .
-make: "cmdline-undefined.mk" line 31: From .MAKEFLAGS ':=': Undefined is .
-make: "cmdline-undefined.mk" line 35: From the command line: Undefined is now defined.
-make: "cmdline-undefined.mk" line 36: From .MAKEFLAGS '=': Undefined is now defined.
-make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is now defined.
+make: "cmdline-undefined.mk" line 31: From the command line: Undefined is .
+make: "cmdline-undefined.mk" line 34: From .MAKEFLAGS '=': Undefined is .
+make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is .
+make: "cmdline-undefined.mk" line 43: From the command line: Undefined is now defined.
+make: "cmdline-undefined.mk" line 46: From .MAKEFLAGS '=': Undefined is now defined.
+make: "cmdline-undefined.mk" line 49: From .MAKEFLAGS ':=': Undefined is now defined.
exit status 0
diff --git a/contrib/bmake/unit-tests/cmdline-undefined.mk b/contrib/bmake/unit-tests/cmdline-undefined.mk
index 5a3375cbbfb8..062449f80df2 100644
--- a/contrib/bmake/unit-tests/cmdline-undefined.mk
+++ b/contrib/bmake/unit-tests/cmdline-undefined.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cmdline-undefined.mk,v 1.2 2020/11/04 04:49:33 rillig Exp $
+# $NetBSD: cmdline-undefined.mk,v 1.3 2023/06/01 20:56:35 rillig Exp $
#
# Tests for undefined variable expressions in the command line.
@@ -26,14 +26,26 @@ all:
.MAKEFLAGS: MAKEFLAGS_ASSIGN='Undefined is $${UNDEFINED}.'
.MAKEFLAGS: MAKEFLAGS_SUBST:='Undefined is $${UNDEFINED}.'
+# expect+2: From the command line: Undefined is .
+# expect+1: From the command line: Undefined is .
.info From the command line: ${CMDLINE}
+# expect+2: From .MAKEFLAGS '=': Undefined is .
+# expect+1: From .MAKEFLAGS '=': Undefined is .
.info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN}
+# expect+2: From .MAKEFLAGS ':=': Undefined is .
+# expect+1: From .MAKEFLAGS ':=': Undefined is .
.info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST}
UNDEFINED?= now defined
+# expect+2: From the command line: Undefined is now defined.
+# expect+1: From the command line: Undefined is now defined.
.info From the command line: ${CMDLINE}
+# expect+2: From .MAKEFLAGS '=': Undefined is now defined.
+# expect+1: From .MAKEFLAGS '=': Undefined is now defined.
.info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN}
+# expect+2: From .MAKEFLAGS ':=': Undefined is now defined.
+# expect+1: From .MAKEFLAGS ':=': Undefined is now defined.
.info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST}
print-undefined:
diff --git a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp
index 72d3d935755b..059007f00c84 100644
--- a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp
+++ b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp
@@ -1,5 +1,5 @@
-make: "cond-cmp-numeric-eq.mk" line 67: Malformed conditional (!(12345 = 12345))
-make: "cond-cmp-numeric-eq.mk" line 74: 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/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk
index c6b39876e75e..4c5f9b8aa830 100755
--- a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk
+++ b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-cmp-numeric-eq.mk,v 1.5 2020/11/08 21:47:59 rillig Exp $
+# $NetBSD: cond-cmp-numeric-eq.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for numeric comparisons with the == operator in .if conditions.
@@ -64,6 +64,7 @@
.endif
# There is no = operator for numbers.
+# expect+1: Malformed conditional (!(12345 = 12345))
.if !(12345 = 12345)
. error
.else
@@ -71,6 +72,7 @@
.endif
# There is no === operator for numbers either.
+# expect+1: Malformed conditional (!(12345 === 12345))
.if !(12345 === 12345)
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-cmp-unary.exp b/contrib/bmake/unit-tests/cond-cmp-unary.exp
index 89f90dc1651f..c5b800122eb9 100755
--- a/contrib/bmake/unit-tests/cond-cmp-unary.exp
+++ b/contrib/bmake/unit-tests/cond-cmp-unary.exp
@@ -1,2 +1,2 @@
-make: "cond-cmp-unary.mk" line 53: This is only reached because of a bug in EvalNotEmpty.
+make: "cond-cmp-unary.mk" line 54: This is only reached because of a bug in EvalTruthy.
exit status 0
diff --git a/contrib/bmake/unit-tests/cond-cmp-unary.mk b/contrib/bmake/unit-tests/cond-cmp-unary.mk
index 90cd04e5092b..58927e3b4944 100755
--- a/contrib/bmake/unit-tests/cond-cmp-unary.mk
+++ b/contrib/bmake/unit-tests/cond-cmp-unary.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-cmp-unary.mk,v 1.3 2022/09/08 05:43:20 rillig Exp $
+# $NetBSD: cond-cmp-unary.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for unary comparisons in .if conditions, that is, comparisons with
# a single operand. If the operand is a number, it is compared to zero,
@@ -26,8 +26,8 @@
# The empty string may come from a variable expression.
#
-# XXX: As of 2020-11-11, this empty string is interpreted "as a number" in
-# EvalNotEmpty, which is plain wrong. The bug is in TryParseNumber.
+# XXX: As of 2023-06-01, this empty string is interpreted "as a number" in
+# EvalTruthy, which is plain wrong. The bug is in TryParseNumber.
.if ${:U}
. error
.endif
@@ -45,12 +45,13 @@
# A string of whitespace should evaluate to false.
#
-# XXX: As of 2020-11-11, the implementation in EvalNotEmpty does not skip
+# XXX: As of 2023-06-01, the implementation in EvalTruthy does not skip
# whitespace before testing for the end. This was probably an oversight in
# a commit from 1992-04-15 saying "A variable is empty when it just contains
# spaces".
.if ${:U }
-. info This is only reached because of a bug in EvalNotEmpty.
+# expect+1: This is only reached because of a bug in EvalTruthy.
+. info This is only reached because of a bug in EvalTruthy.
.else
. error
.endif
diff --git a/contrib/bmake/unit-tests/cond-eof.exp b/contrib/bmake/unit-tests/cond-eof.exp
index 3016a9b27805..58a74d854d91 100644
--- a/contrib/bmake/unit-tests/cond-eof.exp
+++ b/contrib/bmake/unit-tests/cond-eof.exp
@@ -1,6 +1,6 @@
-make: "cond-eof.mk" line 15: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
-make: "cond-eof.mk" line 17: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
-make: "cond-eof.mk" line 19: 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/contrib/bmake/unit-tests/cond-eof.mk b/contrib/bmake/unit-tests/cond-eof.mk
index ddf4a4cd20c8..25c6ec5de708 100644
--- a/contrib/bmake/unit-tests/cond-eof.mk
+++ b/contrib/bmake/unit-tests/cond-eof.mk
@@ -1,7 +1,8 @@
-# $NetBSD: cond-eof.mk,v 1.3 2021/12/10 23:12:44 rillig Exp $
+# $NetBSD: cond-eof.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
-# Tests for parsing conditions, especially the end of such conditions, which
-# are represented as the token TOK_EOF.
+# Tests for parsing the end of '.if' conditions, which are represented as the
+# token TOK_EOF.
+
SIDE_EFFECT= ${:!echo 'side effect' 1>&2!}
SIDE_EFFECT2= ${:!echo 'side effect 2' 1>&2!}
@@ -12,9 +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})
.if 0 ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
+# 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})
.if (0) ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
diff --git a/contrib/bmake/unit-tests/cond-func-defined.exp b/contrib/bmake/unit-tests/cond-func-defined.exp
index 878f56de2ecc..c2fc78c1a35a 100644
--- a/contrib/bmake/unit-tests/cond-func-defined.exp
+++ b/contrib/bmake/unit-tests/cond-func-defined.exp
@@ -1,8 +1,8 @@
-make: "cond-func-defined.mk" line 23: Missing closing parenthesis for defined()
-make: "cond-func-defined.mk" line 33: Missing closing parenthesis for defined()
-make: "cond-func-defined.mk" line 45: In .for loops, variable expressions for the loop variables are
-make: "cond-func-defined.mk" line 46: substituted at evaluation time. There is no actual variable
-make: "cond-func-defined.mk" line 47: involved, even if it feels like it.
+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 47: In .for loops, variable expressions for the loop variables are
+make: "cond-func-defined.mk" line 49: substituted at evaluation time. There is no actual variable
+make: "cond-func-defined.mk" line 51: involved, even if it feels like it.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-func-defined.mk b/contrib/bmake/unit-tests/cond-func-defined.mk
index f13e2a9a1f7c..10adfde292ed 100644
--- a/contrib/bmake/unit-tests/cond-func-defined.mk
+++ b/contrib/bmake/unit-tests/cond-func-defined.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-defined.mk,v 1.9 2022/05/08 06:51:27 rillig Exp $
+# $NetBSD: cond-func-defined.mk,v 1.10 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the defined() function in .if conditions.
@@ -20,6 +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()
.if !defined(A B)
. error
.endif
@@ -29,7 +30,7 @@ ${:UA B}= variable name with spaces
. error
.endif
-# Parse error: missing closing parenthesis; see ParseWord.
+# expect+1: Missing closing parenthesis for defined()
.if defined(DEF
. error
.else
@@ -42,8 +43,11 @@ ${:UA B}= variable name with spaces
. if defined(var)
. error
. else
+# expect+1: In .for loops, variable expressions for the loop variables are
. info In .for loops, variable expressions for the loop variables are
+# expect+1: substituted at evaluation time. There is no actual variable
. info substituted at evaluation time. There is no actual variable
+# expect+1: involved, even if it feels like it.
. info involved, even if it feels like it.
. endif
.endfor
diff --git a/contrib/bmake/unit-tests/cond-func-empty.exp b/contrib/bmake/unit-tests/cond-func-empty.exp
index 35d83adad5cb..5584b4062824 100644
--- a/contrib/bmake/unit-tests/cond-func-empty.exp
+++ b/contrib/bmake/unit-tests/cond-func-empty.exp
@@ -1,5 +1,5 @@
-make: "cond-func-empty.mk" line 153: Unclosed variable "WORD"
-make: "cond-func-empty.mk" line 153: Malformed conditional (empty(WORD)
+make: "cond-func-empty.mk" line 154: Unclosed variable "WORD"
+make: "cond-func-empty.mk" line 154: Malformed conditional (empty(WORD)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-func-empty.mk b/contrib/bmake/unit-tests/cond-func-empty.mk
index 293305281298..69f489efae08 100644
--- a/contrib/bmake/unit-tests/cond-func-empty.mk
+++ b/contrib/bmake/unit-tests/cond-func-empty.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-empty.mk,v 1.18 2023/03/04 21:15:30 rillig Exp $
+# $NetBSD: cond-func-empty.mk,v 1.20 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the empty() function in .if conditions, which tests a variable
# expression for emptiness.
@@ -25,7 +25,7 @@ WORD= word
.endif
# The :S modifier replaces the empty value with an actual word. After
-# applying the :S modifier to the expression, it value is 'empty', so it is
+# applying the :S modifier to the expression, its value is 'empty', so it is
# no longer empty, but it is still based on an undefined variable. There are
# a few modifiers that turn an undefined expression into a defined expression,
# among them :U and :D, but not :S. Therefore, at the end of evaluating the
@@ -149,7 +149,8 @@ ${:U WORD }= variable name with spaces
. error
.endif
-# Parse error: missing closing parenthesis.
+# expect+2: Unclosed variable "WORD"
+# expect+1: Malformed conditional (empty(WORD)
.if empty(WORD
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-func-make.exp b/contrib/bmake/unit-tests/cond-func-make.exp
index 922203b72cbf..04ef6e29fee1 100644
--- a/contrib/bmake/unit-tests/cond-func-make.exp
+++ b/contrib/bmake/unit-tests/cond-func-make.exp
@@ -1,3 +1,4 @@
+make: "cond-func-make.mk" line 24: warning: Unfinished character list in pattern argument '[' to function 'make'
: via-cmdline
: via-dot-makeflags
exit status 0
diff --git a/contrib/bmake/unit-tests/cond-func-make.mk b/contrib/bmake/unit-tests/cond-func-make.mk
index d75b69bcf98f..15bc9f04d4e0 100644
--- a/contrib/bmake/unit-tests/cond-func-make.mk
+++ b/contrib/bmake/unit-tests/cond-func-make.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-make.mk,v 1.3 2020/09/25 20:11:06 rillig Exp $
+# $NetBSD: cond-func-make.mk,v 1.5 2023/06/23 04:56:54 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
@@ -20,5 +20,10 @@
. error
.endif
+# expect+1: warning: Unfinished character list in pattern argument '[' to function 'make'
+.if make([)
+. error
+.endif
+
via-cmdline via-dot-makeflags:
: $@
diff --git a/contrib/bmake/unit-tests/cond-func.exp b/contrib/bmake/unit-tests/cond-func.exp
index d0663ea68647..eeaa89445887 100644
--- a/contrib/bmake/unit-tests/cond-func.exp
+++ b/contrib/bmake/unit-tests/cond-func.exp
@@ -1,12 +1,12 @@
-make: "cond-func.mk" line 36: Missing closing parenthesis for defined()
-make: "cond-func.mk" line 51: Missing closing parenthesis for defined()
-make: "cond-func.mk" line 54: Missing closing parenthesis for defined()
-make: "cond-func.mk" line 94: The empty variable is never defined.
-make: "cond-func.mk" line 103: A plain function name is parsed as defined(...).
-make: "cond-func.mk" line 110: A plain function name is parsed as defined(...).
-make: "cond-func.mk" line 120: Symbols may start with a function name.
-make: "cond-func.mk" line 125: Symbols may start with a function name.
-make: "cond-func.mk" line 131: Missing closing parenthesis for defined()
+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 98: The empty variable is never defined.
+make: "cond-func.mk" line 108: A plain function name is parsed as defined(...).
+make: "cond-func.mk" line 116: A plain function name is parsed as defined(...).
+make: "cond-func.mk" line 127: Symbols may start with a function name.
+make: "cond-func.mk" line 133: Symbols may start with a function name.
+make: "cond-func.mk" line 139: Missing closing parenthesis for defined()
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-func.mk b/contrib/bmake/unit-tests/cond-func.mk
index e09b363edb64..2e8a6785b0e8 100644
--- a/contrib/bmake/unit-tests/cond-func.mk
+++ b/contrib/bmake/unit-tests/cond-func.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func.mk,v 1.12 2023/05/10 15:53:32 rillig Exp $
+# $NetBSD: cond-func.mk,v 1.13 2023/06/01 20:56:35 rillig Exp $
#
# Tests for those parts of the functions in .if conditions that are common
# among several functions.
@@ -33,6 +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()
.if !defined(A B)
. error
.endif
@@ -48,9 +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()
.if !defined(A&B)
. error
.endif
+# expect+1: Missing closing parenthesis for defined()
.if !defined(A|B)
. error
.endif
@@ -91,6 +94,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
.if defined()
. error
.else
+# expect+1: The empty variable is never defined.
. info The empty variable is never defined.
.endif
@@ -100,6 +104,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
.if defined
. error
.else
+# expect+1: A plain function name is parsed as defined(...).
. info A plain function name is parsed as defined(...).
.endif
@@ -107,6 +112,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
# is interpreted as 'defined(defined)', and the condition evaluates to true.
defined= # defined but empty
.if defined
+# expect+1: A plain function name is parsed as defined(...).
. info A plain function name is parsed as defined(...).
.else
. error
@@ -117,17 +123,19 @@ defined= # defined but empty
.if defined-var
. error
.else
+# expect+1: Symbols may start with a function name.
. info Symbols may start with a function name.
.endif
defined-var= # defined but empty
.if defined-var
+# expect+1: Symbols may start with a function name.
. info Symbols may start with a function name.
.else
. error
.endif
-# Missing closing parenthesis when parsing the function argument.
+# expect+1: Missing closing parenthesis for defined()
.if defined(
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-op-and-lint.exp b/contrib/bmake/unit-tests/cond-op-and-lint.exp
index 8817fd0d658b..0f2cdb0028f9 100644
--- a/contrib/bmake/unit-tests/cond-op-and-lint.exp
+++ b/contrib/bmake/unit-tests/cond-op-and-lint.exp
@@ -1,4 +1,4 @@
-make: "cond-op-and-lint.mk" line 9: Unknown operator '&'
+make: "cond-op-and-lint.mk" line 10: Unknown operator '&'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op-and-lint.mk b/contrib/bmake/unit-tests/cond-op-and-lint.mk
index 6262339016f5..bac4566314b0 100644
--- a/contrib/bmake/unit-tests/cond-op-and-lint.mk
+++ b/contrib/bmake/unit-tests/cond-op-and-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-and-lint.mk,v 1.1 2020/11/08 23:54:28 rillig Exp $
+# $NetBSD: cond-op-and-lint.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the && operator in .if conditions, in lint mode.
@@ -6,6 +6,7 @@
# The '&' operator is not allowed in lint mode.
# It is not used in practice anyway.
+# expect+1: Unknown operator '&'
.if 0 & 0
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-op-and.exp b/contrib/bmake/unit-tests/cond-op-and.exp
index cd6b03a8359e..6d5a14b211cc 100644
--- a/contrib/bmake/unit-tests/cond-op-and.exp
+++ b/contrib/bmake/unit-tests/cond-op-and.exp
@@ -1,7 +1,7 @@
-make: "cond-op-and.mk" line 36: Malformed conditional (0 || (${DEF} && ${UNDEF}))
-make: "cond-op-and.mk" line 40: Malformed conditional (0 || (${UNDEF} && ${UNDEF}))
-make: "cond-op-and.mk" line 42: Malformed conditional (0 || (!${UNDEF} && ${UNDEF}))
-make: "cond-op-and.mk" line 71: Malformed conditional (0 &&& 0)
+make: "cond-op-and.mk" line 37: Malformed conditional (0 || (${DEF} && ${UNDEF}))
+make: "cond-op-and.mk" line 42: Malformed conditional (0 || (${UNDEF} && ${UNDEF}))
+make: "cond-op-and.mk" line 45: Malformed conditional (0 || (!${UNDEF} && ${UNDEF}))
+make: "cond-op-and.mk" line 75: Malformed conditional (0 &&& 0)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op-and.mk b/contrib/bmake/unit-tests/cond-op-and.mk
index 83386ed77de4..d12c6821f3b4 100644
--- a/contrib/bmake/unit-tests/cond-op-and.mk
+++ b/contrib/bmake/unit-tests/cond-op-and.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-and.mk,v 1.6 2021/12/10 19:14:35 rillig Exp $
+# $NetBSD: cond-op-and.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the && operator in .if conditions.
@@ -33,12 +33,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})
.if 0 || (${DEF} && ${UNDEF})
.endif
.if 0 || (!${DEF} && ${UNDEF})
.endif
+# expect+1: Malformed conditional (0 || (${UNDEF} && ${UNDEF})
.if 0 || (${UNDEF} && ${UNDEF})
.endif
+# expect+1: Malformed conditional (0 || (!${UNDEF} && ${UNDEF})
.if 0 || (!${UNDEF} && ${UNDEF})
.endif
.if 1 || (${DEF} && ${UNDEF})
@@ -68,6 +71,7 @@ DEF= defined
.endif
# There is no operator &&&.
+# expect+1: Malformed conditional (0 &&& 0)
.if 0 &&& 0
. error
.endif
diff --git a/contrib/bmake/unit-tests/cond-op-not.exp b/contrib/bmake/unit-tests/cond-op-not.exp
index 440670ca7249..fcdceee9af21 100644
--- a/contrib/bmake/unit-tests/cond-op-not.exp
+++ b/contrib/bmake/unit-tests/cond-op-not.exp
@@ -1,9 +1,9 @@
-make: "cond-op-not.mk" line 29: Not empty evaluates to true.
-make: "cond-op-not.mk" line 37: Not space evaluates to false.
-make: "cond-op-not.mk" line 41: Not 0 evaluates to true.
-make: "cond-op-not.mk" line 49: Not 1 evaluates to false.
-make: "cond-op-not.mk" line 55: Not word evaluates to false.
-make: "cond-op-not.mk" line 59: Malformed conditional (!)
+make: "cond-op-not.mk" line 30: Not empty evaluates to true.
+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: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op-not.mk b/contrib/bmake/unit-tests/cond-op-not.mk
index ffd5bc89e4bf..28f835fa3cbd 100644
--- a/contrib/bmake/unit-tests/cond-op-not.mk
+++ b/contrib/bmake/unit-tests/cond-op-not.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-not.mk,v 1.7 2021/01/19 17:49:13 rillig Exp $
+# $NetBSD: cond-op-not.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the ! operator in .if conditions, which negates its argument.
@@ -26,6 +26,7 @@
.endif
.if !${:U}
+# expect+1: Not empty evaluates to true.
. info Not empty evaluates to true.
.else
. info Not empty evaluates to false.
@@ -34,10 +35,12 @@
.if !${:U }
. info Not space evaluates to true.
.else
+# expect+1: Not space evaluates to false.
. info Not space evaluates to false.
.endif
.if !${:U0}
+# expect+1: Not 0 evaluates to true.
. info Not 0 evaluates to true.
.else
. info Not 0 evaluates to false.
@@ -46,16 +49,19 @@
.if !${:U1}
. info Not 1 evaluates to true.
.else
+# expect+1: Not 1 evaluates to false.
. info Not 1 evaluates to false.
.endif
.if !${:Uword}
. info Not word evaluates to true.
.else
+# expect+1: Not word evaluates to false.
. info Not word evaluates to false.
.endif
# A single exclamation mark is a parse error.
+# expect+1: Malformed conditional (!)
.if !
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-op-or-lint.exp b/contrib/bmake/unit-tests/cond-op-or-lint.exp
index 8abae99b6c4c..0fb1d0dae166 100644
--- a/contrib/bmake/unit-tests/cond-op-or-lint.exp
+++ b/contrib/bmake/unit-tests/cond-op-or-lint.exp
@@ -1,4 +1,4 @@
-make: "cond-op-or-lint.mk" line 9: Unknown operator '|'
+make: "cond-op-or-lint.mk" line 10: Unknown operator '|'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op-or-lint.mk b/contrib/bmake/unit-tests/cond-op-or-lint.mk
index aa29e9a6c2f2..9ece9d5c9af6 100644
--- a/contrib/bmake/unit-tests/cond-op-or-lint.mk
+++ b/contrib/bmake/unit-tests/cond-op-or-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-or-lint.mk,v 1.1 2020/11/08 23:54:28 rillig Exp $
+# $NetBSD: cond-op-or-lint.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the || operator in .if conditions, in lint mode.
@@ -6,6 +6,7 @@
# The '|' operator is not allowed in lint mode.
# It is not used in practice anyway.
+# expect+1: Unknown operator '|'
.if 0 | 0
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-op-or.exp b/contrib/bmake/unit-tests/cond-op-or.exp
index 43b9a5438a31..b10bc4bf7c52 100644
--- a/contrib/bmake/unit-tests/cond-op-or.exp
+++ b/contrib/bmake/unit-tests/cond-op-or.exp
@@ -1,7 +1,7 @@
-make: "cond-op-or.mk" line 46: Malformed conditional (1 && (!${DEF} || ${UNDEF}))
-make: "cond-op-or.mk" line 48: Malformed conditional (1 && (${UNDEF} || ${UNDEF}))
-make: "cond-op-or.mk" line 50: Malformed conditional (1 && (!${UNDEF} || ${UNDEF}))
-make: "cond-op-or.mk" line 71: Malformed conditional (0 ||| 0)
+make: "cond-op-or.mk" line 47: Malformed conditional (1 && (!${DEF} || ${UNDEF}))
+make: "cond-op-or.mk" line 50: Malformed conditional (1 && (${UNDEF} || ${UNDEF}))
+make: "cond-op-or.mk" line 53: Malformed conditional (1 && (!${UNDEF} || ${UNDEF}))
+make: "cond-op-or.mk" line 75: Malformed conditional (0 ||| 0)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op-or.mk b/contrib/bmake/unit-tests/cond-op-or.mk
index 0b7ac55e6c35..d0c9f3f2cd81 100644
--- a/contrib/bmake/unit-tests/cond-op-or.mk
+++ b/contrib/bmake/unit-tests/cond-op-or.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-or.mk,v 1.8 2021/12/10 19:14:35 rillig Exp $
+# $NetBSD: cond-op-or.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the || operator in .if conditions.
@@ -43,10 +43,13 @@ DEF= defined
.endif
.if 1 && (${DEF} || ${UNDEF})
.endif
+# expect+1: Malformed conditional (1 && (!${DEF} || ${UNDEF})
.if 1 && (!${DEF} || ${UNDEF})
.endif
+# expect+1: Malformed conditional (1 && (${UNDEF} || ${UNDEF})
.if 1 && (${UNDEF} || ${UNDEF})
.endif
+# expect+1: Malformed conditional (1 && (!${UNDEF} || ${UNDEF})
.if 1 && (!${UNDEF} || ${UNDEF})
.endif
@@ -68,6 +71,7 @@ DEF= defined
.endif
# There is no operator |||.
+# expect+1: Malformed conditional (0 ||| 0)
.if 0 ||| 0
. error
.endif
diff --git a/contrib/bmake/unit-tests/cond-op-parentheses.exp b/contrib/bmake/unit-tests/cond-op-parentheses.exp
index c2530f62de64..1daad92b2682 100644
--- a/contrib/bmake/unit-tests/cond-op-parentheses.exp
+++ b/contrib/bmake/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 43: Malformed conditional (()
-make: "cond-op-parentheses.mk" line 56: Malformed conditional ())
+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 in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op-parentheses.mk b/contrib/bmake/unit-tests/cond-op-parentheses.mk
index 8f8c3ee1e791..b6c9bd3c0e9d 100644
--- a/contrib/bmake/unit-tests/cond-op-parentheses.mk
+++ b/contrib/bmake/unit-tests/cond-op-parentheses.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op-parentheses.mk,v 1.6 2022/09/04 22:55:00 rillig Exp $
+# $NetBSD: cond-op-parentheses.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for parentheses in .if conditions, which group expressions to override
# the precedence of the operators '!', '&&' and '||'. Parentheses cannot be
@@ -40,6 +40,7 @@
.endif
# An unbalanced opening parenthesis is a parse error.
+# expect+1: Malformed conditional (()
.if (
. error
.else
@@ -53,6 +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 ())
.if )
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-op.exp b/contrib/bmake/unit-tests/cond-op.exp
index b8f6a4301819..33bab484a6c8 100644
--- a/contrib/bmake/unit-tests/cond-op.exp
+++ b/contrib/bmake/unit-tests/cond-op.exp
@@ -1,22 +1,21 @@
-make: "cond-op.mk" line 50: Malformed conditional ("!word" == !word)
-make: "cond-op.mk" line 76: Malformed conditional (0 ${ERR::=evaluated})
-make: "cond-op.mk" line 80: A misplaced expression after 0 is not evaluated.
-make: "cond-op.mk" line 84: Malformed conditional (1 ${ERR::=evaluated})
-make: "cond-op.mk" line 88: A misplaced expression after 1 is not evaluated.
-make: "cond-op.mk" line 92: Parsing continues until here.
-make: "cond-op.mk" line 95: A B C => (A || B) && C A || B && C A || (B && C)
-make: "cond-op.mk" line 102: 0 0 0 => 0 0 0
-make: "cond-op.mk" line 102: 0 0 1 => 0 0 0
-make: "cond-op.mk" line 102: 0 1 0 => 0 0 0
-make: "cond-op.mk" line 102: 0 1 1 => 1 1 1
-make: "cond-op.mk" line 102: 1 0 0 => 0 1 1
-make: "cond-op.mk" line 102: 1 0 1 => 1 1 1
-make: "cond-op.mk" line 102: 1 1 0 => 0 1 1
-make: "cond-op.mk" line 102: 1 1 1 => 1 1 1
-make: "cond-op.mk" line 113: Malformed conditional (1 &&)
-make: "cond-op.mk" line 121: Malformed conditional (0 &&)
-make: "cond-op.mk" line 129: Malformed conditional (1 ||)
-make: "cond-op.mk" line 138: Malformed conditional (0 ||)
+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 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
+make: "cond-op.mk" line 108: 0 0 1 => 0 0 0
+make: "cond-op.mk" line 108: 0 1 0 => 0 0 0
+make: "cond-op.mk" line 108: 0 1 1 => 1 1 1
+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: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-op.mk b/contrib/bmake/unit-tests/cond-op.mk
index c3ab09f7709a..6371e4db0594 100644
--- a/contrib/bmake/unit-tests/cond-op.mk
+++ b/contrib/bmake/unit-tests/cond-op.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-op.mk,v 1.15 2021/12/10 23:12:44 rillig Exp $
+# $NetBSD: cond-op.mk,v 1.16 2023/06/01 20:56:35 rillig Exp $
#
# Tests for operators like &&, ||, ! in .if conditions.
#
@@ -47,6 +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)
.if "!word" == !word
. error
.endif
@@ -66,32 +67,29 @@
# nevertheless, since CondParser_Or and CondParser_And asked for the expanded
# 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})
.if 0 ${ERR::=evaluated}
. error
.endif
.if ${ERR:Uundefined} == undefined
+# expect+1: A misplaced expression after 0 is not evaluated.
. info A misplaced expression after 0 is not evaluated.
.endif
.undef ERR
+# expect+1: Malformed conditional (1 ${ERR::=evaluated})
.if 1 ${ERR::=evaluated}
. error
.endif
.if ${ERR:Uundefined} == undefined
+# expect+1: A misplaced expression after 1 is not evaluated.
. info A misplaced expression after 1 is not evaluated.
.endif
-# Just in case that parsing should ever stop on the first error.
-.info Parsing continues until here.
# Demonstration that '&&' has higher precedence than '||'.
+# expect+1: A B C => (A || B) && C A || B && C A || (B && C)
.info A B C => (A || B) && C A || B && C A || (B && C)
.for a in 0 1
. for b in 0 1
@@ -99,6 +97,14 @@
. for r1 in ${ ($a || $b) && $c :?1:0}
. for r2 in ${ $a || $b && $c :?1:0}
. for r3 in ${ $a || ($b && $c) :?1:0}
+# expect+8: 0 0 0 => 0 0 0
+# expect+7: 0 0 1 => 0 0 0
+# expect+6: 0 1 0 => 0 0 0
+# expect+5: 0 1 1 => 1 1 1
+# expect+4: 1 0 0 => 0 1 1
+# expect+3: 1 0 1 => 1 1 1
+# expect+2: 1 1 0 => 0 1 1
+# expect+1: 1 1 1 => 1 1 1
. info $a $b $c => ${r1} ${r2} ${r3}
. endfor
. endfor
@@ -110,6 +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 &&)
.if 1 &&
. error
.else
@@ -118,6 +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 &&)
.if 0 &&
. error
.else
@@ -126,6 +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 ||)
.if 1 ||
. error
.else
@@ -135,6 +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 ||)
.if 0 ||
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-token-number.exp b/contrib/bmake/unit-tests/cond-token-number.exp
index 1d472b63bc77..d05833b4e01b 100644
--- a/contrib/bmake/unit-tests/cond-token-number.exp
+++ b/contrib/bmake/unit-tests/cond-token-number.exp
@@ -1,7 +1,7 @@
-make: "cond-token-number.mk" line 15: Malformed conditional (-0)
-make: "cond-token-number.mk" line 25: Malformed conditional (+0)
-make: "cond-token-number.mk" line 35: Malformed conditional (!-1)
-make: "cond-token-number.mk" line 45: 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 in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-token-number.mk b/contrib/bmake/unit-tests/cond-token-number.mk
index d1dd7371f447..6cec21cf6c44 100644
--- a/contrib/bmake/unit-tests/cond-token-number.mk
+++ b/contrib/bmake/unit-tests/cond-token-number.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-number.mk,v 1.8 2023/03/04 08:07:29 rillig Exp $
+# $NetBSD: cond-token-number.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for number tokens in .if conditions.
#
@@ -12,6 +12,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
+# expect+1: Malformed conditional (-0)
.if -0
. error
.else
@@ -22,6 +23,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
+# expect+1: Malformed conditional (+0)
.if +0
. error
.else
@@ -32,6 +34,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
+# expect+1: Malformed conditional (!-1)
.if !-1
. error
.else
@@ -42,6 +45,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
+# expect+1: Malformed conditional (!+1)
.if !+1
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-token-plain.exp b/contrib/bmake/unit-tests/cond-token-plain.exp
index 572e8b3b2c9f..a14f69581658 100644
--- a/contrib/bmake/unit-tests/cond-token-plain.exp
+++ b/contrib/bmake/unit-tests/cond-token-plain.exp
@@ -27,37 +27,37 @@ Comparing "var&&name" != "var&&name"
CondParser_Eval: ${:Uvar}||name != "var||name"
Comparing "var||name" != "var||name"
CondParser_Eval: bare
-make: "cond-token-plain.mk" line 105: A bare word is treated like defined(...), and the variable 'bare' is not defined.
+make: "cond-token-plain.mk" line 106: A bare word is treated like defined(...), and the variable 'bare' is not defined.
CondParser_Eval: VAR
-make: "cond-token-plain.mk" line 111: A bare word is treated like defined(...).
+make: "cond-token-plain.mk" line 113: A bare word is treated like defined(...).
CondParser_Eval: V${:UA}R
-make: "cond-token-plain.mk" line 118: ok
+make: "cond-token-plain.mk" line 121: ok
CondParser_Eval: V${UNDEF}AR
-make: "cond-token-plain.mk" line 126: Undefined variables in bare words expand to an empty string.
+make: "cond-token-plain.mk" line 130: Undefined variables in bare words expand to an empty string.
CondParser_Eval: 0${:Ux00}
-make: "cond-token-plain.mk" line 134: Numbers can be composed from literals and variable expressions.
+make: "cond-token-plain.mk" line 139: Numbers can be composed from literals and variable expressions.
CondParser_Eval: 0${:Ux01}
-make: "cond-token-plain.mk" line 138: Numbers can be composed from literals and variable expressions.
+make: "cond-token-plain.mk" line 144: Numbers can be composed from literals and variable expressions.
CondParser_Eval: "" ==
-make: "cond-token-plain.mk" line 144: Missing right-hand side of operator '=='
+make: "cond-token-plain.mk" line 151: Missing right-hand side of operator '=='
CondParser_Eval: == ""
-make: "cond-token-plain.mk" line 152: Malformed conditional (== "")
+make: "cond-token-plain.mk" line 160: Malformed conditional (== "")
CondParser_Eval: \\
-make: "cond-token-plain.mk" line 167: The variable '\\' is not defined.
+make: "cond-token-plain.mk" line 176: The variable '\\' is not defined.
CondParser_Eval: \\
-make: "cond-token-plain.mk" line 172: Now the variable '\\' is defined.
+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 186: Malformed conditional ($$$$$$$$ != "")
+make: "cond-token-plain.mk" line 197: Malformed conditional ($$$$$$$$ != "")
CondParser_Eval: left == right
-make: "cond-token-plain.mk" line 195: 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 201: 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 206: Malformed conditional (left == right || ${0:?:})
-make: "cond-token-plain.mk" line 225: 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/contrib/bmake/unit-tests/cond-token-plain.mk b/contrib/bmake/unit-tests/cond-token-plain.mk
index 54bdd4fbf626..b6444e8ac1d3 100644
--- a/contrib/bmake/unit-tests/cond-token-plain.mk
+++ b/contrib/bmake/unit-tests/cond-token-plain.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-plain.mk,v 1.17 2023/02/14 20:49:09 rillig Exp $
+# $NetBSD: cond-token-plain.mk,v 1.18 2023/06/01 20:56:35 rillig Exp $
#
# Tests for plain tokens (that is, string literals without quotes)
# in .if conditions. These are also called bare words.
@@ -102,12 +102,14 @@
.if bare
. error
.else
+# expect+1: A bare word is treated like defined(...), and the variable 'bare' is not defined.
. info A bare word is treated like defined(...), and the variable $\
'bare' is not defined.
.endif
VAR= defined
.if VAR
+# expect+1: A bare word is treated like defined(...).
. info A bare word is treated like defined(...).
.else
. error
@@ -115,6 +117,7 @@ VAR= defined
# Bare words may be intermixed with variable expressions.
.if V${:UA}R
+# expect+1: ok
. info ok
.else
. error
@@ -123,6 +126,7 @@ VAR= defined
# In bare words, even undefined variables are allowed. Without the bare
# words, undefined variables are not allowed. That feels inconsistent.
.if V${UNDEF}AR
+# expect+1: Undefined variables in bare words expand to an empty string.
. info Undefined variables in bare words expand to an empty string.
.else
. error
@@ -131,16 +135,19 @@ VAR= defined
.if 0${:Ux00}
. error
.else
+# expect+1: Numbers can be composed from literals and variable expressions.
. info Numbers can be composed from literals and variable expressions.
.endif
.if 0${:Ux01}
+# expect+1: Numbers can be composed from literals and variable expressions.
. info Numbers can be composed from literals and variable expressions.
.else
. error
.endif
# If the right-hand side is missing, it's a parse error.
+# expect+1: Missing right-hand side of operator '=='
.if "" ==
. error
.else
@@ -149,6 +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 (== "")
.if == ""
. error
.else
@@ -164,11 +172,13 @@ VAR= defined
.if \\
. error
.else
+# expect+1: The variable '\\' is not defined.
. info The variable '\\' is not defined.
.endif
${:U\\\\}= backslash
.if \\
+# expect+1: Now the variable '\\' is defined.
. info Now the variable '\\' is defined.
.else
. error
@@ -183,6 +193,7 @@ ${:U\\\\}= backslash
# FIXME: In CondParser_String, Var_Parse returns var_Error without a
# corresponding error message.
+# expect+1: Malformed conditional ($$$$$$$$ != "")
.if $$$$$$$$ != ""
. error
.else
diff --git a/contrib/bmake/unit-tests/cond-token-string.exp b/contrib/bmake/unit-tests/cond-token-string.exp
index 854de02b7310..959effba0908 100644
--- a/contrib/bmake/unit-tests/cond-token-string.exp
+++ b/contrib/bmake/unit-tests/cond-token-string.exp
@@ -1,18 +1,18 @@
-make: "cond-token-string.mk" line 13: Unknown modifier "Z"
-make: "cond-token-string.mk" line 13: Malformed conditional ("" != "${:Uvalue:Z}")
-make: "cond-token-string.mk" line 22: xvalue is not defined.
-make: "cond-token-string.mk" line 28: Malformed conditional (x${:Uvalue} == "")
-make: "cond-token-string.mk" line 37: Expected.
+make: "cond-token-string.mk" line 15: 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.
CondParser_Eval: "UNDEF"
-make: "cond-token-string.mk" line 46: The string literal "UNDEF" is not empty.
+make: "cond-token-string.mk" line 52: The string literal "UNDEF" is not empty.
CondParser_Eval: " "
-make: "cond-token-string.mk" line 54: The string literal " " is not empty, even though it consists of whitespace only.
+make: "cond-token-string.mk" line 61: The string literal " " is not empty, even though it consists of whitespace only.
CondParser_Eval: "${UNDEF}"
-make: "cond-token-string.mk" line 63: An undefined variable in quotes expands to an empty string, which then evaluates to false.
+make: "cond-token-string.mk" line 71: An undefined variable in quotes expands to an empty string, which then evaluates to false.
CondParser_Eval: "${:Uvalue}"
-make: "cond-token-string.mk" line 68: A nonempty variable expression evaluates to true.
+make: "cond-token-string.mk" line 77: A nonempty variable expression evaluates to true.
CondParser_Eval: "${:U}"
-make: "cond-token-string.mk" line 76: An empty variable evaluates to false.
+make: "cond-token-string.mk" line 86: An empty variable evaluates to false.
CondParser_Eval: ("${VAR}")
CondParser_Eval: "quoted" == quoted
Comparing "quoted" == "quoted"
diff --git a/contrib/bmake/unit-tests/cond-token-string.mk b/contrib/bmake/unit-tests/cond-token-string.mk
index 4a0f175fc79f..7ecf3059e300 100644
--- a/contrib/bmake/unit-tests/cond-token-string.mk
+++ b/contrib/bmake/unit-tests/cond-token-string.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-string.mk,v 1.6 2022/05/08 06:57:00 rillig Exp $
+# $NetBSD: cond-token-string.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for quoted string literals in .if conditions.
#
@@ -9,7 +9,9 @@
# TODO: Implementation
# Cover the code in CondParser_String that frees the memory after parsing
-# a variable expression based on an undefined variable.
+# an expression based on an undefined variable.
+# expect+2: Malformed conditional ("" != "${:Uvalue:Z}")
+# expect+1: Unknown modifier "Z"
.if "" != "${:Uvalue:Z}"
. error
.else
@@ -19,12 +21,14 @@
.if x${:Uvalue}
. error
.else
+# expect+1: xvalue is not defined.
. info xvalue is not defined.
.endif
# The 'x' produces a "Malformed conditional" since the left-hand side of a
# comparison in an .if directive must be either a variable expression, a
# quoted string literal or a number that starts with a digit.
+# expect+1: Malformed conditional (x${:Uvalue} == "")
.if x${:Uvalue} == ""
. error
.else
@@ -34,6 +38,7 @@
# In plain words, a '\' can be used to escape any character, just as in
# double-quoted string literals. See CondParser_String.
.if \x${:Uvalue} == "xvalue"
+# expect+1: Expected.
. info Expected.
.else
. error
@@ -43,6 +48,7 @@
# A string in quotes is checked whether it is not empty.
.if "UNDEF"
+# expect+1: The string literal "UNDEF" is not empty.
. info The string literal "UNDEF" is not empty.
.else
. error
@@ -51,6 +57,7 @@
# A space is not empty as well.
# This differs from many other places where whitespace is trimmed.
.if " "
+# expect+1: The string literal " " is not empty, even though it consists of whitespace only.
. info The string literal " " is not empty, even though it consists of $\
whitespace only.
.else
@@ -60,11 +67,13 @@
.if "${UNDEF}"
. error
.else
+# expect+1: An undefined variable in quotes expands to an empty string, which then evaluates to false.
. info An undefined variable in quotes expands to an empty string, which $\
then evaluates to false.
.endif
.if "${:Uvalue}"
+# expect+1: A nonempty variable expression evaluates to true.
. info A nonempty variable expression evaluates to true.
.else
. error
@@ -73,6 +82,7 @@
.if "${:U}"
. error
.else
+# expect+1: An empty variable evaluates to false.
. info An empty variable evaluates to false.
.endif
diff --git a/contrib/bmake/unit-tests/cond-token-var.exp b/contrib/bmake/unit-tests/cond-token-var.exp
index fcd92d12a3da..d84ca56e981b 100644
--- a/contrib/bmake/unit-tests/cond-token-var.exp
+++ b/contrib/bmake/unit-tests/cond-token-var.exp
@@ -1,7 +1,7 @@
-make: "cond-token-var.mk" line 20: ok
-make: "cond-token-var.mk" line 27: Malformed conditional (${UNDEF} == ${DEF})
-make: "cond-token-var.mk" line 33: Malformed conditional (${DEF} == ${UNDEF})
-make: "cond-token-var.mk" line 42: Malformed conditional (${UNDEF})
+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: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-token-var.mk b/contrib/bmake/unit-tests/cond-token-var.mk
index 168c63c46ac1..b50c0439c127 100644
--- a/contrib/bmake/unit-tests/cond-token-var.mk
+++ b/contrib/bmake/unit-tests/cond-token-var.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-token-var.mk,v 1.6 2021/04/25 21:05:38 rillig Exp $
+# $NetBSD: cond-token-var.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for variable expressions in .if conditions.
#
@@ -17,19 +17,20 @@ DEF= defined
# A defined variable may appear on either side of the comparison.
.if ${DEF} == ${DEF}
+# expect+1: ok
. info ok
.else
. error
.endif
# A variable that appears on the left-hand side must be defined.
-# The following line thus generates a parse error.
+# expect+1: Malformed conditional (${UNDEF} == ${DEF})
.if ${UNDEF} == ${DEF}
. error
.endif
# A variable that appears on the right-hand side must be defined.
-# The following line thus generates a parse error.
+# expect+1: Malformed conditional (${DEF} == ${UNDEF})
.if ${DEF} == ${UNDEF}
. error
.endif
@@ -39,6 +40,7 @@ DEF= defined
.endif
# An undefined variable on its own generates a parse error.
+# expect+1: Malformed conditional (${UNDEF})
.if ${UNDEF}
.endif
diff --git a/contrib/bmake/unit-tests/cond-undef-lint.exp b/contrib/bmake/unit-tests/cond-undef-lint.exp
index 55073b2116c6..efab46113f67 100755
--- a/contrib/bmake/unit-tests/cond-undef-lint.exp
+++ b/contrib/bmake/unit-tests/cond-undef-lint.exp
@@ -1,10 +1,10 @@
-make: "cond-undef-lint.mk" line 23: Variable "UNDEF" is undefined
-make: "cond-undef-lint.mk" line 23: Malformed conditional (${UNDEF})
-make: "cond-undef-lint.mk" line 38: Variable "UNDEF" is undefined
-make: "cond-undef-lint.mk" line 38: Variable "VAR." is undefined
-make: "cond-undef-lint.mk" line 38: Malformed conditional (${VAR.${UNDEF}})
-make: "cond-undef-lint.mk" line 49: Variable "VAR.defined" is undefined
-make: "cond-undef-lint.mk" line 49: Malformed conditional (${VAR.${DEF}})
+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: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/cond-undef-lint.mk b/contrib/bmake/unit-tests/cond-undef-lint.mk
index 9dfd1bd53252..6fd353dc60e2 100755
--- a/contrib/bmake/unit-tests/cond-undef-lint.mk
+++ b/contrib/bmake/unit-tests/cond-undef-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cond-undef-lint.mk,v 1.3 2020/11/15 14:58:14 rillig Exp $
+# $NetBSD: cond-undef-lint.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for defined and undefined variables in .if conditions, in lint mode.
#
@@ -20,6 +20,8 @@ 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
.else
@@ -35,6 +37,9 @@ DEF= defined
#
# 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}})
.if ${VAR.${UNDEF}}
. error
.else
@@ -46,6 +51,8 @@ DEF= defined
# 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}})
.if ${VAR.${DEF}}
. error
.else
diff --git a/contrib/bmake/unit-tests/dep-colon-bug-cross-file.exp b/contrib/bmake/unit-tests/dep-colon-bug-cross-file.exp
index 855b575c48bc..a8ef9d0707af 100644
--- a/contrib/bmake/unit-tests/dep-colon-bug-cross-file.exp
+++ b/contrib/bmake/unit-tests/dep-colon-bug-cross-file.exp
@@ -1,4 +1,4 @@
-make: "dep-colon-bug-cross-file.mk" line 31: warning: duplicate script for target "all" ignored
-make: "dep-colon-bug-cross-file.mk" line 40: warning: using previous script for "all" defined here
+make: "dep-colon-bug-cross-file.mk" line 32: warning: duplicate script for target "all" ignored
+make: "dep-colon-bug-cross-file.mk" line 42: warning: using previous script for "all" defined here
: pass 1
exit status 0
diff --git a/contrib/bmake/unit-tests/dep-colon-bug-cross-file.mk b/contrib/bmake/unit-tests/dep-colon-bug-cross-file.mk
index 57fbf478163c..930358af2871 100644
--- a/contrib/bmake/unit-tests/dep-colon-bug-cross-file.mk
+++ b/contrib/bmake/unit-tests/dep-colon-bug-cross-file.mk
@@ -1,4 +1,4 @@
-# $NetBSD: dep-colon-bug-cross-file.mk,v 1.4 2020/09/27 09:53:41 rillig Exp $
+# $NetBSD: dep-colon-bug-cross-file.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Until 2020-09-25, the very last dependency group of a top-level makefile
# was not finished properly. This made it possible to add further commands
@@ -28,6 +28,7 @@ PASS?= 1
.if ${PASS} == 2
all:
+# expect+1: warning: duplicate script for target "all" ignored
: pass 2
.endif
@@ -37,5 +38,6 @@ PASS= 2
.MAKEFLAGS: -f ${.PARSEDIR:q}/${.PARSEFILE:q}
all:
+# expect+1: warning: using previous script for "all" defined here
: pass 1
.endif
diff --git a/contrib/bmake/unit-tests/dep-wildcards.mk b/contrib/bmake/unit-tests/dep-wildcards.mk
index 781b149f5a70..b3e2f14a07c3 100644
--- a/contrib/bmake/unit-tests/dep-wildcards.mk
+++ b/contrib/bmake/unit-tests/dep-wildcards.mk
@@ -1,4 +1,4 @@
-# $NetBSD: dep-wildcards.mk,v 1.3 2020/09/08 05:33:05 rillig Exp $
+# $NetBSD: dep-wildcards.mk,v 1.4 2023/06/21 12:27:50 rillig Exp $
#
# Tests for wildcards such as *.c in dependency declarations.
@@ -7,3 +7,9 @@ all: ${.PARSEDIR}/dep-*.mk
# The :O is necessary since the result of the dependency resolution
# does not order the directory entries itself.
@printf '%s\n' ${.ALLSRC:T:O}
+
+# This is not a wildcard rule as implemented by GNU make, as those rules would
+# use '%' instead of '*'. Instead, the pattern '*.target' is a file pattern
+# in the current working directory. As there are no such files, the target
+# list becomes empty, and the source pattern '*.source' is not even expanded.
+*.target: *.source
diff --git a/contrib/bmake/unit-tests/dep.mk b/contrib/bmake/unit-tests/dep.mk
index 54566d43d2a1..53fadc789b13 100644
--- a/contrib/bmake/unit-tests/dep.mk
+++ b/contrib/bmake/unit-tests/dep.mk
@@ -1,4 +1,4 @@
-# $NetBSD: dep.mk,v 1.3 2021/12/13 23:38:54 rillig Exp $
+# $NetBSD: dep.mk,v 1.4 2023/06/01 07:27:30 rillig Exp $
#
# Tests for dependency declarations, such as "target: sources".
@@ -15,4 +15,16 @@ only-colon::
# would be another error message.
only-colon:
+
+# Before parse.c 1.158 from 2009-10-07, the parser broke dependency lines at
+# the first ';', without parsing expressions as such. It interpreted the
+# first ';' as the separator between the dependency and its commands, and the
+# '^' as a shell command.
+all: for-subst
+.for file in ${.PARSEFILE}
+for-subst: ${file:S;^;./;g}
+ @echo ".for with :S;... OK"
+.endfor
+
+
all:
diff --git a/contrib/bmake/unit-tests/deptgt-begin.exp b/contrib/bmake/unit-tests/deptgt-begin.exp
index abc80afe9964..db4c7d7dfa13 100644
--- a/contrib/bmake/unit-tests/deptgt-begin.exp
+++ b/contrib/bmake/unit-tests/deptgt-begin.exp
@@ -1,5 +1,5 @@
-make: "deptgt-begin.mk" line 17: warning: duplicate script for target ".BEGIN" ignored
-make: "deptgt-begin.mk" line 8: warning: using previous script for ".BEGIN" defined here
+make: "deptgt-begin.mk" line 19: warning: duplicate script for target ".BEGIN" ignored
+make: "deptgt-begin.mk" line 9: warning: using previous script for ".BEGIN" defined here
: parse time
: Making before-begin before .BEGIN.
: .BEGIN
diff --git a/contrib/bmake/unit-tests/deptgt-begin.mk b/contrib/bmake/unit-tests/deptgt-begin.mk
index 543e377c05db..8b9842641a2d 100644
--- a/contrib/bmake/unit-tests/deptgt-begin.mk
+++ b/contrib/bmake/unit-tests/deptgt-begin.mk
@@ -1,9 +1,10 @@
-# $NetBSD: deptgt-begin.mk,v 1.6 2022/05/07 08:01:20 rillig Exp $
+# $NetBSD: deptgt-begin.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the special target .BEGIN in dependency declarations,
# which is a container for commands that are run before any other
# commands from the shell lines.
+# expect+2: warning: using previous script for ".BEGIN" defined here
.BEGIN:
: $@
@@ -13,6 +14,7 @@
# add its commands after this.
#
# There are several ways to resolve this situation, which are detailed below.
+# expect+2: warning: duplicate script for target ".BEGIN" ignored
.BEGIN:
: Making another $@.
diff --git a/contrib/bmake/unit-tests/deptgt-delete_on_error.mk b/contrib/bmake/unit-tests/deptgt-delete_on_error.mk
index e6d0610f4672..2309e67c01a5 100644
--- a/contrib/bmake/unit-tests/deptgt-delete_on_error.mk
+++ b/contrib/bmake/unit-tests/deptgt-delete_on_error.mk
@@ -1,4 +1,4 @@
- # $NetBSD: deptgt-delete_on_error.mk,v 1.3 2020/10/25 21:31:00 rillig Exp $
+# $NetBSD: deptgt-delete_on_error.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the special target .DELETE_ON_ERROR in dependency declarations,
# which controls whether the target is deleted if a shell command fails or
diff --git a/contrib/bmake/unit-tests/deptgt.exp b/contrib/bmake/unit-tests/deptgt.exp
index 73d4a7f0c33f..00d312685de9 100644
--- a/contrib/bmake/unit-tests/deptgt.exp
+++ b/contrib/bmake/unit-tests/deptgt.exp
@@ -1,17 +1,17 @@
-make: "deptgt.mk" line 10: warning: Extra target '.PHONY' ignored
-make: "deptgt.mk" line 28: Unassociated shell command ": command3 # parse error, since targets == NULL"
-Parsing line 34: ${:U}: empty-source
-ParseDependency(: empty-source)
-Parsing line 35: : command for empty targets list
-Parsing line 36: : empty-source
+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
ParseDependency(: empty-source)
Parsing line 37: : command for empty targets list
-Parsing line 38: .MAKEFLAGS: -d0
+Parsing line 38: : empty-source
+ParseDependency(: empty-source)
+Parsing line 39: : command for empty targets list
+Parsing line 40: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
-make: "deptgt.mk" line 46: Unknown modifier "Z"
-make: "deptgt.mk" line 49: warning: Extra target 'ordinary' ignored
-make: "deptgt.mk" line 52: warning: Extra target (ordinary) ignored
-make: "deptgt.mk" line 55: warning: Special and mundane targets don't mix. Mundane ones ignored
+make: "deptgt.mk" line 49: 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
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/deptgt.mk b/contrib/bmake/unit-tests/deptgt.mk
index 7d43220e888a..67c47e4909e6 100644
--- a/contrib/bmake/unit-tests/deptgt.mk
+++ b/contrib/bmake/unit-tests/deptgt.mk
@@ -1,4 +1,4 @@
-# $NetBSD: deptgt.mk,v 1.13 2023/01/03 00:00:45 rillig Exp $
+# $NetBSD: deptgt.mk,v 1.14 2023/06/01 20:56:35 rillig Exp $
#
# Tests for special targets like .BEGIN or .SUFFIXES in dependency
# declarations.
@@ -7,6 +7,7 @@
# Just in case anyone tries to compile several special targets in a single
# dependency line: That doesn't work, and make immediately rejects it.
+# expect+1: warning: Extra target '.PHONY' ignored
.SUFFIXES .PHONY: .c.o
# The following lines demonstrate how 'targets' is set and reset during
@@ -25,6 +26,7 @@ target1 target2: sources # targets := [target1, target2]
: command1 # targets == [target1, target2]
: command2 # targets == [target1, target2]
VAR=value # targets := NULL
+# expect+1: Unassociated shell command ": command3 # parse error, since targets == NULL"
: command3 # parse error, since targets == NULL
# In a dependency declaration, the list of targets can be empty.
@@ -43,6 +45,7 @@ ${:U}: empty-source
# expansion would be to use the variable modifier '::=' to modify the
# targets. This in turn would be such an extreme and unreliable edge case
# that nobody uses it.
+# expect+1: Unknown modifier "Z"
$$$$$$$${:U:Z}:
# expect+1: warning: Extra target 'ordinary' ignored
diff --git a/contrib/bmake/unit-tests/directive-elif.exp b/contrib/bmake/unit-tests/directive-elif.exp
index 6856494023d7..15dd6bf1430b 100644
--- a/contrib/bmake/unit-tests/directive-elif.exp
+++ b/contrib/bmake/unit-tests/directive-elif.exp
@@ -1,21 +1,21 @@
-make: "directive-elif.mk" line 47: Unknown directive "elsif"
-make: "directive-elif.mk" line 52: This branch is taken.
-make: "directive-elif.mk" line 60: Unknown directive "elsif"
-make: "directive-elif.mk" line 63: This branch is taken.
-make: "directive-elif.mk" line 69: This branch is taken.
-make: "directive-elif.mk" line 89: Unknown directive "elsif"
-make: "directive-elif.mk" line 90: This misspelling is detected.
-make: "directive-elif.mk" line 91: This branch is taken because of the .else.
-make: "directive-elif.mk" line 109: What happens on misspelling in a skipped branch?
-make: "directive-elif.mk" line 119: else
-make: "directive-elif.mk" line 122: What happens on misspelling in a taken branch?
-make: "directive-elif.mk" line 124: 1-then
-make: "directive-elif.mk" line 125: Unknown directive "elsif"
-make: "directive-elif.mk" line 126: 1-elsif
-make: "directive-elif.mk" line 127: Unknown directive "elsif"
-make: "directive-elif.mk" line 128: 2-elsif
-make: "directive-elif.mk" line 134: if-less elif
-make: "directive-elif.mk" line 139: warning: extra elif
+make: "directive-elif.mk" line 48: Unknown directive "elsif"
+make: "directive-elif.mk" line 54: This branch is taken.
+make: "directive-elif.mk" line 62: Unknown directive "elsif"
+make: "directive-elif.mk" line 66: This branch is taken.
+make: "directive-elif.mk" line 73: This branch is taken.
+make: "directive-elif.mk" line 94: Unknown directive "elsif"
+make: "directive-elif.mk" line 96: This misspelling is detected.
+make: "directive-elif.mk" line 98: This branch is taken because of the .else.
+make: "directive-elif.mk" line 117: What happens on misspelling in a skipped branch?
+make: "directive-elif.mk" line 128: else
+make: "directive-elif.mk" line 132: What happens on misspelling in a taken branch?
+make: "directive-elif.mk" line 135: 1-then
+make: "directive-elif.mk" line 137: Unknown directive "elsif"
+make: "directive-elif.mk" line 139: 1-elsif
+make: "directive-elif.mk" line 141: Unknown directive "elsif"
+make: "directive-elif.mk" line 143: 2-elsif
+make: "directive-elif.mk" line 149: if-less elif
+make: "directive-elif.mk" line 154: warning: extra elif
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-elif.mk b/contrib/bmake/unit-tests/directive-elif.mk
index e7b89beec4e9..d6500cc1e872 100644
--- a/contrib/bmake/unit-tests/directive-elif.mk
+++ b/contrib/bmake/unit-tests/directive-elif.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-elif.mk,v 1.7 2020/12/19 19:49:01 rillig Exp $
+# $NetBSD: directive-elif.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .elif directive.
#
@@ -44,28 +44,32 @@
# Misspelling '.elsif' below an .if branch that is taken.
.if 1
# This misspelling is in an active branch and is therefore detected.
+# expect+1: Unknown directive "elsif"
.elsif 0
# The only thing that make detects here is a misspelled directive, make
# doesn't recognize that it was meant to be a conditional directive.
# Therefore the branch continues here, even though the '.elsif' condition
# evaluates to false.
+# expect+1: This branch is taken.
. info This branch is taken.
.endif
# Misspelling '.elsif' below an .if branch that is taken.
.if 1
-# As of 2020-12-19, the misspelling is in an active branch and is therefore
-# detected.
+# The misspelling is in an active branch and is therefore detected.
+# expect+1: Unknown directive "elsif"
.elsif 1
# Since both conditions evaluate to true, this branch is taken no matter
# whether make detects a misspelling or not.
+# expect+1: This branch is taken.
. info This branch is taken.
.endif
# Misspelling '.elsif' in a skipped branch below a branch that was taken.
.if 1
+# expect+1: This branch is taken.
. info This branch is taken.
.elif 0
. info This branch is not taken.
@@ -86,8 +90,11 @@
# Misspelling '.elsif' in an .else branch that is taken.
.if 0
.else
+# expect+1: Unknown directive "elsif"
.elsif 1
+# expect+1: This misspelling is detected.
. info This misspelling is detected.
+# expect+1: This branch is taken because of the .else.
. info This branch is taken because of the .else.
.endif
@@ -106,6 +113,7 @@
.endif
+# expect+1: What happens on misspelling in a skipped branch?
.info What happens on misspelling in a skipped branch?
.if 0
. info 0-then
@@ -116,26 +124,33 @@
. info XXX: This misspelling is not detected.
. info 2-elsif
.else
+# expect+1: else
. info else
.endif
+# expect+1: What happens on misspelling in a taken branch?
.info What happens on misspelling in a taken branch?
.if 1
+# expect+1: 1-then
. info 1-then
+# expect+1: Unknown directive "elsif"
.elsif 1
+# expect+1: 1-elsif
. info 1-elsif
+# expect+1: Unknown directive "elsif"
.elsif 2
+# expect+1: 2-elsif
. info 2-elsif
.else
. info else
.endif
-# Expect: "if-less elif"
+# expect+1: if-less elif
.elif 0
.if 1
.else
-# Expect: "warning: extra elif"
+# expect+1: warning: extra elif
.elif
.endif
diff --git a/contrib/bmake/unit-tests/directive-else.exp b/contrib/bmake/unit-tests/directive-else.exp
index 17d5571ba74b..992b60e9308b 100644
--- a/contrib/bmake/unit-tests/directive-else.exp
+++ b/contrib/bmake/unit-tests/directive-else.exp
@@ -1,11 +1,11 @@
make: "directive-else.mk" line 14: The .else directive does not take arguments
-make: "directive-else.mk" line 15: ok
-make: "directive-else.mk" line 19: ok
-make: "directive-else.mk" line 21: The .else directive does not take arguments
-make: "directive-else.mk" line 26: if-less else
-make: "directive-else.mk" line 32: ok
-make: "directive-else.mk" line 33: warning: extra else
-make: "directive-else.mk" line 45: The .else directive does not take arguments
+make: "directive-else.mk" line 16: ok
+make: "directive-else.mk" line 21: ok
+make: "directive-else.mk" line 23: The .else directive does not take arguments
+make: "directive-else.mk" line 29: if-less else
+make: "directive-else.mk" line 36: ok
+make: "directive-else.mk" line 38: warning: extra else
+make: "directive-else.mk" line 51: The .else directive does not take arguments
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-else.mk b/contrib/bmake/unit-tests/directive-else.mk
index 794057110ef7..41b38a14a6cf 100644
--- a/contrib/bmake/unit-tests/directive-else.mk
+++ b/contrib/bmake/unit-tests/directive-else.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-else.mk,v 1.7 2020/12/14 22:17:11 rillig Exp $
+# $NetBSD: directive-else.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .else directive.
#
@@ -10,26 +10,31 @@
.if 0
. warning must not be reached
-# The .else directive does not take any arguments.
+# expect+1: The .else directive does not take arguments
.else 123
+# expect+1: ok
. info ok
.endif
.if 1
+# expect+1: ok
. info ok
-# The .else directive does not take any arguments.
+# expect+1: The .else directive does not take arguments
.else 123
. warning must not be reached
.endif
# An .else without a corresponding .if is an error.
+# expect+1: if-less else
.else
# Accidental extra .else directives are detected too.
.if 0
. warning must not be reached
.else
+# expect+1: ok
. info ok
+# expect+1: warning: extra else
.else
. info After an extra .else, everything is skipped.
.endif
@@ -42,6 +47,7 @@
# A variable expression does count as an argument, even if it is empty.
.if 0
+# expect+1: The .else directive does not take arguments
.else ${:U}
.endif
diff --git a/contrib/bmake/unit-tests/directive-endfor.exp b/contrib/bmake/unit-tests/directive-endfor.exp
index 7e243a8f67e6..8b77c0b31307 100644
--- a/contrib/bmake/unit-tests/directive-endfor.exp
+++ b/contrib/bmake/unit-tests/directive-endfor.exp
@@ -1,4 +1,4 @@
-make: "directive-endfor.mk" line 9: for-less endfor
+make: "directive-endfor.mk" line 10: for-less endfor
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-endfor.mk b/contrib/bmake/unit-tests/directive-endfor.mk
index b0c37f388504..93119156fb89 100644
--- a/contrib/bmake/unit-tests/directive-endfor.mk
+++ b/contrib/bmake/unit-tests/directive-endfor.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-endfor.mk,v 1.1 2020/12/30 14:50:08 rillig Exp $
+# $NetBSD: directive-endfor.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Test for the directive .endfor, which ends a .for loop.
#
@@ -6,4 +6,5 @@
# directive-for.mk
# An .endfor without a corresponding .for is a parse error.
+# expect+1: for-less endfor
.endfor
diff --git a/contrib/bmake/unit-tests/directive-endif.exp b/contrib/bmake/unit-tests/directive-endif.exp
index 0de1ecf0bf25..c88cc97c44c5 100644
--- a/contrib/bmake/unit-tests/directive-endif.exp
+++ b/contrib/bmake/unit-tests/directive-endif.exp
@@ -1,8 +1,8 @@
-make: "directive-endif.mk" line 18: The .endif directive does not take arguments
-make: "directive-endif.mk" line 23: The .endif directive does not take arguments
-make: "directive-endif.mk" line 33: The .endif directive does not take arguments
+make: "directive-endif.mk" line 16: The .endif directive does not take arguments
+make: "directive-endif.mk" line 21: The .endif directive does not take arguments
+make: "directive-endif.mk" line 32: The .endif directive does not take arguments
make: "directive-endif.mk" line 39: The .endif directive does not take arguments
-make: "directive-endif.mk" line 45: Unknown directive "endifx"
+make: "directive-endif.mk" line 44: Unknown directive "endifx"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-endif.mk b/contrib/bmake/unit-tests/directive-endif.mk
index 10dd6ce22ce8..5e01382af5f2 100644
--- a/contrib/bmake/unit-tests/directive-endif.mk
+++ b/contrib/bmake/unit-tests/directive-endif.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-endif.mk,v 1.5 2020/12/14 21:56:17 rillig Exp $
+# $NetBSD: directive-endif.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .endif directive.
#
@@ -8,18 +8,16 @@
# See also:
# Cond_EvalLine
-# TODO: Implementation
-
.MAKEFLAGS: -dL
-# Error: .endif does not take arguments
.if 0
-# Since 2020-12-15, complain about the extra text after the 'endif'.
+# Since 2020-12-15:
+# expect+1: The .endif directive does not take arguments
.endif 0
-# Error: .endif does not take arguments
.if 1
-# Since 2020-12-15, complain about the extra text after the 'endif'.
+# Since 2020-12-15:
+# expect+1: The .endif directive does not take arguments
.endif 1
# Comments are allowed after an '.endif'.
@@ -29,21 +27,19 @@
# Only whitespace and comments are allowed after an '.endif', but nothing
# else.
.if 1
-# Since 2020-12-15, complain about the extra text after the 'endif'.
+# Since 2020-12-15:
+# expect+1: The .endif directive does not take arguments
.endif0
# Only whitespace and comments are allowed after an '.endif', but nothing
# else.
.if 1
-# Since 2020-12-15, complain about the extra text after the 'endif'.
+# Since 2020-12-15:
+# expect+1: The .endif directive does not take arguments
.endif/
-# After an '.endif', no other letter must occur. This 'endifx' is not
-# parsed as an 'endif', therefore another '.endif' must follow to balance
-# the directives.
+# After an '.endif', no other letter must occur.
.if 1
+# expect+1: Unknown directive "endifx"
.endifx
-.endif # to close the preceding '.if'
-
-all:
- @:;
+.endif # to close the preceding '.if'
diff --git a/contrib/bmake/unit-tests/directive-error.exp b/contrib/bmake/unit-tests/directive-error.exp
index bad12326a514..8ce33160e67f 100644
--- a/contrib/bmake/unit-tests/directive-error.exp
+++ b/contrib/bmake/unit-tests/directive-error.exp
@@ -1,4 +1,4 @@
-make: "directive-error.mk" line 13: message
+make: "directive-error.mk" line 14: message
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-error.mk b/contrib/bmake/unit-tests/directive-error.mk
index 135db2159dd2..f35a9da3a018 100644
--- a/contrib/bmake/unit-tests/directive-error.mk
+++ b/contrib/bmake/unit-tests/directive-error.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-error.mk,v 1.5 2021/01/27 00:02:38 rillig Exp $
+# $NetBSD: directive-error.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .error directive, which prints an error message and exits
# immediately, unlike other "fatal" parse errors, which continue to parse
@@ -10,4 +10,5 @@
# Before parse.c 1.532 from 2021-01-27, the ".error" issued an irrelevant
# message saying "parsing warnings being treated as errors".
.MAKEFLAGS: -W
+# expect+1: message
.error message
diff --git a/contrib/bmake/unit-tests/directive-for-break.exp b/contrib/bmake/unit-tests/directive-for-break.exp
index b036ebfeb661..64941448141c 100644
--- a/contrib/bmake/unit-tests/directive-for-break.exp
+++ b/contrib/bmake/unit-tests/directive-for-break.exp
@@ -1,4 +1,5 @@
make: "directive-for-break.mk" line 45: break outside of for loop
+make: "directive-for-break.mk" line 65: The .break directive does not take arguments
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-for-break.mk b/contrib/bmake/unit-tests/directive-for-break.mk
index a86acfa8bde0..d9290d38c215 100644
--- a/contrib/bmake/unit-tests/directive-for-break.mk
+++ b/contrib/bmake/unit-tests/directive-for-break.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-break.mk,v 1.3 2022/09/24 10:52:05 rillig Exp $
+# $NetBSD: directive-for-break.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for .break in .for loops, which immediately terminates processing of
# the surrounding .for loop.
@@ -58,3 +58,9 @@ COMBINED+= ${outer}-${inner}
. endfor
. endif
.endif
+
+
+.for i in 1
+# expect+1: The .break directive does not take arguments
+. break 1
+.endfor
diff --git a/contrib/bmake/unit-tests/directive-for-empty.exp b/contrib/bmake/unit-tests/directive-for-empty.exp
index b9764b3196af..5cc3ac846b36 100644
--- a/contrib/bmake/unit-tests/directive-for-empty.exp
+++ b/contrib/bmake/unit-tests/directive-for-empty.exp
@@ -1,9 +1,9 @@
-make: "directive-for-empty.mk" line 21: 2
-make: "directive-for-empty.mk" line 34: Missing argument for ".error"
-make: "directive-for-empty.mk" line 34: Missing argument for ".error"
-make: "directive-for-empty.mk" line 34: Missing argument for ".error"
+make: "directive-for-empty.mk" line 22: 2
+make: "directive-for-empty.mk" line 38: Missing argument for ".error"
+make: "directive-for-empty.mk" line 38: Missing argument for ".error"
+make: "directive-for-empty.mk" line 38: Missing argument for ".error"
For: end for 1
-For: loop body:
+For: loop body with i = value:
# The identifier 'empty' can only be used in conditions such as .if, .ifdef or
# .elif. In other lines the string 'empty(' must be preserved.
CPPFLAGS+= -Dmessage="empty(i)"
diff --git a/contrib/bmake/unit-tests/directive-for-empty.mk b/contrib/bmake/unit-tests/directive-for-empty.mk
index 7f22a822ef77..52a65b39beeb 100644
--- a/contrib/bmake/unit-tests/directive-for-empty.mk
+++ b/contrib/bmake/unit-tests/directive-for-empty.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-empty.mk,v 1.1 2022/05/23 22:33:56 rillig Exp $
+# $NetBSD: directive-for-empty.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Tests for .for loops containing conditions of the form 'empty(var:...)'.
#
@@ -18,6 +18,7 @@
# when in fact they aren't.
.for i in 11 12 13
. if ${i:M*2*}
+# expect+1: 2
.info 2
. endif
.endfor
@@ -31,6 +32,9 @@
# Asking for an empty iteration variable does not make sense as the .for loop
# splits the iteration items into words, and such a word cannot be empty.
. if empty(i)
+# expect+3: Missing argument for ".error"
+# expect+2: Missing argument for ".error"
+# expect+1: Missing argument for ".error"
. error # due to the leaky abstraction
. endif
# The typical way of using 'empty' with variables from .for loops is pattern
diff --git a/contrib/bmake/unit-tests/directive-for-errors.exp b/contrib/bmake/unit-tests/directive-for-errors.exp
index 36ed569c7932..115a6af5b069 100644
--- a/contrib/bmake/unit-tests/directive-for-errors.exp
+++ b/contrib/bmake/unit-tests/directive-for-errors.exp
@@ -1,17 +1,17 @@
-make: "directive-for-errors.mk" line 11: Unknown directive "fori"
-make: "directive-for-errors.mk" line 12: warning: <>
-make: "directive-for-errors.mk" line 13: for-less endfor
-make: "directive-for-errors.mk" line 27: Unknown directive "for"
-make: "directive-for-errors.mk" line 28: warning: <>
-make: "directive-for-errors.mk" line 29: for-less endfor
-make: "directive-for-errors.mk" line 46: invalid character '$' in .for loop variable name
-make: "directive-for-errors.mk" line 54: no iteration variables in for
-make: "directive-for-errors.mk" line 66: Wrong number of words (5) in .for substitution list with 3 variables
-make: "directive-for-errors.mk" line 80: missing `in' in for
-make: "directive-for-errors.mk" line 91: Unknown modifier "Z"
-make: "directive-for-errors.mk" line 92: warning: Should not be reached.
-make: "directive-for-errors.mk" line 92: warning: Should not be reached.
-make: "directive-for-errors.mk" line 92: warning: Should not be reached.
+make: "directive-for-errors.mk" line 9: Unknown directive "fori"
+make: "directive-for-errors.mk" line 10: warning: <>
+make: "directive-for-errors.mk" line 11: for-less endfor
+make: "directive-for-errors.mk" line 25: Unknown directive "for"
+make: "directive-for-errors.mk" line 26: warning: <>
+make: "directive-for-errors.mk" line 27: for-less endfor
+make: "directive-for-errors.mk" line 44: invalid character '$' in .for loop variable name
+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: Unknown modifier "Z"
+make: "directive-for-errors.mk" line 90: warning: Should not be reached.
+make: "directive-for-errors.mk" line 90: warning: Should not be reached.
+make: "directive-for-errors.mk" line 90: warning: Should not be reached.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-for-errors.mk b/contrib/bmake/unit-tests/directive-for-errors.mk
index 24df5e131839..0af65350e643 100644
--- a/contrib/bmake/unit-tests/directive-for-errors.mk
+++ b/contrib/bmake/unit-tests/directive-for-errors.mk
@@ -1,9 +1,7 @@
-# $NetBSD: directive-for-errors.mk,v 1.5 2023/05/09 19:43:12 rillig Exp $
+# $NetBSD: directive-for-errors.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for error handling in .for loops.
-# expect-all
-
# A .for directive must be followed by whitespace, everything else results
# in a parse error.
diff --git a/contrib/bmake/unit-tests/directive-for-escape.exp b/contrib/bmake/unit-tests/directive-for-escape.exp
index 0326b62377f3..1f6c6bcc3109 100644
--- a/contrib/bmake/unit-tests/directive-for-escape.exp
+++ b/contrib/bmake/unit-tests/directive-for-escape.exp
@@ -1,60 +1,60 @@
For: end for 1
-For: loop body:
+For: loop body with chars = !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~:
. info ${:U!"#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
make: Unclosed variable expression, expecting '}' for modifier "U!"" of variable "" with value "!""
-make: "directive-for-escape.mk" line 21: !"
+make: "directive-for-escape.mk" line 19: !"
For: end for 1
-For: loop body:
+For: loop body with chars = !"\\#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~:
. info ${:U!"\\\\#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
make: Unclosed variable expression, expecting '}' for modifier "U!"\\\\" of variable "" with value "!"\\"
-make: "directive-for-escape.mk" line 32: !"\\
+make: "directive-for-escape.mk" line 30: !"\\
For: end for 1
-For: loop body:
+For: loop body with i = $:
. info ${:U\$}
-make: "directive-for-escape.mk" line 47: $
-For: loop body:
+make: "directive-for-escape.mk" line 45: $
+For: loop body with i = ${V}:
. info ${:U${V}}
-make: "directive-for-escape.mk" line 47: value
-For: loop body:
+make: "directive-for-escape.mk" line 45: value
+For: loop body with i = ${V:=-with-modifier}:
. info ${:U${V:=-with-modifier}}
-make: "directive-for-escape.mk" line 47: value-with-modifier
-For: loop body:
+make: "directive-for-escape.mk" line 45: value-with-modifier
+For: loop body with i = $(V):
. info ${:U$(V)}
-make: "directive-for-escape.mk" line 47: value
-For: loop body:
+make: "directive-for-escape.mk" line 45: value
+For: loop body with i = $(V:=-with-modifier):
. info ${:U$(V:=-with-modifier)}
-make: "directive-for-escape.mk" line 47: value-with-modifier
+make: "directive-for-escape.mk" line 45: value-with-modifier
For: end for 1
-For: loop body:
+For: loop body with i = ${UNDEF:U\$\$:
# ${:U\${UNDEF\:U\\$\\$}
-For: loop body:
+For: loop body with i = {{}}:
# ${:U{{\}\}}
-For: loop body:
+For: loop body with i = end}:
# ${:Uend\}}
For: end for 1
-For: loop body:
+For: loop body with i = ${UNDEF:U\$\$:
. info ${:U\${UNDEF\:U\\$\\$}
-make: "directive-for-escape.mk" line 101: ${UNDEF:U\backslash$
-For: loop body:
+make: "directive-for-escape.mk" line 99: ${UNDEF:U\backslash$
+For: loop body with i = {{}}:
. info ${:U{{\}\}}
-make: "directive-for-escape.mk" line 101: {{}}
-For: loop body:
+make: "directive-for-escape.mk" line 99: {{}}
+For: loop body with i = end}:
. info ${:Uend\}}
-make: "directive-for-escape.mk" line 101: end}
+make: "directive-for-escape.mk" line 99: end}
For: end for 1
-For: loop body:
+For: loop body with i = begin<${UNDEF:Ufallback:N{{{}}}}>end:
. info ${:Ubegin<${UNDEF:Ufallback:N{{{}}}}>end}
-make: "directive-for-escape.mk" line 122: begin<fallback>end
+make: "directive-for-escape.mk" line 120: begin<fallback>end
For: end for 1
-For: loop body:
+For: loop body with i = $:
. info ${:U\$}
-make: "directive-for-escape.mk" line 131: $
-make: "directive-for-escape.mk" line 140: invalid character ':' in .for loop variable name
+make: "directive-for-escape.mk" line 129: $
+make: "directive-for-escape.mk" line 138: invalid character ':' in .for loop variable name
For: end for 1
-make: "directive-for-escape.mk" line 150: invalid character '}' in .for loop variable name
+make: "directive-for-escape.mk" line 148: invalid character '}' in .for loop variable name
For: end for 1
For: end for 1
-For: loop body:
+For: loop body with i = inner:
. info . $$i: ${:Uinner}
. info . $${i}: ${:Uinner}
. info . $${i:M*}: ${:Uinner:M*}
@@ -65,80 +65,83 @@ For: loop body:
. info . $${i2}: ${i2}
. info . $${i,}: ${i,}
. info . adjacent: ${:Uinner}${:Uinner}${:Uinner:M*}${:Uinner}
-make: "directive-for-escape.mk" line 159: . $i: inner
-make: "directive-for-escape.mk" line 160: . ${i}: inner
-make: "directive-for-escape.mk" line 161: . ${i:M*}: inner
-make: "directive-for-escape.mk" line 162: . $(i): inner
-make: "directive-for-escape.mk" line 163: . $(i:M*): inner
-make: "directive-for-escape.mk" line 164: . ${i${:U}}: outer
-make: "directive-for-escape.mk" line 165: . ${i\}}: inner}
-make: "directive-for-escape.mk" line 166: . ${i2}: two
-make: "directive-for-escape.mk" line 167: . ${i,}: comma
-make: "directive-for-escape.mk" line 168: . adjacent: innerinnerinnerinner
-make: "directive-for-escape.mk" line 187: invalid character '$' in .for loop variable name
-For: end for 1
-make: "directive-for-escape.mk" line 199: eight and no cents.
-For: end for 1
-make: "directive-for-escape.mk" line 212: newline in .for value
-make: "directive-for-escape.mk" line 212: newline in .for value
-For: loop body:
+make: "directive-for-escape.mk" line 157: . $i: inner
+make: "directive-for-escape.mk" line 158: . ${i}: inner
+make: "directive-for-escape.mk" line 159: . ${i:M*}: inner
+make: "directive-for-escape.mk" line 160: . $(i): inner
+make: "directive-for-escape.mk" line 161: . $(i:M*): inner
+make: "directive-for-escape.mk" line 162: . ${i${:U}}: outer
+make: "directive-for-escape.mk" line 163: . ${i\}}: inner}
+make: "directive-for-escape.mk" line 164: . ${i2}: two
+make: "directive-for-escape.mk" line 165: . ${i,}: comma
+make: "directive-for-escape.mk" line 166: . adjacent: innerinnerinnerinner
+make: "directive-for-escape.mk" line 185: invalid character '$' in .for loop variable name
+For: end for 1
+make: "directive-for-escape.mk" line 197: eight and no cents.
+For: end for 1
+make: "directive-for-escape.mk" line 210: newline in .for value
+make: "directive-for-escape.mk" line 210: newline in .for value
+For: loop body with i = "
+":
. info short: ${:U" "}
. info long: ${:U" "}
-make: "directive-for-escape.mk" line 213: short: " "
-make: "directive-for-escape.mk" line 214: long: " "
+make: "directive-for-escape.mk" line 211: short: " "
+make: "directive-for-escape.mk" line 212: long: " "
For: end for 1
-For: loop body:
+For: loop body with i = "
+":
For: end for 1
-Parse_PushInput: .for loop in directive-for-escape.mk, line 230
-make: "directive-for-escape.mk" line 230: newline in .for value
- in .for loop from directive-for-escape.mk:230 with i = "
+Parse_PushInput: .for loop in directive-for-escape.mk, line 228
+make: "directive-for-escape.mk" line 228: newline in .for value
+ in .for loop from directive-for-escape.mk:228 with i = "
"
-For: loop body:
+For: loop body with i = "
+":
: ${:U" "}
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
-Parsing line 231: : ${:U" "}
+Parsing line 229: : ${:U" "}
ParseDependency(: " ")
-ParseEOF: returning to file directive-for-escape.mk, line 233
+ParseEOF: returning to file directive-for-escape.mk, line 231
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
-Parsing line 233: .MAKEFLAGS: -d0
+Parsing line 231: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
For: end for 1
-For: loop body:
+For: loop body with i = #:
# ${:U#}
-For: loop body:
+For: loop body with i = \\#:
# ${:U\\\\#}
For: end for 1
-For: loop body:
+For: loop body with i = $:
# ${:U\$}
-For: loop body:
+For: loop body with i = $i:
# ${:U$i}
-For: loop body:
+For: loop body with i = $(i):
# ${:U$(i)}
-For: loop body:
+For: loop body with i = ${i}:
# ${:U${i}}
-For: loop body:
+For: loop body with i = $$:
# ${:U$$}
-For: loop body:
+For: loop body with i = $$$$:
# ${:U$$$$}
-For: loop body:
+For: loop body with i = ${:U\$\$}:
# ${:U${:U\$\$}}
For: end for 1
-For: loop body:
+For: loop body with i = ${.TARGET}:
# ${:U${.TARGET}}
-For: loop body:
+For: loop body with i = ${.TARGET}:
# ${:U${.TARGET}}
-For: loop body:
+For: loop body with i = $${.TARGET}:
# ${:U$${.TARGET\}}
-For: loop body:
+For: loop body with i = $${.TARGET}:
# ${:U$${.TARGET\}}
For: end for 1
-For: loop body:
+For: loop body with i = (((:
# ${:U(((}
-For: loop body:
+For: loop body with i = {{{:
# ${:U{{{}
-For: loop body:
+For: loop body with i = ))):
# ${:U)))}
-For: loop body:
+For: loop body with i = }}}:
# ${:U\}\}\}}
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
diff --git a/contrib/bmake/unit-tests/directive-for-escape.mk b/contrib/bmake/unit-tests/directive-for-escape.mk
index 7fbd09131d2c..aa0d2504f944 100644
--- a/contrib/bmake/unit-tests/directive-for-escape.mk
+++ b/contrib/bmake/unit-tests/directive-for-escape.mk
@@ -1,11 +1,9 @@
-# $NetBSD: directive-for-escape.mk,v 1.18 2023/05/09 19:43:12 rillig Exp $
+# $NetBSD: directive-for-escape.mk,v 1.20 2023/06/01 20:56:35 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
# escaping and unescaping must pass all characters and strings unmodified.
-# expect-all
-
.MAKEFLAGS: -df
# Even though the .for loops take quotes into account when splitting the
@@ -74,11 +72,11 @@ VALUES= $${UNDEF:U\$$\$$ {{}} end}
# When these words are injected into the body of the .for loop, each inside a
# '${:U...}' expression, the result is:
#
-# expect: For: loop body:
+# expect: For: loop body with i = ${UNDEF:U\$\$:
# expect: # ${:U\${UNDEF\:U\\$\\$}
-# expect: For: loop body:
+# expect: For: loop body with i = {{}}:
# expect: # ${:U{{\}\}}
-# expect: For: loop body:
+# expect: For: loop body with i = end}:
# expect: # ${:Uend\}}
# expect: For: end for 1
#
diff --git a/contrib/bmake/unit-tests/directive-for-generating-endif.exp b/contrib/bmake/unit-tests/directive-for-generating-endif.exp
index 5f57f89c250f..ecdeb0962202 100755
--- a/contrib/bmake/unit-tests/directive-for-generating-endif.exp
+++ b/contrib/bmake/unit-tests/directive-for-generating-endif.exp
@@ -1,7 +1,7 @@
-make: "directive-for-generating-endif.mk" line 21: if-less endif
-make: "directive-for-generating-endif.mk" line 21: if-less endif
-make: "directive-for-generating-endif.mk" line 21: if-less endif
-make: "directive-for-generating-endif.mk" line 26: 3 open conditionals
+make: "directive-for-generating-endif.mk" line 24: if-less endif
+make: "directive-for-generating-endif.mk" line 24: if-less endif
+make: "directive-for-generating-endif.mk" line 24: if-less endif
+make: "directive-for-generating-endif.mk" line 30: 3 open conditionals
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-for-generating-endif.mk b/contrib/bmake/unit-tests/directive-for-generating-endif.mk
index b4d709551003..3079ad3353c2 100755
--- a/contrib/bmake/unit-tests/directive-for-generating-endif.mk
+++ b/contrib/bmake/unit-tests/directive-for-generating-endif.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-generating-endif.mk,v 1.1 2020/08/29 18:50:25 rillig Exp $
+# $NetBSD: directive-for-generating-endif.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Test whether a .for loop can be used to generate multiple .endif
# directives to close nested .if directives. Depending on the exact
@@ -18,8 +18,12 @@
. if 2
. if 3
.for i in 3 2 1
+# expect+3: if-less endif
+# expect+2: if-less endif
+# expect+1: if-less endif
.endif
.endfor
all:
@:;
+# expect+1: 3 open conditionals
diff --git a/contrib/bmake/unit-tests/directive-for-if.exp b/contrib/bmake/unit-tests/directive-for-if.exp
index 85bfc484856b..f30171f4db87 100644
--- a/contrib/bmake/unit-tests/directive-for-if.exp
+++ b/contrib/bmake/unit-tests/directive-for-if.exp
@@ -1,6 +1,6 @@
-make: "directive-for-if.mk" line 48: if-less endif
-make: "directive-for-if.mk" line 48: if-less endif
-make: "directive-for-if.mk" line 48: if-less endif
+make: "directive-for-if.mk" line 51: if-less endif
+make: "directive-for-if.mk" line 51: if-less endif
+make: "directive-for-if.mk" line 51: if-less endif
VAR1
VAR3
make: Fatal errors encountered -- cannot continue
diff --git a/contrib/bmake/unit-tests/directive-for-if.mk b/contrib/bmake/unit-tests/directive-for-if.mk
index 8d73e8ae8c4d..f2d0b550c693 100644
--- a/contrib/bmake/unit-tests/directive-for-if.mk
+++ b/contrib/bmake/unit-tests/directive-for-if.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-if.mk,v 1.1 2021/08/30 17:08:13 rillig Exp $
+# $NetBSD: directive-for-if.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Test for a .for directive that contains an .if directive.
#
@@ -45,6 +45,9 @@
# expanded to their bare textual value.
.for directive in if ifdef ifndef
. ${directive} "1" != "0"
+# expect+3: if-less endif
+# expect+2: if-less endif
+# expect+1: if-less endif
. endif
.endfor
# In 2021, the above code does not generate an error message, even though the
diff --git a/contrib/bmake/unit-tests/directive-for-lines.exp b/contrib/bmake/unit-tests/directive-for-lines.exp
index 7aeaaa4a7002..857b4829083b 100644
--- a/contrib/bmake/unit-tests/directive-for-lines.exp
+++ b/contrib/bmake/unit-tests/directive-for-lines.exp
@@ -1,9 +1,9 @@
-make: "directive-for-lines.mk" line 23: expect 23
-make: "directive-for-lines.mk" line 23: expect 23
-make: "directive-for-lines.mk" line 30: expect 30
-make: "directive-for-lines.mk" line 23: expect 23
-make: "directive-for-lines.mk" line 23: expect 23
-make: "directive-for-lines.mk" line 30: expect 30
+make: "directive-for-lines.mk" line 27: expect 23
+make: "directive-for-lines.mk" line 27: expect 23
+make: "directive-for-lines.mk" line 36: expect 30
+make: "directive-for-lines.mk" line 27: expect 23
+make: "directive-for-lines.mk" line 27: expect 23
+make: "directive-for-lines.mk" line 36: expect 30
make: no target to make.
make: stopped in unit-tests
diff --git a/contrib/bmake/unit-tests/directive-for-lines.mk b/contrib/bmake/unit-tests/directive-for-lines.mk
index 648c6112daff..cae4e0a38897 100644
--- a/contrib/bmake/unit-tests/directive-for-lines.mk
+++ b/contrib/bmake/unit-tests/directive-for-lines.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-lines.mk,v 1.4 2022/05/08 06:51:27 rillig Exp $
+# $NetBSD: directive-for-lines.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the line numbers that are reported in .for loops.
#
@@ -20,6 +20,10 @@
VAR= \
multi-line
+# expect+4: expect 23
+# expect+3: expect 23
+# expect+2: expect 23
+# expect+1: expect 23
.info expect 23
.endfor
@@ -27,6 +31,8 @@ VAR= \
# comment \
# continued comment
+# expect+2: expect 30
+# expect+1: expect 30
.info expect 30
.endfor
diff --git a/contrib/bmake/unit-tests/directive-for.exp b/contrib/bmake/unit-tests/directive-for.exp
index 97878ee49f44..7f37da4ef364 100755
--- a/contrib/bmake/unit-tests/directive-for.exp
+++ b/contrib/bmake/unit-tests/directive-for.exp
@@ -1,41 +1,41 @@
-make: "directive-for.mk" line 119: outer
-make: "directive-for.mk" line 137: a:\ a:\file.txt
-make: "directive-for.mk" line 137: d:\\
-make: "directive-for.mk" line 137: d:\\file.txt
-make: "directive-for.mk" line 148: ( ( (
-make: "directive-for.mk" line 148: [ [ [
-make: "directive-for.mk" line 148: { { {
-make: "directive-for.mk" line 148: ) ) )
-make: "directive-for.mk" line 148: ] ] ]
-make: "directive-for.mk" line 148: } } }
-make: "directive-for.mk" line 148: (()) (()) (())
-make: "directive-for.mk" line 148: [[]] [[]] [[]]
-make: "directive-for.mk" line 148: {{}} {{}} {{}}
-make: "directive-for.mk" line 148: )( )( )(
-make: "directive-for.mk" line 148: ][ ][ ][
-make: "directive-for.mk" line 148: }{ }{ }{
-make: "directive-for.mk" line 168: invalid character ':' in .for loop variable name
-make: "directive-for.mk" line 175: invalid character '$' in .for loop variable name
-make: "directive-for.mk" line 187: invalid character '$' in .for loop variable name
-make: "directive-for.mk" line 198: Unknown modifier "Z"
-make: "directive-for.mk" line 199: XXX: Not reached word1
-make: "directive-for.mk" line 199: XXX: Not reached word3
-make: "directive-for.mk" line 206: no iteration variables in for
-make: "directive-for.mk" line 232: 1 open conditional
-make: "directive-for.mk" line 248: for-less endfor
-make: "directive-for.mk" line 249: if-less endif
-make: "directive-for.mk" line 257: if-less endif
+make: "directive-for.mk" line 117: outer
+make: "directive-for.mk" line 135: a:\ a:\file.txt
+make: "directive-for.mk" line 135: d:\\
+make: "directive-for.mk" line 135: d:\\file.txt
+make: "directive-for.mk" line 146: ( ( (
+make: "directive-for.mk" line 146: [ [ [
+make: "directive-for.mk" line 146: { { {
+make: "directive-for.mk" line 146: ) ) )
+make: "directive-for.mk" line 146: ] ] ]
+make: "directive-for.mk" line 146: } } }
+make: "directive-for.mk" line 146: (()) (()) (())
+make: "directive-for.mk" line 146: [[]] [[]] [[]]
+make: "directive-for.mk" line 146: {{}} {{}} {{}}
+make: "directive-for.mk" line 146: )( )( )(
+make: "directive-for.mk" line 146: ][ ][ ][
+make: "directive-for.mk" line 146: }{ }{ }{
+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 196: Unknown modifier "Z"
+make: "directive-for.mk" line 197: XXX: Not reached word1
+make: "directive-for.mk" line 197: XXX: Not reached word3
+make: "directive-for.mk" line 204: no iteration variables in for
+make: "directive-for.mk" line 230: 1 open conditional
+make: "directive-for.mk" line 246: for-less endfor
+make: "directive-for.mk" line 247: if-less endif
+make: "directive-for.mk" line 255: if-less endif
For: new loop 2
For: end for 2
For: end for 1
-For: loop body:
+For: loop body with outer = o:
.\
for inner in i
.\
endfor
For: end for 1
-For: loop body:
-make: "directive-for.mk" line 305: newline-item=(a)
+For: loop body with inner = i:
+make: "directive-for.mk" line 303: newline-item=(a)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-for.mk b/contrib/bmake/unit-tests/directive-for.mk
index 224a466a7709..22b9f78e5fe1 100755
--- a/contrib/bmake/unit-tests/directive-for.mk
+++ b/contrib/bmake/unit-tests/directive-for.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for.mk,v 1.20 2023/05/10 13:03:06 rillig Exp $
+# $NetBSD: directive-for.mk,v 1.22 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .for directive.
#
@@ -12,8 +12,6 @@
# See also:
# varmod-loop.mk The ':@var@...@' modifier
-# expect-all
-
# A typical use case for a .for loop is to populate a variable with a list of
# values depending on other variables. In simple cases, the same effect can
# be achieved using the ':@var@${var}@' modifier.
@@ -87,9 +85,9 @@ var2= value before
. warning After the .for loop, var2 must still have its original value.
.endif
-# Until 2008-12-21, the values of the iteration variables were simply
-# inserted as plain text and then parsed as usual, which made it possible
-# to achieve all kinds of strange effects, such as generating '.if'
+# Before for.c 1.39 from 2008-12-21, the values of the iteration variables
+# were simply inserted as plain text and then parsed as usual, which made it
+# possible to achieve all kinds of strange effects, such as generating '.if'
# directives or inserting '$' characters in random places, thereby changing
# how following '$' are interpreted.
#
diff --git a/contrib/bmake/unit-tests/directive-if.exp b/contrib/bmake/unit-tests/directive-if.exp
index 5682df501e9c..34ba63d034dd 100644
--- a/contrib/bmake/unit-tests/directive-if.exp
+++ b/contrib/bmake/unit-tests/directive-if.exp
@@ -1,18 +1,18 @@
-make: "directive-if.mk" line 13: 0 evaluates to false.
-make: "directive-if.mk" line 17: 1 evaluates to true.
-make: "directive-if.mk" line 41: Unknown directive "ifx"
-make: "directive-if.mk" line 43: This is not conditional.
-make: "directive-if.mk" line 45: if-less else
-make: "directive-if.mk" line 47: This is not conditional.
-make: "directive-if.mk" line 49: if-less endif
-make: "directive-if.mk" line 53: Malformed conditional ()
-make: "directive-if.mk" line 63: Quotes in plain words are probably a mistake.
-make: "directive-if.mk" line 72: Don't do this, always put a space after a directive.
+make: "directive-if.mk" line 14: 0 evaluates to false.
+make: "directive-if.mk" line 19: 1 evaluates to true.
+make: "directive-if.mk" line 43: Unknown directive "ifx"
+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 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 82: Don't do this, always put a space around comparison operators.
-make: "directive-if.mk" line 88: Don't do this, always put a space after a directive.
-make: "directive-if.mk" line 92: Don't do this, always put a space after a directive.
-make: "directive-if.mk" line 100: Unknown directive "ifn"
+make: "directive-if.mk" line 81: Don't do this, always put a space after a directive.
+make: "directive-if.mk" line 88: Don't do this, always put a space around comparison operators.
+make: "directive-if.mk" line 95: Don't do this, always put a space after a directive.
+make: "directive-if.mk" line 100: Don't do this, always put a space after a directive.
+make: "directive-if.mk" line 108: Unknown directive "ifn"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-if.mk b/contrib/bmake/unit-tests/directive-if.mk
index 1acd5c958008..7a68c0041415 100644
--- a/contrib/bmake/unit-tests/directive-if.mk
+++ b/contrib/bmake/unit-tests/directive-if.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-if.mk,v 1.11 2022/01/23 21:48:59 rillig Exp $
+# $NetBSD: directive-if.mk,v 1.12 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .if directive.
#
@@ -10,10 +10,12 @@
.if 0
. error
.else
+# expect+1: 0 evaluates to false.
. info 0 evaluates to false.
.endif
.if 1
+# expect+1: 1 evaluates to true.
. info 1 evaluates to true.
.else
. error
@@ -60,6 +62,7 @@
# though, which are kept. The quotes need not be balanced. The next space
# ends the word, and the remaining " || 1" is parsed as "or true".
.if ${:Uplain"""""} == plain""""" || 1
+# expect+1: Quotes in plain words are probably a mistake.
. info Quotes in plain words are probably a mistake.
# XXX: Accepting quotes in plain words is probably a mistake as well.
.else
@@ -69,26 +72,31 @@
.if0
. error
.else
+# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.endif
.if${:U-3}
+# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.else
. error
.endif
.if${:U-3}>-4
+# expect+1: Don't do this, always put a space around comparison operators.
. info Don't do this, always put a space around comparison operators.
.else
. error
.endif
.if(1)
+# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.endif
.if!0
+# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.endif
diff --git a/contrib/bmake/unit-tests/directive-ifmake.exp b/contrib/bmake/unit-tests/directive-ifmake.exp
index bf4ded97911f..e607726fd87c 100644
--- a/contrib/bmake/unit-tests/directive-ifmake.exp
+++ b/contrib/bmake/unit-tests/directive-ifmake.exp
@@ -1,10 +1,10 @@
-make: "directive-ifmake.mk" line 13: ok: positive condition works
-make: "directive-ifmake.mk" line 24: ok: negation works
-make: "directive-ifmake.mk" line 33: ok: double negation works
-make: "directive-ifmake.mk" line 40: ok: both mentioned
-make: "directive-ifmake.mk" line 47: ok: only those mentioned
-make: "directive-ifmake.mk" line 57: Targets can even be added at parse time.
-make: "directive-ifmake.mk" line 75: ok
+make: "directive-ifmake.mk" line 14: ok: positive condition works
+make: "directive-ifmake.mk" line 26: ok: negation works
+make: "directive-ifmake.mk" line 36: ok: double negation works
+make: "directive-ifmake.mk" line 44: ok: both mentioned
+make: "directive-ifmake.mk" line 52: ok: only those mentioned
+make: "directive-ifmake.mk" line 63: Targets can even be added at parse time.
+make: "directive-ifmake.mk" line 82: ok
: first
: second
: late-target
diff --git a/contrib/bmake/unit-tests/directive-ifmake.mk b/contrib/bmake/unit-tests/directive-ifmake.mk
index a1ff3aef6825..2a0cedda463e 100644
--- a/contrib/bmake/unit-tests/directive-ifmake.mk
+++ b/contrib/bmake/unit-tests/directive-ifmake.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-ifmake.mk,v 1.10 2022/02/09 21:09:24 rillig Exp $
+# $NetBSD: directive-ifmake.mk,v 1.11 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .ifmake directive, which provides a shortcut for asking
# whether a certain target is requested to be made from the command line.
@@ -10,6 +10,7 @@
# This is the most basic form.
.ifmake first
+# expect+1: ok: positive condition works
. info ok: positive condition works
.else
. warning positive condition fails
@@ -21,6 +22,7 @@
.ifmake !first
. warning unexpected
.else
+# expect+1: ok: negation works
. info ok: negation works
.endif
@@ -30,6 +32,7 @@
# exclamation mark were part of the name instead, the name would be '!!first',
# and such a target was not requested to be made.
.ifmake !!first
+# expect+1: ok: double negation works
. info ok: double negation works
.else
. warning double negation fails
@@ -37,6 +40,7 @@
# Multiple targets can be combined using the && and || operators.
.ifmake first && second
+# expect+1: ok: both mentioned
. info ok: both mentioned
.else
. warning && does not work as expected
@@ -44,6 +48,7 @@
# Negation also works in complex conditions.
.ifmake first && !unmentioned
+# expect+1: ok: only those mentioned
. info ok: only those mentioned
.else
. warning && with ! does not work as expected
@@ -54,6 +59,7 @@
# possible to extend the targets to be made.
.MAKEFLAGS: late-target
.ifmake late-target
+# expect+1: Targets can even be added at parse time.
. info Targets can even be added at parse time.
.else
. info No, targets cannot be added at parse time anymore.
@@ -72,6 +78,7 @@
# A condition that consists of a variable expression only (without any
# comparison operator) can be used with .if and the other .ifxxx directives.
.ifmake ${:Ufirst}
+# expect+1: ok
. info ok
.else
. error
diff --git a/contrib/bmake/unit-tests/directive-ifndef.exp b/contrib/bmake/unit-tests/directive-ifndef.exp
index c653f6344429..d018e78616bc 100644
--- a/contrib/bmake/unit-tests/directive-ifndef.exp
+++ b/contrib/bmake/unit-tests/directive-ifndef.exp
@@ -1,2 +1,2 @@
-make: "directive-ifndef.mk" line 10: guarded section
+make: "directive-ifndef.mk" line 14: guarded section
exit status 0
diff --git a/contrib/bmake/unit-tests/directive-ifndef.mk b/contrib/bmake/unit-tests/directive-ifndef.mk
index bf509ef8075e..95b8df6bcbb8 100644
--- a/contrib/bmake/unit-tests/directive-ifndef.mk
+++ b/contrib/bmake/unit-tests/directive-ifndef.mk
@@ -1,12 +1,16 @@
-# $NetBSD: directive-ifndef.mk,v 1.6 2020/10/24 08:46:08 rillig Exp $
+# $NetBSD: directive-ifndef.mk,v 1.8 2023/06/19 20:44:06 rillig Exp $
#
# Tests for the .ifndef directive, which can be used for multiple-inclusion
# guards. In contrast to C, where #ifndef and #define nicely line up the
# macro name, there is no such syntax in make. Therefore, it is more
# common to use .if !defined(GUARD) instead.
+#
+# See also:
+# directive-include-guard.mk
.ifndef GUARD
GUARD= # defined
+# expect+1: guarded section
. info guarded section
.endif
@@ -20,5 +24,30 @@ GUARD= # defined
. info guarded section
.endif
+
+# The '.ifndef' directive can be used with multiple arguments, even negating
+# them. Since these conditions are confusing for humans, they should be
+# replaced with easier-to-understand plain '.if' directives.
+DEFINED=
+.ifndef UNDEFINED && UNDEFINED
+.else
+. error
+.endif
+.ifndef UNDEFINED && DEFINED
+. error
+.endif
+.ifndef DEFINED && DEFINED
+. error
+.endif
+.ifndef !UNDEFINED && !UNDEFINED
+. error
+.endif
+.ifndef !UNDEFINED && !DEFINED
+. error
+.endif
+.ifndef !DEFINED && !DEFINED
+.else
+. error
+.endif
+
all:
- @:;
diff --git a/contrib/bmake/unit-tests/directive-include-fatal.exp b/contrib/bmake/unit-tests/directive-include-fatal.exp
index c8ca97a0fd5f..cae0fc97a59d 100755
--- a/contrib/bmake/unit-tests/directive-include-fatal.exp
+++ b/contrib/bmake/unit-tests/directive-include-fatal.exp
@@ -1,4 +1,4 @@
-make: "directive-include-fatal.mk" line 13: Malformed conditional (${UNDEF})
+make: "directive-include-fatal.mk" line 14: Malformed conditional (${UNDEF})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-include-fatal.mk b/contrib/bmake/unit-tests/directive-include-fatal.mk
index 6744f9e80e5c..d4ed26f2a4aa 100755
--- a/contrib/bmake/unit-tests/directive-include-fatal.mk
+++ b/contrib/bmake/unit-tests/directive-include-fatal.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-include-fatal.mk,v 1.3 2021/02/01 22:16:57 rillig Exp $
+# $NetBSD: directive-include-fatal.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Test for the .include directive combined with fatal errors.
#
@@ -10,6 +10,7 @@
# the "fatals" counter.
# Using an undefined variable in a condition generates a fatal error.
+# expect+1: Malformed conditional (${UNDEF})
.if ${UNDEF}
.endif
diff --git a/contrib/bmake/unit-tests/directive-include-guard.exp b/contrib/bmake/unit-tests/directive-include-guard.exp
new file mode 100644
index 000000000000..487e67e33e77
--- /dev/null
+++ b/contrib/bmake/unit-tests/directive-include-guard.exp
@@ -0,0 +1,88 @@
+Parse_PushInput: file variable-ifndef.tmp, line 1
+Skipping 'variable-ifndef.tmp' because 'VARIABLE_IFNDEF' is defined
+Parse_PushInput: file variable-ifndef-reuse.tmp, line 1
+Skipping 'variable-ifndef-reuse.tmp' because 'VARIABLE_IFNDEF' is defined
+Parse_PushInput: file comments.tmp, line 1
+Skipping 'comments.tmp' because 'COMMENTS' is defined
+Parse_PushInput: file variable-if.tmp, line 1
+Skipping 'variable-if.tmp' because 'VARIABLE_IF' is defined
+Parse_PushInput: file variable-if-reuse.tmp, line 1
+Skipping 'variable-if-reuse.tmp' because 'VARIABLE_IF' is defined
+Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+Parse_PushInput: file variable-name-mismatch.tmp, line 1
+Parse_PushInput: file variable-name-mismatch.tmp, line 1
+Parse_PushInput: file variable-name-exclamation.tmp, line 1
+Parse_PushInput: file variable-name-exclamation.tmp, line 1
+Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+Parse_PushInput: file variable-name-parentheses.tmp, line 1
+Parse_PushInput: file variable-name-parentheses.tmp, line 1
+Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+Parse_PushInput: file variable-if-plus.tmp, line 1
+Parse_PushInput: file variable-if-plus.tmp, line 1
+Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
+Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
+Parse_PushInput: file variable-if-indirect.tmp, line 1
+Parse_PushInput: file variable-if-indirect.tmp, line 1
+Parse_PushInput: file variable-assign-indirect.tmp, line 1
+Skipping 'variable-assign-indirect.tmp' because 'VARIABLE_ASSIGN_INDIRECT' is defined
+Parse_PushInput: file variable-assign-late.tmp, line 1
+Skipping 'variable-assign-late.tmp' because 'VARIABLE_ASSIGN_LATE' is defined
+Parse_PushInput: file variable-assign-nested.tmp, line 1
+Parse_PushInput: .for loop in variable-assign-nested.tmp, line 3
+Skipping 'variable-assign-nested.tmp' because 'VARIABLE_ASSIGN_NESTED' is defined
+Parse_PushInput: file variable-already-defined.tmp, line 1
+Skipping 'variable-already-defined.tmp' because 'VARIABLE_ALREADY_DEFINED' is defined
+Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
+Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
+Parse_PushInput: file variable-two-times.tmp, line 1
+Parse_PushInput: file variable-two-times.tmp, line 1
+Parse_PushInput: file variable-clash.tmp, line 1
+Skipping 'variable-clash.tmp' because 'VARIABLE_IF' is defined
+Parse_PushInput: file variable-swapped.tmp, line 1
+Parse_PushInput: file variable-swapped.tmp, line 1
+Parse_PushInput: file variable-undef-between.tmp, line 1
+Parse_PushInput: file variable-undef-between.tmp, line 1
+Parse_PushInput: file variable-undef-inside.tmp, line 1
+Parse_PushInput: file variable-undef-inside.tmp, line 1
+Parse_PushInput: file variable-not-defined.tmp, line 1
+Parse_PushInput: file variable-not-defined.tmp, line 1
+Parse_PushInput: file if-elif.tmp, line 1
+Parse_PushInput: file if-elif.tmp, line 1
+Parse_PushInput: file if-elif-reuse.tmp, line 1
+Parse_PushInput: file if-elif-reuse.tmp, line 1
+Parse_PushInput: file if-else.tmp, line 1
+Parse_PushInput: file if-else.tmp, line 1
+Parse_PushInput: file if-else-reuse.tmp, line 1
+Parse_PushInput: file if-else-reuse.tmp, line 1
+Parse_PushInput: file inner-if-elif-else.tmp, line 1
+Skipping 'inner-if-elif-else.tmp' because 'INNER_IF_ELIF_ELSE' is defined
+Parse_PushInput: file target.tmp, line 1
+Skipping 'target.tmp' because '__target.tmp__' is defined
+Parse_PushInput: file target-sys.tmp, line 1
+Skipping 'target-sys.tmp' because '__<target-sys.tmp>__' is defined
+Parse_PushInput: file target-indirect.tmp, line 1
+Skipping 'target-indirect.tmp' because 'target-indirect.tmp' is defined
+Parse_PushInput: file target-indirect-PARSEFILE.tmp, line 1
+Skipping 'target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
+Parse_PushInput: file target-indirect-PARSEFILE2.tmp, line 1
+Skipping 'target-indirect-PARSEFILE2.tmp' because '__target-indirect-PARSEFILE2.tmp__' is defined
+Parse_PushInput: file subdir/target-indirect-PARSEFILE.tmp, line 1
+Skipping 'subdir/target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
+Parse_PushInput: file target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
+Skipping 'target-indirect-PARSEDIR-PARSEFILE.tmp' because '__target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
+Parse_PushInput: file subdir/target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
+Skipping 'subdir/target-indirect-PARSEDIR-PARSEFILE.tmp' because '__subdir/target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
+Parse_PushInput: file target-unguarded.tmp, line 1
+Parse_PushInput: file target-unguarded.tmp, line 1
+Parse_PushInput: file target-plus.tmp, line 1
+Parse_PushInput: file target-plus.tmp, line 1
+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
+exit status 0
diff --git a/contrib/bmake/unit-tests/directive-include-guard.mk b/contrib/bmake/unit-tests/directive-include-guard.mk
new file mode 100644
index 000000000000..1d19a67944e5
--- /dev/null
+++ b/contrib/bmake/unit-tests/directive-include-guard.mk
@@ -0,0 +1,552 @@
+# $NetBSD: directive-include-guard.mk,v 1.11 2023/06/21 21:21:52 sjg Exp $
+#
+# Tests for multiple-inclusion guards in makefiles.
+#
+# A file that is guarded by a multiple-inclusion guard has one of the
+# following forms:
+#
+# .ifndef GUARD_VARIABLE
+# .endif
+#
+# .if !defined(GUARD_VARIABLE)
+# .endif
+#
+# .if !target(guard-target)
+# .endif
+#
+# When such a file is included for the second or later time, and the guard
+# variable or the guard target is defined, including the file has no effect,
+# as all its content is skipped.
+#
+# See also:
+# https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
+
+# Each of the following test cases creates a temporary file named after the
+# test case and writes some lines of text to that file. That file is then
+# included twice, to see whether the second '.include' is skipped.
+
+
+# This is the canonical form of a variable-based multiple-inclusion guard.
+INCS+= variable-ifndef
+LINES.variable-ifndef= \
+ '.ifndef VARIABLE_IFNDEF' \
+ 'VARIABLE_IFNDEF=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-ifndef.tmp, line 1
+# expect: Skipping 'variable-ifndef.tmp' because 'VARIABLE_IFNDEF' is defined
+
+# A file that reuses a guard from a previous file (or whose guard is defined
+# for any other reason) is only processed once, to see whether it is guarded.
+# Its content is skipped, therefore the syntax error is not detected.
+INCS+= variable-ifndef-reuse
+LINES.variable-ifndef-reuse= \
+ '.ifndef VARIABLE_IFNDEF' \
+ 'syntax error' \
+ '.endif'
+# expect: Parse_PushInput: file variable-ifndef-reuse.tmp, line 1
+# expect: Skipping 'variable-ifndef-reuse.tmp' because 'VARIABLE_IFNDEF' is defined
+
+# Comments and empty lines do not affect the multiple-inclusion guard.
+INCS+= comments
+LINES.comments= \
+ '\# comment' \
+ '' \
+ '.ifndef COMMENTS' \
+ '\# comment' \
+ 'COMMENTS=\#comment' \
+ '.endif' \
+ '\# comment'
+# expect: Parse_PushInput: file comments.tmp, line 1
+# expect: Skipping 'comments.tmp' because 'COMMENTS' is defined
+
+# An alternative form uses the 'defined' function. It is more verbose than
+# the canonical form but avoids the '.ifndef' directive, as that directive is
+# not commonly used.
+INCS+= variable-if
+LINES.variable-if= \
+ '.if !defined(VARIABLE_IF)' \
+ 'VARIABLE_IF=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-if.tmp, line 1
+# expect: Skipping 'variable-if.tmp' because 'VARIABLE_IF' is defined
+
+# A file that reuses a guard from a previous file (or whose guard is defined
+# for any other reason) is only processed once, to see whether it is guarded.
+# Its content is skipped, therefore the syntax error is not detected.
+INCS+= variable-if-reuse
+LINES.variable-if-reuse= \
+ '.if !defined(VARIABLE_IF)' \
+ 'syntax error' \
+ '.endif'
+# expect: Parse_PushInput: file variable-if-reuse.tmp, line 1
+# expect: Skipping 'variable-if-reuse.tmp' because 'VARIABLE_IF' is defined
+
+# Triple negation is so uncommon that it's not recognized, even though it has
+# the same effect as a single negation.
+INCS+= variable-if-triple-negation
+LINES.variable-if-triple-negation= \
+ '.if !!!defined(VARIABLE_IF_TRIPLE_NEGATION)' \
+ 'VARIABLE_IF_TRIPLE_NEGATION=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+# expect: Parse_PushInput: file variable-if-triple-negation.tmp, line 1
+
+# A conditional other than '.if' or '.ifndef' does not guard the file, even if
+# it is otherwise equivalent to the above accepted forms.
+INCS+= variable-ifdef-negated
+LINES.variable-ifdef-negated= \
+ '.ifdef !VARIABLE_IFDEF_NEGATED' \
+ 'VARIABLE_IFDEF_NEGATED=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+# expect: Parse_PushInput: file variable-ifdef-negated.tmp, line 1
+
+# The variable names in the '.if' and the assignment must be the same.
+INCS+= variable-name-mismatch
+LINES.variable-name-mismatch= \
+ '.ifndef VARIABLE_NAME_MISMATCH' \
+ 'VARIABLE_NAME_DIFFERENT=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-name-mismatch.tmp, line 1
+# expect: Parse_PushInput: file variable-name-mismatch.tmp, line 1
+
+# The variable name '!VARNAME' cannot be used in an '.ifndef' directive, as
+# the '!' would be a negation. It is syntactically valid in a '.if !defined'
+# condition, but ignored there. Furthermore, when defining the variable, the
+# character '!' has to be escaped, to prevent it from being interpreted as the
+# '!' dependency operator.
+INCS+= variable-name-exclamation
+LINES.variable-name-exclamation= \
+ '.if !defined(!VARIABLE_NAME_EXCLAMATION)' \
+ '${:U!}VARIABLE_NAME_EXCLAMATION=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-name-exclamation.tmp, line 1
+# expect: Parse_PushInput: file variable-name-exclamation.tmp, line 1
+
+# A variable name can contain a '!' in the middle, as that character is
+# interpreted as an ordinary character in conditions as well as on the left
+# side of a variable assignment. For guard variable names, the '!' is not
+# supported in any place, though.
+INCS+= variable-name-exclamation-middle
+LINES.variable-name-exclamation-middle= \
+ '.ifndef VARIABLE_NAME!MIDDLE' \
+ 'VARIABLE_NAME!MIDDLE=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+# expect: Parse_PushInput: file variable-name-exclamation-middle.tmp, line 1
+
+# A variable name can contain balanced parentheses, at least in conditions and
+# on the left side of a variable assignment. There are enough places in make
+# where parentheses or braces are handled inconsistently to make this naming
+# choice a bad idea, therefore these characters are not allowed in guard
+# variable names.
+INCS+= variable-name-parentheses
+LINES.variable-name-parentheses= \
+ '.ifndef VARIABLE_NAME(&)PARENTHESES' \
+ 'VARIABLE_NAME(&)PARENTHESES=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-name-parentheses.tmp, line 1
+# expect: Parse_PushInput: file variable-name-parentheses.tmp, line 1
+
+# The guard condition must consist of only the guard variable, nothing else.
+INCS+= variable-ifndef-plus
+LINES.variable-ifndef-plus= \
+ '.ifndef VARIABLE_IFNDEF_PLUS && VARIABLE_IFNDEF_SECOND' \
+ 'VARIABLE_IFNDEF_PLUS=' \
+ 'VARIABLE_IFNDEF_SECOND=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+# expect: Parse_PushInput: file variable-ifndef-plus.tmp, line 1
+
+# The guard condition must consist of only the guard variable, nothing else.
+INCS+= variable-if-plus
+LINES.variable-if-plus= \
+ '.if !defined(VARIABLE_IF_PLUS) && !defined(VARIABLE_IF_SECOND)' \
+ 'VARIABLE_IF_PLUS=' \
+ 'VARIABLE_IF_SECOND=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-if-plus.tmp, line 1
+# expect: Parse_PushInput: file variable-if-plus.tmp, line 1
+
+# The variable name in an '.ifndef' guard must be given directly, it must not
+# contain any '$' expression.
+INCS+= variable-ifndef-indirect
+LINES.variable-ifndef-indirect= \
+ '.ifndef $${VARIABLE_IFNDEF_INDIRECT:L}' \
+ 'VARIABLE_IFNDEF_INDIRECT=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
+# expect: Parse_PushInput: file variable-ifndef-indirect.tmp, line 1
+
+# The variable name in an '.if' guard must be given directly, it must not
+# contain any '$' expression.
+INCS+= variable-if-indirect
+LINES.variable-if-indirect= \
+ '.if !defined($${VARIABLE_IF_INDIRECT:L})' \
+ 'VARIABLE_IF_INDIRECT=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-if-indirect.tmp, line 1
+# expect: Parse_PushInput: file variable-if-indirect.tmp, line 1
+
+# The variable name in the guard condition must only contain alphanumeric
+# characters and underscores. The guard variable is more flexible, it can be
+# defined anywhere, as long as it is defined at the point where the file is
+# included the next time.
+INCS+= variable-assign-indirect
+LINES.variable-assign-indirect= \
+ '.ifndef VARIABLE_ASSIGN_INDIRECT' \
+ '$${VARIABLE_ASSIGN_INDIRECT:L}=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-assign-indirect.tmp, line 1
+# expect: Skipping 'variable-assign-indirect.tmp' because 'VARIABLE_ASSIGN_INDIRECT' is defined
+
+# The time at which the guard variable is defined doesn't matter, as long as
+# it is defined at the point where the file is included the next time.
+INCS+= variable-assign-late
+LINES.variable-assign-late= \
+ '.ifndef VARIABLE_ASSIGN_LATE' \
+ 'VARIABLE_ASSIGN_LATE_OTHER=' \
+ 'VARIABLE_ASSIGN_LATE=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-assign-late.tmp, line 1
+# expect: Skipping 'variable-assign-late.tmp' because 'VARIABLE_ASSIGN_LATE' is defined
+
+# The time at which the guard variable is defined doesn't matter, as long as
+# it is defined at the point where the file is included the next time.
+INCS+= variable-assign-nested
+LINES.variable-assign-nested= \
+ '.ifndef VARIABLE_ASSIGN_NESTED' \
+ '. if 1' \
+ '. for i in once' \
+ 'VARIABLE_ASSIGN_NESTED=' \
+ '. endfor' \
+ '. endif' \
+ '.endif'
+# expect: Parse_PushInput: file variable-assign-nested.tmp, line 1
+# expect: Skipping 'variable-assign-nested.tmp' because 'VARIABLE_ASSIGN_NESTED' is defined
+
+# If the guard variable is defined before the file is included for the first
+# time, the file is considered guarded as well. In such a case, the parser
+# skips almost all lines, as they are irrelevant, but the structure of the
+# top-level '.if/.endif' conditional can be determined reliably enough to
+# decide whether the file is guarded.
+INCS+= variable-already-defined
+LINES.variable-already-defined= \
+ '.ifndef VARIABLE_ALREADY_DEFINED' \
+ 'VARIABLE_ALREADY_DEFINED=' \
+ '.endif'
+VARIABLE_ALREADY_DEFINED=
+# expect: Parse_PushInput: file variable-already-defined.tmp, line 1
+# expect: Skipping 'variable-already-defined.tmp' because 'VARIABLE_ALREADY_DEFINED' is defined
+
+# If the guard variable is defined before the file is included the first time,
+# the file is processed but its content is skipped. If that same guard
+# variable is undefined when the file is included the second time, the file is
+# processed as usual.
+INCS+= variable-defined-then-undefined
+LINES.variable-defined-then-undefined= \
+ '.ifndef VARIABLE_DEFINED_THEN_UNDEFINED' \
+ '.endif'
+VARIABLE_DEFINED_THEN_UNDEFINED=
+UNDEF_BETWEEN.variable-defined-then-undefined= \
+ VARIABLE_DEFINED_THEN_UNDEFINED
+# expect: Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
+# expect: Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
+
+# The whole file content must be guarded by a single '.if' conditional, not by
+# several, even if they have the same effect. This case is not expected to
+# occur in practice, as the two parts would rather be split into separate
+# files.
+INCS+= variable-two-times
+LINES.variable-two-times= \
+ '.ifndef VARIABLE_TWO_TIMES_1' \
+ 'VARIABLE_TWO_TIMES_1=' \
+ '.endif' \
+ '.ifndef VARIABLE_TWO_TIMES_2' \
+ 'VARIABLE_TWO_TIMES_2=' \
+ '.endif'
+# expect: Parse_PushInput: file variable-two-times.tmp, line 1
+# expect: Parse_PushInput: file variable-two-times.tmp, line 1
+
+# When multiple files use the same guard variable name, the optimization of
+# skipping the file affects each of these files.
+#
+# Choosing unique guard names is the responsibility of the makefile authors.
+# A typical pattern of guard variable names is '${PROJECT}_${DIR}_${FILE}_MK'.
+# System-provided files typically start the guard names with '_'.
+INCS+= variable-clash
+LINES.variable-clash= \
+ ${LINES.variable-if}
+# expect: Parse_PushInput: file variable-clash.tmp, line 1
+# expect: Skipping 'variable-clash.tmp' because 'VARIABLE_IF' is defined
+
+# The conditional must come before the assignment, otherwise the conditional
+# is useless, as it always evaluates to false.
+INCS+= variable-swapped
+LINES.variable-swapped= \
+ 'SWAPPED=' \
+ '.ifndef SWAPPED' \
+ '. error' \
+ '.endif'
+# expect: Parse_PushInput: file variable-swapped.tmp, line 1
+# expect: Parse_PushInput: file variable-swapped.tmp, line 1
+
+# If the guard variable is undefined between the first and the second time the
+# file is included, the guarded file is included again.
+INCS+= variable-undef-between
+LINES.variable-undef-between= \
+ '.ifndef VARIABLE_UNDEF_BETWEEN' \
+ 'VARIABLE_UNDEF_BETWEEN=' \
+ '.endif'
+UNDEF_BETWEEN.variable-undef-between= \
+ VARIABLE_UNDEF_BETWEEN
+# expect: Parse_PushInput: file variable-undef-between.tmp, line 1
+# expect: Parse_PushInput: file variable-undef-between.tmp, line 1
+
+# If the guard variable is undefined while the file is included the first
+# time, the guard does not have an effect, and the file is included again.
+INCS+= variable-undef-inside
+LINES.variable-undef-inside= \
+ '.ifndef VARIABLE_UNDEF_INSIDE' \
+ 'VARIABLE_UNDEF_INSIDE=' \
+ '.undef VARIABLE_UNDEF_INSIDE' \
+ '.endif'
+# expect: Parse_PushInput: file variable-undef-inside.tmp, line 1
+# expect: Parse_PushInput: file variable-undef-inside.tmp, line 1
+
+# If the file does not define the guard variable, the guard does not have an
+# effect, and the file is included again.
+INCS+= variable-not-defined
+LINES.variable-not-defined= \
+ '.ifndef VARIABLE_NOT_DEFINED' \
+ '.endif'
+# expect: Parse_PushInput: file variable-not-defined.tmp, line 1
+# expect: Parse_PushInput: file variable-not-defined.tmp, line 1
+
+# The outermost '.if' must not have an '.elif' branch.
+INCS+= if-elif
+LINES.if-elif= \
+ '.ifndef IF_ELIF' \
+ 'IF_ELIF=' \
+ '.elif 1' \
+ '.endif'
+# expect: Parse_PushInput: file if-elif.tmp, line 1
+# expect: Parse_PushInput: file if-elif.tmp, line 1
+
+# When a file with an '.if/.elif/.endif' conditional at the top level is
+# included, it is never optimized, as one of its branches is taken.
+INCS+= if-elif-reuse
+LINES.if-elif-reuse= \
+ '.ifndef IF_ELIF' \
+ 'syntax error' \
+ '.elif 1' \
+ '.endif'
+# expect: Parse_PushInput: file if-elif-reuse.tmp, line 1
+# expect: Parse_PushInput: file if-elif-reuse.tmp, line 1
+
+# The outermost '.if' must not have an '.else' branch.
+INCS+= if-else
+LINES.if-else= \
+ '.ifndef IF_ELSE' \
+ 'IF_ELSE=' \
+ '.else' \
+ '.endif'
+# expect: Parse_PushInput: file if-else.tmp, line 1
+# expect: Parse_PushInput: file if-else.tmp, line 1
+
+# When a file with an '.if/.else/.endif' conditional at the top level is
+# included, it is never optimized, as one of its branches is taken.
+INCS+= if-else-reuse
+LINES.if-else-reuse= \
+ '.ifndef IF_ELSE' \
+ 'syntax error' \
+ '.else' \
+ '.endif'
+# expect: Parse_PushInput: file if-else-reuse.tmp, line 1
+# expect: Parse_PushInput: file if-else-reuse.tmp, line 1
+
+# The inner '.if' directives may have an '.elif' or '.else', and it doesn't
+# matter which of their branches are taken.
+INCS+= inner-if-elif-else
+LINES.inner-if-elif-else= \
+ '.ifndef INNER_IF_ELIF_ELSE' \
+ 'INNER_IF_ELIF_ELSE=' \
+ '. if 0' \
+ '. elif 0' \
+ '. else' \
+ '. endif' \
+ '. if 0' \
+ '. elif 1' \
+ '. else' \
+ '. endif' \
+ '. if 1' \
+ '. elif 1' \
+ '. else' \
+ '. endif' \
+ '.endif'
+# expect: Parse_PushInput: file inner-if-elif-else.tmp, line 1
+# expect: Skipping 'inner-if-elif-else.tmp' because 'INNER_IF_ELIF_ELSE' is defined
+
+# The guard can also be a target instead of a variable. Using a target as a
+# guard has the benefit that a target cannot be undefined once it is defined.
+# The target should be declared '.NOTMAIN'. Since the target names are
+# usually chosen according to a pattern that doesn't interfere with real
+# target names, they don't need to be declared '.PHONY' as they don't generate
+# filesystem operations.
+INCS+= target
+LINES.target= \
+ '.if !target(__target.tmp__)' \
+ '__target.tmp__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target.tmp, line 1
+# expect: Skipping 'target.tmp' because '__target.tmp__' is defined
+
+# When used for system files, the target name may include '<' and '>', for
+# symmetry with the '.include <sys.mk>' directive. The characters '<' and '>'
+# are ordinary characters.
+INCS+= target-sys
+LINES.target-sys= \
+ '.if !target(__<target-sys.tmp>__)' \
+ '__<target-sys.tmp>__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-sys.tmp, line 1
+# expect: Skipping 'target-sys.tmp' because '__<target-sys.tmp>__' is defined
+
+# The target name may include variable references. These references are
+# expanded as usual. Due to the current implementation, the expressions are
+# evaluated twice: Once for checking whether the condition evaluates to true,
+# and once for determining the guard name. This double evaluation should not
+# matter in practice, as guard expressions are expected to be simple,
+# deterministic and without side effects.
+INCS+= target-indirect
+LINES.target-indirect= \
+ '.if !target($${target-indirect.tmp:L})' \
+ 'target-indirect.tmp: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-indirect.tmp, line 1
+# expect: Skipping 'target-indirect.tmp' because 'target-indirect.tmp' is defined
+
+# A common form of guard target is __${.PARSEFILE}__. This form can only be
+# used if all files using this form have unique basenames. To get a robust
+# pattern based on the same idea, use __${.PARSEDIR}/${.PARSEFILE}__ instead.
+# This form does not work when the basename contains whitespace characters, as
+# it is not possible to define a target with whitespace, not even by cheating.
+INCS+= target-indirect-PARSEFILE
+LINES.target-indirect-PARSEFILE= \
+ '.if !target(__$${.PARSEFILE}__)' \
+ '__$${.PARSEFILE}__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-indirect-PARSEFILE.tmp, line 1
+# expect: Skipping 'target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
+
+# Two files with different basenames can both use the same syntactic pattern
+# for the target guard name, as the expressions expand to different strings.
+INCS+= target-indirect-PARSEFILE2
+LINES.target-indirect-PARSEFILE2= \
+ '.if !target(__$${.PARSEFILE}__)' \
+ '__$${.PARSEFILE}__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-indirect-PARSEFILE2.tmp, line 1
+# expect: Skipping 'target-indirect-PARSEFILE2.tmp' because '__target-indirect-PARSEFILE2.tmp__' is defined
+
+# Using plain .PARSEFILE without .PARSEDIR leads to name clashes. The include
+# guard is the same as in the test case 'target-indirect-PARSEFILE', as the
+# guard name only contains the basename but not the directory name.
+INCS+= subdir/target-indirect-PARSEFILE
+LINES.subdir/target-indirect-PARSEFILE= \
+ '.if !target(__$${.PARSEFILE}__)' \
+ '__$${.PARSEFILE}__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file subdir/target-indirect-PARSEFILE.tmp, line 1
+# expect: Skipping 'subdir/target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
+
+# Another common form of guard target is __${.PARSEDIR}/${.PARSEFILE}__
+# or __${.PARSEDIR:tA}/${.PARSEFILE}__ to be truely unique.
+INCS+= target-indirect-PARSEDIR-PARSEFILE
+LINES.target-indirect-PARSEDIR-PARSEFILE= \
+ '.if !target(__$${.PARSEDIR}/$${.PARSEFILE}__)' \
+ '__$${.PARSEDIR}/$${.PARSEFILE}__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
+# expect: Skipping 'target-indirect-PARSEDIR-PARSEFILE.tmp' because '__target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
+# The actual target starts with '__${.OBJDIR}/', see the .rawout file, but the
+# string '${.OBJDIR}/' gets stripped in post processing.
+
+# Using the combination of '.PARSEDIR' and '.PARSEFILE', a file in a
+# subdirectory gets a different guard target name than the previous one.
+INCS+= subdir/target-indirect-PARSEDIR-PARSEFILE
+LINES.subdir/target-indirect-PARSEDIR-PARSEFILE= \
+ '.if !target(__$${.PARSEDIR}/$${.PARSEFILE}__)' \
+ '__$${.PARSEDIR}/$${.PARSEFILE}__: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file subdir/target-indirect-PARSEDIR-PARSEFILE.tmp, line 1
+# expect: Skipping 'subdir/target-indirect-PARSEDIR-PARSEFILE.tmp' because '__subdir/target-indirect-PARSEDIR-PARSEFILE.tmp__' is defined
+# The actual target starts with '__${.OBJDIR}/', see the .rawout file, but the
+# string '${.OBJDIR}/' gets stripped in post processing.
+
+# If the guard target is not defined when including the file the next time,
+# the file is processed again.
+INCS+= target-unguarded
+LINES.target-unguarded= \
+ '.if !target(target-unguarded)' \
+ '.endif'
+# expect: Parse_PushInput: file target-unguarded.tmp, line 1
+# expect: Parse_PushInput: file target-unguarded.tmp, line 1
+
+# The guard condition must consist of only the guard target, nothing else.
+INCS+= target-plus
+LINES.target-plus= \
+ '.if !target(target-plus) && 1' \
+ 'target-plus: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-plus.tmp, line 1
+# expect: Parse_PushInput: file target-plus.tmp, line 1
+
+# If the guard target is defined before the file is included the first time,
+# the file is not considered guarded.
+INCS+= target-already-defined
+LINES.target-already-defined= \
+ '.if !target(target-already-defined)' \
+ 'target-already-defined: .NOTMAIN' \
+ '.endif'
+target-already-defined: .NOTMAIN
+# expect: Parse_PushInput: file target-already-defined.tmp, line 1
+# expect: Skipping 'target-already-defined.tmp' because 'target-already-defined' is defined
+
+# A target name cannot contain the character '!'. In the condition, the '!'
+# is syntactically valid, but in the dependency declaration line, the '!' is
+# interpreted as the '!' dependency operator, no matter whether it occurs at
+# the beginning or in the middle of a target name. Escaping it as '${:U!}'
+# doesn't work, as the whole line is first expanded and then scanned for the
+# dependency operator. Escaping it as '\!' doesn't work either, even though
+# the '\' escapes the '!' from being a dependency operator, but when reading
+# the target name, the '\' is kept, resulting in the target name
+# '\!target-name-exclamation' instead of '!target-name-exclamation'.
+INCS+= target-name-exclamation
+LINES.target-name-exclamation= \
+ '.if !target(!target-name-exclamation)' \
+ '\!target-name-exclamation: .NOTMAIN' \
+ '.endif'
+# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
+# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
+
+# Now run all test cases by including each of the files twice and looking at
+# the debug output. The files that properly guard against multiple inclusion
+# generate a 'Skipping' line, the others repeat the 'Parse_PushInput' line.
+#
+# Some debug output lines are suppressed in the .exp file, see ./Makefile.
+.for i in ${INCS}
+. for fname in $i.tmp
+_:= ${fname:H:N.:@dir@${:!mkdir -p ${dir}!}@}
+_!= printf '%s\n' ${LINES.$i} > ${fname}
+.MAKEFLAGS: -dp
+.include "${.CURDIR}/${fname}"
+.undef ${UNDEF_BETWEEN.$i:U}
+.include "${.CURDIR}/${fname}"
+.MAKEFLAGS: -d0
+_!= rm ${fname}
+_:= ${fname:H:N.:@dir@${:!rmdir ${dir}!}@}
+. endfor
+.endfor
+
+all:
diff --git a/contrib/bmake/unit-tests/directive-include.exp b/contrib/bmake/unit-tests/directive-include.exp
index 0ddf40a75d2d..161f1750f7a7 100755
--- a/contrib/bmake/unit-tests/directive-include.exp
+++ b/contrib/bmake/unit-tests/directive-include.exp
@@ -2,12 +2,12 @@ CondParser_Eval: ${.MAKE.MAKEFILES:T} != "${.PARSEFILE} null"
Comparing "directive-include.mk null" != "directive-include.mk null"
CondParser_Eval: ${.MAKE.MAKEFILES:T} != "${.PARSEFILE} null"
Comparing "directive-include.mk null" != "directive-include.mk null"
-make: "directive-include.mk" line 25: Could not find nonexistent.mk
-make: "directive-include.mk" line 47: Could not find "
-make: "directive-include.mk" line 52: Unknown modifier "Z"
-make: "directive-include.mk" line 52: Could not find nonexistent.mk
-make: "directive-include.mk" line 57: Cannot open /nonexistent
-make: "directive-include.mk" line 62: Invalid line type
+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: Unknown modifier "Z"
+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 type
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-include.mk b/contrib/bmake/unit-tests/directive-include.mk
index edf27d02483e..404730a0cb6b 100755
--- a/contrib/bmake/unit-tests/directive-include.mk
+++ b/contrib/bmake/unit-tests/directive-include.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-include.mk,v 1.11 2022/01/15 12:35:18 rillig Exp $
+# $NetBSD: directive-include.mk,v 1.12 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .include directive, which includes another file.
@@ -22,6 +22,7 @@
. error
.endif
+# expect+1: Could not find nonexistent.mk
.include "nonexistent.mk"
.include "/dev/null" # size 0
# including a directory technically succeeds, but shouldn't.
@@ -44,11 +45,14 @@ DEV= null
# would be empty, and the closing '"' would be in the trailing part of the
# line, which is ignored as of 2021-12-03.
DQUOT= "
+# expect+1: Could not find "
.include "${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: Unknown modifier "Z"
.include "nonexistent${:U123:Z}.mk"
# The traditional include directive is seldom used.
diff --git a/contrib/bmake/unit-tests/directive-info.exp b/contrib/bmake/unit-tests/directive-info.exp
index 70def02441d1..397d9d31ef38 100644
--- a/contrib/bmake/unit-tests/directive-info.exp
+++ b/contrib/bmake/unit-tests/directive-info.exp
@@ -1,15 +1,15 @@
-make: "directive-info.mk" line 11: begin .info tests
-make: "directive-info.mk" line 12: Unknown directive "inf"
-make: "directive-info.mk" line 13: Missing argument for ".info"
-make: "directive-info.mk" line 14: message
-make: "directive-info.mk" line 15: indented message
-make: "directive-info.mk" line 16: Unknown directive "information"
-make: "directive-info.mk" line 17: Unknown directive "information"
-make: "directive-info.mk" line 22: Missing argument for ".info"
-make: "directive-info.mk" line 23: Missing argument for ".info"
-make: "directive-info.mk" line 26: Unknown directive "info-message"
-make: "directive-info.mk" line 27: no-target: no-source
-make: "directive-info.mk" line 35: expect line 35 for multi-line message
+make: "directive-info.mk" line 12: begin .info tests
+make: "directive-info.mk" line 14: Unknown directive "inf"
+make: "directive-info.mk" line 16: Missing argument for ".info"
+make: "directive-info.mk" line 18: message
+make: "directive-info.mk" line 20: indented message
+make: "directive-info.mk" line 22: Unknown directive "information"
+make: "directive-info.mk" line 24: Unknown directive "information"
+make: "directive-info.mk" line 30: Missing argument for ".info"
+make: "directive-info.mk" line 32: Missing argument for ".info"
+make: "directive-info.mk" line 36: Unknown directive "info-message"
+make: "directive-info.mk" line 38: no-target: no-source
+make: "directive-info.mk" line 47: expect line 35 for multi-line message
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-info.mk b/contrib/bmake/unit-tests/directive-info.mk
index 327ff63e7f9b..ab550555d44f 100644
--- a/contrib/bmake/unit-tests/directive-info.mk
+++ b/contrib/bmake/unit-tests/directive-info.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-info.mk,v 1.10 2022/05/08 06:51:27 rillig Exp $
+# $NetBSD: directive-info.mk,v 1.11 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .info directive.
#
@@ -8,22 +8,33 @@
# TODO: Implementation
+# expect+1: begin .info tests
.info begin .info tests
+# expect+1: Unknown directive "inf"
.inf # misspelled
-.info # "Missing argument"
+# expect+1: Missing argument for ".info"
+.info
+# expect+1: message
.info message
+# expect+1: indented message
.info indented message
+# expect+1: Unknown directive "information"
.information
+# expect+1: Unknown directive "information"
.information message # Accepted before 2020-12-13 01:07:54.
.info.man: # not a message, but possibly a suffix rule
# Even if lines would have trailing whitespace, this would be trimmed by
# ParseRawLine.
+# expect+1: Missing argument for ".info"
.info
+# expect+1: Missing argument for ".info"
.info # comment
.info: message # This is a dependency declaration.
+# expect+1: Unknown directive "info-message"
.info-message # This is an unknown directive.
+# expect+1: no-target: no-source
.info no-target: no-source # This is a .info directive, not a dependency.
# See directive.mk for more tests of this kind.
@@ -32,9 +43,7 @@
# number of completely read lines. For the following multi-line directive,
# this meant that the reported line number was the one of the last line, not
# of the first line.
+# expect+1: expect line 35 for multi-line message
.info expect line 35 for\
multi$\
-line message
-
-all:
- @:;
diff --git a/contrib/bmake/unit-tests/directive-misspellings.exp b/contrib/bmake/unit-tests/directive-misspellings.exp
index e51d8473b305..a00615926740 100644
--- a/contrib/bmake/unit-tests/directive-misspellings.exp
+++ b/contrib/bmake/unit-tests/directive-misspellings.exp
@@ -1,45 +1,45 @@
-make: "directive-misspellings.mk" line 12: Unknown directive "dinclud"
-make: "directive-misspellings.mk" line 14: Unknown directive "dincludx"
-make: "directive-misspellings.mk" line 15: .include filename must be delimited by '"' or '<'
-make: "directive-misspellings.mk" line 17: Unknown directive "erro"
-make: "directive-misspellings.mk" line 18: Unknown directive "errox"
-make: "directive-misspellings.mk" line 22: Unknown directive "expor"
-make: "directive-misspellings.mk" line 24: Unknown directive "exporx"
-make: "directive-misspellings.mk" line 25: Unknown directive "exports"
-make: "directive-misspellings.mk" line 27: Unknown directive "export-en"
-make: "directive-misspellings.mk" line 30: Unknown directive "export-environment"
-make: "directive-misspellings.mk" line 32: Unknown directive "export-litera"
-make: "directive-misspellings.mk" line 34: Unknown directive "export-literax"
-make: "directive-misspellings.mk" line 35: Unknown directive "export-literally"
-make: "directive-misspellings.mk" line 37: Unknown directive "-includ"
-make: "directive-misspellings.mk" line 39: Unknown directive "-includx"
-make: "directive-misspellings.mk" line 40: .include filename must be delimited by '"' or '<'
-make: "directive-misspellings.mk" line 42: Unknown directive "includ"
-make: "directive-misspellings.mk" line 43: Could not find file
-make: "directive-misspellings.mk" line 44: Unknown directive "includx"
-make: "directive-misspellings.mk" line 45: .include filename must be delimited by '"' or '<'
-make: "directive-misspellings.mk" line 47: Unknown directive "inf"
-make: "directive-misspellings.mk" line 48: msg
-make: "directive-misspellings.mk" line 49: Unknown directive "infx"
-make: "directive-misspellings.mk" line 50: Unknown directive "infos"
-make: "directive-misspellings.mk" line 52: Unknown directive "sinclud"
-make: "directive-misspellings.mk" line 54: Unknown directive "sincludx"
-make: "directive-misspellings.mk" line 55: .include filename must be delimited by '"' or '<'
-make: "directive-misspellings.mk" line 57: Unknown directive "unde"
-make: "directive-misspellings.mk" line 59: Unknown directive "undex"
-make: "directive-misspellings.mk" line 60: Unknown directive "undefs"
-make: "directive-misspellings.mk" line 62: Unknown directive "unexpor"
-make: "directive-misspellings.mk" line 64: Unknown directive "unexporx"
-make: "directive-misspellings.mk" line 65: Unknown directive "unexports"
-make: "directive-misspellings.mk" line 67: Unknown directive "unexport-en"
-make: "directive-misspellings.mk" line 69: The directive .unexport-env does not take arguments
-make: "directive-misspellings.mk" line 70: Unknown directive "unexport-enx"
-make: "directive-misspellings.mk" line 71: Unknown directive "unexport-envs"
-make: "directive-misspellings.mk" line 73: Unknown directive "warn"
-make: "directive-misspellings.mk" line 74: Unknown directive "warnin"
-make: "directive-misspellings.mk" line 75: warning: msg
-make: "directive-misspellings.mk" line 76: Unknown directive "warninx"
-make: "directive-misspellings.mk" line 77: Unknown directive "warnings"
+make: "directive-misspellings.mk" line 13: Unknown directive "dinclud"
+make: "directive-misspellings.mk" line 16: Unknown directive "dincludx"
+make: "directive-misspellings.mk" line 18: .include filename must be delimited by '"' or '<'
+make: "directive-misspellings.mk" line 21: Unknown directive "erro"
+make: "directive-misspellings.mk" line 23: Unknown directive "errox"
+make: "directive-misspellings.mk" line 28: Unknown directive "expor"
+make: "directive-misspellings.mk" line 31: Unknown directive "exporx"
+make: "directive-misspellings.mk" line 33: Unknown directive "exports"
+make: "directive-misspellings.mk" line 36: Unknown directive "export-en"
+make: "directive-misspellings.mk" line 40: Unknown directive "export-environment"
+make: "directive-misspellings.mk" line 43: Unknown directive "export-litera"
+make: "directive-misspellings.mk" line 46: Unknown directive "export-literax"
+make: "directive-misspellings.mk" line 48: Unknown directive "export-literally"
+make: "directive-misspellings.mk" line 51: Unknown directive "-includ"
+make: "directive-misspellings.mk" line 54: Unknown directive "-includx"
+make: "directive-misspellings.mk" line 56: .include filename must be delimited by '"' or '<'
+make: "directive-misspellings.mk" line 59: Unknown directive "includ"
+make: "directive-misspellings.mk" line 61: Could not find file
+make: "directive-misspellings.mk" line 63: Unknown directive "includx"
+make: "directive-misspellings.mk" line 65: .include filename must be delimited by '"' or '<'
+make: "directive-misspellings.mk" line 68: Unknown directive "inf"
+make: "directive-misspellings.mk" line 70: msg
+make: "directive-misspellings.mk" line 72: Unknown directive "infx"
+make: "directive-misspellings.mk" line 74: Unknown directive "infos"
+make: "directive-misspellings.mk" line 77: Unknown directive "sinclud"
+make: "directive-misspellings.mk" line 80: Unknown directive "sincludx"
+make: "directive-misspellings.mk" line 82: .include filename must be delimited by '"' or '<'
+make: "directive-misspellings.mk" line 85: Unknown directive "unde"
+make: "directive-misspellings.mk" line 88: Unknown directive "undex"
+make: "directive-misspellings.mk" line 90: Unknown directive "undefs"
+make: "directive-misspellings.mk" line 93: Unknown directive "unexpor"
+make: "directive-misspellings.mk" line 96: Unknown directive "unexporx"
+make: "directive-misspellings.mk" line 98: Unknown directive "unexports"
+make: "directive-misspellings.mk" line 101: Unknown directive "unexport-en"
+make: "directive-misspellings.mk" line 104: The directive .unexport-env does not take arguments
+make: "directive-misspellings.mk" line 106: Unknown directive "unexport-enx"
+make: "directive-misspellings.mk" line 108: Unknown directive "unexport-envs"
+make: "directive-misspellings.mk" line 111: Unknown directive "warn"
+make: "directive-misspellings.mk" line 113: Unknown directive "warnin"
+make: "directive-misspellings.mk" line 115: warning: msg
+make: "directive-misspellings.mk" line 117: Unknown directive "warninx"
+make: "directive-misspellings.mk" line 119: Unknown directive "warnings"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-misspellings.mk b/contrib/bmake/unit-tests/directive-misspellings.mk
index 5f479f03b7f1..0014076d041f 100644
--- a/contrib/bmake/unit-tests/directive-misspellings.mk
+++ b/contrib/bmake/unit-tests/directive-misspellings.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-misspellings.mk,v 1.3 2020/12/13 01:10:22 rillig Exp $
+# $NetBSD: directive-misspellings.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for misspelled directives.
#
@@ -9,71 +9,111 @@
# ".information" were aliases to ".info" since the code for these diagnostic
# directives just skipped any letters following the "error", "warn" or "info".
+# expect+1: Unknown directive "dinclud"
.dinclud "file"
.dinclude "file"
+# expect+1: Unknown directive "dincludx"
.dincludx "file"
+# expect+1: .include filename must be delimited by '"' or '<'
.dincludes "file" # XXX: the 's' is not meant to be a filename
+# expect+1: Unknown directive "erro"
.erro msg
+# expect+1: Unknown directive "errox"
.errox msg
# no .error since that would exit immediately
# no .errors since that would exit immediately, even with the typo
+# expect+1: Unknown directive "expor"
.expor varname
.export varname
+# expect+1: Unknown directive "exporx"
.exporx varname
+# expect+1: Unknown directive "exports"
.exports varname # Accepted before 2020-12-13 01:07:54.
+# expect+1: Unknown directive "export-en"
.export-en # Accepted before 2020-12-13 01:07:54.
.export-env
.export-env extra argument # XXX: undetected extra argument
+# expect+1: Unknown directive "export-environment"
.export-environment # Accepted before 2020-12-13 01:07:54.
+# expect+1: Unknown directive "export-litera"
.export-litera varname # Accepted before 2020-12-13 01:07:54.
.export-literal varname
+# expect+1: Unknown directive "export-literax"
.export-literax varname # Accepted before 2020-12-13 01:07:54.
+# expect+1: Unknown directive "export-literally"
.export-literally varname # Accepted before 2020-12-13 01:07:54.
+# expect+1: Unknown directive "-includ"
.-includ "file"
.-include "file"
+# expect+1: Unknown directive "-includx"
.-includx "file"
+# expect+1: .include filename must be delimited by '"' or '<'
.-includes "file" # XXX: the 's' is not meant to be a filename
+# expect+1: Unknown directive "includ"
.includ "file"
+# expect+1: Could not find file
.include "file"
+# expect+1: Unknown directive "includx"
.includx "file"
+# expect+1: .include filename must be delimited by '"' or '<'
.includex "file" # XXX: the 's' is not meant to be a filename
+# expect+1: Unknown directive "inf"
.inf msg
+# expect+1: msg
.info msg
+# expect+1: Unknown directive "infx"
.infx msg
+# expect+1: Unknown directive "infos"
.infos msg # Accepted before 2020-12-13 01:07:54.
+# expect+1: Unknown directive "sinclud"
.sinclud "file"
.sinclude "file"
+# expect+1: Unknown directive "sincludx"
.sincludx "file"
+# expect+1: .include filename must be delimited by '"' or '<'
.sincludes "file" # XXX: the 's' is not meant to be a filename
+# expect+1: Unknown directive "unde"
.unde varname
.undef varname
+# expect+1: Unknown directive "undex"
.undex varname
+# expect+1: Unknown directive "undefs"
.undefs varname # Accepted before 2020-12-13 01:07:54.
+# expect+1: Unknown directive "unexpor"
.unexpor varname
.unexport varname
+# expect+1: Unknown directive "unexporx"
.unexporx varname
+# expect+1: Unknown directive "unexports"
.unexports varname # Accepted before 2020-12-12 18:00:18.
+# expect+1: Unknown directive "unexport-en"
.unexport-en # Accepted before 2020-12-12 18:11:42.
.unexport-env
+# expect+1: The directive .unexport-env does not take arguments
.unexport-env extra argument # Accepted before 2020-12-12 18:00:18.
+# expect+1: Unknown directive "unexport-enx"
.unexport-enx # Accepted before 2020-12-12 18:00:18.
+# expect+1: Unknown directive "unexport-envs"
.unexport-envs # Accepted before 2020-12-12 18:00:18.
+# expect+1: Unknown directive "warn"
.warn msg
+# expect+1: Unknown directive "warnin"
.warnin msg
+# expect+1: warning: msg
.warning msg
+# expect+1: Unknown directive "warninx"
.warninx msg
+# expect+1: Unknown directive "warnings"
.warnings msg # Accepted before 2020-12-13 01:07:54.
-
-all:
diff --git a/contrib/bmake/unit-tests/directive-undef.exp b/contrib/bmake/unit-tests/directive-undef.exp
index 20df58a8dc73..f3957a990e18 100644
--- a/contrib/bmake/unit-tests/directive-undef.exp
+++ b/contrib/bmake/unit-tests/directive-undef.exp
@@ -1,6 +1,6 @@
-make: "directive-undef.mk" line 29: The .undef directive requires an argument
-make: "directive-undef.mk" line 86: Unknown modifier "Z"
-make: "directive-undef.mk" line 102: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore.
+make: "directive-undef.mk" line 30: The .undef directive requires an argument
+make: "directive-undef.mk" line 88: Unknown modifier "Z"
+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 in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-undef.mk b/contrib/bmake/unit-tests/directive-undef.mk
index 5ac7d939c71e..ef047fefe177 100644
--- a/contrib/bmake/unit-tests/directive-undef.mk
+++ b/contrib/bmake/unit-tests/directive-undef.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-undef.mk,v 1.12 2022/03/26 12:44:57 rillig Exp $
+# $NetBSD: directive-undef.mk,v 1.13 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .undef directive.
#
@@ -26,6 +26,7 @@
# to delete the variable with the empty name, which never exists; see
# varname-empty.mk. Since var.c 1.737 from 2020-12-19, .undef complains
# about a missing argument.
+# expect+1: The .undef directive requires an argument
.undef
@@ -83,6 +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: Unknown modifier "Z"
.undef ${VARNAMES:L:Z}
@@ -99,6 +101,7 @@ UT_EXPORTED= exported-value
. error
.endif
.if ${.MAKE.EXPORTED:MUT_EXPORTED}
+# expect+1: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore.
. warning UT_EXPORTED is still listed in .MAKE.EXPORTED even though $\
it is not exported anymore.
.endif
diff --git a/contrib/bmake/unit-tests/directive-unexport-env.exp b/contrib/bmake/unit-tests/directive-unexport-env.exp
index 22528c31c3a1..663034cee12c 100644
--- a/contrib/bmake/unit-tests/directive-unexport-env.exp
+++ b/contrib/bmake/unit-tests/directive-unexport-env.exp
@@ -1,9 +1,9 @@
-make: "directive-unexport-env.mk" line 13: Unknown directive "unexport-en"
-make: "directive-unexport-env.mk" line 15: Unknown directive "unexport-environment"
+make: "directive-unexport-env.mk" line 14: Unknown directive "unexport-en"
+make: "directive-unexport-env.mk" line 17: Unknown directive "unexport-environment"
Global: UT_EXPORTED = value
Global: UT_UNEXPORTED = value
Global: .MAKE.EXPORTED = UT_EXPORTED
-make: "directive-unexport-env.mk" line 21: The directive .unexport-env does not take arguments
+make: "directive-unexport-env.mk" line 24: The directive .unexport-env does not take arguments
Var_Parse: ${.MAKE.EXPORTED:O:u} (eval)
Evaluating modifier ${.MAKE.EXPORTED:O} on value "UT_EXPORTED"
Result of ${.MAKE.EXPORTED:O} is "UT_EXPORTED"
diff --git a/contrib/bmake/unit-tests/directive-unexport-env.mk b/contrib/bmake/unit-tests/directive-unexport-env.mk
index e9620684dfcb..e56e47865011 100644
--- a/contrib/bmake/unit-tests/directive-unexport-env.mk
+++ b/contrib/bmake/unit-tests/directive-unexport-env.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-unexport-env.mk,v 1.8 2022/01/23 16:09:38 rillig Exp $
+# $NetBSD: directive-unexport-env.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .unexport-env directive.
#
@@ -10,14 +10,17 @@
# TODO: Implementation
+# expect+1: Unknown directive "unexport-en"
.unexport-en # misspelled
.unexport-env # ok
+# expect+1: Unknown directive "unexport-environment"
.unexport-environment # misspelled
.MAKEFLAGS: -dv
UT_EXPORTED= value
UT_UNEXPORTED= value
.export UT_EXPORTED
+# expect+1: The directive .unexport-env does not take arguments
.unexport-env UT_EXPORTED UT_UNEXPORTED
.MAKEFLAGS: -d0
diff --git a/contrib/bmake/unit-tests/directive-unexport.exp b/contrib/bmake/unit-tests/directive-unexport.exp
index d59fb4713259..b084daf5d147 100644
--- a/contrib/bmake/unit-tests/directive-unexport.exp
+++ b/contrib/bmake/unit-tests/directive-unexport.exp
@@ -1,5 +1,5 @@
-make: "directive-unexport.mk" line 18: UT_A=a UT_B=b UT_C=c
-make: "directive-unexport.mk" line 19: UT_A UT_B UT_C
-make: "directive-unexport.mk" line 27: UT_A=a UT_B=b UT_C=c
-make: "directive-unexport.mk" line 28:
+make: "directive-unexport.mk" line 19: UT_A=a UT_B=b UT_C=c
+make: "directive-unexport.mk" line 21: UT_A UT_B UT_C
+make: "directive-unexport.mk" line 30: UT_A=a UT_B=b UT_C=c
+make: "directive-unexport.mk" line 31:
exit status 0
diff --git a/contrib/bmake/unit-tests/directive-unexport.mk b/contrib/bmake/unit-tests/directive-unexport.mk
index efc103efedf6..e759fe3e35f2 100644
--- a/contrib/bmake/unit-tests/directive-unexport.mk
+++ b/contrib/bmake/unit-tests/directive-unexport.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-unexport.mk,v 1.7 2020/12/13 01:07:54 rillig Exp $
+# $NetBSD: directive-unexport.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .unexport directive.
#
@@ -15,7 +15,9 @@ UT_C= c
.export UT_A UT_B UT_C
# Show the exported variables and their values.
+# expect+1: UT_A=a UT_B=b UT_C=c
.info ${:!env|sort|grep '^UT_'!}
+# expect+1: UT_A UT_B UT_C
.info ${.MAKE.EXPORTED}
# XXX: Now try to unexport all of them. The variables are still exported
@@ -24,6 +26,7 @@ UT_C= c
*= asterisk
.unexport *
+# expect+1: UT_A=a UT_B=b UT_C=c
.info ${:!env|sort|grep '^UT_'!}
.info ${.MAKE.EXPORTED}
diff --git a/contrib/bmake/unit-tests/directive-warning.exp b/contrib/bmake/unit-tests/directive-warning.exp
index 932b88a151e2..6fbeed91df0f 100644
--- a/contrib/bmake/unit-tests/directive-warning.exp
+++ b/contrib/bmake/unit-tests/directive-warning.exp
@@ -1,11 +1,11 @@
-make: "directive-warning.mk" line 9: Unknown directive "warn"
make: "directive-warning.mk" line 10: Unknown directive "warn"
-make: "directive-warning.mk" line 11: Unknown directive "warnin"
-make: "directive-warning.mk" line 12: Unknown directive "warnin"
-make: "directive-warning.mk" line 13: Missing argument for ".warning"
-make: "directive-warning.mk" line 14: warning: message
-make: "directive-warning.mk" line 15: Unknown directive "warnings"
-make: "directive-warning.mk" line 16: Unknown directive "warnings"
+make: "directive-warning.mk" line 12: Unknown directive "warn"
+make: "directive-warning.mk" line 14: Unknown directive "warnin"
+make: "directive-warning.mk" line 16: Unknown directive "warnin"
+make: "directive-warning.mk" line 18: Missing argument for ".warning"
+make: "directive-warning.mk" line 19: warning: message
+make: "directive-warning.mk" line 21: Unknown directive "warnings"
+make: "directive-warning.mk" line 23: Unknown directive "warnings"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/directive-warning.mk b/contrib/bmake/unit-tests/directive-warning.mk
index 9d5cec1ff0b8..b4c8f4730b78 100644
--- a/contrib/bmake/unit-tests/directive-warning.mk
+++ b/contrib/bmake/unit-tests/directive-warning.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-warning.mk,v 1.7 2022/01/23 16:09:38 rillig Exp $
+# $NetBSD: directive-warning.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .warning directive.
#
@@ -6,13 +6,20 @@
# produced the wrong error message "Unknown directive". Since parse.c 1.503
# from 2020-12-19, the correct "Missing argument" is produced.
+# expect+1: Unknown directive "warn"
.warn # misspelled
+# expect+1: Unknown directive "warn"
.warn message # misspelled
+# expect+1: Unknown directive "warnin"
.warnin # misspelled
+# expect+1: Unknown directive "warnin"
.warnin message # misspelled
+# expect+1: Missing argument for ".warning"
.warning # "Missing argument"
.warning message # expect+0: message
+# expect+1: Unknown directive "warnings"
.warnings # misspelled
+# expect+1: Unknown directive "warnings"
.warnings messages # Accepted before 2020-12-13 01:07:54.
all: .PHONY
diff --git a/contrib/bmake/unit-tests/doterror.mk b/contrib/bmake/unit-tests/doterror.mk
index d46fb3581a25..0f3698ad5cf2 100644
--- a/contrib/bmake/unit-tests/doterror.mk
+++ b/contrib/bmake/unit-tests/doterror.mk
@@ -1,4 +1,4 @@
-# $NetBSD: doterror.mk,v 1.2 2020/10/24 08:34:59 rillig Exp $
+# $NetBSD: doterror.mk,v 1.3 2023/06/01 20:56:35 rillig Exp $
.BEGIN:
@@ -17,4 +17,3 @@ happy:
sad:
@echo and now: $@; exit 1
-
diff --git a/contrib/bmake/unit-tests/error.exp b/contrib/bmake/unit-tests/error.exp
index 3adc099a4625..e782664498bf 100644
--- a/contrib/bmake/unit-tests/error.exp
+++ b/contrib/bmake/unit-tests/error.exp
@@ -1,6 +1,6 @@
-make: "error.mk" line 6: just FYI
-make: "error.mk" line 7: warning: this could be serious
-make: "error.mk" line 8: this is fatal
+make: "error.mk" line 7: just FYI
+make: "error.mk" line 9: warning: this could be serious
+make: "error.mk" line 11: this is fatal
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/error.mk b/contrib/bmake/unit-tests/error.mk
index 0029b3bc6aa9..2383e60da6fb 100644
--- a/contrib/bmake/unit-tests/error.mk
+++ b/contrib/bmake/unit-tests/error.mk
@@ -1,10 +1,13 @@
-# $NetBSD: error.mk,v 1.3 2020/11/03 17:38:45 rillig Exp $
+# $NetBSD: error.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Demonstrate that the .error directive exits immediately, without
# continuing parsing until the end of the file.
+# expect+1: just FYI
.info just FYI
+# expect+1: warning: this could be serious
.warning this could be serious
+# expect+1: this is fatal
.error this is fatal
.info this is not reached because of the .error above
diff --git a/contrib/bmake/unit-tests/export-env.mk b/contrib/bmake/unit-tests/export-env.mk
index 1605b1a71d61..80653f4bb3c9 100644
--- a/contrib/bmake/unit-tests/export-env.mk
+++ b/contrib/bmake/unit-tests/export-env.mk
@@ -1,4 +1,4 @@
-# $NetBSD: export-env.mk,v 1.4 2020/10/24 08:50:17 rillig Exp $
+# $NetBSD: export-env.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
# our normal .export, subsequent changes affect the environment
UT_TEST= this
@@ -21,7 +21,3 @@ UT_LIT= literal ${UT_TEST}
all:
@echo make:; ${UT_TEST UT_ENV UT_EXP UT_LIT:L:@v@echo $v=${$v};@}
@echo env:; ${UT_TEST UT_ENV UT_EXP UT_LIT:L:@v@echo $v=$${$v};@}
-
-
-
-
diff --git a/contrib/bmake/unit-tests/forsubst.exp b/contrib/bmake/unit-tests/forsubst.exp
deleted file mode 100644
index 0a98c00aff30..000000000000
--- a/contrib/bmake/unit-tests/forsubst.exp
+++ /dev/null
@@ -1,2 +0,0 @@
-.for with :S;... OK
-exit status 0
diff --git a/contrib/bmake/unit-tests/forsubst.mk b/contrib/bmake/unit-tests/forsubst.mk
deleted file mode 100644
index 9f293ab7f94e..000000000000
--- a/contrib/bmake/unit-tests/forsubst.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# $NetBSD: forsubst.mk,v 1.3 2020/11/03 17:59:27 rillig Exp $
-#
-# The parser used to break dependency lines at ';' without regard for
-# substitution patterns. Back then, the first ';' was interpreted as the
-# separator between the dependency and its commands. This (perhaps coupled
-# with the new handling of .for variables in ${:U<value>...) caused
-# interesting results for lines like:
-#
-# .for file in ${LIST}
-# for-subst: ${file:S;^;${here}/;g}
-# .endfor
-#
-# See the commit to unit-tests/forsubst (without the .mk) from 2009-10-07.
-
-all: for-subst
-
-here := ${.PARSEDIR}
-# this should not run foul of the parser
-.for file in ${.PARSEFILE}
-for-subst: ${file:S;^;${here}/;g}
- @echo ".for with :S;... OK"
-.endfor
diff --git a/contrib/bmake/unit-tests/include-main.exp b/contrib/bmake/unit-tests/include-main.exp
index f58870486f87..fcc38247109f 100644
--- a/contrib/bmake/unit-tests/include-main.exp
+++ b/contrib/bmake/unit-tests/include-main.exp
@@ -1,5 +1,5 @@
-make: "include-main.mk" line 14: main-before-ok
-make: "include-main.mk" line 21: main-before-for-ok
+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
@@ -7,11 +7,11 @@ 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:27
+ in include-main.mk:29
Parsing line 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
-make: "include-main.mk" line 30: main-after-ok
-make: "include-main.mk" line 37: main-after-for-ok
+make: "include-main.mk" line 33: main-after-ok
+make: "include-main.mk" line 41: main-after-for-ok
exit status 0
diff --git a/contrib/bmake/unit-tests/include-main.mk b/contrib/bmake/unit-tests/include-main.mk
index 50be0587348b..373bbdea1721 100644
--- a/contrib/bmake/unit-tests/include-main.mk
+++ b/contrib/bmake/unit-tests/include-main.mk
@@ -1,4 +1,4 @@
-# $NetBSD: include-main.mk,v 1.8 2023/01/19 23:26:14 rillig Exp $
+# $NetBSD: include-main.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Until 2020-09-05, the .INCLUDEDFROMFILE magic variable did not behave
# as described in the manual page.
@@ -11,6 +11,7 @@
# properly handle nested includes and even .for loops.
.if !defined(.INCLUDEDFROMFILE)
+# expect+1: main-before-ok
. info main-before-ok
.else
. warning main-before-fail(${.INCLUDEDFROMFILE})
@@ -18,6 +19,7 @@
.for i in once
. if !defined(.INCLUDEDFROMFILE)
+# expect+1: main-before-for-ok
. info main-before-for-ok
. else
. warning main-before-for-fail(${.INCLUDEDFROMFILE})
@@ -27,6 +29,7 @@
.include "include-sub.inc"
.if !defined(.INCLUDEDFROMFILE)
+# expect+1: main-after-ok
. info main-after-ok
.else
. warning main-after-fail(${.INCLUDEDFROMFILE})
@@ -34,6 +37,7 @@
.for i in once
. if !defined(.INCLUDEDFROMFILE)
+# expect+1: main-after-for-ok
. info main-after-for-ok
. else
. warning main-after-for-fail(${.INCLUDEDFROMFILE})
diff --git a/contrib/bmake/unit-tests/modmatch.exp b/contrib/bmake/unit-tests/modmatch.exp
deleted file mode 100644
index fcaf6c02ed69..000000000000
--- a/contrib/bmake/unit-tests/modmatch.exp
+++ /dev/null
@@ -1,17 +0,0 @@
-LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a"
-LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a"
-LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A"
-LIB=b X_LIBS:M${LIB${LIB:tu}} is ""
-LIB=b X_LIBS:M*/lib${LIB}.a is ""
-LIB=b X_LIBS:M*/lib${LIB}.a:tu is ""
-LIB=c X_LIBS:M${LIB${LIB:tu}} is ""
-LIB=c X_LIBS:M*/lib${LIB}.a is ""
-LIB=c X_LIBS:M*/lib${LIB}.a:tu is ""
-LIB=d X_LIBS:M${LIB${LIB:tu}} is "/tmp/libd.a"
-LIB=d X_LIBS:M*/lib${LIB}.a is "/tmp/libd.a"
-LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A"
-LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a"
-LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a"
-LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A"
-Mscanner=OK
-exit status 0
diff --git a/contrib/bmake/unit-tests/modmatch.mk b/contrib/bmake/unit-tests/modmatch.mk
deleted file mode 100644
index 7dcacf09da6d..000000000000
--- a/contrib/bmake/unit-tests/modmatch.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# $NetBSD: modmatch.mk,v 1.9 2020/10/24 08:50:17 rillig Exp $
-#
-# Tests for the :M and :S modifiers.
-
-X= a b c d e
-
-.for x in $X
-LIB${x:tu}= /tmp/lib$x.a
-.endfor
-
-X_LIBS= ${LIBA} ${LIBD} ${LIBE}
-
-LIB?= a
-
-var= head
-res= no
-.if !empty(var:M${:Uhead\:tail:C/:.*//})
-res= OK
-.endif
-
-all: show-libs
-
-show-libs:
- @for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done
- @echo "Mscanner=${res}"
-
-show:
- @echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is "${X_LIBS:M${LIB${LIB:tu}}}"'
- @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"'
- @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"'
diff --git a/contrib/bmake/unit-tests/modmisc.exp b/contrib/bmake/unit-tests/modmisc.exp
index 10475e65ee0f..f243511ab491 100644
--- a/contrib/bmake/unit-tests/modmisc.exp
+++ b/contrib/bmake/unit-tests/modmisc.exp
@@ -6,7 +6,6 @@ path='/bin':'/tmp':'/':'/no/such/dir'
path_/usr/xbin=/opt/xbin/
paths=/bin /tmp / /no/such/dir /opt/xbin
PATHS=/BIN /TMP / /NO/SUCH/DIR /OPT/XBIN
-The answer is 42
S:
C:
@:
diff --git a/contrib/bmake/unit-tests/modmisc.mk b/contrib/bmake/unit-tests/modmisc.mk
index 9ace35c15162..4868abef92f1 100644
--- a/contrib/bmake/unit-tests/modmisc.mk
+++ b/contrib/bmake/unit-tests/modmisc.mk
@@ -1,4 +1,4 @@
-# $NetBSD: modmisc.mk,v 1.52 2020/12/20 19:29:06 rillig Exp $
+# $NetBSD: modmisc.mk,v 1.53 2023/06/16 07:20:45 rillig Exp $
#
# miscellaneous modifier tests
@@ -15,14 +15,10 @@ MOD_HOMES= S,/home/,/homes/,
MOD_OPT= @d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@
MOD_SEP= S,:, ,g
-all: modvar modvarloop modsysv emptyvar undefvar
+all: modvar modvarloop emptyvar undefvar
all: mod-quote
all: mod-break-many-words
-# See also sysv.mk.
-modsysv:
- @echo "The answer is ${libfoo.a:L:libfoo.a=42}"
-
# Demonstrates modifiers that are given indirectly from a variable.
modvar:
@echo "path='${path}'"
@@ -60,6 +56,6 @@ undefvar:
mod-quote:
@echo $@: new${.newline:Q}${.newline:Q}line
-# Cover the bmake_realloc in Str_Words.
+# Cover the bmake_realloc in Substring_Words.
mod-break-many-words:
@echo $@: ${UNDEF:U:range=500:[#]}
diff --git a/contrib/bmake/unit-tests/opt-debug-file.exp b/contrib/bmake/unit-tests/opt-debug-file.exp
index 712686f60b3c..8bdaca612310 100644
--- a/contrib/bmake/unit-tests/opt-debug-file.exp
+++ b/contrib/bmake/unit-tests/opt-debug-file.exp
@@ -1,6 +1,6 @@
-make: "opt-debug-file.mk" line 43: This goes to stderr only, once.
-make: "opt-debug-file.mk" line 45: This goes to stderr only, once.
-make: "opt-debug-file.mk" line 47: This goes to stderr, and in addition to the debug log.
+make: "opt-debug-file.mk" line 44: This goes to stderr only, once.
+make: "opt-debug-file.mk" line 47: This goes to stderr only, once.
+make: "opt-debug-file.mk" line 50: This goes to stderr, and in addition to the debug log.
CondParser_Eval: ${:!cat opt-debug-file.debuglog!:Maddition:[#]} != 1
Comparing 1.000000 != 1.000000
make: Missing delimiter for modifier ':S'
diff --git a/contrib/bmake/unit-tests/opt-debug-file.mk b/contrib/bmake/unit-tests/opt-debug-file.mk
index b878c2bcf734..a8190b2f1b50 100644
--- a/contrib/bmake/unit-tests/opt-debug-file.mk
+++ b/contrib/bmake/unit-tests/opt-debug-file.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-file.mk,v 1.8 2022/01/11 19:47:34 rillig Exp $
+# $NetBSD: opt-debug-file.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the -dF command line option, which redirects the debug log
# to a file instead of writing it to stderr.
@@ -40,10 +40,13 @@ DEBUG_OUTPUT:= ${:!cat opt-debug-file.debuglog!}
# See Parse_Error.
.MAKEFLAGS: -dFstdout
+# expect+1: This goes to stderr only, once.
. info This goes to stderr only, once.
.MAKEFLAGS: -dFstderr
+# expect+1: This goes to stderr only, once.
. info This goes to stderr only, once.
.MAKEFLAGS: -dFopt-debug-file.debuglog
+# expect+1: This goes to stderr, and in addition to the debug log.
. info This goes to stderr, and in addition to the debug log.
.MAKEFLAGS: -dFstderr -d0c
.if ${:!cat opt-debug-file.debuglog!:Maddition:[#]} != 1
diff --git a/contrib/bmake/unit-tests/opt-debug-for.exp b/contrib/bmake/unit-tests/opt-debug-for.exp
index ea811b9bfcf5..a8f63b85fec3 100644
--- a/contrib/bmake/unit-tests/opt-debug-for.exp
+++ b/contrib/bmake/unit-tests/opt-debug-for.exp
@@ -1,22 +1,22 @@
For: new loop 2
For: end for 2
For: end for 1
-For: loop body:
+For: loop body with outer = a:
. for inner in 1 2
VAR.${:Ua}${inner}= value
. endfor
For: end for 1
-For: loop body:
+For: loop body with inner = 1:
VAR.${:Ua}${:U1}= value
-For: loop body:
+For: loop body with inner = 2:
VAR.${:Ua}${:U2}= value
-For: loop body:
+For: loop body with outer = b:
. for inner in 1 2
VAR.${:Ub}${inner}= value
. endfor
For: end for 1
-For: loop body:
+For: loop body with inner = 1:
VAR.${:Ub}${:U1}= value
-For: loop body:
+For: loop body with inner = 2:
VAR.${:Ub}${:U2}= value
exit status 0
diff --git a/contrib/bmake/unit-tests/opt-debug-hash.exp b/contrib/bmake/unit-tests/opt-debug-hash.exp
index b239399ec44d..194b08daa5f2 100644
--- a/contrib/bmake/unit-tests/opt-debug-hash.exp
+++ b/contrib/bmake/unit-tests/opt-debug-hash.exp
@@ -1,4 +1,4 @@
-make: "opt-debug-hash.mk" line 11: Missing argument for ".error"
+make: "opt-debug-hash.mk" line 12: Missing argument for ".error"
make: Fatal errors encountered -- cannot continue
HashTable targets: size=16 numEntries=0 maxchain=0
HashTable Global variables: size=16 numEntries=<entries> maxchain=3
diff --git a/contrib/bmake/unit-tests/opt-debug-hash.mk b/contrib/bmake/unit-tests/opt-debug-hash.mk
index 8b757ff3f290..a1b21e145bf0 100644
--- a/contrib/bmake/unit-tests/opt-debug-hash.mk
+++ b/contrib/bmake/unit-tests/opt-debug-hash.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-hash.mk,v 1.3 2022/01/22 18:59:24 rillig Exp $
+# $NetBSD: opt-debug-hash.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the -dh command line option, which adds debug logging for
# hash tables. Even more detailed logging is available by compiling
@@ -8,4 +8,5 @@
# Force a parse error, to demonstrate the newline character in the diagnostic
# that had been missing before parse.c 1.655 from 2022-01-22.
+# expect+1: Missing argument for ".error"
.error
diff --git a/contrib/bmake/unit-tests/opt-debug-lint.exp b/contrib/bmake/unit-tests/opt-debug-lint.exp
index 83643e9a8772..5a6510bd029a 100644
--- a/contrib/bmake/unit-tests/opt-debug-lint.exp
+++ b/contrib/bmake/unit-tests/opt-debug-lint.exp
@@ -1,10 +1,10 @@
-make: "opt-debug-lint.mk" line 19: Variable "X" is undefined
-make: "opt-debug-lint.mk" line 19: Malformed conditional ($X)
-make: "opt-debug-lint.mk" line 41: Variable "UNDEF" is undefined
-make: "opt-debug-lint.mk" line 41: Malformed conditional (${UNDEF})
-make: "opt-debug-lint.mk" line 61: Missing delimiter ':' after modifier "L"
-make: "opt-debug-lint.mk" line 61: Missing delimiter ':' after modifier "P"
-make: "opt-debug-lint.mk" line 69: Unknown modifier "${"
+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: Missing delimiter ':' after modifier "L"
+make: "opt-debug-lint.mk" line 67: Missing delimiter ':' after modifier "P"
+make: "opt-debug-lint.mk" line 76: Unknown modifier "${"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/opt-debug-lint.mk b/contrib/bmake/unit-tests/opt-debug-lint.mk
index 155e1a3de3be..0fcaf8b102ad 100644
--- a/contrib/bmake/unit-tests/opt-debug-lint.mk
+++ b/contrib/bmake/unit-tests/opt-debug-lint.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-lint.mk,v 1.14 2021/03/14 10:57:12 rillig Exp $
+# $NetBSD: opt-debug-lint.mk,v 1.15 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the -dL command line option, which runs additional checks
# to catch common mistakes, such as unclosed variable expressions.
@@ -16,6 +16,8 @@
#
# See also:
# cond-undef-lint.mk
+# expect+2: Malformed conditional ($X)
+# expect+1: Variable "X" is undefined
.if $X
. error
.endif
@@ -38,6 +40,8 @@
# 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
.endif
@@ -58,6 +62,8 @@ ${UNDEF}: ${UNDEF}
# Since 2020-10-03, in lint mode the variable modifier must be separated
# by colons. See varparse-mod.mk.
+# expect+2: Missing delimiter ':' after modifier "L"
+# expect+1: Missing delimiter ':' after modifier "P"
.if ${value:LPL} != "value"
. error
.endif
@@ -66,6 +72,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: Unknown modifier "${"
.if ${value:${:UL}PL} != "LPL}" # FIXME: "LPL}" is unexpected here.
. error ${value:${:UL}PL}
.endif
diff --git a/contrib/bmake/unit-tests/opt-debug-parse.exp b/contrib/bmake/unit-tests/opt-debug-parse.exp
index 0e11024647a1..811c6b45dce5 100644
--- a/contrib/bmake/unit-tests/opt-debug-parse.exp
+++ b/contrib/bmake/unit-tests/opt-debug-parse.exp
@@ -1,26 +1,26 @@
Parse_PushInput: .for loop in opt-debug-parse.mk, line 16
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 20: .info trace with multi-line .for loop head
-make: "opt-debug-parse.mk" line 20: trace with multi-line .for loop head
+Parsing line 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 22
+ParseEOF: returning to file opt-debug-parse.mk, line 23
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 25: .include "/dev/null"
+Parsing line 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 26
+ParseEOF: returning to file opt-debug-parse.mk, line 27
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parse_PushInput: .for loop in opt-debug-parse.mk, line 30
+Parse_PushInput: .for loop in opt-debug-parse.mk, line 31
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk'
-Parsing line 31: .info trace
-make: "opt-debug-parse.mk" line 31: trace
- in .for loop from opt-debug-parse.mk:30 with a = 1, b = 2, c = 3
-Parsing line 31: .info trace
-make: "opt-debug-parse.mk" line 31: trace
- in .for loop from opt-debug-parse.mk:30 with a = 4, b = 5, c = 6
-ParseEOF: returning to file opt-debug-parse.mk, line 33
+Parsing line 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
+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 35: .MAKEFLAGS: -d0
+Parsing line 38: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
exit status 0
diff --git a/contrib/bmake/unit-tests/opt-debug-parse.mk b/contrib/bmake/unit-tests/opt-debug-parse.mk
index 9517bb62b976..347537015b52 100644
--- a/contrib/bmake/unit-tests/opt-debug-parse.mk
+++ b/contrib/bmake/unit-tests/opt-debug-parse.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-parse.mk,v 1.7 2022/02/09 21:09:24 rillig Exp $
+# $NetBSD: opt-debug-parse.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the -dp command line option, which adds debug logging about
# makefile parsing.
@@ -17,6 +17,7 @@
var \
in \
value
+# expect+1: trace with multi-line .for loop head
.info trace with multi-line .for loop head
.endfor
@@ -28,6 +29,8 @@
# In .for loops with multiple variables, the variable details are included in
# the stack trace, just as with a single variable.
.for a b c in 1 2 3 ${:U4 5 6}
+# expect+2: trace
+# expect+1: trace
.info trace
.endfor
diff --git a/contrib/bmake/unit-tests/opt-warnings-as-errors.exp b/contrib/bmake/unit-tests/opt-warnings-as-errors.exp
index 1db56b753bed..87d1db249a20 100644
--- a/contrib/bmake/unit-tests/opt-warnings-as-errors.exp
+++ b/contrib/bmake/unit-tests/opt-warnings-as-errors.exp
@@ -1,6 +1,6 @@
-make: "opt-warnings-as-errors.mk" line 12: warning: message 1
+make: "opt-warnings-as-errors.mk" line 13: warning: message 1
make: parsing warnings being treated as errors
-make: "opt-warnings-as-errors.mk" line 13: warning: message 2
+make: "opt-warnings-as-errors.mk" line 15: warning: message 2
parsing continues
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
diff --git a/contrib/bmake/unit-tests/opt-warnings-as-errors.mk b/contrib/bmake/unit-tests/opt-warnings-as-errors.mk
index c29343f960a7..3896dad10f1a 100644
--- a/contrib/bmake/unit-tests/opt-warnings-as-errors.mk
+++ b/contrib/bmake/unit-tests/opt-warnings-as-errors.mk
@@ -1,4 +1,4 @@
-# $NetBSD: opt-warnings-as-errors.mk,v 1.5 2021/01/27 00:02:38 rillig Exp $
+# $NetBSD: opt-warnings-as-errors.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the -W command line option, which turns warnings into errors.
#
@@ -9,7 +9,9 @@
.MAKEFLAGS: -W
+# expect+1: warning: message 1
.warning message 1
+# expect+1: warning: message 2
.warning message 2
_!= echo 'parsing continues' 1>&2
diff --git a/contrib/bmake/unit-tests/parse.exp b/contrib/bmake/unit-tests/parse.exp
index a11de0c194ae..694e35e3b6e2 100644
--- a/contrib/bmake/unit-tests/parse.exp
+++ b/contrib/bmake/unit-tests/parse.exp
@@ -1,6 +1,6 @@
make: "parse.mk" line 7: Makefile appears to contain unresolved CVS/RCS/??? merge conflicts
make: "parse.mk" line 14: Makefile appears to contain unresolved CVS/RCS/??? merge conflicts
-make: "parse.mk" line 24: Invalid line type
+make: "parse.mk" line 25: Invalid line type
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/parse.mk b/contrib/bmake/unit-tests/parse.mk
index 551dc98aaf24..296c19f5cd99 100644
--- a/contrib/bmake/unit-tests/parse.mk
+++ b/contrib/bmake/unit-tests/parse.mk
@@ -1,4 +1,4 @@
-# $NetBSD: parse.mk,v 1.4 2023/04/28 13:09:48 rillig Exp $
+# $NetBSD: parse.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Test those parts of the parsing that do not belong in any of the other
# categories.
@@ -21,6 +21,7 @@
# the expanded line's terminating '\0'.
#
# https://bugs.freebsd.org/265119
+# expect+1: Invalid line type
one-target ${:U }
diff --git a/contrib/bmake/unit-tests/recursive.exp b/contrib/bmake/unit-tests/recursive.exp
index 36cd1c989532..dc50fe034969 100644
--- a/contrib/bmake/unit-tests/recursive.exp
+++ b/contrib/bmake/unit-tests/recursive.exp
@@ -1,5 +1,5 @@
-make: "recursive.mk" line 36: Unclosed variable "MISSING_PAREN"
-make: "recursive.mk" line 37: Unclosed variable "MISSING_BRACE"
+make: "recursive.mk" line 37: Unclosed variable "MISSING_PAREN"
+make: "recursive.mk" line 39: Unclosed variable "MISSING_BRACE"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/recursive.mk b/contrib/bmake/unit-tests/recursive.mk
index 5265cec59a2d..307515d70a08 100644
--- a/contrib/bmake/unit-tests/recursive.mk
+++ b/contrib/bmake/unit-tests/recursive.mk
@@ -1,4 +1,4 @@
-# $NetBSD: recursive.mk,v 1.5 2021/03/15 12:15:03 rillig Exp $
+# $NetBSD: recursive.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# In -dL mode, a variable may get expanded before it makes sense.
# This would stop make from doing anything since the "recursive" error
@@ -33,6 +33,8 @@ AM_DEFAULT_VERBOSITY= 1
# therefore that's acceptable. In most practical cases, the missing
# brace would be detected directly in the line where it is produced.
MISSING_BRACE_INDIRECT:= ${:U\${MISSING_BRACE}
+# expect+1: Unclosed variable "MISSING_PAREN"
UNCLOSED= $(MISSING_PAREN
+# expect+1: Unclosed variable "MISSING_BRACE"
UNCLOSED= ${MISSING_BRACE
UNCLOSED= ${MISSING_BRACE_INDIRECT}
diff --git a/contrib/bmake/unit-tests/var-eval-short.exp b/contrib/bmake/unit-tests/var-eval-short.exp
index ea6e0d7485f9..14e3d372f198 100644
--- a/contrib/bmake/unit-tests/var-eval-short.exp
+++ b/contrib/bmake/unit-tests/var-eval-short.exp
@@ -1,5 +1,5 @@
-make: "var-eval-short.mk" line 44: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar
-make: "var-eval-short.mk" line 44: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
+make: "var-eval-short.mk" line 46: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar
+make: "var-eval-short.mk" line 46: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
CondParser_Eval: 0 && ${0:?${FAIL}then:${FAIL}else}
Var_Parse: ${0:?${FAIL}then:${FAIL}else} (parse-only)
Parsing modifier ${0:?...}
@@ -8,7 +8,7 @@ Modifier part: "${FAIL}then"
Var_Parse: ${FAIL}else} (parse-only)
Modifier part: "${FAIL}else"
Result of ${0:?${FAIL}then:${FAIL}else} is "" (parse-only, defined)
-Parsing line 165: DEFINED= defined
+Parsing line 167: DEFINED= defined
Global: DEFINED = defined
CondParser_Eval: 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
Var_Parse: ${DEFINED:L:?${FAIL}then:${FAIL}else} (parse-only)
@@ -20,7 +20,7 @@ Modifier part: "${FAIL}then"
Var_Parse: ${FAIL}else} (parse-only)
Modifier part: "${FAIL}else"
Result of ${DEFINED:?${FAIL}then:${FAIL}else} is "defined" (parse-only, regular)
-Parsing line 168: .MAKEFLAGS: -d0
+Parsing line 170: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
Global: .MAKEFLAGS = -r -k -d cpv -d
Global: .MAKEFLAGS = -r -k -d cpv -d 0
diff --git a/contrib/bmake/unit-tests/var-eval-short.mk b/contrib/bmake/unit-tests/var-eval-short.mk
index 7faf1cc5d154..aa8bf79decec 100644
--- a/contrib/bmake/unit-tests/var-eval-short.mk
+++ b/contrib/bmake/unit-tests/var-eval-short.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-eval-short.mk,v 1.9 2023/05/09 16:27:00 rillig Exp $
+# $NetBSD: var-eval-short.mk,v 1.10 2023/06/01 20:56:35 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,6 +41,8 @@ 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: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar
+# expect+1: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
.if 0 && ${:Uword:@${FAIL}@expr@}
.endif
diff --git a/contrib/bmake/unit-tests/var-op-append.mk b/contrib/bmake/unit-tests/var-op-append.mk
index 420ee376b75d..5f06fd887332 100644
--- a/contrib/bmake/unit-tests/var-op-append.mk
+++ b/contrib/bmake/unit-tests/var-op-append.mk
@@ -1,7 +1,20 @@
-# $NetBSD: var-op-append.mk,v 1.9 2021/04/04 10:13:09 rillig Exp $
+# $NetBSD: var-op-append.mk,v 1.10 2023/06/21 07:30:50 rillig Exp $
#
-# Tests for the += variable assignment operator, which appends to a variable,
-# creating it if necessary.
+# Tests for the '+=' variable assignment operator, which appends to a
+# variable, creating it if necessary.
+#
+# See also
+# var-op.mk
+#
+# Standards
+# The '+=' variable assignment operator is planned to be added in
+# POSIX.1-202x.
+#
+# This implementation does not support the immediate-expansion macros
+# specified in POSIX.1-202x. All variables are delayed-expansion.
+#
+# History
+# The '+=' variable assignment operator was added before 1993-03-21.
# Appending to an undefined variable is possible.
# The variable is created, and no extra space is added before the value.
diff --git a/contrib/bmake/unit-tests/var-op-assign.exp b/contrib/bmake/unit-tests/var-op-assign.exp
index 73e580403d78..593dfa4b904b 100644
--- a/contrib/bmake/unit-tests/var-op-assign.exp
+++ b/contrib/bmake/unit-tests/var-op-assign.exp
@@ -1,6 +1,6 @@
this will be evaluated later
-make: "var-op-assign.mk" line 59: Invalid line type
-make: "var-op-assign.mk" line 93: Parsing still continues until here.
+make: "var-op-assign.mk" line 60: Invalid line type
+make: "var-op-assign.mk" line 95: Parsing still continues until here.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/var-op-assign.mk b/contrib/bmake/unit-tests/var-op-assign.mk
index 18ecf8d0d5ed..0a1c686fe5c5 100644
--- a/contrib/bmake/unit-tests/var-op-assign.mk
+++ b/contrib/bmake/unit-tests/var-op-assign.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-assign.mk,v 1.8 2021/03/15 19:15:04 rillig Exp $
+# $NetBSD: var-op-assign.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the = variable assignment operator, which overwrites an existing
# variable or creates it.
@@ -56,6 +56,7 @@ VAR= ${:! echo 'this will be evaluated later' 1>&2 !}
# In a variable assignment, the variable name must consist of a single word.
# The following line therefore generates a parse error.
+# expect+1: Invalid line type
VARIABLE NAME= variable value
# But if the whitespace appears inside parentheses or braces, everything is
@@ -90,6 +91,7 @@ VARNAME_BRACES= VAR{spaces in braces}
# unexpected variable values.
#
# Therefore, just output an info message.
+# expect+1: Parsing still continues until here.
.info Parsing still continues until here.
all:
diff --git a/contrib/bmake/unit-tests/var-op-expand.exp b/contrib/bmake/unit-tests/var-op-expand.exp
index 4916336c0400..5ea4e6b6954c 100644
--- a/contrib/bmake/unit-tests/var-op-expand.exp
+++ b/contrib/bmake/unit-tests/var-op-expand.exp
@@ -1,7 +1,7 @@
make: "var-op-expand.mk" line 274: Unknown modifier "s,value,replaced,"
-make: "var-op-expand.mk" line 277: warning: XXX Neither branch should be taken.
-make: "var-op-expand.mk" line 282: Unknown modifier "s,value,replaced,"
-make: "var-op-expand.mk" line 283: warning: XXX Neither branch should be taken.
+make: "var-op-expand.mk" line 278: warning: XXX Neither branch should be taken.
+make: "var-op-expand.mk" line 283: Unknown modifier "s,value,replaced,"
+make: "var-op-expand.mk" line 285: warning: XXX Neither branch should be taken.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/var-op-expand.mk b/contrib/bmake/unit-tests/var-op-expand.mk
index f89aa6fa4b56..a0b9cc475404 100644
--- a/contrib/bmake/unit-tests/var-op-expand.mk
+++ b/contrib/bmake/unit-tests/var-op-expand.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-expand.mk,v 1.17 2022/09/08 20:23:45 rillig Exp $
+# $NetBSD: var-op-expand.mk,v 1.18 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the := variable assignment operator, which expands its
# right-hand side.
@@ -274,12 +274,14 @@ indirect:= ${INDIRECT:tl}
.if ${indirect} != " ok "
. error
.else
+# expect+1: warning: XXX Neither branch should be taken.
. warning XXX Neither branch should be taken.
.endif
LATER= uppercase-value
later= lowercase-value
# 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.
.else
. error
diff --git a/contrib/bmake/unit-tests/var-op-shell.exp b/contrib/bmake/unit-tests/var-op-shell.exp
index 0e9bd2cbc35a..0837cd4f832e 100644
--- a/contrib/bmake/unit-tests/var-op-shell.exp
+++ b/contrib/bmake/unit-tests/var-op-shell.exp
@@ -1,8 +1,8 @@
-make: "var-op-shell.mk" line 31: warning: "echo "failed"; false" returned non-zero status
-make: "var-op-shell.mk" line 37: warning: "false" returned non-zero status
-make: "var-op-shell.mk" line 59: warning: "kill $$" exited on a signal
+make: "var-op-shell.mk" line 32: warning: "echo "failed"; false" returned non-zero status
+make: "var-op-shell.mk" line 39: warning: "false" returned non-zero status
+make: "var-op-shell.mk" line 62: warning: "kill $$" exited on a signal
/bin/no/such/command: not found
-make: "var-op-shell.mk" line 65: warning: "/bin/no/such/command" returned non-zero status
+make: "var-op-shell.mk" line 69: warning: "/bin/no/such/command" returned non-zero status
stderr
Capturing the output of command "echo '$$$$'"
Global: OUTPUT = $$$$
diff --git a/contrib/bmake/unit-tests/var-op-shell.mk b/contrib/bmake/unit-tests/var-op-shell.mk
index bd2a48f17cc4..de26bff94905 100644
--- a/contrib/bmake/unit-tests/var-op-shell.mk
+++ b/contrib/bmake/unit-tests/var-op-shell.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-shell.mk,v 1.6 2022/01/10 20:32:29 rillig Exp $
+# $NetBSD: var-op-shell.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the != variable assignment operator, which runs its right-hand
# side through the shell.
@@ -28,12 +28,14 @@ OUTPUT!= true
# '::!=', expression modifier ':!...!'), a failed command generates only a
# warning, not an "error". These "errors" are ignored in default mode, for
# compatibility, but not in lint mode (-dL).
+# expect+1: warning: "echo "failed"; false" returned non-zero status
OUTPUT!= echo "failed"; false
.if ${OUTPUT} != "failed"
. error
.endif
# A command with empty output may fail as well.
+# expect+1: warning: "false" returned non-zero status
OUTPUT!= false
.if ${OUTPUT} != ""
. error
@@ -56,12 +58,14 @@ OUTPUT!= echo "before"; false; echo "after"
# This should result in a warning about "exited on a signal".
# This used to be kill -14 (SIGALRM), but that stopped working on
# Darwin18 after recent update.
+# expect+1: warning: "kill $$" exited on a signal
OUTPUT!= kill $$$$
.if ${OUTPUT} != ""
. error
.endif
# A nonexistent command produces a non-zero exit status.
+# expect+1: warning: "/bin/no/such/command" returned non-zero status
OUTPUT!= /bin/no/such/command
.if ${OUTPUT} != ""
. error
diff --git a/contrib/bmake/unit-tests/var-readonly.mk b/contrib/bmake/unit-tests/var-readonly.mk
index 43799e4adb5c..050b44d1b4e8 100644
--- a/contrib/bmake/unit-tests/var-readonly.mk
+++ b/contrib/bmake/unit-tests/var-readonly.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-readonly.mk,v 1.1 2023/01/24 00:20:00 sjg Exp $
+# $NetBSD: var-readonly.mk,v 1.3 2023/06/19 15:37:48 sjg Exp $
# the answer
N = 42
@@ -9,6 +9,12 @@ N = 666
.error N ($N) should be 42
.endif
+# undef should fail
+.undef N
+.ifndef N
+.error N should not be undef'd
+.endif
+
.NOREADONLY: N
# now we can change it
N = 69
@@ -17,4 +23,3 @@ N = 69
.endif
all:
-
diff --git a/contrib/bmake/unit-tests/var-recursive.exp b/contrib/bmake/unit-tests/var-recursive.exp
index 44c381f94ff9..2158286749f3 100644
--- a/contrib/bmake/unit-tests/var-recursive.exp
+++ b/contrib/bmake/unit-tests/var-recursive.exp
@@ -1,19 +1,19 @@
-make: "var-recursive.mk" line 20: still there
+make: "var-recursive.mk" line 21: still there
Variable DIRECT is recursive.
- in var-recursive.mk:21
+ in var-recursive.mk:22
make: stopped in unit-tests
Variable INDIRECT1 is recursive.
- in var-recursive.mk:28
+ in var-recursive.mk:29
make: stopped in unit-tests
-make: "var-recursive.mk" line 35: ok
+make: "var-recursive.mk" line 37: ok
Variable V is recursive.
- in var-recursive.mk:43
+ in var-recursive.mk:45
make: stopped in unit-tests
: OK
-In a command near "var-recursive.mk" line 55: Variable VAR is recursive.
+In a command near "var-recursive.mk" line 57: Variable VAR is recursive.
make: stopped in unit-tests
exit status 0
diff --git a/contrib/bmake/unit-tests/var-recursive.mk b/contrib/bmake/unit-tests/var-recursive.mk
index 1825c8a63120..998d0d8c312a 100644
--- a/contrib/bmake/unit-tests/var-recursive.mk
+++ b/contrib/bmake/unit-tests/var-recursive.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-recursive.mk,v 1.4 2022/01/29 10:21:26 rillig Exp $
+# $NetBSD: var-recursive.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for variable expressions that refer to themselves and thus
# cannot be evaluated.
@@ -17,6 +17,7 @@ all:
.elif ${TEST} == direct
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.
@@ -32,6 +33,7 @@ INDIRECT2= ${INDIRECT1}
# The variable refers to itself, but only in the branch of a condition that
# is never satisfied and is thus not evaluated.
CONDITIONAL= ${1:?ok:${CONDITIONAL}}
+# expect+1: ok
. info ${CONDITIONAL}
.elif ${TEST} == short
diff --git a/contrib/bmake/unit-tests/var-scope-cmdline.exp b/contrib/bmake/unit-tests/var-scope-cmdline.exp
index 281b5af291ca..c663a9069a9f 100644
--- a/contrib/bmake/unit-tests/var-scope-cmdline.exp
+++ b/contrib/bmake/unit-tests/var-scope-cmdline.exp
@@ -1,4 +1,4 @@
-make: "var-scope-cmdline.mk" line 71: global
-make: "var-scope-cmdline.mk" line 80: makeflags
+make: "var-scope-cmdline.mk" line 72: global
+make: "var-scope-cmdline.mk" line 82: makeflags
makeflags
exit status 0
diff --git a/contrib/bmake/unit-tests/var-scope-cmdline.mk b/contrib/bmake/unit-tests/var-scope-cmdline.mk
index fbfb2d0290a4..eaa2c58347ae 100644
--- a/contrib/bmake/unit-tests/var-scope-cmdline.mk
+++ b/contrib/bmake/unit-tests/var-scope-cmdline.mk
@@ -1,4 +1,4 @@
-# $NetBSD: var-scope-cmdline.mk,v 1.2 2023/04/07 05:54:16 rillig Exp $
+# $NetBSD: var-scope-cmdline.mk,v 1.3 2023/06/01 20:56:35 rillig Exp $
#
# Tests for variables specified on the command line.
#
@@ -68,6 +68,7 @@
# A normal global variable, without any cmdline variable nearby.
VAR= global
+# expect+1: global
.info ${VAR}
# The global variable is "overridden" by simply deleting it and then
@@ -77,6 +78,7 @@ VAR= global
#
# See varmod-loop.mk for a non-obvious way to undefine a cmdline variable.
.MAKEFLAGS: VAR=makeflags
+# expect+1: makeflags
.info ${VAR}
# If Var_SetWithFlags should ever forget to delete the global variable,
diff --git a/contrib/bmake/unit-tests/vardebug.exp b/contrib/bmake/unit-tests/vardebug.exp
index 19e5c9c9fdd0..a668807b94e3 100644
--- a/contrib/bmake/unit-tests/vardebug.exp
+++ b/contrib/bmake/unit-tests/vardebug.exp
@@ -54,11 +54,11 @@ 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 44: Unknown modifier "unknown"
+make: "vardebug.mk" line 46: Unknown modifier "unknown"
Result of ${:unknown} is error (eval-defined, defined)
-make: "vardebug.mk" line 44: Malformed conditional (${:Uvariable:unknown})
+make: "vardebug.mk" line 46: Malformed conditional (${:Uvariable:unknown})
Var_Parse: ${UNDEFINED} (eval-defined)
-make: "vardebug.mk" line 53: Malformed conditional (${UNDEFINED})
+make: "vardebug.mk" line 56: Malformed conditional (${UNDEFINED})
Global: delete .SHELL (not found)
Command: .SHELL = </path/to/shell>
Command: .SHELL = overwritten ignored (read-only)
diff --git a/contrib/bmake/unit-tests/vardebug.mk b/contrib/bmake/unit-tests/vardebug.mk
index 4a16a7f2797f..34015aa71db9 100644
--- a/contrib/bmake/unit-tests/vardebug.mk
+++ b/contrib/bmake/unit-tests/vardebug.mk
@@ -1,4 +1,4 @@
-# $NetBSD: vardebug.mk,v 1.7 2021/02/04 21:42:47 rillig Exp $
+# $NetBSD: vardebug.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Demonstrates the debugging output for var.c.
@@ -41,6 +41,8 @@ VAR+= 3
# When ApplyModifiers results in an error, this appears in the debug log
# as "is error", without surrounding quotes.
+# expect+2: Malformed conditional (${:Uvariable:unknown})
+# expect+1: Unknown modifier "unknown"
.if ${:Uvariable:unknown}
.endif
@@ -50,6 +52,7 @@ VAR+= 3
# 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})
.if ${UNDEFINED}
.endif
diff --git a/contrib/bmake/unit-tests/varmod-assign-shell.exp b/contrib/bmake/unit-tests/varmod-assign-shell.exp
index 7bb41108cb62..b7c6cd223f24 100644
--- a/contrib/bmake/unit-tests/varmod-assign-shell.exp
+++ b/contrib/bmake/unit-tests/varmod-assign-shell.exp
@@ -1,4 +1,4 @@
-make: "varmod-assign-shell.mk" line 27: warning: "echo output; false" returned non-zero status
+make: "varmod-assign-shell.mk" line 28: warning: "echo output; false" returned non-zero status
Global: _ = # (empty)
Var_Parse: ${ASSIGNED::!=echo output; ${:Ufalse}} (eval-keep-dollar-and-undefined)
Evaluating modifier ${ASSIGNED::...} on value "previous" (eval-keep-dollar-and-undefined, regular)
diff --git a/contrib/bmake/unit-tests/varmod-assign-shell.mk b/contrib/bmake/unit-tests/varmod-assign-shell.mk
index d03692942d5b..6158bac14eaa 100644
--- a/contrib/bmake/unit-tests/varmod-assign-shell.mk
+++ b/contrib/bmake/unit-tests/varmod-assign-shell.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-assign-shell.mk,v 1.4 2022/01/10 20:32:29 rillig Exp $
+# $NetBSD: varmod-assign-shell.mk,v 1.5 2023/06/01 20:56:35 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
@@ -24,6 +24,7 @@
# assignment operator '!=' is another unnecessary inconsistency.
DIRECT= previous
+# expect+1: warning: "echo output; false" returned non-zero status
DIRECT!= echo output; false
ASSIGNED= previous
diff --git a/contrib/bmake/unit-tests/varmod-edge.exp b/contrib/bmake/unit-tests/varmod-edge.exp
index d9db72b2e2ef..92204d8e1840 100644
--- a/contrib/bmake/unit-tests/varmod-edge.exp
+++ b/contrib/bmake/unit-tests/varmod-edge.exp
@@ -1,27 +1,27 @@
-make: "varmod-edge.mk" line 166: ok M-paren
-make: "varmod-edge.mk" line 166: ok M-mixed
-make: "varmod-edge.mk" line 166: ok M-unescape
+make: "varmod-edge.mk" line 184: ok M-paren
+make: "varmod-edge.mk" line 184: ok M-mixed
+make: "varmod-edge.mk" line 184: ok M-unescape
make: Unclosed variable expression, expecting '}' for modifier "U*)" of variable "" with value "*)"
-make: "varmod-edge.mk" line 166: ok M-nest-mix
-make: "varmod-edge.mk" line 166: ok M-nest-brk
-make: "varmod-edge.mk" line 166: ok M-pat-err
-make: "varmod-edge.mk" line 166: ok M-bsbs
-make: "varmod-edge.mk" line 166: ok M-bs1-par
-make: "varmod-edge.mk" line 166: ok M-bs2-par
-make: "varmod-edge.mk" line 166: ok M-128
-make: "varmod-edge.mk" line 166: ok eq-ext
-make: "varmod-edge.mk" line 166: ok eq-q
-make: "varmod-edge.mk" line 166: ok eq-bs
+make: "varmod-edge.mk" line 184: ok M-nest-mix
+make: "varmod-edge.mk" line 184: ok M-nest-brk
+make: "varmod-edge.mk" line 184: ok M-pat-err
+make: "varmod-edge.mk" line 184: ok M-bsbs
+make: "varmod-edge.mk" line 184: ok M-bs1-par
+make: "varmod-edge.mk" line 184: ok M-bs2-par
+make: "varmod-edge.mk" line 184: ok M-128
+make: "varmod-edge.mk" line 184: ok eq-ext
+make: "varmod-edge.mk" line 184: ok eq-q
+make: "varmod-edge.mk" line 184: ok eq-bs
make: Unfinished modifier for "INP.eq-esc" ('=' missing)
-make: "varmod-edge.mk" line 166: ok eq-esc
-make: "varmod-edge.mk" line 166: ok colon
-make: "varmod-edge.mk" line 165: Unknown modifier ":"
-make: "varmod-edge.mk" line 165: Unknown modifier ":"
-make: "varmod-edge.mk" line 166: ok colons
-make: "varmod-edge.mk" line 175: Unknown modifier "Z"
-make: "varmod-edge.mk" line 175: Malformed conditional (${:Z})
+make: "varmod-edge.mk" line 184: ok eq-esc
+make: "varmod-edge.mk" line 184: ok colon
+make: "varmod-edge.mk" line 167: Unknown modifier ":"
+make: "varmod-edge.mk" line 167: Unknown modifier ":"
+make: "varmod-edge.mk" line 184: ok colons
+make: "varmod-edge.mk" line 195: Unknown modifier "Z"
+make: "varmod-edge.mk" line 195: Malformed conditional (${:Z})
make: Unfinished modifier for "" (',' missing)
-make: "varmod-edge.mk" line 188: Malformed conditional (${:S,})
+make: "varmod-edge.mk" line 209: Malformed conditional (${:S,})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-edge.mk b/contrib/bmake/unit-tests/varmod-edge.mk
index 762053d281a3..2d63b372e85e 100644
--- a/contrib/bmake/unit-tests/varmod-edge.mk
+++ b/contrib/bmake/unit-tests/varmod-edge.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-edge.mk,v 1.16 2021/02/23 15:56:30 rillig Exp $
+# $NetBSD: varmod-edge.mk,v 1.17 2023/06/01 20:56:35 rillig Exp $
#
# Tests for edge cases in variable modifiers.
#
@@ -162,7 +162,25 @@ MOD.colons= ${INP.colons::::}
EXP.colons= # empty
.for test in ${TESTS}
+# expect+2: Unknown modifier ":"
+# expect+1: Unknown modifier ":"
. if ${MOD.${test}} == ${EXP.${test}}
+# expect+16: ok M-paren
+# expect+15: ok M-mixed
+# expect+14: ok M-unescape
+# expect+13: ok M-nest-mix
+# expect+12: ok M-nest-brk
+# expect+11: ok M-pat-err
+# expect+10: ok M-bsbs
+# expect+09: ok M-bs1-par
+# expect+08: ok M-bs2-par
+# expect+07: ok M-128
+# expect+06: ok eq-ext
+# expect+05: ok eq-q
+# expect+04: ok eq-bs
+# expect+03: ok eq-esc
+# expect+02: ok colon
+# expect+01: ok colons
. info ok ${test}
. else
. warning error in ${test}: expected "${EXP.${test}}", got "${MOD.${test}}"
@@ -172,6 +190,8 @@ EXP.colons= # empty
# 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: Unknown modifier "Z"
.if ${:Z}
. error
.else
@@ -185,6 +205,7 @@ EXP.colons= # empty
# modifier for (',' missing)", having two spaces in a row.
#
# XXX: The error message should report the filename:lineno.
+# expect+1: Malformed conditional (${:S,})
.if ${:S,}
. error
.else
diff --git a/contrib/bmake/unit-tests/varmod-gmtime.exp b/contrib/bmake/unit-tests/varmod-gmtime.exp
index 916e471c462b..bbb8bd547bd5 100644
--- a/contrib/bmake/unit-tests/varmod-gmtime.exp
+++ b/contrib/bmake/unit-tests/varmod-gmtime.exp
@@ -1,13 +1,13 @@
-make: "varmod-gmtime.mk" line 59: Invalid time value "-1"
-make: "varmod-gmtime.mk" line 59: Malformed conditional (${:L:gmtime=-1} != "")
-make: "varmod-gmtime.mk" line 68: Invalid time value " 1"
-make: "varmod-gmtime.mk" line 68: Malformed conditional (${:L:gmtime= 1} != "")
-make: "varmod-gmtime.mk" line 114: Invalid time value "10000000000000000000000000000000"
-make: "varmod-gmtime.mk" line 114: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "")
-make: "varmod-gmtime.mk" line 125: Invalid time value "error"
-make: "varmod-gmtime.mk" line 125: Malformed conditional (${:L:gmtime=error} != "")
-make: "varmod-gmtime.mk" line 134: Invalid time value "100000S,1970,bad,"
-make: "varmod-gmtime.mk" line 134: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad")
+make: "varmod-gmtime.mk" line 61: Invalid time value "-1"
+make: "varmod-gmtime.mk" line 61: Malformed conditional (${:L:gmtime=-1} != "")
+make: "varmod-gmtime.mk" line 72: Invalid time value " 1"
+make: "varmod-gmtime.mk" line 72: Malformed conditional (${:L:gmtime= 1} != "")
+make: "varmod-gmtime.mk" line 120: Invalid time value "10000000000000000000000000000000"
+make: "varmod-gmtime.mk" line 120: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "")
+make: "varmod-gmtime.mk" line 133: Invalid time value "error"
+make: "varmod-gmtime.mk" line 133: Malformed conditional (${:L:gmtime=error} != "")
+make: "varmod-gmtime.mk" line 144: Invalid time value "100000S,1970,bad,"
+make: "varmod-gmtime.mk" line 144: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-gmtime.mk b/contrib/bmake/unit-tests/varmod-gmtime.mk
index 639c95b24f6b..9f68501fa128 100644
--- a/contrib/bmake/unit-tests/varmod-gmtime.mk
+++ b/contrib/bmake/unit-tests/varmod-gmtime.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-gmtime.mk,v 1.14 2023/05/10 15:53:32 rillig Exp $
+# $NetBSD: varmod-gmtime.mk,v 1.15 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the :gmtime variable modifier, which formats a timestamp
# using strftime(3) in UTC.
@@ -56,6 +56,8 @@
# 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: Invalid time value "-1"
+# expect+1: Malformed conditional (${:L:gmtime=-1} != "")
.if ${:L:gmtime=-1} != ""
. error
.else
@@ -65,6 +67,8 @@
# 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: Invalid time value " 1"
+# expect+1: Malformed conditional (${:L:gmtime= 1} != "")
.if ${:L:gmtime= 1} != ""
. error
.else
@@ -111,6 +115,8 @@
#
# Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a
# parse error.
+# expect+2: Invalid time value "10000000000000000000000000000000"
+# expect+1: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "")
.if ${:L:gmtime=10000000000000000000000000000000} != ""
. error
.else
@@ -122,6 +128,8 @@
# 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: Invalid time value "error"
+# expect+1: Malformed conditional (${:L:gmtime=error} != "")
.if ${:L:gmtime=error} != ""
. error
.else
@@ -131,6 +139,8 @@
# 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: Invalid time value "100000S,1970,bad,"
+# expect+1: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad")
.if ${%Y:L:gmtime=100000S,1970,bad,} != "bad"
. error
.endif
diff --git a/contrib/bmake/unit-tests/varmod-ifelse.exp b/contrib/bmake/unit-tests/varmod-ifelse.exp
index 94cbcbdeae82..5b83ed49a759 100644
--- a/contrib/bmake/unit-tests/varmod-ifelse.exp
+++ b/contrib/bmake/unit-tests/varmod-ifelse.exp
@@ -1,32 +1,32 @@
make: Bad conditional expression 'variable expression == "literal"' in 'variable expression == "literal"?bad:bad'
-make: "varmod-ifelse.mk" line 27: Malformed conditional (${${:Uvariable expression} == "literal":?bad:bad})
+make: "varmod-ifelse.mk" line 28: Malformed conditional (${${:Uvariable expression} == "literal":?bad:bad})
make: Bad conditional expression ' == ""' in ' == ""?bad-assign:bad-assign'
make: Bad conditional expression ' == ""' in ' == ""?bad-cond:bad-cond'
-make: "varmod-ifelse.mk" line 44: Malformed conditional (${${UNDEF} == "":?bad-cond:bad-cond})
+make: "varmod-ifelse.mk" line 46: Malformed conditional (${${UNDEF} == "":?bad-cond:bad-cond})
make: Bad conditional expression '1 == == 2' in '1 == == 2?yes:no'
-make: "varmod-ifelse.mk" line 66: Malformed conditional (${1 == == 2:?yes:no} != "")
+make: "varmod-ifelse.mk" line 69: Malformed conditional (${1 == == 2:?yes:no} != "")
CondParser_Eval: "${1 == == 2:?yes:no}" != ""
CondParser_Eval: 1 == == 2
Comparing 1.000000 == 0.000000
make: Bad conditional expression '1 == == 2' in '1 == == 2?yes:no'
Comparing "" != ""
-make: "varmod-ifelse.mk" line 92: warning: Oops, the parse error should have been propagated.
+make: "varmod-ifelse.mk" line 96: 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 153: no.
-make: "varmod-ifelse.mk" line 154: Comparison with '>=' requires both operands 'no' and '10' to be numeric
+make: "varmod-ifelse.mk" line 158: no.
+make: "varmod-ifelse.mk" line 161: Comparison with '>=' requires both operands 'no' and '10' to be numeric
make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no'
-make: "varmod-ifelse.mk" line 154: .
+make: "varmod-ifelse.mk" line 161: .
make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no'
-make: "varmod-ifelse.mk" line 159: .
+make: "varmod-ifelse.mk" line 167: .
make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no'
-make: "varmod-ifelse.mk" line 160: .
-make: "varmod-ifelse.mk" line 167: true
-make: "varmod-ifelse.mk" line 169: false
+make: "varmod-ifelse.mk" line 169: .
+make: "varmod-ifelse.mk" line 177: true
+make: "varmod-ifelse.mk" line 180: false
make: Bad conditional expression ' ' in ' ?true:false'
-make: "varmod-ifelse.mk" line 171:
+make: "varmod-ifelse.mk" line 182:
CondParser_Eval: 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated"
CondParser_Eval: 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1"
CondParser_Eval: 0
diff --git a/contrib/bmake/unit-tests/varmod-ifelse.mk b/contrib/bmake/unit-tests/varmod-ifelse.mk
index 0df45cae6870..1a71cab5c7a3 100644
--- a/contrib/bmake/unit-tests/varmod-ifelse.mk
+++ b/contrib/bmake/unit-tests/varmod-ifelse.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-ifelse.mk,v 1.21 2023/02/18 18:23:58 rillig Exp $
+# $NetBSD: varmod-ifelse.mk,v 1.22 2023/06/01 20:56:35 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,6 +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+1: Malformed conditional (${${:Uvariable expression} == "literal":?bad:bad})
.if ${${:Uvariable expression} == "literal":?bad:bad}
. error
.else
@@ -41,6 +42,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+1: Malformed conditional (${${UNDEF} == "":?bad-cond:bad-cond})
.if ${${UNDEF} == "":?bad-cond:bad-cond}
. error
.else
@@ -63,6 +65,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+1: Malformed conditional (${1 == == 2:?yes:no} != "")
.if ${1 == == 2:?yes:no} != ""
. error
.else
@@ -89,6 +92,7 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
.if "${1 == == 2:?yes:no}" != ""
. error
.else
+# expect+1: warning: Oops, the parse error should have been propagated.
. warning Oops, the parse error should have been propagated.
.endif
.MAKEFLAGS: -d0
@@ -150,13 +154,18 @@ VAR= value
# instead of just saying that the whole condition is bad.
STRING= string
NUMBER= no # not really a number
+# expect+1: no.
.info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}.
+# expect+2: .
+# expect+1: Comparison with '>=' requires both operands 'no' and '10' to be numeric
.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+1: .
.info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}.
+# expect+1: .
.info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}.
# CondParser_LeafToken handles [0-9-+] specially, treating them as a number.
@@ -164,8 +173,10 @@ PLUS= +
ASTERISK= *
EMPTY= # empty
# "true" since "+" is not the empty string.
+# expect+1: true
.info ${${PLUS} :?true:false}
# "false" since the variable named "*" is not defined.
+# expect+1: false
.info ${${ASTERISK} :?true:false}
# syntax error since the condition is completely blank.
.info ${${EMPTY} :?true:false}
diff --git a/contrib/bmake/unit-tests/varmod-indirect.exp b/contrib/bmake/unit-tests/varmod-indirect.exp
index 46fa1af7a8cb..ecf52033ee4b 100644
--- a/contrib/bmake/unit-tests/varmod-indirect.exp
+++ b/contrib/bmake/unit-tests/varmod-indirect.exp
@@ -1,20 +1,20 @@
make: "varmod-indirect.mk" line 19: Unknown modifier "${"
make: "varmod-indirect.mk" line 52: Unknown modifier "${"
-make: "varmod-indirect.mk" line 53: 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 140: before
-make: "varmod-indirect.mk" line 140: after
-make: "varmod-indirect.mk" line 146: before
-make: "varmod-indirect.mk" line 146: after
-make: "varmod-indirect.mk" line 152: before
-make: "varmod-indirect.mk" line 152: after
-make: "varmod-indirect.mk" line 156: Unknown modifier "Z"
-make: "varmod-indirect.mk" line 157: before
-make: "varmod-indirect.mk" line 157: after
-Parsing line 166: _:= before ${UNDEF} after
+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
+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: Unknown modifier "Z"
+make: "varmod-indirect.mk" line 167: before
+make: "varmod-indirect.mk" line 167: after
+Parsing line 176: _:= before ${UNDEF} after
Global: _ = # (empty)
Var_Parse: ${UNDEF} after (eval-keep-dollar-and-undefined)
Global: _ = before ${UNDEF} after
-Parsing line 169: _:= before ${UNDEF:${:US,a,a,}} after
+Parsing line 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 +23,18 @@ 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 179: _:= before ${UNDEF:${:U}} after
+Parsing line 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 184: _:= before ${UNDEF:${:UZ}} after
+Parsing line 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 184: Unknown modifier "Z"
+make: "varmod-indirect.mk" line 195: Unknown modifier "Z"
Result of ${UNDEF:Z} is error (eval-keep-dollar-and-undefined, undefined)
Global: _ = before ${UNDEF:Z} after
-Parsing line 186: .MAKEFLAGS: -d0
+Parsing line 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/contrib/bmake/unit-tests/varmod-indirect.mk b/contrib/bmake/unit-tests/varmod-indirect.mk
index 082efb035c74..f79f041cd1ea 100644
--- a/contrib/bmake/unit-tests/varmod-indirect.mk
+++ b/contrib/bmake/unit-tests/varmod-indirect.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-indirect.mk,v 1.11 2022/01/15 12:35:18 rillig Exp $
+# $NetBSD: varmod-indirect.mk,v 1.12 2023/06/01 20:56:35 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
@@ -50,6 +50,7 @@
# 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.
. warning FIXME: this expression should have resulted in a parse $\
error rather than returning the unparsed portion of the $\
expression.
@@ -137,23 +138,32 @@ M_NoPrimes= ${PRIMES:${M_ListToSkip}}
# An undefined expression without any modifiers expands to an empty string.
.for var in before ${UNDEF} after
+# expect+2: before
+# expect+1: after
. info ${var}
.endfor
# An undefined expression with only modifiers that keep the expression
# undefined expands to an empty string.
.for var in before ${UNDEF:${:US,a,a,}} after
+# expect+2: before
+# expect+1: after
. info ${var}
.endfor
# Even in an indirect modifier based on an undefined variable, the value of
# the expression in Var_Parse is a simple empty string.
.for var in before ${UNDEF:${:U}} after
+# expect+2: before
+# expect+1: after
. info ${var}
.endfor
# An error in an indirect modifier.
+# expect+1: Unknown modifier "Z"
.for var in before ${UNDEF:${:UZ}} after
+# expect+2: before
+# expect+1: after
. info ${var}
.endfor
@@ -181,6 +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 variable expression ${_} is
# parsed but not evaluated.
+# expect+1: Unknown modifier "Z"
_:= before ${UNDEF:${:UZ}} after
.MAKEFLAGS: -d0
diff --git a/contrib/bmake/unit-tests/varmod-localtime.exp b/contrib/bmake/unit-tests/varmod-localtime.exp
index c734c234f083..a7c3ff6ab932 100644
--- a/contrib/bmake/unit-tests/varmod-localtime.exp
+++ b/contrib/bmake/unit-tests/varmod-localtime.exp
@@ -1,13 +1,13 @@
-make: "varmod-localtime.mk" line 59: Invalid time value "-1"
-make: "varmod-localtime.mk" line 59: Malformed conditional (${:L:localtime=-1} != "")
-make: "varmod-localtime.mk" line 68: Invalid time value " 1"
-make: "varmod-localtime.mk" line 68: Malformed conditional (${:L:localtime= 1} != "")
-make: "varmod-localtime.mk" line 114: Invalid time value "10000000000000000000000000000000"
-make: "varmod-localtime.mk" line 114: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "")
-make: "varmod-localtime.mk" line 125: Invalid time value "error"
-make: "varmod-localtime.mk" line 125: Malformed conditional (${:L:localtime=error} != "")
-make: "varmod-localtime.mk" line 134: Invalid time value "100000S,1970,bad,"
-make: "varmod-localtime.mk" line 134: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad")
+make: "varmod-localtime.mk" line 61: Invalid time value "-1"
+make: "varmod-localtime.mk" line 61: Malformed conditional (${:L:localtime=-1} != "")
+make: "varmod-localtime.mk" line 72: Invalid time value " 1"
+make: "varmod-localtime.mk" line 72: Malformed conditional (${:L:localtime= 1} != "")
+make: "varmod-localtime.mk" line 120: Invalid time value "10000000000000000000000000000000"
+make: "varmod-localtime.mk" line 120: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "")
+make: "varmod-localtime.mk" line 133: Invalid time value "error"
+make: "varmod-localtime.mk" line 133: Malformed conditional (${:L:localtime=error} != "")
+make: "varmod-localtime.mk" line 144: Invalid time value "100000S,1970,bad,"
+make: "varmod-localtime.mk" line 144: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-localtime.mk b/contrib/bmake/unit-tests/varmod-localtime.mk
index 7d66745aae8e..86f90064ded3 100644
--- a/contrib/bmake/unit-tests/varmod-localtime.mk
+++ b/contrib/bmake/unit-tests/varmod-localtime.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-localtime.mk,v 1.12 2023/05/10 15:53:32 rillig Exp $
+# $NetBSD: varmod-localtime.mk,v 1.13 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the :localtime variable modifier, which formats a timestamp
# using strftime(3) in local time.
@@ -56,6 +56,8 @@
# 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: Invalid time value "-1"
+# expect+1: Malformed conditional (${:L:localtime=-1} != "")
.if ${:L:localtime=-1} != ""
. error
.else
@@ -65,6 +67,8 @@
# 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: Invalid time value " 1"
+# expect+1: Malformed conditional (${:L:localtime= 1} != "")
.if ${:L:localtime= 1} != ""
. error
.else
@@ -111,6 +115,8 @@
#
# Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a
# parse error.
+# expect+2: Invalid time value "10000000000000000000000000000000"
+# expect+1: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "")
.if ${:L:localtime=10000000000000000000000000000000} != ""
. error
.else
@@ -122,6 +128,8 @@
# 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: Invalid time value "error"
+# expect+1: Malformed conditional (${:L:localtime=error} != "")
.if ${:L:localtime=error} != ""
. error
.else
@@ -131,6 +139,8 @@
# 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: Invalid time value "100000S,1970,bad,"
+# expect+1: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad")
.if ${%Y:L:localtime=100000S,1970,bad,} != "bad"
. error
.endif
diff --git a/contrib/bmake/unit-tests/varmod-loop-delete.exp b/contrib/bmake/unit-tests/varmod-loop-delete.exp
index aac86ee39061..47a2f74545a3 100644
--- a/contrib/bmake/unit-tests/varmod-loop-delete.exp
+++ b/contrib/bmake/unit-tests/varmod-loop-delete.exp
@@ -1,4 +1,4 @@
-make: "varmod-loop-delete.mk" line 19: Cannot delete variable "VAR" while it is used
+make: "varmod-loop-delete.mk" line 20: Cannot delete variable "VAR" while it is used
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-loop-delete.mk b/contrib/bmake/unit-tests/varmod-loop-delete.mk
index ed145b59ba0f..1ec6d361949d 100644
--- a/contrib/bmake/unit-tests/varmod-loop-delete.mk
+++ b/contrib/bmake/unit-tests/varmod-loop-delete.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop-delete.mk,v 1.2 2021/12/05 15:51:33 rillig Exp $
+# $NetBSD: varmod-loop-delete.mk,v 1.3 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the variable modifier ':@', which as a side effect allows to
# delete an arbitrary variable.
@@ -16,6 +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: Cannot delete variable "VAR" while it is used
EVAL:= ${VAR}
.if ${EVAL} != " rest of the value"
. error
diff --git a/contrib/bmake/unit-tests/varmod-loop-varname.exp b/contrib/bmake/unit-tests/varmod-loop-varname.exp
index 4f0379d5ea0a..2060b51c31df 100644
--- a/contrib/bmake/unit-tests/varmod-loop-varname.exp
+++ b/contrib/bmake/unit-tests/varmod-loop-varname.exp
@@ -1,11 +1,11 @@
-make: "varmod-loop-varname.mk" line 16: In the :@ modifier of "", the variable name "${:Ubar:S,b,v,}" must not contain a dollar
-make: "varmod-loop-varname.mk" line 16: Malformed conditional (${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+")
-make: "varmod-loop-varname.mk" line 85: In the :@ modifier of "1 2 3", the variable name "v$" must not contain a dollar
-make: "varmod-loop-varname.mk" line 85: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)")
-make: "varmod-loop-varname.mk" line 90: In the :@ modifier of "1 2 3", the variable name "v$$" must not contain a dollar
-make: "varmod-loop-varname.mk" line 90: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()")
-make: "varmod-loop-varname.mk" line 95: In the :@ modifier of "1 2 3", the variable name "v$$$" must not contain a dollar
-make: "varmod-loop-varname.mk" line 95: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()")
+make: "varmod-loop-varname.mk" line 18: In the :@ modifier of "", 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: In the :@ modifier of "1 2 3", 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: In the :@ modifier of "1 2 3", 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: In the :@ modifier of "1 2 3", 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: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-loop-varname.mk b/contrib/bmake/unit-tests/varmod-loop-varname.mk
index 91f8a4876466..43c72cee3ee5 100644
--- a/contrib/bmake/unit-tests/varmod-loop-varname.mk
+++ b/contrib/bmake/unit-tests/varmod-loop-varname.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-loop-varname.mk,v 1.4 2021/12/05 15:01:04 rillig Exp $
+# $NetBSD: varmod-loop-varname.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the first part of the variable modifier ':@var@...@', which
# contains the variable name to use during the loop.
@@ -13,6 +13,8 @@
# 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: In the :@ modifier of "", 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+")
.if ${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"
. error
.else
@@ -82,16 +84,22 @@ 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: In the :@ modifier of "1 2 3", the variable name "v$" must not contain a dollar
+# expect+1: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)")
.if ${1 2 3:L:@v$@($v)@} != "(1) (2) (3)"
. error
.else
. error
.endif
+# expect+2: In the :@ modifier of "1 2 3", the variable name "v$$" must not contain a dollar
+# expect+1: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()")
.if ${1 2 3:L:@v$$@($v)@} != "() () ()"
. error
.else
. error
.endif
+# expect+2: In the :@ modifier of "1 2 3", the variable name "v$$$" must not contain a dollar
+# expect+1: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()")
.if ${1 2 3:L:@v$$$@($v)@} != "() () ()"
. error
.else
diff --git a/contrib/bmake/unit-tests/varmod-match-escape.exp b/contrib/bmake/unit-tests/varmod-match-escape.exp
index 25cf6c0719d4..9a8f9ccf6082 100755
--- a/contrib/bmake/unit-tests/varmod-match-escape.exp
+++ b/contrib/bmake/unit-tests/varmod-match-escape.exp
@@ -30,10 +30,12 @@ Pattern for ':M' is ":\:"
ModifyWords: split ": :: :\:" into 3 words
Result of ${VALUES:M${:U\:}\:} is "::"
Comparing ":" != "::"
-make: "varmod-match-escape.mk" line 42: warning: XXX: Oops
+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 67: Dollar followed by nothing
+make: "varmod-match-escape.mk" line 69: Dollar followed by nothing
+make: "varmod-match-escape.mk" line 110: warning: Unfinished character list in pattern '[A-]' of modifier ':M'
+make: "varmod-match-escape.mk" line 110: warning: Unfinished character list in pattern '[^A-]' of modifier ':M'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-match-escape.mk b/contrib/bmake/unit-tests/varmod-match-escape.mk
index 5ac69f964a68..098a24dd9f72 100755
--- a/contrib/bmake/unit-tests/varmod-match-escape.mk
+++ b/contrib/bmake/unit-tests/varmod-match-escape.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match-escape.mk,v 1.7 2021/04/03 11:08:40 rillig Exp $
+# $NetBSD: varmod-match-escape.mk,v 1.10 2023/06/23 04:56:54 rillig Exp $
#
# As of 2020-08-01, the :M and :N modifiers interpret backslashes differently,
# depending on whether there was a variable expression somewhere before the
@@ -39,6 +39,7 @@ SPECIALS= \: : \\ * \*
#
VALUES= : :: :\:
.if ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:}
+# expect+1: warning: XXX: Oops
. warning XXX: Oops
.endif
@@ -64,6 +65,7 @@ VALUES= : :: :\:
# In lint mode, the case of a lonely '$' is covered with an error message.
.MAKEFLAGS: -dL
+# expect+1: Dollar followed by nothing
.if ${:U\$:M\$} != ""
. error
.endif
@@ -75,12 +77,41 @@ VALUES= : :: :\:
#
# TODO: Str_Match("a-z]", "[a-z]")
# TODO: Str_Match("012", "[0-]]")
-# TODO: Str_Match("0]", "[0-]]")
-# TODO: Str_Match("1]", "[0-]]")
# TODO: Str_Match("[", "[[]")
# TODO: Str_Match("]", "[]")
# TODO: Str_Match("]", "[[-]]")
+# Demonstrate an inconsistency between positive and negative character lists
+# when the range ends with the character ']'.
+#
+# 'A' begins the range, 'B' is in the middle of the range, ']' ends the range,
+# 'a' is outside the range.
+WORDS= A A] A]] B B] B]] ] ]] ]]] a a] a]]
+# The ']' is part of the character range and at the same time ends the
+# character list.
+EXP.[A-]= A B ]
+# The first ']' is part of the character range and at the same time ends the
+# character list.
+EXP.[A-]]= A] B] ]]
+# The first ']' is part of the character range and at the same time ends the
+# character list.
+EXP.[A-]]]= A]] B]] ]]]
+# For negative character lists, the ']' ends the character range but does not
+# end the character list.
+# XXX: This is unnecessarily inconsistent but irrelevant in practice as there
+# is no practical need for a character range that ends at ']'.
+EXP.[^A-]= a
+EXP.[^A-]]= a
+EXP.[^A-]]]= a]
+
+.for pattern in [A-] [A-]] [A-]]] [^A-] [^A-]] [^A-]]]
+# expect+2: warning: Unfinished character list in pattern '[A-]' of modifier ':M'
+# expect+1: warning: Unfinished character list in pattern '[^A-]' of modifier ':M'
+. if ${WORDS:M${pattern}} != ${EXP.${pattern}}
+. warning ${pattern}: ${WORDS:M${pattern}} != ${EXP.${pattern}}
+. endif
+.endfor
+
# In brackets, the backslash is just an ordinary character.
# Outside brackets, it is an escape character for a few special characters.
# TODO: Str_Match("\\", "[\\-]]")
diff --git a/contrib/bmake/unit-tests/varmod-match.exp b/contrib/bmake/unit-tests/varmod-match.exp
index 5bf3da46e524..4ac89bda8e0b 100644
--- a/contrib/bmake/unit-tests/varmod-match.exp
+++ b/contrib/bmake/unit-tests/varmod-match.exp
@@ -10,8 +10,16 @@ CondParser_Eval: ${:Ua \$ sign:M*$$*} != "\$"
Comparing "$" != "$"
CondParser_Eval: ${:Ua \$ sign any-asterisk:M*\$*} != "any-asterisk"
Comparing "any-asterisk" != "any-asterisk"
-make: "varmod-match.mk" line 157: Unknown modifier "]"
-make: "varmod-match.mk" line 157: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+make: "varmod-match.mk" line 162: warning: Unfinished character list in pattern '[' of modifier ':M'
+make: "varmod-match.mk" line 162: Unknown modifier "]"
+make: "varmod-match.mk" line 162: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+make: "varmod-match.mk" line 205: warning: Unfinished character list in pattern 'a[' of modifier ':M'
+make: "varmod-match.mk" line 213: warning: Unfinished character list in pattern 'a[^' of modifier ':M'
+make: "varmod-match.mk" line 221: warning: Unfinished character list in pattern '[-x1-3' of modifier ':M'
+make: "varmod-match.mk" line 229: warning: Unfinished character list in pattern '*[-x1-3' of modifier ':M'
+make: "varmod-match.mk" line 238: warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M'
+make: "varmod-match.mk" line 258: warning: Unfinished character range in pattern '[x-' of modifier ':M'
+make: "varmod-match.mk" line 270: warning: Unfinished character range in pattern '[^x-' of modifier ':M'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-match.mk b/contrib/bmake/unit-tests/varmod-match.mk
index 87928267d794..2804c2f2da4a 100644
--- a/contrib/bmake/unit-tests/varmod-match.mk
+++ b/contrib/bmake/unit-tests/varmod-match.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match.mk,v 1.12 2022/08/24 21:03:57 rillig Exp $
+# $NetBSD: varmod-match.mk,v 1.15 2023/06/23 04:56:54 rillig Exp $
#
# Tests for the :M variable modifier, which filters words that match the
# given pattern.
@@ -33,8 +33,12 @@ NUMBERS= One Two Three Four five six seven
.if ${:U****************:M****************b}
.endif
-# As of 2022-06-11, this expression calls Str_Match 5,242,223 times.
-# Adding another '*?' to the pattern calls Str_Match 41,261,143 times.
+# Before 2023-06-22, this expression called Str_Match 2,621,112 times.
+# Adding another '*?' to the pattern called Str_Match 20,630,572 times.
+# Adding another '*?' to the pattern called Str_Match 136,405,672 times.
+# Adding another '*?' to the pattern called Str_Match 773,168,722 times.
+# Adding another '*?' to the pattern called Str_Match 3,815,481,072 times.
+# Since 2023-06-22, Str_Match no longer backtracks.
.if ${:U..................................................b:M*?*?*?*?*?a}
.endif
@@ -152,6 +156,7 @@ WORDS= a\b a[\]b ab
.endif
# [:] matches never since the ':' starts the next modifier
+# expect+3: warning: Unfinished character list in pattern '[' of modifier ':M'
# expect+2: Unknown modifier "]"
# expect+1: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
.if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":"
@@ -196,6 +201,7 @@ WORDS= - -]
# [ Incomplete empty character list, never matches.
WORDS= a a[
+# expect+1: warning: Unfinished character list in pattern 'a[' of modifier ':M'
.if ${WORDS:Ma[} != ""
. error
.endif
@@ -203,6 +209,7 @@ WORDS= a a[
# [^ Incomplete negated empty character list, matches any single
# character.
WORDS= a a[ aX
+# expect+1: warning: Unfinished character list in pattern 'a[^' of modifier ':M'
.if ${WORDS:Ma[^} != "a[ aX"
. error
.endif
@@ -210,14 +217,24 @@ 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: warning: Unfinished character list in pattern '[-x1-3' of modifier ':M'
.if ${WORDS:M[-x1-3} != "- x 1 2 3"
. error
.endif
+# *[-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: warning: 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
+
# [^-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: warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M'
.if ${WORDS:M[^-x1-3} != "+ 0 4"
. error
.endif
@@ -237,6 +254,7 @@ WORDS= \\ \a ${:Ux\\}
# [x- Incomplete character list containing an incomplete character
# range, matches only the 'x'.
WORDS= [x- x x- y
+# expect+1: warning: Unfinished character range in pattern '[x-' of modifier ':M'
.if ${WORDS:M[x-} != "x"
. error
.endif
@@ -248,6 +266,7 @@ WORDS= [x- x x- y
# XXX: Even matches strings that are longer than a single
# character.
WORDS= [x- x x- y yyyyy
+# expect+1: warning: Unfinished character range in pattern '[^x-' of modifier ':M'
.if ${WORDS:M[^x-} != "[x- y yyyyy"
. error
.endif
diff --git a/contrib/bmake/unit-tests/varmod-order.exp b/contrib/bmake/unit-tests/varmod-order.exp
index e5d03f887fc7..487243a1678d 100644
--- a/contrib/bmake/unit-tests/varmod-order.exp
+++ b/contrib/bmake/unit-tests/varmod-order.exp
@@ -1,26 +1,26 @@
make: Bad modifier ":OX" for variable "WORDS"
-make: "varmod-order.mk" line 14: Undefined variable "${WORDS:OX"
+make: "varmod-order.mk" line 16: Undefined variable "${WORDS:OX"
make: Bad modifier ":OxXX" for variable "WORDS"
-make: "varmod-order.mk" line 17: Undefined variable "${WORDS:Ox"
+make: "varmod-order.mk" line 21: Undefined variable "${WORDS:Ox"
make: Unclosed variable expression, expecting '}' for modifier "O" of variable "WORDS" with value "eight five four nine one seven six ten three two"
make: Unclosed variable expression, expecting '}' for modifier "On" of variable "NUMBERS" with value "1 2 3 4 5 6 7 8 9 10"
make: Unclosed variable expression, expecting '}' for modifier "Onr" of variable "NUMBERS" with value "10 9 8 7 6 5 4 3 2 1"
make: Bad modifier ":Oxn" for variable "NUMBERS"
-make: "varmod-order.mk" line 29: Malformed conditional (${NUMBERS:Oxn})
+make: "varmod-order.mk" line 33: Malformed conditional (${NUMBERS:Oxn})
make: Bad modifier ":On_typo" for variable "NUMBERS"
-make: "varmod-order.mk" line 39: Malformed conditional (${NUMBERS:On_typo})
+make: "varmod-order.mk" line 44: Malformed conditional (${NUMBERS:On_typo})
make: Bad modifier ":Onr_typo" for variable "NUMBERS"
-make: "varmod-order.mk" line 48: Malformed conditional (${NUMBERS:Onr_typo})
+make: "varmod-order.mk" line 54: Malformed conditional (${NUMBERS:Onr_typo})
make: Bad modifier ":Orn_typo" for variable "NUMBERS"
-make: "varmod-order.mk" line 57: Malformed conditional (${NUMBERS:Orn_typo})
+make: "varmod-order.mk" line 64: Malformed conditional (${NUMBERS:Orn_typo})
make: Bad modifier ":Onn" for variable "NUMBERS"
-make: "varmod-order.mk" line 68: Malformed conditional (${NUMBERS:Onn})
+make: "varmod-order.mk" line 76: Malformed conditional (${NUMBERS:Onn})
make: Bad modifier ":Onrr" for variable "NUMBERS"
-make: "varmod-order.mk" line 77: Malformed conditional (${NUMBERS:Onrr})
+make: "varmod-order.mk" line 86: Malformed conditional (${NUMBERS:Onrr})
make: Bad modifier ":Orrn" for variable "NUMBERS"
-make: "varmod-order.mk" line 86: Malformed conditional (${NUMBERS:Orrn})
+make: "varmod-order.mk" line 96: Malformed conditional (${NUMBERS:Orrn})
make: Bad modifier ":On=Off" for variable "SWITCH"
-make: "varmod-order.mk" line 100: Malformed conditional (${SWITCH:On=Off} != "Off")
+make: "varmod-order.mk" line 111: Malformed conditional (${SWITCH:On=Off} != "Off")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-order.mk b/contrib/bmake/unit-tests/varmod-order.mk
index b4d5452263c7..67919543a93e 100644
--- a/contrib/bmake/unit-tests/varmod-order.mk
+++ b/contrib/bmake/unit-tests/varmod-order.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-order.mk,v 1.10 2023/02/27 08:29:36 rillig Exp $
+# $NetBSD: varmod-order.mk,v 1.11 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the :O variable modifier and its variants, which either sort the
# words of the value or shuffle them.
@@ -11,9 +11,13 @@ NUMBERS= 8 5 4 9 1 7 6 10 3 2 # in English alphabetical order
.endif
# Unknown modifier "OX"
+# FIXME: The error message is wrong.
+# expect+1: Undefined variable "${WORDS:OX"
_:= ${WORDS:OX}
# Unknown modifier "OxXX"
+# FIXME: The error message is wrong.
+# expect+1: Undefined variable "${WORDS:Ox"
_:= ${WORDS:OxXX}
# Missing closing brace, to cover the error handling code.
@@ -36,6 +40,7 @@ _:= ${NUMBERS:Onr
# TODO: Add line number information to the "Bad modifier" diagnostic.
#
# expect: make: Bad modifier ":On_typo" for variable "NUMBERS"
+# expect+1: Malformed conditional (${NUMBERS:On_typo})
.if ${NUMBERS:On_typo}
. error
.else
@@ -45,6 +50,7 @@ _:= ${NUMBERS:Onr
# Extra characters after ':Onr' are detected and diagnosed.
#
# expect: make: Bad modifier ":Onr_typo" for variable "NUMBERS"
+# expect+1: Malformed conditional (${NUMBERS:Onr_typo})
.if ${NUMBERS:Onr_typo}
. error
.else
@@ -54,6 +60,7 @@ _:= ${NUMBERS:Onr
# Extra characters after ':Orn' are detected and diagnosed.
#
# expect: make: Bad modifier ":Orn_typo" for variable "NUMBERS"
+# expect+1: Malformed conditional (${NUMBERS:Orn_typo})
.if ${NUMBERS:Orn_typo}
. error
.else
@@ -65,6 +72,7 @@ _:= ${NUMBERS:Onr
# not make sense.
#
# expect: make: Bad modifier ":Onn" for variable "NUMBERS"
+# expect+1: Malformed conditional (${NUMBERS:Onn})
.if ${NUMBERS:Onn}
. error
.else
@@ -74,6 +82,7 @@ _:= ${NUMBERS:Onr
# Repeating the 'r' is not supported as well, for the same reasons as above.
#
# expect: make: Bad modifier ":Onrr" for variable "NUMBERS"
+# expect+1: Malformed conditional (${NUMBERS:Onrr})
.if ${NUMBERS:Onrr}
. error
.else
@@ -83,6 +92,7 @@ _:= ${NUMBERS:Onr
# Repeating the 'r' is not supported as well, for the same reasons as above.
#
# expect: make: Bad modifier ":Orrn" for variable "NUMBERS"
+# expect+1: Malformed conditional (${NUMBERS:Orrn})
.if ${NUMBERS:Orrn}
. error
.else
@@ -97,6 +107,7 @@ _:= ${NUMBERS:Onr
# There is no such fallback for the ':O' modifiers.
SWITCH= On
# expect: make: Bad modifier ":On=Off" for variable "SWITCH"
+# expect+1: Malformed conditional (${SWITCH:On=Off} != "Off")
.if ${SWITCH:On=Off} != "Off"
. error
.else
diff --git a/contrib/bmake/unit-tests/varmod-range.exp b/contrib/bmake/unit-tests/varmod-range.exp
index f4ada11ebde6..b6226ec82c5b 100644
--- a/contrib/bmake/unit-tests/varmod-range.exp
+++ b/contrib/bmake/unit-tests/varmod-range.exp
@@ -1,13 +1,13 @@
-make: "varmod-range.mk" line 53: Invalid number "x}Rest" != "Rest"" for ':range' modifier
-make: "varmod-range.mk" line 53: Malformed conditional ("${:U:range=x}Rest" != "Rest")
-make: "varmod-range.mk" line 62: Unknown modifier "x0"
-make: "varmod-range.mk" line 62: Malformed conditional ("${:U:range=0x0}Rest" != "Rest")
-make: "varmod-range.mk" line 78: Unknown modifier "rang"
-make: "varmod-range.mk" line 78: Malformed conditional ("${a b c:L:rang}Rest" != "Rest")
-make: "varmod-range.mk" line 85: Unknown modifier "rango"
-make: "varmod-range.mk" line 85: Malformed conditional ("${a b c:L:rango}Rest" != "Rest")
-make: "varmod-range.mk" line 92: Unknown modifier "ranger"
-make: "varmod-range.mk" line 92: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest")
+make: "varmod-range.mk" line 55: Invalid number "x}Rest" != "Rest"" for ':range' modifier
+make: "varmod-range.mk" line 55: Malformed conditional ("${:U:range=x}Rest" != "Rest")
+make: "varmod-range.mk" line 66: Unknown modifier "x0"
+make: "varmod-range.mk" line 66: Malformed conditional ("${:U:range=0x0}Rest" != "Rest")
+make: "varmod-range.mk" line 84: Unknown modifier "rang"
+make: "varmod-range.mk" line 84: Malformed conditional ("${a b c:L:rang}Rest" != "Rest")
+make: "varmod-range.mk" line 93: Unknown modifier "rango"
+make: "varmod-range.mk" line 93: Malformed conditional ("${a b c:L:rango}Rest" != "Rest")
+make: "varmod-range.mk" line 102: Unknown modifier "ranger"
+make: "varmod-range.mk" line 102: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-range.mk b/contrib/bmake/unit-tests/varmod-range.mk
index d63525248e58..86ef11a59eaf 100644
--- a/contrib/bmake/unit-tests/varmod-range.mk
+++ b/contrib/bmake/unit-tests/varmod-range.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-range.mk,v 1.7 2020/11/01 14:36:25 rillig Exp $
+# $NetBSD: varmod-range.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the :range variable modifier, which generates sequences
# of integers from the given range.
@@ -50,6 +50,8 @@
#
# Since 2020-11-01, the parser issues a more precise "Invalid number" error
# instead.
+# expect+2: Invalid number "x}Rest" != "Rest"" for ':range' modifier
+# expect+1: Malformed conditional ("${:U:range=x}Rest" != "Rest")
.if "${:U:range=x}Rest" != "Rest"
. error
.else
@@ -59,6 +61,8 @@
# 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: Unknown modifier "x0"
+# expect+1: Malformed conditional ("${:U:range=0x0}Rest" != "Rest")
.if "${:U:range=0x0}Rest" != "Rest"
. error
.else
@@ -75,6 +79,8 @@
#.endif
# modifier name too short
+# expect+2: Unknown modifier "rang"
+# expect+1: Malformed conditional ("${a b c:L:rang}Rest" != "Rest")
.if "${a b c:L:rang}Rest" != "Rest"
. error
.else
@@ -82,6 +88,8 @@
.endif
# misspelled modifier name
+# expect+2: Unknown modifier "rango"
+# expect+1: Malformed conditional ("${a b c:L:rango}Rest" != "Rest")
.if "${a b c:L:rango}Rest" != "Rest"
. error
.else
@@ -89,6 +97,8 @@
.endif
# modifier name too long
+# expect+2: Unknown modifier "ranger"
+# expect+1: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest")
.if "${a b c:L:ranger}Rest" != "Rest"
. error
.else
diff --git a/contrib/bmake/unit-tests/varmod-subst.mk b/contrib/bmake/unit-tests/varmod-subst.mk
index 763535ff835a..0ddf2cfb2019 100644
--- a/contrib/bmake/unit-tests/varmod-subst.mk
+++ b/contrib/bmake/unit-tests/varmod-subst.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-subst.mk,v 1.9 2021/09/06 21:18:55 rillig Exp $
+# $NetBSD: varmod-subst.mk,v 1.12 2023/06/16 07:20:45 rillig Exp $
#
# Tests for the :S,from,to, variable modifier.
@@ -9,83 +9,117 @@ all: mod-subst-dollar
WORDS= sequences of letters
+# The empty pattern never matches anything.
.if ${WORDS:S,,,} != ${WORDS}
-. warning The empty pattern matches something.
+. error
.endif
+# The :S modifier flag '1' is applied exactly once.
.if ${WORDS:S,e,*,1} != "s*quences of letters"
-. warning The :S modifier flag '1' is not applied exactly once.
+. error
.endif
+# The :S modifier flag '1' is applied to the first occurrence, no matter if
+# the occurrence is in the first word or not.
.if ${WORDS:S,f,*,1} != "sequences o* letters"
-. warning The :S modifier flag '1' is only applied to the first word,\
- not to the first occurrence.
+. error
.endif
+# The :S modifier replaces every first match per word.
.if ${WORDS:S,e,*,} != "s*quences of l*tters"
-. warning The :S modifier does not replace every first match per word.
+. error
.endif
+# The :S modifier flag 'g' replaces every occurrence.
.if ${WORDS:S,e,*,g} != "s*qu*nc*s of l*tt*rs"
-. warning The :S modifier flag 'g' does not replace every occurrence.
+. error
.endif
+# The '^' in the search pattern anchors the pattern at the beginning of each
+# word, thereby matching a prefix.
.if ${WORDS:S,^sequ,occurr,} != "occurrences of letters"
-. warning The :S modifier fails for a short match anchored at the start.
+. error
.endif
+# The :S modifier with a '^' anchor replaces the whole word if that word is
+# exactly the pattern.
.if ${WORDS:S,^of,with,} != "sequences with letters"
-. warning The :S modifier fails for an exact match anchored at the start.
+. error
.endif
+# The :S modifier does not match if the pattern is longer than the word.
.if ${WORDS:S,^office,does not match,} != ${WORDS}
-. warning The :S modifier matches a too long pattern anchored at the start.
+. warning
.endif
+# The '$' in the search pattern anchors the pattern at the end of each word,
+# thereby matching a suffix.
.if ${WORDS:S,f$,r,} != "sequences or letters"
-. warning The :S modifier fails for a short match anchored at the end.
+. error
.endif
+# The :S modifier with a '$' anchor replaces at most one occurrence per word.
.if ${WORDS:S,s$,,} != "sequence of letter"
-. warning The :S modifier fails to replace one occurrence per word.
+. error
.endif
+# The :S modifier with a '$' anchor replaces the whole word if that word is
+# exactly the pattern.
.if ${WORDS:S,of$,,} != "sequences letters"
-. warning The :S modifier fails for an exact match anchored at the end.
+. error
.endif
+# The :S modifier with a '$' anchor and a pattern that is longer than a word
+# cannot match that word.
.if ${WORDS:S,eof$,,} != ${WORDS}
-. warning The :S modifier matches a too long pattern anchored at the end.
+. warning
.endif
+# The :S modifier with the '^' and '$' anchors matches an exact word.
.if ${WORDS:S,^of$,,} != "sequences letters"
-. warning The :S modifier does not match a word anchored at both ends.
+. error
.endif
+# The :S modifier with the '^' and '$' anchors does not match a word that
+# starts with the pattern but is longer than the pattern.
.if ${WORDS:S,^o$,,} != ${WORDS}
-. warning The :S modifier matches a prefix anchored at both ends.
+. error
.endif
+# The :S modifier with the '^' and '$' anchors does not match a word that ends
+# with the pattern but is longer than the pattern.
.if ${WORDS:S,^f$,,} != ${WORDS}
-. warning The :S modifier matches a suffix anchored at both ends.
+. error
.endif
+# The :S modifier with the '^' and '$' anchors does not match a word if the
+# pattern ends with the word but is longer than the word.
.if ${WORDS:S,^eof$,,} != ${WORDS}
-. warning The :S modifier matches a too long prefix anchored at both ends.
+. error
.endif
+# The :S modifier with the '^' and '$' anchors does not match a word if the
+# pattern starts with the word but is longer than the word.
.if ${WORDS:S,^office$,,} != ${WORDS}
-. warning The :S modifier matches a too long suffix anchored at both ends.
+. error
.endif
+# Except for the '^' and '$' anchors, the pattern does not contain any special
+# characters, so the '*' from the pattern would only match a literal '*' in a
+# word.
.if ${WORDS:S,*,replacement,} != ${WORDS}
-. error The '*' seems to be interpreted as a wildcard of some kind.
+. error
.endif
+# Except for the '^' and '$' anchors, the pattern does not contain any special
+# characters, so the '.' from the pattern would only match a literal '.' in a
+# word.
.if ${WORDS:S,.,replacement,} != ${WORDS}
-. error The '.' seems to be interpreted as a wildcard of some kind.
+. error
.endif
+# The '&' in the replacement is a placeholder for the text matched by the
+# pattern.
.if ${:Uvalue:S,^val,&,} != "value"
. error
.endif
@@ -99,6 +133,14 @@ WORDS= sequences of letters
. error
.endif
+
+# When a word is replaced with nothing, the remaining words are separated by a
+# single space, not two.
+.if ${1 2 3:L:S,2,,} != "1 3"
+. error
+.endif
+
+
mod-subst:
@echo $@:
@echo :${:Ua b b c:S,a b,,:Q}:
diff --git a/contrib/bmake/unit-tests/varmod-sysv.exp b/contrib/bmake/unit-tests/varmod-sysv.exp
index 59275857f98a..6a3728c3c0fc 100644
--- a/contrib/bmake/unit-tests/varmod-sysv.exp
+++ b/contrib/bmake/unit-tests/varmod-sysv.exp
@@ -1,5 +1,5 @@
make: Unfinished modifier for "word214" ('=' missing)
-make: "varmod-sysv.mk" line 214: Malformed conditional (${word214:L:from${:D=}to})
+make: "varmod-sysv.mk" line 215: Malformed conditional (${word214:L:from${:D=}to})
word modifier result
'' = ""
suffix = "suffix"
diff --git a/contrib/bmake/unit-tests/varmod-sysv.mk b/contrib/bmake/unit-tests/varmod-sysv.mk
index 712c1731717b..78651ea869dc 100644
--- a/contrib/bmake/unit-tests/varmod-sysv.mk
+++ b/contrib/bmake/unit-tests/varmod-sysv.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-sysv.mk,v 1.14 2021/04/12 16:09:57 rillig Exp $
+# $NetBSD: varmod-sysv.mk,v 1.15 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the variable modifier ':from=to', which replaces the suffix
# "from" with "to". It can also use '%' as a wildcard.
@@ -211,6 +211,7 @@
# XXX: As of 2020-12-05, this expression generates an "Unfinished modifier"
# error, while the correct error message would be "Unknown modifier" since
# there is no modifier named "fromto".
+# expect+1: Malformed conditional (${word214:L:from${:D=}to})
.if ${word214:L:from${:D=}to}
. error
.endif
diff --git a/contrib/bmake/unit-tests/varmod-to-abs.exp b/contrib/bmake/unit-tests/varmod-to-abs.exp
index 426b4d39744f..4506d5ea8175 100644
--- a/contrib/bmake/unit-tests/varmod-to-abs.exp
+++ b/contrib/bmake/unit-tests/varmod-to-abs.exp
@@ -1,5 +1,5 @@
-make: "varmod-to-abs.mk" line 18: does-not-exist.c
make: "varmod-to-abs.mk" line 19: does-not-exist.c
+make: "varmod-to-abs.mk" line 21: does-not-exist.c
cached_realpath: varmod-to-abs.mk -> varmod-to-abs.mk
-make: "varmod-to-abs.mk" line 23: varmod-to-abs.mk
+make: "varmod-to-abs.mk" line 26: varmod-to-abs.mk
exit status 0
diff --git a/contrib/bmake/unit-tests/varmod-to-abs.mk b/contrib/bmake/unit-tests/varmod-to-abs.mk
index 7f23318487e3..bc4722068988 100644
--- a/contrib/bmake/unit-tests/varmod-to-abs.mk
+++ b/contrib/bmake/unit-tests/varmod-to-abs.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-to-abs.mk,v 1.5 2020/11/15 05:48:17 rillig Exp $
+# $NetBSD: varmod-to-abs.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the :tA variable modifier, which returns the absolute path for
# each of the words in the variable value.
@@ -15,11 +15,14 @@
# keeping the cache, just like the GNode for global variables.
.MAKEFLAGS: -dd
does-not-exist.c= /dev/null
+# expect+1: does-not-exist.c
.info ${does-not-exist.c:L:tA}
+# expect+1: does-not-exist.c
.info ${does-not-exist.c:L:tA}
# The output of the following line is modified by the global _SED_CMDS in
# unit-tests/Makefile. See the .rawout file for the truth.
+# expect+1: varmod-to-abs.mk
.info ${MAKEFILE:tA}
.MAKEFLAGS: -d0
diff --git a/contrib/bmake/unit-tests/varmod-to-separator.exp b/contrib/bmake/unit-tests/varmod-to-separator.exp
index bfcfa3ebc103..a7d4ddb20147 100644
--- a/contrib/bmake/unit-tests/varmod-to-separator.exp
+++ b/contrib/bmake/unit-tests/varmod-to-separator.exp
@@ -1,25 +1,25 @@
-make: "varmod-to-separator.mk" line 153: Invalid character number at "400:tu}"
-make: "varmod-to-separator.mk" line 153: Malformed conditional (${WORDS:[1..3]:ts\400:tu})
-make: "varmod-to-separator.mk" line 167: Invalid character number at "100:tu}"
-make: "varmod-to-separator.mk" line 167: Malformed conditional (${WORDS:[1..3]:ts\x100:tu})
+make: "varmod-to-separator.mk" line 155: 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: Invalid character number at "100:tu}"
+make: "varmod-to-separator.mk" line 171: Malformed conditional (${WORDS:[1..3]:ts\x100:tu})
make: Bad modifier ":ts\-300" for variable "WORDS"
-make: "varmod-to-separator.mk" line 174: Malformed conditional (${WORDS:[1..3]:ts\-300:tu})
+make: "varmod-to-separator.mk" line 179: Malformed conditional (${WORDS:[1..3]:ts\-300:tu})
make: Bad modifier ":ts\8" for variable "1 2 3"
-make: "varmod-to-separator.mk" line 182: Malformed conditional (${1 2 3:L:ts\8:tu})
+make: "varmod-to-separator.mk" line 188: Malformed conditional (${1 2 3:L:ts\8:tu})
make: Bad modifier ":ts\100L" for variable "1 2 3"
-make: "varmod-to-separator.mk" line 189: Malformed conditional (${1 2 3:L:ts\100L})
+make: "varmod-to-separator.mk" line 196: Malformed conditional (${1 2 3:L:ts\100L})
make: Bad modifier ":ts\x40g" for variable "1 2 3"
-make: "varmod-to-separator.mk" line 196: Malformed conditional (${1 2 3:L:ts\x40g})
+make: "varmod-to-separator.mk" line 204: Malformed conditional (${1 2 3:L:ts\x40g})
make: Bad modifier ":tx" for variable "WORDS"
-make: "varmod-to-separator.mk" line 205: Malformed conditional (${WORDS:tx})
+make: "varmod-to-separator.mk" line 214: Malformed conditional (${WORDS:tx})
make: Bad modifier ":ts\X" for variable "WORDS"
-make: "varmod-to-separator.mk" line 213: Malformed conditional (${WORDS:ts\X})
+make: "varmod-to-separator.mk" line 223: Malformed conditional (${WORDS:ts\X})
make: Bad modifier ":t\X" for variable "WORDS"
-make: "varmod-to-separator.mk" line 221: Malformed conditional (${WORDS:t\X} != "anything")
+make: "varmod-to-separator.mk" line 232: Malformed conditional (${WORDS:t\X} != "anything")
make: Bad modifier ":ts\69" for variable ""
-make: "varmod-to-separator.mk" line 237: Malformed conditional (${:Ua b:ts\69})
-make: "varmod-to-separator.mk" line 246: Invalid character number at "1F60E}"
-make: "varmod-to-separator.mk" line 246: Malformed conditional (${:Ua b:ts\x1F60E})
+make: "varmod-to-separator.mk" line 249: Malformed conditional (${:Ua b:ts\69})
+make: "varmod-to-separator.mk" line 258: Invalid character number at "1F60E}"
+make: "varmod-to-separator.mk" line 258: Malformed conditional (${:Ua b:ts\x1F60E})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod-to-separator.mk b/contrib/bmake/unit-tests/varmod-to-separator.mk
index bf960639f831..f17dece447a9 100644
--- a/contrib/bmake/unit-tests/varmod-to-separator.mk
+++ b/contrib/bmake/unit-tests/varmod-to-separator.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-to-separator.mk,v 1.11 2022/02/09 21:09:24 rillig Exp $
+# $NetBSD: varmod-to-separator.mk,v 1.12 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the :ts variable modifier, which joins the words of the variable
# using an arbitrary character as word separator.
@@ -150,6 +150,8 @@ 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: Invalid character number at "400:tu}"
+# expect+1: Malformed conditional (${WORDS:[1..3]:ts\400:tu})
.if ${WORDS:[1..3]:ts\400:tu}
. warning The separator \400 is accepted even though it is out of bounds.
.else
@@ -164,6 +166,8 @@ 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: Invalid character number at "100:tu}"
+# expect+1: Malformed conditional (${WORDS:[1..3]:ts\x100:tu})
.if ${WORDS:[1..3]:ts\x100:tu}
. warning The separator \x100 is accepted even though it is out of bounds.
.else
@@ -171,6 +175,7 @@ WORDS= one two three four five six
.endif
# Negative numbers are not allowed for the separator character.
+# expect+1: Malformed conditional (${WORDS:[1..3]:ts\-300:tu})
.if ${WORDS:[1..3]:ts\-300:tu}
. warning The separator \-300 is accepted even though it is negative.
.else
@@ -179,6 +184,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+1: Malformed conditional (${1 2 3:L:ts\8:tu})
.if ${1 2 3:L:ts\8:tu}
. warning The separator \8 is accepted even though it is not octal.
.else
@@ -186,6 +192,7 @@ WORDS= one two three four five six
.endif
# Trailing characters after the octal character number are rejected.
+# expect+1: Malformed conditional (${1 2 3:L:ts\100L})
.if ${1 2 3:L:ts\100L}
. warning The separator \100L is accepted even though it contains an 'L'.
.else
@@ -193,6 +200,7 @@ WORDS= one two three four five six
.endif
# Trailing characters after the hexadecimal character number are rejected.
+# expect+1: Malformed conditional (${1 2 3:L:ts\x40g})
.if ${1 2 3:L:ts\x40g}
. warning The separator \x40g is accepted even though it contains a 'g'.
.else
@@ -202,6 +210,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: make: Bad modifier ":tx" for variable "WORDS"
+# expect+1: Malformed conditional (${WORDS:tx})
.if ${WORDS:tx}
. error
.else
@@ -210,6 +219,7 @@ WORDS= one two three four five six
# The word separator can only be a single character.
# expect: make: Bad modifier ":ts\X" for variable "WORDS"
+# expect+1: Malformed conditional (${WORDS:ts\X})
.if ${WORDS:ts\X}
. error
.else
@@ -218,6 +228,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+1: Malformed conditional (${WORDS:t\X} != "anything")
.if ${WORDS:t\X} != "anything"
. info This line is not reached.
.endif
@@ -234,6 +245,7 @@ WORDS= one two three four five six
# 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: make: Bad modifier ":ts\69" for variable ""
+# expect+1: Malformed conditional (${:Ua b:ts\69})
.if ${:Ua b:ts\69}
. error
.else
diff --git a/contrib/bmake/unit-tests/varmod.exp b/contrib/bmake/unit-tests/varmod.exp
index 3e588dc4d83f..19577fa495c7 100644
--- a/contrib/bmake/unit-tests/varmod.exp
+++ b/contrib/bmake/unit-tests/varmod.exp
@@ -1,8 +1,8 @@
-make: "varmod.mk" line 96: To escape a dollar, use \$, not $$, at "$$:L} != """
-make: "varmod.mk" line 96: Invalid variable name ':', at "$:L} != """
-make: "varmod.mk" line 101: Dollar followed by nothing
-make: "varmod.mk" line 110: Missing delimiter ':' after modifier "P"
-make: "varmod.mk" line 111: Missing argument for ".error"
+make: "varmod.mk" line 98: To escape a dollar, use \$, not $$, at "$$:L} != """
+make: "varmod.mk" line 98: Invalid variable name ':', at "$:L} != """
+make: "varmod.mk" line 104: Dollar followed by nothing
+make: "varmod.mk" line 114: Missing delimiter ':' after modifier "P"
+make: "varmod.mk" line 116: Missing argument for ".error"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varmod.mk b/contrib/bmake/unit-tests/varmod.mk
index 17bc1e6e3ae3..2ed2f6ee7cea 100644
--- a/contrib/bmake/unit-tests/varmod.mk
+++ b/contrib/bmake/unit-tests/varmod.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varmod.mk,v 1.7 2022/08/24 21:38:06 rillig Exp $
+# $NetBSD: varmod.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for variable modifiers, such as :Q, :S,from,to or :Ufallback.
#
@@ -93,11 +93,14 @@ DOLLAR2= ${:U\$}
# For compatibility, make does not print these error messages in normal mode.
# Should it?
.MAKEFLAGS: -dL
+# expect+2: To escape a dollar, use \$, not $$, at "$$:L} != """
+# expect+1: Invalid variable name ':', at "$:L} != """
.if ${$$:L} != ""
. error
.endif
# A '$' followed by nothing is an error as well.
+# expect+1: Dollar followed by nothing
.if ${:Uword:@word@${word}$@} != "word"
. error
.endif
@@ -107,7 +110,9 @@ DOLLAR2= ${:U\$}
# XXX: The .error should not be reached since the variable expression is
# malformed, and this error should be propagated up to Cond_EvalLine.
VAR= STOP
+# expect+1: Missing delimiter ':' after modifier "P"
.if ${VAR:P=RE} != "STORE"
+# expect+1: Missing argument for ".error"
. error
.endif
diff --git a/contrib/bmake/unit-tests/varname-dollar.exp b/contrib/bmake/unit-tests/varname-dollar.exp
index c880e82f0170..4f7c2ebbdf12 100644
--- a/contrib/bmake/unit-tests/varname-dollar.exp
+++ b/contrib/bmake/unit-tests/varname-dollar.exp
@@ -1,5 +1,5 @@
-make: "varname-dollar.mk" line 16: dollar is $.
-make: "varname-dollar.mk" line 17: dollar in braces is .
-make: "varname-dollar.mk" line 25: dollar is $.
-make: "varname-dollar.mk" line 26: dollar in braces is dollar.
+make: "varname-dollar.mk" line 17: dollar is $.
+make: "varname-dollar.mk" line 19: dollar in braces is .
+make: "varname-dollar.mk" line 28: dollar is $.
+make: "varname-dollar.mk" line 30: dollar in braces is dollar.
exit status 0
diff --git a/contrib/bmake/unit-tests/varname-dollar.mk b/contrib/bmake/unit-tests/varname-dollar.mk
index d1db9f833306..e60c9dd43e8f 100644
--- a/contrib/bmake/unit-tests/varname-dollar.mk
+++ b/contrib/bmake/unit-tests/varname-dollar.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varname-dollar.mk,v 1.3 2020/08/19 05:40:06 rillig Exp $
+# $NetBSD: varname-dollar.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the expression "$$", which looks as if it referred to a variable,
# but simply expands to a single '$' sign.
@@ -13,7 +13,9 @@ DOLLAR= $$
# At this point, the variable '$' is not defined. Therefore the second line
# returns an empty string.
+# expect+1: dollar is $.
.info dollar is $$.
+# expect+1: dollar in braces is .
.info dollar in braces is ${${DOLLAR}}.
# Now overwrite the '$' variable to see whether '$$' really expands to that
@@ -22,7 +24,9 @@ ${DOLLAR}= dollar
# At this point, the variable '$' is defined, therefore its value is printed
# in the second .info directive.
+# expect+1: dollar is $.
.info dollar is $$.
+# expect+1: dollar in braces is dollar.
.info dollar in braces is ${${DOLLAR}}.
all:
diff --git a/contrib/bmake/unit-tests/varname-dot-makeflags.exp b/contrib/bmake/unit-tests/varname-dot-makeflags.exp
index 28cc64fd66c8..8004ab40a363 100644
--- a/contrib/bmake/unit-tests/varname-dot-makeflags.exp
+++ b/contrib/bmake/unit-tests/varname-dot-makeflags.exp
@@ -1,9 +1,9 @@
-make: "varname-dot-makeflags.mk" line 10: MAKEFLAGS=<undefined>
-make: "varname-dot-makeflags.mk" line 11: .MAKEFLAGS=< -r -k>
-make: "varname-dot-makeflags.mk" line 12: .MAKEOVERRIDES=<>
-make: "varname-dot-makeflags.mk" line 18: MAKEFLAGS=<undefined>
-make: "varname-dot-makeflags.mk" line 20: .MAKEFLAGS=< -r -k -D VARNAME -r>
-make: "varname-dot-makeflags.mk" line 22: .MAKEOVERRIDES=< VAR>
+make: "varname-dot-makeflags.mk" line 11: MAKEFLAGS=<undefined>
+make: "varname-dot-makeflags.mk" line 13: .MAKEFLAGS=< -r -k>
+make: "varname-dot-makeflags.mk" line 15: .MAKEOVERRIDES=<>
+make: "varname-dot-makeflags.mk" line 21: MAKEFLAGS=<undefined>
+make: "varname-dot-makeflags.mk" line 23: .MAKEFLAGS=< -r -k -D VARNAME -r>
+make: "varname-dot-makeflags.mk" line 25: .MAKEOVERRIDES=< VAR>
runtime: MAKEFLAGS=< -r -k -D VARNAME -r VAR=value>
runtime: .MAKEFLAGS=< -r -k -D VARNAME -r>
runtime: .MAKEOVERRIDES=< VAR>
diff --git a/contrib/bmake/unit-tests/varname-dot-makeflags.mk b/contrib/bmake/unit-tests/varname-dot-makeflags.mk
index cca285f93013..ffb09decb70e 100644
--- a/contrib/bmake/unit-tests/varname-dot-makeflags.mk
+++ b/contrib/bmake/unit-tests/varname-dot-makeflags.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varname-dot-makeflags.mk,v 1.7 2023/02/25 19:24:07 rillig Exp $
+# $NetBSD: varname-dot-makeflags.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the special .MAKEFLAGS variable, which collects almost all
# command line arguments and passes them on to any child processes via
@@ -7,8 +7,11 @@
# See also:
# varname-dot-makeoverrides.mk
+# expect+1: MAKEFLAGS=<undefined>
.info MAKEFLAGS=<${MAKEFLAGS:Uundefined}>
+# expect+1: .MAKEFLAGS=< -r -k>
.info .MAKEFLAGS=<${.MAKEFLAGS}>
+# expect+1: .MAKEOVERRIDES=<>
.info .MAKEOVERRIDES=<${.MAKEOVERRIDES:Uundefined}>
# Append an option with argument, a plain option and a variable assignment.
diff --git a/contrib/bmake/unit-tests/varname-dot-parsedir.exp b/contrib/bmake/unit-tests/varname-dot-parsedir.exp
index c0bc56f41d6e..4ac953c813cd 100644
--- a/contrib/bmake/unit-tests/varname-dot-parsedir.exp
+++ b/contrib/bmake/unit-tests/varname-dot-parsedir.exp
@@ -1,5 +1,5 @@
-make: "varname-dot-parsedir.mk" line 28: At this point, .PARSEDIR is undefined.
-make: "<normalized>" line 34: The location can be faked in some cases.
-make: "varname-dot-parsedir.mk" line 38: The location is no longer fake.
+make: "varname-dot-parsedir.mk" line 37: At this point, .PARSEDIR is undefined.
+make: "<normalized>" line 43: The location can be faked in some cases.
+make: "varname-dot-parsedir.mk" line 48: The location is no longer fake.
At run time, .PARSEDIR is undefined.
exit status 0
diff --git a/contrib/bmake/unit-tests/varname-dot-parsedir.mk b/contrib/bmake/unit-tests/varname-dot-parsedir.mk
index 7c74419ddd10..525fdbd5636f 100644
--- a/contrib/bmake/unit-tests/varname-dot-parsedir.mk
+++ b/contrib/bmake/unit-tests/varname-dot-parsedir.mk
@@ -1,7 +1,15 @@
-# $NetBSD: varname-dot-parsedir.mk,v 1.6 2020/10/24 08:50:17 rillig Exp $
+# $NetBSD: varname-dot-parsedir.mk,v 1.8 2023/06/21 07:30:50 rillig Exp $
#
# Tests for the special .PARSEDIR variable, which contains the directory part
# of the file that is currently parsed.
+#
+# See also
+# varname-dot-includedfromdir.mk
+# varname-dot-includedfromfile.mk
+# varname-dot-parsefile.mk
+#
+# History
+# .PARSEDIR and .PARSEFILE were added on 1999-08-09.
# The .PARSEDIR may be absolute or relative, therefore there is not much that
# can be tested here.
@@ -25,6 +33,7 @@
#
# The .rawout file contains the full path to the current directory.
# In the .out file, it is filtered out.
+# expect+1: At this point, .PARSEDIR is undefined.
.info At this point, .PARSEDIR is undefined.
# There is absolutely no point in faking the location of the file that is
@@ -35,6 +44,7 @@
# After including another file, .PARSEDIR is reset.
.include "/dev/null"
+# expect+1: The location is no longer fake.
.info The location is no longer fake.
all:
diff --git a/contrib/bmake/unit-tests/varname-dot-parsefile.exp b/contrib/bmake/unit-tests/varname-dot-parsefile.exp
index b61f01c01ab7..651666ebcf24 100644
--- a/contrib/bmake/unit-tests/varname-dot-parsefile.exp
+++ b/contrib/bmake/unit-tests/varname-dot-parsefile.exp
@@ -1,5 +1,5 @@
-make: "varname-dot-parsefile.mk" line 23: At this point, .PARSEFILE is undefined.
-make: "<normalized>" line 29: The location can be faked in some cases.
-make: "varname-dot-parsefile.mk" line 33: The location is no longer fake.
+make: "varname-dot-parsefile.mk" line 32: At this point, .PARSEFILE is undefined.
+make: "<normalized>" line 38: The location can be faked in some cases.
+make: "varname-dot-parsefile.mk" line 43: The location is no longer fake.
At run time, .PARSEFILE is undefined.
exit status 0
diff --git a/contrib/bmake/unit-tests/varname-dot-parsefile.mk b/contrib/bmake/unit-tests/varname-dot-parsefile.mk
index 17b48a5f77ec..0a6ed3c378e0 100644
--- a/contrib/bmake/unit-tests/varname-dot-parsefile.mk
+++ b/contrib/bmake/unit-tests/varname-dot-parsefile.mk
@@ -1,7 +1,15 @@
-# $NetBSD: varname-dot-parsefile.mk,v 1.5 2020/10/24 08:50:17 rillig Exp $
+# $NetBSD: varname-dot-parsefile.mk,v 1.7 2023/06/21 07:30:50 rillig Exp $
#
# Tests for the special .PARSEFILE variable, which contains the basename part
# of the file that is currently parsed.
+#
+# See also
+# varname-dot-includedfromdir.mk
+# varname-dot-includedfromfile.mk
+# varname-dot-parsedir.mk
+#
+# History
+# .PARSEDIR and .PARSEFILE were added on 1999-08-09.
.if ${.PARSEFILE} != "varname-dot-parsefile.mk"
. error
@@ -20,6 +28,7 @@
# The variable .PARSEFILE is indirectly used by the .info directive,
# via PrintLocation.
+# expect+1: At this point, .PARSEFILE is undefined.
.info At this point, .PARSEFILE is undefined.
# There is absolutely no point in faking the location of the file that is
@@ -30,6 +39,7 @@
# After including another file, .PARSEFILE is reset.
.include "/dev/null"
+# expect+1: The location is no longer fake.
.info The location is no longer fake.
all:
diff --git a/contrib/bmake/unit-tests/varname-makeflags.mk b/contrib/bmake/unit-tests/varname-makeflags.mk
index da339ba9c5e2..4173c5a92095 100644
--- a/contrib/bmake/unit-tests/varname-makeflags.mk
+++ b/contrib/bmake/unit-tests/varname-makeflags.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varname-makeflags.mk,v 1.7 2023/02/25 19:24:07 rillig Exp $
+# $NetBSD: varname-makeflags.mk,v 1.8 2023/06/01 07:27:30 rillig Exp $
#
# Tests for the environment variable 'MAKEFLAGS', from which additional
# command line arguments are read before the actual command line arguments.
@@ -96,7 +96,7 @@ dollars_stage_1:
# $\ the value of the variable named '\'
# {varname\} a literal string
#
- # Since the variable name '\' is not defined, the resulting value is
+ # Since the variable named '\' is not defined, the resulting value is
# '\{varname\}'. Make doesn't handle isolated '$' characters in
# strings well, instead each '$' has to be part of a '$$' or be part
# of a subexpression like '${VAR}'.
@@ -135,9 +135,9 @@ dollars_stage_3:
@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
-# Demonstrates in which exact order the MAKEFLAGS are built together from the
-# parent MAKEFLAGS and the flags from the command line, in particular that
-# variable assignments are passed at the end, after the options.
+# Demonstrates in which exact order the MAKEFLAGS are built from the parent
+# MAKEFLAGS and the flags from the command line, in particular that variable
+# assignments are passed at the end, after the options.
append_stage_0:
@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
@${MAKE} -Dbefore-0 -f ${MAKEFILE} append_stage_1 VAR0=value -Dafter-0
diff --git a/contrib/bmake/unit-tests/varname.exp b/contrib/bmake/unit-tests/varname.exp
index 942532b654d5..72aea120c6e6 100644
--- a/contrib/bmake/unit-tests/varname.exp
+++ b/contrib/bmake/unit-tests/varname.exp
@@ -5,13 +5,13 @@ Var_Parse: ${VARNAME} (eval)
Global: VAR((( = 3 open parentheses
Var_Parse: ${VAR(((}}}}" != "3 open parentheses}}}" (eval)
Global: .ALLTARGETS = VAR(((=)
-make: "varname.mk" line 30: No closing parenthesis in archive specification
-make: "varname.mk" line 30: Error in archive specification: "VAR"
+make: "varname.mk" line 32: No closing parenthesis 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)
Global: .ALLTARGETS = VAR(((=) VAR\(\(\(=
-make: "varname.mk" line 35: Invalid line type
+make: "varname.mk" line 38: Invalid line type
Var_Parse: ${VARNAME} (eval)
Global: VAR((( = try3
Global: .MAKEFLAGS = -r -k -d v -d
diff --git a/contrib/bmake/unit-tests/varname.mk b/contrib/bmake/unit-tests/varname.mk
index e86fd9176a2a..f3e5bdeffeef 100644
--- a/contrib/bmake/unit-tests/varname.mk
+++ b/contrib/bmake/unit-tests/varname.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varname.mk,v 1.10 2022/02/09 21:09:24 rillig Exp $
+# $NetBSD: varname.mk,v 1.11 2023/06/01 20:56:35 rillig Exp $
#
# Tests for special variables, such as .MAKE or .PARSEDIR.
# And for variable names in general.
@@ -27,11 +27,14 @@ ${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
${: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
# level, which at the end of the line is still 3. Therefore this is not a
# variable assignment as well.
+# expect+1: Invalid line type
${:UVAR\(\(\(}= try2
# To assign to a variable with an arbitrary name, the variable name has to
# come from an external source, not the text that is parsed in the assignment
diff --git a/contrib/bmake/unit-tests/varparse-dynamic.exp b/contrib/bmake/unit-tests/varparse-dynamic.exp
index a2ff29413167..caf8424fa91a 100644
--- a/contrib/bmake/unit-tests/varparse-dynamic.exp
+++ b/contrib/bmake/unit-tests/varparse-dynamic.exp
@@ -1,5 +1,5 @@
-make: "varparse-dynamic.mk" line 8: Malformed conditional (${.TARGEX})
-make: "varparse-dynamic.mk" line 10: Malformed conditional (${.TARGXX})
+make: "varparse-dynamic.mk" line 9: Malformed conditional (${.TARGEX})
+make: "varparse-dynamic.mk" line 12: Malformed conditional (${.TARGXX})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/contrib/bmake/unit-tests/varparse-dynamic.mk b/contrib/bmake/unit-tests/varparse-dynamic.mk
index d4d165017a7f..88e4e6a4917e 100644
--- a/contrib/bmake/unit-tests/varparse-dynamic.mk
+++ b/contrib/bmake/unit-tests/varparse-dynamic.mk
@@ -1,12 +1,14 @@
-# $NetBSD: varparse-dynamic.mk,v 1.5 2021/02/22 20:38:55 rillig Exp $
+# $NetBSD: varparse-dynamic.mk,v 1.7 2023/06/01 20:56:35 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 must not be defined.
+# To trigger the bug, the variable had to be undefined.
.if ${.TARGET} # exact match, may be undefined
.endif
+# expect+1: Malformed conditional (${.TARGEX})
.if ${.TARGEX} # 1 character difference, must be defined
.endif
+# expect+1: Malformed conditional (${.TARGXX})
.if ${.TARGXX} # 2 characters difference, must be defined
.endif
@@ -30,6 +32,3 @@
.if ${.TARGET:M${UNDEF}} != "\${.TARGET:M\${UNDEF}}"
. error
.endif
-
-all:
- @:
diff --git a/contrib/bmake/unit-tests/varparse-errors.exp b/contrib/bmake/unit-tests/varparse-errors.exp
index fc20e427296a..41db6d8c6f43 100644
--- a/contrib/bmake/unit-tests/varparse-errors.exp
+++ b/contrib/bmake/unit-tests/varparse-errors.exp
@@ -1,10 +1,10 @@
-make: "varparse-errors.mk" line 37: Unknown modifier "Z"
-make: "varparse-errors.mk" line 45: Unknown modifier "Z"
+make: "varparse-errors.mk" line 38: Unknown modifier "Z"
+make: "varparse-errors.mk" line 47: Unknown modifier "Z"
make: Bad modifier ":OX" for variable ""
-make: "varparse-errors.mk" line 67: Undefined variable "${:U:OX"
+make: "varparse-errors.mk" line 71: Undefined variable "${:U:OX"
make: Bad modifier ":OX" for variable ""
make: Bad modifier ":OX" for variable ""
-make: "varparse-errors.mk" line 67: Undefined variable "${:U:OX"
+make: "varparse-errors.mk" line 71: Undefined variable "${:U:OX"
make: Bad modifier ":OX" for variable ""
make: Unclosed variable expression, expecting '}' for modifier "Q" of variable "" with value ""
make: Unclosed variable expression, expecting '}' for modifier "sh" of variable "" with value ""
diff --git a/contrib/bmake/unit-tests/varparse-errors.mk b/contrib/bmake/unit-tests/varparse-errors.mk
index 9ce41cc3be9a..3ae6d2db1de9 100644
--- a/contrib/bmake/unit-tests/varparse-errors.mk
+++ b/contrib/bmake/unit-tests/varparse-errors.mk
@@ -1,4 +1,4 @@
-# $NetBSD: varparse-errors.mk,v 1.8 2023/02/14 21:56:48 rillig Exp $
+# $NetBSD: varparse-errors.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
# Tests for parsing and evaluating all kinds of variable expressions.
#
@@ -34,6 +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: Unknown modifier "Z"
VAR.${:U:Z}= unknown modifier in the variable name
.if ${VAR.} != "unknown modifier in the variable name"
. error
@@ -42,6 +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: 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
@@ -64,6 +66,8 @@ VAR.${:U:Z}post= unknown modifier with text in the variable name
#
#.MAKEFLAGS: -dv
IND= ${:OX}
+# expect+2: Undefined variable "${:U:OX"
+# expect+1: Undefined variable "${:U:OX"
_:= ${:U:OX:U${IND}} ${:U:OX:U${IND}}
#.MAKEFLAGS: -d0
diff --git a/contrib/bmake/var.c b/contrib/bmake/var.c
index 074a96639bdb..43eaf75fb842 100644
--- a/contrib/bmake/var.c
+++ b/contrib/bmake/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.1054 2023/05/10 18:22:33 sjg Exp $ */
+/* $NetBSD: var.c,v 1.1059 2023/06/23 05:21:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -147,7 +147,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1054 2023/05/10 18:22:33 sjg Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1059 2023/06/23 05:21:10 rillig Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@@ -521,6 +521,11 @@ Var_Delete(GNode *scope, const char *varname)
DEBUG2(VAR, "%s: delete %s\n", scope->name, varname);
v = he->value;
+ if (v->readOnly) {
+ DEBUG2(VAR, "%s: delete %s (readOnly)\n",
+ scope->name, varname);
+ return;
+ }
if (v->inUse) {
Parse_Error(PARSE_FATAL,
"Cannot delete variable \"%s\" while it is used",
@@ -1322,7 +1327,7 @@ SepBuf_AddBytes(SepBuf *buf, const char *mem, size_t mem_size)
}
static void
-SepBuf_AddBytesBetween(SepBuf *buf, const char *start, const char *end)
+SepBuf_AddRange(SepBuf *buf, const char *start, const char *end)
{
SepBuf_AddBytes(buf, start, (size_t)(end - start));
}
@@ -1336,7 +1341,7 @@ SepBuf_AddStr(SepBuf *buf, const char *str)
static void
SepBuf_AddSubstring(SepBuf *buf, Substring sub)
{
- SepBuf_AddBytesBetween(buf, sub.start, sub.end);
+ SepBuf_AddRange(buf, sub.start, sub.end);
}
static char *
@@ -1393,7 +1398,7 @@ ModifyWord_Suffix(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
{
const char *lastDot = Substring_LastIndex(word, '.');
if (lastDot != NULL)
- SepBuf_AddBytesBetween(buf, lastDot + 1, word.end);
+ SepBuf_AddRange(buf, lastDot + 1, word.end);
}
/*
@@ -1408,35 +1413,7 @@ ModifyWord_Root(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
lastDot = Substring_LastIndex(word, '.');
end = lastDot != NULL ? lastDot : word.end;
- SepBuf_AddBytesBetween(buf, word.start, end);
-}
-
-/*
- * Callback for ModifyWords to implement the :M modifier.
- * Place the word in the buffer if it matches the given pattern.
- */
-static void
-ModifyWord_Match(Substring word, SepBuf *buf, void *data)
-{
- const char *pattern = data;
-
- assert(word.end[0] == '\0'); /* assume null-terminated word */
- if (Str_Match(word.start, pattern))
- SepBuf_AddSubstring(buf, word);
-}
-
-/*
- * Callback for ModifyWords to implement the :N modifier.
- * Place the word in the buffer if it doesn't match the given pattern.
- */
-static void
-ModifyWord_NoMatch(Substring word, SepBuf *buf, void *data)
-{
- const char *pattern = data;
-
- assert(word.end[0] == '\0'); /* assume null-terminated word */
- if (!Str_Match(word.start, pattern))
- SepBuf_AddSubstring(buf, word);
+ SepBuf_AddRange(buf, word.start, end);
}
#ifdef SYSVVARSUB
@@ -1471,9 +1448,9 @@ ModifyWord_SysVSubst(Substring word, SepBuf *buf, void *data)
percent = args->lhsPercent ? strchr(rhs.str, '%') : NULL;
if (percent != NULL)
- SepBuf_AddBytesBetween(buf, rhs.str, percent);
+ SepBuf_AddRange(buf, rhs.str, percent);
if (percent != NULL || !args->lhsPercent)
- SepBuf_AddBytesBetween(buf,
+ SepBuf_AddRange(buf,
word.start + Substring_Length(args->lhsPrefix),
word.end - Substring_Length(args->lhsSuffix));
SepBuf_AddStr(buf, percent != NULL ? percent + 1 : rhs.str);
@@ -1530,7 +1507,7 @@ ModifyWord_Subst(Substring word, SepBuf *buf, void *data)
/* :S,^prefix,replacement, or :S,^whole$,replacement, */
SepBuf_AddSubstring(buf, args->rhs);
- SepBuf_AddBytesBetween(buf, word.start + lhsLen, wordEnd);
+ SepBuf_AddRange(buf, word.start + lhsLen, wordEnd);
args->matched = true;
return;
}
@@ -1542,7 +1519,7 @@ ModifyWord_Subst(Substring word, SepBuf *buf, void *data)
goto nosub;
/* :S,suffix$,replacement, */
- SepBuf_AddBytesBetween(buf, word.start, wordEnd - lhsLen);
+ SepBuf_AddRange(buf, word.start, wordEnd - lhsLen);
SepBuf_AddSubstring(buf, args->rhs);
args->matched = true;
return;
@@ -1553,7 +1530,7 @@ ModifyWord_Subst(Substring word, SepBuf *buf, void *data)
/* unanchored case, may match more than once */
while ((match = Substring_Find(word, args->lhs)) != NULL) {
- SepBuf_AddBytesBetween(buf, word.start, match);
+ SepBuf_AddRange(buf, word.start, match);
SepBuf_AddSubstring(buf, args->rhs);
args->matched = true;
word.start = match + lhsLen;
@@ -1567,7 +1544,7 @@ nosub:
#ifndef NO_REGEX
/* Print the error caused by a regcomp or regexec call. */
static void
-VarREError(int reerr, const regex_t *pat, const char *str)
+RegexError(int reerr, const regex_t *pat, const char *str)
{
size_t errlen = regerror(reerr, pat, NULL, 0);
char *errbuf = bmake_malloc(errlen);
@@ -1589,7 +1566,7 @@ RegexReplaceBackref(char ref, SepBuf *buf, const char *wp,
if (opts.strict)
Error("No match for subexpression \\%u", n);
} else {
- SepBuf_AddBytesBetween(buf,
+ SepBuf_AddRange(buf,
wp + (size_t)m[n].rm_so,
wp + (size_t)m[n].rm_eo);
}
@@ -1613,7 +1590,7 @@ RegexReplace(Substring replace, SepBuf *buf, const char *wp,
ch_isdigit(rp[1]))
RegexReplaceBackref(*++rp, buf, wp, m, nsub);
else if (*rp == '&') {
- SepBuf_AddBytesBetween(buf,
+ SepBuf_AddRange(buf,
wp + (size_t)m[0].rm_so,
wp + (size_t)m[0].rm_eo);
} else
@@ -1652,9 +1629,9 @@ again:
if (xrv == 0)
goto ok;
if (xrv != REG_NOMATCH)
- VarREError(xrv, &args->re, "Unexpected regex error");
+ RegexError(xrv, &args->re, "Unexpected regex error");
no_match:
- SepBuf_AddBytesBetween(buf, wp, word.end);
+ SepBuf_AddRange(buf, wp, word.end);
return;
ok:
@@ -1809,8 +1786,7 @@ SubstringWords_JoinFree(SubstringWords words)
*/
Buf_AddByte(&buf, ' ');
}
- Buf_AddBytesBetween(&buf,
- words.words[i].start, words.words[i].end);
+ Buf_AddRange(&buf, words.words[i].start, words.words[i].end);
}
SubstringWords_Free(words);
@@ -1824,7 +1800,7 @@ SubstringWords_JoinFree(SubstringWords words)
* If quoteDollar is set, also quote and double any '$' characters.
*/
static void
-VarQuote(const char *str, bool quoteDollar, LazyBuf *buf)
+QuoteShell(const char *str, bool quoteDollar, LazyBuf *buf)
{
const char *p;
@@ -1850,7 +1826,7 @@ VarQuote(const char *str, bool quoteDollar, LazyBuf *buf)
* algorithm. Output is encoded as 8 hex digits, in Little Endian order.
*/
static char *
-VarHash(const char *str)
+Hash(const char *str)
{
static const char hexdigits[16] = "0123456789abcdef";
const unsigned char *ustr = (const unsigned char *)str;
@@ -1910,7 +1886,7 @@ VarHash(const char *str)
}
static char *
-VarStrftime(const char *fmt, time_t t, bool gmt)
+FormatTime(const char *fmt, time_t t, bool gmt)
{
char buf[BUFSIZ];
@@ -2607,7 +2583,7 @@ ApplyModifier_Time(const char **pp, ModChain *ch)
expr = ch->expr;
if (Expr_ShouldEval(expr))
- Expr_SetValueOwn(expr, VarStrftime(Expr_Str(expr), t, gmt));
+ Expr_SetValueOwn(expr, FormatTime(Expr_Str(expr), t, gmt));
return AMR_OK;
}
@@ -2621,7 +2597,7 @@ ApplyModifier_Hash(const char **pp, ModChain *ch)
*pp += 4;
if (ModChain_ShouldEval(ch))
- Expr_SetValueOwn(ch->expr, VarHash(Expr_Str(ch->expr)));
+ Expr_SetValueOwn(ch->expr, Hash(Expr_Str(ch->expr)));
return AMR_OK;
}
@@ -2822,6 +2798,29 @@ ParseModifier_Match(const char **pp, const ModChain *ch)
return pattern;
}
+struct ModifyWord_MatchArgs {
+ const char *pattern;
+ bool neg;
+ bool error_reported;
+};
+
+static void
+ModifyWord_Match(Substring word, SepBuf *buf, void *data)
+{
+ struct ModifyWord_MatchArgs *args = data;
+ StrMatchResult res;
+ assert(word.end[0] == '\0'); /* assume null-terminated word */
+ res = Str_Match(word.start, args->pattern);
+ if (res.error != NULL && !args->error_reported) {
+ args->error_reported = true;
+ Parse_Error(PARSE_WARNING,
+ "%s in pattern '%s' of modifier '%s'",
+ res.error, args->pattern, args->neg ? ":N" : ":M");
+ }
+ if (res.matched != args->neg)
+ SepBuf_AddSubstring(buf, word);
+}
+
/* :Mpattern or :Npattern */
static ApplyModifierResult
ApplyModifier_Match(const char **pp, ModChain *ch)
@@ -2832,9 +2831,11 @@ ApplyModifier_Match(const char **pp, ModChain *ch)
pattern = ParseModifier_Match(pp, ch);
if (ModChain_ShouldEval(ch)) {
- ModifyWordProc modifyWord =
- mod == 'M' ? ModifyWord_Match : ModifyWord_NoMatch;
- ModifyWords(ch, modifyWord, pattern, ch->oneBigWord);
+ struct ModifyWord_MatchArgs args;
+ args.pattern = pattern;
+ args.neg = mod == 'N';
+ args.error_reported = false;
+ ModifyWords(ch, ModifyWord_Match, &args, ch->oneBigWord);
}
free(pattern);
@@ -3016,7 +3017,7 @@ ApplyModifier_Regex(const char **pp, ModChain *ch)
error = regcomp(&args.re, re.str, REG_EXTENDED);
if (error != 0) {
- VarREError(error, &args.re, "Regex compilation error");
+ RegexError(error, &args.re, "Regex compilation error");
LazyBuf_Done(&replaceBuf);
FStr_Done(&re);
return AMR_CLEANUP;
@@ -3052,7 +3053,7 @@ ApplyModifier_Quote(const char **pp, ModChain *ch)
if (!ModChain_ShouldEval(ch))
return AMR_OK;
- VarQuote(Expr_Str(ch->expr), quoteDollar, &buf);
+ QuoteShell(Expr_Str(ch->expr), quoteDollar, &buf);
if (buf.data != NULL)
Expr_SetValue(ch->expr, LazyBuf_DoneGet(&buf));
else
@@ -4743,7 +4744,7 @@ VarSubstPlain(const char **pp, Buffer *res)
for (p++; *p != '$' && *p != '\0'; p++)
continue;
- Buf_AddBytesBetween(res, start, p);
+ Buf_AddRange(res, start, p);
*pp = p;
}
diff --git a/usr.bin/bmake/Makefile b/usr.bin/bmake/Makefile
index ed2f5b3d5e2f..fddd0564459d 100644
--- a/usr.bin/bmake/Makefile
+++ b/usr.bin/bmake/Makefile
@@ -12,7 +12,7 @@ CFLAGS+= -I${.CURDIR}
CLEANDIRS+= FreeBSD
CLEANFILES+= bootstrap
-# $Id: Makefile,v 1.124 2023/02/25 20:27:44 sjg Exp $
+# $Id: Makefile,v 1.125 2023/05/17 00:15:46 sjg Exp $
PROG?= ${.CURDIR:T}
@@ -81,7 +81,9 @@ FILEMON_H ?= /usr/include/dev/filemon/filemon.h
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
.endif
-.endif # USE_FILEMON == dev
+.elif ${USE_FILEMON} == "ktrace"
+COPTS.filemon_ktrace.c += -Wno-error=unused-parameter
+.endif
.endif # USE_FILEMON
diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config
index 83920a75165b..afaf0a1d15cd 100644
--- a/usr.bin/bmake/Makefile.config
+++ b/usr.bin/bmake/Makefile.config
@@ -7,7 +7,7 @@ SRCTOP?= ${.CURDIR:H:H}
# things set by configure
-_MAKE_VERSION?=20230510
+_MAKE_VERSION?=20230622
prefix?= /usr
srcdir= ${SRCTOP}/contrib/bmake
diff --git a/usr.bin/bmake/unit-tests/Makefile b/usr.bin/bmake/unit-tests/Makefile
index cacf343d162f..987dceae51ff 100644
--- a/usr.bin/bmake/unit-tests/Makefile
+++ b/usr.bin/bmake/unit-tests/Makefile
@@ -2,9 +2,9 @@
# See contrib/bmake/bsd.after-import.mk
#
# $FreeBSD$
-# $Id: Makefile,v 1.195 2023/05/10 18:26:24 sjg Exp $
+# $Id: Makefile,v 1.199 2023/06/20 17:27:20 sjg Exp $
#
-# $NetBSD: Makefile,v 1.335 2023/05/10 13:03:06 rillig Exp $
+# $NetBSD: Makefile,v 1.339 2023/06/20 09:25:34 rillig Exp $
#
# Unit tests for make(1)
#
@@ -199,6 +199,7 @@ TESTS+= directive-ifndef
TESTS+= directive-ifnmake
TESTS+= directive-include
TESTS+= directive-include-fatal
+TESTS+= directive-include-guard
TESTS+= directive-info
TESTS+= directive-misspellings
TESTS+= directive-sinclude
@@ -215,7 +216,6 @@ TESTS+= export
TESTS+= export-all
TESTS+= export-env
TESTS+= export-variants
-TESTS+= forsubst
TESTS+= gnode-submake
TESTS+= hanoi-include
TESTS+= impsrc
@@ -232,7 +232,6 @@ TESTS+= lint
TESTS+= make-exported
TESTS+= meta-cmd-cmp
TESTS+= moderrs
-TESTS+= modmatch
TESTS+= modmisc
.if ${.MAKE.UID} > 0
TESTS+= objdir-writable
@@ -428,10 +427,14 @@ TESTS+= varname-dot-make-meta-files
.if ${.MAKE.PATH_FILEMON:Uno:Nktrace:N/dev*} == "" && ${TMPDIR:N/tmp*:N/var/tmp*} != ""
# these tests will not work if TMPDIR is or is a subdir of
# /tmp or /var/tmp
+.if ${.MAKE.PATH_FILEMON:N/dev/*} != "" || exists(${.MAKE.PATH_FILEMON})
TESTS+= varname-dot-make-meta-ignore_filter
TESTS+= varname-dot-make-meta-ignore_paths
TESTS+= varname-dot-make-meta-ignore_patterns
TESTS+= varname-dot-make-path_filemon
+.else
+.warning Skipping tests that require ${.MAKE.PATH_FILEMON}
+.endif
.endif
TESTS+= varname-dot-make-meta-prefix
TESTS+= varname-dot-make-mode
@@ -542,6 +545,12 @@ FLAGS.varname-empty= -dv '$${:U}=cmdline-u' '=cmdline-plain'
# Some tests need extra postprocessing.
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 '/^SetFilenameVars:/d' \
+ -e '/^ParseDependency/d' \
+ -e '/^ParseEOF:/d'
SED_CMDS.export= -e '/^[^=_A-Za-z0-9]*=/d'
SED_CMDS.export-all= ${SED_CMDS.export}
SED_CMDS.export-env= ${SED_CMDS.export}