Author: sjg
Date: Fri Nov 20 03:54:37 2020
New Revision: 367860
URL: https://svnweb.freebsd.org/changeset/base/367860

Log:
  Import bmake-20201117
  
  o allow env var MAKE_OBJDIR_CHECK_WRITABLE=no to skip writable
    checks in InitObjdir.  Explicit .OBJDIR target always allows
    read-only directory.
  
  o Fix building and unit-tests on non-BSD.
  
  o More code cleanup and refactoring.
  
  o More unit tests

Added:
  vendor/NetBSD/bmake/dist/missing/
  vendor/NetBSD/bmake/dist/missing/sys/
  vendor/NetBSD/bmake/dist/missing/sys/cdefs.h   (contents, props changed)
  vendor/NetBSD/bmake/dist/unit-tests/cmd-errors-lint.exp
  vendor/NetBSD/bmake/dist/unit-tests/cmd-errors-lint.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/cmd-errors.exp
  vendor/NetBSD/bmake/dist/unit-tests/cmd-errors.mk   (contents, props changed)
  vendor/NetBSD/bmake/dist/unit-tests/cmdline-undefined.exp
  vendor/NetBSD/bmake/dist/unit-tests/cmdline-undefined.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-and-lint.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-and-lint.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-or-lint.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-or-lint.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/directive-if-nested.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-if-nested.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/gnode-submake.exp
  vendor/NetBSD/bmake/dist/unit-tests/gnode-submake.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/job-flags.exp
  vendor/NetBSD/bmake/dist/unit-tests/job-flags.mk   (contents, props changed)
  vendor/NetBSD/bmake/dist/unit-tests/objdir-writable.exp
  vendor/NetBSD/bmake/dist/unit-tests/objdir-writable.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/opt-touch-jobs.exp
  vendor/NetBSD/bmake/dist/unit-tests/opt-touch-jobs.mk   (contents, props 
changed)
  vendor/NetBSD/bmake/dist/unit-tests/suff-self.exp
  vendor/NetBSD/bmake/dist/unit-tests/suff-self.mk   (contents, props changed)
  vendor/NetBSD/bmake/dist/unit-tests/varparse-errors.exp
  vendor/NetBSD/bmake/dist/unit-tests/varparse-errors.mk   (contents, props 
changed)
Deleted:
  vendor/NetBSD/bmake/dist/unit-tests/directives.exp
  vendor/NetBSD/bmake/dist/unit-tests/directives.mk
  vendor/NetBSD/bmake/dist/unit-tests/varshell.exp
  vendor/NetBSD/bmake/dist/unit-tests/varshell.mk
Modified:
  vendor/NetBSD/bmake/dist/ChangeLog
  vendor/NetBSD/bmake/dist/FILES
  vendor/NetBSD/bmake/dist/Makefile
  vendor/NetBSD/bmake/dist/Makefile.config.in
  vendor/NetBSD/bmake/dist/VERSION
  vendor/NetBSD/bmake/dist/arch.c
  vendor/NetBSD/bmake/dist/bmake.1
  vendor/NetBSD/bmake/dist/bmake.cat1
  vendor/NetBSD/bmake/dist/boot-strap
  vendor/NetBSD/bmake/dist/buf.c
  vendor/NetBSD/bmake/dist/buf.h
  vendor/NetBSD/bmake/dist/compat.c
  vendor/NetBSD/bmake/dist/cond.c
  vendor/NetBSD/bmake/dist/configure
  vendor/NetBSD/bmake/dist/configure.in
  vendor/NetBSD/bmake/dist/dir.c
  vendor/NetBSD/bmake/dist/dir.h
  vendor/NetBSD/bmake/dist/filemon/filemon_dev.c
  vendor/NetBSD/bmake/dist/filemon/filemon_ktrace.c
  vendor/NetBSD/bmake/dist/for.c
  vendor/NetBSD/bmake/dist/hash.c
  vendor/NetBSD/bmake/dist/hash.h
  vendor/NetBSD/bmake/dist/job.c
  vendor/NetBSD/bmake/dist/job.h
  vendor/NetBSD/bmake/dist/lst.c
  vendor/NetBSD/bmake/dist/lst.h
  vendor/NetBSD/bmake/dist/main.c
  vendor/NetBSD/bmake/dist/make-bootstrap.sh.in
  vendor/NetBSD/bmake/dist/make.1
  vendor/NetBSD/bmake/dist/make.c
  vendor/NetBSD/bmake/dist/make.h
  vendor/NetBSD/bmake/dist/make_malloc.h
  vendor/NetBSD/bmake/dist/meta.c
  vendor/NetBSD/bmake/dist/metachar.h
  vendor/NetBSD/bmake/dist/mk/ChangeLog
  vendor/NetBSD/bmake/dist/mk/install-mk
  vendor/NetBSD/bmake/dist/mk/meta.autodep.mk
  vendor/NetBSD/bmake/dist/mk/meta2deps.sh
  vendor/NetBSD/bmake/dist/nonints.h
  vendor/NetBSD/bmake/dist/parse.c
  vendor/NetBSD/bmake/dist/str.c
  vendor/NetBSD/bmake/dist/suff.c
  vendor/NetBSD/bmake/dist/targ.c
  vendor/NetBSD/bmake/dist/unit-tests/Makefile
  vendor/NetBSD/bmake/dist/unit-tests/archive-suffix.mk
  vendor/NetBSD/bmake/dist/unit-tests/archive.mk
  vendor/NetBSD/bmake/dist/unit-tests/cmd-interrupt.mk
  vendor/NetBSD/bmake/dist/unit-tests/cmdline.mk
  vendor/NetBSD/bmake/dist/unit-tests/comment.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-numeric-eq.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-numeric-eq.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-numeric.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-numeric.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-string.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-string.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-unary.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-cmp-unary.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-func-commands.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-func-defined.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-func-defined.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-func-empty.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-func-empty.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-func.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-func.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-late.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-not.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-not.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-parentheses.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-op-parentheses.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-op.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-op.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-short.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-number.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-number.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-plain.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-string.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-string.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-var.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-token-var.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond-undef-lint.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond-undef-lint.mk
  vendor/NetBSD/bmake/dist/unit-tests/cond1.exp
  vendor/NetBSD/bmake/dist/unit-tests/cond1.mk
  vendor/NetBSD/bmake/dist/unit-tests/dep-double-colon.mk
  vendor/NetBSD/bmake/dist/unit-tests/dep-exclam.mk
  vendor/NetBSD/bmake/dist/unit-tests/depsrc-ignore.mk
  vendor/NetBSD/bmake/dist/unit-tests/depsrc-make.mk
  vendor/NetBSD/bmake/dist/unit-tests/depsrc-optional.exp
  vendor/NetBSD/bmake/dist/unit-tests/depsrc-optional.mk
  vendor/NetBSD/bmake/dist/unit-tests/depsrc-precious.mk
  vendor/NetBSD/bmake/dist/unit-tests/depsrc-usebefore.mk
  vendor/NetBSD/bmake/dist/unit-tests/depsrc.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-begin.exp
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-begin.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-error.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-ignore.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-interrupt.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-main.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-makeflags.exp
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-makeflags.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-silent.exp
  vendor/NetBSD/bmake/dist/unit-tests/deptgt-silent.mk
  vendor/NetBSD/bmake/dist/unit-tests/deptgt.exp
  vendor/NetBSD/bmake/dist/unit-tests/deptgt.mk
  vendor/NetBSD/bmake/dist/unit-tests/dir.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-elif.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-elif.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-else.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-else.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-endif.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-export-env.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-export-gmake.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-export-literal.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-export.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-export.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-for.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-for.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-if.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-if.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-ifdef.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-ifdef.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-ifmake.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-ifmake.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-include.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-include.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-info.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-info.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-sinclude.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-undef.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-undef.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-unexport-env.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-unexport.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-unexport.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive-warning.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive-warning.mk
  vendor/NetBSD/bmake/dist/unit-tests/directive.exp
  vendor/NetBSD/bmake/dist/unit-tests/directive.mk
  vendor/NetBSD/bmake/dist/unit-tests/dollar.exp
  vendor/NetBSD/bmake/dist/unit-tests/dollar.mk
  vendor/NetBSD/bmake/dist/unit-tests/envfirst.mk
  vendor/NetBSD/bmake/dist/unit-tests/error.exp
  vendor/NetBSD/bmake/dist/unit-tests/error.mk
  vendor/NetBSD/bmake/dist/unit-tests/escape.mk
  vendor/NetBSD/bmake/dist/unit-tests/forloop.exp
  vendor/NetBSD/bmake/dist/unit-tests/forloop.mk
  vendor/NetBSD/bmake/dist/unit-tests/forsubst.mk
  vendor/NetBSD/bmake/dist/unit-tests/include-sub.mk
  vendor/NetBSD/bmake/dist/unit-tests/moderrs.mk
  vendor/NetBSD/bmake/dist/unit-tests/modmisc.mk
  vendor/NetBSD/bmake/dist/unit-tests/modts.mk
  vendor/NetBSD/bmake/dist/unit-tests/modword.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-chdir.exp
  vendor/NetBSD/bmake/dist/unit-tests/opt-chdir.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-debug-jobs.exp
  vendor/NetBSD/bmake/dist/unit-tests/opt-debug-jobs.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-ignore.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-keep-going.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-no-action.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-query.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-touch.exp
  vendor/NetBSD/bmake/dist/unit-tests/opt-touch.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-var-expanded.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-var-literal.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt-warnings-as-errors.exp
  vendor/NetBSD/bmake/dist/unit-tests/opt-warnings-as-errors.mk
  vendor/NetBSD/bmake/dist/unit-tests/opt.exp
  vendor/NetBSD/bmake/dist/unit-tests/opt.mk
  vendor/NetBSD/bmake/dist/unit-tests/order.mk
  vendor/NetBSD/bmake/dist/unit-tests/recursive.exp
  vendor/NetBSD/bmake/dist/unit-tests/recursive.mk
  vendor/NetBSD/bmake/dist/unit-tests/sh-leading-at.exp
  vendor/NetBSD/bmake/dist/unit-tests/sh-leading-at.mk
  vendor/NetBSD/bmake/dist/unit-tests/sh-leading-hyphen.mk
  vendor/NetBSD/bmake/dist/unit-tests/sh-leading-plus.mk
  vendor/NetBSD/bmake/dist/unit-tests/sh-meta-chars.mk
  vendor/NetBSD/bmake/dist/unit-tests/use-inference.mk
  vendor/NetBSD/bmake/dist/unit-tests/var-class-local.exp
  vendor/NetBSD/bmake/dist/unit-tests/var-class-local.mk
  vendor/NetBSD/bmake/dist/unit-tests/var-op-assign.exp
  vendor/NetBSD/bmake/dist/unit-tests/var-op-assign.mk
  vendor/NetBSD/bmake/dist/unit-tests/var-op-expand.exp
  vendor/NetBSD/bmake/dist/unit-tests/var-op-expand.mk
  vendor/NetBSD/bmake/dist/unit-tests/var-op-shell.exp
  vendor/NetBSD/bmake/dist/unit-tests/var-op-shell.mk
  vendor/NetBSD/bmake/dist/unit-tests/var-op-sunsh.mk
  vendor/NetBSD/bmake/dist/unit-tests/vardebug.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmisc.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-defined.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod-defined.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-exclam-shell.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-ifelse.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod-ifelse.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-loop.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod-loop.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-match.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-order-shuffle.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-shell.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod-shell.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-subst.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod-subst.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-to-abs.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod-to-abs.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-to-lower.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-to-separator.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod-undefined.mk
  vendor/NetBSD/bmake/dist/unit-tests/varmod.exp
  vendor/NetBSD/bmake/dist/unit-tests/varmod.mk
  vendor/NetBSD/bmake/dist/unit-tests/varname-dot-shell.exp
  vendor/NetBSD/bmake/dist/unit-tests/varname-empty.exp
  vendor/NetBSD/bmake/dist/unit-tests/varname-makefile.exp
  vendor/NetBSD/bmake/dist/unit-tests/varname-makefile.mk
  vendor/NetBSD/bmake/dist/unit-tests/varname-vpath.exp
  vendor/NetBSD/bmake/dist/unit-tests/varname-vpath.mk
  vendor/NetBSD/bmake/dist/unit-tests/varname.exp
  vendor/NetBSD/bmake/dist/unit-tests/varname.mk
  vendor/NetBSD/bmake/dist/unit-tests/varparse-undef-partial.mk
  vendor/NetBSD/bmake/dist/util.c
  vendor/NetBSD/bmake/dist/var.c

Modified: vendor/NetBSD/bmake/dist/ChangeLog
==============================================================================
--- vendor/NetBSD/bmake/dist/ChangeLog  Fri Nov 20 03:33:30 2020        
(r367859)
+++ vendor/NetBSD/bmake/dist/ChangeLog  Fri Nov 20 03:54:37 2020        
(r367860)
@@ -1,3 +1,78 @@
+2020-11-17  Simon J Gerraty  <s...@beast.crufty.net>
+
+       * VERSION (_MAKE_VERSION): 20201117
+       Merge with NetBSD make, pick up
+       o fix some unit-tests when dash is .SHELL
+       o rename Targ_NewGN to GNode_New
+       o make some GNode functions const
+       o main.c: call Targ_Init before Var_Init
+       cleanup PrintOnError, getTmpdir and ParseBoolean
+       o var.c: fix error message of failed :!cmd! modifier
+
+2020-11-14  Simon J Gerraty  <s...@beast.crufty.net>
+
+       * VERSION (_MAKE_VERSION): 20201114
+       Merge with NetBSD make, pick up
+       o replace a few HashTable_CreateEntry with HashTable_Set
+       o clean up cached_stats
+       o rename DEFAULT to defaultNode
+       o remove redundant struct make_stat
+       o cond.c: in lint mode, check for ".else <cond>"
+       use bitset for IfState
+       replace large switch with if-else in Cond_EvalLine
+       o job.c: clean up JobExec, JobStart, JobDoOutput
+       use stderr for error message about failed touch
+       clean up Job_Touch
+       replace macro DBPRINTF with JobPrintln
+       rename JobState to JobStatus
+       main.c: switch cache for realpath from GNode to HashTable
+       clean up Fatal
+       clean up InitDefSysIncPath
+       use progname instead of hard-coded 'make' in warning
+       rename Main_SetVarObjdir to SetVarObjdir
+       make.1: document the -S option
+       make.c: fix debug output for GNode details
+       use symbolic names in debug output of GNodes
+
+2020-11-12  Simon J Gerraty  <s...@beast.crufty.net>
+
+       * configure.in: fix --with-force-machine-arch
+
+       * VERSION (_MAKE_VERSION): 20201112
+       Merge with NetBSD make, pick up
+       o allow env var MAKE_OBJDIR_CHECK_WRITABLE=no to skip writable
+       checks in InitObjdir.  Explicit .OBJDIR target always allows
+       read-only directory.
+       o cond.c: clean up Cond_EvalLine
+
+2020-11-11  Simon J Gerraty  <s...@beast.crufty.net>
+
+       * VERSION (_MAKE_VERSION): 20201111
+       Merge with NetBSD make, pick up
+       o more unit-tests
+       o style cleanup
+       remove redundant parentheses from sizeof operator
+       replace character literal 0 with '\0'.
+       replace pointer literal 0 with NULL.
+       remove redundant parentheses.
+       replace (expr & mask) == 0 with !(expr & mask).
+       use strict typing in conditions of the form !var
+       o rename Make_OODate to GNode_IsOODate
+       o rename Make_TimeStamp to GNode_UpdateYoungestChild
+       o rename Var_Set_with_flags to Var_SetWithFlags
+       o rename dieQuietly to shouldDieQuietly
+       o buf.c: make API of Buf_Init simpler
+       o compat.c: clean up Compat_Make, Compat_RunCommand,
+       CompatDeleteTarget and CompatInterrupt
+       o cond.c: in lint mode, only allow '&&' and '||', not '&' and '|'
+       clean up CondParser_Comparison
+       o main.c: rename getBoolean and s2Boolean
+       rename MAKEFILE_PREFERENCE for consistency
+       o parse.c: replace strstr in ParseMaybeSubMake with optimized code
+       o var.c: rename VARE_ASSIGN to VARE_KEEP_DOLLAR
+       replace emptyString with allocated empty string
+       error out on unclosed expressions after the colon
+
 2020-11-01  Simon J Gerraty  <s...@beast.crufty.net>
 
        * VERSION (_MAKE_VERSION): 20201101

Modified: vendor/NetBSD/bmake/dist/FILES
==============================================================================
--- vendor/NetBSD/bmake/dist/FILES      Fri Nov 20 03:33:30 2020        
(r367859)
+++ vendor/NetBSD/bmake/dist/FILES      Fri Nov 20 03:54:37 2020        
(r367860)
@@ -75,8 +75,14 @@ unit-tests/archive-suffix.exp
 unit-tests/archive-suffix.mk
 unit-tests/archive.exp
 unit-tests/archive.mk
+unit-tests/cmd-errors-lint.exp
+unit-tests/cmd-errors-lint.mk
+unit-tests/cmd-errors.exp
+unit-tests/cmd-errors.mk
 unit-tests/cmd-interrupt.exp
 unit-tests/cmd-interrupt.mk
+unit-tests/cmdline-undefined.exp
+unit-tests/cmdline-undefined.mk
 unit-tests/cmdline.exp
 unit-tests/cmdline.mk
 unit-tests/comment.exp
@@ -115,10 +121,14 @@ unit-tests/cond-func.exp
 unit-tests/cond-func.mk
 unit-tests/cond-late.exp
 unit-tests/cond-late.mk
+unit-tests/cond-op-and-lint.exp
+unit-tests/cond-op-and-lint.mk
 unit-tests/cond-op-and.exp
 unit-tests/cond-op-and.mk
 unit-tests/cond-op-not.exp
 unit-tests/cond-op-not.mk
+unit-tests/cond-op-or-lint.exp
+unit-tests/cond-op-or-lint.mk
 unit-tests/cond-op-or.exp
 unit-tests/cond-op-or.mk
 unit-tests/cond-op-parentheses.exp
@@ -287,6 +297,8 @@ unit-tests/directive-for.exp
 unit-tests/directive-for.mk
 unit-tests/directive-hyphen-include.exp
 unit-tests/directive-hyphen-include.mk
+unit-tests/directive-if-nested.exp
+unit-tests/directive-if-nested.mk
 unit-tests/directive-if.exp
 unit-tests/directive-if.mk
 unit-tests/directive-ifdef.exp
@@ -315,8 +327,6 @@ unit-tests/directive-warning.exp
 unit-tests/directive-warning.mk
 unit-tests/directive.exp
 unit-tests/directive.mk
-unit-tests/directives.exp
-unit-tests/directives.mk
 unit-tests/dollar.exp
 unit-tests/dollar.mk
 unit-tests/doterror.exp
@@ -341,6 +351,8 @@ unit-tests/forloop.exp
 unit-tests/forloop.mk
 unit-tests/forsubst.exp
 unit-tests/forsubst.mk
+unit-tests/gnode-submake.exp
+unit-tests/gnode-submake.mk
 unit-tests/hanoi-include.exp
 unit-tests/hanoi-include.mk
 unit-tests/impsrc.exp
@@ -349,6 +361,8 @@ unit-tests/include-main.exp
 unit-tests/include-main.mk
 unit-tests/include-sub.mk
 unit-tests/include-subsub.mk
+unit-tests/job-flags.exp
+unit-tests/job-flags.mk
 unit-tests/job-output-long-lines.exp
 unit-tests/job-output-long-lines.mk
 unit-tests/lint.exp
@@ -365,6 +379,8 @@ 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
 unit-tests/opt-backwards.mk
 unit-tests/opt-chdir.exp
@@ -447,6 +463,8 @@ unit-tests/opt-raw.exp
 unit-tests/opt-raw.mk
 unit-tests/opt-silent.exp
 unit-tests/opt-silent.mk
+unit-tests/opt-touch-jobs.exp
+unit-tests/opt-touch-jobs.mk
 unit-tests/opt-touch.exp
 unit-tests/opt-touch.mk
 unit-tests/opt-tracefile.exp
@@ -517,6 +535,8 @@ unit-tests/suff-main.exp
 unit-tests/suff-main.mk
 unit-tests/suff-rebuild.exp
 unit-tests/suff-rebuild.mk
+unit-tests/suff-self.exp
+unit-tests/suff-self.mk
 unit-tests/suff-transform-endless.exp
 unit-tests/suff-transform-endless.mk
 unit-tests/suff-transform-expand.exp
@@ -737,14 +757,14 @@ unit-tests/varname.exp
 unit-tests/varname.mk
 unit-tests/varparse-dynamic.exp
 unit-tests/varparse-dynamic.mk
+unit-tests/varparse-errors.exp
+unit-tests/varparse-errors.mk
 unit-tests/varparse-mod.exp
 unit-tests/varparse-mod.mk
 unit-tests/varparse-undef-partial.exp
 unit-tests/varparse-undef-partial.mk
 unit-tests/varquote.exp
 unit-tests/varquote.mk
-unit-tests/varshell.exp
-unit-tests/varshell.mk
 util.c
 var.c
 wait.h

Modified: vendor/NetBSD/bmake/dist/Makefile
==============================================================================
--- vendor/NetBSD/bmake/dist/Makefile   Fri Nov 20 03:33:30 2020        
(r367859)
+++ vendor/NetBSD/bmake/dist/Makefile   Fri Nov 20 03:54:37 2020        
(r367860)
@@ -1,4 +1,4 @@
-#      $Id: Makefile,v 1.113 2020/10/26 17:55:09 sjg Exp $
+#      $Id: Makefile,v 1.114 2020/11/13 21:47:25 sjg Exp $
 
 PROG=  bmake
 
@@ -48,6 +48,12 @@ CFLAGS+= -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"
 CFLAGS+= -I. -I${srcdir} ${XDEFS} -DMAKE_NATIVE
 CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
 COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\""
+
+.for x in FORCE_MACHINE FORCE_MACHINE_ARCH
+.ifdef $x
+COPTS.main.c+= "-D$x=\"${$x}\""
+.endif
+.endfor
 
 # meta mode can be useful even without filemon
 # should be set by now

Modified: vendor/NetBSD/bmake/dist/Makefile.config.in
==============================================================================
--- vendor/NetBSD/bmake/dist/Makefile.config.in Fri Nov 20 03:33:30 2020        
(r367859)
+++ vendor/NetBSD/bmake/dist/Makefile.config.in Fri Nov 20 03:54:37 2020        
(r367860)
@@ -5,8 +5,8 @@ _MAKE_VERSION?=@_MAKE_VERSION@
 prefix?= @prefix@
 srcdir= @srcdir@
 CC?= @CC@
-MACHINE?= @machine@
-MACHINE_ARCH?= @machine_arch@
+@force_machine@MACHINE?= @machine@
+@force_machine_arch@MACHINE_ARCH?= @machine_arch@
 DEFAULT_SYS_PATH?= @default_sys_path@
 
 CPPFLAGS+= @CPPFLAGS@

Modified: vendor/NetBSD/bmake/dist/VERSION
==============================================================================
--- vendor/NetBSD/bmake/dist/VERSION    Fri Nov 20 03:33:30 2020        
(r367859)
+++ vendor/NetBSD/bmake/dist/VERSION    Fri Nov 20 03:54:37 2020        
(r367860)
@@ -1,2 +1,2 @@
 # keep this compatible with sh and make
-_MAKE_VERSION=20201101
+_MAKE_VERSION=20201117

Modified: vendor/NetBSD/bmake/dist/arch.c
==============================================================================
--- vendor/NetBSD/bmake/dist/arch.c     Fri Nov 20 03:33:30 2020        
(r367859)
+++ vendor/NetBSD/bmake/dist/arch.c     Fri Nov 20 03:54:37 2020        
(r367860)
@@ -1,4 +1,4 @@
-/*     $NetBSD: arch.c,v 1.151 2020/10/31 18:41:07 rillig Exp $        */
+/*     $NetBSD: arch.c,v 1.177 2020/11/14 21:29:44 rillig Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -68,38 +68,38 @@
  * SUCH DAMAGE.
  */
 
-/*-
- * arch.c --
- *     Functions to manipulate libraries, archives and their members.
+/* Manipulate libraries, archives and their members.
  *
- *     Once again, cacheing/hashing comes into play in the manipulation
- * of archives. The first time an archive is referenced, all of its members'
- * headers are read and hashed and the archive closed again. All hashed
- * archives are kept on a list which is searched each time an archive member
- * is referenced.
+ * The first time an archive is referenced, all of its members' headers are
+ * read and cached and the archive closed again.  All cached archives are kept
+ * on a list which is searched each time an archive member is referenced.
  *
  * The interface to this module is:
+ *
+ *     Arch_Init       Initialize this module.
+ *
+ *     Arch_End        Clean up this module.
+ *
  *     Arch_ParseArchive
- *                     Given an archive specification, return a list
- *                     of GNode's, one for each member in the spec.
- *                     FALSE is returned if the specification is
- *                     invalid for some reason.
+ *                     Parse an archive specification such as
+ *                     "archive.a(member1 member2)".
  *
  *     Arch_Touch      Alter the modification time of the archive
  *                     member described by the given node to be
- *                     the current time.
+ *                     the time when make was started.
  *
  *     Arch_TouchLib   Update the modification time of the library
  *                     described by the given node. This is special
  *                     because it also updates the modification time
  *                     of the library's table of contents.
  *
- *     Arch_MTime      Find the modification time of a member of
- *                     an archive *in the archive*. The time is also
- *                     placed in the member's GNode. Returns the
- *                     modification time.
+ *     Arch_UpdateMTime
+ *                     Find the modification time of a member of
+ *                     an archive *in the archive* and place it in the
+ *                     member's GNode.
  *
- *     Arch_MemTime    Find the modification time of a member of
+ *     Arch_UpdateMemberMTime
+ *                     Find the modification time of a member of
  *                     an archive. Called when the member doesn't
  *                     already exist. Looks in the archive for the
  *                     modification time. Returns the modification
@@ -109,12 +109,7 @@
  *                     library name in the GNode should be in
  *                     -l<name> format.
  *
- *     Arch_LibOODate  Special function to decide if a library node
- *                     is out-of-date.
- *
- *     Arch_Init       Initialize this module.
- *
- *     Arch_End        Clean up this module.
+ *     Arch_LibOODate  Decide if a library node is out-of-date.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -151,17 +146,8 @@ struct ar_hdr {
 #include "dir.h"
 
 /*     "@(#)arch.c     8.2 (Berkeley) 1/2/94"  */
-MAKE_RCSID("$NetBSD: arch.c,v 1.151 2020/10/31 18:41:07 rillig Exp $");
+MAKE_RCSID("$NetBSD: arch.c,v 1.177 2020/11/14 21:29:44 rillig Exp $");
 
-#ifdef TARGET_MACHINE
-#undef MAKE_MACHINE
-#define MAKE_MACHINE TARGET_MACHINE
-#endif
-#ifdef TARGET_MACHINE_ARCH
-#undef MAKE_MACHINE_ARCH
-#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH
-#endif
-
 typedef struct List ArchList;
 typedef struct ListNode ArchListNode;
 
@@ -230,39 +216,37 @@ ArchFree(void *ap)
 #endif
 
 
-/*-
- *-----------------------------------------------------------------------
- * Arch_ParseArchive --
- *     Parse the archive specification in the given line and find/create
- *     the nodes for the specified archive members, placing their nodes
- *     on the given list.
+/*
+ * Parse an archive specification such as "archive.a(member1 member2.${EXT})",
+ * adding nodes for the expanded members to nodeLst.  Nodes are created as
+ * necessary.
  *
  * Input:
- *     linePtr         Pointer to start of specification
- *     nodeLst         Lst on which to place the nodes
- *     ctxt            Context in which to expand variables
+ *     pp              The start of the specification.
+ *     nodeLst         The list on which to place the nodes.
+ *     ctxt            The context in which to expand variables.
  *
- * Results:
- *     TRUE if it was a valid specification. The linePtr is updated
- *     to point to the first non-space after the archive spec. The
- *     nodes for the members are placed on the given list.
- *-----------------------------------------------------------------------
+ * Output:
+ *     return          TRUE if it was a valid specification.
+ *     *pp             Points to the first non-space after the archive spec.
+ *     *nodeLst        Nodes for the members have been added.
  */
 Boolean
-Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, GNode *ctxt)
+Arch_ParseArchive(char **pp, GNodeList *nodeLst, GNode *ctxt)
 {
     char *cp;                  /* Pointer into line */
     GNode *gn;                 /* New node */
     char *libName;             /* Library-part of specification */
+    char *libName_freeIt = NULL;
     char *memName;             /* Member-part of specification */
     char saveChar;             /* Ending delimiter of member-name */
-    Boolean subLibName;                /* TRUE if libName should have/had
-                                * variable substitution performed on it */
+    Boolean expandLibName;     /* Whether the parsed libName contains
+                                * variable expressions that need to be
+                                * expanded */
 
-    libName = *linePtr;
+    libName = *pp;
+    expandLibName = FALSE;
 
-    subLibName = FALSE;
-
     for (cp = libName; *cp != '(' && *cp != '\0';) {
        if (*cp == '$') {
            /*
@@ -274,7 +258,8 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
            const char *result;
            Boolean isError;
 
-           (void)Var_Parse(&nested_p, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+           /* XXX: is expanded twice: once here and once below */
+           (void)Var_Parse(&nested_p, ctxt, VARE_WANTRES | VARE_UNDEFERR,
                            &result, &result_freeIt);
            /* TODO: handle errors */
            isError = result == var_Error;
@@ -282,16 +267,17 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
            if (isError)
                return FALSE;
 
-           subLibName = TRUE;
+           expandLibName = TRUE;
            cp += nested_p - cp;
        } else
            cp++;
     }
 
     *cp++ = '\0';
-    if (subLibName) {
-       (void)Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES, &libName);
+    if (expandLibName) {
+       (void)Var_Subst(libName, ctxt, VARE_WANTRES | VARE_UNDEFERR, &libName);
        /* TODO: handle errors */
+       libName_freeIt = libName;
     }
 
 
@@ -317,7 +303,7 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
                Boolean isError;
                const char *nested_p = cp;
 
-               (void)Var_Parse(&nested_p, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+               (void)Var_Parse(&nested_p, ctxt, VARE_WANTRES | VARE_UNDEFERR,
                                &result, &freeIt);
                /* TODO: handle errors */
                isError = result == var_Error;
@@ -339,7 +325,7 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
         * so it's better to return failure than allow such things to happen
         */
        if (*cp == '\0') {
-           printf("No closing parenthesis in archive specification\n");
+           Parse_Error(PARSE_FATAL, "No closing parenthesis in archive 
specification");
            return FALSE;
        }
 
@@ -370,7 +356,7 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
            char *sacrifice;
            char *oldMemName = memName;
 
-           (void)Var_Subst(memName, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+           (void)Var_Subst(memName, ctxt, VARE_WANTRES | VARE_UNDEFERR,
                            &memName);
            /* TODO: handle errors */
 
@@ -381,7 +367,8 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
             */
            buf = sacrifice = str_concat4(libName, "(", memName, ")");
 
-           if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) {
+           if (strchr(memName, '$') != NULL &&
+               strcmp(memName, oldMemName) == 0) {
                /*
                 * Must contain dynamic sources, so we can't deal with it now.
                 * Just create an ARCHV node for the thing and let
@@ -437,17 +424,12 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
        *cp = saveChar;
     }
 
-    /*
-     * If substituted libName, free it now, since we need it no longer.
-     */
-    if (subLibName) {
-       free(libName);
-    }
+    free(libName_freeIt);
 
     cp++;                      /* skip the ')' */
-    /* We promised that linePtr would be set up at the next non-space. */
+    /* We promised that pp would be set up at the next non-space. */
     pp_skip_whitespace(&cp);
-    *linePtr = cp;
+    *pp = cp;
     return TRUE;
 }
 
@@ -457,15 +439,17 @@ Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, 
  * Input:
  *     archive         Path to the archive
  *     member          Name of member; only its basename is used.
- *     hash            TRUE if archive should be hashed if not already so.
+ *     addToCache      TRUE if archive should be cached if not already so.
  *
  * Results:
- *     The ar_hdr for the member.
+ *     The ar_hdr for the member, or NULL.
+ *
+ * See ArchFindMember for an almost identical copy of this code.
  */
 static struct ar_hdr *
-ArchStatMember(const char *archive, const char *member, Boolean hash)
+ArchStatMember(const char *archive, const char *member, Boolean addToCache)
 {
-#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME) - 1)
+#define AR_MAX_NAME_LEN (sizeof arh.AR_NAME - 1)
     FILE *arch;                        /* Stream to archive */
     size_t size;               /* Size of archive member */
     char magic[SARMAG];
@@ -484,8 +468,8 @@ ArchStatMember(const char *archive, const char *member
        member = lastSlash + 1;
 
     for (ln = archives->first; ln != NULL; ln = ln->next) {
-       const Arch *archPtr = ln->datum;
-       if (strcmp(archPtr->name, archive) == 0)
+       const Arch *a = ln->datum;
+       if (strcmp(a->name, archive) == 0)
            break;
     }
 
@@ -505,17 +489,17 @@ ArchStatMember(const char *archive, const char *member
            if (len > AR_MAX_NAME_LEN) {
                len = AR_MAX_NAME_LEN;
                snprintf(copy, sizeof copy, "%s", member);
+               hdr = HashTable_FindValue(&ar->members, copy);
            }
-           hdr = HashTable_FindValue(&ar->members, copy);
            return hdr;
        }
     }
 
-    if (!hash) {
+    if (!addToCache) {
        /*
-        * Caller doesn't want the thing hashed, just use ArchFindMember
+        * Caller doesn't want the thing cached, just use ArchFindMember
         * to read the header for the member out and close down the stream
-        * again. Since the archive is not to be hashed, we assume there's
+        * again. Since the archive is not to be cached, we assume there's
         * no need to allocate extra room for the header we're returning,
         * so just declare it static.
         */
@@ -541,98 +525,92 @@ ArchStatMember(const char *archive, const char *member
      * We use the ARMAG string to make sure this is an archive we
      * can handle...
      */
-    if ((fread(magic, SARMAG, 1, arch) != 1) ||
-       (strncmp(magic, ARMAG, SARMAG) != 0)) {
-       fclose(arch);
+    if (fread(magic, SARMAG, 1, arch) != 1 ||
+       strncmp(magic, ARMAG, SARMAG) != 0) {
+       (void)fclose(arch);
        return NULL;
     }
 
-    ar = bmake_malloc(sizeof(Arch));
+    ar = bmake_malloc(sizeof *ar);
     ar->name = bmake_strdup(archive);
     ar->fnametab = NULL;
     ar->fnamesize = 0;
     HashTable_Init(&ar->members);
     memName[AR_MAX_NAME_LEN] = '\0';
 
-    while (fread((char *)&arh, sizeof(struct ar_hdr), 1, arch) == 1) {
-       if (strncmp(arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) {
-           /*
-            * The header is bogus, so the archive is bad
-            * and there's no way we can recover...
-            */
+    while (fread(&arh, sizeof arh, 1, arch) == 1) {
+       char *nameend;
+
+       /* If the header is bogus, there's no way we can recover. */
+       if (strncmp(arh.AR_FMAG, ARFMAG, sizeof arh.AR_FMAG) != 0)
            goto badarch;
-       } else {
-           char *nameend;
 
-           /*
-            * We need to advance the stream's pointer to the start of the
-            * next header. Files are padded with newlines to an even-byte
-            * boundary, so we need to extract the size of the file from the
-            * 'size' field of the header and round it up during the seek.
-            */
-           arh.AR_SIZE[sizeof(arh.AR_SIZE) - 1] = '\0';
-           size = (size_t)strtol(arh.ar_size, NULL, 10);
+       /*
+        * We need to advance the stream's pointer to the start of the
+        * next header. Files are padded with newlines to an even-byte
+        * boundary, so we need to extract the size of the file from the
+        * 'size' field of the header and round it up during the seek.
+        */
+       arh.AR_SIZE[sizeof arh.AR_SIZE - 1] = '\0';
+       size = (size_t)strtol(arh.AR_SIZE, NULL, 10);
 
-           memcpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
-           nameend = memName + AR_MAX_NAME_LEN;
-           while (*nameend == ' ') {
-               nameend--;
-           }
-           nameend[1] = '\0';
+       memcpy(memName, arh.AR_NAME, sizeof arh.AR_NAME);
+       nameend = memName + AR_MAX_NAME_LEN;
+       while (nameend > memName && *nameend == ' ')
+           nameend--;
+       nameend[1] = '\0';
 
 #ifdef SVR4ARCHIVES
+       /*
+        * svr4 names are slash terminated. Also svr4 extended AR format.
+        */
+       if (memName[0] == '/') {
            /*
-            * svr4 names are slash terminated. Also svr4 extended AR format.
+            * svr4 magic mode; handle it
             */
-           if (memName[0] == '/') {
-               /*
-                * svr4 magic mode; handle it
-                */
-               switch (ArchSVR4Entry(ar, memName, size, arch)) {
-               case -1:        /* Invalid data */
-                   goto badarch;
-               case 0:         /* List of files entry */
-                   continue;
-               default:        /* Got the entry */
-                   break;
-               }
-           } else {
-               if (nameend[0] == '/')
-                   nameend[0] = '\0';
+           switch (ArchSVR4Entry(ar, memName, size, arch)) {
+           case -1:    /* Invalid data */
+               goto badarch;
+           case 0:             /* List of files entry */
+               continue;
+           default:    /* Got the entry */
+               break;
            }
+       } else {
+           if (nameend[0] == '/')
+               nameend[0] = '\0';
+       }
 #endif
 
 #ifdef AR_EFMT1
-           /*
-            * BSD 4.4 extended AR format: #1/<namelen>, with name as the
-            * first <namelen> bytes of the file
-            */
-           if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
-               ch_isdigit(memName[sizeof(AR_EFMT1) - 1])) {
+       /*
+        * BSD 4.4 extended AR format: #1/<namelen>, with name as the
+        * first <namelen> bytes of the file
+        */
+       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]);
+           int elen = atoi(memName + sizeof AR_EFMT1 - 1);
 
-               if ((unsigned int)elen > MAXPATHLEN)
-                   goto badarch;
-               if (fread(memName, (size_t)elen, 1, arch) != 1)
-                   goto badarch;
-               memName[elen] = '\0';
-               if (fseek(arch, -elen, SEEK_CUR) != 0)
-                   goto badarch;
-               if (DEBUG(ARCH) || DEBUG(MAKE)) {
-                   debug_printf("ArchStat: Extended format entry for %s\n",
-                                memName);
-               }
-           }
+           if ((unsigned int)elen > MAXPATHLEN)
+               goto badarch;
+           if (fread(memName, (size_t)elen, 1, arch) != 1)
+               goto badarch;
+           memName[elen] = '\0';
+           if (fseek(arch, -elen, SEEK_CUR) != 0)
+               goto badarch;
+           if (DEBUG(ARCH) || DEBUG(MAKE))
+               debug_printf("ArchStatMember: Extended format entry for %s\n",
+                            memName);
+       }
 #endif
 
-           {
-               HashEntry *he;
-               he = HashTable_CreateEntry(&ar->members, memName, NULL);
-               HashEntry_Set(he, bmake_malloc(sizeof(struct ar_hdr)));
-               memcpy(HashEntry_Get(he), &arh, sizeof(struct ar_hdr));
-           }
+       {
+           struct ar_hdr *cached_hdr = bmake_malloc(sizeof *cached_hdr);
+           memcpy(cached_hdr, &arh, sizeof arh);
+           HashTable_Set(&ar->members, memName, cached_hdr);
        }
+
        if (fseek(arch, ((long)size + 1) & ~1, SEEK_CUR) != 0)
            goto badarch;
     }
@@ -643,7 +621,7 @@ ArchStatMember(const char *archive, const char *member
 
     /*
      * Now that the archive has been read and cached, we can look into
-     * the hash table to find the desired member's header.
+     * the addToCache table to find the desired member's header.
      */
     return HashTable_FindValue(&ar->members, member);
 
@@ -674,15 +652,15 @@ badarch:
  *-----------------------------------------------------------------------
  */
 static int
-ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
+ArchSVR4Entry(Arch *ar, char *inout_name, size_t size, FILE *arch)
 {
 #define ARLONGNAMES1 "//"
 #define ARLONGNAMES2 "/ARFILENAMES"
     size_t entry;
     char *ptr, *eptr;
 
-    if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 ||
-       strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
+    if (strncmp(inout_name, ARLONGNAMES1, sizeof ARLONGNAMES1 - 1) == 0 ||
+       strncmp(inout_name, ARLONGNAMES2, sizeof ARLONGNAMES2 - 1) == 0) {
 
        if (ar->fnametab != NULL) {
            DEBUG0(ARCH, "Attempted to redefine an SVR4 name table\n");
@@ -711,51 +689,74 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE 
        return 0;
     }
 
-    if (name[1] == ' ' || name[1] == '\0')
+    if (inout_name[1] == ' ' || inout_name[1] == '\0')
        return 2;
 
-    entry = (size_t)strtol(&name[1], &eptr, 0);
-    if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
-       DEBUG1(ARCH, "Could not parse SVR4 name %s\n", name);
+    entry = (size_t)strtol(&inout_name[1], &eptr, 0);
+    if ((*eptr != ' ' && *eptr != '\0') || eptr == &inout_name[1]) {
+       DEBUG1(ARCH, "Could not parse SVR4 name %s\n", inout_name);
        return 2;
     }
     if (entry >= ar->fnamesize) {
        DEBUG2(ARCH, "SVR4 entry offset %s is greater than %lu\n",
-              name, (unsigned long)ar->fnamesize);
+              inout_name, (unsigned long)ar->fnamesize);
        return 2;
     }
 
-    DEBUG2(ARCH, "Replaced %s with %s\n", name, &ar->fnametab[entry]);
+    DEBUG2(ARCH, "Replaced %s with %s\n", inout_name, &ar->fnametab[entry]);
 
-    snprintf(name, MAXPATHLEN + 1, "%s", &ar->fnametab[entry]);
+    snprintf(inout_name, MAXPATHLEN + 1, "%s", &ar->fnametab[entry]);
     return 1;
 }
 #endif
 
 
-/*-
- *-----------------------------------------------------------------------
- * ArchFindMember --
- *     Locate a member of an archive, given the path of the archive and
- *     the path of the desired member. If the archive is to be modified,
- *     the mode should be "r+", if not, it should be "r".
- *     The passed struct ar_hdr structure is filled in.
+static Boolean
+ArchiveMember_HasName(const struct ar_hdr *hdr,
+                     const char *name, size_t namelen)
+{
+    const size_t ar_name_len = sizeof hdr->AR_NAME;
+    const char *ar_name = hdr->AR_NAME;
+
+    if (strncmp(ar_name, name, namelen) != 0)
+       return FALSE;
+
+    if (namelen >= ar_name_len)
+       return namelen == ar_name_len;
+
+    /* hdr->AR_NAME is space-padded to the right. */
+    if (ar_name[namelen] == ' ')
+       return TRUE;
+
+    /* 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;
+
+    return FALSE;
+}
+
+/* Locate a member of an archive, given the path of the archive and the path
+ * of the desired member.
  *
  * Input:
  *     archive         Path to the archive
  *     member          Name of member. If it is a path, only the last
  *                     component is used.
- *     arhPtr          Pointer to header structure to be filled in
- *     mode            The mode for opening the stream
+ *     out_arh         Archive header to be filled in
+ *     mode            "r" for read-only access, "r+" for read-write access
  *
- * Results:
- *     An FILE *, opened for reading and writing, positioned at the
- *     start of the member's struct ar_hdr, or NULL if the member was
- *     nonexistent. The current struct ar_hdr for member.
- *-----------------------------------------------------------------------
+ * Output:
+ *     return          The archive file, positioned at the start of the
+ *                     member's struct ar_hdr, or NULL if the member doesn't
+ *                     exist.
+ *     *out_arh        The current struct ar_hdr for member.
+ *
+ * See ArchStatMember for an almost identical copy of this code.
  */
 static FILE *
-ArchFindMember(const char *archive, const char *member, struct ar_hdr *arhPtr,
+ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
               const char *mode)
 {
     FILE *arch;                        /* Stream to archive */
@@ -772,8 +773,8 @@ ArchFindMember(const char *archive, const char *member
      * We use the ARMAG string to make sure this is an archive we
      * can handle...
      */
-    if ((fread(magic, SARMAG, 1, arch) != 1) ||
-       (strncmp(magic, ARMAG, SARMAG) != 0)) {
+    if (fread(magic, SARMAG, 1, arch) != 1 ||
+       strncmp(magic, ARMAG, SARMAG) != 0) {
        fclose(arch);
        return NULL;
     }
@@ -787,13 +788,13 @@ ArchFindMember(const char *archive, const char *member
        member = lastSlash + 1;
 
     len = tlen = strlen(member);
-    if (len > sizeof(arhPtr->AR_NAME)) {
-       tlen = sizeof(arhPtr->AR_NAME);
+    if (len > sizeof out_arh->AR_NAME) {
+       tlen = sizeof out_arh->AR_NAME;
     }
 
-    while (fread((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) == 1) {
+    while (fread(out_arh, sizeof *out_arh, 1, arch) == 1) {
 
-       if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof(arhPtr->AR_FMAG)) != 0) {
+       if (strncmp(out_arh->AR_FMAG, ARFMAG, sizeof out_arh->AR_FMAG) != 0) {
            /*
             * The header is bogus, so the archive is bad
             * and there's no way we can recover...
@@ -802,25 +803,21 @@ ArchFindMember(const char *archive, const char *member
            return NULL;
        }
 
-       if (strncmp(member, arhPtr->AR_NAME, tlen) == 0) {
-           /*
-            * If the member's name doesn't take up the entire 'name' field,
-            * we have to be careful of matching prefixes. Names are space-
-            * padded to the right, so if the character in 'name' at the end
-            * of the matched string is anything but a space, this isn't the
-            * member we sought.
-            */
-           if (tlen != sizeof arhPtr->AR_NAME && arhPtr->AR_NAME[tlen] != ' ')
-               goto skip;
+       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);
 
+       if (ArchiveMember_HasName(out_arh, member, len)) {
            /*
-            * To make life easier, we reposition the file at the start
+            * To make life easier for callers that want to update the
+            * archive, we reposition the file at the start
             * of the header we just read before we return the stream.
             * In a more general situation, it might be better to leave
             * the file at the actual member, rather than its header, but
-            * not here...
+            * not here.
             */
-           if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) {
+           if (fseek(arch, -(long)sizeof *out_arh, SEEK_CUR) != 0) {
                fclose(arch);
                return NULL;
            }
@@ -832,10 +829,10 @@ ArchFindMember(const char *archive, const char *member
         * BSD 4.4 extended AR format: #1/<namelen>, with name as the
         * first <namelen> bytes of the file
         */
-       if (strncmp(arhPtr->AR_NAME, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
-           ch_isdigit(arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1]))
+       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(&arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1]);
+           int elen = atoi(&out_arh->AR_NAME[sizeof AR_EFMT1 - 1]);
            char ename[MAXPATHLEN + 1];
 
            if ((unsigned int)elen > MAXPATHLEN) {
@@ -847,9 +844,9 @@ ArchFindMember(const char *archive, const char *member
                return NULL;
            }
            ename[elen] = '\0';
-           if (DEBUG(ARCH) || DEBUG(MAKE)) {
-               debug_printf("ArchFind: Extended format entry for %s\n", ename);
-           }
+           if (DEBUG(ARCH) || DEBUG(MAKE))
+               debug_printf("ArchFindMember: Extended format entry for %s\n",
+                            ename);
            if (strncmp(ename, member, len) == 0) {
                /* Found as extended name */
                if (fseek(arch, -(long)sizeof(struct ar_hdr) - elen,
@@ -866,7 +863,6 @@ ArchFindMember(const char *archive, const char *member
        }
 #endif
 
-skip:
        /*
         * This isn't the member we're after, so we need to advance the
         * stream's pointer to the start of the next header. Files are
@@ -874,113 +870,89 @@ skip:
         * extract the size of the file from the 'size' field of the
         * header and round it up during the seek.
         */
-       arhPtr->ar_size[sizeof(arhPtr->ar_size) - 1] = '\0';
-       size = (int)strtol(arhPtr->ar_size, NULL, 10);
+       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) {
            fclose(arch);
            return NULL;
        }
     }
 
-    /*
-     * We've looked everywhere, but the member is not to be found. Close the
-     * archive and return NULL -- an error.
-     */
     fclose(arch);
     return NULL;
 }
 
-/*-
- *-----------------------------------------------------------------------
- * Arch_Touch --
- *     Touch a member of an archive.
- *     The modification time of the entire archive is also changed.
- *     For a library, this could necessitate the re-ranlib'ing of the
- *     whole thing.
+/* Touch a member of an archive, on disk.
+ * The GNode's modification time is left as-is.
  *
+ * The st_mtime of the entire archive is also changed.
+ * For a library, it may be required to run ranlib after this.
+ *
  * Input:
  *     gn              Node of member to touch
  *
  * Results:
  *     The 'time' field of the member's header is updated.
- *-----------------------------------------------------------------------
  */
 void
 Arch_Touch(GNode *gn)
 {
-    FILE *arch;                /* Stream open to archive, positioned properly 
*/
-    struct ar_hdr arh; /* Current header describing member */
+    FILE *f;
+    struct ar_hdr arh;
 
-    arch = ArchFindMember(GNode_VarArchive(gn), GNode_VarMember(gn),
-                         &arh, "r+");
+    f = ArchFindMember(GNode_VarArchive(gn), GNode_VarMember(gn), &arh, "r+");
+    if (f == NULL)
+       return;
 
-    snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long)now);
-
-    if (arch != NULL) {
-       (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch);
-       fclose(arch);
-    }
+    snprintf(arh.ar_date, sizeof arh.ar_date, "%-ld", (unsigned long)now);
+    (void)fwrite(&arh, sizeof arh, 1, f);
+    fclose(f);                 /* TODO: handle errors */
 }
 
 /* Given a node which represents a library, touch the thing, making sure that
- * the table of contents also is touched.
+ * the table of contents is also touched.
  *
  * Both the modification time of the library and of the RANLIBMAG member are
- * set to 'now'.
- *
- * Input:
- *     gn              The node of the library to touch
- */
+ * set to 'now'. */
 void
-Arch_TouchLib(GNode *gn)
+Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED)
 {
 #ifdef RANLIBMAG

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to