Import bmake-20220330

Most relevant change:

	o parse.c: try to include 'posix.mk' the first time
	.POSIX: is encountered, to allow for beter POSIX compliance.

Others

	o cond.c: make debug logging for comparisons less technical
	o lst.c: fix mem leak in Lst_Remove
	o job.c: fix echoing of command with '-' in silent target in jobs mode
	o var.c: make debug logs more readable
	prefer 'long long' over 'long' on 32-bit C99 platforms
	fix crash on .undef of an environment variable
This commit is contained in:
Simon J. Gerraty 2022-04-03 12:52:08 -07:00
parent 535c59a6a9
commit a052cb4320
95 changed files with 1145 additions and 562 deletions

View File

@ -1,3 +1,41 @@
2022-03-30 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220330
Merge with NetBSD make, pick up
o var.c: fix spacing, and a typo in a test
2022-03-26 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220326
Merge with NetBSD make, pick up
o parse.c: try to include 'posix.mk' the first time
.POSIX: is encountered, to allow for beter POSIX compliance.
o var.c: make debug logs more readable
prefer 'long long' over 'long' on 32-bit C99 platforms
fix crash on .undef of an environment variable
2022-03-03 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220303
Merge with NetBSD make, pick up
o tell meta mode unit tests not to expect filemon
o cond.c: make debug logging for comparisons less technical
o lst.c: fix mem leak in Lst_Remove
o str.c: make code for string matching syntactically more consistent
o var.c: simplify ParseModifier_Match
2022-02-14 Simon J Gerraty <sjg@beast.crufty.net>
* unit-tests/Makefile: control MAKESYSPATH for deptgt-phony
* VERSION (_MAKE_VERSION): 20220214
Merge with NetBSD make, pick up
o cond.c: simplify control flow in CondParser_Comparison
o job.c: fix echoing of command with '-' in silent target in jobs mode
o main.c: prefix the warning about read-only .OBJDIR with a colon
o parse.c: remove redundant conditions
o var.c: simplify control flow in ModifyWord_SysVSubst
2022-02-08 Simon J Gerraty <sjg@beast.crufty.net>
* unit-tests/Makefile: disable opt-debug-x-trace on Linux if there

4
FILES
View File

@ -278,6 +278,8 @@ unit-tests/deptgt-precious.exp
unit-tests/deptgt-precious.mk
unit-tests/deptgt-shell.exp
unit-tests/deptgt-shell.mk
unit-tests/deptgt-silent-jobs.exp
unit-tests/deptgt-silent-jobs.mk
unit-tests/deptgt-silent.exp
unit-tests/deptgt-silent.mk
unit-tests/deptgt-stale.exp
@ -502,6 +504,8 @@ unit-tests/opt-jobs-no-action.exp
unit-tests/opt-jobs-no-action.mk
unit-tests/opt-jobs.exp
unit-tests/opt-jobs.mk
unit-tests/opt-keep-going-indirect.exp
unit-tests/opt-keep-going-indirect.mk
unit-tests/opt-keep-going-multiple.exp
unit-tests/opt-keep-going-multiple.mk
unit-tests/opt-keep-going.exp

View File

@ -1,2 +1,2 @@
# keep this compatible with sh and make
_MAKE_VERSION=20220208
_MAKE_VERSION=20220330

35
bmake.1
View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.304 2022/01/29 20:54:58 sjg Exp $
.\" $NetBSD: make.1,v 1.307 2022/03/26 15:39:58 sjg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
.Dd January 28, 2022
.Dd March 24, 2022
.Dt BMAKE 1
.Os
.Sh NAME
@ -692,15 +692,15 @@ Variables that are defined specific to a certain target.
.El
.Pp
Local variables can be set on a dependency line, if
.Va .MAKE.TARGET_LOCAL_VARIABLES ,
.Va .MAKE.TARGET_LOCAL_VARIABLES
is not set to
.Ql false .
The rest of the line
(which will already have had Global variables expanded),
(which will already have had global variables expanded)
is the variable value.
For example:
.Bd -literal -offset indent
COMPILER_WRAPPERS+= ccache distcc icecc
COMPILER_WRAPPERS= ccache distcc icecc
${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
.Ed
@ -708,17 +708,17 @@ ${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
Only the targets
.Ql ${OBJS}
will be impacted by that filter (in "meta" mode) and
simply enabling/disabling any of the wrappers will not render all
simply enabling/disabling any of the compiler wrappers will not render all
of those targets out-of-date.
.Pp
.Em NOTE :
target local variable assignments behave differently in that;
target-local variable assignments behave differently in that;
.Bl -tag -width Ds -offset indent
.It Ic \&+=
Only appends to a previous local assignment
for the same target and variable.
.It Ic \&:=
Is redundant with respect to Global variables,
Is redundant with respect to global variables,
which have already been expanded.
.El
.Pp
@ -2290,6 +2290,25 @@ The suffix must have been previously declared with
Apply the
.Ic .PHONY
attribute to any specified sources.
.It Ic .POSIX
This should be the first non-comment line in a Makefile.
It results in the variable
.Va %POSIX
being defined with the value
.Ql 1003.2 .
The first time
.Ic .POSIX
is encountered, the makefile
.Ql posix.mk
will be included if possible,
to provide POSIX compatible default rules.
If
.Nm
is run with the
.Fl r
flag, then only
.Ql posix.mk
will contribute to the default rules.
.It Ic .PRECIOUS
Apply the
.Ic .PRECIOUS

View File

@ -444,24 +444,24 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
Variables that are defined specific to a certain target.
Local variables can be set on a dependency line, if
.MAKE.TARGET_LOCAL_VARIABLES, is not set to `false'. The rest of the
line (which will already have had Global variables expanded), is the
variable value. For example:
.MAKE.TARGET_LOCAL_VARIABLES is not set to `false'. The rest of the line
(which will already have had global variables expanded) is the variable
value. For example:
COMPILER_WRAPPERS+= ccache distcc icecc
COMPILER_WRAPPERS= ccache distcc icecc
${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
Only the targets `${OBJS}' will be impacted by that filter (in "meta"
mode) and simply enabling/disabling any of the wrappers will not render
all of those targets out-of-date.
mode) and simply enabling/disabling any of the compiler wrappers will not
render all of those targets out-of-date.
NOTE: target local variable assignments behave differently in that;
NOTE: target-local variable assignments behave differently in that;
+= Only appends to a previous local assignment for the same
target and variable.
:= Is redundant with respect to Global variables, which have
:= Is redundant with respect to global variables, which have
already been expanded.
The seven built-in local variables are as follows:
@ -1468,6 +1468,13 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
.PHONY Apply the .PHONY attribute to any specified sources.
.POSIX This should be the first non-comment line in a Makefile. It re-
sults in the variable %POSIX being defined with the value
`1003.2'. The first time .POSIX is encountered, the makefile
`posix.mk' will be included if possible, to provide POSIX com-
patible default rules. If bmake is run with the -r flag, then
only `posix.mk' will contribute to the default rules.
.PRECIOUS
Apply the .PRECIOUS attribute to any specified sources. If no
sources are specified, the .PRECIOUS attribute is applied to ev-
@ -1622,4 +1629,4 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
There is no way of escaping a space character in a filename.
FreeBSD 13.0 January 28, 2022 FreeBSD 13.0
FreeBSD 13.0 March 24, 2022 FreeBSD 13.0

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 83 KiB

50
cond.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.327 2022/01/29 01:12:36 rillig Exp $ */
/* $NetBSD: cond.c,v 1.333 2022/03/03 19:46:31 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -95,7 +95,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: cond.c,v 1.327 2022/01/29 01:12:36 rillig Exp $");
MAKE_RCSID("$NetBSD: cond.c,v 1.333 2022/03/03 19:46:31 rillig Exp $");
/*
* Conditional expressions conform to this grammar:
@ -140,7 +140,9 @@ typedef struct CondParser {
/*
* The plain '.if ${VAR}' evaluates to true if the value of the
* expression has length > 0. The other '.if' variants delegate
* to evalBare instead.
* to evalBare instead, for example '.ifdef ${VAR}' is equivalent to
* '.if defined(${VAR})', checking whether the variable named by the
* expression '${VAR}' is defined.
*/
bool plain;
@ -157,8 +159,8 @@ typedef struct CondParser {
* make cannot know anymore whether the left-hand side had originally
* been a variable expression or a plain word.
*
* In all other contexts, the left-hand side must either be a
* variable expression, a quoted string or a number.
* In conditional directives like '.if', the left-hand side must
* either be a variable expression, a quoted string or a number.
*/
bool leftUnquotedOK;
@ -213,10 +215,10 @@ static char *
ParseWord(const char **pp, bool doEval)
{
const char *p = *pp;
Buffer argBuf;
Buffer word;
int paren_depth;
Buf_InitSize(&argBuf, 16);
Buf_InitSize(&word, 16);
paren_depth = 0;
for (;;) {
@ -240,7 +242,7 @@ ParseWord(const char **pp, bool doEval)
FStr nestedVal;
(void)Var_Parse(&p, SCOPE_CMDLINE, emode, &nestedVal);
/* TODO: handle errors */
Buf_AddStr(&argBuf, nestedVal.str);
Buf_AddStr(&word, nestedVal.str);
FStr_Done(&nestedVal);
continue;
}
@ -248,14 +250,14 @@ ParseWord(const char **pp, bool doEval)
paren_depth++;
else if (ch == ')' && --paren_depth < 0)
break;
Buf_AddByte(&argBuf, ch);
Buf_AddByte(&word, ch);
p++;
}
cpp_skip_hspace(&p);
*pp = p;
return Buf_DoneData(&argBuf);
return Buf_DoneData(&word);
}
/* Parse the function argument, including the surrounding parentheses. */
@ -286,21 +288,21 @@ ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func)
return res;
}
/* Test whether the given variable is defined. */
/* See if the given variable is defined. */
static bool
FuncDefined(const char *var)
{
return Var_Exists(SCOPE_CMDLINE, var);
}
/* See if the given target is requested to be made. */
/* See if a target matching targetPattern is requested to be made. */
static bool
FuncMake(const char *target)
FuncMake(const char *targetPattern)
{
StringListNode *ln;
for (ln = opts.create.first; ln != NULL; ln = ln->next)
if (Str_Match(ln->datum, target))
if (Str_Match(ln->datum, targetPattern))
return true;
return false;
}
@ -557,7 +559,7 @@ EvalNotEmpty(CondParser *par, const char *value, bool quoted)
static bool
EvalCompareNum(double lhs, ComparisonOp op, double rhs)
{
DEBUG3(COND, "lhs = %f, rhs = %f, op = %.2s\n", lhs, rhs, opname[op]);
DEBUG3(COND, "Comparing %f %s %f\n", lhs, opname[op], rhs);
switch (op) {
case LT:
@ -586,8 +588,7 @@ EvalCompareStr(CondParser *par, const char *lhs,
return TOK_ERROR;
}
DEBUG3(COND, "lhs = \"%s\", rhs = \"%s\", op = %.2s\n",
lhs, rhs, opname[op]);
DEBUG3(COND, "Comparing \"%s\" %s \"%s\"\n", lhs, opname[op], rhs);
return ToToken((op == EQ) == (strcmp(lhs, rhs) == 0));
}
@ -663,18 +664,11 @@ CondParser_Comparison(CondParser *par, bool doEval)
}
CondParser_Leaf(par, doEval, true, &rhs, &rhsQuoted);
if (rhs.str == NULL)
goto done_rhs;
if (!doEval) {
t = TOK_FALSE;
goto done_rhs;
}
t = EvalCompare(par, lhs.str, lhsQuoted, op, rhs.str, rhsQuoted);
done_rhs:
t = rhs.str == NULL ? TOK_ERROR
: !doEval ? TOK_FALSE
: EvalCompare(par, lhs.str, lhsQuoted, op, rhs.str, rhsQuoted);
FStr_Done(&rhs);
done_lhs:
FStr_Done(&lhs);
return t;

View File

@ -1,4 +1,4 @@
/* $NetBSD: filemon_dev.c,v 1.8 2021/02/01 21:09:25 rillig Exp $ */
/* $NetBSD: filemon_dev.c,v 1.9 2022/03/04 23:17:16 sjg Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@ -46,6 +46,10 @@
#define _PATH_FILEMON "/dev/filemon"
#endif
#ifndef MAKE_ATTR_UNUSED
#define MAKE_ATTR_UNUSED __attribute__((__unused__))
#endif
struct filemon {
int fd;
};
@ -101,7 +105,7 @@ filemon_setfd(struct filemon *F, int fd)
}
void
filemon_setpid_parent(struct filemon *F, pid_t pid)
filemon_setpid_parent(struct filemon *F MAKE_ATTR_UNUSED, pid_t pid MAKE_ATTR_UNUSED)
{
/* Nothing to do! */
}
@ -137,14 +141,14 @@ filemon_close(struct filemon *F)
}
int
filemon_readfd(const struct filemon *F)
filemon_readfd(const struct filemon *F MAKE_ATTR_UNUSED)
{
return -1;
}
int
filemon_process(struct filemon *F)
filemon_process(struct filemon *F MAKE_ATTR_UNUSED)
{
return 0;

6
hash.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: hash.c,v 1.71 2022/01/27 11:00:07 rillig Exp $ */
/* $NetBSD: hash.c,v 1.72 2022/02/09 21:09:24 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -74,7 +74,7 @@
#include "make.h"
/* "@(#)hash.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: hash.c,v 1.71 2022/01/27 11:00:07 rillig Exp $");
MAKE_RCSID("$NetBSD: hash.c,v 1.72 2022/02/09 21:09:24 rillig Exp $");
/*
* The ratio of # entries to # buckets at which we rebuild the table to
@ -283,7 +283,7 @@ HashTable_Set(HashTable *t, const char *key, void *value)
HashEntry_Set(he, value);
}
/* Delete the entry from the table and free the associated memory. */
/* Delete the entry from the table, don't free the value of the entry. */
void
HashTable_DeleteEntry(HashTable *t, HashEntry *he)
{

9
job.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.451 2022/02/04 23:22:19 rillig Exp $ */
/* $NetBSD: job.c,v 1.452 2022/02/12 11:14:48 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -155,7 +155,7 @@
#include "trace.h"
/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: job.c,v 1.451 2022/02/04 23:22:19 rillig Exp $");
MAKE_RCSID("$NetBSD: job.c,v 1.452 2022/02/12 11:14:48 rillig Exp $");
/*
* A shell defines how the commands are run. All commands for a target are
@ -848,7 +848,7 @@ static void
JobWriteSpecialsEchoCtl(Job *job, ShellWriter *wr, CommandFlags *inout_cmdFlags,
const char *escCmd, const char **inout_cmdTemplate)
{
/* XXX: Why is the job modified at this point? */
/* XXX: Why is the whole job modified at this point? */
job->ignerr = true;
if (job->echo && inout_cmdFlags->echo) {
@ -860,9 +860,6 @@ JobWriteSpecialsEchoCtl(Job *job, ShellWriter *wr, CommandFlags *inout_cmdFlags,
* for toggling the error checking.
*/
inout_cmdFlags->echo = false;
} else {
if (inout_cmdFlags->echo)
ShellWriter_EchoCmd(wr, escCmd);
}
*inout_cmdTemplate = shell->runIgnTmpl;

6
lst.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: lst.c,v 1.105 2021/03/15 16:45:30 rillig Exp $ */
/* $NetBSD: lst.c,v 1.106 2022/02/26 11:57:21 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -34,7 +34,7 @@
#include "make.h"
MAKE_RCSID("$NetBSD: lst.c,v 1.105 2021/03/15 16:45:30 rillig Exp $");
MAKE_RCSID("$NetBSD: lst.c,v 1.106 2022/02/26 11:57:21 rillig Exp $");
static ListNode *
LstNodeNew(ListNode *prev, ListNode *next, void *datum)
@ -163,6 +163,8 @@ Lst_Remove(List *list, ListNode *ln)
list->first = ln->next;
if (list->last == ln)
list->last = ln->prev;
free(ln);
}
/* Replace the datum in the given node with the new datum. */

6
lst.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: lst.h,v 1.102 2021/12/15 12:24:13 rillig Exp $ */
/* $NetBSD: lst.h,v 1.103 2022/03/03 19:55:27 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -142,9 +142,9 @@ ListNode *Lst_FindDatum(List *, const void *) MAKE_ATTR_USE;
/* Insert a datum before the given node. */
void Lst_InsertBefore(List *, ListNode *, void *);
/* Add a datum at the front of the list. */
/* Add a datum at the head of the list. */
void Lst_Prepend(List *, void *);
/* Add a datum at the end of the list. */
/* Add a datum at the tail of the list. */
void Lst_Append(List *, void *);
/* Remove the node from the list. */
void Lst_Remove(List *, ListNode *);

19
main.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.577 2022/01/29 09:38:26 rillig Exp $ */
/* $NetBSD: main.c,v 1.579 2022/03/22 23:37:09 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -111,7 +111,7 @@
#include "trace.h"
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: main.c,v 1.577 2022/01/29 09:38:26 rillig Exp $");
MAKE_RCSID("$NetBSD: main.c,v 1.579 2022/03/22 23:37:09 rillig Exp $");
#if defined(MAKE_NATIVE) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
"The Regents of the University of California. "
@ -318,7 +318,7 @@ MainParseArgDebug(const char *argvalue)
break;
case 'F':
MainParseArgDebugFile(modules + 1);
goto debug_setbuf;
goto finish;
default:
(void)fprintf(stderr,
"%s: illegal argument to d option -- %c\n",
@ -327,20 +327,15 @@ MainParseArgDebug(const char *argvalue)
}
}
debug_setbuf:
finish:
opts.debug = debug;
/*
* Make the debug_file unbuffered, and make
* stdout line buffered (unless debugfile == stdout).
*/
setvbuf(opts.debug_file, NULL, _IONBF, 0);
if (opts.debug_file != stdout) {
if (opts.debug_file != stdout)
setvbuf(stdout, NULL, _IOLBF, 0);
}
}
/* Is path relative, or does it contain any relative component "." or ".."? */
/* Is path relative or does it contain any relative component "." or ".."? */
static bool
IsRelativePath(const char *path)
{
@ -736,7 +731,7 @@ Main_SetObjdir(bool writable, const char *fmt, ...)
return false;
if ((writable && access(path, W_OK) != 0) || chdir(path) != 0) {
(void)fprintf(stderr, "%s warning: %s: %s.\n",
(void)fprintf(stderr, "%s: warning: %s: %s.\n",
progname, path, strerror(errno));
return false;
}

35
make.1
View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.304 2022/01/29 20:54:58 sjg Exp $
.\" $NetBSD: make.1,v 1.307 2022/03/26 15:39:58 sjg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
.Dd January 28, 2022
.Dd March 24, 2022
.Dt MAKE 1
.Os
.Sh NAME
@ -692,15 +692,15 @@ Variables that are defined specific to a certain target.
.El
.Pp
Local variables can be set on a dependency line, if
.Va .MAKE.TARGET_LOCAL_VARIABLES ,
.Va .MAKE.TARGET_LOCAL_VARIABLES
is not set to
.Ql false .
The rest of the line
(which will already have had Global variables expanded),
(which will already have had global variables expanded)
is the variable value.
For example:
.Bd -literal -offset indent
COMPILER_WRAPPERS+= ccache distcc icecc
COMPILER_WRAPPERS= ccache distcc icecc
${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
.Ed
@ -708,17 +708,17 @@ ${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
Only the targets
.Ql ${OBJS}
will be impacted by that filter (in "meta" mode) and
simply enabling/disabling any of the wrappers will not render all
simply enabling/disabling any of the compiler wrappers will not render all
of those targets out-of-date.
.Pp
.Em NOTE :
target local variable assignments behave differently in that;
target-local variable assignments behave differently in that;
.Bl -tag -width Ds -offset indent
.It Ic \&+=
Only appends to a previous local assignment
for the same target and variable.
.It Ic \&:=
Is redundant with respect to Global variables,
Is redundant with respect to global variables,
which have already been expanded.
.El
.Pp
@ -2290,6 +2290,25 @@ The suffix must have been previously declared with
Apply the
.Ic .PHONY
attribute to any specified sources.
.It Ic .POSIX
This should be the first non-comment line in a Makefile.
It results in the variable
.Va %POSIX
being defined with the value
.Ql 1003.2 .
The first time
.Ic .POSIX
is encountered, the makefile
.Ql posix.mk
will be included if possible,
to provide POSIX compatible default rules.
If
.Nm
is run with the
.Fl r
flag, then only
.Ql posix.mk
will contribute to the default rules.
.It Ic .PRECIOUS
Apply the
.Ic .PRECIOUS

4
make.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.298 2022/02/05 00:26:21 rillig Exp $ */
/* $NetBSD: make.h,v 1.299 2022/03/26 14:02:40 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -141,7 +141,7 @@
#define MAKE_ATTR_USE /* delete */
#endif
#if __STDC__ >= 199901L || defined(lint)
#if __STDC_VERSION__ >= 199901L || defined(lint)
#define MAKE_INLINE static inline MAKE_ATTR_UNUSED
#else
#define MAKE_INLINE static MAKE_ATTR_UNUSED

13
meta.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.197 2022/02/08 22:36:02 sjg Exp $ */
/* $NetBSD: meta.c,v 1.199 2022/03/04 23:17:16 sjg Exp $ */
/*
* Implement 'meta' mode.
@ -675,7 +675,7 @@ meta_job_start(Job *job, GNode *gn)
* It does not disturb our state.
*/
void
meta_job_child(Job *job)
meta_job_child(Job *job MAKE_ATTR_UNUSED)
{
#ifdef USE_FILEMON
BuildMon *pbm;
@ -700,7 +700,7 @@ meta_job_child(Job *job)
}
void
meta_job_parent(Job *job, pid_t pid)
meta_job_parent(Job *job MAKE_ATTR_UNUSED, pid_t pid MAKE_ATTR_UNUSED)
{
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
BuildMon *pbm;
@ -717,7 +717,7 @@ meta_job_parent(Job *job, pid_t pid)
}
int
meta_job_fd(Job *job)
meta_job_fd(Job *job MAKE_ATTR_UNUSED)
{
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
BuildMon *pbm;
@ -735,7 +735,7 @@ meta_job_fd(Job *job)
}
int
meta_job_event(Job *job)
meta_job_event(Job *job MAKE_ATTR_UNUSED)
{
#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
BuildMon *pbm;
@ -1167,8 +1167,7 @@ meta_oodate(GNode *gn, bool oodate)
/* we want to track all the .meta we read */
Global_Append(".MAKE.META.FILES", fname);
cmp_filter = metaCmpFilter ? metaCmpFilter :
Var_Exists(gn, MAKE_META_CMP_FILTER);
cmp_filter = metaCmpFilter || Var_Exists(gn, MAKE_META_CMP_FILTER);
cmdNode = gn->commands.first;
while (!oodate && (x = fgetLine(&buf, &bufsz, 0, fp)) > 0) {

View File

@ -1,3 +1,26 @@
2022-03-25 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220323
* posix.mk: default rules for .POSIX:
2022-03-17 Simon J Gerraty <sjg@beast.crufty.net>
* sys/*.mk: remove l from ARFLAGS
2022-03-14 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220314
* dirdeps-options.mk: allow options to be per RELDIR
try DIRDEPS_OPTIONS_QUALIFIER_LIST first prefixed
with ${DEP_RELDIR}.
2022-02-14 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220214
* cc-wrap.mk: fix :@ modifier
2022-02-06 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220206

View File

@ -33,6 +33,7 @@ nls.mk
obj.mk
options.mk
own.mk
posix.mk
prlist.mk
prog.mk
progs.mk

View File

@ -1,4 +1,4 @@
# $Id: cc-wrap.mk,v 1.5 2022/02/07 19:02:55 sjg Exp $
# $Id: cc-wrap.mk,v 1.6 2022/02/16 17:41:52 sjg Exp $
#
# @(#) Copyright (c) 2022, Simon J. Gerraty
#
@ -41,7 +41,7 @@ ${w:tu} ?= $w
# we do not want to make all these targets out-of-date
# just because one of the above wrappers are enabled/disabled
${CC_WRAP_TARGETS}: .MAKE.META.CMP_FILTER = ${CC_WRAPPERS:tu@W@${$W}@:S,^,N,}
${CC_WRAP_TARGETS}: .MAKE.META.CMP_FILTER = ${CC_WRAPPERS:tu:@W@${$W}@:S,^,N,}
# some object src types we should not wrap
CC_WRAP_SKIP_EXTS += s

View File

@ -1,6 +1,6 @@
# $Id: dirdeps-options.mk,v 1.18 2020/12/22 18:10:34 sjg Exp $
# $Id: dirdeps-options.mk,v 1.20 2022/03/17 20:11:36 sjg Exp $
#
# @(#) Copyright (c) 2018-2020, Simon J. Gerraty
# @(#) Copyright (c) 2018-2022, Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
@ -54,6 +54,7 @@ DIRDEPS_OPTIONS ?=
# :U below avoids potential errors when we :=
# some options can depend on TARGET_SPEC!
DIRDEPS_OPTIONS_QUALIFIER_LIST ?= \
${DEP_RELDIR} \
${DEP_TARGET_SPEC:U${TARGET_SPEC}} \
${TARGET_SPEC_VARSr:U${TARGET_SPEC_VARS}:@v@${DEP_$v:U${$v}}@}
# note that we need to include $o in the variable _o$o
@ -61,7 +62,9 @@ DIRDEPS_OPTIONS_QUALIFIER_LIST ?= \
.for o in ${DIRDEPS_OPTIONS}
.undef _o$o
.undef _v$o
.for x in ${DIRDEPS_OPTIONS_QUALIFIER_LIST}
.for x in ${DIRDEPS_OPTIONS_QUALIFIER_LIST:S,^,${DEP_RELDIR}.,} \
${DIRDEPS_OPTIONS_QUALIFIER_LIST}
#.info MK_$o.$x=${MK_$o.$x:Uundefined}
.if defined(MK_$o.$x)
_o$o ?= MK_$o.$x
_v$o ?= ${MK_$o.$x}

4
mk/install-mk Executable file → Normal file
View File

@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: install-mk,v 1.214 2022/02/07 19:02:55 sjg Exp $
# $Id: install-mk,v 1.217 2022/03/25 23:43:43 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@ -70,7 +70,7 @@
# sjg@crufty.net
#
MK_VERSION=20220206
MK_VERSION=20220323
OWNER=
GROUP=
MODE=444

104
mk/posix.mk Normal file
View File

@ -0,0 +1,104 @@
# $Id: posix.mk,v 1.2 2022/03/25 23:55:37 sjg Exp $
#
# @(#) Copyright (c) 2022, Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
# Permission to copy, redistribute or otherwise
# use this file is hereby granted provided that
# the above copyright notice and this notice are
# left intact.
#
# Please send copies of changes and bug-fixes to:
# sjg@crufty.net
#
# The minimal set of rules required by POSIX
.if !defined(%POSIX)
.error ${.newline}Do not inlcude this directly, put .POSIX: at start of Makefile
.endif
.if ${.MAKEFLAGS:M-r} == ""
# undo some work done by sys.mk
.SUFFIXES:
.undef ARFLAGS
.undef CC CFLAGS
.undef FC FFLAGS
.undef LDFLAGS LFLAGS
.undef RANLIBFLAGS
.undef YFLAGS
.endif
.SUFFIXES: .o .c .y .l .a .sh .f
# these can still be set via environment
AR ?= ar
ARFLAGS ?= -rv
CC ?= c99
CFLAGS ?= -O
FC ?= fort77
FFLAGS ?= -O 1
LDFLAGS ?=
LEX ?= lex
LFLAGS ?=
RANLIBFLAGS ?= -D
YACC ?= yacc
YFLAGS ?=
.c:
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $<
.f:
${FC} ${FFLAGS} ${LDFLAGS} -o $@ $<
.sh:
cp $< $@
chmod a+x $@
.c.o:
${CC} ${CFLAGS} -c $<
.f.o:
${FC} ${FFLAGS} -c $<
.y.o:
${YACC} ${YFLAGS} $<
${CC} ${CFLAGS} -c y.tab.c
rm -f y.tab.c
mv y.tab.o $@
.l.o:
${LEX} ${LFLAGS} $<
${CC} ${CFLAGS} -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.o $@
.y.c:
${YACC} ${YFLAGS} $<
mv y.tab.c $@
.l.c:
${LEX} ${LFLAGS} $<
mv lex.yy.c $@
.c.a:
${CC} -c ${CFLAGS} $<
${AR} ${ARFLAGS} $@ $*.o
rm -f $*.o
.f.a:
${FC} -c ${FFLAGS} $<
${AR} ${ARFLAGS} $@ $*.o
rm -f $*.o

View File

@ -14,7 +14,7 @@ NOPIC ?=no # no shared libs?
.LIBS: .a
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= ranlib
AS ?= as
@ -182,3 +182,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -14,7 +14,7 @@ HOST_LIBEXT ?= .dylib
DSHLIBEXT ?= .dylib
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB =
AS ?= as
@ -220,3 +220,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -1,4 +1,4 @@
# $Id: Generic.mk,v 1.17 2020/08/19 17:51:53 sjg Exp $
# $Id: Generic.mk,v 1.19 2022/03/25 23:43:06 sjg Exp $
#
# some reasonable defaults
@ -27,7 +27,7 @@ MACHINE_ARCH = ${MACHINE_ARCH.${MACHINE}}
TSORT += -q
.endif
ARFLAGS ?= rl
ARFLAGS ?= r
AS ?= as
AFLAGS ?=
@ -201,4 +201,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -1,4 +1,4 @@
# $Id: HP-UX.mk,v 1.15 2020/08/19 17:51:53 sjg Exp $
# $Id: HP-UX.mk,v 1.17 2022/03/25 23:43:06 sjg Exp $
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
@ -33,7 +33,7 @@ LDADD+= /usr/lib/end.o
.endif
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= :
AFLAGS=
@ -224,3 +224,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -16,7 +16,7 @@ unix ?= We run ${OS}.
.LIBS: .a
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= ranlib
AS ?= as
@ -193,3 +193,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -1,4 +1,4 @@
# $Id: Linux.mk,v 1.13 2020/08/19 17:51:53 sjg Exp $
# $Id: Linux.mk,v 1.15 2022/03/25 23:43:06 sjg Exp $
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
@ -17,7 +17,7 @@ NEED_SOLINKS ?=yes
.LIBS: .a
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= ranlib
AS ?= as
@ -185,3 +185,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -25,7 +25,7 @@ MAKE_VERSION ?= 20010606
.LIBS: .a
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= ranlib
AS ?= as
@ -228,3 +228,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -1,4 +1,4 @@
# $Id: OSF1.mk,v 1.12 2020/08/19 17:51:53 sjg Exp $
# $Id: OSF1.mk,v 1.14 2022/03/25 23:43:06 sjg Exp $
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
@ -20,7 +20,7 @@ LD_X=
LD_x ?= -x
LD_r ?= -r
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= ranlib
AS ?= as
@ -196,3 +196,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -16,7 +16,7 @@ MACHINE_ARCH ?= ${MACHINE_ARCH.${MACHINE}}
.endif
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= ranlib
AS ?= as
@ -203,3 +203,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -1,4 +1,4 @@
# $Id: SunOS.mk,v 1.12 2020/08/19 17:51:53 sjg Exp $
# $Id: SunOS.mk,v 1.14 2022/03/25 23:43:06 sjg Exp $
.if ${.PARSEFILE} == "sys.mk"
.include <host-target.mk>
@ -46,7 +46,7 @@ CPP ?= cpp
.LIBS: .a
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
AS ?= as
AS_STDIN ?= -
@ -217,3 +217,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

View File

@ -1,4 +1,4 @@
# $Id: UnixWare.mk,v 1.8 2021/10/13 16:45:52 sjg Exp $
# $Id: UnixWare.mk,v 1.10 2022/03/25 23:43:06 sjg Exp $
# based on "Id: SunOS.5.sys.mk,v 1.6 2003/09/30 16:42:23 sjg Exp "
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
@ -22,7 +22,7 @@ PATH ?= /usr/sbin:/usr/bin:/usr/ccs/bin:/usr/ccs/lib:/usr/ucb:${DEV_TOOLS_PREFIX
LD_X=
LD_x=
AR ?= ar
ARFLAGS ?= rl
ARFLAGS ?= r
RANLIB ?= :
AS ?= as
@ -245,3 +245,4 @@ ${CXX_SUFFIXES:%=%.a}:
.sh:
rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET}

288
parse.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.663 2022/02/07 23:24:26 rillig Exp $ */
/* $NetBSD: parse.c,v 1.668 2022/03/25 21:16:04 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -121,7 +121,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: parse.c,v 1.663 2022/02/07 23:24:26 rillig Exp $");
MAKE_RCSID("$NetBSD: parse.c,v 1.668 2022/03/25 21:16:04 sjg Exp $");
/*
* A file being read.
@ -139,7 +139,7 @@ typedef struct IncludedFile {
bool depending; /* state of doing_depend on EOF */
Buffer buf; /* the file's content or the body of the .for
* loop; always ends with '\n' */
* loop; either empty or ends with '\n' */
char *buf_ptr; /* next char to be read */
char *buf_end; /* buf_end[-1] == '\n' */
@ -479,7 +479,7 @@ PrintLocation(FILE *f, bool useVars, const char *fname, unsigned lineno)
static void MAKE_ATTR_PRINTFLIKE(6, 0)
ParseVErrorInternal(FILE *f, bool useVars, const char *fname, unsigned lineno,
ParseErrorLevel type, const char *fmt, va_list ap)
ParseErrorLevel level, const char *fmt, va_list ap)
{
static bool fatal_warning_error_printed = false;
@ -487,15 +487,15 @@ ParseVErrorInternal(FILE *f, bool useVars, const char *fname, unsigned lineno,
if (fname != NULL)
PrintLocation(f, useVars, fname, lineno);
if (type == PARSE_WARNING)
if (level == PARSE_WARNING)
(void)fprintf(f, "warning: ");
(void)vfprintf(f, fmt, ap);
(void)fprintf(f, "\n");
(void)fflush(f);
if (type == PARSE_FATAL)
if (level == PARSE_FATAL)
parseErrors++;
if (type == PARSE_WARNING && opts.parseWarnFatal) {
if (level == PARSE_WARNING && opts.parseWarnFatal) {
if (!fatal_warning_error_printed) {
Error("parsing warnings being treated as errors");
fatal_warning_error_printed = true;
@ -509,19 +509,19 @@ ParseVErrorInternal(FILE *f, bool useVars, const char *fname, unsigned lineno,
static void MAKE_ATTR_PRINTFLIKE(4, 5)
ParseErrorInternal(const char *fname, unsigned lineno,
ParseErrorLevel type, const char *fmt, ...)
ParseErrorLevel level, const char *fmt, ...)
{
va_list ap;
(void)fflush(stdout);
va_start(ap, fmt);
ParseVErrorInternal(stderr, false, fname, lineno, type, fmt, ap);
ParseVErrorInternal(stderr, false, fname, lineno, level, fmt, ap);
va_end(ap);
if (opts.debug_file != stdout && opts.debug_file != stderr) {
va_start(ap, fmt);
ParseVErrorInternal(opts.debug_file, false, fname, lineno,
type, fmt, ap);
level, fmt, ap);
va_end(ap);
}
}
@ -535,7 +535,7 @@ ParseErrorInternal(const char *fname, unsigned lineno,
* Fmt is given without a trailing newline.
*/
void
Parse_Error(ParseErrorLevel type, const char *fmt, ...)
Parse_Error(ParseErrorLevel level, const char *fmt, ...)
{
va_list ap;
const char *fname;
@ -552,13 +552,13 @@ Parse_Error(ParseErrorLevel type, const char *fmt, ...)
(void)fflush(stdout);
va_start(ap, fmt);
ParseVErrorInternal(stderr, true, fname, lineno, type, fmt, ap);
ParseVErrorInternal(stderr, true, fname, lineno, level, fmt, ap);
va_end(ap);
if (opts.debug_file != stdout && opts.debug_file != stderr) {
va_start(ap, fmt);
ParseVErrorInternal(opts.debug_file, true, fname, lineno,
type, fmt, ap);
level, fmt, ap);
va_end(ap);
}
}
@ -768,14 +768,15 @@ ApplyDependencySourceMain(const char *src)
Global_Append(".TARGETS", src);
}
/*
* For the sources of a .ORDER target, create predecessor/successor links
* between the previous source and the current one.
*/
static void
ApplyDependencySourceOrder(const char *src)
{
GNode *gn;
/*
* Create proper predecessor/successor links between the previous
* source and the current one.
*/
gn = Targ_GetNode(src);
if (doing_depend)
RememberLocation(gn);
@ -861,7 +862,6 @@ static void
InvalidLineType(const char *line)
{
if (strncmp(line, "<<<<<<", 6) == 0 ||
strncmp(line, "======", 6) == 0 ||
strncmp(line, ">>>>>>", 6) == 0)
Parse_Error(PARSE_FATAL,
"Makefile appears to contain unresolved CVS/RCS/??? merge conflicts");
@ -1093,9 +1093,7 @@ CheckSpecialMundaneMixture(ParseSpecial special)
* shouldn't be empty.
*/
case SP_NOT:
/*
* Nothing special here -- targets can be empty if it wants.
*/
/* Nothing special here -- targets may be empty. */
break;
default:
Parse_Error(PARSE_WARNING,
@ -1132,6 +1130,121 @@ ClearPaths(SearchPathList *paths)
Dir_SetPATH();
}
/*
* Handle one of the .[-ds]include directives by remembering the current file
* and pushing the included file on the stack. After the included file has
* finished, parsing continues with the including file; see Parse_PushInput
* and ParseEOF.
*
* System includes are looked up in sysIncPath, any other includes are looked
* up in the parsedir and then in the directories specified by the -I command
* line options.
*/
static void
IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
{
Buffer buf;
char *fullname; /* full pathname of file */
char *newName;
char *slash, *incdir;
int fd;
int i;
fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
if (fullname == NULL && !isSystem) {
/*
* Include files contained in double-quotes are first searched
* relative to the including file's location. We don't want to
* cd there, of course, so we just tack on the old file's
* leading path components and call Dir_FindFile to see if
* we can locate the file.
*/
incdir = bmake_strdup(CurFile()->name.str);
slash = strrchr(incdir, '/');
if (slash != NULL) {
*slash = '\0';
/*
* Now do lexical processing of leading "../" on the
* filename.
*/
for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
slash = strrchr(incdir + 1, '/');
if (slash == NULL || strcmp(slash, "/..") == 0)
break;
*slash = '\0';
}
newName = str_concat3(incdir, "/", file + i);
fullname = Dir_FindFile(newName, parseIncPath);
if (fullname == NULL)
fullname = Dir_FindFile(newName,
&dirSearchPath);
free(newName);
}
free(incdir);
if (fullname == NULL) {
/*
* Makefile wasn't found in same directory as included
* makefile.
*
* Search for it first on the -I search path, then on
* the .PATH search path, if not found in a -I
* directory. If we have a suffix-specific path, we
* should use that.
*/
const char *suff;
SearchPath *suffPath = NULL;
if ((suff = strrchr(file, '.')) != NULL) {
suffPath = Suff_GetPath(suff);
if (suffPath != NULL)
fullname = Dir_FindFile(file, suffPath);
}
if (fullname == NULL) {
fullname = Dir_FindFile(file, parseIncPath);
if (fullname == NULL)
fullname = Dir_FindFile(file,
&dirSearchPath);
}
}
}
/* Looking for a system file or file still not found */
if (fullname == NULL) {
/*
* Look for it on the system path
*/
SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs)
? defSysIncPath : sysIncPath;
fullname = Dir_FindFile(file, path);
}
if (fullname == NULL) {
if (!silent)
Parse_Error(PARSE_FATAL, "Could not find %s", file);
return;
}
/* Actually open the file... */
fd = open(fullname, O_RDONLY);
if (fd == -1) {
if (!silent)
Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
free(fullname);
return;
}
buf = loadfile(fullname, fd);
(void)close(fd);
Parse_PushInput(fullname, 1, 0, buf, NULL);
if (depinc)
doing_depend = depinc; /* only turn it on */
free(fullname);
}
/* Handle a "dependency" line like '.SPECIAL:' without any sources. */
static void
HandleDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths)
@ -1155,6 +1268,23 @@ HandleDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths)
#ifdef POSIX
case SP_POSIX:
Global_Set("%POSIX", "1003.2");
{
static bool first_posix = true;
/*
* Since .POSIX: should be the first
* operative line in a makefile,
* if '-r' flag is used, no default rules have
* been read yet, in which case 'posix.mk' can
* be a substiute for 'sys.mk'.
* If '-r' is not used, then 'posix.mk' acts
* as an extension of 'sys.mk'.
*/
if (first_posix) {
first_posix = false;
IncludeFile("posix.mk", true, false, true);
}
}
break;
#endif
default:
@ -1556,7 +1686,7 @@ Parse_IsVar(const char *p, VarAssign *out_var)
cpp_skip_hspace(&p); /* Skip to variable name */
/*
* During parsing, the '+' of the '+=' operator is initially parsed
* During parsing, the '+' of the operator '+=' is initially parsed
* as part of the variable name. It is later corrected, as is the
* ':sh' modifier. Of these two (nameEnd and eq), the earlier one
* determines the actual end of the variable name.
@ -1840,120 +1970,6 @@ Parse_AddIncludeDir(const char *dir)
(void)SearchPath_Add(parseIncPath, dir);
}
/*
* Handle one of the .[-ds]include directives by remembering the current file
* and pushing the included file on the stack. After the included file has
* finished, parsing continues with the including file; see Parse_PushInput
* and ParseEOF.
*
* System includes are looked up in sysIncPath, any other includes are looked
* up in the parsedir and then in the directories specified by the -I command
* line options.
*/
static void
IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
{
Buffer buf;
char *fullname; /* full pathname of file */
char *newName;
char *slash, *incdir;
int fd;
int i;
fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
if (fullname == NULL && !isSystem) {
/*
* Include files contained in double-quotes are first searched
* relative to the including file's location. We don't want to
* cd there, of course, so we just tack on the old file's
* leading path components and call Dir_FindFile to see if
* we can locate the file.
*/
incdir = bmake_strdup(CurFile()->name.str);
slash = strrchr(incdir, '/');
if (slash != NULL) {
*slash = '\0';
/*
* Now do lexical processing of leading "../" on the
* filename.
*/
for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
slash = strrchr(incdir + 1, '/');
if (slash == NULL || strcmp(slash, "/..") == 0)
break;
*slash = '\0';
}
newName = str_concat3(incdir, "/", file + i);
fullname = Dir_FindFile(newName, parseIncPath);
if (fullname == NULL)
fullname = Dir_FindFile(newName,
&dirSearchPath);
free(newName);
}
free(incdir);
if (fullname == NULL) {
/*
* Makefile wasn't found in same directory as included
* makefile.
*
* Search for it first on the -I search path, then on
* the .PATH search path, if not found in a -I
* directory. If we have a suffix-specific path, we
* should use that.
*/
const char *suff;
SearchPath *suffPath = NULL;
if ((suff = strrchr(file, '.')) != NULL) {
suffPath = Suff_GetPath(suff);
if (suffPath != NULL)
fullname = Dir_FindFile(file, suffPath);
}
if (fullname == NULL) {
fullname = Dir_FindFile(file, parseIncPath);
if (fullname == NULL)
fullname = Dir_FindFile(file,
&dirSearchPath);
}
}
}
/* Looking for a system file or file still not found */
if (fullname == NULL) {
/*
* Look for it on the system path
*/
SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs)
? defSysIncPath : sysIncPath;
fullname = Dir_FindFile(file, path);
}
if (fullname == NULL) {
if (!silent)
Parse_Error(PARSE_FATAL, "Could not find %s", file);
return;
}
/* Actually open the file... */
fd = open(fullname, O_RDONLY);
if (fd == -1) {
if (!silent)
Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
free(fullname);
return;
}
buf = loadfile(fullname, fd);
(void)close(fd);
Parse_PushInput(fullname, 1, 0, buf, NULL);
if (depinc)
doing_depend = depinc; /* only turn it on */
free(fullname);
}
/*
* Parse a directive like '.include' or '.-include'.

8
str.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: str.c,v 1.88 2021/12/15 10:57:01 rillig Exp $ */
/* $NetBSD: str.c,v 1.89 2022/03/03 19:50:01 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -71,7 +71,7 @@
#include "make.h"
/* "@(#)str.c 5.8 (Berkeley) 6/1/90" */
MAKE_RCSID("$NetBSD: str.c,v 1.88 2021/12/15 10:57:01 rillig Exp $");
MAKE_RCSID("$NetBSD: str.c,v 1.89 2022/03/03 19:50:01 rillig Exp $");
static HashTable interned_strings;
@ -364,9 +364,9 @@ Str_Match(const char *str, const char *pat)
if (pat[1] == '-') {
if (pat[2] == '\0')
return neg;
if (*pat <= *str && pat[2] >= *str)
if (pat[0] <= *str && *str <= pat[2])
break;
if (*pat >= *str && pat[2] <= *str)
if (pat[2] <= *str && *str <= pat[0])
break;
pat += 2;
}

14
suff.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: suff.c,v 1.364 2022/01/07 20:54:45 rillig Exp $ */
/* $NetBSD: suff.c,v 1.366 2022/03/04 23:17:16 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -115,7 +115,7 @@
#include "dir.h"
/* "@(#)suff.c 8.4 (Berkeley) 3/21/94" */
MAKE_RCSID("$NetBSD: suff.c,v 1.364 2022/01/07 20:54:45 rillig Exp $");
MAKE_RCSID("$NetBSD: suff.c,v 1.366 2022/03/04 23:17:16 sjg Exp $");
typedef List SuffixList;
typedef ListNode SuffixListNode;
@ -145,8 +145,8 @@ static int sNum = 0;
typedef List SuffixListList;
/*
* A suffix such as ".c" or ".o" that is used in suffix transformation rules
* such as ".c.o:".
* A suffix such as ".c" or ".o" that may be used in suffix transformation
* rules such as ".c.o:".
*/
typedef struct Suffix {
/* The suffix itself, such as ".c" */
@ -859,9 +859,9 @@ Suff_AddSuffix(const char *name)
/* Return the search path for the given suffix, or NULL. */
SearchPath *
Suff_GetPath(const char *sname)
Suff_GetPath(const char *name)
{
Suffix *suff = FindSuffixByName(sname);
Suffix *suff = FindSuffixByName(name);
return suff != NULL ? suff->searchPath : NULL;
}
@ -1019,7 +1019,7 @@ Candidate_New(char *name, char *prefix, Suffix *suff, Candidate *parent,
/*ARGSUSED*/
static void
CandidateList_Add(CandidateList *list, char *srcName, Candidate *targ,
Suffix *suff, const char *debug_tag)
Suffix *suff, const char *debug_tag MAKE_ATTR_UNUSED)
{
Candidate *cand = Candidate_New(srcName, targ->prefix, suff, targ,
NULL);

View File

@ -1,4 +1,4 @@
/* $NetBSD: trace.c,v 1.31 2022/02/05 00:26:21 rillig Exp $ */
/* $NetBSD: trace.c,v 1.32 2022/03/26 14:02:40 rillig Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -48,7 +48,7 @@
#include "job.h"
#include "trace.h"
MAKE_RCSID("$NetBSD: trace.c,v 1.31 2022/02/05 00:26:21 rillig Exp $");
MAKE_RCSID("$NetBSD: trace.c,v 1.32 2022/03/26 14:02:40 rillig Exp $");
static FILE *trfile;
static pid_t trpid;
@ -90,7 +90,7 @@ Trace_Log(TrEvent event, Job *job)
gettimeofday(&rightnow, NULL);
#if __STDC__ >= 199901L
#if __STDC_VERSION__ >= 199901L
fprintf(trfile, "%lld.%06ld %d %s %d %s",
(long long)rightnow.tv_sec, (long)rightnow.tv_usec,
jobTokensRunning,

View File

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.174 2022/02/09 02:42:59 sjg Exp $
# $Id: Makefile,v 1.178 2022/03/26 23:10:27 sjg Exp $
#
# $NetBSD: Makefile,v 1.303 2022/02/07 22:43:50 rillig Exp $
# $NetBSD: Makefile,v 1.311 2022/03/26 12:44:57 rillig Exp $
#
# Unit tests for make(1)
#
@ -145,6 +145,7 @@ TESTS+= deptgt-phony
TESTS+= deptgt-precious
TESTS+= deptgt-shell
TESTS+= deptgt-silent
TESTS+= deptgt-silent-jobs
TESTS+= deptgt-stale
TESTS+= deptgt-suffixes
TESTS+= dir
@ -258,6 +259,7 @@ TESTS+= opt-jobs
TESTS+= opt-jobs-internal
TESTS+= opt-jobs-no-action
TESTS+= opt-keep-going
TESTS+= opt-keep-going-indirect
TESTS+= opt-keep-going-multiple
TESTS+= opt-m-include-dir
TESTS+= opt-no-action
@ -501,6 +503,8 @@ TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}}
# Additional environment variables for some of the tests.
# The base environment is -i PATH="$PATH".
ENV.depsrc-optional+= TZ=UTC
ENV.deptgt-phony+= MAKESYSPATH=.
ENV.directive-undef= ENV_VAR=env-value
ENV.envfirst= FROM_ENV=value-from-env
ENV.varmisc= FROM_ENV=env
ENV.varmisc+= FROM_ENV_BEFORE=env
@ -519,9 +523,8 @@ FLAGS.jobs-error-nested-make= # none, especially not -k
FLAGS.varname-empty= -dv '$${:U}=cmdline-u' '=cmdline-plain'
# Some tests need extra postprocessing.
SED_CMDS.dir= ${:D remove output from -DCLEANUP mode }
SED_CMDS.dir+= -e '/^OpenDirs_Done:/d'
SED_CMDS.dir+= -e '/^CachedDir /d'
SED_CMDS.deptgt-phony= ${STD_SED_CMDS.dd}
SED_CMDS.dir= ${STD_SED_CMDS.dd}
SED_CMDS.export= -e '/^[^=_A-Za-z0-9]*=/d'
SED_CMDS.export-all= ${SED_CMDS.export}
SED_CMDS.export-env= ${SED_CMDS.export}
@ -592,6 +595,11 @@ unexport-env.rawout: export.mk
# Some standard sed commands, to be used in the SED_CMDS above.
# In tests that use the debugging option -dd, ignore debugging output that is
# only logged in -DCLEANUP mode.
STD_SED_CMDS.dd= -e '/^OpenDirs_Done:/d'
STD_SED_CMDS.dd+= -e '/^CachedDir /d'
# Omit details such as process IDs from the output of the -dg1 option.
STD_SED_CMDS.dg1= -e '/\#.* \.$$/d'
STD_SED_CMDS.dg1+= -e '/\.MAKE.PATH_FILEMON/d'
@ -712,7 +720,7 @@ TMPDIR:= /tmp/uid${.MAKE.UID}
.endif
# make sure it exists
.if !exist(${TMPDIR})
x!= echo; mkdir -p ${TMPDIR}
_!= mkdir -p ${TMPDIR}
.endif
MAKE_TEST_ENV= MALLOC_OPTIONS="JA" # for jemalloc 100
@ -724,7 +732,7 @@ LIMIT_RESOURCES?= ulimit -v 200000
.endif
LIMIT_RESOURCES?= :
# Each test is run in a sub-make, to keep the tests for interfering with
# Each test is run in a sub-make, to keep the tests from interfering with
# each other, and because they use different environment variables and
# command line options.
.SUFFIXES: .mk .rawout .out
@ -747,14 +755,13 @@ LIMIT_RESOURCES?= :
# always pretend .MAKE was called 'make'
_SED_CMDS+= -e 's,^${TEST_MAKE:T:S,.,\\.,g}[][0-9]*:,make:,'
_SED_CMDS+= -e 's,${TEST_MAKE:S,.,\\.,g},make,'
_SED_CMDS+= -e 's,${TEST_MAKE:T:S,.,\\.,g}[][0-9]* warning,make warning,'
_SED_CMDS+= -e 's,^usage: ${TEST_MAKE:T:S,.,\\.,g} ,usage: make ,'
# replace anything after 'stopped in' with unit-tests
_SED_CMDS+= -e '/stopped/s, /.*, unit-tests,'
# Allow the test files to be placed anywhere.
_SED_CMDS+= -e 's,\(\.PARSEDIR}\) = `'"/[^']*'"',\1 = <some-dir>,'
_SED_CMDS+= -e 's,\(\.INCLUDEDFROMDIR}\) = `'"/[^']*'"',\1 = <some-dir>,'
_SED_CMDS+= -e 's,${TMPDIR},TMPDIR,g'
_SED_CMDS+= -e 's,${TMPDIR},<tmpdir>,g'
# canonicalize ${.OBJDIR} and ${.CURDIR}
.if ${.OBJDIR} != ${.CURDIR}
# yes this is inaccurate but none of the tests expect <objdir> anywhere

View File

@ -1,5 +1,5 @@
makeobjdir-direct:
show-objdir: TMPDIR/6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5
show-objdir: <tmpdir>/6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5
makeobjdir-indirect:
show-objdir: TMPDIR/a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45/
show-objdir: <tmpdir>/a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45/
exit status 0

View File

@ -3,11 +3,11 @@ make: "cond-cmp-numeric.mk" line 11: String comparison operator must be either =
CondParser_Eval: ${:UNaN} > NaN
make: "cond-cmp-numeric.mk" line 16: String comparison operator must be either == or !=
CondParser_Eval: !(${:UNaN} == NaN)
lhs = "NaN", rhs = "NaN", op = ==
Comparing "NaN" == "NaN"
CondParser_Eval: 123 ! 123
make: "cond-cmp-numeric.mk" line 34: Malformed conditional (123 ! 123)
CondParser_Eval: ${:U 123} < 124
lhs = 123.000000, rhs = 124.000000, op = <
Comparing 123.000000 < 124.000000
CondParser_Eval: ${:U123 } < 124
make: "cond-cmp-numeric.mk" line 50: String comparison operator must be either == or !=
make: Fatal errors encountered -- cannot continue

View File

@ -1,31 +1,31 @@
CondParser_Eval: ${:Uvalue} != value
lhs = "value", rhs = "value", op = !=
Comparing "value" != "value"
CondParser_Eval: ${:U} != "
lhs = "", rhs = "", op = !=
Comparing "" != ""
CondParser_Eval: ${:U#hash} != "#hash"
lhs = "#hash", rhs = "#hash", op = !=
Comparing "#hash" != "#hash"
CondParser_Eval: ${:U\\} != "\\
lhs = "\", rhs = "\", op = !=
Comparing "\" != "\"
CondParser_Eval: ${:U#hash} != #hash
lhs = "#hash", rhs = "#hash", op = !=
Comparing "#hash" != "#hash"
CondParser_Eval: 0 # This is treated as a comment, but why?
CondParser_Eval: ${0 # comment :?yes:no} != no
CondParser_Eval: 0 # comment
lhs = "no", rhs = "no", op = !=
Comparing "no" != "no"
CondParser_Eval: ${1 # comment :?yes:no} != yes
CondParser_Eval: 1 # comment
lhs = "yes", rhs = "yes", op = !=
Comparing "yes" != "yes"
CondParser_Eval: ${UNDEF:Uundefined}!=undefined
lhs = "undefined", rhs = "undefined", op = !=
Comparing "undefined" != "undefined"
CondParser_Eval: ${UNDEF:U12345}>12345
lhs = 12345.000000, rhs = 12345.000000, op = >
Comparing 12345.000000 > 12345.000000
CondParser_Eval: ${UNDEF:U12345}<12345
lhs = 12345.000000, rhs = 12345.000000, op = <
Comparing 12345.000000 < 12345.000000
CondParser_Eval: (${UNDEF:U0})||0
CondParser_Eval: ${:Uvar}&&name != "var&&name"
lhs = "var&&name", rhs = "var&&name", op = !=
Comparing "var&&name" != "var&&name"
CondParser_Eval: ${:Uvar}||name != "var||name"
lhs = "var||name", rhs = "var||name", op = !=
Comparing "var||name" != "var||name"
CondParser_Eval: bare
make: "cond-token-plain.mk" line 105: A bare word is treated like defined(...), and the variable 'bare' is not defined.
CondParser_Eval: VAR
@ -47,7 +47,7 @@ make: "cond-token-plain.mk" line 167: The variable '\\' is not defined.
CondParser_Eval: \\
make: "cond-token-plain.mk" line 172: Now the variable '\\' is defined.
CondParser_Eval: "unquoted\"quoted" != unquoted"quoted
lhs = "unquoted"quoted", rhs = "unquoted"quoted", op = !=
Comparing "unquoted"quoted" != "unquoted"quoted"
CondParser_Eval: $$$$$$$$ != ""
CondParser_Eval: left == right
make: "cond-token-plain.mk" line 195: Malformed conditional (left == right)

View File

@ -1,4 +1,4 @@
# $NetBSD: depsrc-meta.mk,v 1.6 2022/01/26 22:47:03 rillig Exp $
# $NetBSD: depsrc-meta.mk,v 1.7 2022/03/02 19:32:15 sjg Exp $
#
# Tests for the special source .META in dependency declarations.
@ -9,7 +9,7 @@
.if make(actual-test)
.MAKEFLAGS: -dM
.MAKE.MODE= meta curDirOk=true
.MAKE.MODE= meta curDirOk=true nofilemon
.endif
actual-test: depsrc-meta-target

View File

@ -1,9 +1,9 @@
Global:delete DOLLAR (not found)
Global: delete DOLLAR (not found)
Command: DOLLAR = $$$$
Global: .MAKEOVERRIDES = VAR DOLLAR
CondParser_Eval: ${DOLLAR} != "\$\$"
Var_Parse: ${DOLLAR} != "\$\$" (eval-defined)
lhs = "$$", rhs = "$$", op = !=
Comparing "$$" != "$$"
Global: .MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d
Global: .MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d 0
make: Unterminated quoted string [make VAR=initial UNBALANCED=']

View File

@ -1 +1,42 @@
Expanding "depsrc-phony-pr-15164-*-wildcard"...
Expanding "deptgt-phony-pr-15164-*-wildcard"...
Searching for .depend ...
failed.
Searching for .depend ...
. ...
failed.
Wildcard expanding "all"...
Searching for all ...
failed.
Found 'all' as '(not found)'
SuffFindDeps "all"
No known suffix on all. Using .NULL suffix
adding suffix rules
Wildcard expanding "depsrc-phony-pr-15164-*-wildcard"...
Expanding "depsrc-phony-pr-15164-*-wildcard"...
Wildcard expanding "deptgt-phony-pr-15164-*-wildcard"...
Expanding "deptgt-phony-pr-15164-*-wildcard"...
Searching for all ...
failed.
SuffFindDeps "depsrc-phony-pr-15164"
No valid suffix on depsrc-phony-pr-15164
SuffFindDeps "deptgt-phony-pr-15164"
No valid suffix on deptgt-phony-pr-15164
: Making depsrc-phony-pr-15164
: Making deptgt-phony-pr-15164
Wildcard expanding "all"...
Searching for all ...
failed.
Found 'all' as '(not found)'
SuffFindDeps ".END"
No known suffix on .END. Using .NULL suffix
adding suffix rules
Searching for .END ...
failed.
Wildcard expanding ".END"...
Searching for .END ...
failed.
Found '.END' as '(not found)'
exit status 0

View File

@ -1,8 +1,31 @@
# $NetBSD: deptgt-phony.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
# $NetBSD: deptgt-phony.mk,v 1.3 2022/02/11 23:44:18 rillig Exp $
#
# Tests for the special target .PHONY in dependency declarations.
# TODO: Implementation
all:
@:;
# https://gnats.netbsd.org/15164 describes that .PHONY targets are still
# looked up in directories, even though .PHONY means that these targets do
# _not_ correspond to actual files.
#
# expect: Expanding "depsrc-phony-pr-15164-*-wildcard"...
# expect: Expanding "deptgt-phony-pr-15164-*-wildcard"...
.MAKEFLAGS: -dds
depsrc-phony-pr-15164: .PHONY
: Making ${.TARGET}
depsrc-phony-pr-15164-*-wildcard: .PHONY
: Making ${.TARGET}
.PHONY: deptgt-phony-pr-15164
deptgt-phony-pr-15164:
: Making ${.TARGET}
.PHONY: deptgt-phony-pr-15164-*-wildcard
deptgt-phony-pr-15164-*-wildcard:
: Making ${.TARGET}
all: depsrc-phony-pr-15164 depsrc-phony-pr-15164-*-wildcard
all: deptgt-phony-pr-15164 deptgt-phony-pr-15164-*-wildcard

View File

@ -0,0 +1,7 @@
compat: testing 1
compat: testing 2
compat: testing 3
jobs: testing 1
jobs: testing 2
jobs: testing 3
exit status 0

View File

@ -0,0 +1,35 @@
# $NetBSD: deptgt-silent-jobs.mk,v 1.2 2022/02/12 11:14:48 rillig Exp $
#
# Ensure that the special dependency target '.SILENT' only affects the amount
# of output, but not the kind of error handling.
#
# History:
# In job.c 1.83 from 2003.12.20.00.18.22, in an attempt to fix
# https://gnats.netbsd.org/18573, commands that suppressed error
# handling were output in jobs mode, even when the global '.SILENT'
# was set. This was fixed in job.c 1.452 from 2022-02-12.
#
# See also:
# https://gnats.netbsd.org/45356
all: compat jobs
.PHONY: all compat jobs test
.SILENT:
test:
@echo '${VARIANT}: testing 1'
-echo '${VARIANT}: testing 2'
echo '${VARIANT}: testing 3'
# expect: compat: testing 1
# expect: compat: testing 2
# expect: compat: testing 3
compat:
@${MAKE} -r -f ${MAKEFILE} test VARIANT=compat
# expect: jobs: testing 1
# expect: echo 'jobs: testing 2'
# expect: jobs: testing 2
# expect: jobs: testing 3
jobs:
@${MAKE} -r -f ${MAKEFILE} test VARIANT=jobs -j1

View File

@ -1,7 +1,7 @@
# $NetBSD: directive-elifdef.mk,v 1.3 2022/01/22 16:23:56 rillig Exp $
# $NetBSD: directive-elifdef.mk,v 1.4 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the .elifdef directive, which is seldom used. Instead of writing
# '.elifdef VAR', the usual form is the more versatile '.elif defined(VAR)'.
# '.elifdef VAR', the usual form is the more general '.elif defined(VAR)'.
# At this point, VAR is not defined, so the condition evaluates to false.
.if 0

View File

@ -23,7 +23,7 @@ Result of ${.MAKE.EXPORTED:u} is "UT_VAR"
Var_Parse: ${UT_VAR} (eval)
Var_Parse: ${REF}> (eval)
Result of ${:!echo "\$UT_VAR"!} is "<>" (eval-defined, defined)
lhs = "<>", rhs = "<>", op = !=
Comparing "<>" != "<>"
Parsing line 50: : ${UT_VAR:N*}
Var_Parse: ${UT_VAR:N*} (eval-defined)
Var_Parse: ${REF}> (eval-defined)
@ -47,7 +47,7 @@ Result of ${.MAKE.EXPORTED:u} is "UT_VAR"
Var_Parse: ${UT_VAR} (eval)
Var_Parse: ${REF}> (eval)
Result of ${:!echo "\$UT_VAR"!} is "<defined>" (eval-defined, defined)
lhs = "<defined>", rhs = "<defined>", op = !=
Comparing "<defined>" != "<defined>"
Parsing line 62: all:
ParseDependency(all:)
Global: .ALLTARGETS = all

View File

@ -1,10 +1,10 @@
# $NetBSD: directive-ifmake.mk,v 1.9 2022/01/22 16:23:56 rillig Exp $
# $NetBSD: directive-ifmake.mk,v 1.10 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the .ifmake directive, which provides a shortcut for asking
# whether a certain target is requested to be made from the command line.
#
# TODO: Describe why the shortcut may be useful (if it's useful at all),
# instead of using the more versatile '.if make(target)'.
# instead of using the more general '.if make(target)'.
.MAKEFLAGS: first second

View File

@ -1,7 +1,7 @@
CondParser_Eval: ${.MAKE.MAKEFILES:T} != "${.PARSEFILE} null"
lhs = "directive-include.mk null", rhs = "directive-include.mk null", op = !=
Comparing "directive-include.mk null" != "directive-include.mk null"
CondParser_Eval: ${.MAKE.MAKEFILES:T} != "${.PARSEFILE} null"
lhs = "directive-include.mk null", rhs = "directive-include.mk null", op = !=
Comparing "directive-include.mk null" != "directive-include.mk null"
make: "directive-include.mk" line 25: Could not find nonexistent.mk
make: "directive-include.mk" line 47: Could not find "
make: "directive-include.mk" line 52: Unknown modifier "Z"

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-undef.mk,v 1.10 2021/02/16 18:02:19 rillig Exp $
# $NetBSD: directive-undef.mk,v 1.12 2022/03/26 12:44:57 rillig Exp $
#
# Tests for the .undef directive.
#
@ -43,11 +43,11 @@
3= 3
${:U1 2 3}= one two three
VARNAMES= 1 2 3
.undef ${VARNAMES} # undefines the variable "1 2 3"
.if !defined(${:U1 2 3})
.undef ${VARNAMES} # undefines the variables "1", "2" and "3"
.if ${${:U1 2 3}} != "one two three" # still there
. error
.endif
.if ${1:U_}${2:U_}${3:U_} != "___" # these are still defined
.if ${1:U_}${2:U_}${3:U_} != "___" # these have been undefined
. error
.endif
@ -104,4 +104,42 @@ UT_EXPORTED= exported-value
.endif
# When an exported variable is undefined, the variable is removed both from
# the global scope as well as from the environment.
DIRECT= direct
INDIRECT= in-${DIRECT}
.export DIRECT INDIRECT
.if ${DIRECT} != "direct"
. error
.endif
.if ${INDIRECT} != "in-direct"
. error
.endif
# Deletes the variables from the global scope and also from the environment.
# This applies to both variables, even though 'INDIRECT' is not actually
# exported yet since it refers to another variable.
.undef DIRECT # Separate '.undef' directives,
.undef INDIRECT # for backwards compatibility.
.if ${DIRECT:Uundefined} != "undefined"
. error
.endif
.if ${INDIRECT:Uundefined} != "undefined"
. error
.endif
# Since var.c 1.570 from 2020-10-06 and before var.c 1.1014 from 2022-03-26,
# make ran into an assertion failure when trying to undefine a variable that
# was based on an environment variable.
.if ${ENV_VAR} != "env-value" # see ./Makefile, ENV.directive-undef
. error
.endif
ENV_VAR+= appended # moves the short-lived variable to the
# global scope
.undef ENV_VAR # removes the variable from both the global
# scope and from the environment
all:

View File

@ -10,7 +10,7 @@ Result of ${.MAKE.EXPORTED:O} is "UT_EXPORTED"
Evaluating modifier ${.MAKE.EXPORTED:u} on value "UT_EXPORTED"
Result of ${.MAKE.EXPORTED:u} is "UT_EXPORTED"
Unexporting "UT_EXPORTED"
Global:delete .MAKE.EXPORTED
Global: delete .MAKE.EXPORTED
Global: .MAKEFLAGS = -r -k -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0
make: Fatal errors encountered -- cannot continue

View File

@ -2,7 +2,7 @@ make: "directive.mk" line 10: Unknown directive "indented"
make: "directive.mk" line 12: Unknown directive "indented"
make: "directive.mk" line 14: Unknown directive "indented"
make: "directive.mk" line 21: Unknown directive "info"
Global: .info =
Global: .info = # (empty)
Global: .info = value
make: "directive.mk" line 33: := value
Global: .MAKEFLAGS = -r -k -d v -d

View File

@ -1,5 +1,5 @@
MAKELEVEL=1
TMPDIR=TMPDIR
TMPDIR=<tmpdir>
UT_DOLLAR=This is $UT_FU
UT_FOO=foobar is fubar
UT_FU=fubar

View File

@ -1,11 +1,11 @@
# $NetBSD: meta-cmd-cmp.mk,v 1.4 2022/01/27 06:02:59 sjg Exp $
# $NetBSD: meta-cmd-cmp.mk,v 1.6 2022/03/02 19:32:15 sjg Exp $
#
# Tests META_MODE command line comparison
#
.MAIN: all
.MAKE.MODE= meta verbose silent=yes curdirok=yes
.MAKE.MODE= meta verbose silent=yes curdirok=yes nofilemon
tf:= .${.PARSEFILE:R}
.if ${.TARGETS:Nall} == ""
@ -36,7 +36,7 @@ ${tf}.cmp2:
@echo FLAGS2=${FLAGS2:Uempty} > $@
@echo This line not compared FLAGS=${FLAGS:Uempty} ${.OODATE:MNOMETA_CMP}
COMPILER_WRAPPERS+= ccache distcc icecc
COMPILER_WRAPPERS= ccache distcc icecc
WRAPPER?= ccache
.ifdef WITH_CMP_FILTER
.MAKE.META.CMP_FILTER+= ${COMPILER_WRAPPERS:S,^,N,}

View File

@ -1,5 +1,5 @@
make warning: TMPDIR/roobj: Permission denied.
TMPDIR
TMPDIR/roobj
TMPDIR/roobj
make: warning: <tmpdir>/roobj: Permission denied.
<tmpdir>
<tmpdir>/roobj
<tmpdir>/roobj
exit status 0

View File

@ -1,4 +1,4 @@
# $NetBSD: objdir-writable.mk,v 1.5 2021/07/04 01:28:54 sjg Exp $
# $NetBSD: objdir-writable.mk,v 1.7 2022/02/09 21:24:29 rillig Exp $
# test checking for writable objdir
@ -14,7 +14,8 @@ do-objdir:
all: no-objdir ro-objdir explicit-objdir
# make it now
x!= echo; mkdir -p ${RO_OBJDIR}; chmod 555 ${RO_OBJDIR}
_!= mkdir -p ${RO_OBJDIR}
_!= chmod 555 ${RO_OBJDIR}
.END: rm-objdir
rm-objdir:
@ -29,4 +30,3 @@ ro-objdir:
explicit-objdir:
@MAKEOBJDIR=${TMPDIR} ${.MAKE} -r -f ${MAKEFILE:tA} -C ${TMPDIR} do-objdir -V .OBJDIR
.endif

View File

@ -1,6 +1,6 @@
CondParser_Eval: ${:U12345} > ${:U55555}
lhs = 12345.000000, rhs = 55555.000000, op = >
Comparing 12345.000000 > 55555.000000
CondParser_Eval: "string" != "string"
lhs = "string", rhs = "string", op = !=
Comparing "string" != "string"
CondParser_Eval: "nonempty"
exit status 0

View File

@ -2,11 +2,11 @@ make: "opt-debug-file.mk" line 43: This goes to stderr only, once.
make: "opt-debug-file.mk" line 45: This goes to stderr only, once.
make: "opt-debug-file.mk" line 47: This goes to stderr, and in addition to the debug log.
CondParser_Eval: ${:!cat opt-debug-file.debuglog!:Maddition:[#]} != 1
lhs = 1.000000, rhs = 1.000000, op = !=
Comparing 1.000000 != 1.000000
make: Missing delimiter for modifier ':S'
make: Missing delimiter for modifier ':S'
make: Missing delimiter for modifier ':S'
CondParser_Eval: ${:!cat opt-debug-file.debuglog!:Mdelimiter:[#]} != 1
lhs = 1.000000, rhs = 1.000000, op = !=
Comparing 1.000000 != 1.000000
Cannot open debug file "/nonexistent-6f21c672-a22d-4ef7/opt-debug-file.debuglog"
exit status 2

View File

@ -16,8 +16,8 @@
#*** Global Variables:
.ALLTARGETS = all made-target made-target-no-sources made-source unmade-target unmade-sources unmade-silent-source unmade-target-no-sources
.CURDIR = <curdir>
.INCLUDES =
.LIBS =
.INCLUDES = # (empty)
.LIBS = # (empty)
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
@ -29,12 +29,12 @@
.MAKE.PPID = <details omitted>
.MAKE.UID = <details omitted>
.MAKEFLAGS = -r -k -d g1
.MAKEOVERRIDES =
.MAKEOVERRIDES = # (empty)
.OBJDIR = <curdir>
.PATH = . <curdir>
.TARGETS =
.TARGETS = # (empty)
.newline =
# (ends with space)
MACHINE = <details omitted>
MACHINE_ARCH = <details omitted>
MAKE = <details omitted>

View File

@ -50,8 +50,8 @@ all : made-target error-target aborted-target
#*** Global Variables:
.ALLTARGETS = made-target error-target aborted-target aborted-target-dependency all .END
.CURDIR = <curdir>
.INCLUDES =
.LIBS =
.INCLUDES = # (empty)
.LIBS = # (empty)
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
@ -63,12 +63,12 @@ all : made-target error-target aborted-target
.MAKE.PPID = <details omitted>
.MAKE.UID = <details omitted>
.MAKEFLAGS = -r -k -d g2
.MAKEOVERRIDES =
.MAKEOVERRIDES = # (empty)
.OBJDIR = <curdir>
.PATH = . <curdir>
.TARGETS = all
.newline =
# (ends with space)
MACHINE = <details omitted>
MACHINE_ARCH = <details omitted>
MAKE = <details omitted>

View File

@ -50,8 +50,8 @@ all : made-target error-target aborted-target
#*** Global Variables:
.ALLTARGETS = made-target error-target aborted-target aborted-target-dependency all .END
.CURDIR = <curdir>
.INCLUDES =
.LIBS =
.INCLUDES = # (empty)
.LIBS = # (empty)
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
@ -63,12 +63,12 @@ all : made-target error-target aborted-target
.MAKE.PPID = <details omitted>
.MAKE.UID = <details omitted>
.MAKEFLAGS = -r -k -d g3
.MAKEOVERRIDES =
.MAKEOVERRIDES = # (empty)
.OBJDIR = <curdir>
.PATH = . <curdir>
.TARGETS = all
.newline =
# (ends with space)
MACHINE = <details omitted>
MACHINE_ARCH = <details omitted>
MAKE = <details omitted>

View File

@ -1,4 +1,4 @@
# $NetBSD: opt-debug-parse.mk,v 1.6 2022/01/08 23:52:26 rillig Exp $
# $NetBSD: opt-debug-parse.mk,v 1.7 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the -dp command line option, which adds debug logging about
# makefile parsing.
@ -20,7 +20,7 @@
.info trace with multi-line .for loop head
.endfor
# Before parse.c 1.461 from 2022-01-08, the debug log said it returned to
# Before parse.c 1.641 from 2022-01-08, the debug log said it returned to
# the line of the '.include' instead of the line following it.
.include "/dev/null"

View File

@ -1,5 +1,5 @@
Global: ASSIGNED = value
Global: SUBST =
Global: SUBST = # (empty)
Global: SUBST = value
Var_Parse: y(ASSIGNED) (eval)
Global: .MAKEFLAGS = -r -k -d v -d

View File

@ -1,5 +1,5 @@
make: "opt-env.mk" line 9: Malformed conditional (${FROM_ENV} != value-from-env)
make: "opt-env.mk" line 16: value-from-mk
make: "opt-env.mk" line 13: Malformed conditional (${FROM_ENV} != value-from-env)
make: "opt-env.mk" line 20: value-from-mk
make: stopped in unit-tests
exit status 1

View File

@ -1,6 +1,10 @@
# $NetBSD: opt-env.mk,v 1.3 2022/01/23 16:09:38 rillig Exp $
# $NetBSD: opt-env.mk,v 1.4 2022/03/26 13:32:31 rillig Exp $
#
# Tests for the -e command line option.
# Tests for the -e command line option, which looks up environment variables
# before those from the global scope. It has no influence on variables from
# the command line though.
#
# This option is required by POSIX.
# The variable FROM_ENV is defined in ./Makefile.

View File

@ -1,4 +1,4 @@
# $NetBSD: opt-file.mk,v 1.14 2021/12/09 20:47:33 rillig Exp $
# $NetBSD: opt-file.mk,v 1.15 2022/03/26 13:32:31 rillig Exp $
#
# Tests for the -f command line option, which adds a makefile to the list of
# files that are parsed.
@ -15,7 +15,7 @@ all: file-containing-null-byte
# possible.
#
# In the unlikely case where a file ends in a backslash instead of a newline,
# that backslash is trimmed. See ParseGetLine.
# that backslash is trimmed. See ReadLowLevelLine.
#
# make-2014.01.01.00.00.00 invoked undefined behavior, reading text from
# outside of the file buffer.
@ -52,7 +52,7 @@ file-ending-in-backslash-mmap: .PHONY
# Since parse.c 1.511 from 2020-12-22, an assertion in ParseGetLine failed
# for lines that contained trailing whitespace. Worked around in parse.c
# 1.513, properly fixed in parse.c 1.514.
# 1.513, properly fixed in parse.c 1.514 from 2020-12-22.
line-with-trailing-whitespace: .PHONY
@printf '%s' 'VAR=$@ ' > opt-file-trailing-whitespace
@${MAKE} -r -f opt-file-trailing-whitespace -V VAR

View File

@ -0,0 +1,32 @@
direct compat
false
*** Error code 1 (continuing)
Stop.
make: stopped in unit-tests
exited 1
direct jobs
false
*** [direct] Error code 1
make: stopped in unit-tests
exited 1
indirect compat
false
*** Error code 1 (continuing)
`indirect' not remade because of errors.
Stop.
make: stopped in unit-tests
exited 1
indirect jobs
false
*** [direct] Error code 1
make: stopped in unit-tests
exited 1
exit status 0

View File

@ -0,0 +1,90 @@
# $NetBSD: opt-keep-going-indirect.mk,v 1.2 2022/02/12 20:05:36 rillig Exp $
#
# Tests for the -k command line option, which stops building a target as soon
# as an error is detected, but continues building the other, independent
# targets, as far as possible.
#
# History:
# In 1993, the exit status for the option '-k' was always 0, even if a
# direct or an indirect target failed.
#
# Since 2000.12.30.02.05.21, the word '(continuing)' is missing in jobs
# mode, both for direct as well as indirect targets.
#
# Since 2001.10.16.18.50.12, the exit status for a direct failure in
# compat mode is the correct 1, while jobs mode and indirect failures
# still return the wrong exit status 0. The number of empty lines
# between the various error messages differs between the modes, for no
# reason.
#
# At 2006.11.17.22.07.39, the exit status for direct failures in both
# modes and for indirect failures in jobs mode was fixed to the correct
# 1. The exit status for indirect failures in compat mode is still the
# wrong 0. On the downside, a failed indirect target in jobs mode is no
# longer listed as "not remade because of errors".
#
# At 2016.08.26.23.28.39, the additional empty line for a direct failure
# in compat mode was removed, making it consistent with a direct failure
# in jobs mode. This left only one inconsistency, in that indirect
# failures in jobs mode (by far the most common when building large
# projects) did not produce any empty line.
#
# Since 2020.12.07.00.53.30, the exit status is consistently 1 for
# failures in all 4 modes.
#
# Bugs:
# The output in case of a failure needlessly differs between compat and
# jobs mode. As of 2022-02-12, compat mode outputs '(continuing)' while
# jobs mode doesn't. In compat mode, the output does not mention which
# target failed.
#
# See also:
# https://gnats.netbsd.org/49720
.PHONY: all direct indirect
# The 'set +e' was necessary in 2003, when the shell was run with '-e' by
# default.
# The 'env -i' prevents that the environment variable MAKEFLAGS is passed down
# to the child processes.
all:
@echo 'direct compat'
@set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k direct; echo "exited $$?"
@echo
@echo 'direct jobs'
@set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k direct -j1; echo "exited $$?"
@echo
@echo 'indirect compat'
@set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k indirect; echo "exited $$?"
@echo
@echo 'indirect jobs'
@set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k indirect -j1; echo "exited $$?"
@echo
indirect: direct
direct:
false
# TODO: Mention the target that failed, maybe even the chain of targets.
# expect: direct compat
# expect: *** Error code 1 (continuing)
# expect: exited 1
# TODO: Add '(continuing)'.
# expect: direct jobs
# expect: *** [direct] Error code 1
# expect: exited 1
# TODO: Mention the target that failed, maybe even the chain of targets.
# expect: indirect compat
# expect: *** Error code 1 (continuing)
# expect: exited 1
# TODO: Add '(continuing)'.
# TODO: Add 'not remade because of errors'.
# expect: indirect jobs
# expect: *** [direct] Error code 1
# expect: exited 1

View File

@ -1102,7 +1102,6 @@ opt-_j____-tgt-__s-cmd-__s
running
opt-_j____-tgt-__s-cmd-_i_
echo running; false
running
*** [opt-_j____-tgt-__s-cmd-_i_] Error code 1 (ignored)
@ -1117,7 +1116,6 @@ opt-_j____-tgt-__s-cmd-a_s
running
opt-_j____-tgt-__s-cmd-ai_
echo running; false
running
*** [opt-_j____-tgt-__s-cmd-ai_] Error code 1 (ignored)
@ -1170,7 +1168,6 @@ running
*** [opt-_j____-tgt-_is-cmd-__s] Error code 1 (ignored)
opt-_j____-tgt-_is-cmd-_i_
echo running; false
running
*** [opt-_j____-tgt-_is-cmd-_i_] Error code 1 (ignored)
@ -1187,7 +1184,6 @@ running
*** [opt-_j____-tgt-_is-cmd-a_s] Error code 1 (ignored)
opt-_j____-tgt-_is-cmd-ai_
echo running; false
running
*** [opt-_j____-tgt-_is-cmd-ai_] Error code 1 (ignored)
@ -1234,7 +1230,6 @@ opt-_j____-tgt-a_s-cmd-__s
running
opt-_j____-tgt-a_s-cmd-_i_
echo running; false
running
*** [opt-_j____-tgt-a_s-cmd-_i_] Error code 1 (ignored)
@ -1249,7 +1244,6 @@ opt-_j____-tgt-a_s-cmd-a_s
running
opt-_j____-tgt-a_s-cmd-ai_
echo running; false
running
*** [opt-_j____-tgt-a_s-cmd-ai_] Error code 1 (ignored)
@ -1302,7 +1296,6 @@ running
*** [opt-_j____-tgt-ais-cmd-__s] Error code 1 (ignored)
opt-_j____-tgt-ais-cmd-_i_
echo running; false
running
*** [opt-_j____-tgt-ais-cmd-_i_] Error code 1 (ignored)
@ -1319,7 +1312,6 @@ running
*** [opt-_j____-tgt-ais-cmd-a_s] Error code 1 (ignored)
opt-_j____-tgt-ais-cmd-ai_
echo running; false
running
*** [opt-_j____-tgt-ais-cmd-ai_] Error code 1 (ignored)
@ -1496,7 +1488,6 @@ opt-_j_n__-tgt-a_s-cmd-__s
running
opt-_j_n__-tgt-a_s-cmd-_i_
echo running; false
running
opt-_j_n__-tgt-a_s-cmd-_is
@ -1509,7 +1500,6 @@ opt-_j_n__-tgt-a_s-cmd-a_s
running
opt-_j_n__-tgt-a_s-cmd-ai_
echo running; false
running
opt-_j_n__-tgt-a_s-cmd-ais
@ -1550,7 +1540,6 @@ opt-_j_n__-tgt-ais-cmd-__s
running
opt-_j_n__-tgt-ais-cmd-_i_
echo running; false
running
opt-_j_n__-tgt-ais-cmd-_is
@ -1563,7 +1552,6 @@ opt-_j_n__-tgt-ais-cmd-a_s
running
opt-_j_n__-tgt-ais-cmd-ai_
echo running; false
running
opt-_j_n__-tgt-ais-cmd-ais
@ -1612,12 +1600,10 @@ opt-_jl___-tgt-__s-cmd-__s
running
opt-_jl___-tgt-__s-cmd-_i_
echo running; false
running
*** [opt-_jl___-tgt-__s-cmd-_i_] Error code 1 (ignored)
opt-_jl___-tgt-__s-cmd-_is
echo running; false
running
*** [opt-_jl___-tgt-__s-cmd-_is] Error code 1 (ignored)
@ -1628,12 +1614,10 @@ opt-_jl___-tgt-__s-cmd-a_s
running
opt-_jl___-tgt-__s-cmd-ai_
echo running; false
running
*** [opt-_jl___-tgt-__s-cmd-ai_] Error code 1 (ignored)
opt-_jl___-tgt-__s-cmd-ais
echo running; false
running
*** [opt-_jl___-tgt-__s-cmd-ais] Error code 1 (ignored)
@ -1686,12 +1670,10 @@ running
*** [opt-_jl___-tgt-_is-cmd-__s] Error code 1 (ignored)
opt-_jl___-tgt-_is-cmd-_i_
echo running; false
running
*** [opt-_jl___-tgt-_is-cmd-_i_] Error code 1 (ignored)
opt-_jl___-tgt-_is-cmd-_is
echo running; false
running
*** [opt-_jl___-tgt-_is-cmd-_is] Error code 1 (ignored)
@ -1704,12 +1686,10 @@ running
*** [opt-_jl___-tgt-_is-cmd-a_s] Error code 1 (ignored)
opt-_jl___-tgt-_is-cmd-ai_
echo running; false
running
*** [opt-_jl___-tgt-_is-cmd-ai_] Error code 1 (ignored)
opt-_jl___-tgt-_is-cmd-ais
echo running; false
running
*** [opt-_jl___-tgt-_is-cmd-ais] Error code 1 (ignored)
@ -1756,12 +1736,10 @@ opt-_jl___-tgt-a_s-cmd-__s
running
opt-_jl___-tgt-a_s-cmd-_i_
echo running; false
running
*** [opt-_jl___-tgt-a_s-cmd-_i_] Error code 1 (ignored)
opt-_jl___-tgt-a_s-cmd-_is
echo running; false
running
*** [opt-_jl___-tgt-a_s-cmd-_is] Error code 1 (ignored)
@ -1772,12 +1750,10 @@ opt-_jl___-tgt-a_s-cmd-a_s
running
opt-_jl___-tgt-a_s-cmd-ai_
echo running; false
running
*** [opt-_jl___-tgt-a_s-cmd-ai_] Error code 1 (ignored)
opt-_jl___-tgt-a_s-cmd-ais
echo running; false
running
*** [opt-_jl___-tgt-a_s-cmd-ais] Error code 1 (ignored)
@ -1830,12 +1806,10 @@ running
*** [opt-_jl___-tgt-ais-cmd-__s] Error code 1 (ignored)
opt-_jl___-tgt-ais-cmd-_i_
echo running; false
running
*** [opt-_jl___-tgt-ais-cmd-_i_] Error code 1 (ignored)
opt-_jl___-tgt-ais-cmd-_is
echo running; false
running
*** [opt-_jl___-tgt-ais-cmd-_is] Error code 1 (ignored)
@ -1848,12 +1822,10 @@ running
*** [opt-_jl___-tgt-ais-cmd-a_s] Error code 1 (ignored)
opt-_jl___-tgt-ais-cmd-ai_
echo running; false
running
*** [opt-_jl___-tgt-ais-cmd-ai_] Error code 1 (ignored)
opt-_jl___-tgt-ais-cmd-ais
echo running; false
running
*** [opt-_jl___-tgt-ais-cmd-ais] Error code 1 (ignored)
@ -2032,11 +2004,9 @@ opt-_jln__-tgt-a_s-cmd-__s
running
opt-_jln__-tgt-a_s-cmd-_i_
echo running; false
running
opt-_jln__-tgt-a_s-cmd-_is
echo running; false
running
opt-_jln__-tgt-a_s-cmd-a__
@ -2046,11 +2016,9 @@ opt-_jln__-tgt-a_s-cmd-a_s
running
opt-_jln__-tgt-a_s-cmd-ai_
echo running; false
running
opt-_jln__-tgt-a_s-cmd-ais
echo running; false
running
opt-_jln__-tgt-ai_-cmd-___
@ -2092,11 +2060,9 @@ opt-_jln__-tgt-ais-cmd-__s
running
opt-_jln__-tgt-ais-cmd-_i_
echo running; false
running
opt-_jln__-tgt-ais-cmd-_is
echo running; false
running
opt-_jln__-tgt-ais-cmd-a__
@ -2106,11 +2072,9 @@ opt-_jln__-tgt-ais-cmd-a_s
running
opt-_jln__-tgt-ais-cmd-ai_
echo running; false
running
opt-_jln__-tgt-ais-cmd-ais
echo running; false
running
opt-i_____-tgt-___-cmd-___
@ -3278,7 +3242,6 @@ running
*** [opt-ij____-tgt-__s-cmd-__s] Error code 1 (ignored)
opt-ij____-tgt-__s-cmd-_i_
echo running; false
running
*** [opt-ij____-tgt-__s-cmd-_i_] Error code 1 (ignored)
@ -3295,7 +3258,6 @@ running
*** [opt-ij____-tgt-__s-cmd-a_s] Error code 1 (ignored)
opt-ij____-tgt-__s-cmd-ai_
echo running; false
running
*** [opt-ij____-tgt-__s-cmd-ai_] Error code 1 (ignored)
@ -3348,7 +3310,6 @@ running
*** [opt-ij____-tgt-_is-cmd-__s] Error code 1 (ignored)
opt-ij____-tgt-_is-cmd-_i_
echo running; false
running
*** [opt-ij____-tgt-_is-cmd-_i_] Error code 1 (ignored)
@ -3365,7 +3326,6 @@ running
*** [opt-ij____-tgt-_is-cmd-a_s] Error code 1 (ignored)
opt-ij____-tgt-_is-cmd-ai_
echo running; false
running
*** [opt-ij____-tgt-_is-cmd-ai_] Error code 1 (ignored)
@ -3418,7 +3378,6 @@ running
*** [opt-ij____-tgt-a_s-cmd-__s] Error code 1 (ignored)
opt-ij____-tgt-a_s-cmd-_i_
echo running; false
running
*** [opt-ij____-tgt-a_s-cmd-_i_] Error code 1 (ignored)
@ -3435,7 +3394,6 @@ running
*** [opt-ij____-tgt-a_s-cmd-a_s] Error code 1 (ignored)
opt-ij____-tgt-a_s-cmd-ai_
echo running; false
running
*** [opt-ij____-tgt-a_s-cmd-ai_] Error code 1 (ignored)
@ -3488,7 +3446,6 @@ running
*** [opt-ij____-tgt-ais-cmd-__s] Error code 1 (ignored)
opt-ij____-tgt-ais-cmd-_i_
echo running; false
running
*** [opt-ij____-tgt-ais-cmd-_i_] Error code 1 (ignored)
@ -3505,7 +3462,6 @@ running
*** [opt-ij____-tgt-ais-cmd-a_s] Error code 1 (ignored)
opt-ij____-tgt-ais-cmd-ai_
echo running; false
running
*** [opt-ij____-tgt-ais-cmd-ai_] Error code 1 (ignored)
@ -3686,7 +3642,6 @@ opt-ij_n__-tgt-a_s-cmd-__s
running
opt-ij_n__-tgt-a_s-cmd-_i_
echo running; false
running
opt-ij_n__-tgt-a_s-cmd-_is
@ -3699,7 +3654,6 @@ opt-ij_n__-tgt-a_s-cmd-a_s
running
opt-ij_n__-tgt-a_s-cmd-ai_
echo running; false
running
opt-ij_n__-tgt-a_s-cmd-ais
@ -3740,7 +3694,6 @@ opt-ij_n__-tgt-ais-cmd-__s
running
opt-ij_n__-tgt-ais-cmd-_i_
echo running; false
running
opt-ij_n__-tgt-ais-cmd-_is
@ -3753,7 +3706,6 @@ opt-ij_n__-tgt-ais-cmd-a_s
running
opt-ij_n__-tgt-ais-cmd-ai_
echo running; false
running
opt-ij_n__-tgt-ais-cmd-ais
@ -3808,12 +3760,10 @@ running
*** [opt-ijl___-tgt-__s-cmd-__s] Error code 1 (ignored)
opt-ijl___-tgt-__s-cmd-_i_
echo running; false
running
*** [opt-ijl___-tgt-__s-cmd-_i_] Error code 1 (ignored)
opt-ijl___-tgt-__s-cmd-_is
echo running; false
running
*** [opt-ijl___-tgt-__s-cmd-_is] Error code 1 (ignored)
@ -3826,12 +3776,10 @@ running
*** [opt-ijl___-tgt-__s-cmd-a_s] Error code 1 (ignored)
opt-ijl___-tgt-__s-cmd-ai_
echo running; false
running
*** [opt-ijl___-tgt-__s-cmd-ai_] Error code 1 (ignored)
opt-ijl___-tgt-__s-cmd-ais
echo running; false
running
*** [opt-ijl___-tgt-__s-cmd-ais] Error code 1 (ignored)
@ -3884,12 +3832,10 @@ running
*** [opt-ijl___-tgt-_is-cmd-__s] Error code 1 (ignored)
opt-ijl___-tgt-_is-cmd-_i_
echo running; false
running
*** [opt-ijl___-tgt-_is-cmd-_i_] Error code 1 (ignored)
opt-ijl___-tgt-_is-cmd-_is
echo running; false
running
*** [opt-ijl___-tgt-_is-cmd-_is] Error code 1 (ignored)
@ -3902,12 +3848,10 @@ running
*** [opt-ijl___-tgt-_is-cmd-a_s] Error code 1 (ignored)
opt-ijl___-tgt-_is-cmd-ai_
echo running; false
running
*** [opt-ijl___-tgt-_is-cmd-ai_] Error code 1 (ignored)
opt-ijl___-tgt-_is-cmd-ais
echo running; false
running
*** [opt-ijl___-tgt-_is-cmd-ais] Error code 1 (ignored)
@ -3960,12 +3904,10 @@ running
*** [opt-ijl___-tgt-a_s-cmd-__s] Error code 1 (ignored)
opt-ijl___-tgt-a_s-cmd-_i_
echo running; false
running
*** [opt-ijl___-tgt-a_s-cmd-_i_] Error code 1 (ignored)
opt-ijl___-tgt-a_s-cmd-_is
echo running; false
running
*** [opt-ijl___-tgt-a_s-cmd-_is] Error code 1 (ignored)
@ -3978,12 +3920,10 @@ running
*** [opt-ijl___-tgt-a_s-cmd-a_s] Error code 1 (ignored)
opt-ijl___-tgt-a_s-cmd-ai_
echo running; false
running
*** [opt-ijl___-tgt-a_s-cmd-ai_] Error code 1 (ignored)
opt-ijl___-tgt-a_s-cmd-ais
echo running; false
running
*** [opt-ijl___-tgt-a_s-cmd-ais] Error code 1 (ignored)
@ -4036,12 +3976,10 @@ running
*** [opt-ijl___-tgt-ais-cmd-__s] Error code 1 (ignored)
opt-ijl___-tgt-ais-cmd-_i_
echo running; false
running
*** [opt-ijl___-tgt-ais-cmd-_i_] Error code 1 (ignored)
opt-ijl___-tgt-ais-cmd-_is
echo running; false
running
*** [opt-ijl___-tgt-ais-cmd-_is] Error code 1 (ignored)
@ -4054,12 +3992,10 @@ running
*** [opt-ijl___-tgt-ais-cmd-a_s] Error code 1 (ignored)
opt-ijl___-tgt-ais-cmd-ai_
echo running; false
running
*** [opt-ijl___-tgt-ais-cmd-ai_] Error code 1 (ignored)
opt-ijl___-tgt-ais-cmd-ais
echo running; false
running
*** [opt-ijl___-tgt-ais-cmd-ais] Error code 1 (ignored)
@ -4242,11 +4178,9 @@ opt-ijln__-tgt-a_s-cmd-__s
running
opt-ijln__-tgt-a_s-cmd-_i_
echo running; false
running
opt-ijln__-tgt-a_s-cmd-_is
echo running; false
running
opt-ijln__-tgt-a_s-cmd-a__
@ -4256,11 +4190,9 @@ opt-ijln__-tgt-a_s-cmd-a_s
running
opt-ijln__-tgt-a_s-cmd-ai_
echo running; false
running
opt-ijln__-tgt-a_s-cmd-ais
echo running; false
running
opt-ijln__-tgt-ai_-cmd-___
@ -4302,11 +4234,9 @@ opt-ijln__-tgt-ais-cmd-__s
running
opt-ijln__-tgt-ais-cmd-_i_
echo running; false
running
opt-ijln__-tgt-ais-cmd-_is
echo running; false
running
opt-ijln__-tgt-ais-cmd-a__
@ -4316,10 +4246,8 @@ opt-ijln__-tgt-ais-cmd-a_s
running
opt-ijln__-tgt-ais-cmd-ai_
echo running; false
running
opt-ijln__-tgt-ais-cmd-ais
echo running; false
running
exit status 0

View File

@ -81,8 +81,8 @@ ParseDependency(.MAKEFLAGS: -d0 -dg1)
#*** Global Variables:
.ALLTARGETS = .1.2 .1.3 .1.4 next-main suff-main-several.1 suff-main-several.{2,3,4}
.CURDIR = <curdir>
.INCLUDES =
.LIBS =
.INCLUDES = # (empty)
.LIBS = # (empty)
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
@ -94,12 +94,12 @@ ParseDependency(.MAKEFLAGS: -d0 -dg1)
.MAKE.PPID = <details omitted>
.MAKE.UID = <details omitted>
.MAKEFLAGS = -r -k -d mps -d 0 -d g1
.MAKEOVERRIDES =
.MAKEOVERRIDES = # (empty)
.OBJDIR = <curdir>
.PATH = . <curdir>
.TARGETS =
.TARGETS = # (empty)
.newline =
# (ends with space)
MACHINE = <details omitted>
MACHINE_ARCH = <details omitted>
MAKE = <details omitted>

View File

@ -7,8 +7,8 @@
#*** Global Variables:
.ALLTARGETS = all
.CURDIR = <curdir>
.INCLUDES =
.LIBS =
.INCLUDES = # (empty)
.LIBS = # (empty)
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
@ -20,12 +20,12 @@
.MAKE.PPID = <details omitted>
.MAKE.UID = <details omitted>
.MAKEFLAGS = -r -k -d g1
.MAKEOVERRIDES =
.MAKEOVERRIDES = # (empty)
.OBJDIR = <curdir>
.PATH = . <curdir>
.TARGETS =
.TARGETS = # (empty)
.newline =
# (ends with space)
MACHINE = <details omitted>
MACHINE_ARCH = <details omitted>
MAKE = <details omitted>

View File

@ -1,28 +1,28 @@
# $NetBSD: suff-use.mk,v 1.1 2022/02/07 22:43:50 rillig Exp $
# $NetBSD: suff-use.mk,v 1.2 2022/02/09 21:09:24 rillig Exp $
#
# This test combines a .USE node with suffix rules, trying to add an
# additional command before and after successful compilation of a .c file.
#
# History:
# bin/make-2001.11.12.21.58.18-plain
# make-2001.11.12.21.58.18
# | : 'Making demo.c out of nothing'
# | make: don't know how to make demo.o. Stop
# |
# | make: stopped in /home/rillig/proj/make-archive
# | make: stopped in <curdir>
# | exit status 2
# bin/make-2007.10.11.21.19.28-plain
# make-2007.10.11.21.19.28
#
# bin/make-2014.08.23.15.05.40-plain
# make-2014.08.23.15.05.40
# | : 'Making demo.c out of nothing'
# | : 'Compiling demo.c to demo.o'
# | exit status 0
# bin/make-2014.09.05.06.57.20-plain
# make-2014.09.05.06.57.20
#
# bin/make-2014.09.07.20.55.34-plain
# make-2014.09.07.20.55.34
# | : 'Making demo.c out of nothing'
# | make: don't know how to make demo.o. Stop
# |
# | make: stopped in /home/rillig/proj/make-archive
# | make: stopped in <curdir>
# | exit status 2
# ...
#

View File

@ -1,8 +1,8 @@
# $NetBSD: var-op-sunsh.mk,v 1.9 2022/01/16 09:38:04 rillig Exp $
# $NetBSD: var-op-sunsh.mk,v 1.10 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the :sh= variable assignment operator, which runs its right-hand
# side through the shell. It is a seldom-used alternative to the !=
# assignment operator, adopted from SUN make.
# assignment operator, adopted from Sun make.
.MAKEFLAGS: -dL # Enable sane error messages

View File

@ -3,7 +3,7 @@ Global: .ALLTARGETS = one two
Var_Parse: ${.MAKE.TARGET_LOCAL_VARIABLES} (eval)
Var_SetExpand: variable name "" expands to empty string, with value "three" - ignored
Var_SetExpand: variable name "" expands to empty string, with value "three" - ignored
Global: one two =
Global: one two = # (empty)
Global: one two = three
Global: .MAKEFLAGS = -r -k -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0

View File

@ -1,4 +1,4 @@
# $NetBSD: var-scope-local.mk,v 1.4 2022/02/05 10:41:15 rillig Exp $
# $NetBSD: var-scope-local.mk,v 1.5 2022/02/09 21:09:24 rillig Exp $
#
# Tests for target-local variables, such as ${.TARGET} or $@. These variables
# are relatively short-lived as they are created just before making the
@ -18,7 +18,7 @@
# these expressions to expand right in time when the target-local variables
# are actually set.
#
# Conditions like the ones below are evaluated in the scope of the command
# Conditions from .if directives are evaluated in the scope of the command
# line, which means that variables from the command line, from the global
# scope and from the environment are resolved, in this order (but see the
# command line option '-e'). In that phase, expressions involving
@ -33,15 +33,16 @@
# expressions like ${@}, ${.TARGET} ${VAR:Mpattern} (see Var_Parse,
# ParseVarname).
#
# In the following condition, make does not expand '$@' but instead changes it
# to the long-format alias '$(.TARGET)'; note that the alias is not written
# with braces, as would be common in BSD makefiles, but with parentheses.
# This alternative form behaves equivalently though.
# In the following condition, make expands '$@' to the long-format alias
# '$(.TARGET)'; note that the alias is not written with braces, as would be
# common in BSD makefiles, but with parentheses. This alternative spelling
# behaves the same though.
.if $@ != "\$\(.TARGET)"
. error
.endif
# In the long form of writing a target-local variable, the expression is
# preserved exactly as written, no matter whether with '{' or '('.
# In the long form of writing a target-local variable, the text of the
# expression is preserved exactly as written, no matter whether it is written
# with '{' or '('.
.if ${@} != "\$\{@}"
. error
.endif
@ -60,7 +61,7 @@
# In the following examples, the expressions are based on target-local
# variables but use the modifier ':L', which turns an undefined expression
# into a defined one. At the end of evaluating the expression, the state of
# the expression is not 'undefined' anymore, and the value of the expression
# the expression is not 'undefined' anymore. The value of the expression
# is the name of the variable, since that's what the modifier ':L' does.
.if ${@:L} != "@"
. error
@ -164,10 +165,11 @@ var-scope-local-append.o: VAR+= local
var-scope-local-append.o: VAR += to ${.TARGET}
# To access the value of a global variable, use a variable expression. This
# expression is expanded before parsing the whole dependency line. Since the
# expansion happens to the right of both the dependency operator ':' and also
# to the right of the assignment operator '=', the expanded text does not
# affect the dependency or the variable assignment structurally. The
# effective variable assignment, after expanding the whole line first, is thus
# expansion happens to the right of the dependency operator ':', the expanded
# text does not influence parsing of the dependency line. Since the expansion
# happens to the right of the assignment operator '=', the expanded text does
# not influence the parsing of the variable assignment. The effective
# variable assignment, after expanding the whole line first, is thus
# 'VAR= global+local'.
# expect: : Making var-scope-local-append-global.o with VAR="global+local".
var-scope-local-append-global.o: VAR= ${VAR}+local
@ -182,17 +184,22 @@ var-scope-local-default.o: VAR ?= second
# Using the variable assignment operator ':=' provides another way of
# accessing a global variable and extending it with local modifications. The
# '$' has to be written as '$$' though to survive the expansion of the
# dependency line as a whole.
# dependency line as a whole. After that, the parser sees the variable
# assignment as 'VAR := ${VAR}+local' and searches for the variable 'VAR' in
# the usual scopes, picking up the variable from the global scope.
# expect: : Making var-scope-local-subst.o with VAR="global+local".
var-scope-local-subst.o: VAR := $${VAR}+local
# The variable assignment operator '!=' assigns the output of the shell
# command, as everywhere else.
# command, as everywhere else. The shell command is run when the dependency
# line is parsed.
var-scope-local-shell.o: VAR != echo output
# While VAR=use will be set for a .USE node, it will never be seen since only
# the ultimate target's context is searched; the variable assignments from the
# .USE target are not copied to the ultimate target's.
# expect: : var-scope-local-use.o uses .USE VAR="global"
a_use: .USE VAR=use
: ${.TARGET} uses .USE VAR="${VAR}"

View File

@ -1,10 +1,10 @@
Global:delete FROM_CMDLINE (not found)
Command: FROM_CMDLINE =
Global: delete FROM_CMDLINE (not found)
Command: FROM_CMDLINE = # (empty)
Global: .MAKEOVERRIDES = FROM_CMDLINE
Global: VAR = added
Global: VAR = overwritten
Global:delete VAR
Global:delete VAR (not found)
Global: delete VAR
Global: delete VAR (not found)
Var_SetExpand: variable name "${:U}" expands to empty string, with value "empty name" - ignored
Var_AppendExpand: variable name "${:U}" expands to empty string, with value "empty name" - ignored
Global: FROM_CMDLINE = overwritten ignored!
@ -49,7 +49,7 @@ Evaluating modifier ${:M...} on value "value" (eval-defined, defined)
Pattern for ':M' is "valu[e]"
ModifyWords: split "value" into 1 word
Result of ${:Mvalu[e]} is "value" (eval-defined, defined)
Global:delete VAR
Global: delete VAR
Var_Parse: ${:Uvariable:unknown} (eval-defined)
Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
Result of ${:Uvariable} is "variable" (eval-defined, defined)
@ -59,7 +59,7 @@ Result of ${:unknown} is error (eval-defined, defined)
make: "vardebug.mk" line 44: Malformed conditional (${:Uvariable:unknown})
Var_Parse: ${UNDEFINED} (eval-defined)
make: "vardebug.mk" line 53: Malformed conditional (${UNDEFINED})
Global:delete .SHELL (not found)
Global: delete .SHELL (not found)
Command: .SHELL = </path/to/shell>
Command: .SHELL = overwritten ignored (read-only)
Global: .MAKEFLAGS = -r -k -d v -d

View File

@ -1,12 +1,12 @@
make: "varmod-assign-shell.mk" line 27: warning: "echo output; false" returned non-zero status
Global: _ =
Global: _ = # (empty)
Var_Parse: ${ASSIGNED::!=echo output; ${:Ufalse}} (eval-keep-dollar-and-undefined)
Evaluating modifier ${ASSIGNED::...} on value "previous" (eval-keep-dollar-and-undefined, regular)
Modifier part: "echo output; false"
Capturing the output of command "echo output; false"
make: "echo output; false" returned non-zero status
Result of ${ASSIGNED::!=echo output; ${:Ufalse}} is "" (eval-keep-dollar-and-undefined, regular)
Global: _ =
Global: _ = # (empty)
Global: .MAKEFLAGS = -r -k -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0
DIRECT=output

View File

@ -1,4 +1,4 @@
# $NetBSD: varmod-assign.mk,v 1.14 2021/12/05 10:13:44 rillig Exp $
# $NetBSD: varmod-assign.mk,v 1.15 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the obscure ::= variable modifiers, which perform variable
# assignments during evaluation, just like the = operator in C.
@ -34,8 +34,8 @@ all: mod-assign-shell-error
. error
.endif
# The assignments happen in the global scope and thus are preserved even after
# the shell command has been run and the condition has been evaluated.
# The assignments were performed as part of .if conditions and thus happened
# in the command line scope.
.if "${FIRST}, ${LAST}, ${APPENDED}, ${RAN}" != "1, 3, 1 2 3, <3>"
. error
.endif
@ -84,7 +84,8 @@ mod-assign-empty:
mod-assign-parse:
# The modifier for assignment operators starts with a ':'.
# An 'x' after that is an invalid modifier.
@echo ${ASSIGN::x} # 'x' is an unknown assignment operator
# expect: make: Unknown modifier ":x"
@echo ${ASSIGN::x}
# When parsing an assignment operator fails because the operator is
# incomplete, make falls back to the SysV modifier.

View File

@ -1,5 +1,5 @@
Global: 8_DOLLARS = $$$$$$$$
Global: VAR =
Global: VAR = # (empty)
Var_Parse: ${8_DOLLARS} (eval-keep-dollar-and-undefined)
Global: VAR = $$$$$$$$
Var_Parse: ${VAR:D${8_DOLLARS}} (eval-keep-dollar-and-undefined)
@ -15,7 +15,7 @@ ModifyWords: split "$$$$$$$$" into 1 word
Global: var = $$$$$$$$
Var_Parse: ${8_DOLLARS} (eval-keep-undefined)
ModifyWord_Loop: in "$$$$$$$$", replace "var" with "${8_DOLLARS}" to "$$$$"
Global:delete var
Global: delete var
Result of ${VAR:@var@${8_DOLLARS}@} is "$$$$" (eval-keep-dollar-and-undefined, regular)
Global: VAR = $$$$
Global: .MAKEFLAGS = -r -k -d v -d

View File

@ -7,14 +7,14 @@ make: Bad conditional expression '1 == == 2' in '1 == == 2?yes:no'
make: "varmod-ifelse.mk" line 66: Malformed conditional (${1 == == 2:?yes:no} != "")
CondParser_Eval: "${1 == == 2:?yes:no}" != ""
CondParser_Eval: 1 == == 2
lhs = 1.000000, rhs = 0.000000, op = ==
Comparing 1.000000 == 0.000000
make: Bad conditional expression '1 == == 2' in '1 == == 2?yes:no'
lhs = "", rhs = "", op = !=
Comparing "" != ""
make: "varmod-ifelse.mk" line 92: warning: Oops, the parse error should have been propagated.
CondParser_Eval: ${ ${:U\$}{VAR} == value :?ok:bad} != "ok"
CondParser_Eval: ${VAR} == value
lhs = "value", rhs = "value", op = ==
lhs = "ok", rhs = "ok", op = !=
Comparing "value" == "value"
Comparing "ok" != "ok"
make: "varmod-ifelse.mk" line 153: no.
make: "varmod-ifelse.mk" line 154: String comparison operator must be either == or !=
make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no'

View File

@ -11,7 +11,7 @@ make: "varmod-indirect.mk" line 156: Unknown modifier "Z"
make: "varmod-indirect.mk" line 157: before
make: "varmod-indirect.mk" line 157: after
Parsing line 166: _:= before ${UNDEF} after
Global: _ =
Global: _ = # (empty)
Var_Parse: ${UNDEF} after (eval-keep-dollar-and-undefined)
Global: _ = before ${UNDEF} after
Parsing line 169: _:= before ${UNDEF:${:US,a,a,}} after

View File

@ -1,9 +1,9 @@
Parsing line 78: USE_8_DOLLARS= ${:U1:@var@${8_DOLLARS}@} ${8_DOLLARS} $$$$$$$$
CondParser_Eval: ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$"
lhs = "$$$$ $$$$ $$$$", rhs = "$$$$ $$$$ $$$$", op = !=
Comparing "$$$$ $$$$ $$$$" != "$$$$ $$$$ $$$$"
Parsing line 83: SUBST_CONTAINING_LOOP:= ${USE_8_DOLLARS}
CondParser_Eval: ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$"
lhs = "$$ $$$$ $$$$", rhs = "$$ $$$$ $$$$", op = !=
Comparing "$$ $$$$ $$$$" != "$$ $$$$ $$$$"
Parsing line 108: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
:varname-overwriting-target: :x1y x2y x3y: ::

View File

@ -10,7 +10,7 @@ Evaluating modifier ${SPECIALS:M...} on value "\: : \\ * \*"
Pattern for ':M' is ":"
ModifyWords: split "\: : \\ * \*" into 5 words
Result of ${SPECIALS:M\:${:U}} is ":"
lhs = ":", rhs = ":", op = !=
Comparing ":" != ":"
Global: VALUES = : :: :\:
CondParser_Eval: ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:}
Var_Parse: ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:} (eval-defined)
@ -29,7 +29,7 @@ Result of ${:U\:} is ":" (eval-defined, defined)
Pattern for ':M' is ":\:"
ModifyWords: split ": :: :\:" into 3 words
Result of ${VALUES:M${:U\:}\:} is "::"
lhs = ":", rhs = "::", op = !=
Comparing ":" != "::"
make: "varmod-match-escape.mk" line 42: warning: XXX: Oops
Global: .MAKEFLAGS = -r -k -d cv -d
Global: .MAKEFLAGS = -r -k -d cv -d 0

View File

@ -1,12 +1,16 @@
CondParser_Eval: ${NUMBERS:M[A-Z]*} != "One Two Three Four"
lhs = "One Two Three Four", rhs = "One Two Three Four", op = !=
Comparing "One Two Three Four" != "One Two Three Four"
CondParser_Eval: ${NUMBERS:M[^A-Z]*} != "five six seven"
lhs = "five six seven", rhs = "five six seven", op = !=
Comparing "five six seven" != "five six seven"
CondParser_Eval: ${NUMBERS:M[^s]*[ex]} != "One Three five"
lhs = "One Three five", rhs = "One Three five", op = !=
Comparing "One Three five" != "One Three five"
CondParser_Eval: ${:U****************:M****************b}
CondParser_Eval: ${:Ua \$ sign:M*$$*} != "\$"
lhs = "$", rhs = "$", op = !=
Comparing "$" != "$"
CondParser_Eval: ${:Ua \$ sign any-asterisk:M*\$*} != "any-asterisk"
lhs = "any-asterisk", rhs = "any-asterisk", op = !=
exit status 0
Comparing "any-asterisk" != "any-asterisk"
make: "varmod-match.mk" line 146: Unknown modifier "]"
make: "varmod-match.mk" line 146: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: varmod-match.mk,v 1.6 2020/11/15 18:33:41 rillig Exp $
# $NetBSD: varmod-match.mk,v 1.8 2022/03/27 18:39:01 rillig Exp $
#
# Tests for the :M variable modifier, which filters words that match the
# given pattern.
@ -56,5 +56,131 @@ ${:U*}= asterisk
# TODO: ${VAR:M${UNBALANCED}}
# TODO: ${VAR:M${:U(((\}\}\}}}
all:
@:;
.MAKEFLAGS: -d0
# Special characters:
# * matches 0 or more arbitrary characters
# ? matches a single arbitrary character
# \ starts an escape sequence, only outside ranges
# [ starts a set for matching a single character
# ] ends a set for matching a single character
# - in a set, forms a range of characters
# ^ as the first character in a set, negates the set
# ( during parsing of the pattern, starts a nesting level
# ) during parsing of the pattern, ends a nesting level
# { during parsing of the pattern, starts a nesting level
# } during parsing of the pattern, ends a nesting level
# : during parsing of the pattern, finishes the pattern
# $ during parsing of the pattern, starts a nested expression
# # in a line except a shell command, starts a comment
#
# Pattern parts:
# * matches 0 or more arbitrary characters
# ? matches exactly 1 arbitrary character
# \x matches exactly the character 'x'
# [...] matches exactly 1 character from the set
# [^...] matches exactly 1 character outside the set
# [a-z] matches exactly 1 character from the range 'a' to 'z'
#
# [] matches never
.if ${ ab a[]b a[b a b :L:M[]} != ""
. error
.endif
# a[]b matches never
.if ${ ab a[]b a[b a b [ ] :L:Ma[]b} != ""
. error
.endif
# [^] matches exactly 1 arbitrary character
.if ${ ab a[]b a[b a b [ ] :L:M[^]} != "a b [ ]"
. error
.endif
# a[^]b matches 'a', then exactly 1 arbitrary character, then 'b'
.if ${ ab a[]b a[b a b :L:Ma[^]b} != "a[b"
. error
.endif
# [Nn0] matches exactly 1 character from the set 'N', 'n', '0'
.if ${ a b N n 0 Nn0 [ ] :L:M[Nn0]} != "N n 0"
. error
.endif
# [a-c] matches exactly 1 character from the range 'a' to 'c'
.if ${ A B C a b c d [a-c] [a] :L:M[a-c]} != "a b c"
. error
.endif
# [c-a] matches the same as [a-c]
.if ${ A B C a b c d [a-c] [a] :L:M[c-a]} != "a b c"
. error
.endif
# [^a-c67]
# matches a single character, except for 'a', 'b', 'c', '6' or
# '7'
.if ${ A B C a b c d 5 6 7 8 [a-c] [a] :L:M[^a-c67]} != "A B C d 5 8"
. error
.endif
# : terminates the pattern
.if ${ A * :L:M:} != ""
. error
.endif
# \: matches a colon
.if ${ ${:U\: \:\:} :L:M\:} != ":"
. error
.endif
# ${:U\:} matches a colon
.if ${ ${:U\:} ${:U\:\:} :L:M${:U\:}} != ":"
. error
.endif
# [:] matches never since the ':' starts the next modifier
# expect+2: Unknown modifier "]"
# expect+1: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
.if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":"
. error
.else
. error
.endif
# [\] matches exactly a backslash; no escaping takes place in
# character ranges
# Without the 'a' in the below expressions, the backslash would end a word and
# thus influence how the string is split into words.
.if ${ ${:U\\a} ${:U\\\\a} :L:M[\]a} != "\\a"
. error
.endif
#.MAKEFLAGS: -dcv
#
# Incomplete patterns:
# [ matches TODO
# [x matches TODO
# [^ matches TODO
# [- matches TODO
# [xy matches TODO
# [^x matches TODO
# [\ matches TODO
#
# [x- matches exactly 'x', doesn't match 'x-'
# [^x- matches TODO
# \ matches never
# The modifier ':tW' prevents splitting at whitespace. Even leading and
# trailing whitespace is preserved.
.if ${ plain string :L:tW:M*} != " plain string "
. error
.endif
# Without the modifier ':tW', the string is split into words. All whitespace
# around and between the words is normalized to a single space.
.if ${ plain string :L:M*} != "plain string"
. error
.endif

View File

@ -1,4 +1,4 @@
# $NetBSD: varmod-order-numeric.mk,v 1.6 2022/02/04 23:43:10 rillig Exp $
# $NetBSD: varmod-order-numeric.mk,v 1.7 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the variable modifiers ':On', which returns the words, sorted in
# ascending numeric order, and for ':Orn' and ':Onr', which additionally
@ -32,7 +32,7 @@ NUMBERS= 3 5 7 1 42 -42 5K -3m 1M 1k -2G
# Duplicate numbers are preserved in the output. In this case the
# equal-valued numbers are spelled the same, so they are indistinguishable in
# the output.
DUPLICATES= 3 1 2 2 1 1 # https://oeis.org/A034002
DUPLICATES= 3 1 2 2 1 1 # subsequence of https://oeis.org/A034002
.if ${DUPLICATES:On} != "1 1 1 2 2 3"
. error ${DUPLICATES:On}
.endif
@ -44,7 +44,7 @@ SAME_VALUE:= ${:U 79 80 0x0050 81 :On}
. error ${SAME_VALUE}
.endif
# Hexadecimal and octal numbers are supported as well.
# Hexadecimal and octal numbers can be sorted as well.
MIXED_BASE= 0 010 0x7 9
.if ${MIXED_BASE:On} != "0 0x7 010 9"
. error ${MIXED_BASE:On}

View File

@ -1,6 +1,6 @@
make: "echo word; false" returned non-zero status
make: "echo word; false" returned non-zero status
Global: _ =
Global: _ = # (empty)
Var_Parse: ${:!echo word; ${:Ufalse}!} (eval-keep-dollar-and-undefined)
Evaluating modifier ${:!...} on value "" (eval-keep-dollar-and-undefined, undefined)
Modifier part: "echo word; false"

View File

@ -1,5 +1,5 @@
make: "echo word; false" returned non-zero status
Global: _ =
Global: _ = # (empty)
Var_Parse: ${echo word; ${:Ufalse}:L:sh} (eval-keep-dollar-and-undefined)
Evaluating modifier ${echo word; false:L} on value "" (eval-keep-dollar-and-undefined, undefined)
Result of ${echo word; false:L} is "echo word; false" (eval-keep-dollar-and-undefined, defined)

View File

@ -1,4 +1,4 @@
# $NetBSD: varmod-to-separator.mk,v 1.10 2022/01/23 21:48:59 rillig Exp $
# $NetBSD: varmod-to-separator.mk,v 1.11 2022/02/09 21:09:24 rillig Exp $
#
# Tests for the :ts variable modifier, which joins the words of the variable
# using an arbitrary character as word separator.
@ -208,7 +208,7 @@ WORDS= one two three four five six
. error
.endif
# The word separator must be can only be a single character.
# The word separator can only be a single character.
# expect: make: Bad modifier ":ts\X" for variable "WORDS"
.if ${WORDS:ts\X}
. error

View File

@ -1,7 +1,7 @@
Parsing line 10: ORIG_SHELL:= ${.SHELL}
Global: ORIG_SHELL =
Global: ORIG_SHELL = # (empty)
Var_Parse: ${.SHELL} (eval-keep-dollar-and-undefined)
Global:delete .SHELL (not found)
Global: delete .SHELL (not found)
Command: .SHELL = (details omitted)
Global: ORIG_SHELL = (details omitted)
Parsing line 12: .SHELL= overwritten
@ -9,22 +9,22 @@ Global: .SHELL = overwritten
CondParser_Eval: ${.SHELL} != ${ORIG_SHELL}
Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined)
Var_Parse: ${ORIG_SHELL} (eval-defined)
lhs = "(details omitted)", rhs = "(details omitted)", op = !=
Comparing "(details omitted)" != "(details omitted)"
Parsing line 19: .MAKEFLAGS: .SHELL+=appended
ParseDependency(.MAKEFLAGS: .SHELL+=appended)
Ignoring append to .SHELL since it is read-only
CondParser_Eval: ${.SHELL} != ${ORIG_SHELL}
Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined)
Var_Parse: ${ORIG_SHELL} (eval-defined)
lhs = "(details omitted)", rhs = "(details omitted)", op = !=
Comparing "(details omitted)" != "(details omitted)"
Parsing line 27: .undef .SHELL
Global:delete .SHELL
Global: delete .SHELL
Parsing line 28: .SHELL= newly overwritten
Global: .SHELL = newly overwritten
CondParser_Eval: ${.SHELL} != ${ORIG_SHELL}
Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined)
Var_Parse: ${ORIG_SHELL} (eval-defined)
lhs = "(details omitted)", rhs = "(details omitted)", op = !=
Comparing "(details omitted)" != "(details omitted)"
Parsing line 33: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
Global: .MAKEFLAGS = -r -k -d cpv -d

View File

@ -1,15 +1,15 @@
Global:delete .SUFFIXES (not found)
Global: delete .SUFFIXES (not found)
Global: .MAKEFLAGS = -r -k -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0
Global: .SUFFIXES = set ignored (read-only)
Global: .SUFFIXES = append ignored (read-only)
Global: _ =
Global: _ = # (empty)
Var_Parse: ${.SUFFIXES::=assign} (eval-keep-dollar-and-undefined)
Evaluating modifier ${.SUFFIXES::...} on value ".c .o .1 .err .tar.gz" (eval-keep-dollar-and-undefined, regular)
Modifier part: "assign"
Global: .SUFFIXES = assign ignored (read-only)
Result of ${.SUFFIXES::=assign} is "" (eval-keep-dollar-and-undefined, regular)
Global: _ =
Global: _ = # (empty)
Var_Parse: ${preserve:L:_=.SUFFIXES} (eval-keep-dollar-and-undefined)
Evaluating modifier ${preserve:L} on value "" (eval-keep-dollar-and-undefined, undefined)
Result of ${preserve:L} is "preserve" (eval-keep-dollar-and-undefined, defined)
@ -32,7 +32,7 @@ ModifyWord_Loop: in "1", replace ".SUFFIXES" with "${.SUFFIXES}" to ".c .o .1 .e
Command: .SUFFIXES = 2 ignored (read-only)
Var_Parse: ${.SUFFIXES} (eval-defined)
ModifyWord_Loop: in "2", replace ".SUFFIXES" with "${.SUFFIXES}" to ".c .o .1 .err .tar.gz"
Command:delete .SUFFIXES (not found)
Command: delete .SUFFIXES (not found)
Result of ${1 2:@.SUFFIXES@${.SUFFIXES}@} is ".c .o .1 .err .tar.gz .c .o .1 .err .tar.gz" (eval-defined, defined)
Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0 -d v -d 0 -d v -d 0

View File

@ -2,12 +2,12 @@ Var_SetExpand: variable name "${:U}" expands to empty string, with value "cmdlin
Var_SetExpand: variable name "" expands to empty string, with value "cmdline-plain" - ignored
Global: .CURDIR = <curdir>
Var_Parse: ${MAKE_OBJDIR_CHECK_WRITABLE} (eval)
Global: .TARGETS =
Global: .TARGETS = # (empty)
Internal: MAKEFILE = varname-empty.mk
Global: .MAKE.MAKEFILES = varname-empty.mk
Global: .PARSEFILE = varname-empty.mk
Global:delete .INCLUDEDFROMDIR (not found)
Global:delete .INCLUDEDFROMFILE (not found)
Global: delete .INCLUDEDFROMDIR (not found)
Global: delete .INCLUDEDFROMFILE (not found)
Var_SetExpand: variable name "" expands to empty string, with value "default" - ignored
Var_SetExpand: variable name "" expands to empty string, with value "assigned" - ignored
SetVar: variable name is empty - ignored

View File

@ -1,4 +1,4 @@
# $NetBSD: varname.mk,v 1.9 2022/01/27 10:42:02 rillig Exp $
# $NetBSD: varname.mk,v 1.10 2022/02/09 21:09:24 rillig Exp $
#
# Tests for special variables, such as .MAKE or .PARSEDIR.
# And for variable names in general.
@ -42,7 +42,7 @@ ${VARNAME}= try3
.MAKEFLAGS: -d0
# All variable names of a scope are stored in the same hash table, using a
# simple hash function. Ensure that HashEntry_KeyEquals handles collisions
# simple hash function. Ensure that HashTable_Find handles collisions
# correctly and that the correct variable is looked up. The strings "0x" and
# "1Y" have the same hash code, as 31 * '0' + 'x' == 31 * '1' + 'Y'.
V.0x= 0x

99
var.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.1009 2022/02/04 23:43:10 rillig Exp $ */
/* $NetBSD: var.c,v 1.1019 2022/03/27 18:39:01 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -147,7 +147,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: var.c,v 1.1009 2022/02/04 23:43:10 rillig Exp $");
MAKE_RCSID("$NetBSD: var.c,v 1.1019 2022/03/27 18:39:01 rillig Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@ -440,11 +440,6 @@ VarFindSubstring(Substring name, GNode *scope, bool elsewhere)
FStr envName;
const char *envValue;
/*
* TODO: try setting an environment variable with the empty
* name, which should be technically possible, just to see
* how make reacts. All .for loops should be broken then.
*/
envName = Substring_Str(name);
envValue = getenv(envName.str);
if (envValue != NULL)
@ -484,6 +479,16 @@ VarFreeShortLived(Var *v)
free(v);
}
static const char *
ValueDescription(const char *value)
{
if (value[0] == '\0')
return "# (empty)";
if (ch_isspace(value[strlen(value) - 1]))
return "# (ends with space)";
return "";
}
/* Add a new variable of the given name and value to the given scope. */
static Var *
VarAdd(const char *name, const char *value, GNode *scope, VarSetFlags flags)
@ -492,7 +497,8 @@ VarAdd(const char *name, const char *value, GNode *scope, VarSetFlags flags)
Var *v = VarNew(FStr_InitRefer(/* aliased to */ he->key), value,
false, false, (flags & VAR_SET_READONLY) != 0);
HashEntry_Set(he, v);
DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, value);
DEBUG4(VAR, "%s: %s = %s%s\n",
scope->name, name, value, ValueDescription(value));
return v;
}
@ -507,11 +513,12 @@ Var_Delete(GNode *scope, const char *varname)
Var *v;
if (he == NULL) {
DEBUG2(VAR, "%s:delete %s (not found)\n", scope->name, varname);
DEBUG2(VAR, "%s: delete %s (not found)\n",
scope->name, varname);
return;
}
DEBUG2(VAR, "%s:delete %s\n", scope->name, varname);
DEBUG2(VAR, "%s: delete %s\n", scope->name, varname);
v = he->value;
if (v->inUse) {
Parse_Error(PARSE_FATAL,
@ -519,10 +526,12 @@ Var_Delete(GNode *scope, const char *varname)
v->name.str);
return;
}
if (v->exported)
unsetenv(v->name.str);
if (strcmp(v->name.str, MAKE_EXPORTED) == 0)
var_exportedVars = VAR_EXPORTED_NONE;
assert(v->name.freeIt == NULL);
HashTable_DeleteEntry(&scope->vars, he);
Buf_Done(&v->val);
@ -989,7 +998,8 @@ Var_SetWithFlags(GNode *scope, const char *name, const char *val,
Buf_Clear(&v->val);
Buf_AddStr(&v->val, val);
DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, val);
DEBUG4(VAR, "%s: %s = %s%s\n",
scope->name, name, val, ValueDescription(val));
if (v->exported)
ExportVar(name, VEM_PLAIN);
}
@ -1101,20 +1111,14 @@ Var_Append(GNode *scope, const char *name, const char *val)
DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, v->val.data);
if (v->fromEnvironment) {
/*
* The variable originally came from the environment.
* Install it in the global scope (we could place it
* in the environment, but then we should provide a
* way to export other variables...)
*/
v->fromEnvironment = false;
/* See VarAdd. */
HashEntry *he =
HashTable_CreateEntry(&scope->vars, name, NULL);
HashEntry_Set(he, v);
FStr_Done(&v->name);
v->name = FStr_InitRefer(/* aliased to */ he->key);
v->shortLived = false;
/*
* This is the only place where a variable is
* created in a scope, where v->name does not alias
* scope->vars->key.
*/
HashTable_Set(&scope->vars, name, v);
v->fromEnvironment = false;
}
}
}
@ -1438,10 +1442,11 @@ ModifyWord_SysVSubst(Substring word, SepBuf *buf, void *data)
if (Substring_IsEmpty(word))
return;
if (!Substring_HasPrefix(word, args->lhsPrefix))
goto no_match;
if (!Substring_HasSuffix(word, args->lhsSuffix))
goto no_match;
if (!Substring_HasPrefix(word, args->lhsPrefix) ||
!Substring_HasSuffix(word, args->lhsSuffix)) {
SepBuf_AddSubstring(buf, word);
return;
}
rhs = FStr_InitRefer(args->rhs);
Var_Expand(&rhs, args->scope, VARE_WANTRES);
@ -1457,10 +1462,6 @@ ModifyWord_SysVSubst(Substring word, SepBuf *buf, void *data)
SepBuf_AddStr(buf, percent != NULL ? percent + 1 : rhs.str);
FStr_Done(&rhs);
return;
no_match:
SepBuf_AddSubstring(buf, word);
}
#endif
@ -2711,9 +2712,8 @@ ApplyModifier_Range(const char **pp, ModChain *ch)
}
/* Parse a ':M' or ':N' modifier. */
static void
ParseModifier_Match(const char **pp, const ModChain *ch,
char **out_pattern)
static char *
ParseModifier_Match(const char **pp, const ModChain *ch)
{
const char *mod = *pp;
Expr *expr = ch->expr;
@ -2777,6 +2777,10 @@ ParseModifier_Match(const char **pp, const ModChain *ch,
if (needSubst) {
char *old_pattern = pattern;
/*
* XXX: Contrary to ParseModifierPart, a dollar in a ':M' or
* ':N' modifier must be escaped as '$$', not as '\$'.
*/
(void)Var_Subst(pattern, expr->scope, expr->emode, &pattern);
/* TODO: handle errors */
free(old_pattern);
@ -2784,7 +2788,7 @@ ParseModifier_Match(const char **pp, const ModChain *ch,
DEBUG2(VAR, "Pattern for ':%c' is \"%s\"\n", mod[0], pattern);
*out_pattern = pattern;
return pattern;
}
/* :Mpattern or :Npattern */
@ -2794,7 +2798,7 @@ ApplyModifier_Match(const char **pp, ModChain *ch)
char mod = **pp;
char *pattern;
ParseModifier_Match(pp, ch, &pattern);
pattern = ParseModifier_Match(pp, ch);
if (ModChain_ShouldEval(ch)) {
ModifyWordProc modifyWord =
@ -3225,7 +3229,7 @@ ApplyModifier_Words(const char **pp, ModChain *ch)
/* Normal case: select the words described by first and last. */
Expr_SetValueOwn(expr,
VarSelectWords(Expr_Str(expr), first, last,
ch->sep, ch->oneBigWord));
ch->sep, ch->oneBigWord));
ok:
FStr_Done(&festr);
@ -3488,11 +3492,11 @@ ApplyModifier_Assign(const char **pp, ModChain *ch)
scope = expr->scope; /* scope where v belongs */
if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL) {
Var *gv = VarFind(expr->name, expr->scope, false);
if (gv == NULL)
Var *v = VarFind(expr->name, expr->scope, false);
if (v == NULL)
scope = SCOPE_GLOBAL;
else
VarFreeShortLived(gv);
VarFreeShortLived(v);
}
if (op[0] == '+')
@ -4035,9 +4039,9 @@ ApplyModifiers(
/*
* TODO: Use p + strlen(p) instead, to stop parsing immediately.
*
* In the unit tests, this generates a few unterminated strings in the
* shell commands though. Instead of producing these unfinished
* strings, commands with evaluation errors should not be run at all.
* In the unit tests, this generates a few shell commands with
* unbalanced quotes. Instead of producing these incomplete strings,
* commands with evaluation errors should not be run at all.
*
* To make that happen, Var_Subst must report the actual errors
* instead of returning VPR_OK unconditionally.
@ -4047,8 +4051,8 @@ ApplyModifiers(
}
/*
* Only 4 of the 7 local variables are treated specially as they are the only
* ones that will be set when dynamic sources are expanded.
* Only 4 of the 7 built-in local variables are treated specially as they are
* the only ones that will be set when dynamic sources are expanded.
*/
static bool
VarnameIsDynamic(Substring varname)
@ -4798,7 +4802,8 @@ Var_Dump(GNode *scope)
for (i = 0; i < vec.len; i++) {
const char *varname = varnames[i];
Var *var = HashTable_FindValue(&scope->vars, varname);
debug_printf("%-16s = %s\n", varname, var->val.data);
debug_printf("%-16s = %s%s\n", varname,
var->val.data, ValueDescription(var->val.data));
}
Vector_Done(&vec);