git: b69c3b89fea2 - stable/13 - Merge bmake-20220204

From: Simon J. Gerraty <sjg_at_FreeBSD.org>
Date: Wed, 16 Feb 2022 05:38:57 UTC
The branch stable/13 has been updated by sjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=b69c3b89fea21e1f59393018230fe6cc1f5e2e00

commit b69c3b89fea21e1f59393018230fe6cc1f5e2e00
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2022-02-05 20:26:16 +0000
Commit:     Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2022-02-16 05:37:07 +0000

    Merge bmake-20220204
    
    (cherry picked from commit 9f45a3c8c82ffead7044ae836d9257113c630d3b)
---
 contrib/bmake/ChangeLog                            |  155 ++
 contrib/bmake/FILES                                |   41 +-
 contrib/bmake/VERSION                              |    2 +-
 contrib/bmake/arch.c                               |   90 +-
 contrib/bmake/bmake.1                              |   51 +-
 contrib/bmake/bmake.cat1                           |   39 +-
 contrib/bmake/buf.c                                |   15 +-
 contrib/bmake/buf.h                                |   19 +-
 contrib/bmake/compat.c                             |   93 +-
 contrib/bmake/cond.c                               |  429 +++---
 contrib/bmake/dir.c                                |   21 +-
 contrib/bmake/dir.h                                |   14 +-
 contrib/bmake/filemon/filemon.h                    |    4 +-
 contrib/bmake/for.c                                |  228 ++-
 contrib/bmake/hash.c                               |   80 +-
 contrib/bmake/hash.h                               |   24 +-
 contrib/bmake/job.c                                |   99 +-
 contrib/bmake/job.h                                |   34 +-
 contrib/bmake/lst.h                                |   20 +-
 contrib/bmake/main.c                               |  548 +++----
 contrib/bmake/make.1                               |   51 +-
 contrib/bmake/make.c                               |   32 +-
 contrib/bmake/make.h                               |  672 ++++++--
 contrib/bmake/make_malloc.c                        |   12 +-
 contrib/bmake/make_malloc.h                        |   26 +-
 contrib/bmake/meta.c                               |  172 ++-
 contrib/bmake/meta.h                               |    8 +-
 contrib/bmake/metachar.h                           |   12 +-
 contrib/bmake/mk/ChangeLog                         |   57 +
 contrib/bmake/mk/FILES                             |    1 +
 contrib/bmake/mk/cc-wrap.mk                        |   61 +
 contrib/bmake/mk/dirdeps.mk                        |  101 +-
 contrib/bmake/mk/host-target.mk                    |    7 +-
 contrib/bmake/mk/init.mk                           |    8 +-
 contrib/bmake/mk/install-mk                        |    4 +-
 contrib/bmake/mk/meta2deps.py                      |   38 +-
 contrib/bmake/mk/meta2deps.sh                      |   29 +-
 contrib/bmake/mk/mk-files.txt                      |   93 +-
 contrib/bmake/mk/sys.clean-env.mk                  |    6 +-
 contrib/bmake/nonints.h                            |  348 -----
 contrib/bmake/parse.c                              | 1608 ++++++++------------
 contrib/bmake/str.c                                |   29 +-
 contrib/bmake/str.h                                |   46 +-
 contrib/bmake/suff.c                               |   66 +-
 contrib/bmake/targ.c                               |   40 +-
 contrib/bmake/trace.c                              |   17 +-
 contrib/bmake/unit-tests/Makefile                  |   30 +-
 contrib/bmake/unit-tests/comment.mk                |    6 +-
 contrib/bmake/unit-tests/cond-func-empty.mk        |   17 +-
 contrib/bmake/unit-tests/cond-func.exp             |   10 +-
 contrib/bmake/unit-tests/cond-func.mk              |   20 +-
 contrib/bmake/unit-tests/cond-op-parentheses.exp   |    7 +-
 contrib/bmake/unit-tests/cond-op-parentheses.mk    |   36 +-
 contrib/bmake/unit-tests/cond-short.mk             |   12 +-
 contrib/bmake/unit-tests/cond-token-number.exp     |    2 +-
 contrib/bmake/unit-tests/cond-token-number.mk      |   15 +-
 contrib/bmake/unit-tests/cond-token-plain.exp      |    3 +-
 contrib/bmake/unit-tests/cond-token-plain.mk       |   49 +-
 contrib/bmake/unit-tests/cond-token-string.exp     |    4 +-
 contrib/bmake/unit-tests/dep-duplicate.exp         |    4 +
 contrib/bmake/unit-tests/dep-duplicate.mk          |   27 +
 contrib/bmake/unit-tests/dep-op-missing.exp        |    4 +
 contrib/bmake/unit-tests/dep-op-missing.mk         |   13 +
 contrib/bmake/unit-tests/dep-wildcards.exp         |    2 +
 contrib/bmake/unit-tests/dep.exp                   |    6 +-
 contrib/bmake/unit-tests/dep.mk                    |   16 +-
 contrib/bmake/unit-tests/depsrc-meta.exp           |    2 +
 contrib/bmake/unit-tests/depsrc-meta.mk            |   19 +-
 contrib/bmake/unit-tests/depsrc-use.mk             |    7 +-
 contrib/bmake/unit-tests/depsrc-usebefore.mk       |    7 +-
 contrib/bmake/unit-tests/depsrc.exp                |    1 +
 contrib/bmake/unit-tests/depsrc.mk                 |   14 +-
 contrib/bmake/unit-tests/deptgt-error.exp          |   10 +-
 contrib/bmake/unit-tests/deptgt-error.mk           |   22 +-
 contrib/bmake/unit-tests/deptgt-ignore.exp         |   12 +-
 contrib/bmake/unit-tests/deptgt-ignore.mk          |   30 +-
 contrib/bmake/unit-tests/deptgt-interrupt.exp      |    3 +-
 contrib/bmake/unit-tests/deptgt-interrupt.mk       |    9 +-
 contrib/bmake/unit-tests/deptgt-main.exp           |    1 +
 contrib/bmake/unit-tests/deptgt-main.mk            |   27 +-
 contrib/bmake/unit-tests/deptgt-notparallel.exp    |    8 +
 contrib/bmake/unit-tests/deptgt-notparallel.mk     |   18 +-
 contrib/bmake/unit-tests/deptgt-order.exp          |    7 +
 contrib/bmake/unit-tests/deptgt-order.mk           |    4 +-
 contrib/bmake/unit-tests/deptgt-path-suffix.exp    |    5 +-
 contrib/bmake/unit-tests/deptgt-path-suffix.mk     |   10 +-
 contrib/bmake/unit-tests/deptgt.exp                |   13 +-
 contrib/bmake/unit-tests/deptgt.mk                 |   11 +-
 contrib/bmake/unit-tests/directive-dinclude.exp    |    5 +-
 contrib/bmake/unit-tests/directive-dinclude.mk     |   25 +-
 contrib/bmake/unit-tests/directive-elifdef.mk      |   21 +-
 contrib/bmake/unit-tests/directive-elifndef.mk     |   23 +-
 contrib/bmake/unit-tests/directive-export-impl.exp |   16 +-
 contrib/bmake/unit-tests/directive-for-escape.exp  |  102 +-
 contrib/bmake/unit-tests/directive-for-escape.mk   |   62 +-
 .../unit-tests/directive-for-generating-endif.exp  |    2 +-
 contrib/bmake/unit-tests/directive-for.exp         |   18 +
 contrib/bmake/unit-tests/directive-for.mk          |   81 +-
 .../bmake/unit-tests/directive-hyphen-include.exp  |    5 +-
 .../bmake/unit-tests/directive-hyphen-include.mk   |   22 +-
 contrib/bmake/unit-tests/directive-if.exp          |   23 +-
 contrib/bmake/unit-tests/directive-if.mk           |   15 +-
 contrib/bmake/unit-tests/directive-ifdef.exp       |    3 -
 contrib/bmake/unit-tests/directive-ifdef.mk        |   44 +-
 contrib/bmake/unit-tests/directive-ifmake.exp      |    6 +-
 contrib/bmake/unit-tests/directive-ifmake.mk       |   39 +-
 contrib/bmake/unit-tests/directive-include.exp     |    2 +
 contrib/bmake/unit-tests/directive-include.mk      |   33 +-
 contrib/bmake/unit-tests/directive-info.exp        |    2 +-
 contrib/bmake/unit-tests/directive-info.mk         |   13 +-
 contrib/bmake/unit-tests/directive-sinclude.exp    |    5 +-
 contrib/bmake/unit-tests/directive-sinclude.mk     |   18 +-
 contrib/bmake/unit-tests/directive-undef.exp       |    2 +-
 contrib/bmake/unit-tests/directive-unexport-env.mk |    5 +-
 contrib/bmake/unit-tests/directive-warning.exp     |   16 +-
 contrib/bmake/unit-tests/directive-warning.mk      |    9 +-
 contrib/bmake/unit-tests/directive.exp             |   10 +-
 contrib/bmake/unit-tests/directive.mk              |   22 +-
 contrib/bmake/unit-tests/envfirst.mk               |   44 -
 contrib/bmake/unit-tests/hanoi-include.mk          |    6 +-
 contrib/bmake/unit-tests/include-main.exp          |   12 +-
 contrib/bmake/unit-tests/include-main.mk           |    4 +-
 contrib/bmake/unit-tests/include-sub.mk            |   10 +-
 contrib/bmake/unit-tests/meta-cmd-cmp.exp          |   16 +
 contrib/bmake/unit-tests/meta-cmd-cmp.mk           |   36 +-
 contrib/bmake/unit-tests/modts.exp                 |   14 -
 contrib/bmake/unit-tests/modts.mk                  |   47 -
 contrib/bmake/unit-tests/modword.exp               |  126 --
 contrib/bmake/unit-tests/modword.mk                |  161 --
 contrib/bmake/unit-tests/opt-debug-cond.exp        |    5 +
 contrib/bmake/unit-tests/opt-debug-cond.mk         |   22 +-
 contrib/bmake/unit-tests/opt-debug-curdir.mk       |   10 +-
 contrib/bmake/unit-tests/opt-debug-file.exp        |   13 +-
 contrib/bmake/unit-tests/opt-debug-file.mk         |   48 +-
 contrib/bmake/unit-tests/opt-debug-hash.exp        |    7 +-
 contrib/bmake/unit-tests/opt-debug-hash.mk         |    9 +-
 contrib/bmake/unit-tests/opt-debug-parse.exp       |   25 +
 contrib/bmake/unit-tests/opt-debug-parse.mk        |   34 +-
 contrib/bmake/unit-tests/opt-debug-var.exp         |    6 +
 contrib/bmake/unit-tests/opt-debug-var.mk          |   30 +-
 contrib/bmake/unit-tests/opt-debug-x-trace.exp     |    2 +
 contrib/bmake/unit-tests/opt-debug-x-trace.mk      |   10 +-
 contrib/bmake/unit-tests/opt-define.mk             |   30 +-
 contrib/bmake/unit-tests/opt-env.exp               |    6 +-
 contrib/bmake/unit-tests/opt-env.mk                |   45 +-
 contrib/bmake/unit-tests/opt-jobs-internal.exp     |    7 +-
 contrib/bmake/unit-tests/opt-jobs-internal.mk      |   11 +-
 contrib/bmake/unit-tests/opt-raw.mk                |   16 +-
 contrib/bmake/unit-tests/opt-silent.exp            |    2 +
 contrib/bmake/unit-tests/opt-silent.mk             |    8 +-
 .../unit-tests/{var-class.exp => opt-version.exp}  |    1 +
 contrib/bmake/unit-tests/opt-version.mk            |   12 +
 contrib/bmake/unit-tests/opt-where-am-i.exp        |    3 +
 contrib/bmake/unit-tests/opt-where-am-i.mk         |   14 +-
 contrib/bmake/unit-tests/parse.exp                 |    5 +
 contrib/bmake/unit-tests/parse.mk                  |   14 +
 contrib/bmake/unit-tests/posix.mk                  |    7 +-
 contrib/bmake/unit-tests/sh.mk                     |    5 +-
 contrib/bmake/unit-tests/suff-incomplete.exp       |   12 +-
 contrib/bmake/unit-tests/suff-main-several.exp     |   30 +-
 contrib/bmake/unit-tests/suff-rebuild.exp          |   22 +-
 contrib/bmake/unit-tests/var-class-cmdline.exp     |    4 -
 contrib/bmake/unit-tests/var-class-global.mk       |    8 -
 contrib/bmake/unit-tests/var-class-local.exp       |    5 -
 contrib/bmake/unit-tests/var-class-local.mk        |   45 -
 contrib/bmake/unit-tests/var-class.mk              |    9 -
 contrib/bmake/unit-tests/var-eval-short.exp        |   16 +-
 contrib/bmake/unit-tests/var-eval-short.mk         |   11 +-
 contrib/bmake/unit-tests/var-op-expand.mk          |    4 +-
 contrib/bmake/unit-tests/var-op-shell.exp          |   12 +-
 contrib/bmake/unit-tests/var-op-shell.mk           |   15 +-
 contrib/bmake/unit-tests/var-op-sunsh.mk           |   49 +-
 contrib/bmake/unit-tests/var-recursive.exp         |    7 +
 contrib/bmake/unit-tests/var-recursive.mk          |   16 +-
 contrib/bmake/unit-tests/var-scope-cmdline.exp     |    4 +
 .../{var-class-cmdline.mk => var-scope-cmdline.mk} |    2 +-
 .../unit-tests/{envfirst.exp => var-scope-env.exp} |    0
 .../{var-class-env.mk => var-scope-env.mk}         |    2 +-
 .../{var-class-env.exp => var-scope-global.exp}    |    0
 contrib/bmake/unit-tests/var-scope-global.mk       |   18 +
 ...class-global.exp => var-scope-local-legacy.exp} |    0
 ...s-local-legacy.mk => var-scope-local-legacy.mk} |    2 +-
 contrib/bmake/unit-tests/var-scope-local.exp       |   21 +
 contrib/bmake/unit-tests/var-scope-local.mk        |  200 +++
 .../{var-class-local-legacy.exp => var-scope.exp}  |    0
 contrib/bmake/unit-tests/var-scope.mk              |    9 +
 contrib/bmake/unit-tests/varmod-assign-shell.exp   |   14 +
 contrib/bmake/unit-tests/varmod-assign-shell.mk    |   36 +
 contrib/bmake/unit-tests/varmod-ifelse.mk          |    6 +-
 contrib/bmake/unit-tests/varmod-indirect.exp       |   12 +-
 contrib/bmake/unit-tests/varmod-indirect.mk        |    6 +-
 contrib/bmake/unit-tests/varmod-loop.exp           |    6 +-
 contrib/bmake/unit-tests/varmod-order-numeric.mk   |    7 +-
 contrib/bmake/unit-tests/varmod-order.mk           |   16 +-
 contrib/bmake/unit-tests/varmod-quote-dollar.exp   |    1 +
 contrib/bmake/unit-tests/varmod-quote-dollar.mk    |    6 +-
 contrib/bmake/unit-tests/varmod-select-words.exp   |  125 ++
 contrib/bmake/unit-tests/varmod-select-words.mk    |  162 +-
 contrib/bmake/unit-tests/varmod-shell.exp          |   10 +
 contrib/bmake/unit-tests/varmod-shell.mk           |   10 +-
 contrib/bmake/unit-tests/varmod-sun-shell.exp      |   11 +
 contrib/bmake/unit-tests/varmod-sun-shell.mk       |    7 +-
 contrib/bmake/unit-tests/varmod-to-separator.exp   |   26 +-
 contrib/bmake/unit-tests/varmod-to-separator.mk    |   93 +-
 contrib/bmake/unit-tests/varname-dot-make-jobs.exp |    7 +
 contrib/bmake/unit-tests/varname-dot-make-jobs.mk  |   24 +-
 contrib/bmake/unit-tests/varname-dot-make-pid.mk   |   18 +-
 contrib/bmake/unit-tests/varname-dot-make-ppid.mk  |   25 +-
 contrib/bmake/unit-tests/varname-dot-shell.exp     |   12 +-
 contrib/bmake/unit-tests/varname-dot-suffixes.mk   |    6 +-
 contrib/bmake/unit-tests/varname-empty.exp         |    1 +
 contrib/bmake/unit-tests/varname-makeflags.mk      |   20 +-
 contrib/bmake/unit-tests/varname.mk                |   44 +-
 contrib/bmake/unit-tests/varparse-errors.exp       |    6 +
 contrib/bmake/unit-tests/varparse-errors.mk        |   22 +-
 contrib/bmake/unit-tests/varquote.mk               |    6 +-
 contrib/bmake/util.c                               |   43 +-
 contrib/bmake/var.c                                |  692 ++++-----
 218 files changed, 5441 insertions(+), 4167 deletions(-)

diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog
index 5eb2d7c5bb4a..a87f39fc49c9 100644
--- a/contrib/bmake/ChangeLog
+++ b/contrib/bmake/ChangeLog
@@ -1,3 +1,158 @@
+2022-02-04  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220204
+	Merge with NetBSD make, pick up
+	o use unsigned consistently for line numbers, avoid the need for %z
+	o parse.c: do not step off end of input in Parse_IsVar
+	when checking for target local variable assignments
+
+2022-02-02  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220202
+	Merge with NetBSD make, pick up
+	o remove redundant declaration of HashIter_Init
+	o make DEBUG0 simpler
+
+2022-01-30  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* cast gn->lineno to avoid %z
+
+	* VERSION (_MAKE_VERSION): 20220130
+	Merge with NetBSD make, pick up
+	o more unit tests
+	o make GNode lineno unsigned to please lint
+	o print location of recursive variable references in commands
+	o print "stack trace" (makefile includes) on fatal errors
+	o make.1: refine documentation for target local assignments
+
+2022-01-28  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220128
+	Merge with NetBSD make, pick up
+	o inline functions called only once
+	o for.c: clean up AddEscape for building the body of a .for loop
+	o hash.c: merge duplicate code for finding an entry in a hash table
+	replace HashEntry_KeyEquals with strncmp
+	o make.1: document quirks of target local variable assignments.
+	o parse.c: cleanup white-space
+
+2022-01-26  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220126
+	Merge with NetBSD make, pick up
+	o allow setting target local variables
+	o more unit tests
+	o add missing newline after "cannot continue" message
+	o meta.c: clean up eat_dots
+	o parse.c: fix filename in warning about duplicate script
+	o var.c: when expanding nested variables, check simple things first
+
+2022-01-16  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220116
+	Merge with NetBSD make, pick up
+	o fix for unit-tests/varname-makeflags on non-BSD systems
+	o use Var_Exists rather than Var_Value where appropriate
+	o remove unnecessary functions for expanding variable names
+	o cond.c: inline EvalBare
+	o main.c: lint cleanup
+	o parse.c: condense code in Parse_IsVar
+	use islower for parsing directives (none have upper case)
+
+2022-01-12  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220112
+	Merge with NetBSD make, pick up
+	o meta.c: add .MAKE.META.CMP_FILTER for filtering commands before
+	comparion, rarely needed but useful when it is.
+
+2022-01-10  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220110
+	Merge with NetBSD make, pick up
+	o inline Buf_Clear
+	o remove redundant braces
+	o rename and inline Targ_Precious
+	o cond.c: remove redundant initializer in CondParser_ComparisonOrLeaf
+	o for.c: clean up handling of .for loops
+	fix reported line numbers of continuation lines
+	add details about .for loop variables to stack traces
+	o job.c: reduce code for initializing error handling in shell
+	o main.c: in Cmd_Exec, return error message instead of format string
+	have as few statements as possible between va_start and va_end
+	add debug logging for capturing the output of external commands
+	o make.c: use consistent variable names for varargs
+	o make_malloc.c: remove duplicate code from bmake_strdup
+	o parse.c: add missing printflike annotations
+	remove redundant lines from stack traces
+	fix stack traces in -dp mode
+	reduce confusing code in ParseForLoop
+	fix line number in debug log after returning from a file
+	rename IFile and its fields to match their actual content
+	clean up ParseDependencySources
+	o var.c: shorten ApplyModifier_Assign
+	rename is_shell_metachar, fix character conversion warning
+	merge calls to ApplyModifier_Time
+	merge duplicate code for modifiers 'gmtime' and 'localtime'
+
+2022-01-04  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* parse.c: loadfile restore extra byte in buffer.
+
+2022-01-01  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20220101
+	Merge with NetBSD make, pick up
+	o more unit-tests
+	o remove unnecessary words from command line options in CmdOpts
+	o rename eunlink to unlink_file
+	o cond.c: make ParseWord in condition parser simpler
+	internally return false for irrelevant leaves in conditions
+	replace table for function lookup in conditions with simple code
+	merge duplicate types CondEvalResult and CondResult
+	o for.c: clean up handling of .for loops and .include directives
+	o main.c: constify cached_realpath
+	clean up Cmd_Exec
+	o parse.c: sync API documentation
+	fix error message when reading more than 1 GB from stdin
+	clean up parsing of makefiles
+	fix line number in error message about open conditionals
+	unexport types VarAssignOp and VarAssign
+	clean up function names
+	remove redundant parameters in dependency parsing functions
+	reduce scope of the list of wildcard target names
+	extract OP_NOTARGET into separate function
+	clean up variable names for parsing dependency lines
+	make debug logging a bit more human-friendly
+	o var.c: condense code in ApplyModifier_Assign
+
+2021-12-21  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211221
+	Merge with NetBSD make, pick up
+	o more unit-tests
+	o style cleanup
+	o in CLEANUP mode, free interned strings at the very end
+	o fix memory leak for filenames in .for loops
+	o buf.c: avoid memory leak
+	o cond.c: condense CondParser_ComparisonOp
+	o hash.c: change return type of HashTable_Set to void
+	o job.c: change return type of Compat_RunCommand from int to bool
+	o main.c: remove bmake_free
+	o parse.c: condense repetetive code in ParseDirective
+	remove dead code for handling traditional include directives
+	clean up parsing of variable assignments
+	remove unreachable code for parsing the dependency operator
+	clean up loading of files
+	fix memory leak in IncludeFile
+	o var.c: fix memory leak when parsing a variable name
+	fix memory leak from ${.SUFFIXES}
+	reduce memory allocation in modifier ':?' and ':C'
+	condense RegexReplace for the modifier ':C' and avoid strlen
+	merge duplicate code for memory handling in Var_Parse
+	distinguish between short-lived and environment variables
+	rename VarFreeEnv to VarFreeShortLived
+
 2021-12-15  Simon J Gerraty  <sjg@beast.crufty.net>
 
 	* cond.c: fix mem leak in CondParser_Leaf
diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES
index 53b961468db6..8193debe5032 100644
--- a/contrib/bmake/FILES
+++ b/contrib/bmake/FILES
@@ -53,7 +53,6 @@ metachar.c
 metachar.h
 missing/sys/cdefs.h
 mkdeps.sh
-nonints.h
 os.sh
 parse.c
 pathnames.h
@@ -173,10 +172,14 @@ unit-tests/dep-double-colon-indep.exp
 unit-tests/dep-double-colon-indep.mk
 unit-tests/dep-double-colon.exp
 unit-tests/dep-double-colon.mk
+unit-tests/dep-duplicate.exp
+unit-tests/dep-duplicate.mk
 unit-tests/dep-exclam.exp
 unit-tests/dep-exclam.mk
 unit-tests/dep-none.exp
 unit-tests/dep-none.mk
+unit-tests/dep-op-missing.exp
+unit-tests/dep-op-missing.mk
 unit-tests/dep-percent.exp
 unit-tests/dep-percent.mk
 unit-tests/dep-var.exp
@@ -371,8 +374,6 @@ unit-tests/doterror.exp
 unit-tests/doterror.mk
 unit-tests/dotwait.exp
 unit-tests/dotwait.mk
-unit-tests/envfirst.exp
-unit-tests/envfirst.mk
 unit-tests/error.exp
 unit-tests/error.mk
 unit-tests/escape.exp
@@ -427,10 +428,6 @@ unit-tests/modmatch.exp
 unit-tests/modmatch.mk
 unit-tests/modmisc.exp
 unit-tests/modmisc.mk
-unit-tests/modts.exp
-unit-tests/modts.mk
-unit-tests/modword.exp
-unit-tests/modword.mk
 unit-tests/objdir-writable.exp
 unit-tests/objdir-writable.mk
 unit-tests/opt-backwards.exp
@@ -535,6 +532,8 @@ unit-tests/opt-var-expanded.exp
 unit-tests/opt-var-expanded.mk
 unit-tests/opt-var-literal.exp
 unit-tests/opt-var-literal.mk
+unit-tests/opt-version.exp
+unit-tests/opt-version.mk
 unit-tests/opt-warnings-as-errors.exp
 unit-tests/opt-warnings-as-errors.mk
 unit-tests/opt-where-am-i.exp
@@ -547,6 +546,8 @@ unit-tests/order.exp
 unit-tests/order.mk
 unit-tests/parse-var.exp
 unit-tests/parse-var.mk
+unit-tests/parse.exp
+unit-tests/parse.mk
 unit-tests/phony-end.exp
 unit-tests/phony-end.mk
 unit-tests/posix.exp
@@ -625,18 +626,6 @@ unit-tests/unexport.exp
 unit-tests/unexport.mk
 unit-tests/use-inference.exp
 unit-tests/use-inference.mk
-unit-tests/var-class-cmdline.exp
-unit-tests/var-class-cmdline.mk
-unit-tests/var-class-env.exp
-unit-tests/var-class-env.mk
-unit-tests/var-class-global.exp
-unit-tests/var-class-global.mk
-unit-tests/var-class-local-legacy.exp
-unit-tests/var-class-local-legacy.mk
-unit-tests/var-class-local.exp
-unit-tests/var-class-local.mk
-unit-tests/var-class.exp
-unit-tests/var-class.mk
 unit-tests/var-eval-short.exp
 unit-tests/var-eval-short.mk
 unit-tests/var-op-append.exp
@@ -655,6 +644,18 @@ unit-tests/var-op.exp
 unit-tests/var-op.mk
 unit-tests/var-recursive.exp
 unit-tests/var-recursive.mk
+unit-tests/var-scope-cmdline.exp
+unit-tests/var-scope-cmdline.mk
+unit-tests/var-scope-env.exp
+unit-tests/var-scope-env.mk
+unit-tests/var-scope-global.exp
+unit-tests/var-scope-global.mk
+unit-tests/var-scope-local-legacy.exp
+unit-tests/var-scope-local-legacy.mk
+unit-tests/var-scope-local.exp
+unit-tests/var-scope-local.mk
+unit-tests/var-scope.exp
+unit-tests/var-scope.mk
 unit-tests/varcmd.exp
 unit-tests/varcmd.mk
 unit-tests/vardebug.exp
@@ -663,6 +664,8 @@ unit-tests/varfind.exp
 unit-tests/varfind.mk
 unit-tests/varmisc.exp
 unit-tests/varmisc.mk
+unit-tests/varmod-assign-shell.exp
+unit-tests/varmod-assign-shell.mk
 unit-tests/varmod-assign.exp
 unit-tests/varmod-assign.mk
 unit-tests/varmod-defined.exp
diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION
index 8485c4810bf0..ae363192cf1c 100644
--- a/contrib/bmake/VERSION
+++ b/contrib/bmake/VERSION
@@ -1,2 +1,2 @@
 # keep this compatible with sh and make
-_MAKE_VERSION=20211212
+_MAKE_VERSION=20220204
diff --git a/contrib/bmake/arch.c b/contrib/bmake/arch.c
index 515713af7af7..5e561b132f36 100644
--- a/contrib/bmake/arch.c
+++ b/contrib/bmake/arch.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: arch.c,v 1.205 2021/12/12 22:41:47 rillig Exp $	*/
+/*	$NetBSD: arch.c,v 1.210 2022/01/15 18:34:41 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -147,7 +147,7 @@ struct ar_hdr {
 #include "dir.h"
 
 /*	"@(#)arch.c	8.2 (Berkeley) 1/2/94"	*/
-MAKE_RCSID("$NetBSD: arch.c,v 1.205 2021/12/12 22:41:47 rillig Exp $");
+MAKE_RCSID("$NetBSD: arch.c,v 1.210 2022/01/15 18:34:41 rillig Exp $");
 
 typedef struct List ArchList;
 typedef struct ListNode ArchListNode;
@@ -247,19 +247,20 @@ FullName(const char *archive, const char *member)
 bool
 Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 {
-	char *cp;		/* Pointer into line */
+	char *spec;		/* For modifying some bytes of *pp */
+	const char *cp;		/* Pointer into line */
 	GNode *gn;		/* New node */
-	MFStr libName;		/* Library-part of specification */
+	FStr lib;		/* Library-part of specification */
 	FStr mem;		/* Member-part of specification */
 	char saveChar;		/* Ending delimiter of member-name */
-	bool expandLibName;	/* Whether the parsed libName contains
-				 * variable expressions that need to be
-				 * expanded */
+	bool expandLib;		/* Whether the parsed lib contains variable
+				 * expressions that need to be expanded */
 
-	libName = MFStr_InitRefer(*pp);
-	expandLibName = false;
+	spec = *pp;
+	lib = FStr_InitRefer(spec);
+	expandLib = false;
 
-	for (cp = libName.str; *cp != '(' && *cp != '\0';) {
+	for (cp = lib.str; *cp != '(' && *cp != '\0';) {
 		if (*cp == '$') {
 			/* Expand nested variable expressions. */
 			/* XXX: This code can probably be shortened. */
@@ -276,20 +277,15 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 			if (isError)
 				return false;
 
-			expandLibName = true;
+			expandLib = true;
 			cp += nested_p - cp;
 		} else
 			cp++;
 	}
 
-	*cp++ = '\0';
-	if (expandLibName) {
-		char *expanded;
-		(void)Var_Subst(libName.str, scope, VARE_UNDEFERR, &expanded);
-		/* TODO: handle errors */
-		libName = MFStr_InitOwn(expanded);
-	}
-
+	spec[cp++ - spec] = '\0';
+	if (expandLib)
+		Var_Expand(&lib, scope, VARE_UNDEFERR);
 
 	for (;;) {
 		/*
@@ -299,13 +295,15 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 		 */
 		bool doSubst = false;
 
-		pp_skip_whitespace(&cp);
+		cpp_skip_whitespace(&cp);
 
 		mem = FStr_InitRefer(cp);
 		while (*cp != '\0' && *cp != ')' && !ch_isspace(*cp)) {
 			if (*cp == '$') {
 				/* Expand nested variable expressions. */
-				/* XXX: This code can probably be shortened. */
+				/*
+				 * XXX: This code can probably be shortened.
+				 */
 				FStr result;
 				bool isError;
 				const char *nested_p = cp;
@@ -334,8 +332,8 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 		 */
 		if (*cp == '\0') {
 			Parse_Error(PARSE_FATAL,
-				    "No closing parenthesis "
-				    "in archive specification");
+			    "No closing parenthesis "
+			    "in archive specification");
 			return false;
 		}
 
@@ -346,7 +344,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 			break;
 
 		saveChar = *cp;
-		*cp = '\0';
+		spec[cp - spec] = '\0';
 
 		/*
 		 * XXX: This should be taken care of intelligently by
@@ -363,19 +361,16 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 		 */
 		if (doSubst) {
 			char *fullName;
-			char *p, *expandedMem;
+			char *p;
 			const char *unexpandedMem = mem.str;
 
-			(void)Var_Subst(mem.str, scope, VARE_UNDEFERR,
-			    &expandedMem);
-			/* TODO: handle errors */
-			mem = FStr_InitOwn(expandedMem);
+			Var_Expand(&mem, scope, VARE_UNDEFERR);
 
 			/*
 			 * Now form an archive spec and recurse to deal with
 			 * nested variables and multi-word variable values.
 			 */
-			fullName = FullName(libName.str, mem.str);
+			fullName = FullName(lib.str, mem.str);
 			p = fullName;
 
 			if (strcmp(mem.str, unexpandedMem) == 0) {
@@ -404,7 +399,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 
 			while (!Lst_IsEmpty(&members)) {
 				char *member = Lst_Dequeue(&members);
-				char *fullname = FullName(libName.str, member);
+				char *fullname = FullName(lib.str, member);
 				free(member);
 
 				gn = Targ_GetNode(fullname);
@@ -416,7 +411,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 			Lst_Done(&members);
 
 		} else {
-			char *fullname = FullName(libName.str, mem.str);
+			char *fullname = FullName(lib.str, mem.str);
 			gn = Targ_GetNode(fullname);
 			free(fullname);
 
@@ -432,15 +427,15 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 		}
 		FStr_Done(&mem);
 
-		*cp = saveChar;
+		spec[cp - spec] = saveChar;
 	}
 
-	MFStr_Done(&libName);
+	FStr_Done(&lib);
 
 	cp++;			/* skip the ')' */
 	/* We promised that pp would be set up at the next non-space. */
-	pp_skip_whitespace(&cp);
-	*pp = cp;
+	cpp_skip_whitespace(&cp);
+	*pp += cp - *pp;
 	return true;
 }
 
@@ -672,7 +667,7 @@ ArchSVR4Entry(Arch *ar, char *inout_name, size_t size, FILE *arch)
 
 		if (ar->fnametab != NULL) {
 			DEBUG0(ARCH,
-			       "Attempted to redefine an SVR4 name table\n");
+			    "Attempted to redefine an SVR4 name table\n");
 			return -1;
 		}
 
@@ -693,8 +688,9 @@ ArchSVR4Entry(Arch *ar, char *inout_name, size_t size, FILE *arch)
 				entry++;
 				*ptr = '\0';
 			}
-		DEBUG1(ARCH, "Found svr4 archive name table with %lu entries\n",
-		       (unsigned long)entry);
+		DEBUG1(ARCH,
+		    "Found svr4 archive name table with %lu entries\n",
+		    (unsigned long)entry);
 		return 0;
 	}
 
@@ -708,7 +704,7 @@ ArchSVR4Entry(Arch *ar, char *inout_name, size_t size, FILE *arch)
 	}
 	if (entry >= ar->fnamesize) {
 		DEBUG2(ARCH, "SVR4 entry offset %s is greater than %lu\n",
-		       inout_name, (unsigned long)ar->fnamesize);
+		    inout_name, (unsigned long)ar->fnamesize);
 		return 2;
 	}
 
@@ -737,8 +733,10 @@ ArchiveMember_HasName(const struct ar_hdr *hdr,
 	if (ar_name[namelen] == ' ')
 		return true;
 
-	/* In archives created by GNU binutils 2.27, the member names end with
-	 * a slash. */
+	/*
+	 * In archives created by GNU binutils 2.27, the member names end
+	 * with a slash.
+	 */
 	if (ar_name[namelen] == '/' &&
 	    (namelen == ar_name_len || ar_name[namelen + 1] == ' '))
 		return true;
@@ -809,9 +807,9 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
 		}
 
 		DEBUG5(ARCH, "Reading archive %s member %.*s mtime %.*s\n",
-		       archive,
-		       (int)sizeof out_arh->AR_NAME, out_arh->AR_NAME,
-		       (int)sizeof out_arh->ar_date, out_arh->ar_date);
+		    archive,
+		    (int)sizeof out_arh->AR_NAME, out_arh->AR_NAME,
+		    (int)sizeof out_arh->ar_date, out_arh->ar_date);
 
 		if (ArchiveMember_HasName(out_arh, member, len)) {
 			/*
@@ -912,7 +910,7 @@ Arch_Touch(GNode *gn)
 	struct ar_hdr arh;
 
 	f = ArchFindMember(GNode_VarArchive(gn), GNode_VarMember(gn), &arh,
-			   "r+");
+	    "r+");
 	if (f == NULL)
 		return;
 
diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1
index daea73cf538d..8f34441c34b4 100644
--- a/contrib/bmake/bmake.1
+++ b/contrib/bmake/bmake.1
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.300 2021/12/12 20:45:48 sjg Exp $
+.\"	$NetBSD: make.1,v 1.304 2022/01/29 20:54:58 sjg Exp $
 .\"
 .\" Copyright (c) 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"	from: @(#)make.1	8.4 (Berkeley) 3/19/94
 .\"
-.Dd December 12, 2021
+.Dd January 28, 2022
 .Dt BMAKE 1
 .Os
 .Sh NAME
@@ -691,10 +691,38 @@ Variables defined as part of the command line.
 Variables that are defined specific to a certain target.
 .El
 .Pp
-Local variables are all built in and their values vary magically from
-target to target.
-It is not currently possible to define new local variables.
-The seven local variables are as follows:
+Local variables can be set on a dependency line, if
+.Va .MAKE.TARGET_LOCAL_VARIABLES ,
+is not set to
+.Ql false .
+The rest of the line
+(which will already have had Global variables expanded),
+is the variable value.
+For example:
+.Bd -literal -offset indent
+COMPILER_WRAPPERS+= ccache distcc icecc
+
+${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
+.Ed
+.Pp
+Only the targets
+.Ql ${OBJS}
+will be impacted by that filter (in "meta" mode) and
+simply enabling/disabling any of the wrappers will not render all
+of those targets out-of-date.
+.Pp
+.Em NOTE :
+target local variable assignments behave differently in that;
+.Bl -tag -width Ds -offset indent
+.It Ic \&+=
+Only appends to a previous local assignment
+for the same target and variable.
+.It Ic \&:=
+Is redundant with respect to Global variables,
+which have already been expanded.
+.El
+.Pp
+The seven built-in local variables are as follows:
 .Bl -tag -width ".ARCHIVE" -offset indent
 .It Va .ALLSRC
 The list of all sources for this target; also known as
@@ -846,6 +874,11 @@ For example:
 would produce tokens like
 .Ql ---make[1234] target ---
 making it easier to track the degree of parallelism being achieved.
+.It .MAKE.TARGET_LOCAL_VARIABLES
+If set to
+.Ql false ,
+apparent variable assignments in dependency lines are
+treated as normal sources.
 .It Ev MAKEFLAGS
 The environment variable
 .Ql Ev MAKEFLAGS
@@ -954,6 +987,12 @@ If a file that was generated outside of
 .Va .OBJDIR
 but within said bailiwick is missing,
 the current target is considered out-of-date.
+.It Va .MAKE.META.CMP_FILTER
+In "meta" mode, it can (very rarely!) be useful to filter command
+lines before comparison.
+This variable can be set to a set of modifiers that will be applied to
+each line of the old and new command that differ, if the filtered
+commands still differ, the target is considered out-of-date.
 .It Va .MAKE.META.CREATED
 In "meta" mode, this variable contains a list of all the meta files
 updated.
diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1
index 73191dea7344..6aa6f382d54b 100644
--- a/contrib/bmake/bmake.cat1
+++ b/contrib/bmake/bmake.cat1
@@ -443,9 +443,28 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)
      Local variables
              Variables that are defined specific to a certain target.
 
-     Local variables are all built in and their values vary magically from
-     target to target.  It is not currently possible to define new local vari-
-     ables.  The seven local variables are as follows:
+     Local variables can be set on a dependency line, if
+     .MAKE.TARGET_LOCAL_VARIABLES, is not set to `false'.  The rest of the
+     line (which will already have had Global variables expanded), is the
+     variable value.  For example:
+
+           COMPILER_WRAPPERS+= ccache distcc icecc
+
+           ${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
+
+     Only the targets `${OBJS}' will be impacted by that filter (in "meta"
+     mode) and simply enabling/disabling any of the wrappers will not render
+     all of those targets out-of-date.
+
+     NOTE: target local variable assignments behave differently in that;
+
+           +=      Only appends to a previous local assignment for the same
+                   target and variable.
+
+           :=      Is redundant with respect to Global variables, which have
+                   already been expanded.
+
+     The seven built-in local variables are as follows:
 
            .ALLSRC   The list of all sources for this target; also known as
                      `>'.
@@ -538,6 +557,10 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)
                      ing it easier to track the degree of parallelism being
                      achieved.
 
+     .MAKE.TARGET_LOCAL_VARIABLES
+                     If set to `false', apparent variable assignments in de-
+                     pendency lines are treated as normal sources.
+
      MAKEFLAGS       The environment variable `MAKEFLAGS' may contain anything
                      that may be specified on bmake's command line.  Anything
                      specified on bmake's command line is appended to the
@@ -616,6 +639,14 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)
                      generated outside of .OBJDIR but within said bailiwick is
                      missing, the current target is considered out-of-date.
 
+     .MAKE.META.CMP_FILTER
+                     In "meta" mode, it can (very rarely!) be useful to filter
+                     command lines before comparison.  This variable can be
+                     set to a set of modifiers that will be applied to each
+                     line of the old and new command that differ, if the fil-
+                     tered commands still differ, the target is considered
+                     out-of-date.
+
      .MAKE.META.CREATED
                      In "meta" mode, this variable contains a list of all the
                      meta files updated.  If not empty, it can be used to
@@ -1591,4 +1622,4 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)
 
      There is no way of escaping a space character in a filename.
 
-FreeBSD 13.0                   December 12, 2021                  FreeBSD 13.0
+FreeBSD 13.0                   January 28, 2022                   FreeBSD 13.0
diff --git a/contrib/bmake/buf.c b/contrib/bmake/buf.c
index 8c26cfa24955..73b2eac17d4f 100644
--- a/contrib/bmake/buf.c
+++ b/contrib/bmake/buf.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: buf.c,v 1.53 2021/11/28 22:48:06 rillig Exp $	*/
+/*	$NetBSD: buf.c,v 1.55 2022/01/08 17:25:19 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.53 2021/11/28 22:48:06 rillig Exp $");
+MAKE_RCSID("$NetBSD: buf.c,v 1.55 2022/01/08 17:25:19 rillig Exp $");
 
 /* Make space in the buffer for adding at least 16 more bytes. */
 void
@@ -138,14 +138,6 @@ Buf_AddFlag(Buffer *buf, bool flag, const char *name)
 	}
 }
 
-/* Mark the buffer as empty, so it can be filled with data again. */
-void
-Buf_Empty(Buffer *buf)
-{
-	buf->len = 0;
-	buf->data[0] = '\0';
-}
-
 /* Initialize a buffer. */
 void
 Buf_InitSize(Buffer *buf, size_t cap)
@@ -214,8 +206,9 @@ Buf_DoneDataCompact(Buffer *buf)
 	if (buf->cap - buf->len >= BUF_COMPACT_LIMIT) {
 		/* We trust realloc to be smart */
 		char *data = bmake_realloc(buf->data, buf->len + 1);
+		buf->data = NULL;
 		data[buf->len] = '\0';	/* XXX: unnecessary */
-		Buf_DoneData(buf);
+		Buf_Done(buf);
 		return data;
 	}
 #endif
diff --git a/contrib/bmake/buf.h b/contrib/bmake/buf.h
index af36773405b0..14d048bfa514 100644
--- a/contrib/bmake/buf.h
+++ b/contrib/bmake/buf.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: buf.h,v 1.44 2021/11/28 22:48:06 rillig Exp $	*/
+/*	$NetBSD: buf.h,v 1.47 2022/01/08 17:25:19 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -88,6 +88,14 @@ typedef struct Buffer {
 
 void Buf_Expand(Buffer *);
 
+/* Mark the buffer as empty, so it can be filled with data again. */
+MAKE_INLINE void
+Buf_Clear(Buffer *buf)
+{
+	buf->len = 0;
+	buf->data[0] = '\0';
+}
+
 /* Buf_AddByte adds a single byte to a buffer. */
 MAKE_INLINE void
 Buf_AddByte(Buffer *buf, char byte)
@@ -101,7 +109,7 @@ Buf_AddByte(Buffer *buf, char byte)
 	end[1] = '\0';
 }
 
-MAKE_INLINE bool
+MAKE_INLINE bool MAKE_ATTR_USE
 Buf_EndsWith(const Buffer *buf, char ch)
 {
*** 16748 LINES SKIPPED ***