Import bmake-20230622

Relevant/interesting changes:

	o optimize string matching for ':M' and ':N'
	o warn about malformed patterns in ':M', ':N' and '.if make(...)'
	o allow guards to be targets as well as variables
	The guard targets may include variable references like
	__${.PARSEDIR:tA}/${.PARSEFILE}__
	o optimization for makefiles protected from multiple-inclusion
	skip even opening the file after first include.
	o var.c: do not allow delete of readOnly variable
	o parse.c: .break takes no args
This commit is contained in:
Simon J. Gerraty 2023-06-27 13:29:43 -07:00
parent 945078deae
commit 3e39ce563b
213 changed files with 2670 additions and 1108 deletions

View File

@ -1,3 +1,74 @@
2023-06-22 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230622
Merge with NetBSD make, pick up
o optimize string matching for ':M' and ':N'
o warn about malformed patterns in ':M', ':N' and '.if make(...)'
2023-06-21 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230621
Merge with NetBSD make, pick up
o more extensive tests for include guards
o parse.c: if a guard is already defined a file that uses the same
guard is still guarded by it.
2023-06-20 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230620
Merge with NetBSD make, pick up
o allow guards to be targets as well as variables
The guard targets may include variable references like
__${.PARSEDIR:tA}/${.PARSEFILE}__
2023-06-19 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230619
Merge with NetBSD make, pick up
o unit test for .undef of readOnly vars
o optimization for makefiles protected from multiple-inclusion
skip even opening the file after first include.
Initially this only handles makefiles guarded by a variable
target guards are next.
2023-06-16 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230616
Merge with NetBSD make, pick up
o var.c: do not allow delete of readOnly variable
2023-06-03 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230601
Merge with NetBSD make, pick up
o parse.c: .break takes no args
o lots of unit test updates
2023-05-29 Simon J Gerraty <sjg@beast.crufty.net>
* unit-tests/Makefile: skip tests that require /dev/filemon
if it does not exists - issue a warning.
2023-05-22 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230522
Fix building on darwin ppc
* os.sh (MACHINE): Darwin powerpc cannot use `uname -m`
also recent NetBSD uses x86_64 for MACHINE_ARCH so conform.
2023-05-15 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230515
* Makefile (COPTS.filemon_ktrace.c): NetBSD 7 needs help to
compile filemon_ktrace.c
2023-05-13 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230512
o sys.dirdeps.mk - broke after-import target
2023-05-10 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230510

6
FILES
View File

@ -356,6 +356,8 @@ unit-tests/directive-ifnmake.exp
unit-tests/directive-ifnmake.mk
unit-tests/directive-include-fatal.exp
unit-tests/directive-include-fatal.mk
unit-tests/directive-include-guard.exp
unit-tests/directive-include-guard.mk
unit-tests/directive-include.exp
unit-tests/directive-include.mk
unit-tests/directive-info.exp
@ -392,8 +394,6 @@ unit-tests/export-variants.exp
unit-tests/export-variants.mk
unit-tests/export.exp
unit-tests/export.mk
unit-tests/forsubst.exp
unit-tests/forsubst.mk
unit-tests/gnode-submake.exp
unit-tests/gnode-submake.mk
unit-tests/hanoi-include.exp
@ -429,8 +429,6 @@ unit-tests/meta-cmd-cmp.mk
unit-tests/meta-ignore.inc
unit-tests/moderrs.exp
unit-tests/moderrs.mk
unit-tests/modmatch.exp
unit-tests/modmatch.mk
unit-tests/modmisc.exp
unit-tests/modmisc.mk
unit-tests/objdir-writable.exp

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.124 2023/02/25 20:27:44 sjg Exp $
# $Id: Makefile,v 1.125 2023/05/17 00:15:46 sjg Exp $
PROG= bmake
@ -68,7 +68,9 @@ FILEMON_H ?= /usr/include/dev/filemon/filemon.h
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
.endif
.endif # USE_FILEMON == dev
.elif ${USE_FILEMON} == "ktrace"
COPTS.filemon_ktrace.c += -Wno-error=unused-parameter
.endif
.endif # USE_FILEMON

View File

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

6
buf.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.c,v 1.55 2022/01/08 17:25:19 rillig Exp $ */
/* $NetBSD: buf.c,v 1.56 2023/06/01 07:44:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -75,7 +75,7 @@
#include "make.h"
/* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: buf.c,v 1.55 2022/01/08 17:25:19 rillig Exp $");
MAKE_RCSID("$NetBSD: buf.c,v 1.56 2023/06/01 07:44:10 rillig Exp $");
/* Make space in the buffer for adding at least 16 more bytes. */
void
@ -106,7 +106,7 @@ Buf_AddBytes(Buffer *buf, const char *bytes, size_t bytes_len)
/* Add the bytes between start and end to the buffer. */
void
Buf_AddBytesBetween(Buffer *buf, const char *start, const char *end)
Buf_AddRange(Buffer *buf, const char *start, const char *end)
{
Buf_AddBytes(buf, start, (size_t)(end - start));
}

4
buf.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.h,v 1.47 2022/01/08 17:25:19 rillig Exp $ */
/* $NetBSD: buf.h,v 1.48 2023/06/01 07:44:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -116,7 +116,7 @@ Buf_EndsWith(const Buffer *buf, char ch)
}
void Buf_AddBytes(Buffer *, const char *, size_t);
void Buf_AddBytesBetween(Buffer *, const char *, const char *);
void Buf_AddRange(Buffer *, const char *, const char *);
void Buf_AddStr(Buffer *, const char *);
void Buf_AddInt(Buffer *, int);
void Buf_AddFlag(Buffer *, bool, const char *);

99
cond.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.344 2023/02/14 21:08:00 rillig Exp $ */
/* $NetBSD: cond.c,v 1.353 2023/06/23 05:21:10 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -92,7 +92,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: cond.c,v 1.344 2023/02/14 21:08:00 rillig Exp $");
MAKE_RCSID("$NetBSD: cond.c,v 1.353 2023/06/23 05:21:10 rillig Exp $");
/*
* Conditional expressions conform to this grammar:
@ -136,10 +136,10 @@ 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, for example '.ifdef ${VAR}' is equivalent to
* '.if defined(${VAR})', checking whether the variable named by the
* expression '${VAR}' is defined.
* expression has length > 0 and is not numerically zero. The other
* '.if' variants delegate 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;
@ -173,7 +173,7 @@ typedef struct CondParser {
bool printedError;
} CondParser;
static CondResult CondParser_Or(CondParser *par, bool);
static CondResult CondParser_Or(CondParser *, bool);
unsigned int cond_depth = 0; /* current .if nesting level */
@ -295,10 +295,19 @@ static bool
FuncMake(const char *targetPattern)
{
StringListNode *ln;
bool warned = false;
for (ln = opts.create.first; ln != NULL; ln = ln->next)
if (Str_Match(ln->datum, targetPattern))
for (ln = opts.create.first; ln != NULL; ln = ln->next) {
StrMatchResult res = Str_Match(ln->datum, targetPattern);
if (res.error != NULL && !warned) {
warned = true;
Parse_Error(PARSE_WARNING,
"%s in pattern argument '%s' to function 'make'",
res.error, targetPattern);
}
if (res.matched)
return true;
}
return false;
}
@ -338,7 +347,7 @@ FuncCommands(const char *node)
}
/*
* Convert the string into a floating-point number. Accepted formats are
* Convert the string to a floating point number. Accepted formats are
* base-10 integer, base-16 integer and finite floating point numbers.
*/
static bool
@ -507,7 +516,7 @@ CondParser_Leaf(CondParser *par, bool doEval, bool unquotedOK,
* ".if 0".
*/
static bool
EvalNotEmpty(CondParser *par, const char *value, bool quoted)
EvalTruthy(CondParser *par, const char *value, bool quoted)
{
double num;
@ -631,7 +640,7 @@ CondParser_Comparison(CondParser *par, bool doEval)
if (!CondParser_ComparisonOp(par, &op)) {
/* Unknown operator, compare against an empty string or 0. */
t = ToToken(doEval && EvalNotEmpty(par, lhs.str, lhsQuoted));
t = ToToken(doEval && EvalTruthy(par, lhs.str, lhsQuoted));
goto done_lhs;
}
@ -1123,6 +1132,7 @@ Cond_EvalLine(const char *line)
/* Return state for previous conditional */
cond_depth--;
Parse_GuardEndif();
return cond_states[cond_depth] & IFS_ACTIVE
? CR_TRUE : CR_FALSE;
}
@ -1150,6 +1160,7 @@ Cond_EvalLine(const char *line)
Parse_Error(PARSE_FATAL, "if-less else");
return CR_TRUE;
}
Parse_GuardElse();
state = cond_states[cond_depth];
if (state == IFS_INITIAL) {
@ -1185,6 +1196,7 @@ Cond_EvalLine(const char *line)
Parse_Error(PARSE_FATAL, "if-less elif");
return CR_TRUE;
}
Parse_GuardElse();
state = cond_states[cond_depth];
if (state & IFS_SEEN_ELSE) {
Parse_Error(PARSE_WARNING, "extra elif");
@ -1234,6 +1246,69 @@ Cond_EvalLine(const char *line)
return res;
}
static bool
ParseVarnameGuard(const char **pp, const char **varname)
{
const char *p = *pp;
if (ch_isalpha(*p) || *p == '_') {
while (ch_isalnum(*p) || *p == '_')
p++;
*varname = *pp;
*pp = p;
return true;
}
return false;
}
/* Extracts the multiple-inclusion guard from a conditional, if any. */
Guard *
Cond_ExtractGuard(const char *line)
{
const char *p, *varname;
Substring dir;
enum GuardKind kind;
Guard *guard;
p = line + 1; /* skip the '.' */
cpp_skip_hspace(&p);
dir.start = p;
while (ch_isalpha(*p))
p++;
dir.end = p;
cpp_skip_hspace(&p);
if (Substring_Equals(dir, "if")) {
if (skip_string(&p, "!defined(")) {
if (ParseVarnameGuard(&p, &varname)
&& strcmp(p, ")") == 0)
goto found_variable;
} else if (skip_string(&p, "!target(")) {
const char *arg_p = p;
free(ParseWord(&p, false));
if (strcmp(p, ")") == 0) {
char *target = ParseWord(&arg_p, true);
guard = bmake_malloc(sizeof(*guard));
guard->kind = GK_TARGET;
guard->name = target;
return guard;
}
}
} else if (Substring_Equals(dir, "ifndef")) {
if (ParseVarnameGuard(&p, &varname) && *p == '\0')
goto found_variable;
}
return NULL;
found_variable:
kind = GK_VARIABLE;
guard = bmake_malloc(sizeof(*guard));
guard->kind = kind;
guard->name = bmake_strsedup(varname, p);
return guard;
}
void
Cond_EndFile(void)
{

14
dir.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.280 2023/01/24 00:24:02 sjg Exp $ */
/* $NetBSD: dir.c,v 1.282 2023/06/23 04:56:54 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -138,7 +138,7 @@
#include "job.h"
/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: dir.c,v 1.280 2023/01/24 00:24:02 sjg Exp $");
MAKE_RCSID("$NetBSD: dir.c,v 1.282 2023/06/23 04:56:54 rillig Exp $");
/*
* A search path is a list of CachedDir structures. A CachedDir has in it the
@ -668,8 +668,10 @@ DirMatchFiles(const char *pattern, CachedDir *dir, StringList *expansions)
HashIter_InitSet(&hi, &dir->files);
while (HashIter_Next(&hi) != NULL) {
const char *base = hi.entry->key;
StrMatchResult res = Str_Match(base, pattern);
/* TODO: handle errors from res.error */
if (!Str_Match(base, pattern))
if (!res.matched)
continue;
/*
@ -822,14 +824,14 @@ DirExpandCurly(const char *word, const char *brace, SearchPath *path,
}
/* Expand the word in each of the directories from the path. */
/* Expand the pattern in each of the directories from the path. */
static void
DirExpandPath(const char *word, SearchPath *path, StringList *expansions)
DirExpandPath(const char *pattern, SearchPath *path, StringList *expansions)
{
SearchPathNode *ln;
for (ln = path->dirs.first; ln != NULL; ln = ln->next) {
CachedDir *dir = ln->datum;
DirMatchFiles(word, dir, expansions);
DirMatchFiles(pattern, dir, expansions);
}
}

40
for.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: for.c,v 1.174 2023/05/09 19:43:12 rillig Exp $ */
/* $NetBSD: for.c,v 1.176 2023/06/01 09:02:14 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: for.c,v 1.174 2023/05/09 19:43:12 rillig Exp $");
MAKE_RCSID("$NetBSD: for.c,v 1.176 2023/06/01 09:02:14 rillig Exp $");
typedef struct ForLoop {
@ -115,7 +115,7 @@ ForLoop_Free(ForLoop *f)
}
char *
ForLoop_Details(ForLoop *f)
ForLoop_Details(const ForLoop *f)
{
size_t i, n;
const char **vars;
@ -133,7 +133,7 @@ ForLoop_Details(ForLoop *f)
Buf_AddStr(&buf, ", ");
Buf_AddStr(&buf, vars[i]);
Buf_AddStr(&buf, " = ");
Buf_AddBytesBetween(&buf, items[i].start, items[i].end);
Buf_AddRange(&buf, items[i].start, items[i].end);
}
return Buf_DoneData(&buf);
}
@ -351,7 +351,7 @@ NeedsEscapes(Substring value, char endc)
}
/*
* While expanding the body of a .for loop, write the item in the ${:U...}
* While expanding the body of a .for loop, write the item as a ${:U...}
* expression, escaping characters as needed. The result is later unescaped
* by ApplyModifier_Defined.
*/
@ -362,7 +362,7 @@ AddEscaped(Buffer *cmds, Substring item, char endc)
char ch;
if (!NeedsEscapes(item, endc)) {
Buf_AddBytesBetween(cmds, item.start, item.end);
Buf_AddRange(cmds, item.start, item.end);
return;
}
@ -392,7 +392,7 @@ AddEscaped(Buffer *cmds, Substring item, char endc)
}
/*
* When expanding the body of a .for loop, replace the variable name of an
* While expanding the body of a .for loop, replace the variable name of an
* expression like ${i} or ${i:...} or $(i) or $(i:...) with ":Uvalue".
*/
static void
@ -401,12 +401,12 @@ ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body,
{
size_t i;
const char *start = *pp;
const char **vars = Vector_Get(&f->vars, 0);
const char **varnames = Vector_Get(&f->vars, 0);
for (i = 0; i < f->vars.len; i++) {
const char *p = start;
if (!cpp_skip_string(&p, vars[i]))
if (!cpp_skip_string(&p, varnames[i]))
continue;
/* XXX: why test for backslash here? */
if (*p != ':' && *p != endc && *p != '\\')
@ -416,7 +416,7 @@ ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body,
* Found a variable match. Skip over the variable name and
* instead add ':U<value>' to the current body.
*/
Buf_AddBytesBetween(body, *inout_mark, start);
Buf_AddRange(body, *inout_mark, start);
Buf_AddStr(body, ":U");
AddEscaped(body, f->items.words[firstItem + i], endc);
@ -427,7 +427,7 @@ ForLoop_SubstVarLong(ForLoop *f, unsigned int firstItem, Buffer *body,
}
/*
* When expanding the body of a .for loop, replace single-character
* While expanding the body of a .for loop, replace single-character
* variable expressions like $i with their ${:U...} expansion.
*/
static void
@ -451,7 +451,7 @@ ForLoop_SubstVarShort(ForLoop *f, unsigned int firstItem, Buffer *body,
return;
found:
Buf_AddBytesBetween(body, *inout_mark, p);
Buf_AddRange(body, *inout_mark, p);
*inout_mark = p + 1;
/* Replace $<ch> with ${:U<value>} */
@ -465,13 +465,14 @@ ForLoop_SubstVarShort(ForLoop *f, unsigned int firstItem, Buffer *body,
* replacing the expressions for the iteration variables on the way.
*
* Using variable expressions ensures that the .for loop can't generate
* syntax, and that the later parsing will still see a variable.
* This code assumes that the variable with the empty name will never be
* defined, see unit-tests/varname-empty.mk for more details.
* syntax, and that the later parsing will still see an expression.
* This code assumes that the variable with the empty name is never defined,
* see unit-tests/varname-empty.mk.
*
* The detection of substitutions of the loop control variables is naive.
* Many of the modifiers use '\$' instead of '$$' to escape '$', so it is
* possible to contrive a makefile where an unwanted substitution happens.
* See unit-tests/directive-for-escape.mk.
*/
static void
ForLoop_SubstBody(ForLoop *f, unsigned int firstItem, Buffer *body)
@ -497,7 +498,7 @@ ForLoop_SubstBody(ForLoop *f, unsigned int firstItem, Buffer *body)
break;
}
Buf_AddBytesBetween(body, mark, end);
Buf_AddRange(body, mark, end);
}
/*
@ -512,7 +513,12 @@ For_NextIteration(ForLoop *f, Buffer *body)
f->nextItem += (unsigned int)f->vars.len;
ForLoop_SubstBody(f, f->nextItem - (unsigned int)f->vars.len, body);
DEBUG1(FOR, "For: loop body:\n%s", body->data);
if (DEBUG(FOR)) {
char *details = ForLoop_Details(f);
debug_printf("For: loop body with %s:\n%s",
details, body->data);
free(details);
}
return true;
}

19
make.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.319 2023/03/28 14:39:31 rillig Exp $ */
/* $NetBSD: make.h,v 1.323 2023/06/20 09:25:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -555,6 +555,14 @@ typedef enum CondResult {
CR_ERROR /* Unknown directive or parse error */
} CondResult;
typedef struct {
enum GuardKind {
GK_VARIABLE,
GK_TARGET
} kind;
char *name;
} Guard;
/* Names of the variables that are "local" to a specific target. */
#define TARGET "@" /* Target of dependency */
#define OODATE "?" /* All out-of-date sources */
@ -794,8 +802,8 @@ void Arch_End(void);
bool Arch_ParseArchive(char **, GNodeList *, GNode *);
void Arch_Touch(GNode *);
void Arch_TouchLib(GNode *);
void Arch_UpdateMTime(GNode *gn);
void Arch_UpdateMemberMTime(GNode *gn);
void Arch_UpdateMTime(GNode *);
void Arch_UpdateMemberMTime(GNode *);
void Arch_FindLib(GNode *, SearchPath *);
bool Arch_LibOODate(GNode *) MAKE_ATTR_USE;
bool Arch_IsLib(GNode *) MAKE_ATTR_USE;
@ -809,6 +817,7 @@ void Compat_Make(GNode *, GNode *);
extern unsigned int cond_depth;
CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE;
CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE;
Guard *Cond_ExtractGuard(const char *) MAKE_ATTR_USE;
void Cond_EndFile(void);
/* dir.c; see also dir.h */
@ -836,7 +845,7 @@ int For_Eval(const char *) MAKE_ATTR_USE;
bool For_Accum(const char *, int *) MAKE_ATTR_USE;
void For_Run(unsigned, unsigned);
bool For_NextIteration(struct ForLoop *, Buffer *);
char *ForLoop_Details(struct ForLoop *);
char *ForLoop_Details(const struct ForLoop *);
void ForLoop_Free(struct ForLoop *);
void For_Break(struct ForLoop *);
@ -873,6 +882,8 @@ void Parse_PushInput(const char *, unsigned, unsigned, Buffer,
void Parse_MainName(GNodeList *);
int Parse_NumErrors(void) MAKE_ATTR_USE;
unsigned int CurFile_CondMinDepth(void) MAKE_ATTR_USE;
void Parse_GuardElse(void);
void Parse_GuardEndif(void);
/* suff.c */

View File

@ -1,3 +1,49 @@
2023-05-25 Simon J Gerraty <sjg@beast.crufty.net>
* meta.autodep.mk (beforegendirdeps): allow tasks to be done
at END but before gendirdeps
2023-05-22 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20230522
* host-target.mk: deal with garbage from uname -m on
Darwin ppc, also NetBSD appears to use x86_64 for MACHINE_ARCH
these days so just leave it be.
For Darwin arm and i386 use _HOST_MACHINE for _HOST_ARCH so we get
arm64 and x86_64 in HOST_TARGET.
2023-05-15 Simon J Gerraty <sjg@beast.crufty.net>
* sys.vars.mk: M_mtime use :mtime or 'stat -f %m' for older
versions of bmake.
* dirdeps.mk (TARGET_SPEC_VARS.host):
While *most* projects need only DEP_MACHINE for host,
there is always an exception. So we allow for
TARGET_SPEC_VARS.host to be a subset of TARGET_SPEC_VARS.
The default will *just work* for most projects.
We set DEP_TARGET_SPEC_VARS and hence DEP_TARGET_SPEC
based on DEP_MACHINE.
Allow for M_dep_qual_fixes.host to be different too
and take care to apply the right set.
2023-05-14 Simon J Gerraty <sjg@beast.crufty.net>
* sys.dirdeps.mk: we *do* want to override OBJTOP
and if MAKEOBJDIR was not in env as we want it;
put it there - carefully.
Ensure OBJROOT ends in / or - (/ preferred)
Add more comments to explain what/why.
2023-05-13 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20230512
* dirdeps.mk: take care not to qualify "host" dirdeps
* sys.dirdeps.mk (OBJTOP): must use ?=
2023-05-10 Simon J Gerraty <sjg@beast.crufty.net>
* meta.autodep.mk: if LOCAL_DEPENDS_GUARD is "no"

View File

@ -1,4 +1,4 @@
# $Id: dirdeps.mk,v 1.160 2023/05/10 20:44:58 sjg Exp $
# $Id: dirdeps.mk,v 1.162 2023/05/15 17:37:46 sjg Exp $
# SPDX-License-Identifier: BSD-2-Clause
#
@ -212,12 +212,16 @@ _DEP_TARGET_SPEC =
# it should be set by sys.mk or similar by now.
# TARGET_SPEC must not contain any '.'s.
TARGET_SPEC_VARS ?= MACHINE
# we allow for this to be a subset
TARGET_SPEC_VARS.host ?= MACHINE
TARGET_SPEC_VARS.host32 = ${TARGET_SPEC_VARS.host}
# this is what we started with
TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
# this is what we mostly use below
DEP_TARGET_SPEC = ${TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,}
DEP_TARGET_SPEC_VARS = ${TARGET_SPEC_VARS.${DEP_MACHINE}:U${TARGET_SPEC_VARS}}
DEP_TARGET_SPEC = ${DEP_TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,}
# make sure we have defaults
.for v in ${TARGET_SPEC_VARS}
.for v in ${DEP_TARGET_SPEC_VARS}
DEP_$v ?= ${$v}
.endfor
@ -227,12 +231,7 @@ DEP_$v ?= ${$v}
# we compute below are fully qualified wrt DEP_TARGET_SPEC.
# The makefiles may only partially specify (eg. MACHINE only),
# so we need to construct a set of modifiers to fill in the gaps.
.if ${MAKE_VERSION} >= 20170130
_tspec_x := ${TARGET_SPEC_VARS:range}
.else
# do it the hard way
_tspec_x := ${TARGET_SPEC_VARS:[#]:@x@i=1;while [ $$i -le $x ]; do echo $$i; i=$$((i + 1)); done;@:sh}
.endif
_tspec_x := ${TARGET_SPEC_VARS:${M_RANGE:Urange}}
# this handles unqualified entries
M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC};
# there needs to be at least one item missing for these to make sense
@ -242,10 +241,27 @@ _tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,}
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i};
.endfor
TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
.if ${TARGET_SPEC_VARS.host} == ${TARGET_SPEC_VARS}
M_dep_qual_fixes.host = ${M_dep_qual_fixes}
.elif ${TARGET_SPEC_VARS.host:[#]} > 1
_htspec_x := ${TARGET_SPEC_VARS.host:${M_RANGE:Urange}}
# this handles unqualified entries
M_dep_qual_fixes.host = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC};
# there needs to be at least one item missing for these to make sense
.for i in ${_htspec_x:[2..-1]}
_htspec_m$i := ${TARGET_SPEC_VARS.host:[2..$i]:@w@[^,]+@:ts,}
_htspec_a$i := ,${TARGET_SPEC_VARS.host:[$i..-1]:@v@$$$${DEP_$v}@:ts,}
M_dep_qual_fixes.host += C;(\.${_htspec_m$i})$$;\1${_htspec_a$i};
.endfor
.else
M_dep_qual_fixes.host = U
.endif
.else
# A harmless? default.
M_dep_qual_fixes = U
.endif
M_dep_qual_fixes.host ?= ${M_dep_qual_fixes}
M_dep_qual_fixes.host32 = ${M_dep_qual_fixes.host}
.if !defined(.MAKE.DEPENDFILE_PREFERENCE)
# .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater?
@ -328,7 +344,7 @@ _tspec := ${_DEP_TARGET_SPEC:S/,/ /g}
.for i in ${_tspec_x}
DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
.endfor
.for v in ${TARGET_SPEC_VARS:O:u}
.for v in ${DEP_TARGET_SPEC_VARS:O:u}
.if empty(DEP_$v)
.undef DEP_$v
.endif
@ -337,14 +353,6 @@ DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
DEP_MACHINE := ${_DEP_TARGET_SPEC}
.endif
# host is special
.if ${DEP_MACHINE:Mhost*} != ""
DEP_TARGET_SPEC = ${DEP_MACHINE}
.for v in ${TARGET_SPEC_VARS:O:u:NMACHINE}
.undef DEP_$v
.endfor
.endif
# reset each time through
_build_all_dirs =
_build_xtra_dirs =
@ -651,7 +659,7 @@ _machines += host
_machines := ${_machines:O:u}
.endif
.if ${TARGET_SPEC_VARS:[#]} > 1
.if ${DEP_TARGET_SPEC_VARS:[#]} > 1
# we need to tweak _machines
_dm := ${DEP_MACHINE}
# apply the same filtering that we do when qualifying DIRDEPS.
@ -659,7 +667,7 @@ _dm := ${DEP_MACHINE}
# Again we expect that any already qualified machines are fully qualified.
_machines := ${_machines:M*,*} ${_machines:N*,*:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:S,^.,,}
DEP_MACHINE := ${_dm}
_machines := ${_machines:${M_dep_qual_fixes:ts:}:O:u}
_machines := ${_machines:${M_dep_qual_fixes.${DEP_MACHINE}:U${M_dep_qual_fixes}:ts:}:O:u}
.endif
# reset each time through
@ -717,7 +725,16 @@ _build_dirs += \
${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@}
# qualify everything now
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
.if ${_debug_reldir}
.info _build_dirs=${_build_dirs}
.endif
# make sure we do not mess with qualifying "host" entries
_build_dirs := ${_build_dirs:M*.host*:${M_dep_qual_fixes.host:ts:}} \
${_build_dirs:N*.host*:${M_dep_qual_fixes:ts:}}
_build_dirs := ${_build_dirs:O:u}
.if ${_debug_reldir}
.info _build_dirs=${_build_dirs}
.endif
.endif # empty DIRDEPS
@ -767,9 +784,10 @@ _cache_script += echo; echo 'DIRDEPS.${_this_dir}.$m = \';
.endif
# it would be nice to do :N${.TARGET}
.if !empty(__qual_depdirs)
.for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
.for q in ${__qual_depdirs:M*.host*:${M_dep_qual_fixes.host:ts:}:E:O:u:N$m} \
${__qual_depdirs:N*.host*:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
.if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
.info ${DEP_RELDIR}.$m: q=$q graph: ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
.endif
.if ${BUILD_DIRDEPS_CACHE} == "yes"
_cache_deps += ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
@ -816,14 +834,13 @@ _dr := ${d:S,^${SRCTOP}/,,}
_DEP_TARGET_SPEC := ${d:E}
# some makefiles may still look at this
_DEP_MACHINE := ${d:E:C/,.*//}
DEP_MACHINE := ${_DEP_MACHINE}
# set these too in case Makefile.depend* uses them
.if ${TARGET_SPEC_VARS:[#]} > 1
.if ${DEP_TARGET_SPEC_VARS:[#]} > 1
_dtspec := ${_DEP_TARGET_SPEC:S/,/ /g}
.for i in ${_tspec_x}
DEP_${TARGET_SPEC_VARS:[$i]} := ${_dtspec:[$i]}
DEP_${DEP_TARGET_SPEC_VARS:[$i]} := ${_dtspec:[$i]}
.endfor
.else
DEP_MACHINE := ${_DEP_MACHINE}
.endif
# Warning: there is an assumption here that MACHINE is always
# the first entry in TARGET_SPEC_VARS.
@ -831,7 +848,7 @@ DEP_MACHINE := ${_DEP_MACHINE}
_m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:C;${MACHINE}((,.+)?)$;${d:E:C/,.*//}\1;:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]}
.if !empty(_m)
# M_dep_qual_fixes isn't geared to Makefile.depend
_qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}}
_qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes.${d:E}:U${M_dep_qual_fixes}:ts:}}
.if ${_debug_search}
.info Looking for ${_qm}
.endif

View File

@ -1,7 +1,10 @@
# RCSid:
# $Id: host-target.mk,v 1.14 2022/02/04 18:05:22 sjg Exp $
# $Id: host-target.mk,v 1.18 2023/05/22 23:08:31 sjg Exp $
# Host platform information; may be overridden
.if !target(__${.PARSEFILE}__)
__${.PARSEFILE}__: .NOTMAIN
.if !defined(_HOST_OSNAME)
# use .MAKE.OS if available
_HOST_OSNAME := ${.MAKE.OS:U${uname -s:L:sh}}
@ -11,23 +14,27 @@ _HOST_OSNAME := ${.MAKE.OS:U${uname -s:L:sh}}
_HOST_OSREL != uname -r
.export _HOST_OSREL
.endif
.if !defined(_HOST_MACHINE)
_HOST_MACHINE != uname -m
.export _HOST_MACHINE
.endif
.if !defined(_HOST_ARCH)
# for Darwin and NetBSD prefer $MACHINE (amd64 rather than x86_64)
.if ${_HOST_OSNAME:NDarwin:NNetBSD} == ""
_HOST_ARCH := ${_HOST_MACHINE}
.else
_HOST_ARCH != uname -p 2> /dev/null || uname -m
# uname -p may produce garbage on linux
.if ${_HOST_ARCH:[\#]} > 1 || ${_HOST_ARCH:Nunknown} == ""
_HOST_ARCH := ${_HOST_MACHINE}
.endif
_HOST_ARCH = ${_HOST_MACHINE}
.elif ${_HOST_OSNAME:NDarwin} == "" && ${_HOST_ARCH:Narm:Ni386} == ""
# _HOST_MACHINE is more explicit/useful
_HOST_ARCH = ${_HOST_MACHINE}
.endif
.export _HOST_ARCH
.endif
.if !defined(_HOST_MACHINE)
_HOST_MACHINE != uname -m
# just in case
_HOST_ARCH := ${_HOST_ARCH}
# uname -m may produce garbage on darwin ppc
.if ${_HOST_MACHINE:[\#]} > 1
_HOST_MACHINE := ${_HOST_ARCH}
.endif
.export _HOST_MACHINE
.endif
.if !defined(HOST_MACHINE)
HOST_MACHINE := ${_HOST_MACHINE}
.export HOST_MACHINE
@ -48,3 +55,5 @@ HOST_TARGET32 := ${host_os:S,/,,g}${HOST_OSMAJOR}-${_HOST_ARCH32}
TR ?= tr
toLower = ${TR} 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
toUpper = ${TR} 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.endif

View File

@ -59,7 +59,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: install-mk,v 1.234 2023/05/13 15:52:24 sjg Exp $
# $Id: install-mk,v 1.239 2023/05/29 18:04:48 sjg Exp $
#
# @(#) Copyright (c) 1994-2023 Simon J. Gerraty
#
@ -74,7 +74,7 @@
# sjg@crufty.net
#
MK_VERSION=20230510
MK_VERSION=20230601
OWNER=
GROUP=
MODE=444

View File

@ -1,4 +1,4 @@
# $Id: meta.autodep.mk,v 1.57 2023/05/13 15:52:24 sjg Exp $
# $Id: meta.autodep.mk,v 1.58 2023/05/25 22:33:23 sjg Exp $
#
# @(#) Copyright (c) 2010, Simon J. Gerraty
@ -210,7 +210,8 @@ _depend =
.endif
.if ${UPDATE_DEPENDFILE} == "yes"
gendirdeps: ${_DEPENDFILE}
gendirdeps: beforegendirdeps .WAIT ${_DEPENDFILE}
beforegendirdeps:
.endif
.if !target(${_DEPENDFILE})

View File

@ -1,4 +1,4 @@
# $Id: sys.dirdeps.mk,v 1.9 2023/05/11 20:05:42 sjg Exp $
# $Id: sys.dirdeps.mk,v 1.12 2023/05/14 16:16:03 sjg Exp $
#
# @(#) Copyright (c) 2012-2023, Simon J. Gerraty
#
@ -45,6 +45,7 @@ SRCTOP := ${SB_SRC:U${.PARSEDIR:tA:H:H}}
.endif
# fake SB if not using mk wrapper
# SB documented at http://www.crufty.net/sjg/docs/sb-tools.htm
.if !defined(SB)
SB := ${SRCTOP:H}
.export SB
@ -54,6 +55,10 @@ SB := ${SRCTOP:H}
OBJROOT := ${SB_OBJROOT:U${MAKEOBJDIRPREFIX:U${SB}/obj}/}
.export OBJROOT
.endif
# we expect OBJROOT to end with / (- can work too)
.if ${OBJROOT:M*[/-]} == ""
OBJROOT := ${OBJROOT}/
.endif
.if empty(STAGE_ROOT)
STAGE_ROOT ?= ${OBJROOT}stage
@ -66,9 +71,6 @@ STAGE_ROOT ?= ${OBJROOT}stage
# TARGET_SPEC must not contain any '.'s.
TARGET_SPEC_VARS ?= MACHINE
.if !target(_tspec_env_done_)
_tspec_env_done_: .NOTMAIN
.if ${TARGET_SPEC:Uno:M*,*} != ""
# deal with TARGET_SPEC from env
_tspec := ${TARGET_SPEC:S/,/ /g}
@ -86,7 +88,6 @@ TARGET_SPEC=
.endif
.endfor
.endif
.endif
# Now make sure we know what TARGET_SPEC is
# as we may need it to find Makefile.depend*
@ -98,6 +99,10 @@ TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
.endif
.if ${TARGET_SPEC_VARS:[#]} > 1
TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
# alternatives might be
# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARSr:@v@${$v:U}@:ts/}
# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts/}
TARGET_OBJ_SPEC ?= ${TARGET_SPEC_VARS:@v@${$v:U}@:ts.}
.else
TARGET_OBJ_SPEC ?= ${MACHINE}
@ -113,22 +118,37 @@ MACHINE0 := ${MACHINE}
.export MACHINE0
.endif
.if ${MACHINE} == "host"
OBJTOP = ${HOST_OBJTOP}
.elif ${MACHINE} == "host32"
OBJTOP = ${HOST_OBJTOP32}
.endif
MACHINE_OBJ.host = ${HOST_TARGET}
MACHINE_OBJ.host32 = ${HOST_TARGET32}
MACHINE_OBJ.${MACHINE} ?= ${TARGET_OBJ_SPEC}
MACHINE_OBJDIR = ${MACHINE_OBJ.${MACHINE}}
OBJTOP = ${OBJROOT}/${MACHINE_OBJDIR}
# we likely want to override env for OBJTOP
.if ${MACHINE} == "host"
OBJTOP = ${HOST_OBJTOP}
.elif ${MACHINE} == "host32"
OBJTOP = ${HOST_OBJTOP32}
.else
OBJTOP = ${OBJROOT}${MACHINE_OBJDIR}
.endif
.if ${.MAKE.LEVEL} > 0
# should not change from level 1 onwards
# this only matters for cases like bmake/unit-tests
# where we do ${MAKE} -r
.export OBJTOP
.endif
.if ${MAKEOBJDIR:U:M*/*} == ""
# we do not use MAKEOBJDIRPREFIX
# though we may have used it above to initialize OBJROOT
.undef MAKEOBJDIRPREFIX
# we use this
MAKEOBJDIR ?= ${.CURDIR:S,${SRCTOP},${OBJTOP},}
# this is what we expected in env
MAKEOBJDIR = $${.CURDIR:S,^$${SRCTOP},$${OBJTOP},}
# export that but do not track
.export-env MAKEOBJDIR
# this what we need here
MAKEOBJDIR = ${.CURDIR:S,${SRCTOP},${OBJTOP},}
.endif
STAGE_MACHINE ?= ${MACHINE_OBJDIR}
STAGE_OBJTOP ?= ${STAGE_ROOT}/${STAGE_MACHINE}

View File

@ -1,4 +1,4 @@
# $Id: sys.vars.mk,v 1.14 2023/02/17 22:32:47 sjg Exp $
# $Id: sys.vars.mk,v 1.15 2023/05/16 16:41:52 sjg Exp $
#
# @(#) Copyright (c) 2003-2023, Simon J. Gerraty
#
@ -129,3 +129,12 @@ M_Onr = Onr
# index values use ${M_Index:S,K,key,}:[1] to select only the first.
M_Index = _:${M_RANGE}:@i@$${"$${_:[$$i]:MK}":?$$i:}@
# mtime of each word - assumed to be a valid pathname
.if ${.MAKE.LEVEL} < 20230510
M_mtime = tW:S,^,${STAT:Ustat} -f %m ,:sh
.else
# M_mtime_fallback can be =error to throw an error
# or =0 to use 0, default is to use current time
M_mtime = mtime${M_mtime_fallback:U}
.endif

16
os.sh Executable file → Normal file
View File

@ -17,7 +17,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: os.sh,v 1.62 2023/01/17 18:30:21 sjg Exp $
# $Id: os.sh,v 1.63 2023/05/22 20:44:47 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@ -41,12 +41,16 @@ OSMAJOR=`IFS=.; set $OSREL; echo $1`
MACHINE=`uname -m`
MACHINE_ARCH=`uname -p 2>/dev/null || echo $MACHINE`
# there is at least one case of `uname -p` outputting
# a bunch of usless drivel
# there is at least one case of `uname -p`
# and even `uname -m` outputting usless info
# fortunately not both together
case "$MACHINE" in
*[!A-Za-z0-9_-]*) MACHINE="$MACHINE_ARCH";;
esac
case "$MACHINE_ARCH" in
unknown|*[!A-Za-z0-9_-]*) MACHINE_ARCH="$MACHINE";;
esac
# we need this here, and it is not always available...
Which() {
case "$1" in
@ -87,7 +91,7 @@ AIX) # everyone loves to be different...
PS_AXC=-e
SHARE_ARCH=$OS/$OSMAJOR.X
;;
Darwin) # a bit like BSD
Darwin) # this is more explicit (arm64 vs arm)
HOST_ARCH=$MACHINE
;;
SunOS)
@ -140,10 +144,10 @@ SunOS)
esac
# NetBSD at least has good backward compatibility
# so NetBSD/i386 is good enough
# recent NetBSD uses x86_64 for MACHINE_ARCH
case $OS in
NetBSD)
LOCALBASE=/usr/pkg
HOST_ARCH=$MACHINE
SHARE_ARCH=$OS/$HOST_ARCH
;;
OpenBSD)

106
parse.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.698 2023/05/10 16:10:02 rillig Exp $ */
/* $NetBSD: parse.c,v 1.704 2023/06/23 06:08:56 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -121,7 +121,15 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: parse.c,v 1.698 2023/05/10 16:10:02 rillig Exp $");
MAKE_RCSID("$NetBSD: parse.c,v 1.704 2023/06/23 06:08:56 rillig Exp $");
/* Detects a multiple-inclusion guard in a makefile. */
typedef enum {
GS_START, /* at the beginning of the file */
GS_COND, /* after the guard condition */
GS_DONE, /* after the closing .endif */
GS_NO /* the file is not guarded */
} GuardState;
/*
* A file being read.
@ -141,9 +149,12 @@ typedef struct IncludedFile {
Buffer buf; /* the file's content or the body of the .for
* loop; either empty or ends with '\n' */
char *buf_ptr; /* next char to be read */
char *buf_ptr; /* next char to be read from buf */
char *buf_end; /* buf_end[-1] == '\n' */
GuardState guardState;
Guard *guard;
struct ForLoop *forLoop;
} IncludedFile;
@ -315,6 +326,8 @@ static const struct {
enum PosixState posix_state = PS_NOT_YET;
static HashTable /* full file name -> Guard */ guards;
static IncludedFile *
GetInclude(size_t i)
{
@ -429,8 +442,8 @@ IsEscaped(const char *line, const char *p)
}
/*
* Add the filename and lineno to the GNode so that we remember where it
* was first defined.
* Add the filename and lineno to the GNode so that we remember where its
* last command was added or where it was mentioned in a .depend file.
*/
static void
RememberLocation(GNode *gn)
@ -1213,6 +1226,24 @@ FindInQuotPath(const char *file)
return fullname;
}
static bool
SkipGuarded(const char *fullname)
{
Guard *guard = HashTable_FindValue(&guards, fullname);
if (guard != NULL && guard->kind == GK_VARIABLE
&& GNode_ValueDirect(SCOPE_GLOBAL, guard->name) != NULL)
goto skip;
if (guard != NULL && guard->kind == GK_TARGET
&& Targ_FindNode(guard->name) != NULL)
goto skip;
return false;
skip:
DEBUG2(PARSE, "Skipping '%s' because '%s' is defined\n",
fullname, guard->name);
return true;
}
/*
* 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
@ -1247,6 +1278,9 @@ IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
return;
}
if (SkipGuarded(fullname))
return;
if ((fd = open(fullname, O_RDONLY)) == -1) {
if (!silent)
Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
@ -2190,6 +2224,8 @@ Parse_PushInput(const char *name, unsigned lineno, unsigned readLines,
curFile->forBodyReadLines = readLines;
curFile->buf = buf;
curFile->depending = doing_depend; /* restore this on EOF */
curFile->guardState = forLoop == NULL ? GS_START : GS_NO;
curFile->guard = NULL;
curFile->forLoop = forLoop;
if (forLoop != NULL && !For_NextIteration(forLoop, &curFile->buf))
@ -2332,6 +2368,13 @@ ParseEOF(void)
Cond_EndFile();
if (curFile->guardState == GS_DONE)
HashTable_Set(&guards, curFile->name.str, curFile->guard);
else if (curFile->guard != NULL) {
free(curFile->guard->name);
free(curFile->guard);
}
FStr_Done(&curFile->name);
Buf_Done(&curFile->buf);
if (curFile->forLoop != NULL)
@ -2632,8 +2675,10 @@ static char *
ReadHighLevelLine(void)
{
char *line;
CondResult condResult;
for (;;) {
IncludedFile *curFile = CurFile();
line = ReadLowLevelLine(LK_NONEMPTY);
if (posix_state == PS_MAYBE_NEXT_LINE)
posix_state = PS_NOW_OR_NEVER;
@ -2642,10 +2687,24 @@ ReadHighLevelLine(void)
if (line == NULL)
return NULL;
if (curFile->guardState != GS_NO
&& ((curFile->guardState == GS_START && line[0] != '.')
|| curFile->guardState == GS_DONE))
curFile->guardState = GS_NO;
if (line[0] != '.')
return line;
switch (Cond_EvalLine(line)) {
condResult = Cond_EvalLine(line);
if (curFile->guardState == GS_START) {
Guard *guard;
if (condResult != CR_ERROR
&& (guard = Cond_ExtractGuard(line)) != NULL) {
curFile->guardState = GS_COND;
curFile->guard = guard;
} else
curFile->guardState = GS_NO;
}
switch (condResult) {
case CR_FALSE: /* May also mean a syntax error. */
if (!SkipIrrelevantBranches())
return NULL;
@ -2716,10 +2775,14 @@ ParseLine_ShellCommand(const char *p)
}
static void
HandleBreak(void)
HandleBreak(const char *arg)
{
IncludedFile *curFile = CurFile();
if (arg[0] != '\0')
Parse_Error(PARSE_FATAL,
"The .break directive does not take arguments");
if (curFile->forLoop != NULL) {
/* pretend we reached EOF */
For_Break(curFile->forLoop);
@ -2758,7 +2821,7 @@ ParseDirective(char *line)
arg = cp;
if (Substring_Equals(dir, "break"))
HandleBreak();
HandleBreak(arg);
else if (Substring_Equals(dir, "undef"))
Var_Undef(arg);
else if (Substring_Equals(dir, "export"))
@ -2796,6 +2859,23 @@ Parse_VarAssign(const char *line, bool finishDependencyGroup, GNode *scope)
return true;
}
void
Parse_GuardElse(void)
{
IncludedFile *curFile = CurFile();
if (cond_depth == curFile->condMinDepth + 1)
curFile->guardState = GS_NO;
}
void
Parse_GuardEndif(void)
{
IncludedFile *curFile = CurFile();
if (cond_depth == curFile->condMinDepth
&& curFile->guardState == GS_COND)
curFile->guardState = GS_DONE;
}
static char *
FindSemicolon(char *p)
{
@ -2986,6 +3066,7 @@ Parse_Init(void)
sysIncPath = SearchPath_New();
defSysIncPath = SearchPath_New();
Vector_Init(&includes, sizeof(IncludedFile));
HashTable_Init(&guards);
}
/* Clean up the parsing module. */
@ -2993,6 +3074,8 @@ void
Parse_End(void)
{
#ifdef CLEANUP
HashIter hi;
Lst_DoneCall(&targCmds, free);
assert(targets == NULL);
SearchPath_Free(defSysIncPath);
@ -3000,6 +3083,13 @@ Parse_End(void)
SearchPath_Free(parseIncPath);
assert(includes.len == 0);
Vector_Done(&includes);
HashIter_Init(&hi, &guards);
while (HashIter_Next(&hi) != NULL) {
Guard *guard = hi.entry->value;
free(guard->name);
free(guard);
}
HashTable_Done(&guards);
#endif
}

114
str.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: str.c,v 1.94 2022/12/07 10:28:48 rillig Exp $ */
/* $NetBSD: str.c,v 1.99 2023/06/23 05:03:04 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.94 2022/12/07 10:28:48 rillig Exp $");
MAKE_RCSID("$NetBSD: str.c,v 1.99 2023/06/23 05:03:04 rillig Exp $");
static HashTable interned_strings;
@ -316,28 +316,26 @@ in_range(char e1, char c, char e2)
* Test if a string matches a pattern like "*.[ch]". The pattern matching
* characters are '*', '?' and '[]', as in fnmatch(3).
*
* XXX: this function does not detect or report malformed patterns.
*
* See varmod-match.mk for examples and edge cases.
*/
bool
StrMatchResult
Str_Match(const char *str, const char *pat)
{
for (; *pat != '\0'; pat++, str++) {
if (*pat == '*') { /* match any substring */
pat++;
while (*pat == '*')
pat++;
if (*pat == '\0')
return true;
for (; *str != '\0'; str++)
if (Str_Match(str, pat))
return true;
return false;
}
StrMatchResult res = { NULL, false };
const char *fixed_str, *fixed_pat;
bool asterisk, matched;
asterisk = false;
fixed_str = str;
fixed_pat = pat;
match_fixed_length:
str = fixed_str;
pat = fixed_pat;
matched = false;
for (; *pat != '\0' && *pat != '*'; str++, pat++) {
if (*str == '\0')
return false;
return res;
if (*pat == '?') /* match any single character */
continue;
@ -346,25 +344,32 @@ Str_Match(const char *str, const char *pat)
bool neg = pat[1] == '^';
pat += neg ? 2 : 1;
for (;;) {
if (*pat == ']' || *pat == '\0') {
if (neg)
break;
return false;
}
if (*pat == *str)
break;
if (pat[1] == '-') {
if (pat[2] == '\0')
return neg;
if (in_range(pat[0], *str, pat[2]))
break;
pat += 2;
}
pat++;
next_char_in_list:
if (*pat == '\0')
res.error = "Unfinished character list";
if (*pat == ']' || *pat == '\0') {
if (neg)
goto end_of_char_list;
goto match_done;
}
if (*pat == *str)
goto end_of_char_list;
if (pat[1] == '-' && pat[2] == '\0') {
res.error = "Unfinished character range";
res.matched = neg;
return res;
}
if (pat[1] == '-') {
if (in_range(pat[0], *str, pat[2]))
goto end_of_char_list;
pat += 2;
}
pat++;
goto next_char_in_list;
end_of_char_list:
if (neg && *pat != ']' && *pat != '\0')
return false;
goto match_done;
while (*pat != ']' && *pat != '\0')
pat++;
if (*pat == '\0')
@ -374,11 +379,44 @@ Str_Match(const char *str, const char *pat)
if (*pat == '\\') /* match the next character exactly */
pat++;
if (*pat != *str)
return false;
goto match_done;
}
return *str == '\0';
matched = true;
match_done:
if (!asterisk) {
if (!matched)
return res;
if (*pat == '\0') {
res.matched = *str == '\0';
return res;
}
asterisk = true;
} else {
if (!matched) {
fixed_str++;
goto match_fixed_length;
}
if (*pat == '\0') {
if (*str == '\0') {
res.matched = true;
return res;
}
fixed_str += strlen(str);
goto match_fixed_length;
}
}
while (*pat == '*')
pat++;
if (*pat == '\0') {
res.matched = true;
return res;
}
fixed_str = str;
fixed_pat = pat;
goto match_fixed_length;
}
void

9
str.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: str.h,v 1.16 2022/12/05 23:41:24 rillig Exp $ */
/* $NetBSD: str.h,v 1.17 2023/06/23 04:56:54 rillig Exp $ */
/*
Copyright (c) 2021 Roland Illig <rillig@NetBSD.org>
@ -70,6 +70,11 @@ typedef struct SubstringWords {
void *freeIt;
} SubstringWords;
typedef struct StrMatchResult {
const char *error;
bool matched;
} StrMatchResult;
MAKE_INLINE FStr
FStr_Init(const char *str, void *freeIt)
@ -336,7 +341,7 @@ SubstringWords_Free(SubstringWords w)
char *str_concat2(const char *, const char *);
char *str_concat3(const char *, const char *, const char *);
bool Str_Match(const char *, const char *);
StrMatchResult Str_Match(const char *, const char *);
void Str_Intern_Init(void);
void Str_Intern_End(void);

View File

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.195 2023/05/10 18:26:24 sjg Exp $
# $Id: Makefile,v 1.199 2023/06/20 17:27:20 sjg Exp $
#
# $NetBSD: Makefile,v 1.335 2023/05/10 13:03:06 rillig Exp $
# $NetBSD: Makefile,v 1.339 2023/06/20 09:25:34 rillig Exp $
#
# Unit tests for make(1)
#
@ -195,6 +195,7 @@ TESTS+= directive-ifndef
TESTS+= directive-ifnmake
TESTS+= directive-include
TESTS+= directive-include-fatal
TESTS+= directive-include-guard
TESTS+= directive-info
TESTS+= directive-misspellings
TESTS+= directive-sinclude
@ -211,7 +212,6 @@ TESTS+= export
TESTS+= export-all
TESTS+= export-env
TESTS+= export-variants
TESTS+= forsubst
TESTS+= gnode-submake
TESTS+= hanoi-include
TESTS+= impsrc
@ -228,7 +228,6 @@ TESTS+= lint
TESTS+= make-exported
TESTS+= meta-cmd-cmp
TESTS+= moderrs
TESTS+= modmatch
TESTS+= modmisc
.if ${.MAKE.UID} > 0
TESTS+= objdir-writable
@ -424,10 +423,14 @@ TESTS+= varname-dot-make-meta-files
.if ${.MAKE.PATH_FILEMON:Uno:Nktrace:N/dev*} == "" && ${TMPDIR:N/tmp*:N/var/tmp*} != ""
# these tests will not work if TMPDIR is or is a subdir of
# /tmp or /var/tmp
.if ${.MAKE.PATH_FILEMON:N/dev/*} != "" || exists(${.MAKE.PATH_FILEMON})
TESTS+= varname-dot-make-meta-ignore_filter
TESTS+= varname-dot-make-meta-ignore_paths
TESTS+= varname-dot-make-meta-ignore_patterns
TESTS+= varname-dot-make-path_filemon
.else
.warning Skipping tests that require ${.MAKE.PATH_FILEMON}
.endif
.endif
TESTS+= varname-dot-make-meta-prefix
TESTS+= varname-dot-make-mode
@ -538,6 +541,12 @@ FLAGS.varname-empty= -dv '$${:U}=cmdline-u' '=cmdline-plain'
# Some tests need extra postprocessing.
SED_CMDS.deptgt-phony= ${STD_SED_CMDS.dd}
SED_CMDS.dir= ${STD_SED_CMDS.dd}
SED_CMDS.directive-include-guard= \
-e '/\.MAKEFLAGS/d' \
-e '/^Parsing line/d' \
-e '/^SetFilenameVars:/d' \
-e '/^ParseDependency/d' \
-e '/^ParseEOF:/d'
SED_CMDS.export= -e '/^[^=_A-Za-z0-9]*=/d'
SED_CMDS.export-all= ${SED_CMDS.export}
SED_CMDS.export-env= ${SED_CMDS.export}

View File

@ -1,17 +1,17 @@
The = assignment operator
make: "cmdline-undefined.mk" line 29: From the command line: Undefined is .
make: "cmdline-undefined.mk" line 30: From .MAKEFLAGS '=': Undefined is .
make: "cmdline-undefined.mk" line 31: From .MAKEFLAGS ':=': Undefined is .
make: "cmdline-undefined.mk" line 35: From the command line: Undefined is now defined.
make: "cmdline-undefined.mk" line 36: From .MAKEFLAGS '=': Undefined is now defined.
make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is now defined.
make: "cmdline-undefined.mk" line 31: From the command line: Undefined is .
make: "cmdline-undefined.mk" line 34: From .MAKEFLAGS '=': Undefined is .
make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is .
make: "cmdline-undefined.mk" line 43: From the command line: Undefined is now defined.
make: "cmdline-undefined.mk" line 46: From .MAKEFLAGS '=': Undefined is now defined.
make: "cmdline-undefined.mk" line 49: From .MAKEFLAGS ':=': Undefined is now defined.
The := assignment operator
make: "cmdline-undefined.mk" line 29: From the command line: Undefined is .
make: "cmdline-undefined.mk" line 30: From .MAKEFLAGS '=': Undefined is .
make: "cmdline-undefined.mk" line 31: From .MAKEFLAGS ':=': Undefined is .
make: "cmdline-undefined.mk" line 35: From the command line: Undefined is now defined.
make: "cmdline-undefined.mk" line 36: From .MAKEFLAGS '=': Undefined is now defined.
make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is now defined.
make: "cmdline-undefined.mk" line 31: From the command line: Undefined is .
make: "cmdline-undefined.mk" line 34: From .MAKEFLAGS '=': Undefined is .
make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is .
make: "cmdline-undefined.mk" line 43: From the command line: Undefined is now defined.
make: "cmdline-undefined.mk" line 46: From .MAKEFLAGS '=': Undefined is now defined.
make: "cmdline-undefined.mk" line 49: From .MAKEFLAGS ':=': Undefined is now defined.
exit status 0

View File

@ -1,4 +1,4 @@
# $NetBSD: cmdline-undefined.mk,v 1.2 2020/11/04 04:49:33 rillig Exp $
# $NetBSD: cmdline-undefined.mk,v 1.3 2023/06/01 20:56:35 rillig Exp $
#
# Tests for undefined variable expressions in the command line.
@ -26,14 +26,26 @@ all:
.MAKEFLAGS: MAKEFLAGS_ASSIGN='Undefined is $${UNDEFINED}.'
.MAKEFLAGS: MAKEFLAGS_SUBST:='Undefined is $${UNDEFINED}.'
# expect+2: From the command line: Undefined is .
# expect+1: From the command line: Undefined is .
.info From the command line: ${CMDLINE}
# expect+2: From .MAKEFLAGS '=': Undefined is .
# expect+1: From .MAKEFLAGS '=': Undefined is .
.info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN}
# expect+2: From .MAKEFLAGS ':=': Undefined is .
# expect+1: From .MAKEFLAGS ':=': Undefined is .
.info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST}
UNDEFINED?= now defined
# expect+2: From the command line: Undefined is now defined.
# expect+1: From the command line: Undefined is now defined.
.info From the command line: ${CMDLINE}
# expect+2: From .MAKEFLAGS '=': Undefined is now defined.
# expect+1: From .MAKEFLAGS '=': Undefined is now defined.
.info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN}
# expect+2: From .MAKEFLAGS ':=': Undefined is now defined.
# expect+1: From .MAKEFLAGS ':=': Undefined is now defined.
.info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST}
print-undefined:

View File

@ -1,5 +1,5 @@
make: "cond-cmp-numeric-eq.mk" line 67: Malformed conditional (!(12345 = 12345))
make: "cond-cmp-numeric-eq.mk" line 74: Malformed conditional (!(12345 === 12345))
make: "cond-cmp-numeric-eq.mk" line 68: Malformed conditional (!(12345 = 12345))
make: "cond-cmp-numeric-eq.mk" line 76: Malformed conditional (!(12345 === 12345))
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-eq.mk,v 1.5 2020/11/08 21:47:59 rillig Exp $
# $NetBSD: cond-cmp-numeric-eq.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for numeric comparisons with the == operator in .if conditions.
@ -64,6 +64,7 @@
.endif
# There is no = operator for numbers.
# expect+1: Malformed conditional (!(12345 = 12345))
.if !(12345 = 12345)
. error
.else
@ -71,6 +72,7 @@
.endif
# There is no === operator for numbers either.
# expect+1: Malformed conditional (!(12345 === 12345))
.if !(12345 === 12345)
. error
.else

View File

@ -1,2 +1,2 @@
make: "cond-cmp-unary.mk" line 53: This is only reached because of a bug in EvalNotEmpty.
make: "cond-cmp-unary.mk" line 54: This is only reached because of a bug in EvalTruthy.
exit status 0

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-unary.mk,v 1.3 2022/09/08 05:43:20 rillig Exp $
# $NetBSD: cond-cmp-unary.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for unary comparisons in .if conditions, that is, comparisons with
# a single operand. If the operand is a number, it is compared to zero,
@ -26,8 +26,8 @@
# The empty string may come from a variable expression.
#
# XXX: As of 2020-11-11, this empty string is interpreted "as a number" in
# EvalNotEmpty, which is plain wrong. The bug is in TryParseNumber.
# XXX: As of 2023-06-01, this empty string is interpreted "as a number" in
# EvalTruthy, which is plain wrong. The bug is in TryParseNumber.
.if ${:U}
. error
.endif
@ -45,12 +45,13 @@
# A string of whitespace should evaluate to false.
#
# XXX: As of 2020-11-11, the implementation in EvalNotEmpty does not skip
# XXX: As of 2023-06-01, the implementation in EvalTruthy does not skip
# whitespace before testing for the end. This was probably an oversight in
# a commit from 1992-04-15 saying "A variable is empty when it just contains
# spaces".
.if ${:U }
. info This is only reached because of a bug in EvalNotEmpty.
# expect+1: This is only reached because of a bug in EvalTruthy.
. info This is only reached because of a bug in EvalTruthy.
.else
. error
.endif

View File

@ -1,6 +1,6 @@
make: "cond-eof.mk" line 15: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
make: "cond-eof.mk" line 17: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
make: "cond-eof.mk" line 19: Malformed conditional ((0) ${SIDE_EFFECT} ${SIDE_EFFECT2})
make: "cond-eof.mk" line 17: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
make: "cond-eof.mk" line 20: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
make: "cond-eof.mk" line 23: Malformed conditional ((0) ${SIDE_EFFECT} ${SIDE_EFFECT2})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,7 +1,8 @@
# $NetBSD: cond-eof.mk,v 1.3 2021/12/10 23:12:44 rillig Exp $
# $NetBSD: cond-eof.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for parsing conditions, especially the end of such conditions, which
# are represented as the token TOK_EOF.
# Tests for parsing the end of '.if' conditions, which are represented as the
# token TOK_EOF.
SIDE_EFFECT= ${:!echo 'side effect' 1>&2!}
SIDE_EFFECT2= ${:!echo 'side effect 2' 1>&2!}
@ -12,9 +13,12 @@ SIDE_EFFECT2= ${:!echo 'side effect 2' 1>&2!}
# These syntax errors are an edge case that does not occur during normal
# operation. Still, it is easy to avoid evaluating these expressions, just in
# case they have side effects.
# expect+1: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
.if 0 ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
# expect+1: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
.if 1 ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif
# expect+1: Malformed conditional ((0) ${SIDE_EFFECT} ${SIDE_EFFECT2})
.if (0) ${SIDE_EFFECT} ${SIDE_EFFECT2}
.endif

View File

@ -1,8 +1,8 @@
make: "cond-func-defined.mk" line 23: Missing closing parenthesis for defined()
make: "cond-func-defined.mk" line 33: Missing closing parenthesis for defined()
make: "cond-func-defined.mk" line 45: In .for loops, variable expressions for the loop variables are
make: "cond-func-defined.mk" line 46: substituted at evaluation time. There is no actual variable
make: "cond-func-defined.mk" line 47: involved, even if it feels like it.
make: "cond-func-defined.mk" line 24: Missing closing parenthesis for defined()
make: "cond-func-defined.mk" line 34: Missing closing parenthesis for defined()
make: "cond-func-defined.mk" line 47: In .for loops, variable expressions for the loop variables are
make: "cond-func-defined.mk" line 49: substituted at evaluation time. There is no actual variable
make: "cond-func-defined.mk" line 51: involved, even if it feels like it.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-func-defined.mk,v 1.9 2022/05/08 06:51:27 rillig Exp $
# $NetBSD: cond-func-defined.mk,v 1.10 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the defined() function in .if conditions.
@ -20,6 +20,7 @@ ${:UA B}= variable name with spaces
.endif
# The argument of a function must not directly contain whitespace.
# expect+1: Missing closing parenthesis for defined()
.if !defined(A B)
. error
.endif
@ -29,7 +30,7 @@ ${:UA B}= variable name with spaces
. error
.endif
# Parse error: missing closing parenthesis; see ParseWord.
# expect+1: Missing closing parenthesis for defined()
.if defined(DEF
. error
.else
@ -42,8 +43,11 @@ ${:UA B}= variable name with spaces
. if defined(var)
. error
. else
# expect+1: In .for loops, variable expressions for the loop variables are
. info In .for loops, variable expressions for the loop variables are
# expect+1: substituted at evaluation time. There is no actual variable
. info substituted at evaluation time. There is no actual variable
# expect+1: involved, even if it feels like it.
. info involved, even if it feels like it.
. endif
.endfor

View File

@ -1,5 +1,5 @@
make: "cond-func-empty.mk" line 153: Unclosed variable "WORD"
make: "cond-func-empty.mk" line 153: Malformed conditional (empty(WORD)
make: "cond-func-empty.mk" line 154: Unclosed variable "WORD"
make: "cond-func-empty.mk" line 154: Malformed conditional (empty(WORD)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-func-empty.mk,v 1.18 2023/03/04 21:15:30 rillig Exp $
# $NetBSD: cond-func-empty.mk,v 1.20 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the empty() function in .if conditions, which tests a variable
# expression for emptiness.
@ -25,7 +25,7 @@ WORD= word
.endif
# The :S modifier replaces the empty value with an actual word. After
# applying the :S modifier to the expression, it value is 'empty', so it is
# applying the :S modifier to the expression, its value is 'empty', so it is
# no longer empty, but it is still based on an undefined variable. There are
# a few modifiers that turn an undefined expression into a defined expression,
# among them :U and :D, but not :S. Therefore, at the end of evaluating the
@ -149,7 +149,8 @@ ${:U WORD }= variable name with spaces
. error
.endif
# Parse error: missing closing parenthesis.
# expect+2: Unclosed variable "WORD"
# expect+1: Malformed conditional (empty(WORD)
.if empty(WORD
. error
.else

View File

@ -1,3 +1,4 @@
make: "cond-func-make.mk" line 24: warning: Unfinished character list in pattern argument '[' to function 'make'
: via-cmdline
: via-dot-makeflags
exit status 0

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-func-make.mk,v 1.3 2020/09/25 20:11:06 rillig Exp $
# $NetBSD: cond-func-make.mk,v 1.5 2023/06/23 04:56:54 rillig Exp $
#
# Tests for the make() function in .if conditions, which tests whether
# the argument has been passed as a target via the command line or later
@ -20,5 +20,10 @@
. error
.endif
# expect+1: warning: Unfinished character list in pattern argument '[' to function 'make'
.if make([)
. error
.endif
via-cmdline via-dot-makeflags:
: $@

View File

@ -1,12 +1,12 @@
make: "cond-func.mk" line 36: Missing closing parenthesis for defined()
make: "cond-func.mk" line 51: Missing closing parenthesis for defined()
make: "cond-func.mk" line 54: Missing closing parenthesis for defined()
make: "cond-func.mk" line 94: The empty variable is never defined.
make: "cond-func.mk" line 103: A plain function name is parsed as defined(...).
make: "cond-func.mk" line 110: A plain function name is parsed as defined(...).
make: "cond-func.mk" line 120: Symbols may start with a function name.
make: "cond-func.mk" line 125: Symbols may start with a function name.
make: "cond-func.mk" line 131: Missing closing parenthesis for defined()
make: "cond-func.mk" line 37: Missing closing parenthesis for defined()
make: "cond-func.mk" line 53: Missing closing parenthesis for defined()
make: "cond-func.mk" line 57: Missing closing parenthesis for defined()
make: "cond-func.mk" line 98: The empty variable is never defined.
make: "cond-func.mk" line 108: A plain function name is parsed as defined(...).
make: "cond-func.mk" line 116: A plain function name is parsed as defined(...).
make: "cond-func.mk" line 127: Symbols may start with a function name.
make: "cond-func.mk" line 133: Symbols may start with a function name.
make: "cond-func.mk" line 139: Missing closing parenthesis for defined()
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-func.mk,v 1.12 2023/05/10 15:53:32 rillig Exp $
# $NetBSD: cond-func.mk,v 1.13 2023/06/01 20:56:35 rillig Exp $
#
# Tests for those parts of the functions in .if conditions that are common
# among several functions.
@ -33,6 +33,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
.endif
# The argument of a function must not directly contain whitespace.
# expect+1: Missing closing parenthesis for defined()
.if !defined(A B)
. error
.endif
@ -48,9 +49,11 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
#
# It's not entirely clear why these characters are forbidden.
# The most plausible reason seems to be typo detection.
# expect+1: Missing closing parenthesis for defined()
.if !defined(A&B)
. error
.endif
# expect+1: Missing closing parenthesis for defined()
.if !defined(A|B)
. error
.endif
@ -91,6 +94,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
.if defined()
. error
.else
# expect+1: The empty variable is never defined.
. info The empty variable is never defined.
.endif
@ -100,6 +104,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
.if defined
. error
.else
# expect+1: A plain function name is parsed as defined(...).
. info A plain function name is parsed as defined(...).
.endif
@ -107,6 +112,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces
# is interpreted as 'defined(defined)', and the condition evaluates to true.
defined= # defined but empty
.if defined
# expect+1: A plain function name is parsed as defined(...).
. info A plain function name is parsed as defined(...).
.else
. error
@ -117,17 +123,19 @@ defined= # defined but empty
.if defined-var
. error
.else
# expect+1: Symbols may start with a function name.
. info Symbols may start with a function name.
.endif
defined-var= # defined but empty
.if defined-var
# expect+1: Symbols may start with a function name.
. info Symbols may start with a function name.
.else
. error
.endif
# Missing closing parenthesis when parsing the function argument.
# expect+1: Missing closing parenthesis for defined()
.if defined(
. error
.else

View File

@ -1,4 +1,4 @@
make: "cond-op-and-lint.mk" line 9: Unknown operator '&'
make: "cond-op-and-lint.mk" line 10: Unknown operator '&'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op-and-lint.mk,v 1.1 2020/11/08 23:54:28 rillig Exp $
# $NetBSD: cond-op-and-lint.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the && operator in .if conditions, in lint mode.
@ -6,6 +6,7 @@
# The '&' operator is not allowed in lint mode.
# It is not used in practice anyway.
# expect+1: Unknown operator '&'
.if 0 & 0
. error
.else

View File

@ -1,7 +1,7 @@
make: "cond-op-and.mk" line 36: Malformed conditional (0 || (${DEF} && ${UNDEF}))
make: "cond-op-and.mk" line 40: Malformed conditional (0 || (${UNDEF} && ${UNDEF}))
make: "cond-op-and.mk" line 42: Malformed conditional (0 || (!${UNDEF} && ${UNDEF}))
make: "cond-op-and.mk" line 71: Malformed conditional (0 &&& 0)
make: "cond-op-and.mk" line 37: Malformed conditional (0 || (${DEF} && ${UNDEF}))
make: "cond-op-and.mk" line 42: Malformed conditional (0 || (${UNDEF} && ${UNDEF}))
make: "cond-op-and.mk" line 45: Malformed conditional (0 || (!${UNDEF} && ${UNDEF}))
make: "cond-op-and.mk" line 75: Malformed conditional (0 &&& 0)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op-and.mk,v 1.6 2021/12/10 19:14:35 rillig Exp $
# $NetBSD: cond-op-and.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the && operator in .if conditions.
@ -33,12 +33,15 @@
# Test combinations of outer '||' with inner '&&', to ensure that the operands
# of the inner '&&' are only evaluated if necessary.
DEF= defined
# expect+1: Malformed conditional (0 || (${DEF} && ${UNDEF})
.if 0 || (${DEF} && ${UNDEF})
.endif
.if 0 || (!${DEF} && ${UNDEF})
.endif
# expect+1: Malformed conditional (0 || (${UNDEF} && ${UNDEF})
.if 0 || (${UNDEF} && ${UNDEF})
.endif
# expect+1: Malformed conditional (0 || (!${UNDEF} && ${UNDEF})
.if 0 || (!${UNDEF} && ${UNDEF})
.endif
.if 1 || (${DEF} && ${UNDEF})
@ -68,6 +71,7 @@ DEF= defined
.endif
# There is no operator &&&.
# expect+1: Malformed conditional (0 &&& 0)
.if 0 &&& 0
. error
.endif

View File

@ -1,9 +1,9 @@
make: "cond-op-not.mk" line 29: Not empty evaluates to true.
make: "cond-op-not.mk" line 37: Not space evaluates to false.
make: "cond-op-not.mk" line 41: Not 0 evaluates to true.
make: "cond-op-not.mk" line 49: Not 1 evaluates to false.
make: "cond-op-not.mk" line 55: Not word evaluates to false.
make: "cond-op-not.mk" line 59: Malformed conditional (!)
make: "cond-op-not.mk" line 30: Not empty evaluates to true.
make: "cond-op-not.mk" line 39: Not space evaluates to false.
make: "cond-op-not.mk" line 44: Not 0 evaluates to true.
make: "cond-op-not.mk" line 53: Not 1 evaluates to false.
make: "cond-op-not.mk" line 60: Not word evaluates to false.
make: "cond-op-not.mk" line 65: Malformed conditional (!)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op-not.mk,v 1.7 2021/01/19 17:49:13 rillig Exp $
# $NetBSD: cond-op-not.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the ! operator in .if conditions, which negates its argument.
@ -26,6 +26,7 @@
.endif
.if !${:U}
# expect+1: Not empty evaluates to true.
. info Not empty evaluates to true.
.else
. info Not empty evaluates to false.
@ -34,10 +35,12 @@
.if !${:U }
. info Not space evaluates to true.
.else
# expect+1: Not space evaluates to false.
. info Not space evaluates to false.
.endif
.if !${:U0}
# expect+1: Not 0 evaluates to true.
. info Not 0 evaluates to true.
.else
. info Not 0 evaluates to false.
@ -46,16 +49,19 @@
.if !${:U1}
. info Not 1 evaluates to true.
.else
# expect+1: Not 1 evaluates to false.
. info Not 1 evaluates to false.
.endif
.if !${:Uword}
. info Not word evaluates to true.
.else
# expect+1: Not word evaluates to false.
. info Not word evaluates to false.
.endif
# A single exclamation mark is a parse error.
# expect+1: Malformed conditional (!)
.if !
. error
.else

View File

@ -1,4 +1,4 @@
make: "cond-op-or-lint.mk" line 9: Unknown operator '|'
make: "cond-op-or-lint.mk" line 10: Unknown operator '|'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op-or-lint.mk,v 1.1 2020/11/08 23:54:28 rillig Exp $
# $NetBSD: cond-op-or-lint.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the || operator in .if conditions, in lint mode.
@ -6,6 +6,7 @@
# The '|' operator is not allowed in lint mode.
# It is not used in practice anyway.
# expect+1: Unknown operator '|'
.if 0 | 0
. error
.else

View File

@ -1,7 +1,7 @@
make: "cond-op-or.mk" line 46: Malformed conditional (1 && (!${DEF} || ${UNDEF}))
make: "cond-op-or.mk" line 48: Malformed conditional (1 && (${UNDEF} || ${UNDEF}))
make: "cond-op-or.mk" line 50: Malformed conditional (1 && (!${UNDEF} || ${UNDEF}))
make: "cond-op-or.mk" line 71: Malformed conditional (0 ||| 0)
make: "cond-op-or.mk" line 47: Malformed conditional (1 && (!${DEF} || ${UNDEF}))
make: "cond-op-or.mk" line 50: Malformed conditional (1 && (${UNDEF} || ${UNDEF}))
make: "cond-op-or.mk" line 53: Malformed conditional (1 && (!${UNDEF} || ${UNDEF}))
make: "cond-op-or.mk" line 75: Malformed conditional (0 ||| 0)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op-or.mk,v 1.8 2021/12/10 19:14:35 rillig Exp $
# $NetBSD: cond-op-or.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the || operator in .if conditions.
@ -43,10 +43,13 @@ DEF= defined
.endif
.if 1 && (${DEF} || ${UNDEF})
.endif
# expect+1: Malformed conditional (1 && (!${DEF} || ${UNDEF})
.if 1 && (!${DEF} || ${UNDEF})
.endif
# expect+1: Malformed conditional (1 && (${UNDEF} || ${UNDEF})
.if 1 && (${UNDEF} || ${UNDEF})
.endif
# expect+1: Malformed conditional (1 && (!${UNDEF} || ${UNDEF})
.if 1 && (!${UNDEF} || ${UNDEF})
.endif
@ -68,6 +71,7 @@ DEF= defined
.endif
# There is no operator |||.
# expect+1: Malformed conditional (0 ||| 0)
.if 0 ||| 0
. error
.endif

View File

@ -1,7 +1,7 @@
make: "cond-op-parentheses.mk" line 22: Comparison with '>' requires both operands '3' and '(2' to be numeric
make: "cond-op-parentheses.mk" line 25: Malformed conditional ((3) > 2)
make: "cond-op-parentheses.mk" line 43: Malformed conditional (()
make: "cond-op-parentheses.mk" line 56: Malformed conditional ())
make: "cond-op-parentheses.mk" line 44: Malformed conditional (()
make: "cond-op-parentheses.mk" line 58: Malformed conditional ())
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op-parentheses.mk,v 1.6 2022/09/04 22:55:00 rillig Exp $
# $NetBSD: cond-op-parentheses.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for parentheses in .if conditions, which group expressions to override
# the precedence of the operators '!', '&&' and '||'. Parentheses cannot be
@ -40,6 +40,7 @@
.endif
# An unbalanced opening parenthesis is a parse error.
# expect+1: Malformed conditional (()
.if (
. error
.else
@ -53,6 +54,7 @@
# TOK_TRUE, TOK_FALSE or TOK_ERROR. In cond.c 1.241, the return type of that
# function was changed to a properly restricted enum type, to prevent this bug
# from occurring again.
# expect+1: Malformed conditional ())
.if )
. error
.else

View File

@ -1,22 +1,21 @@
make: "cond-op.mk" line 50: Malformed conditional ("!word" == !word)
make: "cond-op.mk" line 76: Malformed conditional (0 ${ERR::=evaluated})
make: "cond-op.mk" line 80: A misplaced expression after 0 is not evaluated.
make: "cond-op.mk" line 84: Malformed conditional (1 ${ERR::=evaluated})
make: "cond-op.mk" line 88: A misplaced expression after 1 is not evaluated.
make: "cond-op.mk" line 92: Parsing continues until here.
make: "cond-op.mk" line 95: A B C => (A || B) && C A || B && C A || (B && C)
make: "cond-op.mk" line 102: 0 0 0 => 0 0 0
make: "cond-op.mk" line 102: 0 0 1 => 0 0 0
make: "cond-op.mk" line 102: 0 1 0 => 0 0 0
make: "cond-op.mk" line 102: 0 1 1 => 1 1 1
make: "cond-op.mk" line 102: 1 0 0 => 0 1 1
make: "cond-op.mk" line 102: 1 0 1 => 1 1 1
make: "cond-op.mk" line 102: 1 1 0 => 0 1 1
make: "cond-op.mk" line 102: 1 1 1 => 1 1 1
make: "cond-op.mk" line 113: Malformed conditional (1 &&)
make: "cond-op.mk" line 121: Malformed conditional (0 &&)
make: "cond-op.mk" line 129: Malformed conditional (1 ||)
make: "cond-op.mk" line 138: Malformed conditional (0 ||)
make: "cond-op.mk" line 51: Malformed conditional ("!word" == !word)
make: "cond-op.mk" line 72: Malformed conditional (0 ${ERR::=evaluated})
make: "cond-op.mk" line 77: A misplaced expression after 0 is not evaluated.
make: "cond-op.mk" line 82: Malformed conditional (1 ${ERR::=evaluated})
make: "cond-op.mk" line 87: A misplaced expression after 1 is not evaluated.
make: "cond-op.mk" line 93: A B C => (A || B) && C A || B && C A || (B && C)
make: "cond-op.mk" line 108: 0 0 0 => 0 0 0
make: "cond-op.mk" line 108: 0 0 1 => 0 0 0
make: "cond-op.mk" line 108: 0 1 0 => 0 0 0
make: "cond-op.mk" line 108: 0 1 1 => 1 1 1
make: "cond-op.mk" line 108: 1 0 0 => 0 1 1
make: "cond-op.mk" line 108: 1 0 1 => 1 1 1
make: "cond-op.mk" line 108: 1 1 0 => 0 1 1
make: "cond-op.mk" line 108: 1 1 1 => 1 1 1
make: "cond-op.mk" line 120: Malformed conditional (1 &&)
make: "cond-op.mk" line 129: Malformed conditional (0 &&)
make: "cond-op.mk" line 138: Malformed conditional (1 ||)
make: "cond-op.mk" line 148: Malformed conditional (0 ||)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-op.mk,v 1.15 2021/12/10 23:12:44 rillig Exp $
# $NetBSD: cond-op.mk,v 1.16 2023/06/01 20:56:35 rillig Exp $
#
# Tests for operators like &&, ||, ! in .if conditions.
#
@ -47,6 +47,7 @@
# appear unquoted. If any, it must be enclosed in quotes.
# In any case, it is not interpreted as a negation of an unquoted string.
# See CondParser_String.
# expect+1: Malformed conditional ("!word" == !word)
.if "!word" == !word
. error
.endif
@ -66,32 +67,29 @@
# nevertheless, since CondParser_Or and CondParser_And asked for the expanded
# next token, even though in this position of the condition, only comparison
# operators, TOK_AND, TOK_OR or TOK_RPAREN are allowed.
#
#
#
#
#
#
.undef ERR
# expect+1: Malformed conditional (0 ${ERR::=evaluated})
.if 0 ${ERR::=evaluated}
. error
.endif
.if ${ERR:Uundefined} == undefined
# expect+1: A misplaced expression after 0 is not evaluated.
. info A misplaced expression after 0 is not evaluated.
.endif
.undef ERR
# expect+1: Malformed conditional (1 ${ERR::=evaluated})
.if 1 ${ERR::=evaluated}
. error
.endif
.if ${ERR:Uundefined} == undefined
# expect+1: A misplaced expression after 1 is not evaluated.
. info A misplaced expression after 1 is not evaluated.
.endif
# Just in case that parsing should ever stop on the first error.
.info Parsing continues until here.
# Demonstration that '&&' has higher precedence than '||'.
# expect+1: A B C => (A || B) && C A || B && C A || (B && C)
.info A B C => (A || B) && C A || B && C A || (B && C)
.for a in 0 1
. for b in 0 1
@ -99,6 +97,14 @@
. for r1 in ${ ($a || $b) && $c :?1:0}
. for r2 in ${ $a || $b && $c :?1:0}
. for r3 in ${ $a || ($b && $c) :?1:0}
# expect+8: 0 0 0 => 0 0 0
# expect+7: 0 0 1 => 0 0 0
# expect+6: 0 1 0 => 0 0 0
# expect+5: 0 1 1 => 1 1 1
# expect+4: 1 0 0 => 0 1 1
# expect+3: 1 0 1 => 1 1 1
# expect+2: 1 1 0 => 0 1 1
# expect+1: 1 1 1 => 1 1 1
. info $a $b $c => ${r1} ${r2} ${r3}
. endfor
. endfor
@ -110,6 +116,7 @@
# This condition is obviously malformed. It is properly detected and also
# was properly detected before 2021-01-19, but only because the left hand
# side of the '&&' evaluated to true.
# expect+1: Malformed conditional (1 &&)
.if 1 &&
. error
.else
@ -118,6 +125,7 @@
# This obviously malformed condition was not detected as such before cond.c
# 1.238 from 2021-01-19.
# expect+1: Malformed conditional (0 &&)
.if 0 &&
. error
.else
@ -126,6 +134,7 @@
# This obviously malformed condition was not detected as such before cond.c
# 1.238 from 2021-01-19.
# expect+1: Malformed conditional (1 ||)
.if 1 ||
. error
.else
@ -135,6 +144,7 @@
# This condition is obviously malformed. It is properly detected and also
# was properly detected before 2021-01-19, but only because the left hand
# side of the '||' evaluated to false.
# expect+1: Malformed conditional (0 ||)
.if 0 ||
. error
.else

View File

@ -1,7 +1,7 @@
make: "cond-token-number.mk" line 15: Malformed conditional (-0)
make: "cond-token-number.mk" line 25: Malformed conditional (+0)
make: "cond-token-number.mk" line 35: Malformed conditional (!-1)
make: "cond-token-number.mk" line 45: Malformed conditional (!+1)
make: "cond-token-number.mk" line 16: Malformed conditional (-0)
make: "cond-token-number.mk" line 27: Malformed conditional (+0)
make: "cond-token-number.mk" line 38: Malformed conditional (!-1)
make: "cond-token-number.mk" line 49: Malformed conditional (!+1)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-token-number.mk,v 1.8 2023/03/04 08:07:29 rillig Exp $
# $NetBSD: cond-token-number.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
#
# Tests for number tokens in .if conditions.
#
@ -12,6 +12,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
# expect+1: Malformed conditional (-0)
.if -0
. error
.else
@ -22,6 +23,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
# expect+1: Malformed conditional (+0)
.if +0
. error
.else
@ -32,6 +34,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
# expect+1: Malformed conditional (!-1)
.if !-1
. error
.else
@ -42,6 +45,7 @@
# accepted by the condition parser.
#
# See the ch_isdigit call in CondParser_String.
# expect+1: Malformed conditional (!+1)
.if !+1
. error
.else

View File

@ -27,37 +27,37 @@ Comparing "var&&name" != "var&&name"
CondParser_Eval: ${:Uvar}||name != "var||name"
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.
make: "cond-token-plain.mk" line 106: A bare word is treated like defined(...), and the variable 'bare' is not defined.
CondParser_Eval: VAR
make: "cond-token-plain.mk" line 111: A bare word is treated like defined(...).
make: "cond-token-plain.mk" line 113: A bare word is treated like defined(...).
CondParser_Eval: V${:UA}R
make: "cond-token-plain.mk" line 118: ok
make: "cond-token-plain.mk" line 121: ok
CondParser_Eval: V${UNDEF}AR
make: "cond-token-plain.mk" line 126: Undefined variables in bare words expand to an empty string.
make: "cond-token-plain.mk" line 130: Undefined variables in bare words expand to an empty string.
CondParser_Eval: 0${:Ux00}
make: "cond-token-plain.mk" line 134: Numbers can be composed from literals and variable expressions.
make: "cond-token-plain.mk" line 139: Numbers can be composed from literals and variable expressions.
CondParser_Eval: 0${:Ux01}
make: "cond-token-plain.mk" line 138: Numbers can be composed from literals and variable expressions.
make: "cond-token-plain.mk" line 144: Numbers can be composed from literals and variable expressions.
CondParser_Eval: "" ==
make: "cond-token-plain.mk" line 144: Missing right-hand side of operator '=='
make: "cond-token-plain.mk" line 151: Missing right-hand side of operator '=='
CondParser_Eval: == ""
make: "cond-token-plain.mk" line 152: Malformed conditional (== "")
make: "cond-token-plain.mk" line 160: Malformed conditional (== "")
CondParser_Eval: \\
make: "cond-token-plain.mk" line 167: The variable '\\' is not defined.
make: "cond-token-plain.mk" line 176: The variable '\\' is not defined.
CondParser_Eval: \\
make: "cond-token-plain.mk" line 172: Now the variable '\\' is defined.
make: "cond-token-plain.mk" line 182: Now the variable '\\' is defined.
CondParser_Eval: "unquoted\"quoted" != unquoted"quoted
Comparing "unquoted"quoted" != "unquoted"quoted"
CondParser_Eval: $$$$$$$$ != ""
make: "cond-token-plain.mk" line 186: Malformed conditional ($$$$$$$$ != "")
make: "cond-token-plain.mk" line 197: Malformed conditional ($$$$$$$$ != "")
CondParser_Eval: left == right
make: "cond-token-plain.mk" line 195: Malformed conditional (left == right)
make: "cond-token-plain.mk" line 206: Malformed conditional (left == right)
CondParser_Eval: ${0:?:} || left == right
CondParser_Eval: 0
make: "cond-token-plain.mk" line 201: Malformed conditional (${0:?:} || left == right)
make: "cond-token-plain.mk" line 212: Malformed conditional (${0:?:} || left == right)
CondParser_Eval: left == right || ${0:?:}
make: "cond-token-plain.mk" line 206: Malformed conditional (left == right || ${0:?:})
make: "cond-token-plain.mk" line 225: Malformed conditional (VAR.${IF_COUNT::+=1} != "")
make: "cond-token-plain.mk" line 217: Malformed conditional (left == right || ${0:?:})
make: "cond-token-plain.mk" line 236: Malformed conditional (VAR.${IF_COUNT::+=1} != "")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-token-plain.mk,v 1.17 2023/02/14 20:49:09 rillig Exp $
# $NetBSD: cond-token-plain.mk,v 1.18 2023/06/01 20:56:35 rillig Exp $
#
# Tests for plain tokens (that is, string literals without quotes)
# in .if conditions. These are also called bare words.
@ -102,12 +102,14 @@
.if bare
. error
.else
# expect+1: A bare word is treated like defined(...), and the variable 'bare' is not defined.
. info A bare word is treated like defined(...), and the variable $\
'bare' is not defined.
.endif
VAR= defined
.if VAR
# expect+1: A bare word is treated like defined(...).
. info A bare word is treated like defined(...).
.else
. error
@ -115,6 +117,7 @@ VAR= defined
# Bare words may be intermixed with variable expressions.
.if V${:UA}R
# expect+1: ok
. info ok
.else
. error
@ -123,6 +126,7 @@ VAR= defined
# In bare words, even undefined variables are allowed. Without the bare
# words, undefined variables are not allowed. That feels inconsistent.
.if V${UNDEF}AR
# expect+1: Undefined variables in bare words expand to an empty string.
. info Undefined variables in bare words expand to an empty string.
.else
. error
@ -131,16 +135,19 @@ VAR= defined
.if 0${:Ux00}
. error
.else
# expect+1: Numbers can be composed from literals and variable expressions.
. info Numbers can be composed from literals and variable expressions.
.endif
.if 0${:Ux01}
# expect+1: Numbers can be composed from literals and variable expressions.
. info Numbers can be composed from literals and variable expressions.
.else
. error
.endif
# If the right-hand side is missing, it's a parse error.
# expect+1: Missing right-hand side of operator '=='
.if "" ==
. error
.else
@ -149,6 +156,7 @@ VAR= defined
# If the left-hand side is missing, it's a parse error as well, but without
# a specific error message.
# expect+1: Malformed conditional (== "")
.if == ""
. error
.else
@ -164,11 +172,13 @@ VAR= defined
.if \\
. error
.else
# expect+1: The variable '\\' is not defined.
. info The variable '\\' is not defined.
.endif
${:U\\\\}= backslash
.if \\
# expect+1: Now the variable '\\' is defined.
. info Now the variable '\\' is defined.
.else
. error
@ -183,6 +193,7 @@ ${:U\\\\}= backslash
# FIXME: In CondParser_String, Var_Parse returns var_Error without a
# corresponding error message.
# expect+1: Malformed conditional ($$$$$$$$ != "")
.if $$$$$$$$ != ""
. error
.else

View File

@ -1,18 +1,18 @@
make: "cond-token-string.mk" line 13: Unknown modifier "Z"
make: "cond-token-string.mk" line 13: Malformed conditional ("" != "${:Uvalue:Z}")
make: "cond-token-string.mk" line 22: xvalue is not defined.
make: "cond-token-string.mk" line 28: Malformed conditional (x${:Uvalue} == "")
make: "cond-token-string.mk" line 37: Expected.
make: "cond-token-string.mk" line 15: Unknown modifier "Z"
make: "cond-token-string.mk" line 15: Malformed conditional ("" != "${:Uvalue:Z}")
make: "cond-token-string.mk" line 25: xvalue is not defined.
make: "cond-token-string.mk" line 32: Malformed conditional (x${:Uvalue} == "")
make: "cond-token-string.mk" line 42: Expected.
CondParser_Eval: "UNDEF"
make: "cond-token-string.mk" line 46: The string literal "UNDEF" is not empty.
make: "cond-token-string.mk" line 52: The string literal "UNDEF" is not empty.
CondParser_Eval: " "
make: "cond-token-string.mk" line 54: The string literal " " is not empty, even though it consists of whitespace only.
make: "cond-token-string.mk" line 61: The string literal " " is not empty, even though it consists of whitespace only.
CondParser_Eval: "${UNDEF}"
make: "cond-token-string.mk" line 63: An undefined variable in quotes expands to an empty string, which then evaluates to false.
make: "cond-token-string.mk" line 71: An undefined variable in quotes expands to an empty string, which then evaluates to false.
CondParser_Eval: "${:Uvalue}"
make: "cond-token-string.mk" line 68: A nonempty variable expression evaluates to true.
make: "cond-token-string.mk" line 77: A nonempty variable expression evaluates to true.
CondParser_Eval: "${:U}"
make: "cond-token-string.mk" line 76: An empty variable evaluates to false.
make: "cond-token-string.mk" line 86: An empty variable evaluates to false.
CondParser_Eval: ("${VAR}")
CondParser_Eval: "quoted" == quoted
Comparing "quoted" == "quoted"

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-token-string.mk,v 1.6 2022/05/08 06:57:00 rillig Exp $
# $NetBSD: cond-token-string.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for quoted string literals in .if conditions.
#
@ -9,7 +9,9 @@
# TODO: Implementation
# Cover the code in CondParser_String that frees the memory after parsing
# a variable expression based on an undefined variable.
# an expression based on an undefined variable.
# expect+2: Malformed conditional ("" != "${:Uvalue:Z}")
# expect+1: Unknown modifier "Z"
.if "" != "${:Uvalue:Z}"
. error
.else
@ -19,12 +21,14 @@
.if x${:Uvalue}
. error
.else
# expect+1: xvalue is not defined.
. info xvalue is not defined.
.endif
# The 'x' produces a "Malformed conditional" since the left-hand side of a
# comparison in an .if directive must be either a variable expression, a
# quoted string literal or a number that starts with a digit.
# expect+1: Malformed conditional (x${:Uvalue} == "")
.if x${:Uvalue} == ""
. error
.else
@ -34,6 +38,7 @@
# In plain words, a '\' can be used to escape any character, just as in
# double-quoted string literals. See CondParser_String.
.if \x${:Uvalue} == "xvalue"
# expect+1: Expected.
. info Expected.
.else
. error
@ -43,6 +48,7 @@
# A string in quotes is checked whether it is not empty.
.if "UNDEF"
# expect+1: The string literal "UNDEF" is not empty.
. info The string literal "UNDEF" is not empty.
.else
. error
@ -51,6 +57,7 @@
# A space is not empty as well.
# This differs from many other places where whitespace is trimmed.
.if " "
# expect+1: The string literal " " is not empty, even though it consists of whitespace only.
. info The string literal " " is not empty, even though it consists of $\
whitespace only.
.else
@ -60,11 +67,13 @@
.if "${UNDEF}"
. error
.else
# expect+1: An undefined variable in quotes expands to an empty string, which then evaluates to false.
. info An undefined variable in quotes expands to an empty string, which $\
then evaluates to false.
.endif
.if "${:Uvalue}"
# expect+1: A nonempty variable expression evaluates to true.
. info A nonempty variable expression evaluates to true.
.else
. error
@ -73,6 +82,7 @@
.if "${:U}"
. error
.else
# expect+1: An empty variable evaluates to false.
. info An empty variable evaluates to false.
.endif

View File

@ -1,7 +1,7 @@
make: "cond-token-var.mk" line 20: ok
make: "cond-token-var.mk" line 27: Malformed conditional (${UNDEF} == ${DEF})
make: "cond-token-var.mk" line 33: Malformed conditional (${DEF} == ${UNDEF})
make: "cond-token-var.mk" line 42: Malformed conditional (${UNDEF})
make: "cond-token-var.mk" line 21: ok
make: "cond-token-var.mk" line 28: Malformed conditional (${UNDEF} == ${DEF})
make: "cond-token-var.mk" line 34: Malformed conditional (${DEF} == ${UNDEF})
make: "cond-token-var.mk" line 44: Malformed conditional (${UNDEF})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-token-var.mk,v 1.6 2021/04/25 21:05:38 rillig Exp $
# $NetBSD: cond-token-var.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for variable expressions in .if conditions.
#
@ -17,19 +17,20 @@ DEF= defined
# A defined variable may appear on either side of the comparison.
.if ${DEF} == ${DEF}
# expect+1: ok
. info ok
.else
. error
.endif
# A variable that appears on the left-hand side must be defined.
# The following line thus generates a parse error.
# expect+1: Malformed conditional (${UNDEF} == ${DEF})
.if ${UNDEF} == ${DEF}
. error
.endif
# A variable that appears on the right-hand side must be defined.
# The following line thus generates a parse error.
# expect+1: Malformed conditional (${DEF} == ${UNDEF})
.if ${DEF} == ${UNDEF}
. error
.endif
@ -39,6 +40,7 @@ DEF= defined
.endif
# An undefined variable on its own generates a parse error.
# expect+1: Malformed conditional (${UNDEF})
.if ${UNDEF}
.endif

View File

@ -1,10 +1,10 @@
make: "cond-undef-lint.mk" line 23: Variable "UNDEF" is undefined
make: "cond-undef-lint.mk" line 23: Malformed conditional (${UNDEF})
make: "cond-undef-lint.mk" line 38: Variable "UNDEF" is undefined
make: "cond-undef-lint.mk" line 38: Variable "VAR." is undefined
make: "cond-undef-lint.mk" line 38: Malformed conditional (${VAR.${UNDEF}})
make: "cond-undef-lint.mk" line 49: Variable "VAR.defined" is undefined
make: "cond-undef-lint.mk" line 49: Malformed conditional (${VAR.${DEF}})
make: "cond-undef-lint.mk" line 25: Variable "UNDEF" is undefined
make: "cond-undef-lint.mk" line 25: Malformed conditional (${UNDEF})
make: "cond-undef-lint.mk" line 43: Variable "UNDEF" is undefined
make: "cond-undef-lint.mk" line 43: Variable "VAR." is undefined
make: "cond-undef-lint.mk" line 43: Malformed conditional (${VAR.${UNDEF}})
make: "cond-undef-lint.mk" line 56: Variable "VAR.defined" is undefined
make: "cond-undef-lint.mk" line 56: Malformed conditional (${VAR.${DEF}})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: cond-undef-lint.mk,v 1.3 2020/11/15 14:58:14 rillig Exp $
# $NetBSD: cond-undef-lint.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for defined and undefined variables in .if conditions, in lint mode.
#
@ -20,6 +20,8 @@ DEF= defined
.endif
# Since the condition fails to evaluate, neither of the branches is taken.
# expect+2: Malformed conditional (${UNDEF})
# expect+1: Variable "UNDEF" is undefined
.if ${UNDEF}
. error
.else
@ -35,6 +37,9 @@ DEF= defined
#
# TODO: Suppress the error message "Variable VAR. is undefined". That part
# of the expression must not be evaluated at all.
# expect+3: Variable "UNDEF" is undefined
# expect+2: Variable "VAR." is undefined
# expect+1: Malformed conditional (${VAR.${UNDEF}})
.if ${VAR.${UNDEF}}
. error
.else
@ -46,6 +51,8 @@ DEF= defined
# TODO: This pattern looks a lot like CFLAGS.${OPSYS}, which is at least
# debatable. Or would any practical use of CFLAGS.${OPSYS} be via an indirect
# expression, as in the next example?
# expect+2: Variable "VAR.defined" is undefined
# expect+1: Malformed conditional (${VAR.${DEF}})
.if ${VAR.${DEF}}
. error
.else

View File

@ -1,4 +1,4 @@
make: "dep-colon-bug-cross-file.mk" line 31: warning: duplicate script for target "all" ignored
make: "dep-colon-bug-cross-file.mk" line 40: warning: using previous script for "all" defined here
make: "dep-colon-bug-cross-file.mk" line 32: warning: duplicate script for target "all" ignored
make: "dep-colon-bug-cross-file.mk" line 42: warning: using previous script for "all" defined here
: pass 1
exit status 0

View File

@ -1,4 +1,4 @@
# $NetBSD: dep-colon-bug-cross-file.mk,v 1.4 2020/09/27 09:53:41 rillig Exp $
# $NetBSD: dep-colon-bug-cross-file.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Until 2020-09-25, the very last dependency group of a top-level makefile
# was not finished properly. This made it possible to add further commands
@ -28,6 +28,7 @@ PASS?= 1
.if ${PASS} == 2
all:
# expect+1: warning: duplicate script for target "all" ignored
: pass 2
.endif
@ -37,5 +38,6 @@ PASS= 2
.MAKEFLAGS: -f ${.PARSEDIR:q}/${.PARSEFILE:q}
all:
# expect+1: warning: using previous script for "all" defined here
: pass 1
.endif

View File

@ -1,4 +1,4 @@
# $NetBSD: dep-wildcards.mk,v 1.3 2020/09/08 05:33:05 rillig Exp $
# $NetBSD: dep-wildcards.mk,v 1.4 2023/06/21 12:27:50 rillig Exp $
#
# Tests for wildcards such as *.c in dependency declarations.
@ -7,3 +7,9 @@ all: ${.PARSEDIR}/dep-*.mk
# The :O is necessary since the result of the dependency resolution
# does not order the directory entries itself.
@printf '%s\n' ${.ALLSRC:T:O}
# This is not a wildcard rule as implemented by GNU make, as those rules would
# use '%' instead of '*'. Instead, the pattern '*.target' is a file pattern
# in the current working directory. As there are no such files, the target
# list becomes empty, and the source pattern '*.source' is not even expanded.
*.target: *.source

View File

@ -1,4 +1,4 @@
# $NetBSD: dep.mk,v 1.3 2021/12/13 23:38:54 rillig Exp $
# $NetBSD: dep.mk,v 1.4 2023/06/01 07:27:30 rillig Exp $
#
# Tests for dependency declarations, such as "target: sources".
@ -15,4 +15,16 @@ only-colon::
# would be another error message.
only-colon:
# Before parse.c 1.158 from 2009-10-07, the parser broke dependency lines at
# the first ';', without parsing expressions as such. It interpreted the
# first ';' as the separator between the dependency and its commands, and the
# '^' as a shell command.
all: for-subst
.for file in ${.PARSEFILE}
for-subst: ${file:S;^;./;g}
@echo ".for with :S;... OK"
.endfor
all:

View File

@ -1,5 +1,5 @@
make: "deptgt-begin.mk" line 17: warning: duplicate script for target ".BEGIN" ignored
make: "deptgt-begin.mk" line 8: warning: using previous script for ".BEGIN" defined here
make: "deptgt-begin.mk" line 19: warning: duplicate script for target ".BEGIN" ignored
make: "deptgt-begin.mk" line 9: warning: using previous script for ".BEGIN" defined here
: parse time
: Making before-begin before .BEGIN.
: .BEGIN

View File

@ -1,9 +1,10 @@
# $NetBSD: deptgt-begin.mk,v 1.6 2022/05/07 08:01:20 rillig Exp $
# $NetBSD: deptgt-begin.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the special target .BEGIN in dependency declarations,
# which is a container for commands that are run before any other
# commands from the shell lines.
# expect+2: warning: using previous script for ".BEGIN" defined here
.BEGIN:
: $@
@ -13,6 +14,7 @@
# add its commands after this.
#
# There are several ways to resolve this situation, which are detailed below.
# expect+2: warning: duplicate script for target ".BEGIN" ignored
.BEGIN:
: Making another $@.

View File

@ -1,4 +1,4 @@
# $NetBSD: deptgt-delete_on_error.mk,v 1.3 2020/10/25 21:31:00 rillig Exp $
# $NetBSD: deptgt-delete_on_error.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the special target .DELETE_ON_ERROR in dependency declarations,
# which controls whether the target is deleted if a shell command fails or

View File

@ -1,17 +1,17 @@
make: "deptgt.mk" line 10: warning: Extra target '.PHONY' ignored
make: "deptgt.mk" line 28: Unassociated shell command ": command3 # parse error, since targets == NULL"
Parsing line 34: ${:U}: empty-source
ParseDependency(: empty-source)
Parsing line 35: : command for empty targets list
Parsing line 36: : empty-source
make: "deptgt.mk" line 11: warning: Extra target '.PHONY' ignored
make: "deptgt.mk" line 30: Unassociated shell command ": command3 # parse error, since targets == NULL"
Parsing line 36: ${:U}: empty-source
ParseDependency(: empty-source)
Parsing line 37: : command for empty targets list
Parsing line 38: .MAKEFLAGS: -d0
Parsing line 38: : empty-source
ParseDependency(: empty-source)
Parsing line 39: : command for empty targets list
Parsing line 40: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
make: "deptgt.mk" line 46: Unknown modifier "Z"
make: "deptgt.mk" line 49: warning: Extra target 'ordinary' ignored
make: "deptgt.mk" line 52: warning: Extra target (ordinary) ignored
make: "deptgt.mk" line 55: warning: Special and mundane targets don't mix. Mundane ones ignored
make: "deptgt.mk" line 49: Unknown modifier "Z"
make: "deptgt.mk" line 52: warning: Extra target 'ordinary' ignored
make: "deptgt.mk" line 55: warning: Extra target (ordinary) ignored
make: "deptgt.mk" line 58: warning: Special and mundane targets don't mix. Mundane ones ignored
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: deptgt.mk,v 1.13 2023/01/03 00:00:45 rillig Exp $
# $NetBSD: deptgt.mk,v 1.14 2023/06/01 20:56:35 rillig Exp $
#
# Tests for special targets like .BEGIN or .SUFFIXES in dependency
# declarations.
@ -7,6 +7,7 @@
# Just in case anyone tries to compile several special targets in a single
# dependency line: That doesn't work, and make immediately rejects it.
# expect+1: warning: Extra target '.PHONY' ignored
.SUFFIXES .PHONY: .c.o
# The following lines demonstrate how 'targets' is set and reset during
@ -25,6 +26,7 @@ target1 target2: sources # targets := [target1, target2]
: command1 # targets == [target1, target2]
: command2 # targets == [target1, target2]
VAR=value # targets := NULL
# expect+1: Unassociated shell command ": command3 # parse error, since targets == NULL"
: command3 # parse error, since targets == NULL
# In a dependency declaration, the list of targets can be empty.
@ -43,6 +45,7 @@ ${:U}: empty-source
# expansion would be to use the variable modifier '::=' to modify the
# targets. This in turn would be such an extreme and unreliable edge case
# that nobody uses it.
# expect+1: Unknown modifier "Z"
$$$$$$$${:U:Z}:
# expect+1: warning: Extra target 'ordinary' ignored

View File

@ -1,21 +1,21 @@
make: "directive-elif.mk" line 47: Unknown directive "elsif"
make: "directive-elif.mk" line 52: This branch is taken.
make: "directive-elif.mk" line 60: Unknown directive "elsif"
make: "directive-elif.mk" line 63: This branch is taken.
make: "directive-elif.mk" line 69: This branch is taken.
make: "directive-elif.mk" line 89: Unknown directive "elsif"
make: "directive-elif.mk" line 90: This misspelling is detected.
make: "directive-elif.mk" line 91: This branch is taken because of the .else.
make: "directive-elif.mk" line 109: What happens on misspelling in a skipped branch?
make: "directive-elif.mk" line 119: else
make: "directive-elif.mk" line 122: What happens on misspelling in a taken branch?
make: "directive-elif.mk" line 124: 1-then
make: "directive-elif.mk" line 125: Unknown directive "elsif"
make: "directive-elif.mk" line 126: 1-elsif
make: "directive-elif.mk" line 127: Unknown directive "elsif"
make: "directive-elif.mk" line 128: 2-elsif
make: "directive-elif.mk" line 134: if-less elif
make: "directive-elif.mk" line 139: warning: extra elif
make: "directive-elif.mk" line 48: Unknown directive "elsif"
make: "directive-elif.mk" line 54: This branch is taken.
make: "directive-elif.mk" line 62: Unknown directive "elsif"
make: "directive-elif.mk" line 66: This branch is taken.
make: "directive-elif.mk" line 73: This branch is taken.
make: "directive-elif.mk" line 94: Unknown directive "elsif"
make: "directive-elif.mk" line 96: This misspelling is detected.
make: "directive-elif.mk" line 98: This branch is taken because of the .else.
make: "directive-elif.mk" line 117: What happens on misspelling in a skipped branch?
make: "directive-elif.mk" line 128: else
make: "directive-elif.mk" line 132: What happens on misspelling in a taken branch?
make: "directive-elif.mk" line 135: 1-then
make: "directive-elif.mk" line 137: Unknown directive "elsif"
make: "directive-elif.mk" line 139: 1-elsif
make: "directive-elif.mk" line 141: Unknown directive "elsif"
make: "directive-elif.mk" line 143: 2-elsif
make: "directive-elif.mk" line 149: if-less elif
make: "directive-elif.mk" line 154: warning: extra elif
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-elif.mk,v 1.7 2020/12/19 19:49:01 rillig Exp $
# $NetBSD: directive-elif.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .elif directive.
#
@ -44,28 +44,32 @@
# Misspelling '.elsif' below an .if branch that is taken.
.if 1
# This misspelling is in an active branch and is therefore detected.
# expect+1: Unknown directive "elsif"
.elsif 0
# The only thing that make detects here is a misspelled directive, make
# doesn't recognize that it was meant to be a conditional directive.
# Therefore the branch continues here, even though the '.elsif' condition
# evaluates to false.
# expect+1: This branch is taken.
. info This branch is taken.
.endif
# Misspelling '.elsif' below an .if branch that is taken.
.if 1
# As of 2020-12-19, the misspelling is in an active branch and is therefore
# detected.
# The misspelling is in an active branch and is therefore detected.
# expect+1: Unknown directive "elsif"
.elsif 1
# Since both conditions evaluate to true, this branch is taken no matter
# whether make detects a misspelling or not.
# expect+1: This branch is taken.
. info This branch is taken.
.endif
# Misspelling '.elsif' in a skipped branch below a branch that was taken.
.if 1
# expect+1: This branch is taken.
. info This branch is taken.
.elif 0
. info This branch is not taken.
@ -86,8 +90,11 @@
# Misspelling '.elsif' in an .else branch that is taken.
.if 0
.else
# expect+1: Unknown directive "elsif"
.elsif 1
# expect+1: This misspelling is detected.
. info This misspelling is detected.
# expect+1: This branch is taken because of the .else.
. info This branch is taken because of the .else.
.endif
@ -106,6 +113,7 @@
.endif
# expect+1: What happens on misspelling in a skipped branch?
.info What happens on misspelling in a skipped branch?
.if 0
. info 0-then
@ -116,26 +124,33 @@
. info XXX: This misspelling is not detected.
. info 2-elsif
.else
# expect+1: else
. info else
.endif
# expect+1: What happens on misspelling in a taken branch?
.info What happens on misspelling in a taken branch?
.if 1
# expect+1: 1-then
. info 1-then
# expect+1: Unknown directive "elsif"
.elsif 1
# expect+1: 1-elsif
. info 1-elsif
# expect+1: Unknown directive "elsif"
.elsif 2
# expect+1: 2-elsif
. info 2-elsif
.else
. info else
.endif
# Expect: "if-less elif"
# expect+1: if-less elif
.elif 0
.if 1
.else
# Expect: "warning: extra elif"
# expect+1: warning: extra elif
.elif
.endif

View File

@ -1,11 +1,11 @@
make: "directive-else.mk" line 14: The .else directive does not take arguments
make: "directive-else.mk" line 15: ok
make: "directive-else.mk" line 19: ok
make: "directive-else.mk" line 21: The .else directive does not take arguments
make: "directive-else.mk" line 26: if-less else
make: "directive-else.mk" line 32: ok
make: "directive-else.mk" line 33: warning: extra else
make: "directive-else.mk" line 45: The .else directive does not take arguments
make: "directive-else.mk" line 16: ok
make: "directive-else.mk" line 21: ok
make: "directive-else.mk" line 23: The .else directive does not take arguments
make: "directive-else.mk" line 29: if-less else
make: "directive-else.mk" line 36: ok
make: "directive-else.mk" line 38: warning: extra else
make: "directive-else.mk" line 51: The .else directive does not take arguments
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-else.mk,v 1.7 2020/12/14 22:17:11 rillig Exp $
# $NetBSD: directive-else.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .else directive.
#
@ -10,26 +10,31 @@
.if 0
. warning must not be reached
# The .else directive does not take any arguments.
# expect+1: The .else directive does not take arguments
.else 123
# expect+1: ok
. info ok
.endif
.if 1
# expect+1: ok
. info ok
# The .else directive does not take any arguments.
# expect+1: The .else directive does not take arguments
.else 123
. warning must not be reached
.endif
# An .else without a corresponding .if is an error.
# expect+1: if-less else
.else
# Accidental extra .else directives are detected too.
.if 0
. warning must not be reached
.else
# expect+1: ok
. info ok
# expect+1: warning: extra else
.else
. info After an extra .else, everything is skipped.
.endif
@ -42,6 +47,7 @@
# A variable expression does count as an argument, even if it is empty.
.if 0
# expect+1: The .else directive does not take arguments
.else ${:U}
.endif

View File

@ -1,4 +1,4 @@
make: "directive-endfor.mk" line 9: for-less endfor
make: "directive-endfor.mk" line 10: for-less endfor
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-endfor.mk,v 1.1 2020/12/30 14:50:08 rillig Exp $
# $NetBSD: directive-endfor.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Test for the directive .endfor, which ends a .for loop.
#
@ -6,4 +6,5 @@
# directive-for.mk
# An .endfor without a corresponding .for is a parse error.
# expect+1: for-less endfor
.endfor

View File

@ -1,8 +1,8 @@
make: "directive-endif.mk" line 18: The .endif directive does not take arguments
make: "directive-endif.mk" line 23: The .endif directive does not take arguments
make: "directive-endif.mk" line 33: The .endif directive does not take arguments
make: "directive-endif.mk" line 16: The .endif directive does not take arguments
make: "directive-endif.mk" line 21: The .endif directive does not take arguments
make: "directive-endif.mk" line 32: The .endif directive does not take arguments
make: "directive-endif.mk" line 39: The .endif directive does not take arguments
make: "directive-endif.mk" line 45: Unknown directive "endifx"
make: "directive-endif.mk" line 44: Unknown directive "endifx"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-endif.mk,v 1.5 2020/12/14 21:56:17 rillig Exp $
# $NetBSD: directive-endif.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .endif directive.
#
@ -8,18 +8,16 @@
# See also:
# Cond_EvalLine
# TODO: Implementation
.MAKEFLAGS: -dL
# Error: .endif does not take arguments
.if 0
# Since 2020-12-15, complain about the extra text after the 'endif'.
# Since 2020-12-15:
# expect+1: The .endif directive does not take arguments
.endif 0
# Error: .endif does not take arguments
.if 1
# Since 2020-12-15, complain about the extra text after the 'endif'.
# Since 2020-12-15:
# expect+1: The .endif directive does not take arguments
.endif 1
# Comments are allowed after an '.endif'.
@ -29,21 +27,19 @@
# Only whitespace and comments are allowed after an '.endif', but nothing
# else.
.if 1
# Since 2020-12-15, complain about the extra text after the 'endif'.
# Since 2020-12-15:
# expect+1: The .endif directive does not take arguments
.endif0
# Only whitespace and comments are allowed after an '.endif', but nothing
# else.
.if 1
# Since 2020-12-15, complain about the extra text after the 'endif'.
# Since 2020-12-15:
# expect+1: The .endif directive does not take arguments
.endif/
# After an '.endif', no other letter must occur. This 'endifx' is not
# parsed as an 'endif', therefore another '.endif' must follow to balance
# the directives.
# After an '.endif', no other letter must occur.
.if 1
# expect+1: Unknown directive "endifx"
.endifx
.endif # to close the preceding '.if'
all:
@:;
.endif # to close the preceding '.if'

View File

@ -1,4 +1,4 @@
make: "directive-error.mk" line 13: message
make: "directive-error.mk" line 14: message
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-error.mk,v 1.5 2021/01/27 00:02:38 rillig Exp $
# $NetBSD: directive-error.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .error directive, which prints an error message and exits
# immediately, unlike other "fatal" parse errors, which continue to parse
@ -10,4 +10,5 @@
# Before parse.c 1.532 from 2021-01-27, the ".error" issued an irrelevant
# message saying "parsing warnings being treated as errors".
.MAKEFLAGS: -W
# expect+1: message
.error message

View File

@ -1,4 +1,5 @@
make: "directive-for-break.mk" line 45: break outside of for loop
make: "directive-for-break.mk" line 65: The .break directive does not take arguments
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-for-break.mk,v 1.3 2022/09/24 10:52:05 rillig Exp $
# $NetBSD: directive-for-break.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for .break in .for loops, which immediately terminates processing of
# the surrounding .for loop.
@ -58,3 +58,9 @@ COMBINED+= ${outer}-${inner}
. endfor
. endif
.endif
.for i in 1
# expect+1: The .break directive does not take arguments
. break 1
.endfor

View File

@ -1,9 +1,9 @@
make: "directive-for-empty.mk" line 21: 2
make: "directive-for-empty.mk" line 34: Missing argument for ".error"
make: "directive-for-empty.mk" line 34: Missing argument for ".error"
make: "directive-for-empty.mk" line 34: Missing argument for ".error"
make: "directive-for-empty.mk" line 22: 2
make: "directive-for-empty.mk" line 38: Missing argument for ".error"
make: "directive-for-empty.mk" line 38: Missing argument for ".error"
make: "directive-for-empty.mk" line 38: Missing argument for ".error"
For: end for 1
For: loop body:
For: loop body with i = value:
# The identifier 'empty' can only be used in conditions such as .if, .ifdef or
# .elif. In other lines the string 'empty(' must be preserved.
CPPFLAGS+= -Dmessage="empty(i)"

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-for-empty.mk,v 1.1 2022/05/23 22:33:56 rillig Exp $
# $NetBSD: directive-for-empty.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Tests for .for loops containing conditions of the form 'empty(var:...)'.
#
@ -18,6 +18,7 @@
# when in fact they aren't.
.for i in 11 12 13
. if ${i:M*2*}
# expect+1: 2
.info 2
. endif
.endfor
@ -31,6 +32,9 @@
# Asking for an empty iteration variable does not make sense as the .for loop
# splits the iteration items into words, and such a word cannot be empty.
. if empty(i)
# expect+3: Missing argument for ".error"
# expect+2: Missing argument for ".error"
# expect+1: Missing argument for ".error"
. error # due to the leaky abstraction
. endif
# The typical way of using 'empty' with variables from .for loops is pattern

View File

@ -1,17 +1,17 @@
make: "directive-for-errors.mk" line 11: Unknown directive "fori"
make: "directive-for-errors.mk" line 12: warning: <>
make: "directive-for-errors.mk" line 13: for-less endfor
make: "directive-for-errors.mk" line 27: Unknown directive "for"
make: "directive-for-errors.mk" line 28: warning: <>
make: "directive-for-errors.mk" line 29: for-less endfor
make: "directive-for-errors.mk" line 46: invalid character '$' in .for loop variable name
make: "directive-for-errors.mk" line 54: no iteration variables in for
make: "directive-for-errors.mk" line 66: Wrong number of words (5) in .for substitution list with 3 variables
make: "directive-for-errors.mk" line 80: missing `in' in for
make: "directive-for-errors.mk" line 91: Unknown modifier "Z"
make: "directive-for-errors.mk" line 92: warning: Should not be reached.
make: "directive-for-errors.mk" line 92: warning: Should not be reached.
make: "directive-for-errors.mk" line 92: warning: Should not be reached.
make: "directive-for-errors.mk" line 9: Unknown directive "fori"
make: "directive-for-errors.mk" line 10: warning: <>
make: "directive-for-errors.mk" line 11: for-less endfor
make: "directive-for-errors.mk" line 25: Unknown directive "for"
make: "directive-for-errors.mk" line 26: warning: <>
make: "directive-for-errors.mk" line 27: for-less endfor
make: "directive-for-errors.mk" line 44: invalid character '$' in .for loop variable name
make: "directive-for-errors.mk" line 52: no iteration variables in for
make: "directive-for-errors.mk" line 64: Wrong number of words (5) in .for substitution list with 3 variables
make: "directive-for-errors.mk" line 78: missing `in' in for
make: "directive-for-errors.mk" line 89: Unknown modifier "Z"
make: "directive-for-errors.mk" line 90: warning: Should not be reached.
make: "directive-for-errors.mk" line 90: warning: Should not be reached.
make: "directive-for-errors.mk" line 90: warning: Should not be reached.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,9 +1,7 @@
# $NetBSD: directive-for-errors.mk,v 1.5 2023/05/09 19:43:12 rillig Exp $
# $NetBSD: directive-for-errors.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
#
# Tests for error handling in .for loops.
# expect-all
# A .for directive must be followed by whitespace, everything else results
# in a parse error.

View File

@ -1,60 +1,60 @@
For: end for 1
For: loop body:
For: loop body with chars = !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~:
. info ${:U!"#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
make: Unclosed variable expression, expecting '}' for modifier "U!"" of variable "" with value "!""
make: "directive-for-escape.mk" line 21: !"
make: "directive-for-escape.mk" line 19: !"
For: end for 1
For: loop body:
For: loop body with chars = !"\\#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~:
. info ${:U!"\\\\#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
make: Unclosed variable expression, expecting '}' for modifier "U!"\\\\" of variable "" with value "!"\\"
make: "directive-for-escape.mk" line 32: !"\\
make: "directive-for-escape.mk" line 30: !"\\
For: end for 1
For: loop body:
For: loop body with i = $:
. info ${:U\$}
make: "directive-for-escape.mk" line 47: $
For: loop body:
make: "directive-for-escape.mk" line 45: $
For: loop body with i = ${V}:
. info ${:U${V}}
make: "directive-for-escape.mk" line 47: value
For: loop body:
make: "directive-for-escape.mk" line 45: value
For: loop body with i = ${V:=-with-modifier}:
. info ${:U${V:=-with-modifier}}
make: "directive-for-escape.mk" line 47: value-with-modifier
For: loop body:
make: "directive-for-escape.mk" line 45: value-with-modifier
For: loop body with i = $(V):
. info ${:U$(V)}
make: "directive-for-escape.mk" line 47: value
For: loop body:
make: "directive-for-escape.mk" line 45: value
For: loop body with i = $(V:=-with-modifier):
. info ${:U$(V:=-with-modifier)}
make: "directive-for-escape.mk" line 47: value-with-modifier
make: "directive-for-escape.mk" line 45: value-with-modifier
For: end for 1
For: loop body:
For: loop body with i = ${UNDEF:U\$\$:
# ${:U\${UNDEF\:U\\$\\$}
For: loop body:
For: loop body with i = {{}}:
# ${:U{{\}\}}
For: loop body:
For: loop body with i = end}:
# ${:Uend\}}
For: end for 1
For: loop body:
For: loop body with i = ${UNDEF:U\$\$:
. info ${:U\${UNDEF\:U\\$\\$}
make: "directive-for-escape.mk" line 101: ${UNDEF:U\backslash$
For: loop body:
make: "directive-for-escape.mk" line 99: ${UNDEF:U\backslash$
For: loop body with i = {{}}:
. info ${:U{{\}\}}
make: "directive-for-escape.mk" line 101: {{}}
For: loop body:
make: "directive-for-escape.mk" line 99: {{}}
For: loop body with i = end}:
. info ${:Uend\}}
make: "directive-for-escape.mk" line 101: end}
make: "directive-for-escape.mk" line 99: end}
For: end for 1
For: loop body:
For: loop body with i = begin<${UNDEF:Ufallback:N{{{}}}}>end:
. info ${:Ubegin<${UNDEF:Ufallback:N{{{}}}}>end}
make: "directive-for-escape.mk" line 122: begin<fallback>end
make: "directive-for-escape.mk" line 120: begin<fallback>end
For: end for 1
For: loop body:
For: loop body with i = $:
. info ${:U\$}
make: "directive-for-escape.mk" line 131: $
make: "directive-for-escape.mk" line 140: invalid character ':' in .for loop variable name
make: "directive-for-escape.mk" line 129: $
make: "directive-for-escape.mk" line 138: invalid character ':' in .for loop variable name
For: end for 1
make: "directive-for-escape.mk" line 150: invalid character '}' in .for loop variable name
make: "directive-for-escape.mk" line 148: invalid character '}' in .for loop variable name
For: end for 1
For: end for 1
For: loop body:
For: loop body with i = inner:
. info . $$i: ${:Uinner}
. info . $${i}: ${:Uinner}
. info . $${i:M*}: ${:Uinner:M*}
@ -65,80 +65,83 @@ For: loop body:
. info . $${i2}: ${i2}
. info . $${i,}: ${i,}
. info . adjacent: ${:Uinner}${:Uinner}${:Uinner:M*}${:Uinner}
make: "directive-for-escape.mk" line 159: . $i: inner
make: "directive-for-escape.mk" line 160: . ${i}: inner
make: "directive-for-escape.mk" line 161: . ${i:M*}: inner
make: "directive-for-escape.mk" line 162: . $(i): inner
make: "directive-for-escape.mk" line 163: . $(i:M*): inner
make: "directive-for-escape.mk" line 164: . ${i${:U}}: outer
make: "directive-for-escape.mk" line 165: . ${i\}}: inner}
make: "directive-for-escape.mk" line 166: . ${i2}: two
make: "directive-for-escape.mk" line 167: . ${i,}: comma
make: "directive-for-escape.mk" line 168: . adjacent: innerinnerinnerinner
make: "directive-for-escape.mk" line 187: invalid character '$' in .for loop variable name
make: "directive-for-escape.mk" line 157: . $i: inner
make: "directive-for-escape.mk" line 158: . ${i}: inner
make: "directive-for-escape.mk" line 159: . ${i:M*}: inner
make: "directive-for-escape.mk" line 160: . $(i): inner
make: "directive-for-escape.mk" line 161: . $(i:M*): inner
make: "directive-for-escape.mk" line 162: . ${i${:U}}: outer
make: "directive-for-escape.mk" line 163: . ${i\}}: inner}
make: "directive-for-escape.mk" line 164: . ${i2}: two
make: "directive-for-escape.mk" line 165: . ${i,}: comma
make: "directive-for-escape.mk" line 166: . adjacent: innerinnerinnerinner
make: "directive-for-escape.mk" line 185: invalid character '$' in .for loop variable name
For: end for 1
make: "directive-for-escape.mk" line 199: eight and no cents.
make: "directive-for-escape.mk" line 197: eight and no cents.
For: end for 1
make: "directive-for-escape.mk" line 212: newline in .for value
make: "directive-for-escape.mk" line 212: newline in .for value
For: loop body:
make: "directive-for-escape.mk" line 210: newline in .for value
make: "directive-for-escape.mk" line 210: newline in .for value
For: loop body with i = "
":
. info short: ${:U" "}
. info long: ${:U" "}
make: "directive-for-escape.mk" line 213: short: " "
make: "directive-for-escape.mk" line 214: long: " "
make: "directive-for-escape.mk" line 211: short: " "
make: "directive-for-escape.mk" line 212: long: " "
For: end for 1
For: loop body:
For: loop body with i = "
":
For: end for 1
Parse_PushInput: .for loop in directive-for-escape.mk, line 230
make: "directive-for-escape.mk" line 230: newline in .for value
in .for loop from directive-for-escape.mk:230 with i = "
Parse_PushInput: .for loop in directive-for-escape.mk, line 228
make: "directive-for-escape.mk" line 228: newline in .for value
in .for loop from directive-for-escape.mk:228 with i = "
"
For: loop body:
For: loop body with i = "
":
: ${:U" "}
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
Parsing line 231: : ${:U" "}
Parsing line 229: : ${:U" "}
ParseDependency(: " ")
ParseEOF: returning to file directive-for-escape.mk, line 233
ParseEOF: returning to file directive-for-escape.mk, line 231
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
Parsing line 233: .MAKEFLAGS: -d0
Parsing line 231: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
For: end for 1
For: loop body:
For: loop body with i = #:
# ${:U#}
For: loop body:
For: loop body with i = \\#:
# ${:U\\\\#}
For: end for 1
For: loop body:
For: loop body with i = $:
# ${:U\$}
For: loop body:
For: loop body with i = $i:
# ${:U$i}
For: loop body:
For: loop body with i = $(i):
# ${:U$(i)}
For: loop body:
For: loop body with i = ${i}:
# ${:U${i}}
For: loop body:
For: loop body with i = $$:
# ${:U$$}
For: loop body:
For: loop body with i = $$$$:
# ${:U$$$$}
For: loop body:
For: loop body with i = ${:U\$\$}:
# ${:U${:U\$\$}}
For: end for 1
For: loop body:
For: loop body with i = ${.TARGET}:
# ${:U${.TARGET}}
For: loop body:
For: loop body with i = ${.TARGET}:
# ${:U${.TARGET}}
For: loop body:
For: loop body with i = $${.TARGET}:
# ${:U$${.TARGET\}}
For: loop body:
For: loop body with i = $${.TARGET}:
# ${:U$${.TARGET\}}
For: end for 1
For: loop body:
For: loop body with i = (((:
# ${:U(((}
For: loop body:
For: loop body with i = {{{:
# ${:U{{{}
For: loop body:
For: loop body with i = ))):
# ${:U)))}
For: loop body:
For: loop body with i = }}}:
# ${:U\}\}\}}
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests

View File

@ -1,11 +1,9 @@
# $NetBSD: directive-for-escape.mk,v 1.18 2023/05/09 19:43:12 rillig Exp $
# $NetBSD: directive-for-escape.mk,v 1.20 2023/06/01 20:56:35 rillig Exp $
#
# Test escaping of special characters in the iteration values of a .for loop.
# These values get expanded later using the :U variable modifier, and this
# escaping and unescaping must pass all characters and strings unmodified.
# expect-all
.MAKEFLAGS: -df
# Even though the .for loops take quotes into account when splitting the
@ -74,11 +72,11 @@ VALUES= $${UNDEF:U\$$\$$ {{}} end}
# When these words are injected into the body of the .for loop, each inside a
# '${:U...}' expression, the result is:
#
# expect: For: loop body:
# expect: For: loop body with i = ${UNDEF:U\$\$:
# expect: # ${:U\${UNDEF\:U\\$\\$}
# expect: For: loop body:
# expect: For: loop body with i = {{}}:
# expect: # ${:U{{\}\}}
# expect: For: loop body:
# expect: For: loop body with i = end}:
# expect: # ${:Uend\}}
# expect: For: end for 1
#

View File

@ -1,7 +1,7 @@
make: "directive-for-generating-endif.mk" line 21: if-less endif
make: "directive-for-generating-endif.mk" line 21: if-less endif
make: "directive-for-generating-endif.mk" line 21: if-less endif
make: "directive-for-generating-endif.mk" line 26: 3 open conditionals
make: "directive-for-generating-endif.mk" line 24: if-less endif
make: "directive-for-generating-endif.mk" line 24: if-less endif
make: "directive-for-generating-endif.mk" line 24: if-less endif
make: "directive-for-generating-endif.mk" line 30: 3 open conditionals
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-for-generating-endif.mk,v 1.1 2020/08/29 18:50:25 rillig Exp $
# $NetBSD: directive-for-generating-endif.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Test whether a .for loop can be used to generate multiple .endif
# directives to close nested .if directives. Depending on the exact
@ -18,8 +18,12 @@
. if 2
. if 3
.for i in 3 2 1
# expect+3: if-less endif
# expect+2: if-less endif
# expect+1: if-less endif
.endif
.endfor
all:
@:;
# expect+1: 3 open conditionals

View File

@ -1,6 +1,6 @@
make: "directive-for-if.mk" line 48: if-less endif
make: "directive-for-if.mk" line 48: if-less endif
make: "directive-for-if.mk" line 48: if-less endif
make: "directive-for-if.mk" line 51: if-less endif
make: "directive-for-if.mk" line 51: if-less endif
make: "directive-for-if.mk" line 51: if-less endif
VAR1
VAR3
make: Fatal errors encountered -- cannot continue

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-for-if.mk,v 1.1 2021/08/30 17:08:13 rillig Exp $
# $NetBSD: directive-for-if.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $
#
# Test for a .for directive that contains an .if directive.
#
@ -45,6 +45,9 @@
# expanded to their bare textual value.
.for directive in if ifdef ifndef
. ${directive} "1" != "0"
# expect+3: if-less endif
# expect+2: if-less endif
# expect+1: if-less endif
. endif
.endfor
# In 2021, the above code does not generate an error message, even though the

View File

@ -1,9 +1,9 @@
make: "directive-for-lines.mk" line 23: expect 23
make: "directive-for-lines.mk" line 23: expect 23
make: "directive-for-lines.mk" line 30: expect 30
make: "directive-for-lines.mk" line 23: expect 23
make: "directive-for-lines.mk" line 23: expect 23
make: "directive-for-lines.mk" line 30: expect 30
make: "directive-for-lines.mk" line 27: expect 23
make: "directive-for-lines.mk" line 27: expect 23
make: "directive-for-lines.mk" line 36: expect 30
make: "directive-for-lines.mk" line 27: expect 23
make: "directive-for-lines.mk" line 27: expect 23
make: "directive-for-lines.mk" line 36: expect 30
make: no target to make.
make: stopped in unit-tests

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-for-lines.mk,v 1.4 2022/05/08 06:51:27 rillig Exp $
# $NetBSD: directive-for-lines.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the line numbers that are reported in .for loops.
#
@ -20,6 +20,10 @@
VAR= \
multi-line
# expect+4: expect 23
# expect+3: expect 23
# expect+2: expect 23
# expect+1: expect 23
.info expect 23
.endfor
@ -27,6 +31,8 @@ VAR= \
# comment \
# continued comment
# expect+2: expect 30
# expect+1: expect 30
.info expect 30
.endfor

View File

@ -1,41 +1,41 @@
make: "directive-for.mk" line 119: outer
make: "directive-for.mk" line 137: a:\ a:\file.txt
make: "directive-for.mk" line 137: d:\\
make: "directive-for.mk" line 137: d:\\file.txt
make: "directive-for.mk" line 148: ( ( (
make: "directive-for.mk" line 148: [ [ [
make: "directive-for.mk" line 148: { { {
make: "directive-for.mk" line 148: ) ) )
make: "directive-for.mk" line 148: ] ] ]
make: "directive-for.mk" line 148: } } }
make: "directive-for.mk" line 148: (()) (()) (())
make: "directive-for.mk" line 148: [[]] [[]] [[]]
make: "directive-for.mk" line 148: {{}} {{}} {{}}
make: "directive-for.mk" line 148: )( )( )(
make: "directive-for.mk" line 148: ][ ][ ][
make: "directive-for.mk" line 148: }{ }{ }{
make: "directive-for.mk" line 168: invalid character ':' in .for loop variable name
make: "directive-for.mk" line 175: invalid character '$' in .for loop variable name
make: "directive-for.mk" line 187: invalid character '$' in .for loop variable name
make: "directive-for.mk" line 198: Unknown modifier "Z"
make: "directive-for.mk" line 199: XXX: Not reached word1
make: "directive-for.mk" line 199: XXX: Not reached word3
make: "directive-for.mk" line 206: no iteration variables in for
make: "directive-for.mk" line 232: 1 open conditional
make: "directive-for.mk" line 248: for-less endfor
make: "directive-for.mk" line 249: if-less endif
make: "directive-for.mk" line 257: if-less endif
make: "directive-for.mk" line 117: outer
make: "directive-for.mk" line 135: a:\ a:\file.txt
make: "directive-for.mk" line 135: d:\\
make: "directive-for.mk" line 135: d:\\file.txt
make: "directive-for.mk" line 146: ( ( (
make: "directive-for.mk" line 146: [ [ [
make: "directive-for.mk" line 146: { { {
make: "directive-for.mk" line 146: ) ) )
make: "directive-for.mk" line 146: ] ] ]
make: "directive-for.mk" line 146: } } }
make: "directive-for.mk" line 146: (()) (()) (())
make: "directive-for.mk" line 146: [[]] [[]] [[]]
make: "directive-for.mk" line 146: {{}} {{}} {{}}
make: "directive-for.mk" line 146: )( )( )(
make: "directive-for.mk" line 146: ][ ][ ][
make: "directive-for.mk" line 146: }{ }{ }{
make: "directive-for.mk" line 166: invalid character ':' in .for loop variable name
make: "directive-for.mk" line 173: invalid character '$' in .for loop variable name
make: "directive-for.mk" line 185: invalid character '$' in .for loop variable name
make: "directive-for.mk" line 196: Unknown modifier "Z"
make: "directive-for.mk" line 197: XXX: Not reached word1
make: "directive-for.mk" line 197: XXX: Not reached word3
make: "directive-for.mk" line 204: no iteration variables in for
make: "directive-for.mk" line 230: 1 open conditional
make: "directive-for.mk" line 246: for-less endfor
make: "directive-for.mk" line 247: if-less endif
make: "directive-for.mk" line 255: if-less endif
For: new loop 2
For: end for 2
For: end for 1
For: loop body:
For: loop body with outer = o:
.\
for inner in i
.\
endfor
For: end for 1
For: loop body:
make: "directive-for.mk" line 305: newline-item=(a)
For: loop body with inner = i:
make: "directive-for.mk" line 303: newline-item=(a)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-for.mk,v 1.20 2023/05/10 13:03:06 rillig Exp $
# $NetBSD: directive-for.mk,v 1.22 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .for directive.
#
@ -12,8 +12,6 @@
# See also:
# varmod-loop.mk The ':@var@...@' modifier
# expect-all
# A typical use case for a .for loop is to populate a variable with a list of
# values depending on other variables. In simple cases, the same effect can
# be achieved using the ':@var@${var}@' modifier.
@ -87,9 +85,9 @@ var2= value before
. warning After the .for loop, var2 must still have its original value.
.endif
# Until 2008-12-21, the values of the iteration variables were simply
# inserted as plain text and then parsed as usual, which made it possible
# to achieve all kinds of strange effects, such as generating '.if'
# Before for.c 1.39 from 2008-12-21, the values of the iteration variables
# were simply inserted as plain text and then parsed as usual, which made it
# possible to achieve all kinds of strange effects, such as generating '.if'
# directives or inserting '$' characters in random places, thereby changing
# how following '$' are interpreted.
#

View File

@ -1,18 +1,18 @@
make: "directive-if.mk" line 13: 0 evaluates to false.
make: "directive-if.mk" line 17: 1 evaluates to true.
make: "directive-if.mk" line 41: Unknown directive "ifx"
make: "directive-if.mk" line 43: This is not conditional.
make: "directive-if.mk" line 45: if-less else
make: "directive-if.mk" line 47: This is not conditional.
make: "directive-if.mk" line 49: if-less endif
make: "directive-if.mk" line 53: Malformed conditional ()
make: "directive-if.mk" line 63: Quotes in plain words are probably a mistake.
make: "directive-if.mk" line 72: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 14: 0 evaluates to false.
make: "directive-if.mk" line 19: 1 evaluates to true.
make: "directive-if.mk" line 43: Unknown directive "ifx"
make: "directive-if.mk" line 45: This is not conditional.
make: "directive-if.mk" line 47: if-less else
make: "directive-if.mk" line 49: This is not conditional.
make: "directive-if.mk" line 51: if-less endif
make: "directive-if.mk" line 55: Malformed conditional ()
make: "directive-if.mk" line 66: Quotes in plain words are probably a mistake.
make: "directive-if.mk" line 76: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 82: Don't do this, always put a space around comparison operators.
make: "directive-if.mk" line 88: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 92: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 100: Unknown directive "ifn"
make: "directive-if.mk" line 81: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 88: Don't do this, always put a space around comparison operators.
make: "directive-if.mk" line 95: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 100: Don't do this, always put a space after a directive.
make: "directive-if.mk" line 108: Unknown directive "ifn"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: directive-if.mk,v 1.11 2022/01/23 21:48:59 rillig Exp $
# $NetBSD: directive-if.mk,v 1.12 2023/06/01 20:56:35 rillig Exp $
#
# Tests for the .if directive.
#
@ -10,10 +10,12 @@
.if 0
. error
.else
# expect+1: 0 evaluates to false.
. info 0 evaluates to false.
.endif
.if 1
# expect+1: 1 evaluates to true.
. info 1 evaluates to true.
.else
. error
@ -60,6 +62,7 @@
# though, which are kept. The quotes need not be balanced. The next space
# ends the word, and the remaining " || 1" is parsed as "or true".
.if ${:Uplain"""""} == plain""""" || 1
# expect+1: Quotes in plain words are probably a mistake.
. info Quotes in plain words are probably a mistake.
# XXX: Accepting quotes in plain words is probably a mistake as well.
.else
@ -69,26 +72,31 @@
.if0
. error
.else
# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.endif
.if${:U-3}
# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.else
. error
.endif
.if${:U-3}>-4
# expect+1: Don't do this, always put a space around comparison operators.
. info Don't do this, always put a space around comparison operators.
.else
. error
.endif
.if(1)
# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.endif
.if!0
# expect+1: Don't do this, always put a space after a directive.
. info Don't do this, always put a space after a directive.
.endif

View File

@ -1,10 +1,10 @@
make: "directive-ifmake.mk" line 13: ok: positive condition works
make: "directive-ifmake.mk" line 24: ok: negation works
make: "directive-ifmake.mk" line 33: ok: double negation works
make: "directive-ifmake.mk" line 40: ok: both mentioned
make: "directive-ifmake.mk" line 47: ok: only those mentioned
make: "directive-ifmake.mk" line 57: Targets can even be added at parse time.
make: "directive-ifmake.mk" line 75: ok
make: "directive-ifmake.mk" line 14: ok: positive condition works
make: "directive-ifmake.mk" line 26: ok: negation works
make: "directive-ifmake.mk" line 36: ok: double negation works
make: "directive-ifmake.mk" line 44: ok: both mentioned
make: "directive-ifmake.mk" line 52: ok: only those mentioned
make: "directive-ifmake.mk" line 63: Targets can even be added at parse time.
make: "directive-ifmake.mk" line 82: ok
: first
: second
: late-target

Some files were not shown because too many files have changed in this diff Show More