git: 76bc3cfd0b94 - stable/13 - Merge bmake-20211212

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

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

commit 76bc3cfd0b94aeae82b5de2c46eba3364bcde940
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2021-12-18 18:09:14 +0000
Commit:     Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2022-02-16 05:37:07 +0000

    Merge bmake-20211212
    
    commit '2935fe8237c83c1dcb113dd5335733263e68e6fd'
    
    (cherry picked from commit 129043849f62f9cfa72f6fae68417d9995860f3f)
---
 contrib/bmake/ChangeLog                            | 231 ++++++++
 contrib/bmake/FILES                                |  15 +-
 contrib/bmake/Makefile                             |  17 +-
 contrib/bmake/Makefile.config.in                   |   2 +-
 contrib/bmake/VERSION                              |   2 +-
 contrib/bmake/_strtol.h                            | 213 +++++++
 contrib/bmake/arch.c                               | 124 ++--
 contrib/bmake/bmake.1                              |  19 +-
 contrib/bmake/bmake.cat1                           |  12 +-
 contrib/bmake/boot-strap                           |  17 +-
 contrib/bmake/bsd.after-import.mk                  |   3 +-
 contrib/bmake/buf.c                                |  23 +-
 contrib/bmake/buf.h                                |   3 +-
 contrib/bmake/compat.c                             |  28 +-
 contrib/bmake/cond.c                               | 342 +++++------
 contrib/bmake/config.h.in                          |  46 ++
 contrib/bmake/configure                            | 481 ++++++++++++++--
 contrib/bmake/configure.in                         | 200 +++++--
 contrib/bmake/dir.c                                |  33 +-
 contrib/bmake/enum.c                               |  80 ---
 contrib/bmake/enum.h                               | 179 ------
 contrib/bmake/filemon/filemon_ktrace.c             |   3 +-
 contrib/bmake/for.c                                | 130 +++--
 contrib/bmake/hash.c                               |  15 +-
 contrib/bmake/hash.h                               |  11 +-
 contrib/bmake/import.sh                            |  13 +-
 contrib/bmake/job.c                                |  43 +-
 contrib/bmake/lst.h                                |   6 +-
 contrib/bmake/main.c                               |   8 +-
 contrib/bmake/make-bootstrap.sh.in                 |   2 +-
 contrib/bmake/make.1                               |  19 +-
 contrib/bmake/make.c                               | 140 +++--
 contrib/bmake/make.h                               |  87 +--
 contrib/bmake/meta.c                               |  50 +-
 contrib/bmake/metachar.c                           |   6 +-
 contrib/bmake/metachar.h                           |  10 +-
 contrib/bmake/mk/ChangeLog                         | 104 ++++
 contrib/bmake/mk/FILES                             |   1 +
 contrib/bmake/mk/auto.dep.mk                       |  52 +-
 contrib/bmake/mk/autoconf.mk                       |  23 +-
 contrib/bmake/mk/autodep.mk                        |   7 +-
 contrib/bmake/mk/compiler.mk                       |  10 +-
 contrib/bmake/mk/dep.mk                            |   4 +-
 contrib/bmake/mk/dirdeps.mk                        |  57 +-
 contrib/bmake/mk/doc.mk                            |   4 +-
 contrib/bmake/mk/dpadd.mk                          |   4 +-
 contrib/bmake/mk/final.mk                          |   4 +-
 contrib/bmake/mk/init.mk                           |   4 +-
 contrib/bmake/mk/install-mk                        |   4 +-
 contrib/bmake/mk/java.mk                           |   4 +-
 contrib/bmake/mk/ldorder.mk                        |   4 +-
 contrib/bmake/mk/lib.mk                            |   6 +-
 contrib/bmake/mk/man.mk                            |  54 +-
 contrib/bmake/mk/meta.autodep.mk                   |  12 +-
 contrib/bmake/mk/meta.stage.mk                     |  11 +-
 contrib/bmake/mk/meta.sys.mk                       |  26 +-
 contrib/bmake/mk/meta2deps.py                      |  29 +-
 contrib/bmake/mk/obj.mk                            |   4 +-
 contrib/bmake/mk/options.mk                        |  38 +-
 contrib/bmake/mk/own.mk                            |   6 +-
 contrib/bmake/mk/prlist.mk                         |   4 +-
 contrib/bmake/mk/prog.mk                           |   4 +-
 contrib/bmake/mk/stage-install.sh                  |  10 +-
 contrib/bmake/mk/sys.mk                            |   9 +-
 contrib/bmake/mk/sys.vars.mk                       |   4 +-
 contrib/bmake/mk/sys/SCO_SV.mk                     |  13 +
 contrib/bmake/mk/sys/UnixWare.mk                   |  24 +-
 contrib/bmake/nonints.h                            |   9 +-
 contrib/bmake/os.sh                                |   4 +-
 contrib/bmake/parse.c                              | 171 +++---
 contrib/bmake/sigact.h                             | 104 ++++
 contrib/bmake/sigaction.c                          | 397 +++++++++++++
 contrib/bmake/str.c                                |   9 +-
 contrib/bmake/str.h                                |  27 +-
 contrib/bmake/suff.c                               | 119 ++--
 contrib/bmake/targ.c                               |  83 +--
 contrib/bmake/trace.c                              |   6 +-
 contrib/bmake/unit-tests/Makefile                  |  75 ++-
 contrib/bmake/unit-tests/Makefile.config.in        |   4 +-
 contrib/bmake/unit-tests/cond-cmp-numeric.exp      |   4 +
 contrib/bmake/unit-tests/cond-cmp-numeric.mk       |  18 +-
 contrib/bmake/unit-tests/cond-cmp-string.mk        |   4 +-
 contrib/bmake/unit-tests/cond-eof.exp              |   3 -
 contrib/bmake/unit-tests/cond-eof.mk               |  12 +-
 contrib/bmake/unit-tests/cond-func-defined.mk      |   4 +-
 contrib/bmake/unit-tests/cond-func-empty.exp       |   4 +-
 contrib/bmake/unit-tests/cond-func-empty.mk        |  73 +--
 contrib/bmake/unit-tests/cond-func.exp             |   2 +-
 contrib/bmake/unit-tests/cond-op-and.exp           |   5 +-
 contrib/bmake/unit-tests/cond-op-and.mk            |  30 +-
 contrib/bmake/unit-tests/cond-op-or.exp            |   5 +-
 contrib/bmake/unit-tests/cond-op-or.mk             |  30 +-
 contrib/bmake/unit-tests/cond-op.exp               |  34 +-
 contrib/bmake/unit-tests/cond-op.mk                |  39 +-
 contrib/bmake/unit-tests/cond-short.mk             |  69 ++-
 contrib/bmake/unit-tests/cond-token-plain.exp      |  27 +-
 contrib/bmake/unit-tests/cond-token-plain.mk       |  35 +-
 contrib/bmake/unit-tests/deptgt-default.exp        |   1 +
 contrib/bmake/unit-tests/deptgt-default.mk         |  17 +-
 contrib/bmake/unit-tests/deptgt-makeflags.mk       |  29 +-
 contrib/bmake/unit-tests/directive-else.exp        |   6 +-
 contrib/bmake/unit-tests/directive-endif.exp       |   8 +-
 contrib/bmake/unit-tests/directive-export-impl.exp |   4 +-
 contrib/bmake/unit-tests/directive-for-escape.exp  |  63 +-
 contrib/bmake/unit-tests/directive-for-escape.mk   |  49 +-
 contrib/bmake/unit-tests/directive-for-if.exp      |   8 +
 contrib/bmake/unit-tests/directive-for-if.mk       |  86 +++
 contrib/bmake/unit-tests/directive-for-null.exp    |   2 +-
 contrib/bmake/unit-tests/directive-include.exp     |   3 +
 contrib/bmake/unit-tests/directive-include.mk      |  24 +-
 contrib/bmake/unit-tests/export.mk                 |   4 +-
 contrib/bmake/unit-tests/job-output-null.exp       |   6 +-
 contrib/bmake/unit-tests/job-output-null.mk        |  21 +-
 contrib/bmake/unit-tests/lint.exp                  |   2 +-
 contrib/bmake/unit-tests/objdir-writable.exp       |   2 +-
 contrib/bmake/unit-tests/objdir-writable.mk        |  11 +-
 contrib/bmake/unit-tests/opt-debug-errors-jobs.exp |  10 +
 contrib/bmake/unit-tests/opt-debug-errors-jobs.mk  |  14 +-
 contrib/bmake/unit-tests/opt-debug-graph1.exp      |   1 -
 contrib/bmake/unit-tests/opt-debug-graph2.exp      |   1 -
 contrib/bmake/unit-tests/opt-debug-graph3.exp      |   1 -
 contrib/bmake/unit-tests/opt-file.mk               |  12 +-
 contrib/bmake/unit-tests/opt-tracefile.exp         |  11 +
 contrib/bmake/unit-tests/opt-tracefile.mk          |  18 +-
 contrib/bmake/unit-tests/suff-main-several.exp     |   1 -
 contrib/bmake/unit-tests/suff-transform-debug.exp  |   1 -
 contrib/bmake/unit-tests/var-eval-short.exp        |  14 +-
 contrib/bmake/unit-tests/var-eval-short.mk         |  18 +-
 contrib/bmake/unit-tests/var-op-expand.exp         |   8 +-
 contrib/bmake/unit-tests/var-op-expand.mk          | 105 +++-
 contrib/bmake/unit-tests/vardebug.exp              |   4 +-
 contrib/bmake/unit-tests/varmisc.mk                |  12 +-
 contrib/bmake/unit-tests/varmod-assign.exp         |  12 -
 contrib/bmake/unit-tests/varmod-assign.mk          | 107 ++--
 contrib/bmake/unit-tests/varmod-defined.exp        |   2 +-
 contrib/bmake/unit-tests/varmod-defined.mk         |   5 +-
 contrib/bmake/unit-tests/varmod-gmtime.exp         |  10 +-
 contrib/bmake/unit-tests/varmod-indirect.exp       |   2 +-
 contrib/bmake/unit-tests/varmod-localtime.exp      |  10 +-
 contrib/bmake/unit-tests/varmod-localtime.mk       |   2 +-
 contrib/bmake/unit-tests/varmod-loop-delete.exp    |   4 +
 contrib/bmake/unit-tests/varmod-loop-delete.mk     |  33 ++
 contrib/bmake/unit-tests/varmod-loop-varname.exp   |  16 +-
 contrib/bmake/unit-tests/varmod-loop-varname.mk    |   7 +-
 contrib/bmake/unit-tests/varmod-loop.exp           |   6 +-
 contrib/bmake/unit-tests/varmod-loop.mk            |  10 +-
 contrib/bmake/unit-tests/varmod-order-numeric.exp  |   1 +
 contrib/bmake/unit-tests/varmod-order-numeric.mk   |  54 ++
 contrib/bmake/unit-tests/varmod-order-reverse.mk   |   9 +-
 contrib/bmake/unit-tests/varmod-order-shuffle.mk   |  19 +-
 contrib/bmake/unit-tests/varmod-order-string.exp   |   1 +
 contrib/bmake/unit-tests/varmod-order-string.mk    |  28 +
 contrib/bmake/unit-tests/varmod-order.exp          |  25 +-
 contrib/bmake/unit-tests/varmod-order.mk           |  91 ++-
 contrib/bmake/unit-tests/varmod-root.exp           |  10 -
 contrib/bmake/unit-tests/varmod-root.mk            |  37 +-
 contrib/bmake/unit-tests/varmod-select-words.mk    |   5 +-
 contrib/bmake/unit-tests/varmod-subst.mk           |  15 +-
 contrib/bmake/unit-tests/varmod-to-separator.exp   |   4 +-
 contrib/bmake/unit-tests/varmod-unique.mk          |  35 +-
 .../unit-tests/varname-dot-make-save_dollars.mk    | 130 ++++-
 contrib/bmake/unit-tests/varname-dot-suffixes.exp  |  39 ++
 contrib/bmake/unit-tests/varname-dot-suffixes.mk   | 104 ++++
 contrib/bmake/unit-tests/varname-empty.exp         |   4 -
 contrib/bmake/util.c                               |  82 ++-
 contrib/bmake/var.c                                | 631 ++++++++++++---------
 166 files changed, 4798 insertions(+), 1888 deletions(-)

diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog
index 35235e1f8205..5eb2d7c5bb4a 100644
--- a/contrib/bmake/ChangeLog
+++ b/contrib/bmake/ChangeLog
@@ -1,3 +1,234 @@
+2021-12-15  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* cond.c: fix mem leak in CondParser_Leaf
+
+2021-12-12  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211212
+	Merge with NetBSD make, pick up
+	o rename Parse_SetInput to Parse_PushInput
+	o remove remove period from end of error messages and warnings
+	to be more consistent
+	o arch.c: use simpler memory management for parsing archive members
+	o cond.c: rework and reduce recursion
+	o for.c: rename some functions to better reflect purpose
+	o suff.c: add Suff_NamesStr to provide .SUFFIXES as a string.
+	o var.c: in parse errors, mark whitespace more clearly
+	inline ParseEmptyArg into CondParser_FuncCallEmpty
+	minimize calls to LazyBuf_Get in ParseVarnameLong
+	treat .SUFFIXES as a read-only variable
+
+2021-12-07  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211207
+	Merge with NetBSD make, pick up
+	o inline HashIter_Init
+	o parse.c: inline common subexpression in ParseRawLine
+	o var.c: merge branches for modifiers ':D' and ':U'
+	extract common code into Expr_Words
+	extract common code into Expr_Str
+	move low-level implementation details out of Var_Parse
+	
+2021-12-06  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211206
+	Merge with NetBSD make, pick up
+	o add unit-tests/varmod-loop-delete
+	o for.c: inline Str_Words - reduce memory allocation
+	o parse.c: do not try to expand fixed variable names
+	only allocate the name of an included file if necessary
+	clean up ParseInclude
+	o var.c: fix use-after-free in modifier ':@'
+	save a memory allocation in each modifier ':O' and ':u'
+	save a memory allocation in the modifier ':[...]'
+	in UnexportVars, replace Str_Words with Substring_Words to
+	reduce allocations and copying.
+	
+2021-12-04  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211204
+	Merge with NetBSD make, pick up
+	o flesh out a number of tests
+	o replace enums with bitfields, this simplifies a lot of code.
+	o var.c: refactor ParseModifierPartSubst
+
+2021-10-24  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211024
+	Merge with NetBSD make, pick up
+	o Punt on write errors - ENOSPC etc.
+
+2021-10-22  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* configure.in: use_defshell, set both DEFSHELL_INDEX
+	and defshell_path if appropriate.
+	This makes it easier to use say the KSH specification with
+	and alternate path for the shell.
+	
+	* configure.in compat.c: for SCO we need to force UseShell
+
+	* configure.in: SCO /bin/sh is not usable, provide a list of
+	alternatives for use as .SHELL.
+	We still have to mark some tests as broken, plus more if we end up
+	with ksh as .SHELL.
+	Issue a warning about skipped tests.
+
+	* boot-strap: leave TOOL_DIFF to configure
+
+	* configure.in: on SCO native cc is not usable,
+	gcc is to be found in /usr/gnu/bin
+	and while ancient is at least able to compile bmake.
+	Thus we add /usr/gnu/bin to PATH if it exists, and later
+	check if $CC would have been found via $PATH.
+	If not we set CC to the full path of $CC.
+	Also gnu diff is known to support -u, so if it exists use it.
+
+	* configure.in: move getopt to AC_REPLACE_FUNCS
+	also add AC_C_INLINE - in an attempt to compile using
+	native cc on SCO.
+
+	* configure.in: check for stresep as well as strsep, since we
+	define the later to the former if necessary, and if we have to
+	provide stresep we also need to provide a prototype.
+
+	* configure.in: we no longer need to worry about
+	sys/cdefs.h providing __RCSID which simplifies things quite a bit.
+
+	* make.h: make sure we have __RCSID
+
+	* unit-tests/Makefile.config.in: add TOOL_DIFF so configure
+	can control it.
+
+2021-10-20  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION: 20211020
+	Merge with NetBSD make, pick up
+	o confirm sync of unit-tests
+
+2021-10-18  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* configure.in: check if timezone Europe/Berlin is supported
+	if not try UTC-1
+	* configure.in: if .OBJDIR is $srcdir/obj we need to create a
+	symlink unit-tests -> ../unit-tests/obj so that
+	unit-tests/Makefile.config is put in the right place.
+	* refine filtering of .OBJDIR in unit-tests
+	
+2021-10-16  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* Fix unit-tests on Minix 3.2.0
+	o job.c: do not punt if read of token pipe fails for EAGAIN.
+	On Minix at least, we are not ready to read the childExitJob pipe
+	when poll says we are.
+	There should actually be no reason for this pipe to be
+	non-blocking, but while that works fine on {Net,Free}BSD it
+	breaks another test case on Minix.
+	o unit-tests/Makefile: deal with variants of error messages
+	  and use of obj as .OBJDIR
+
+2021-10-14  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* configure.in: add sigaction to AC_REPLACE_FUNCS
+	we also need to check for sigaddset etc just for the benefit of
+	sigact.c
+
+	* Add sigact.c as sigaction.c so this "just works".
+	This should have been done back when bmake_signal started using
+	sigaction (I only just noticed that sigact.c wasn't here ;-)
+	Note: I no longer have access to any system where this would matter.
+
+2021-10-13  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211011
+
+	* Makefile: cleanup a little
+
+	* configure.in: check for sigsetmask
+
+2021-10-01  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20211001
+	Merge with NetBSD make, pick up
+	o reduce locations reducing text size
+	o remove unnecessary const
+	o cond.c: fix lint warning on i386
+	do not allow unquoted 'left == right' after modifier ':?'
+	o hash.c: fix build for DEBUG_HASH_LOOKUP
+	o var.c: fix memory leak in error case of the ':?' modifier
+	
+2021-09-11  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210911
+	Merge with NetBSD make, pick up
+	o var.c: replace remaining ModChain_ShouldEval with Expr_ShouldEval
+
+2021-09-08  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210906
+	Merge with NetBSD make, pick up
+	o more unit tests
+	o lint cleanup
+	o rename some functions to better fit purpose
+	o for.c: cleanup - remove unnecessary optimization
+	  fix embedded newlines
+	o parse.c: correct case for CVS/RCS
+	
+2021-08-11  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210808
+	Merge with NetBSD make, pick up
+	o var.c: remove redundant initialization in ApplyModifier_Order
+
+	* mk/options.mk: issue warning for incorrect usage
+
+2021-08-03  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* var.c: use long for :On if we don't have a 64bit int type 
+
+	* VERSION (_MAKE_VERSION): 20210803
+	Merge with NetBSD make, pick up
+	o rework varmod-order tests to avoid qsort instability
+	o make.1: clarify :On entry
+
+2021-07-31  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210731
+	Merge with NetBSD make, pick up
+	o fix some lint issues
+	o more unit tests
+	o var.c: rework of ApplyModifier_Order
+
+2021-07-30  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* util.c: add strto*l if HAVE_STRTO*L not defined
+
+	* VERSION (_MAKE_VERSION): 20210730
+	Merge with NetBSD make, pick up
+	o var.c: add :On and :Orn for numeric sort
+	  disabled if no 64bit type available.
+	o _strtol.h: to implement strto*l functions
+
+2021-07-04  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210704
+	Merge with NetBSD make, pick up
+	o unit-tests: fix some tests to be more portable
+	- job-output-null not all shells do the same number of write calls
+	- objdir-writable if TMPDIR is set; /tmp may not be usable
+
+2021-07-01  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210701
+	Merge with NetBSD make, pick up
+	o unit-tests: allow for BROKEN_TESTS to list TESTS to be skipped;
+	some tests just cannot work in some environments.
+	o buf.c: simpler upper bound for length in Buf_AddInt
+	o cond.c: fix grammar in error message for malformed conditional
+	o for.c: prevent newline injection (from ${.newline}) in .for loops
+	o var.c: use more practical data type in RegexReplace
+	(avoid need for %zu)
+	extract RegexReplace from ModifyWord_SubstRegex
+	
 2021-06-21  Simon J Gerraty  <sjg@beast.crufty.net>
 
 	* VERSION (_MAKE_VERSION): 20210621
diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES
index dc0f6f33c763..53b961468db6 100644
--- a/contrib/bmake/FILES
+++ b/contrib/bmake/FILES
@@ -7,6 +7,7 @@ PSD.doc/Makefile
 PSD.doc/tutorial.ms
 README
 VERSION
+_strtol.h
 aclocal.m4
 arch.c
 bmake.1
@@ -23,8 +24,6 @@ configure.in
 dir.c
 dir.h
 dirname.c
-enum.c
-enum.h
 filemon/filemon.h
 filemon/filemon_dev.c
 filemon/filemon_ktrace.c
@@ -61,6 +60,8 @@ pathnames.h
 ranlib.h
 realpath.c
 setenv.c
+sigact.h
+sigaction.c
 sigcompat.c
 str.c
 str.h
@@ -322,6 +323,8 @@ unit-tests/directive-for-escape.exp
 unit-tests/directive-for-escape.mk
 unit-tests/directive-for-generating-endif.exp
 unit-tests/directive-for-generating-endif.mk
+unit-tests/directive-for-if.exp
+unit-tests/directive-for-if.mk
 unit-tests/directive-for-lines.exp
 unit-tests/directive-for-lines.mk
 unit-tests/directive-for-null.exp
@@ -684,6 +687,8 @@ unit-tests/varmod-l-name-to-value.exp
 unit-tests/varmod-l-name-to-value.mk
 unit-tests/varmod-localtime.exp
 unit-tests/varmod-localtime.mk
+unit-tests/varmod-loop-delete.exp
+unit-tests/varmod-loop-delete.mk
 unit-tests/varmod-loop-varname.exp
 unit-tests/varmod-loop-varname.mk
 unit-tests/varmod-loop.exp
@@ -694,10 +699,14 @@ unit-tests/varmod-match.exp
 unit-tests/varmod-match.mk
 unit-tests/varmod-no-match.exp
 unit-tests/varmod-no-match.mk
+unit-tests/varmod-order-numeric.exp
+unit-tests/varmod-order-numeric.mk
 unit-tests/varmod-order-reverse.exp
 unit-tests/varmod-order-reverse.mk
 unit-tests/varmod-order-shuffle.exp
 unit-tests/varmod-order-shuffle.mk
+unit-tests/varmod-order-string.exp
+unit-tests/varmod-order-string.mk
 unit-tests/varmod-order.exp
 unit-tests/varmod-order.mk
 unit-tests/varmod-path.exp
@@ -814,6 +823,8 @@ unit-tests/varname-dot-path.exp
 unit-tests/varname-dot-path.mk
 unit-tests/varname-dot-shell.exp
 unit-tests/varname-dot-shell.mk
+unit-tests/varname-dot-suffixes.exp
+unit-tests/varname-dot-suffixes.mk
 unit-tests/varname-dot-targets.exp
 unit-tests/varname-dot-targets.mk
 unit-tests/varname-empty.exp
diff --git a/contrib/bmake/Makefile b/contrib/bmake/Makefile
index 38ccb8a6a636..82d9db52af76 100644
--- a/contrib/bmake/Makefile
+++ b/contrib/bmake/Makefile
@@ -1,4 +1,4 @@
-#	$Id: Makefile,v 1.114 2020/11/13 21:47:25 sjg Exp $
+#	$Id: Makefile,v 1.117 2021/12/04 18:51:30 sjg Exp $
 
 PROG=	bmake
 
@@ -8,7 +8,6 @@ SRCS= \
 	compat.c \
 	cond.c \
 	dir.c \
-	enum.c \
 	for.c \
 	hash.c \
 	job.c \
@@ -92,10 +91,11 @@ isBSD44:=${BSD44_LIST:M${OS}}
 .if ${isBSD44} == ""
 MANTARGET= cat
 INSTALL?=${srcdir}/install-sh
-.if (${MACHINE} == "sun386")
+.if ${MACHINE} == "sun386"
 # even I don't have one of these anymore :-)
 CFLAGS+= -DPORTAR
-.elif (${MACHINE} != "sunos")
+.elif ${OS} != "SunOS"
+# assume the worst
 SRCS+= sigcompat.c
 CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART
 .endif
@@ -131,7 +131,7 @@ EXTRACT_MAN=no
 MAN= ${PROG}.1
 MAN1= ${MAN}
 
-.if (${PROG} != "make")
+.if ${PROG} != "make"
 CLEANFILES+= my.history
 .if make(${MAN}) || !exists(${srcdir}/${MAN})
 my.history:
@@ -189,11 +189,12 @@ main.o: ${srcdir}/VERSION
 CONFIGURE_DEPS += ${.CURDIR}/VERSION
 # we do not need or want the generated makefile
 CONFIGURE_ARGS += --without-makefile
+AUTOCONF_GENERATED_MAKEFILE = Makefile.config
 .include <autoconf.mk>
 .endif
-SHARE_MK?=${SHAREDIR}/mk
-MKSRC=${srcdir}/mk
-INSTALL?=${srcdir}/install-sh
+SHARE_MK ?= ${SHAREDIR}/mk
+MKSRC = ${srcdir}/mk
+INSTALL ?= ${srcdir}/install-sh
 
 .if ${MK_INSTALL_MK} == "yes"
 install: install-mk
diff --git a/contrib/bmake/Makefile.config.in b/contrib/bmake/Makefile.config.in
index 55cd60ca80ba..042b2570ff88 100644
--- a/contrib/bmake/Makefile.config.in
+++ b/contrib/bmake/Makefile.config.in
@@ -4,7 +4,7 @@ _MAKE_VERSION?=@_MAKE_VERSION@
 
 prefix?= @prefix@
 srcdir= @srcdir@
-CC?= @CC@
+CC= @CC@
 @force_machine@MACHINE?= @machine@
 @force_machine_arch@MACHINE_ARCH?= @machine_arch@
 DEFAULT_SYS_PATH?= @default_sys_path@
diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION
index 7c28f11013b7..8485c4810bf0 100644
--- a/contrib/bmake/VERSION
+++ b/contrib/bmake/VERSION
@@ -1,2 +1,2 @@
 # keep this compatible with sh and make
-_MAKE_VERSION=20210621
+_MAKE_VERSION=20211212
diff --git a/contrib/bmake/_strtol.h b/contrib/bmake/_strtol.h
new file mode 100644
index 000000000000..51c71490ae57
--- /dev/null
+++ b/contrib/bmake/_strtol.h
@@ -0,0 +1,213 @@
+/* $NetBSD: _strtol.h,v 1.11 2017/07/06 21:08:44 joerg Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Original version ID:
+ * NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp
+ */
+
+/*
+ * function template for strtol, strtoll and strtoimax.
+ *
+ * parameters:
+ *	_FUNCNAME : function name
+ *      __INT     : return type
+ *      __INT_MIN : lower limit of the return type
+ *      __INT_MAX : upper limit of the return type
+ */
+#if defined(_KERNEL) || defined(_STANDALONE) || defined(HAVE_NBTOOL_CONFIG_H) || defined(BCS_ONLY)
+__INT
+_FUNCNAME(const char *nptr, char **endptr, int base)
+#else
+#include <locale.h>
+#include "setlocale_local.h"
+#define INT_FUNCNAME_(pre, name, post)	pre ## name ## post
+#define INT_FUNCNAME(pre, name, post)	INT_FUNCNAME_(pre, name, post)
+
+static __INT
+INT_FUNCNAME(_int_, _FUNCNAME, _l)(const char *nptr, char **endptr,
+				   int base, locale_t loc)
+#endif
+{
+	const char *s;
+	__INT acc, cutoff;
+	unsigned char c;
+	int i, neg, any, cutlim;
+
+	_DIAGASSERT(nptr != NULL);
+	/* endptr may be NULL */
+
+	/* check base value */
+	if (base && (base < 2 || base > 36)) {
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+		errno = EINVAL;
+		if (endptr != NULL)
+			/* LINTED interface specification */
+			*endptr = __UNCONST(nptr);
+		return 0;
+#else
+		panic("%s: invalid base %d", __func__, base);
+#endif
+	}
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	s = nptr;
+#if defined(_KERNEL) || defined(_STANDALONE) || \
+    defined(HAVE_NBTOOL_CONFIG_H) || defined(BCS_ONLY)
+	do {
+		c = *s++;
+	} while (isspace(c));
+#else
+	do {
+		c = *s++;
+	} while (isspace_l(c, loc));
+#endif
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X') &&
+	    ((s[1] >= '0' && s[1] <= '9') ||
+	     (s[1] >= 'a' && s[1] <= 'f') ||
+	     (s[1] >= 'A' && s[1] <= 'F'))) {
+		c = s[1];
+		s += 2;
+		base = 16;
+#if 0
+	} else if ((base == 0 || base == 2) &&
+	    c == '0' && (*s == 'b' || *s == 'B') &&
+	    (s[1] >= '0' && s[1] <= '1')) {
+		c = s[1];
+		s += 2;
+		base = 2;
+#endif
+	} else if (base == 0)
+		base = (c == '0' ? 8 : 10);
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set any if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = (__INT)(neg ? __INT_MIN : __INT_MAX);
+	cutlim = (int)(cutoff % base);
+	cutoff /= base;
+	if (neg) {
+		if (cutlim > 0) {
+			cutlim -= base;
+			cutoff += 1;
+		}
+		cutlim = -cutlim;
+	}
+	for (acc = 0, any = 0;; c = *s++) {
+		if (c >= '0' && c <= '9')
+			i = c - '0';
+		else if (c >= 'a' && c <= 'z')
+			i = (c - 'a') + 10;
+		else if (c >= 'A' && c <= 'Z')
+			i = (c - 'A') + 10;
+		else
+			break;
+		if (i >= base)
+			break;
+		if (any < 0)
+			continue;
+		if (neg) {
+			if (acc < cutoff || (acc == cutoff && i > cutlim)) {
+				acc = __INT_MIN;
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+				any = -1;
+				errno = ERANGE;
+#else
+				any = 0;
+				break;
+#endif
+			} else {
+				any = 1;
+				acc *= base;
+				acc -= i;
+			}
+		} else {
+			if (acc > cutoff || (acc == cutoff && i > cutlim)) {
+				acc = __INT_MAX;
+#if !defined(_KERNEL) && !defined(_STANDALONE)
+				any = -1;
+				errno = ERANGE;
+#else
+				any = 0;
+				break;
+#endif
+			} else {
+				any = 1;
+				acc *= base;
+				acc += i;
+			}
+		}
+	}
+	if (endptr != NULL)
+		/* LINTED interface specification */
+		*endptr = __UNCONST(any ? s - 1 : nptr);
+	return(acc);
+}
+
+#if !defined(_KERNEL) && !defined(_STANDALONE) && \
+    !defined(HAVE_NBTOOL_CONFIG_H) && !defined(BCS_ONLY)
+__INT
+_FUNCNAME(const char *nptr, char **endptr, int base)
+{
+	return INT_FUNCNAME(_int_, _FUNCNAME, _l)(nptr, endptr, base, _current_locale());
+}
+
+__INT
+INT_FUNCNAME(, _FUNCNAME, _l)(const char *nptr, char **endptr, int base, locale_t loc)
+{
+	return INT_FUNCNAME(_int_, _FUNCNAME, _l)(nptr, endptr, base, loc);
+}
+#endif
diff --git a/contrib/bmake/arch.c b/contrib/bmake/arch.c
index 6d9dd60dfbe9..515713af7af7 100644
--- a/contrib/bmake/arch.c
+++ b/contrib/bmake/arch.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: arch.c,v 1.200 2021/05/30 21:16:54 rillig Exp $	*/
+/*	$NetBSD: arch.c,v 1.205 2021/12/12 22:41:47 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.200 2021/05/30 21:16:54 rillig Exp $");
+MAKE_RCSID("$NetBSD: arch.c,v 1.205 2021/12/12 22:41:47 rillig Exp $");
 
 typedef struct List ArchList;
 typedef struct ListNode ArchListNode;
@@ -250,7 +250,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 	char *cp;		/* Pointer into line */
 	GNode *gn;		/* New node */
 	MFStr libName;		/* Library-part of specification */
-	char *memName;		/* Member-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
@@ -301,7 +301,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 
 		pp_skip_whitespace(&cp);
 
-		memName = cp;
+		mem = FStr_InitRefer(cp);
 		while (*cp != '\0' && *cp != ')' && !ch_isspace(*cp)) {
 			if (*cp == '$') {
 				/* Expand nested variable expressions. */
@@ -342,7 +342,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 		/*
 		 * If we didn't move anywhere, we must be done
 		 */
-		if (cp == memName)
+		if (cp == mem.str)
 			break;
 
 		saveChar = *cp;
@@ -363,22 +363,22 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 		 */
 		if (doSubst) {
 			char *fullName;
-			char *p;
-			char *unexpandedMemName = memName;
+			char *p, *expandedMem;
+			const char *unexpandedMem = mem.str;
 
-			(void)Var_Subst(memName, scope, VARE_UNDEFERR,
-			    &memName);
+			(void)Var_Subst(mem.str, scope, VARE_UNDEFERR,
+			    &expandedMem);
 			/* TODO: handle errors */
+			mem = FStr_InitOwn(expandedMem);
 
 			/*
 			 * Now form an archive spec and recurse to deal with
 			 * nested variables and multi-word variable values.
 			 */
-			fullName = FullName(libName.str, memName);
+			fullName = FullName(libName.str, mem.str);
 			p = fullName;
 
-			if (strchr(memName, '$') != NULL &&
-			    strcmp(memName, unexpandedMemName) == 0) {
+			if (strcmp(mem.str, unexpandedMem) == 0) {
 				/*
 				 * Must contain dynamic sources, so we can't
 				 * deal with it now. Just create an ARCHV node
@@ -398,9 +398,9 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 			free(fullName);
 			/* XXX: does unexpandedMemName leak? */
 
-		} else if (Dir_HasWildcards(memName)) {
+		} else if (Dir_HasWildcards(mem.str)) {
 			StringList members = LST_INIT;
-			SearchPath_Expand(&dirSearchPath, memName, &members);
+			SearchPath_Expand(&dirSearchPath, mem.str, &members);
 
 			while (!Lst_IsEmpty(&members)) {
 				char *member = Lst_Dequeue(&members);
@@ -416,7 +416,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 			Lst_Done(&members);
 
 		} else {
-			char *fullname = FullName(libName.str, memName);
+			char *fullname = FullName(libName.str, mem.str);
 			gn = Targ_GetNode(fullname);
 			free(fullname);
 
@@ -430,8 +430,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 			gn->type |= OP_ARCHV;
 			Lst_Append(gns, gn);
 		}
-		if (doSubst)
-			free(memName);
+		FStr_Done(&mem);
 
 		*cp = saveChar;
 	}
@@ -600,14 +599,14 @@ ArchStatMember(const char *archive, const char *member, bool addToCache)
 		if (strncmp(memName, AR_EFMT1, sizeof AR_EFMT1 - 1) == 0 &&
 		    ch_isdigit(memName[sizeof AR_EFMT1 - 1])) {
 
-			int elen = atoi(memName + sizeof AR_EFMT1 - 1);
+			size_t elen = atoi(memName + sizeof AR_EFMT1 - 1);
 
-			if ((unsigned int)elen > MAXPATHLEN)
+			if (elen > MAXPATHLEN)
 				goto badarch;
-			if (fread(memName, (size_t)elen, 1, arch) != 1)
+			if (fread(memName, elen, 1, arch) != 1)
 				goto badarch;
 			memName[elen] = '\0';
-			if (fseek(arch, -elen, SEEK_CUR) != 0)
+			if (fseek(arch, -(long)elen, SEEK_CUR) != 0)
 				goto badarch;
 			if (DEBUG(ARCH) || DEBUG(MAKE))
 				debug_printf(
@@ -839,14 +838,15 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
 		if (strncmp(out_arh->AR_NAME, AR_EFMT1, sizeof AR_EFMT1 - 1) ==
 		    0 &&
 		    (ch_isdigit(out_arh->AR_NAME[sizeof AR_EFMT1 - 1]))) {
-			int elen = atoi(&out_arh->AR_NAME[sizeof AR_EFMT1 - 1]);
+			size_t elen = atoi(
+			    &out_arh->AR_NAME[sizeof AR_EFMT1 - 1]);
 			char ename[MAXPATHLEN + 1];
 
-			if ((unsigned int)elen > MAXPATHLEN) {
+			if (elen > MAXPATHLEN) {
 				fclose(arch);
 				return NULL;
 			}
-			if (fread(ename, (size_t)elen, 1, arch) != 1) {
+			if (fread(ename, elen, 1, arch) != 1) {
 				fclose(arch);
 				return NULL;
 			}
@@ -859,14 +859,14 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
 			if (strncmp(ename, member, len) == 0) {
 				/* Found as extended name */
 				if (fseek(arch,
-					  -(long)sizeof(struct ar_hdr) - elen,
-					  SEEK_CUR) != 0) {
+				    -(long)(sizeof(struct ar_hdr) - elen),
+				    SEEK_CUR) != 0) {
 					fclose(arch);
 					return NULL;
 				}
 				return arch;
 			}
-			if (fseek(arch, -elen, SEEK_CUR) != 0) {
+			if (fseek(arch, -(long)elen, SEEK_CUR) != 0) {
 				fclose(arch);
 				return NULL;
 			}
@@ -882,7 +882,7 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
 		 */
 		out_arh->AR_SIZE[sizeof out_arh->AR_SIZE - 1] = '\0';
 		size = (int)strtol(out_arh->AR_SIZE, NULL, 10);
-		if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) {
+		if (fseek(arch, (size + 1) & ~1L, SEEK_CUR) != 0) {
 			fclose(arch);
 			return NULL;
 		}
@@ -991,12 +991,12 @@ Arch_UpdateMemberMTime(GNode *gn)
 			const char *nameEnd = strchr(nameStart, ')');
 			size_t nameLen = (size_t)(nameEnd - nameStart);
 
-			if ((pgn->flags & REMAKE) &&
+			if (pgn->flags.remake &&
 			    strncmp(nameStart, gn->name, nameLen) == 0) {
 				Arch_UpdateMTime(pgn);
 				gn->mtime = pgn->mtime;
 			}
-		} else if (pgn->flags & REMAKE) {
+		} else if (pgn->flags.remake) {
 			/*
 			 * Something which isn't a library depends on the
 			 * existence of this target, so it needs to exist.
@@ -1036,6 +1036,35 @@ Arch_FindLib(GNode *gn, SearchPath *path)
 #endif
 }
 
+/* ARGSUSED */
+static bool
+RanlibOODate(const GNode *gn MAKE_ATTR_UNUSED)
+{
*** 11523 LINES SKIPPED ***