git: 78968ce3ddbf - stable/13 - Merge bmake-20210206

Simon J. Gerraty sjg at FreeBSD.org
Mon Feb 15 16:55:29 UTC 2021


The branch stable/13 has been updated by sjg:

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

commit 78968ce3ddbf56ac7f7b548cfe8d39707f9989d8
Author:     Simon J. Gerraty <sjg at FreeBSD.org>
AuthorDate: 2021-02-11 06:01:59 +0000
Commit:     Simon J. Gerraty <sjg at FreeBSD.org>
CommitDate: 2021-02-15 16:53:34 +0000

    Merge bmake-20210206
    
    Changes of interest
    
      o unit-tests: use private TMPDIR to avoid errors from other users
      o avoid strdup in mkTempFile
      o always use vfork
      o job.c: do not create empty shell files in jobs mode
        reduce unnecessary calls to waitpid
      o cond.c: fix debug output for comparison operators in conditionals
    
    (cherry picked from commit dba7b0ef928af88caa38728a73657b837aeeac93)
    
    Approved by: re
---
 contrib/bmake/ChangeLog                            |  73 +++
 contrib/bmake/FILES                                |   6 +
 contrib/bmake/VERSION                              |   2 +-
 contrib/bmake/arch.c                               |  24 +-
 contrib/bmake/bmake.1                              |   6 +-
 contrib/bmake/bmake.cat1                           |   4 +-
 contrib/bmake/buf.c                                |  59 +-
 contrib/bmake/buf.h                                |  25 +-
 contrib/bmake/compat.c                             |  18 +-
 contrib/bmake/cond.c                               | 655 ++++++++++---------
 contrib/bmake/config.h.in                          |   3 +
 contrib/bmake/configure                            |  36 +-
 contrib/bmake/configure.in                         |  15 +-
 contrib/bmake/dir.c                                | 454 +++++++------
 contrib/bmake/dir.h                                |  10 +-
 contrib/bmake/enum.c                               |  16 +-
 contrib/bmake/enum.h                               |  33 +-
 contrib/bmake/filemon/filemon.h                    |   4 +-
 contrib/bmake/filemon/filemon_dev.c                |   6 +-
 contrib/bmake/filemon/filemon_ktrace.c             |  13 +-
 contrib/bmake/for.c                                | 253 ++++----
 contrib/bmake/hash.c                               |  13 +-
 contrib/bmake/job.c                                | 260 ++++----
 contrib/bmake/job.h                                |   3 +-
 contrib/bmake/lst.c                                |  17 +-
 contrib/bmake/lst.h                                |   4 +-
 contrib/bmake/main.c                               | 316 ++++-----
 contrib/bmake/make.1                               |   6 +-
 contrib/bmake/make.c                               | 154 +++--
 contrib/bmake/make.h                               | 104 +--
 contrib/bmake/make_malloc.c                        |   6 +-
 contrib/bmake/make_malloc.h                        |   4 +-
 contrib/bmake/meta.c                               |  87 +--
 contrib/bmake/metachar.c                           |   7 +-
 contrib/bmake/metachar.h                           |   6 +-
 contrib/bmake/mk/ChangeLog                         |   9 +
 contrib/bmake/mk/dirdeps.mk                        |  10 +-
 contrib/bmake/mk/install-mk                        |   4 +-
 contrib/bmake/mk/meta.stage.mk                     |   7 +-
 contrib/bmake/nonints.h                            |  58 +-
 contrib/bmake/parse.c                              | 306 ++++-----
 contrib/bmake/str.c                                |  22 +-
 contrib/bmake/suff.c                               |  66 +-
 contrib/bmake/targ.c                               |  30 +-
 contrib/bmake/trace.c                              |  10 +-
 contrib/bmake/trace.h                              |   6 +-
 contrib/bmake/unit-tests/Makefile                  |  80 ++-
 .../bmake/unit-tests/cmdline-redirect-stdin.exp    |   1 +
 contrib/bmake/unit-tests/cmdline-redirect-stdin.mk |  34 +
 contrib/bmake/unit-tests/cmdline.exp               |   4 +-
 contrib/bmake/unit-tests/cmdline.mk                |   4 +-
 contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp   |   1 -
 contrib/bmake/unit-tests/cond-cmp-numeric.exp      |   8 +-
 contrib/bmake/unit-tests/cond-cmp-string.exp       |   5 +-
 contrib/bmake/unit-tests/cond-cmp-string.mk        |  30 +-
 contrib/bmake/unit-tests/cond-func-defined.exp     |   6 +-
 contrib/bmake/unit-tests/cond-func.exp             |   9 +-
 contrib/bmake/unit-tests/cond-op-not.exp           |   5 +-
 contrib/bmake/unit-tests/cond-op-not.mk            |   9 +-
 contrib/bmake/unit-tests/cond-op-parentheses.exp   |   6 +-
 contrib/bmake/unit-tests/cond-op-parentheses.mk    |  19 +-
 contrib/bmake/unit-tests/cond-op.exp               |   4 +
 contrib/bmake/unit-tests/cond-op.mk                |  40 +-
 contrib/bmake/unit-tests/cond-token-plain.exp      |  31 +-
 contrib/bmake/unit-tests/cond-token-plain.mk       |  97 ++-
 contrib/bmake/unit-tests/cond-token-string.exp     |  20 +-
 contrib/bmake/unit-tests/cond-token-string.mk      |  47 +-
 contrib/bmake/unit-tests/cond1.exp                 |   2 +-
 contrib/bmake/unit-tests/dir.mk                    |   4 +-
 contrib/bmake/unit-tests/directive-error.exp       |   5 +-
 contrib/bmake/unit-tests/directive-error.mk        |  13 +-
 contrib/bmake/unit-tests/directive-export-impl.exp |   8 +-
 contrib/bmake/unit-tests/directive-for-escape.exp  |  43 +-
 contrib/bmake/unit-tests/directive-for-escape.mk   |  28 +-
 contrib/bmake/unit-tests/directive-ifdef.exp       |   2 +
 contrib/bmake/unit-tests/directive-ifdef.mk        |  17 +-
 .../bmake/unit-tests/directive-include-fatal.mk    |   4 +-
 contrib/bmake/unit-tests/envfirst.mk               |   4 +-
 contrib/bmake/unit-tests/export.exp                |   1 +
 contrib/bmake/unit-tests/gnode-submake.exp         |  16 +-
 contrib/bmake/unit-tests/include-main.exp          |   9 +-
 contrib/bmake/unit-tests/include-main.mk           |   6 +-
 contrib/bmake/unit-tests/include-subsub.mk         |   4 +-
 contrib/bmake/unit-tests/jobs-empty-commands.exp   |   2 +
 contrib/bmake/unit-tests/jobs-empty-commands.mk    |  18 +
 contrib/bmake/unit-tests/lint.mk                   |  13 +-
 contrib/bmake/unit-tests/objdir-writable.exp       |   6 +-
 contrib/bmake/unit-tests/opt-debug-graph1.exp      |  16 +-
 contrib/bmake/unit-tests/opt-debug-graph2.exp      |  92 ++-
 contrib/bmake/unit-tests/opt-debug-graph2.mk       |  22 +-
 contrib/bmake/unit-tests/opt-debug-graph3.exp      |  92 ++-
 contrib/bmake/unit-tests/opt-debug-graph3.mk       |  22 +-
 contrib/bmake/unit-tests/opt-no-action-touch.exp   |  11 +
 contrib/bmake/unit-tests/opt-no-action-touch.mk    |  48 ++
 contrib/bmake/unit-tests/opt-touch-jobs.mk         |   8 +-
 .../bmake/unit-tests/opt-warnings-as-errors.exp    |   4 +-
 contrib/bmake/unit-tests/opt-warnings-as-errors.mk |   7 +-
 contrib/bmake/unit-tests/suff-incomplete.exp       |   4 +-
 contrib/bmake/unit-tests/suff-main-several.exp     |  16 +-
 contrib/bmake/unit-tests/suff-transform-debug.exp  |   2 +-
 contrib/bmake/unit-tests/var-op-append.exp         |   6 +-
 contrib/bmake/unit-tests/var-op-append.mk          |  14 +-
 contrib/bmake/unit-tests/var-op-assign.exp         |   2 +-
 contrib/bmake/unit-tests/var-op-shell.exp          |   4 +-
 contrib/bmake/unit-tests/var-op-shell.mk           |  13 +-
 contrib/bmake/unit-tests/vardebug.exp              |  36 +-
 contrib/bmake/unit-tests/vardebug.mk               |   4 +-
 contrib/bmake/unit-tests/varmisc.mk                |  10 +-
 contrib/bmake/unit-tests/varmod-assign.mk          |   3 +-
 contrib/bmake/unit-tests/varmod-gmtime.exp         |  20 +-
 contrib/bmake/unit-tests/varmod-gmtime.mk          |  19 +-
 contrib/bmake/unit-tests/varmod-ifelse.mk          |   4 +-
 contrib/bmake/unit-tests/varmod-indirect.exp       |  32 +-
 contrib/bmake/unit-tests/varmod-localtime.exp      |  20 +-
 contrib/bmake/unit-tests/varmod-localtime.mk       |  21 +-
 contrib/bmake/unit-tests/varmod-loop.mk            |   6 +-
 contrib/bmake/unit-tests/varmod-match-escape.exp   |  16 +-
 contrib/bmake/unit-tests/varmod-match-escape.mk    |  20 +-
 contrib/bmake/unit-tests/varname-dot-shell.mk      |   6 +-
 contrib/bmake/unit-tests/varname-empty.exp         |  38 +-
 contrib/bmake/unit-tests/varname-empty.mk          |   9 +-
 .../varname-make_print_var_on_error-jobs.mk        |   4 +-
 .../unit-tests/varname-make_print_var_on_error.mk  |   4 +-
 contrib/bmake/unit-tests/varname.exp               |  10 +-
 contrib/bmake/unit-tests/varparse-dynamic.mk       |   6 +-
 contrib/bmake/util.c                               |  10 +-
 contrib/bmake/var.c                                | 713 ++++++++++++---------
 usr.bin/bmake/Makefile.config                      |   2 +-
 usr.bin/bmake/config.h                             |   7 +-
 usr.bin/bmake/unit-tests/Makefile                  |  80 ++-
 130 files changed, 3225 insertions(+), 2153 deletions(-)

diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog
index 5cf7f1f45384..5cf6f9d8fe57 100644
--- a/contrib/bmake/ChangeLog
+++ b/contrib/bmake/ChangeLog
@@ -1,3 +1,76 @@
+2021-02-06  Simon J Gerraty  <sjg at beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210206
+	Merge with NetBSD make, pick up
+	o unit-tests: use private TMPDIR to avoid errors from other users
+
+2021-02-05  Simon J Gerraty  <sjg at beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210205
+	Merge with NetBSD make, pick up
+	o avoid strdup in mkTempFile
+	o always use vfork
+	o rename context and ctxt to scope
+	o rename some VAR constants to SCOPE
+	o Var_ functions, move the scope to the front
+	o use shortcut functions Global_Set and Global_Append
+	o add shortcut Global_Delete for deleting a global variable
+	o rename Var_Delete to Var_DeleteExpand, Var_DeleteVar to Var_Delete
+	o compat.c: when exiting due to an error, print graph information
+	o enum.c: remove overengineered Enum_ValueToString
+	o make.c: remove unused INTERNAL flag
+	remove unused return type of MakeBuildParent
+	o parse.c: replace parse error "Need an operator" with better message
+	o var.c: improve documentation about variable scopes
+	rename Var_ValueDirect to GNode_ValueDirect
+	rename old Var_SetWithFlags to Var_SetExpandWithFlags
+	merge SetVar into Var_SetWithFlags
+	split Var_Exists into plain Var_Exists and Var_ExistsExpand
+	split Var_Append into Var_Append and Var_AppendExpand
+	replace enum bit-set with bit-field
+	o unit-tests/var-op-shell: use kill rather than kill -14
+	which broke on darwin with recent update.
+
+2021-02-01  Simon J Gerraty  <sjg at beast.crufty.net>
+
+	* configure.in: check for sig_atomic_t and define it as 'int'
+	if missing.
+
+	* VERSION (_MAKE_VERSION): 20210201
+	Merge with NetBSD make, pick up
+	o use sig_atomic_t for caught_sigchld
+
+2021-01-30  Simon J Gerraty  <sjg at beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210130
+	Merge with NetBSD make, pick up
+	o more unit tests
+	o convert SearchPath to struct
+	o split Buf_Destroy into Buf_Done and Buf_DoneData
+	o for.c: split For_Eval into separate functions
+	rename struct For to struct ForLoop
+	o job.c: do not create empty shell files in jobs mode
+	rename JobOpenTmpFile to JobWriteShellCommands
+	reduce unnecessary calls to waitpid
+	o parse.c: in -dp mode, print stack trace with each diagnostic
+
+2021-01-23  Simon J Gerraty  <sjg at beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210123
+	Merge with NetBSD make, pick up
+	o rename Dir_Expand to SearchPath_Expand
+	o rename Dir_AddDir, reorder parameters of SearchPath_ToFlags
+	o cond.c: fix debug output for comparison operators in conditionals
+	o dir.c: split Dir_FindFile into separate functions
+
+2021-01-20  Simon J Gerraty  <sjg at beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20210120
+	Merge with NetBSD make, pick up
+	o fix some more lint nits
+	o refine some unit tests for portability
+	o cond.c: rework parsing
+
 2021-01-10  Simon J Gerraty  <sjg at beast.crufty.net>
 
 	* VERSION (_MAKE_VERSION): 20210110
diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES
index 8e2513e1c183..5e7b8301da87 100644
--- a/contrib/bmake/FILES
+++ b/contrib/bmake/FILES
@@ -83,6 +83,8 @@ unit-tests/cmd-errors.exp
 unit-tests/cmd-errors.mk
 unit-tests/cmd-interrupt.exp
 unit-tests/cmd-interrupt.mk
+unit-tests/cmdline-redirect-stdin.exp
+unit-tests/cmdline-redirect-stdin.mk
 unit-tests/cmdline-undefined.exp
 unit-tests/cmdline-undefined.mk
 unit-tests/cmdline.exp
@@ -397,6 +399,8 @@ 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/jobs-empty-commands.exp
+unit-tests/jobs-empty-commands.mk
 unit-tests/jobs-error-indirect.exp
 unit-tests/jobs-error-indirect.mk
 unit-tests/jobs-error-nested-make.exp
@@ -501,6 +505,8 @@ unit-tests/opt-no-action-at-all.exp
 unit-tests/opt-no-action-at-all.mk
 unit-tests/opt-no-action-runflags.exp
 unit-tests/opt-no-action-runflags.mk
+unit-tests/opt-no-action-touch.exp
+unit-tests/opt-no-action-touch.mk
 unit-tests/opt-no-action.exp
 unit-tests/opt-no-action.mk
 unit-tests/opt-query.exp
diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION
index 70e0f68a60b0..0af794962680 100644
--- a/contrib/bmake/VERSION
+++ b/contrib/bmake/VERSION
@@ -1,2 +1,2 @@
 # keep this compatible with sh and make
-_MAKE_VERSION=20210110
+_MAKE_VERSION=20210206
diff --git a/contrib/bmake/arch.c b/contrib/bmake/arch.c
index 037f6bc548cf..e5c0a5e4ac0f 100644
--- a/contrib/bmake/arch.c
+++ b/contrib/bmake/arch.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: arch.c,v 1.193 2021/01/09 16:06:09 rillig Exp $	*/
+/*	$NetBSD: arch.c,v 1.197 2021/02/05 05:15:12 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.193 2021/01/09 16:06:09 rillig Exp $");
+MAKE_RCSID("$NetBSD: arch.c,v 1.197 2021/02/05 05:15:12 rillig Exp $");
 
 typedef struct List ArchList;
 typedef struct ListNode ArchListNode;
@@ -225,14 +225,14 @@ ArchFree(void *ap)
  * Input:
  *	pp		The start of the specification.
  *	gns		The list on which to place the nodes.
- *	ctxt		The context in which to expand variables.
+ *	scope		The scope in which to expand variables.
  *
  * Output:
  *	return		TRUE if it was a valid specification.
  *	*pp		Points to the first non-space after the archive spec.
  */
 Boolean
-Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
+Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
 {
 	char *cp;		/* Pointer into line */
 	GNode *gn;		/* New node */
@@ -255,7 +255,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
 			Boolean isError;
 
 			/* XXX: is expanded twice: once here and once below */
-			(void)Var_Parse(&nested_p, ctxt,
+			(void)Var_Parse(&nested_p, scope,
 					VARE_WANTRES | VARE_UNDEFERR, &result);
 			/* TODO: handle errors */
 			isError = result.str == var_Error;
@@ -272,7 +272,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
 	*cp++ = '\0';
 	if (expandLibName) {
 		char *expanded;
-		(void)Var_Subst(libName.str, ctxt,
+		(void)Var_Subst(libName.str, scope,
 		    VARE_WANTRES | VARE_UNDEFERR, &expanded);
 		/* TODO: handle errors */
 		libName = MFStr_InitOwn(expanded);
@@ -298,7 +298,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
 				Boolean isError;
 				const char *nested_p = cp;
 
-				(void)Var_Parse(&nested_p, ctxt,
+				(void)Var_Parse(&nested_p, scope,
 						VARE_WANTRES | VARE_UNDEFERR,
 						&result);
 				/* TODO: handle errors */
@@ -355,7 +355,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
 			char *p;
 			char *unexpandedMemName = memName;
 
-			(void)Var_Subst(memName, ctxt,
+			(void)Var_Subst(memName, scope,
 					VARE_WANTRES | VARE_UNDEFERR,
 					&memName);
 			/* TODO: handle errors */
@@ -379,7 +379,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
 				gn->type |= OP_ARCHV;
 				Lst_Append(gns, gn);
 
-			} else if (!Arch_ParseArchive(&p, gns, ctxt)) {
+			} else if (!Arch_ParseArchive(&p, gns, scope)) {
 				/* Error in nested call. */
 				free(fullName);
 				/* XXX: does unexpandedMemName leak? */
@@ -390,7 +390,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
 
 		} else if (Dir_HasWildcards(memName)) {
 			StringList members = LST_INIT;
-			Dir_Expand(memName, &dirSearchPath, &members);
+			SearchPath_Expand(&dirSearchPath, memName, &members);
 
 			while (!Lst_IsEmpty(&members)) {
 				char *member = Lst_Dequeue(&members);
@@ -1022,9 +1022,9 @@ Arch_FindLib(GNode *gn, SearchPath *path)
 	free(libName);
 
 #ifdef LIBRARIES
-	Var_Set(TARGET, gn->name, gn);
+	Var_Set(gn, TARGET, gn->name);
 #else
-	Var_Set(TARGET, gn->path == NULL ? gn->name : gn->path, gn);
+	Var_Set(gn, TARGET, GNode_Path(gn));
 #endif
 }
 
diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1
index f35c14cc1eee..e0d8267994c1 100644
--- a/contrib/bmake/bmake.1
+++ b/contrib/bmake/bmake.1
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.295 2020/12/23 13:49:12 rillig Exp $
+.\"	$NetBSD: make.1,v 1.296 2021/02/04 21:42:46 rillig Exp $
 .\"
 .\" Copyright (c) 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -99,7 +99,7 @@ is equivalent to
 .It Fl D Ar variable
 Define
 .Ar variable
-to be 1, in the global context.
+to be 1, in the global scope.
 .It Fl d Ar [-]flags
 Turn on debugging, and specify which portions of
 .Nm
@@ -355,7 +355,7 @@ Do not build any targets.
 Multiple instances of this option may be specified;
 the variables will be printed one per line,
 with a blank line for each null or undefined variable.
-The value printed is extracted from the global context after all
+The value printed is extracted from the global scope after all
 makefiles have been read.
 By default, the raw variable contents (which may
 include additional unexpanded variable references) are shown.
diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1
index 9ed1dcdd9018..d9723b35cf7f 100644
--- a/contrib/bmake/bmake.cat1
+++ b/contrib/bmake/bmake.cat1
@@ -37,7 +37,7 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)
              -C /etc.
 
      -D variable
-             Define variable to be 1, in the global context.
+             Define variable to be 1, in the global scope.
 
      -d [-]flags
              Turn on debugging, and specify which portions of bmake are to
@@ -224,7 +224,7 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)
              instances of this option may be specified; the variables will be
              printed one per line, with a blank line for each null or unde-
              fined variable.  The value printed is extracted from the global
-             context after all makefiles have been read.  By default, the raw
+             scope after all makefiles have been read.  By default, the raw
              variable contents (which may include additional unexpanded vari-
              able references) are shown.  If variable contains a `$' then the
              value will be recursively expanded to its complete resultant text
diff --git a/contrib/bmake/buf.c b/contrib/bmake/buf.c
index b6a2e9192b60..cef082247278 100644
--- a/contrib/bmake/buf.c
+++ b/contrib/bmake/buf.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: buf.c,v 1.47 2020/12/30 10:03:16 rillig Exp $	*/
+/*	$NetBSD: buf.c,v 1.51 2021/01/30 21:18:14 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.47 2020/12/30 10:03:16 rillig Exp $");
+MAKE_RCSID("$NetBSD: buf.c,v 1.51 2021/01/30 21:18:14 rillig Exp $");
 
 /* Make space in the buffer for adding at least 16 more bytes. */
 void
@@ -92,7 +92,7 @@ Buf_AddBytes(Buffer *buf, const char *bytes, size_t bytes_len)
 	size_t old_len = buf->len;
 	char *end;
 
-	if (__predict_false(old_len + bytes_len >= buf->cap)) {
+	if (old_len + bytes_len >= buf->cap) {
 		size_t minIncr = bytes_len + 16;
 		buf->cap += buf->cap > minIncr ? buf->cap : minIncr;
 		buf->data = bmake_realloc(buf->data, buf->cap);
@@ -135,21 +135,6 @@ Buf_AddInt(Buffer *buf, int n)
 	Buf_AddBytes(buf, str, len);
 }
 
-/*
- * Get the data (usually a string) from the buffer.
- * The returned data is valid until the next modifying operation
- * on the buffer.
- *
- * Returns the data and optionally the length of the data.
- */
-char *
-Buf_GetAll(Buffer *buf, size_t *out_len)
-{
-	if (out_len != NULL)
-		*out_len = buf->len;
-	return buf->data;
-}
-
 /* Mark the buffer as empty, so it can be filled with data again. */
 void
 Buf_Empty(Buffer *buf)
@@ -175,22 +160,35 @@ Buf_Init(Buffer *buf)
 }
 
 /*
- * Reset the buffer.
- * If freeData is TRUE, the data from the buffer is freed as well.
- * Otherwise it is kept and returned.
+ * Free the data from the buffer.
+ * Leave the buffer itself in an indeterminate state.
+ */
+void
+Buf_Done(Buffer *buf)
+{
+	free(buf->data);
+
+#ifdef CLEANUP
+	buf->cap = 0;
+	buf->len = 0;
+	buf->data = NULL;
+#endif
+}
+
+/*
+ * Return the data from the buffer.
+ * Leave the buffer itself in an indeterminate state.
  */
 char *
-Buf_Destroy(Buffer *buf, Boolean freeData)
+Buf_DoneData(Buffer *buf)
 {
 	char *data = buf->data;
-	if (freeData) {
-		free(data);
-		data = NULL;
-	}
 
+#ifdef CLEANUP
 	buf->cap = 0;
 	buf->len = 0;
 	buf->data = NULL;
+#endif
 
 	return data;
 }
@@ -200,22 +198,23 @@ Buf_Destroy(Buffer *buf, Boolean freeData)
 #endif
 
 /*
- * Reset the buffer and return its data.
+ * Return the data from the buffer.
+ * Leave the buffer itself in an indeterminate state.
  *
  * If the buffer size is much greater than its content,
  * a new buffer will be allocated and the old one freed.
  */
 char *
-Buf_DestroyCompact(Buffer *buf)
+Buf_DoneDataCompact(Buffer *buf)
 {
 #if BUF_COMPACT_LIMIT > 0
 	if (buf->cap - buf->len >= BUF_COMPACT_LIMIT) {
 		/* We trust realloc to be smart */
 		char *data = bmake_realloc(buf->data, buf->len + 1);
 		data[buf->len] = '\0';	/* XXX: unnecessary */
-		Buf_Destroy(buf, FALSE);
+		Buf_DoneData(buf);
 		return data;
 	}
 #endif
-	return Buf_Destroy(buf, FALSE);
+	return Buf_DoneData(buf);
 }
diff --git a/contrib/bmake/buf.h b/contrib/bmake/buf.h
index 942b115c76e6..594e9651dbfb 100644
--- a/contrib/bmake/buf.h
+++ b/contrib/bmake/buf.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: buf.h,v 1.38 2020/12/28 15:42:53 rillig Exp $	*/
+/*	$NetBSD: buf.h,v 1.42 2021/01/30 21:25:10 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -81,16 +81,11 @@
 
 /* An automatically growing null-terminated buffer of characters. */
 typedef struct Buffer {
-	size_t cap;	/* Allocated size of the buffer, including the null */
-	size_t len;	/* Number of bytes in buffer, excluding the null */
+	size_t cap;	/* Allocated size of the buffer, including the '\0' */
+	size_t len;	/* Number of bytes in buffer, excluding the '\0' */
 	char *data;	/* The buffer itself (always null-terminated) */
 } Buffer;
 
-/* If we aren't on NetBSD, __predict_false() might not be defined. */
-#ifndef __predict_false
-#define __predict_false(x) (x)
-#endif
-
 void Buf_Expand(Buffer *);
 
 /* Buf_AddByte adds a single byte to a buffer. */
@@ -99,19 +94,13 @@ Buf_AddByte(Buffer *buf, char byte)
 {
 	size_t old_len = buf->len++;
 	char *end;
-	if (__predict_false(old_len + 1 >= buf->cap))
+	if (old_len + 1 >= buf->cap)
 		Buf_Expand(buf);
 	end = buf->data + old_len;
 	end[0] = byte;
 	end[1] = '\0';
 }
 
-MAKE_INLINE size_t
-Buf_Len(const Buffer *buf)
-{
-	return buf->len;
-}
-
 MAKE_INLINE Boolean
 Buf_EndsWith(const Buffer *buf, char ch)
 {
@@ -122,11 +111,11 @@ void Buf_AddBytes(Buffer *, const char *, size_t);
 void Buf_AddBytesBetween(Buffer *, const char *, const char *);
 void Buf_AddStr(Buffer *, const char *);
 void Buf_AddInt(Buffer *, int);
-char *Buf_GetAll(Buffer *, size_t *);
 void Buf_Empty(Buffer *);
 void Buf_Init(Buffer *);
 void Buf_InitSize(Buffer *, size_t);
-char *Buf_Destroy(Buffer *, Boolean);
-char *Buf_DestroyCompact(Buffer *);
+void Buf_Done(Buffer *);
+char *Buf_DoneData(Buffer *);
+char *Buf_DoneDataCompact(Buffer *);
 
 #endif /* MAKE_BUF_H */
diff --git a/contrib/bmake/compat.c b/contrib/bmake/compat.c
index 6c7238318959..59190d8c4354 100644
--- a/contrib/bmake/compat.c
+++ b/contrib/bmake/compat.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat.c,v 1.219 2021/01/10 21:20:46 rillig Exp $	*/
+/*	$NetBSD: compat.c,v 1.224 2021/02/05 05:15:12 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -69,7 +69,7 @@
  * SUCH DAMAGE.
  */
 
-/*-
+/*
  * compat.c --
  *	The routines in this file implement the full-compatibility
  *	mode of PMake. Most of the special functionality of PMake
@@ -99,7 +99,7 @@
 #include "pathnames.h"
 
 /*	"@(#)compat.c	8.2 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: compat.c,v 1.219 2021/01/10 21:20:46 rillig Exp $");
+MAKE_RCSID("$NetBSD: compat.c,v 1.224 2021/02/05 05:15:12 rillig Exp $");
 
 static GNode *curTarg = NULL;
 static pid_t compatChild;
@@ -260,7 +260,7 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
 			/*
 			 * Append the expanded command, to prevent the
 			 * local variables from being interpreted in the
-			 * context of the .END node.
+			 * scope of the .END node.
 			 *
 			 * A probably unintended side effect of this is that
 			 * the expanded command will be expanded again in the
@@ -360,7 +360,7 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
 	/*
 	 * Fork and execute the single command. If the fork fails, we abort.
 	 */
-	compatChild = cpid = vFork();
+	compatChild = cpid = vfork();
 	if (cpid < 0) {
 		Fatal("Could not fork");
 	}
@@ -512,7 +512,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
 	}
 
 	if (Lst_FindDatum(&gn->implicitParents, pgn) != NULL)
-		Var_Set(IMPSRC, GNode_VarTarget(gn), pgn);
+		Var_Set(pgn, IMPSRC, GNode_VarTarget(gn));
 
 	/*
 	 * All the children were made ok. Now youngestChild->mtime contains the
@@ -605,7 +605,7 @@ MakeOther(GNode *gn, GNode *pgn)
 
 	if (Lst_FindDatum(&gn->implicitParents, pgn) != NULL) {
 		const char *target = GNode_VarTarget(gn);
-		Var_Set(IMPSRC, target != NULL ? target : "", pgn);
+		Var_Set(pgn, IMPSRC, target != NULL ? target : "");
 	}
 
 	switch (gn->made) {
@@ -752,6 +752,10 @@ Compat_Run(GNodeList *targs)
 	}
 
 	if (errorNode != NULL) {
+		if (DEBUG(GRAPH2))
+			Targ_PrintGraph(2);
+		else if (DEBUG(GRAPH3))
+			Targ_PrintGraph(3);
 		PrintOnError(errorNode, "\nStop.");
 		exit(1);
 	}
diff --git a/contrib/bmake/cond.c b/contrib/bmake/cond.c
index 1a8aba637fe9..8f36fda22f12 100644
--- a/contrib/bmake/cond.c
+++ b/contrib/bmake/cond.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: cond.c,v 1.235 2021/01/10 21:20:46 rillig Exp $	*/
+/*	$NetBSD: cond.c,v 1.256 2021/02/05 05:15:12 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -95,53 +95,65 @@
 #include "dir.h"
 
 /*	"@(#)cond.c	8.2 (Berkeley) 1/2/94"	*/
-MAKE_RCSID("$NetBSD: cond.c,v 1.235 2021/01/10 21:20:46 rillig Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.256 2021/02/05 05:15:12 rillig Exp $");
 
 /*
  * The parsing of conditional expressions is based on this grammar:
- *	E -> F || E
- *	E -> F
- *	F -> T && F
- *	F -> T
- *	T -> defined(variable)
- *	T -> make(target)
- *	T -> exists(file)
- *	T -> empty(varspec)
- *	T -> target(name)
- *	T -> commands(name)
- *	T -> symbol
- *	T -> $(varspec) op value
- *	T -> $(varspec) == "string"
- *	T -> $(varspec) != "string"
- *	T -> "string"
- *	T -> ( E )
- *	T -> ! T
- *	op -> == | != | > | < | >= | <=
+ *	Or -> And '||' Or
+ *	Or -> And
+ *	And -> Term '&&' And
+ *	And -> Term
+ *	Term -> Function '(' Argument ')'
+ *	Term -> Leaf Operator Leaf
+ *	Term -> Leaf
+ *	Term -> '(' Or ')'
+ *	Term -> '!' Term
+ *	Leaf -> "string"
+ *	Leaf -> Number
+ *	Leaf -> VariableExpression
+ *	Leaf -> Symbol
+ *	Operator -> '==' | '!=' | '>' | '<' | '>=' | '<='
  *
- * 'symbol' is some other symbol to which the default function is applied.
+ * 'Symbol' is an unquoted string literal to which the default function is
+ * applied.
  *
  * The tokens are scanned by CondToken, which returns:
- *	TOK_AND		for '&' or '&&'
- *	TOK_OR		for '|' or '||'
+ *	TOK_AND		for '&&'
+ *	TOK_OR		for '||'
  *	TOK_NOT		for '!'
  *	TOK_LPAREN	for '('
  *	TOK_RPAREN	for ')'
+ *
  * Other terminal symbols are evaluated using either the default function or
  * the function given in the terminal, they return either TOK_TRUE or
  * TOK_FALSE.
- *
- * TOK_FALSE is 0 and TOK_TRUE 1 so we can directly assign C comparisons.
- *
- * All non-terminal functions (CondParser_Expr, CondParser_Factor and
- * CondParser_Term) return either TOK_FALSE, TOK_TRUE, or TOK_ERROR on error.
  */
 typedef enum Token {
-	TOK_FALSE = 0, TOK_TRUE = 1, TOK_AND, TOK_OR, TOK_NOT,
+	TOK_FALSE, TOK_TRUE, TOK_AND, TOK_OR, TOK_NOT,
 	TOK_LPAREN, TOK_RPAREN, TOK_EOF, TOK_NONE, TOK_ERROR
 } Token;
 
+typedef enum CondResult {
+	CR_FALSE, CR_TRUE, CR_ERROR
+} CondResult;
+
+typedef enum ComparisonOp {
+	LT, LE, GT, GE, EQ, NE
+} ComparisonOp;
+
 typedef struct CondParser {
-	const struct If *if_info; /* Info for current statement */
+
+	/*
+	 * The plain '.if ${VAR}' evaluates to true if the value of the
+	 * expression has length > 0.  The other '.if' variants delegate
+	 * to evalBare instead.
+	 */
+	Boolean plain;
+
+	/* The function to apply on unquoted bare words. */
+	Boolean (*evalBare)(size_t, const char *);
+	Boolean negateEvalBare;
+
 	const char *p;		/* The remaining condition to parse */
 	Token curr;		/* Single push-back token used in parsing */
 
@@ -154,11 +166,13 @@ typedef struct CondParser {
 	Boolean printedError;
 } CondParser;
 
-static Token CondParser_Expr(CondParser *par, Boolean);
+static CondResult CondParser_Or(CondParser *par, Boolean);
 
 static unsigned int cond_depth = 0;	/* current .if nesting level */
 static unsigned int cond_min_depth = 0;	/* depth at makefile open */
 
+static const char *opname[] = { "<", "<=", ">", ">=", "==", "!=" };
+
 /*
  * Indicate when we should be strict about lhs of comparisons.
  * In strict mode, the lhs must be a variable expression or a string literal
@@ -214,7 +228,7 @@ CondParser_SkipWhitespace(CondParser *par)
  * Return the length of the argument, or 0 on error.
  */
 static size_t
-ParseFuncArg(const char **pp, Boolean doEval, const char *func,
+ParseFuncArg(CondParser *par, const char **pp, Boolean doEval, const char *func,
 	     char **out_arg)
 {
 	const char *p = *pp;
@@ -254,7 +268,7 @@ ParseFuncArg(const char **pp, Boolean doEval, const char *func,
 			    ? VARE_WANTRES | VARE_UNDEFERR
 			    : VARE_NONE;
 			FStr nestedVal;
-			(void)Var_Parse(&p, VAR_CMDLINE, eflags, &nestedVal);
+			(void)Var_Parse(&p, SCOPE_CMDLINE, eflags, &nestedVal);
 			/* TODO: handle errors */
 			Buf_AddStr(&argBuf, nestedVal.str);
 			FStr_Done(&nestedVal);
@@ -268,16 +282,15 @@ ParseFuncArg(const char **pp, Boolean doEval, const char *func,
 		p++;
 	}
 
-	*out_arg = Buf_GetAll(&argBuf, &argLen);
-	Buf_Destroy(&argBuf, FALSE);
+	argLen = argBuf.len;
+	*out_arg = Buf_DoneData(&argBuf);
 
 	cpp_skip_hspace(&p);
 
 	if (func != NULL && *p++ != ')') {
-		Parse_Error(PARSE_WARNING,
-			    "Missing closing parenthesis for %s()",
-			    func);
-		/* The PARSE_FATAL follows in CondEvalExpression. */
+		Parse_Error(PARSE_FATAL,
+		    "Missing closing parenthesis for %s()", func);
+		par->printedError = TRUE;
 		return 0;
 	}
 
@@ -290,7 +303,7 @@ ParseFuncArg(const char **pp, Boolean doEval, const char *func,
 static Boolean
 FuncDefined(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
 {
-	FStr value = Var_Value(arg, VAR_CMDLINE);
+	FStr value = Var_Value(SCOPE_CMDLINE, arg);
 	Boolean result = value.str != NULL;
 	FStr_Done(&value);
 	return result;
@@ -390,7 +403,70 @@ is_separator(char ch)
 	return ch == '\0' || ch_isspace(ch) || strchr("!=><)", ch) != NULL;
 }
 
-/*-
+/*
+ * In a quoted or unquoted string literal or a number, parse a variable
+ * expression.
+ *
+ * Example: .if x${CENTER}y == "${PREFIX}${SUFFIX}" || 0x${HEX}
+ */
+static Boolean
+CondParser_StringExpr(CondParser *par, const char *start,
+		      Boolean const doEval, Boolean const quoted,
+		      Buffer *buf, FStr *const inout_str)
+{
+	VarEvalFlags eflags;
+	const char *nested_p;
+	Boolean atStart;
+	VarParseResult parseResult;
+
+	/* if we are in quotes, an undefined variable is ok */
+	eflags = doEval && !quoted ? VARE_WANTRES | VARE_UNDEFERR
+	    : doEval ? VARE_WANTRES
+	    : VARE_NONE;
+
+	nested_p = par->p;
+	atStart = nested_p == start;
+	parseResult = Var_Parse(&nested_p, SCOPE_CMDLINE, eflags, inout_str);
+	/* TODO: handle errors */
+	if (inout_str->str == var_Error) {
+		if (parseResult == VPR_ERR) {
+			/*
+			 * FIXME: Even if an error occurs, there is no
+			 *  guarantee that it is reported.
+			 *
+			 * See cond-token-plain.mk $$$$$$$$.
+			 */
+			par->printedError = TRUE;
+		}
+		/*
+		 * XXX: Can there be any situation in which a returned
+		 * var_Error requires freeIt?
+		 */
+		FStr_Done(inout_str);
+		/*
+		 * Even if !doEval, we still report syntax errors, which is
+		 * what getting var_Error back with !doEval means.
+		 */
+		*inout_str = FStr_InitRefer(NULL);
+		return FALSE;
+	}
+	par->p = nested_p;
+
+	/*
+	 * If the '$' started the string literal (which means no quotes), and
+	 * the variable expression is followed by a space, looks like a
+	 * comparison operator or is the end of the expression, we are done.
+	 */
+	if (atStart && is_separator(par->p[0]))
+		return FALSE;
+
+	Buf_AddStr(buf, inout_str->str);
+	FStr_Done(inout_str);
+	*inout_str = FStr_InitRefer(NULL); /* not finished yet */
+	return TRUE;
+}
+
+/*
  * Parse a string from a variable reference or an optionally quoted
  * string.  This is called for the lhs and rhs of string comparisons.
  *
@@ -399,19 +475,14 @@ is_separator(char ch)
  *	Sets out_quoted if the string was quoted.
  *	Sets out_freeIt.
  */
-/* coverity:[+alloc : arg-*4] */
 static void
 CondParser_String(CondParser *par, Boolean doEval, Boolean strictLHS,
 		  FStr *out_str, Boolean *out_quoted)
 {
 	Buffer buf;
 	FStr str;
-	Boolean atStart;
-	const char *nested_p;
 	Boolean quoted;
 	const char *start;
-	VarEvalFlags eflags;
-	VarParseResult parseResult;
 
 	Buf_Init(&buf);
 	str = FStr_InitRefer(NULL);
@@ -430,12 +501,10 @@ CondParser_String(CondParser *par, Boolean doEval, Boolean strictLHS,
 			}
 			continue;
 		case '"':
-			if (quoted) {
-				par->p++;	/* skip the closing quote */
-				goto got_str;
-			}
-			Buf_AddByte(&buf, par->p[0]); /* likely? */
 			par->p++;
+			if (quoted)
+				goto got_str;	/* skip the closing quote */
+			Buf_AddByte(&buf, '"');
 			continue;
 		case ')':	/* see is_separator */
 		case '!':
@@ -450,47 +519,9 @@ CondParser_String(CondParser *par, Boolean doEval, Boolean strictLHS,
 			par->p++;
 			continue;
 		case '$':
-			/* if we are in quotes, an undefined variable is ok */
-			eflags =
-			    doEval && !quoted ? VARE_WANTRES | VARE_UNDEFERR :
-			    doEval ? VARE_WANTRES :
-			    VARE_NONE;
-
-			nested_p = par->p;
-			atStart = nested_p == start;
-			parseResult = Var_Parse(&nested_p, VAR_CMDLINE, eflags,
-			    &str);
-			/* TODO: handle errors */
-			if (str.str == var_Error) {
-				if (parseResult == VPR_ERR)
-					par->printedError = TRUE;
-				/*
*** 10768 LINES SKIPPED ***


More information about the dev-commits-src-all mailing list