Merge commit 'ee914ef902ae018bd4f67192832120f9bf05651f' into new_merge
This commit is contained in:
commit
b0c40a00a6
@ -1,3 +1,116 @@
|
||||
2021-06-21 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210621
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: only report error for unmatched regex subexpression
|
||||
when linting (-dL) since we cannot tell when an unmatched
|
||||
subexpression is an expected result.
|
||||
o move unmatched regex subexpression tests to
|
||||
varmod-subst-regex.mk and enable strict (lint) mode
|
||||
|
||||
2021-06-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210616
|
||||
Merge with NetBSD make, pick up
|
||||
o more unit tests
|
||||
o cond.c: rename If_Eval to EvalBare
|
||||
improve function names for parsing conditions
|
||||
o job.c: fix error handling of targets that cannot be made
|
||||
o var.c: uncompress code in ApplyModifier_Unique
|
||||
|
||||
2021-05-18 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210518
|
||||
Merge with NetBSD make, pick up
|
||||
o fix unit-tests/opt-chdir to cope with /nonexistent existing.
|
||||
o job.c: Print -de error information when running multiple jobs
|
||||
|
||||
2021-04-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210420
|
||||
Merge with NetBSD make, pick up
|
||||
o use C99 bool type
|
||||
o convert VarEvalFlags back into an enum
|
||||
o cond.c: do not complain when skipping the condition 'no >= 10'
|
||||
o hash.c: avoid allocating memory for simple variable names
|
||||
o job.c: use distinct wording for writing to the shell commands file
|
||||
remove type name for the abort status in job handling
|
||||
rename PrintOutput to PrintFilteredOutput to avoid confusion
|
||||
o main.c: avoid double slash in name of temporary directory
|
||||
o var.c: use straight quotes for error 'Bad conditional expression'
|
||||
reduce memory allocations in the modifiers ':D' and ':U'
|
||||
rename members of ModifyWord_LoopArgs
|
||||
clean up pattern flags for the modifiers ':S' and ':C'
|
||||
reduce memory allocation and strlen calls in modifier ':from=to'
|
||||
in the ':Q' modifier, only allocate memory if necessary
|
||||
improve performance for LazyBuf
|
||||
remove redundant parameter from ParseVarnameLong
|
||||
migrate ParseModifierPart to use Substring
|
||||
avoid unnecessary calls to strlen when evaluating modifiers
|
||||
migrate ModifyWord functions to use Substring
|
||||
migrate handling of the modifier ':S,from,to,' to Substring
|
||||
reduce debug logging and memory allocation for ${:U...}
|
||||
reduce verbosity of the -dv debug logging for standard cases
|
||||
clean up debug logging for ':M' and ':N'
|
||||
disallow '$' in the variable name of the modifier ':@'
|
||||
simplify access to the name of an expression during evaluation
|
||||
|
||||
2021-03-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210330
|
||||
Merge with NetBSD make, pick up
|
||||
o replace enum bit-field with struct bit-field for VarEvalFlags
|
||||
o rename VARE_NONE to VARE_PARSE_ONLY
|
||||
o var.c: rename ApplyModifiersState to ModChain
|
||||
fix double varname expansion in the variable modifier '::='
|
||||
change debug log for variable evaluation flags to lowercase
|
||||
|
||||
2021-03-14 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210314
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: avoid evaluating many modifiers in parse only mode
|
||||
in strict mode (-dL) many variable references are parsed twice,
|
||||
the first time just to report parse errors early, so we want to
|
||||
avoid side effects and wasted effort to the extent possible.
|
||||
|
||||
2021-02-26 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210226
|
||||
Merge with NetBSD make, pick up
|
||||
o remove freestanding freeIt variables
|
||||
link via FStr
|
||||
o var.c: restructure code in ParseVarname to target human readers
|
||||
improve error message for;
|
||||
bad modifier in variable expression
|
||||
unclosed modifier
|
||||
unknown modifier
|
||||
remove redundant parameter of ApplySingleModifier
|
||||
explain non-obvious code around indirect variable modifiers
|
||||
quote ':S' in error message about missing delimiter
|
||||
extract ParseModifier_Match into separate function
|
||||
add context information to error message about ':range' modifier
|
||||
add quotes around variable name in an error message
|
||||
reorder code in ModifyWords
|
||||
use more common parameter order for VarSelectWords
|
||||
make ModifyWord_Subst a little easier to understand
|
||||
do not expand variable name from the command line twice
|
||||
extract ExistsInCmdline from Var_SetWithFlags
|
||||
save a hash map lookup when defining a cmdline variable
|
||||
clean up VarAdd, Var_Delete, Var_ReexportVars
|
||||
use bit-shift expressions for VarFlags constants
|
||||
rename constants for VarFlags
|
||||
rename ExprDefined constants for debug logging
|
||||
rename ExprStatus to ExprDefined
|
||||
split parameters for evaluating variable expressions
|
||||
reduce redundant code around ModifyWords
|
||||
print error about failed shell command before overwriting variable
|
||||
clean up ValidShortVarname, ParseVarnameShort
|
||||
rename VarExprStatus to ExprStatus
|
||||
add functions for assigning the value of an expression
|
||||
rename ApplyModifiersState_Define to Expr_Define
|
||||
condense the code for parsing :S and :C modifiers
|
||||
|
||||
2021-02-06 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210206
|
||||
|
@ -63,6 +63,7 @@ realpath.c
|
||||
setenv.c
|
||||
sigcompat.c
|
||||
str.c
|
||||
str.h
|
||||
stresep.c
|
||||
strlcpy.c
|
||||
suff.c
|
||||
@ -399,6 +400,10 @@ unit-tests/job-flags.exp
|
||||
unit-tests/job-flags.mk
|
||||
unit-tests/job-output-long-lines.exp
|
||||
unit-tests/job-output-long-lines.mk
|
||||
unit-tests/job-output-null.exp
|
||||
unit-tests/job-output-null.mk
|
||||
unit-tests/jobs-empty-commands-error.exp
|
||||
unit-tests/jobs-empty-commands-error.mk
|
||||
unit-tests/jobs-empty-commands.exp
|
||||
unit-tests/jobs-empty-commands.mk
|
||||
unit-tests/jobs-error-indirect.exp
|
||||
@ -439,6 +444,8 @@ unit-tests/opt-debug-curdir.exp
|
||||
unit-tests/opt-debug-curdir.mk
|
||||
unit-tests/opt-debug-dir.exp
|
||||
unit-tests/opt-debug-dir.mk
|
||||
unit-tests/opt-debug-errors-jobs.exp
|
||||
unit-tests/opt-debug-errors-jobs.mk
|
||||
unit-tests/opt-debug-errors.exp
|
||||
unit-tests/opt-debug-errors.mk
|
||||
unit-tests/opt-debug-file.exp
|
||||
@ -627,6 +634,8 @@ unit-tests/var-class-local.exp
|
||||
unit-tests/var-class-local.mk
|
||||
unit-tests/var-class.exp
|
||||
unit-tests/var-class.mk
|
||||
unit-tests/var-eval-short.exp
|
||||
unit-tests/var-eval-short.mk
|
||||
unit-tests/var-op-append.exp
|
||||
unit-tests/var-op-append.mk
|
||||
unit-tests/var-op-assign.exp
|
||||
@ -675,6 +684,8 @@ unit-tests/varmod-l-name-to-value.exp
|
||||
unit-tests/varmod-l-name-to-value.mk
|
||||
unit-tests/varmod-localtime.exp
|
||||
unit-tests/varmod-localtime.mk
|
||||
unit-tests/varmod-loop-varname.exp
|
||||
unit-tests/varmod-loop-varname.mk
|
||||
unit-tests/varmod-loop.exp
|
||||
unit-tests/varmod-loop.mk
|
||||
unit-tests/varmod-match-escape.exp
|
||||
@ -709,6 +720,8 @@ unit-tests/varmod-subst-regex.exp
|
||||
unit-tests/varmod-subst-regex.mk
|
||||
unit-tests/varmod-subst.exp
|
||||
unit-tests/varmod-subst.mk
|
||||
unit-tests/varmod-sun-shell.exp
|
||||
unit-tests/varmod-sun-shell.mk
|
||||
unit-tests/varmod-sysv.exp
|
||||
unit-tests/varmod-sysv.mk
|
||||
unit-tests/varmod-tail.exp
|
||||
|
@ -1,2 +1,2 @@
|
||||
# keep this compatible with sh and make
|
||||
_MAKE_VERSION=20210206
|
||||
_MAKE_VERSION=20210621
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: arch.c,v 1.197 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: arch.c,v 1.200 2021/05/30 21:16:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -147,7 +147,7 @@ struct ar_hdr {
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */
|
||||
MAKE_RCSID("$NetBSD: arch.c,v 1.197 2021/02/05 05:15:12 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: arch.c,v 1.200 2021/05/30 21:16:54 rillig Exp $");
|
||||
|
||||
typedef struct List ArchList;
|
||||
typedef struct ListNode ArchListNode;
|
||||
@ -216,6 +216,19 @@ ArchFree(void *ap)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return "archive(member)". */
|
||||
static char *
|
||||
FullName(const char *archive, const char *member)
|
||||
{
|
||||
size_t len1 = strlen(archive);
|
||||
size_t len3 = strlen(member);
|
||||
char *result = bmake_malloc(len1 + 1 + len3 + 1 + 1);
|
||||
memcpy(result, archive, len1);
|
||||
memcpy(result + len1, "(", 1);
|
||||
memcpy(result + len1 + 1, member, len3);
|
||||
memcpy(result + len1 + 1 + len3, ")", 1 + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an archive specification such as "archive.a(member1 member2.${EXT})",
|
||||
@ -228,10 +241,10 @@ ArchFree(void *ap)
|
||||
* scope The scope in which to expand variables.
|
||||
*
|
||||
* Output:
|
||||
* return TRUE if it was a valid specification.
|
||||
* return True if it was a valid specification.
|
||||
* *pp Points to the first non-space after the archive spec.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
{
|
||||
char *cp; /* Pointer into line */
|
||||
@ -239,12 +252,12 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
MFStr libName; /* Library-part of specification */
|
||||
char *memName; /* Member-part of specification */
|
||||
char saveChar; /* Ending delimiter of member-name */
|
||||
Boolean expandLibName; /* Whether the parsed libName contains
|
||||
bool expandLibName; /* Whether the parsed libName contains
|
||||
* variable expressions that need to be
|
||||
* expanded */
|
||||
|
||||
libName = MFStr_InitRefer(*pp);
|
||||
expandLibName = FALSE;
|
||||
expandLibName = false;
|
||||
|
||||
for (cp = libName.str; *cp != '(' && *cp != '\0';) {
|
||||
if (*cp == '$') {
|
||||
@ -252,18 +265,18 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
/* XXX: This code can probably be shortened. */
|
||||
const char *nested_p = cp;
|
||||
FStr result;
|
||||
Boolean isError;
|
||||
bool isError;
|
||||
|
||||
/* XXX: is expanded twice: once here and once below */
|
||||
(void)Var_Parse(&nested_p, scope,
|
||||
VARE_WANTRES | VARE_UNDEFERR, &result);
|
||||
VARE_UNDEFERR, &result);
|
||||
/* TODO: handle errors */
|
||||
isError = result.str == var_Error;
|
||||
FStr_Done(&result);
|
||||
if (isError)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
expandLibName = TRUE;
|
||||
expandLibName = true;
|
||||
cp += nested_p - cp;
|
||||
} else
|
||||
cp++;
|
||||
@ -272,8 +285,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
*cp++ = '\0';
|
||||
if (expandLibName) {
|
||||
char *expanded;
|
||||
(void)Var_Subst(libName.str, scope,
|
||||
VARE_WANTRES | VARE_UNDEFERR, &expanded);
|
||||
(void)Var_Subst(libName.str, scope, VARE_UNDEFERR, &expanded);
|
||||
/* TODO: handle errors */
|
||||
libName = MFStr_InitOwn(expanded);
|
||||
}
|
||||
@ -285,7 +297,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
* place and skip to the end of it (either white-space or
|
||||
* a close paren).
|
||||
*/
|
||||
Boolean doSubst = FALSE;
|
||||
bool doSubst = false;
|
||||
|
||||
pp_skip_whitespace(&cp);
|
||||
|
||||
@ -295,20 +307,19 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
/* Expand nested variable expressions. */
|
||||
/* XXX: This code can probably be shortened. */
|
||||
FStr result;
|
||||
Boolean isError;
|
||||
bool isError;
|
||||
const char *nested_p = cp;
|
||||
|
||||
(void)Var_Parse(&nested_p, scope,
|
||||
VARE_WANTRES | VARE_UNDEFERR,
|
||||
&result);
|
||||
VARE_UNDEFERR, &result);
|
||||
/* TODO: handle errors */
|
||||
isError = result.str == var_Error;
|
||||
FStr_Done(&result);
|
||||
|
||||
if (isError)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
doSubst = TRUE;
|
||||
doSubst = true;
|
||||
cp += nested_p - cp;
|
||||
} else {
|
||||
cp++;
|
||||
@ -325,7 +336,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"No closing parenthesis "
|
||||
"in archive specification");
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -355,16 +366,15 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
char *p;
|
||||
char *unexpandedMemName = memName;
|
||||
|
||||
(void)Var_Subst(memName, scope,
|
||||
VARE_WANTRES | VARE_UNDEFERR,
|
||||
&memName);
|
||||
(void)Var_Subst(memName, scope, VARE_UNDEFERR,
|
||||
&memName);
|
||||
/* TODO: handle errors */
|
||||
|
||||
/*
|
||||
* Now form an archive spec and recurse to deal with
|
||||
* nested variables and multi-word variable values.
|
||||
*/
|
||||
fullName = str_concat4(libName.str, "(", memName, ")");
|
||||
fullName = FullName(libName.str, memName);
|
||||
p = fullName;
|
||||
|
||||
if (strchr(memName, '$') != NULL &&
|
||||
@ -383,7 +393,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
/* Error in nested call. */
|
||||
free(fullName);
|
||||
/* XXX: does unexpandedMemName leak? */
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
free(fullName);
|
||||
/* XXX: does unexpandedMemName leak? */
|
||||
@ -394,8 +404,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
|
||||
while (!Lst_IsEmpty(&members)) {
|
||||
char *member = Lst_Dequeue(&members);
|
||||
char *fullname = str_concat4(libName.str, "(",
|
||||
member, ")");
|
||||
char *fullname = FullName(libName.str, member);
|
||||
free(member);
|
||||
|
||||
gn = Targ_GetNode(fullname);
|
||||
@ -407,8 +416,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
Lst_Done(&members);
|
||||
|
||||
} else {
|
||||
char *fullname = str_concat4(libName.str, "(", memName,
|
||||
")");
|
||||
char *fullname = FullName(libName.str, memName);
|
||||
gn = Targ_GetNode(fullname);
|
||||
free(fullname);
|
||||
|
||||
@ -434,7 +442,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
/* We promised that pp would be set up at the next non-space. */
|
||||
pp_skip_whitespace(&cp);
|
||||
*pp = cp;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -444,7 +452,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
* Input:
|
||||
* archive Path to the archive
|
||||
* member Name of member; only its basename is used.
|
||||
* addToCache TRUE if archive should be cached if not already so.
|
||||
* addToCache True if archive should be cached if not already so.
|
||||
*
|
||||
* Results:
|
||||
* The ar_hdr for the member, or NULL.
|
||||
@ -452,7 +460,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
* See ArchFindMember for an almost identical copy of this code.
|
||||
*/
|
||||
static struct ar_hdr *
|
||||
ArchStatMember(const char *archive, const char *member, Boolean addToCache)
|
||||
ArchStatMember(const char *archive, const char *member, bool addToCache)
|
||||
{
|
||||
#define AR_MAX_NAME_LEN (sizeof arh.ar_name - 1)
|
||||
FILE *arch;
|
||||
@ -713,7 +721,7 @@ ArchSVR4Entry(Arch *ar, char *inout_name, size_t size, FILE *arch)
|
||||
#endif
|
||||
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
ArchiveMember_HasName(const struct ar_hdr *hdr,
|
||||
const char *name, size_t namelen)
|
||||
{
|
||||
@ -721,22 +729,22 @@ ArchiveMember_HasName(const struct ar_hdr *hdr,
|
||||
const char *ar_name = hdr->AR_NAME;
|
||||
|
||||
if (strncmp(ar_name, name, namelen) != 0)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (namelen >= ar_name_len)
|
||||
return namelen == ar_name_len;
|
||||
|
||||
/* hdr->AR_NAME is space-padded to the right. */
|
||||
if (ar_name[namelen] == ' ')
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
/* In archives created by GNU binutils 2.27, the member names end with
|
||||
* a slash. */
|
||||
if (ar_name[namelen] == '/' &&
|
||||
(namelen == ar_name_len || ar_name[namelen + 1] == ' '))
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -951,7 +959,7 @@ Arch_UpdateMTime(GNode *gn)
|
||||
{
|
||||
struct ar_hdr *arh;
|
||||
|
||||
arh = ArchStatMember(GNode_VarArchive(gn), GNode_VarMember(gn), TRUE);
|
||||
arh = ArchStatMember(GNode_VarArchive(gn), GNode_VarMember(gn), true);
|
||||
if (arh != NULL)
|
||||
gn->mtime = (time_t)strtol(arh->ar_date, NULL, 10);
|
||||
else
|
||||
@ -1058,26 +1066,26 @@ Arch_FindLib(GNode *gn, SearchPath *path)
|
||||
* since this is used by 'ar' rules that affect the data contents of the
|
||||
* archive, not by ranlib rules, which affect the TOC.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
Arch_LibOODate(GNode *gn)
|
||||
{
|
||||
Boolean oodate;
|
||||
bool oodate;
|
||||
|
||||
if (gn->type & OP_PHONY) {
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
} else if (!GNode_IsTarget(gn) && Lst_IsEmpty(&gn->children)) {
|
||||
oodate = FALSE;
|
||||
oodate = false;
|
||||
} else if ((!Lst_IsEmpty(&gn->children) && gn->youngestChild == NULL) ||
|
||||
(gn->mtime > now) ||
|
||||
(gn->youngestChild != NULL &&
|
||||
gn->mtime < gn->youngestChild->mtime)) {
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
} else {
|
||||
#ifdef RANLIBMAG
|
||||
struct ar_hdr *arh; /* Header for __.SYMDEF */
|
||||
int modTimeTOC; /* The table-of-contents' mod time */
|
||||
|
||||
arh = ArchStatMember(gn->path, RANLIBMAG, FALSE);
|
||||
arh = ArchStatMember(gn->path, RANLIBMAG, false);
|
||||
|
||||
if (arh != NULL) {
|
||||
modTimeTOC = (int)strtol(arh->ar_date, NULL, 10);
|
||||
@ -1094,10 +1102,10 @@ Arch_LibOODate(GNode *gn)
|
||||
*/
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
debug_printf("no toc...");
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
}
|
||||
#else
|
||||
oodate = FALSE;
|
||||
oodate = false;
|
||||
#endif
|
||||
}
|
||||
return oodate;
|
||||
@ -1119,7 +1127,7 @@ Arch_End(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
Boolean
|
||||
bool
|
||||
Arch_IsLib(GNode *gn)
|
||||
{
|
||||
static const char armag[] = "!<arch>\n";
|
||||
@ -1127,11 +1135,11 @@ Arch_IsLib(GNode *gn)
|
||||
int fd;
|
||||
|
||||
if ((fd = open(gn->path, O_RDONLY)) == -1)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (read(fd, buf, sizeof buf) != sizeof buf) {
|
||||
(void)close(fd);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.h,v 1.42 2021/01/30 21:25:10 rillig Exp $ */
|
||||
/* $NetBSD: buf.h,v 1.43 2021/04/03 11:08:40 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -101,7 +101,7 @@ Buf_AddByte(Buffer *buf, char byte)
|
||||
end[1] = '\0';
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
Buf_EndsWith(const Buffer *buf, char ch)
|
||||
{
|
||||
return buf->len > 0 && buf->data[buf->len - 1] == ch;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.c,v 1.224 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: compat.c,v 1.227 2021/04/27 15:19:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -99,7 +99,7 @@
|
||||
#include "pathnames.h"
|
||||
|
||||
/* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: compat.c,v 1.224 2021/02/05 05:15:12 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: compat.c,v 1.227 2021/04/27 15:19:25 christos Exp $");
|
||||
|
||||
static GNode *curTarg = NULL;
|
||||
static pid_t compatChild;
|
||||
@ -164,7 +164,7 @@ CompatInterrupt(int signo)
|
||||
}
|
||||
|
||||
static void
|
||||
DebugFailedTarget(const char *cmd, GNode *gn)
|
||||
DebugFailedTarget(const char *cmd, const GNode *gn)
|
||||
{
|
||||
const char *p = cmd;
|
||||
debug_printf("\n*** Failed target: %s\n*** Failed command: ",
|
||||
@ -184,7 +184,7 @@ DebugFailedTarget(const char *cmd, GNode *gn)
|
||||
debug_printf("\n");
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
UseShell(const char *cmd MAKE_ATTR_UNUSED)
|
||||
{
|
||||
#if !defined(MAKE_NATIVE)
|
||||
@ -194,7 +194,7 @@ UseShell(const char *cmd MAKE_ATTR_UNUSED)
|
||||
* behaviour. Or perhaps the shell has been replaced with something
|
||||
* that does extra logging, and that should not be bypassed.
|
||||
*/
|
||||
return TRUE;
|
||||
return true;
|
||||
#else
|
||||
/*
|
||||
* Search for meta characters in the command. If there are no meta
|
||||
@ -227,22 +227,22 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
|
||||
{
|
||||
char *cmdStart; /* Start of expanded command */
|
||||
char *bp;
|
||||
Boolean silent; /* Don't print command */
|
||||
Boolean doIt; /* Execute even if -n */
|
||||
volatile Boolean errCheck; /* Check errors */
|
||||
bool silent; /* Don't print command */
|
||||
bool doIt; /* Execute even if -n */
|
||||
volatile bool errCheck; /* Check errors */
|
||||
WAIT_T reason; /* Reason for child's death */
|
||||
WAIT_T status; /* Description of child's death */
|
||||
pid_t cpid; /* Child actually found */
|
||||
pid_t retstat; /* Result of wait */
|
||||
const char **volatile av; /* Argument vector for thing to exec */
|
||||
char **volatile mav; /* Copy of the argument vector for freeing */
|
||||
Boolean useShell; /* TRUE if command should be executed
|
||||
bool useShell; /* True if command should be executed
|
||||
* using a shell */
|
||||
const char *volatile cmd = cmdp;
|
||||
|
||||
silent = (gn->type & OP_SILENT) != 0;
|
||||
errCheck = !(gn->type & OP_IGNORE);
|
||||
doIt = FALSE;
|
||||
doIt = false;
|
||||
|
||||
(void)Var_Subst(cmd, gn, VARE_WANTRES, &cmdStart);
|
||||
/* TODO: handle errors */
|
||||
@ -281,9 +281,9 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
|
||||
if (*cmd == '@')
|
||||
silent = !DEBUG(LOUD);
|
||||
else if (*cmd == '-')
|
||||
errCheck = FALSE;
|
||||
errCheck = false;
|
||||
else if (*cmd == '+') {
|
||||
doIt = TRUE;
|
||||
doIt = true;
|
||||
if (shellName == NULL) /* we came here from jobs */
|
||||
Shell_Init();
|
||||
} else
|
||||
@ -343,7 +343,7 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
|
||||
* command into words to form an argument vector we can
|
||||
* execute.
|
||||
*/
|
||||
Words words = Str_Words(cmd, FALSE);
|
||||
Words words = Str_Words(cmd, false);
|
||||
mav = words.words;
|
||||
bp = words.freeIt;
|
||||
av = (void *)mav;
|
||||
@ -392,7 +392,7 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
|
||||
*/
|
||||
while ((retstat = wait(&reason)) != cpid) {
|
||||
if (retstat > 0)
|
||||
JobReapChild(retstat, reason, FALSE); /* not ours? */
|
||||
JobReapChild(retstat, reason, false); /* not ours? */
|
||||
if (retstat == -1 && errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
@ -425,7 +425,7 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
|
||||
if (errCheck) {
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_job_error(NULL, gn, FALSE, status);
|
||||
meta_job_error(NULL, gn, false, status);
|
||||
}
|
||||
#endif
|
||||
gn->made = ERROR;
|
||||
@ -483,7 +483,7 @@ MakeNodes(GNodeList *gnodes, GNode *pgn)
|
||||
}
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
MakeUnmade(GNode *gn, GNode *pgn)
|
||||
{
|
||||
|
||||
@ -493,7 +493,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
* First mark ourselves to be made, then apply whatever transformations
|
||||
* the suffix module thinks are necessary. Once that's done, we can
|
||||
* descend and make all our children. If any of them has an error
|
||||
* but the -k flag was given, our 'make' field will be set to FALSE
|
||||
* but the -k flag was given, our 'make' field will be set to false
|
||||
* again. This is our signal to not attempt to do anything but abort
|
||||
* our parent as well.
|
||||
*/
|
||||
@ -508,7 +508,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
if (!(gn->flags & REMAKE)) {
|
||||
gn->made = ABORTED;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Lst_FindDatum(&gn->implicitParents, pgn) != NULL)
|
||||
@ -524,7 +524,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
if (!GNode_IsOODate(gn)) {
|
||||
gn->made = UPTODATE;
|
||||
DEBUG0(MAKE, "up-to-date.\n");
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -539,7 +539,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
* We need to be re-made.
|
||||
* Ensure that $? (.OODATE) and $> (.ALLSRC) are both set.
|
||||
*/
|
||||
Make_DoAllVar(gn);
|
||||
GNode_SetLocalVars(gn);
|
||||
|
||||
/*
|
||||
* Alter our type to tell if errors should be ignored or things
|
||||
@ -596,7 +596,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cond.c,v 1.256 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: cond.c,v 1.267 2021/06/11 14:52:03 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -95,7 +95,7 @@
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
|
||||
MAKE_RCSID("$NetBSD: cond.c,v 1.256 2021/02/05 05:15:12 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: cond.c,v 1.267 2021/06/11 14:52:03 rillig Exp $");
|
||||
|
||||
/*
|
||||
* The parsing of conditional expressions is based on this grammar:
|
||||
@ -148,11 +148,11 @@ typedef struct CondParser {
|
||||
* expression has length > 0. The other '.if' variants delegate
|
||||
* to evalBare instead.
|
||||
*/
|
||||
Boolean plain;
|
||||
bool plain;
|
||||
|
||||
/* The function to apply on unquoted bare words. */
|
||||
Boolean (*evalBare)(size_t, const char *);
|
||||
Boolean negateEvalBare;
|
||||
bool (*evalBare)(size_t, const char *);
|
||||
bool negateEvalBare;
|
||||
|
||||
const char *p; /* The remaining condition to parse */
|
||||
Token curr; /* Single push-back token used in parsing */
|
||||
@ -163,10 +163,10 @@ typedef struct CondParser {
|
||||
* specific one, therefore it makes sense to suppress the standard
|
||||
* "Malformed conditional" message.
|
||||
*/
|
||||
Boolean printedError;
|
||||
bool printedError;
|
||||
} CondParser;
|
||||
|
||||
static CondResult CondParser_Or(CondParser *par, Boolean);
|
||||
static CondResult CondParser_Or(CondParser *par, bool);
|
||||
|
||||
static unsigned int cond_depth = 0; /* current .if nesting level */
|
||||
static unsigned int cond_min_depth = 0; /* depth at makefile open */
|
||||
@ -178,21 +178,21 @@ static const char *opname[] = { "<", "<=", ">", ">=", "==", "!=" };
|
||||
* In strict mode, the lhs must be a variable expression or a string literal
|
||||
* in quotes. In non-strict mode it may also be an unquoted string literal.
|
||||
*
|
||||
* TRUE when CondEvalExpression is called from Cond_EvalLine (.if etc)
|
||||
* FALSE when CondEvalExpression is called from ApplyModifier_IfElse
|
||||
* True when CondEvalExpression is called from Cond_EvalLine (.if etc).
|
||||
* False when CondEvalExpression is called from ApplyModifier_IfElse
|
||||
* since lhs is already expanded, and at that point we cannot tell if
|
||||
* it was a variable reference or not.
|
||||
*/
|
||||
static Boolean lhsStrict;
|
||||
static bool lhsStrict;
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
is_token(const char *str, const char *tok, size_t len)
|
||||
{
|
||||
return strncmp(str, tok, len) == 0 && !ch_isalpha(str[len]);
|
||||
}
|
||||
|
||||
static Token
|
||||
ToToken(Boolean cond)
|
||||
ToToken(bool cond)
|
||||
{
|
||||
return cond ? TOK_TRUE : TOK_FALSE;
|
||||
}
|
||||
@ -228,7 +228,7 @@ CondParser_SkipWhitespace(CondParser *par)
|
||||
* Return the length of the argument, or 0 on error.
|
||||
*/
|
||||
static size_t
|
||||
ParseFuncArg(CondParser *par, const char **pp, Boolean doEval, const char *func,
|
||||
ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func,
|
||||
char **out_arg)
|
||||
{
|
||||
const char *p = *pp;
|
||||
@ -264,11 +264,11 @@ ParseFuncArg(CondParser *par, const char **pp, Boolean doEval, const char *func,
|
||||
* so we don't need to do it. Nor do we return an
|
||||
* error, though perhaps we should.
|
||||
*/
|
||||
VarEvalFlags eflags = doEval
|
||||
? VARE_WANTRES | VARE_UNDEFERR
|
||||
: VARE_NONE;
|
||||
VarEvalMode emode = doEval
|
||||
? VARE_UNDEFERR
|
||||
: VARE_PARSE_ONLY;
|
||||
FStr nestedVal;
|
||||
(void)Var_Parse(&p, SCOPE_CMDLINE, eflags, &nestedVal);
|
||||
(void)Var_Parse(&p, SCOPE_CMDLINE, emode, &nestedVal);
|
||||
/* TODO: handle errors */
|
||||
Buf_AddStr(&argBuf, nestedVal.str);
|
||||
FStr_Done(&nestedVal);
|
||||
@ -290,7 +290,7 @@ ParseFuncArg(CondParser *par, const char **pp, Boolean doEval, const char *func,
|
||||
if (func != NULL && *p++ != ')') {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Missing closing parenthesis for %s()", func);
|
||||
par->printedError = TRUE;
|
||||
par->printedError = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -300,34 +300,34 @@ ParseFuncArg(CondParser *par, const char **pp, Boolean doEval, const char *func,
|
||||
|
||||
/* Test whether the given variable is defined. */
|
||||
/*ARGSUSED*/
|
||||
static Boolean
|
||||
static bool
|
||||
FuncDefined(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
{
|
||||
FStr value = Var_Value(SCOPE_CMDLINE, arg);
|
||||
Boolean result = value.str != NULL;
|
||||
bool result = value.str != NULL;
|
||||
FStr_Done(&value);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* See if the given target is being made. */
|
||||
/*ARGSUSED*/
|
||||
static Boolean
|
||||
static bool
|
||||
FuncMake(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
{
|
||||
StringListNode *ln;
|
||||
|
||||
for (ln = opts.create.first; ln != NULL; ln = ln->next)
|
||||
if (Str_Match(ln->datum, arg))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See if the given file exists. */
|
||||
/*ARGSUSED*/
|
||||
static Boolean
|
||||
static bool
|
||||
FuncExists(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
{
|
||||
Boolean result;
|
||||
bool result;
|
||||
char *path;
|
||||
|
||||
path = Dir_FindFile(arg, &dirSearchPath);
|
||||
@ -340,7 +340,7 @@ FuncExists(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
|
||||
/* See if the given node exists and is an actual target. */
|
||||
/*ARGSUSED*/
|
||||
static Boolean
|
||||
static bool
|
||||
FuncTarget(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
{
|
||||
GNode *gn = Targ_FindNode(arg);
|
||||
@ -352,7 +352,7 @@ FuncTarget(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
* associated with it.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static Boolean
|
||||
static bool
|
||||
FuncCommands(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
{
|
||||
GNode *gn = Targ_FindNode(arg);
|
||||
@ -365,10 +365,10 @@ FuncCommands(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
* then we try a floating point conversion instead.
|
||||
*
|
||||
* Results:
|
||||
* Returns TRUE if the conversion succeeded.
|
||||
* Returns true if the conversion succeeded.
|
||||
* Sets 'out_value' to the converted number.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
TryParseNumber(const char *str, double *out_value)
|
||||
{
|
||||
char *end;
|
||||
@ -378,29 +378,30 @@ TryParseNumber(const char *str, double *out_value)
|
||||
errno = 0;
|
||||
if (str[0] == '\0') { /* XXX: why is an empty string a number? */
|
||||
*out_value = 0.0;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
ul_val = strtoul(str, &end, str[1] == 'x' ? 16 : 10);
|
||||
if (*end == '\0' && errno != ERANGE) {
|
||||
*out_value = str[0] == '-' ? -(double)-ul_val : (double)ul_val;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*end != '\0' && *end != '.' && *end != 'e' && *end != 'E')
|
||||
return FALSE; /* skip the expensive strtod call */
|
||||
return false; /* skip the expensive strtod call */
|
||||
dbl_val = strtod(str, &end);
|
||||
if (*end != '\0')
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
*out_value = dbl_val;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
is_separator(char ch)
|
||||
{
|
||||
return ch == '\0' || ch_isspace(ch) || strchr("!=><)", ch) != NULL;
|
||||
return ch == '\0' || ch_isspace(ch) || ch == '!' || ch == '=' ||
|
||||
ch == '>' || ch == '<' || ch == ')' /* but not '(' */;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -409,24 +410,24 @@ is_separator(char ch)
|
||||
*
|
||||
* Example: .if x${CENTER}y == "${PREFIX}${SUFFIX}" || 0x${HEX}
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
CondParser_StringExpr(CondParser *par, const char *start,
|
||||
Boolean const doEval, Boolean const quoted,
|
||||
bool const doEval, bool const quoted,
|
||||
Buffer *buf, FStr *const inout_str)
|
||||
{
|
||||
VarEvalFlags eflags;
|
||||
VarEvalMode emode;
|
||||
const char *nested_p;
|
||||
Boolean atStart;
|
||||
bool atStart;
|
||||
VarParseResult parseResult;
|
||||
|
||||
/* if we are in quotes, an undefined variable is ok */
|
||||
eflags = doEval && !quoted ? VARE_WANTRES | VARE_UNDEFERR
|
||||
emode = doEval && !quoted ? VARE_UNDEFERR
|
||||
: doEval ? VARE_WANTRES
|
||||
: VARE_NONE;
|
||||
: VARE_PARSE_ONLY;
|
||||
|
||||
nested_p = par->p;
|
||||
atStart = nested_p == start;
|
||||
parseResult = Var_Parse(&nested_p, SCOPE_CMDLINE, eflags, inout_str);
|
||||
parseResult = Var_Parse(&nested_p, SCOPE_CMDLINE, emode, inout_str);
|
||||
/* TODO: handle errors */
|
||||
if (inout_str->str == var_Error) {
|
||||
if (parseResult == VPR_ERR) {
|
||||
@ -436,11 +437,11 @@ CondParser_StringExpr(CondParser *par, const char *start,
|
||||
*
|
||||
* See cond-token-plain.mk $$$$$$$$.
|
||||
*/
|
||||
par->printedError = TRUE;
|
||||
par->printedError = true;
|
||||
}
|
||||
/*
|
||||
* XXX: Can there be any situation in which a returned
|
||||
* var_Error requires freeIt?
|
||||
* var_Error needs to be freed?
|
||||
*/
|
||||
FStr_Done(inout_str);
|
||||
/*
|
||||
@ -448,7 +449,7 @@ CondParser_StringExpr(CondParser *par, const char *start,
|
||||
* what getting var_Error back with !doEval means.
|
||||
*/
|
||||
*inout_str = FStr_InitRefer(NULL);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
par->p = nested_p;
|
||||
|
||||
@ -458,30 +459,30 @@ CondParser_StringExpr(CondParser *par, const char *start,
|
||||
* comparison operator or is the end of the expression, we are done.
|
||||
*/
|
||||
if (atStart && is_separator(par->p[0]))
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
Buf_AddStr(buf, inout_str->str);
|
||||
FStr_Done(inout_str);
|
||||
*inout_str = FStr_InitRefer(NULL); /* not finished yet */
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a string from a variable reference or an optionally quoted
|
||||
* string. This is called for the lhs and rhs of string comparisons.
|
||||
* Parse a string from a variable expression or an optionally quoted
|
||||
* string. This is called for the left-hand and right-hand sides of
|
||||
* comparisons.
|
||||
*
|
||||
* Results:
|
||||
* Returns the string, absent any quotes, or NULL on error.
|
||||
* Sets out_quoted if the string was quoted.
|
||||
* Sets out_freeIt.
|
||||
* Sets out_quoted if the leaf was a quoted string literal.
|
||||
*/
|
||||
static void
|
||||
CondParser_String(CondParser *par, Boolean doEval, Boolean strictLHS,
|
||||
FStr *out_str, Boolean *out_quoted)
|
||||
CondParser_Leaf(CondParser *par, bool doEval, bool strictLHS,
|
||||
FStr *out_str, bool *out_quoted)
|
||||
{
|
||||
Buffer buf;
|
||||
FStr str;
|
||||
Boolean quoted;
|
||||
bool quoted;
|
||||
const char *start;
|
||||
|
||||
Buf_Init(&buf);
|
||||
@ -541,14 +542,14 @@ CondParser_String(CondParser *par, Boolean doEval, Boolean strictLHS,
|
||||
got_str:
|
||||
str = FStr_InitOwn(buf.data);
|
||||
cleanup:
|
||||
Buf_DoneData(&buf);
|
||||
Buf_DoneData(&buf); /* XXX: memory leak on failure? */
|
||||
*out_str = str;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
If_Eval(const CondParser *par, const char *arg, size_t arglen)
|
||||
static bool
|
||||
EvalBare(const CondParser *par, const char *arg, size_t arglen)
|
||||
{
|
||||
Boolean res = par->evalBare(arglen, arg);
|
||||
bool res = par->evalBare(arglen, arg);
|
||||
return par->negateEvalBare ? !res : res;
|
||||
}
|
||||
|
||||
@ -556,8 +557,8 @@ If_Eval(const CondParser *par, const char *arg, size_t arglen)
|
||||
* Evaluate a "comparison without operator", such as in ".if ${VAR}" or
|
||||
* ".if 0".
|
||||
*/
|
||||
static Boolean
|
||||
EvalNotEmpty(CondParser *par, const char *value, Boolean quoted)
|
||||
static bool
|
||||
EvalNotEmpty(CondParser *par, const char *value, bool quoted)
|
||||
{
|
||||
double num;
|
||||
|
||||
@ -576,11 +577,11 @@ EvalNotEmpty(CondParser *par, const char *value, Boolean quoted)
|
||||
if (par->plain)
|
||||
return value[0] != '\0';
|
||||
|
||||
return If_Eval(par, value, strlen(value));
|
||||
return EvalBare(par, value, strlen(value));
|
||||
}
|
||||
|
||||
/* Evaluate a numerical comparison, such as in ".if ${VAR} >= 9". */
|
||||
static Boolean
|
||||
static bool
|
||||
EvalCompareNum(double lhs, ComparisonOp op, double rhs)
|
||||
{
|
||||
DEBUG3(COND, "lhs = %f, rhs = %f, op = %.2s\n", lhs, rhs, opname[op]);
|
||||
@ -608,7 +609,7 @@ EvalCompareStr(CondParser *par, const char *lhs,
|
||||
if (op != EQ && op != NE) {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"String comparison operator must be either == or !=");
|
||||
par->printedError = TRUE;
|
||||
par->printedError = true;
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
@ -619,8 +620,8 @@ EvalCompareStr(CondParser *par, const char *lhs,
|
||||
|
||||
/* Evaluate a comparison, such as "${VAR} == 12345". */
|
||||
static Token
|
||||
EvalCompare(CondParser *par, const char *lhs, Boolean lhsQuoted,
|
||||
ComparisonOp op, const char *rhs, Boolean rhsQuoted)
|
||||
EvalCompare(CondParser *par, const char *lhs, bool lhsQuoted,
|
||||
ComparisonOp op, const char *rhs, bool rhsQuoted)
|
||||
{
|
||||
double left, right;
|
||||
|
||||
@ -631,7 +632,7 @@ EvalCompare(CondParser *par, const char *lhs, Boolean lhsQuoted,
|
||||
return EvalCompareStr(par, lhs, op, rhs);
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
CondParser_ComparisonOp(CondParser *par, ComparisonOp *out_op)
|
||||
{
|
||||
const char *p = par->p;
|
||||
@ -655,14 +656,14 @@ CondParser_ComparisonOp(CondParser *par, ComparisonOp *out_op)
|
||||
*out_op = NE;
|
||||
goto length_2;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
length_2:
|
||||
par->p = p + 2;
|
||||
return TRUE;
|
||||
return true;
|
||||
length_1:
|
||||
par->p = p + 1;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -674,18 +675,18 @@ length_1:
|
||||
* ${VAR:U0} < 12345
|
||||
*/
|
||||
static Token
|
||||
CondParser_Comparison(CondParser *par, Boolean doEval)
|
||||
CondParser_Comparison(CondParser *par, bool doEval)
|
||||
{
|
||||
Token t = TOK_ERROR;
|
||||
FStr lhs, rhs;
|
||||
ComparisonOp op;
|
||||
Boolean lhsQuoted, rhsQuoted;
|
||||
bool lhsQuoted, rhsQuoted;
|
||||
|
||||
/*
|
||||
* Parse the variable spec and skip over it, saving its
|
||||
* value in lhs.
|
||||
*/
|
||||
CondParser_String(par, doEval, lhsStrict, &lhs, &lhsQuoted);
|
||||
CondParser_Leaf(par, doEval, lhsStrict, &lhs, &lhsQuoted);
|
||||
if (lhs.str == NULL)
|
||||
goto done_lhs;
|
||||
|
||||
@ -702,11 +703,11 @@ CondParser_Comparison(CondParser *par, Boolean doEval)
|
||||
if (par->p[0] == '\0') {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Missing right-hand-side of operator '%s'", opname[op]);
|
||||
par->printedError = TRUE;
|
||||
par->printedError = true;
|
||||
goto done_lhs;
|
||||
}
|
||||
|
||||
CondParser_String(par, doEval, FALSE, &rhs, &rhsQuoted);
|
||||
CondParser_Leaf(par, doEval, false, &rhs, &rhsQuoted);
|
||||
if (rhs.str == NULL)
|
||||
goto done_rhs;
|
||||
|
||||
@ -731,7 +732,7 @@ done_lhs:
|
||||
/*ARGSUSED*/
|
||||
static size_t
|
||||
ParseEmptyArg(CondParser *par MAKE_ATTR_UNUSED, const char **pp,
|
||||
Boolean doEval, const char *func MAKE_ATTR_UNUSED,
|
||||
bool doEval, const char *func MAKE_ATTR_UNUSED,
|
||||
char **out_arg)
|
||||
{
|
||||
FStr val;
|
||||
@ -741,8 +742,8 @@ ParseEmptyArg(CondParser *par MAKE_ATTR_UNUSED, const char **pp,
|
||||
*out_arg = NULL;
|
||||
|
||||
(*pp)--; /* Make (*pp)[1] point to the '('. */
|
||||
(void)Var_Parse(pp, SCOPE_CMDLINE, doEval ? VARE_WANTRES : VARE_NONE,
|
||||
&val);
|
||||
(void)Var_Parse(pp, SCOPE_CMDLINE,
|
||||
doEval ? VARE_WANTRES : VARE_PARSE_ONLY, &val);
|
||||
/* TODO: handle errors */
|
||||
/* If successful, *pp points beyond the closing ')' now. */
|
||||
|
||||
@ -767,22 +768,23 @@ ParseEmptyArg(CondParser *par MAKE_ATTR_UNUSED, const char **pp,
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static Boolean
|
||||
static bool
|
||||
FuncEmpty(size_t arglen, const char *arg MAKE_ATTR_UNUSED)
|
||||
{
|
||||
/* Magic values ahead, see ParseEmptyArg. */
|
||||
return arglen == 1;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
CondParser_Func(CondParser *par, Boolean doEval, Token *out_token)
|
||||
/* Parse a function call expression, such as 'defined(${file})'. */
|
||||
static bool
|
||||
CondParser_FuncCall(CondParser *par, bool doEval, Token *out_token)
|
||||
{
|
||||
static const struct fn_def {
|
||||
const char *fn_name;
|
||||
size_t fn_name_len;
|
||||
size_t (*fn_parse)(CondParser *, const char **, Boolean,
|
||||
size_t (*fn_parse)(CondParser *, const char **, bool,
|
||||
const char *, char **);
|
||||
Boolean (*fn_eval)(size_t, const char *);
|
||||
bool (*fn_eval)(size_t, const char *);
|
||||
} fns[] = {
|
||||
{ "defined", 7, ParseFuncArg, FuncDefined },
|
||||
{ "make", 4, ParseFuncArg, FuncMake },
|
||||
@ -810,25 +812,25 @@ CondParser_Func(CondParser *par, Boolean doEval, Token *out_token)
|
||||
if (arglen == 0 || arglen == (size_t)-1) {
|
||||
par->p = cp;
|
||||
*out_token = arglen == 0 ? TOK_FALSE : TOK_ERROR;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Evaluate the argument using the required function. */
|
||||
*out_token = ToToken(!doEval || fn->fn_eval(arglen, arg));
|
||||
free(arg);
|
||||
par->p = cp;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a function call, a number, a variable expression or a string
|
||||
* literal.
|
||||
* Parse a comparison such as '${VAR} == "value"', or a simple leaf without
|
||||
* operator, which is a number, a variable expression or a string literal.
|
||||
*/
|
||||
static Token
|
||||
CondParser_LeafToken(CondParser *par, Boolean doEval)
|
||||
CondParser_ComparisonOrLeaf(CondParser *par, bool doEval)
|
||||
{
|
||||
Token t;
|
||||
char *arg = NULL;
|
||||
@ -836,9 +838,6 @@ CondParser_LeafToken(CondParser *par, Boolean doEval)
|
||||
const char *cp;
|
||||
const char *cp1;
|
||||
|
||||
if (CondParser_Func(par, doEval, &t))
|
||||
return t;
|
||||
|
||||
/* Push anything numeric through the compare expression */
|
||||
cp = par->p;
|
||||
if (ch_isdigit(cp[0]) || cp[0] == '-' || cp[0] == '+')
|
||||
@ -852,10 +851,14 @@ CondParser_LeafToken(CondParser *par, Boolean doEval)
|
||||
* syntax would be invalid if we did "defined(a)" - so instead treat
|
||||
* as an expression.
|
||||
*/
|
||||
/*
|
||||
* XXX: Is it possible to have a variable expression evaluated twice
|
||||
* at this point?
|
||||
*/
|
||||
arglen = ParseFuncArg(par, &cp, doEval, NULL, &arg);
|
||||
cp1 = cp;
|
||||
cpp_skip_whitespace(&cp1);
|
||||
if (*cp1 == '=' || *cp1 == '!')
|
||||
if (*cp1 == '=' || *cp1 == '!' || *cp1 == '<' || *cp1 == '>')
|
||||
return CondParser_Comparison(par, doEval);
|
||||
par->p = cp;
|
||||
|
||||
@ -865,14 +868,14 @@ CondParser_LeafToken(CondParser *par, Boolean doEval)
|
||||
* after .if must have been taken literally, so the argument cannot
|
||||
* be empty - even if it contained a variable expansion.
|
||||
*/
|
||||
t = ToToken(!doEval || If_Eval(par, arg, arglen));
|
||||
t = ToToken(!doEval || EvalBare(par, arg, arglen));
|
||||
free(arg);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Return the next token or comparison result from the parser. */
|
||||
static Token
|
||||
CondParser_Token(CondParser *par, Boolean doEval)
|
||||
CondParser_Token(CondParser *par, bool doEval)
|
||||
{
|
||||
Token t;
|
||||
|
||||
@ -900,7 +903,7 @@ CondParser_Token(CondParser *par, Boolean doEval)
|
||||
par->p++;
|
||||
else if (opts.strict) {
|
||||
Parse_Error(PARSE_FATAL, "Unknown operator '|'");
|
||||
par->printedError = TRUE;
|
||||
par->printedError = true;
|
||||
return TOK_ERROR;
|
||||
}
|
||||
return TOK_OR;
|
||||
@ -911,7 +914,7 @@ CondParser_Token(CondParser *par, Boolean doEval)
|
||||
par->p++;
|
||||
else if (opts.strict) {
|
||||
Parse_Error(PARSE_FATAL, "Unknown operator '&'");
|
||||
par->printedError = TRUE;
|
||||
par->printedError = true;
|
||||
return TOK_ERROR;
|
||||
}
|
||||
return TOK_AND;
|
||||
@ -931,7 +934,9 @@ CondParser_Token(CondParser *par, Boolean doEval)
|
||||
return CondParser_Comparison(par, doEval);
|
||||
|
||||
default:
|
||||
return CondParser_LeafToken(par, doEval);
|
||||
if (CondParser_FuncCall(par, doEval, &t))
|
||||
return t;
|
||||
return CondParser_ComparisonOrLeaf(par, doEval);
|
||||
}
|
||||
}
|
||||
|
||||
@ -942,7 +947,7 @@ CondParser_Token(CondParser *par, Boolean doEval)
|
||||
* Term -> Leaf
|
||||
*/
|
||||
static CondResult
|
||||
CondParser_Term(CondParser *par, Boolean doEval)
|
||||
CondParser_Term(CondParser *par, bool doEval)
|
||||
{
|
||||
CondResult res;
|
||||
Token t;
|
||||
@ -979,7 +984,7 @@ CondParser_Term(CondParser *par, Boolean doEval)
|
||||
* And -> Term
|
||||
*/
|
||||
static CondResult
|
||||
CondParser_And(CondParser *par, Boolean doEval)
|
||||
CondParser_And(CondParser *par, bool doEval)
|
||||
{
|
||||
CondResult res;
|
||||
Token op;
|
||||
@ -992,7 +997,7 @@ CondParser_And(CondParser *par, Boolean doEval)
|
||||
if (op == TOK_AND) {
|
||||
if (res == CR_TRUE)
|
||||
return CondParser_And(par, doEval);
|
||||
if (CondParser_And(par, FALSE) == CR_ERROR)
|
||||
if (CondParser_And(par, false) == CR_ERROR)
|
||||
return CR_ERROR;
|
||||
return res;
|
||||
}
|
||||
@ -1006,7 +1011,7 @@ CondParser_And(CondParser *par, Boolean doEval)
|
||||
* Or -> And
|
||||
*/
|
||||
static CondResult
|
||||
CondParser_Or(CondParser *par, Boolean doEval)
|
||||
CondParser_Or(CondParser *par, bool doEval)
|
||||
{
|
||||
CondResult res;
|
||||
Token op;
|
||||
@ -1019,7 +1024,7 @@ CondParser_Or(CondParser *par, Boolean doEval)
|
||||
if (op == TOK_OR) {
|
||||
if (res == CR_FALSE)
|
||||
return CondParser_Or(par, doEval);
|
||||
if (CondParser_Or(par, FALSE) == CR_ERROR)
|
||||
if (CondParser_Or(par, false) == CR_ERROR)
|
||||
return CR_ERROR;
|
||||
return res;
|
||||
}
|
||||
@ -1029,17 +1034,17 @@ CondParser_Or(CondParser *par, Boolean doEval)
|
||||
}
|
||||
|
||||
static CondEvalResult
|
||||
CondParser_Eval(CondParser *par, Boolean *out_value)
|
||||
CondParser_Eval(CondParser *par, bool *out_value)
|
||||
{
|
||||
CondResult res;
|
||||
|
||||
DEBUG1(COND, "CondParser_Eval: %s\n", par->p);
|
||||
|
||||
res = CondParser_Or(par, TRUE);
|
||||
res = CondParser_Or(par, true);
|
||||
if (res == CR_ERROR)
|
||||
return COND_INVALID;
|
||||
|
||||
if (CondParser_Token(par, FALSE) != TOK_EOF)
|
||||
if (CondParser_Token(par, false) != TOK_EOF)
|
||||
return COND_INVALID;
|
||||
|
||||
*out_value = res == CR_TRUE;
|
||||
@ -1058,9 +1063,9 @@ CondParser_Eval(CondParser *par, Boolean *out_value)
|
||||
* (*value) is set to the boolean value of the condition
|
||||
*/
|
||||
static CondEvalResult
|
||||
CondEvalExpression(const char *cond, Boolean *out_value, Boolean plain,
|
||||
Boolean (*evalBare)(size_t, const char *), Boolean negate,
|
||||
Boolean eprint, Boolean strictLHS)
|
||||
CondEvalExpression(const char *cond, bool *out_value, bool plain,
|
||||
bool (*evalBare)(size_t, const char *), bool negate,
|
||||
bool eprint, bool strictLHS)
|
||||
{
|
||||
CondParser par;
|
||||
CondEvalResult rval;
|
||||
@ -1074,7 +1079,7 @@ CondEvalExpression(const char *cond, Boolean *out_value, Boolean plain,
|
||||
par.negateEvalBare = negate;
|
||||
par.p = cond;
|
||||
par.curr = TOK_NONE;
|
||||
par.printedError = FALSE;
|
||||
par.printedError = false;
|
||||
|
||||
rval = CondParser_Eval(&par, out_value);
|
||||
|
||||
@ -1089,33 +1094,33 @@ CondEvalExpression(const char *cond, Boolean *out_value, Boolean plain,
|
||||
* ${"${VAR}" == value:?yes:no}.
|
||||
*/
|
||||
CondEvalResult
|
||||
Cond_EvalCondition(const char *cond, Boolean *out_value)
|
||||
Cond_EvalCondition(const char *cond, bool *out_value)
|
||||
{
|
||||
return CondEvalExpression(cond, out_value, TRUE,
|
||||
FuncDefined, FALSE, FALSE, FALSE);
|
||||
return CondEvalExpression(cond, out_value, true,
|
||||
FuncDefined, false, false, false);
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
IsEndif(const char *p)
|
||||
{
|
||||
return p[0] == 'e' && p[1] == 'n' && p[2] == 'd' &&
|
||||
p[3] == 'i' && p[4] == 'f' && !ch_isalpha(p[5]);
|
||||
}
|
||||
|
||||
static Boolean
|
||||
DetermineKindOfConditional(const char **pp, Boolean *out_plain,
|
||||
Boolean (**out_evalBare)(size_t, const char *),
|
||||
Boolean *out_negate)
|
||||
static bool
|
||||
DetermineKindOfConditional(const char **pp, bool *out_plain,
|
||||
bool (**out_evalBare)(size_t, const char *),
|
||||
bool *out_negate)
|
||||
{
|
||||
const char *p = *pp;
|
||||
|
||||
p += 2;
|
||||
*out_plain = FALSE;
|
||||
*out_plain = false;
|
||||
*out_evalBare = FuncDefined;
|
||||
*out_negate = FALSE;
|
||||
*out_negate = false;
|
||||
if (*p == 'n') {
|
||||
p++;
|
||||
*out_negate = TRUE;
|
||||
*out_negate = true;
|
||||
}
|
||||
if (is_token(p, "def", 3)) { /* .ifdef and .ifndef */
|
||||
p += 3;
|
||||
@ -1123,7 +1128,7 @@ DetermineKindOfConditional(const char **pp, Boolean *out_plain,
|
||||
p += 4;
|
||||
*out_evalBare = FuncMake;
|
||||
} else if (is_token(p, "", 0) && !*out_negate) { /* plain .if */
|
||||
*out_plain = TRUE;
|
||||
*out_plain = true;
|
||||
} else {
|
||||
/*
|
||||
* TODO: Add error message about unknown directive,
|
||||
@ -1132,11 +1137,11 @@ DetermineKindOfConditional(const char **pp, Boolean *out_plain,
|
||||
*
|
||||
* Example: .elifx 123
|
||||
*/
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*pp = p;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1161,9 +1166,9 @@ DetermineKindOfConditional(const char **pp, Boolean *out_plain,
|
||||
*
|
||||
* Results:
|
||||
* COND_PARSE to continue parsing the lines that follow the
|
||||
* conditional (when <cond> evaluates to TRUE)
|
||||
* conditional (when <cond> evaluates to true)
|
||||
* COND_SKIP to skip the lines after the conditional
|
||||
* (when <cond> evaluates to FALSE, or when a previous
|
||||
* (when <cond> evaluates to false, or when a previous
|
||||
* branch has already been taken)
|
||||
* COND_INVALID if the conditional was not valid, either because of
|
||||
* a syntax error or because some variable was undefined
|
||||
@ -1174,17 +1179,17 @@ Cond_EvalLine(const char *line)
|
||||
{
|
||||
typedef enum IfState {
|
||||
|
||||
/* None of the previous <cond> evaluated to TRUE. */
|
||||
/* None of the previous <cond> evaluated to true. */
|
||||
IFS_INITIAL = 0,
|
||||
|
||||
/* The previous <cond> evaluated to TRUE.
|
||||
/* The previous <cond> evaluated to true.
|
||||
* The lines following this condition are interpreted. */
|
||||
IFS_ACTIVE = 1 << 0,
|
||||
|
||||
/* The previous directive was an '.else'. */
|
||||
IFS_SEEN_ELSE = 1 << 1,
|
||||
|
||||
/* One of the previous <cond> evaluated to TRUE. */
|
||||
/* One of the previous <cond> evaluated to true. */
|
||||
IFS_WAS_ACTIVE = 1 << 2
|
||||
|
||||
} IfState;
|
||||
@ -1192,11 +1197,11 @@ Cond_EvalLine(const char *line)
|
||||
static enum IfState *cond_states = NULL;
|
||||
static unsigned int cond_states_cap = 128;
|
||||
|
||||
Boolean plain;
|
||||
Boolean (*evalBare)(size_t, const char *);
|
||||
Boolean negate;
|
||||
Boolean isElif;
|
||||
Boolean value;
|
||||
bool plain;
|
||||
bool (*evalBare)(size_t, const char *);
|
||||
bool negate;
|
||||
bool isElif;
|
||||
bool value;
|
||||
IfState state;
|
||||
const char *p = line;
|
||||
|
||||
@ -1265,9 +1270,9 @@ Cond_EvalLine(const char *line)
|
||||
return state & IFS_ACTIVE ? COND_PARSE : COND_SKIP;
|
||||
}
|
||||
/* Assume for now it is an elif */
|
||||
isElif = TRUE;
|
||||
isElif = true;
|
||||
} else
|
||||
isElif = FALSE;
|
||||
isElif = false;
|
||||
|
||||
if (p[0] != 'i' || p[1] != 'f') {
|
||||
/*
|
||||
@ -1323,7 +1328,7 @@ Cond_EvalLine(const char *line)
|
||||
|
||||
/* And evaluate the conditional expression */
|
||||
if (CondEvalExpression(p, &value, plain, evalBare, negate,
|
||||
TRUE, TRUE) == COND_INVALID) {
|
||||
true, true) == COND_INVALID) {
|
||||
/* Syntax error in conditional, error message already output. */
|
||||
/* Skip everything to matching .endif */
|
||||
/* XXX: An extra '.else' is not detected in this case. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dir.c,v 1.270 2021/02/05 05:48:19 rillig Exp $ */
|
||||
/* $NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -86,7 +86,7 @@
|
||||
* Dir_SetPATH Set ${.PATH} to reflect state of dirSearchPath.
|
||||
*
|
||||
* Dir_HasWildcards
|
||||
* Returns TRUE if the name given it needs to
|
||||
* Returns true if the name given it needs to
|
||||
* be wildcard-expanded.
|
||||
*
|
||||
* SearchPath_Expand
|
||||
@ -138,7 +138,7 @@
|
||||
#include "job.h"
|
||||
|
||||
/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
|
||||
MAKE_RCSID("$NetBSD: dir.c,v 1.270 2021/02/05 05:48:19 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $");
|
||||
|
||||
/*
|
||||
* A search path is a list of CachedDir structures. A CachedDir has in it the
|
||||
@ -217,7 +217,7 @@ struct CachedDir {
|
||||
* and "./." are different.
|
||||
*
|
||||
* Not sure what happens when .CURDIR is assigned a new value; see
|
||||
* Parse_DoVar.
|
||||
* Parse_Var.
|
||||
*/
|
||||
char *name;
|
||||
|
||||
@ -547,14 +547,14 @@ void
|
||||
Dir_SetPATH(void)
|
||||
{
|
||||
CachedDirListNode *ln;
|
||||
Boolean seenDotLast = FALSE; /* true if we should search '.' last */
|
||||
bool seenDotLast = false; /* true if we should search '.' last */
|
||||
|
||||
Global_Delete(".PATH");
|
||||
|
||||
if ((ln = dirSearchPath.dirs.first) != NULL) {
|
||||
CachedDir *dir = ln->datum;
|
||||
if (dir == dotLast) {
|
||||
seenDotLast = TRUE;
|
||||
seenDotLast = true;
|
||||
Global_Append(".PATH", dotLast->name);
|
||||
}
|
||||
}
|
||||
@ -591,34 +591,34 @@ Dir_SetPATH(void)
|
||||
* that make(1) should be expanding patterns, because then you have to set a
|
||||
* mechanism for escaping the expansion!
|
||||
*
|
||||
* Return TRUE if the word should be expanded, FALSE otherwise.
|
||||
* Return true if the word should be expanded, false otherwise.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
Dir_HasWildcards(const char *name)
|
||||
{
|
||||
const char *p;
|
||||
Boolean wild = FALSE;
|
||||
bool wild = false;
|
||||
int braces = 0, brackets = 0;
|
||||
|
||||
for (p = name; *p != '\0'; p++) {
|
||||
switch (*p) {
|
||||
case '{':
|
||||
braces++;
|
||||
wild = TRUE;
|
||||
wild = true;
|
||||
break;
|
||||
case '}':
|
||||
braces--;
|
||||
break;
|
||||
case '[':
|
||||
brackets++;
|
||||
wild = TRUE;
|
||||
wild = true;
|
||||
break;
|
||||
case ']':
|
||||
brackets--;
|
||||
break;
|
||||
case '?':
|
||||
case '*':
|
||||
wild = TRUE;
|
||||
wild = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -647,7 +647,7 @@ static void
|
||||
DirMatchFiles(const char *pattern, CachedDir *dir, StringList *expansions)
|
||||
{
|
||||
const char *dirName = dir->name;
|
||||
Boolean isDot = dirName[0] == '.' && dirName[1] == '\0';
|
||||
bool isDot = dirName[0] == '.' && dirName[1] == '\0';
|
||||
HashIter hi;
|
||||
|
||||
/*
|
||||
@ -725,7 +725,7 @@ separator_comma(const char *p)
|
||||
return p;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
contains_wildcard(const char *p)
|
||||
{
|
||||
for (; *p != '\0'; p++) {
|
||||
@ -734,10 +734,10 @@ contains_wildcard(const char *p)
|
||||
case '?':
|
||||
case '{':
|
||||
case '[':
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -1064,19 +1064,19 @@ DirFindDot(const char *name, const char *base)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
FindFileRelative(SearchPath *path, Boolean seenDotLast,
|
||||
static bool
|
||||
FindFileRelative(SearchPath *path, bool seenDotLast,
|
||||
const char *name, char **out_file)
|
||||
{
|
||||
SearchPathNode *ln;
|
||||
Boolean checkedDot = FALSE;
|
||||
bool checkedDot = false;
|
||||
char *file;
|
||||
|
||||
DEBUG0(DIR, " Trying subdirectories...\n");
|
||||
|
||||
if (!seenDotLast) {
|
||||
if (dot != NULL) {
|
||||
checkedDot = TRUE;
|
||||
checkedDot = true;
|
||||
if ((file = DirLookupSubdir(dot, name)) != NULL)
|
||||
goto found;
|
||||
}
|
||||
@ -1092,7 +1092,7 @@ FindFileRelative(SearchPath *path, Boolean seenDotLast,
|
||||
if (dir == dot) {
|
||||
if (checkedDot)
|
||||
continue;
|
||||
checkedDot = TRUE;
|
||||
checkedDot = true;
|
||||
}
|
||||
if ((file = DirLookupSubdir(dir, name)) != NULL)
|
||||
goto found;
|
||||
@ -1100,7 +1100,7 @@ FindFileRelative(SearchPath *path, Boolean seenDotLast,
|
||||
|
||||
if (seenDotLast) {
|
||||
if (dot != NULL && !checkedDot) {
|
||||
checkedDot = TRUE;
|
||||
checkedDot = true;
|
||||
if ((file = DirLookupSubdir(dot, name)) != NULL)
|
||||
goto found;
|
||||
}
|
||||
@ -1119,15 +1119,15 @@ FindFileRelative(SearchPath *path, Boolean seenDotLast,
|
||||
goto found;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
found:
|
||||
*out_file = file;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
FindFileAbsolute(SearchPath *path, Boolean const seenDotLast,
|
||||
static bool
|
||||
FindFileAbsolute(SearchPath *path, bool const seenDotLast,
|
||||
const char *const name, const char *const base,
|
||||
char **out_file)
|
||||
{
|
||||
@ -1162,7 +1162,7 @@ FindFileAbsolute(SearchPath *path, Boolean const seenDotLast,
|
||||
((file = DirLookupAbs(cur, name, base)) != NULL))
|
||||
goto found;
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
found:
|
||||
if (file[0] == '\0') {
|
||||
@ -1170,7 +1170,7 @@ found:
|
||||
file = NULL;
|
||||
}
|
||||
*out_file = file;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1194,7 +1194,7 @@ char *
|
||||
Dir_FindFile(const char *name, SearchPath *path)
|
||||
{
|
||||
char *file; /* the current filename to check */
|
||||
Boolean seenDotLast = FALSE; /* true if we should search dot last */
|
||||
bool seenDotLast = false; /* true if we should search dot last */
|
||||
struct cached_stat cst; /* Buffer for stat, if necessary */
|
||||
const char *trailing_dot = ".";
|
||||
const char *base = str_basename(name);
|
||||
@ -1210,7 +1210,7 @@ Dir_FindFile(const char *name, SearchPath *path)
|
||||
if (path->dirs.first != NULL) {
|
||||
CachedDir *dir = path->dirs.first->datum;
|
||||
if (dir == dotLast) {
|
||||
seenDotLast = TRUE;
|
||||
seenDotLast = true;
|
||||
DEBUG0(DIR, "[dot last]...");
|
||||
}
|
||||
}
|
||||
@ -1471,7 +1471,7 @@ ResolveFullName(GNode *gn)
|
||||
* The found file is stored in gn->path, unless the node already had a path.
|
||||
*/
|
||||
void
|
||||
Dir_UpdateMTime(GNode *gn, Boolean recheck)
|
||||
Dir_UpdateMTime(GNode *gn, bool recheck)
|
||||
{
|
||||
char *fullName;
|
||||
struct cached_stat cst;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dir.h,v 1.43 2021/02/05 05:48:19 rillig Exp $ */
|
||||
/* $NetBSD: dir.h,v 1.44 2021/04/03 11:08:40 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -82,11 +82,11 @@ void Dir_InitCur(const char *);
|
||||
void Dir_InitDot(void);
|
||||
void Dir_End(void);
|
||||
void Dir_SetPATH(void);
|
||||
Boolean Dir_HasWildcards(const char *);
|
||||
bool Dir_HasWildcards(const char *);
|
||||
void SearchPath_Expand(SearchPath *, const char *, StringList *);
|
||||
char *Dir_FindFile(const char *, SearchPath *);
|
||||
char *Dir_FindHereOrAbove(const char *, const char *);
|
||||
void Dir_UpdateMTime(GNode *, Boolean);
|
||||
void Dir_UpdateMTime(GNode *, bool);
|
||||
CachedDir *SearchPath_Add(SearchPath *, const char *);
|
||||
char *SearchPath_ToFlags(SearchPath *, const char *);
|
||||
void SearchPath_Clear(SearchPath *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: enum.h,v 1.18 2021/02/02 21:26:51 rillig Exp $ */
|
||||
/* $NetBSD: enum.h,v 1.19 2021/03/15 16:00:05 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
@ -112,19 +112,6 @@ const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
} \
|
||||
extern void enum_flags_rtti_dummy(void)
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 2 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_2(typnam, v1, v2) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_1(v1), \
|
||||
ENUM__SPEC_1(v2)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_1(v1), \
|
||||
ENUM__JOIN_STR_1(v2)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 3 flags.
|
||||
@ -138,19 +125,6 @@ const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
ENUM__JOIN_STR_2(v1, v2), \
|
||||
ENUM__JOIN_STR_1(v3)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 4 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_4(typnam, v1, v2, v3, v4) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_2(v3, v4)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_2(v1, v2), \
|
||||
ENUM__JOIN_STR_2(v3, v4)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 6 flags.
|
||||
@ -164,19 +138,6 @@ const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4), \
|
||||
ENUM__JOIN_STR_2(v5, v6)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 8 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4), \
|
||||
ENUM__JOIN_STR_4(v5, v6, v7, v8)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 9 flags.
|
||||
@ -215,25 +176,4 @@ const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
ENUM__JOIN_STR_2(v29, v30), \
|
||||
ENUM__JOIN_STR_1(v31)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 32 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_32(typnam, \
|
||||
v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16, \
|
||||
v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__JOIN_STR_16(v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32)))
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: for.c,v 1.141 2021/02/04 21:33:13 rillig Exp $ */
|
||||
/* $NetBSD: for.c,v 1.142 2021/04/03 11:08:40 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.141 2021/02/04 21:33:13 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: for.c,v 1.142 2021/04/03 11:08:40 rillig Exp $");
|
||||
|
||||
|
||||
/* One of the variables to the left of the "in" in a .for loop. */
|
||||
@ -75,7 +75,7 @@ typedef struct ForLoop {
|
||||
/* Is any of the names 1 character long? If so, when the variable values
|
||||
* are substituted, the parser must handle $V expressions as well, not
|
||||
* only ${V} and $(V). */
|
||||
Boolean short_var;
|
||||
bool short_var;
|
||||
unsigned int sub_next; /* Where to continue iterating */
|
||||
} ForLoop;
|
||||
|
||||
@ -94,7 +94,7 @@ ForLoop_New(void)
|
||||
f->items.words = NULL;
|
||||
f->items.freeIt = NULL;
|
||||
Buf_Init(&f->curBody);
|
||||
f->short_var = FALSE;
|
||||
f->short_var = false;
|
||||
f->sub_next = 0;
|
||||
|
||||
return f;
|
||||
@ -125,7 +125,7 @@ ForLoop_AddVar(ForLoop *f, const char *name, size_t len)
|
||||
var->nameLen = len;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
ForLoop_ParseVarnames(ForLoop *f, const char **pp)
|
||||
{
|
||||
const char *p = *pp;
|
||||
@ -136,7 +136,7 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp)
|
||||
cpp_skip_whitespace(&p);
|
||||
if (*p == '\0') {
|
||||
Parse_Error(PARSE_FATAL, "missing `in' in for");
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -151,7 +151,7 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp)
|
||||
break;
|
||||
}
|
||||
if (len == 1)
|
||||
f->short_var = TRUE;
|
||||
f->short_var = true;
|
||||
|
||||
ForLoop_AddVar(f, p, len);
|
||||
p += len;
|
||||
@ -159,14 +159,14 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp)
|
||||
|
||||
if (f->vars.len == 0) {
|
||||
Parse_Error(PARSE_FATAL, "no iteration variables in for");
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*pp = p;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
ForLoop_ParseItems(ForLoop *f, const char *p)
|
||||
{
|
||||
char *items;
|
||||
@ -175,10 +175,10 @@ ForLoop_ParseItems(ForLoop *f, const char *p)
|
||||
|
||||
if (Var_Subst(p, SCOPE_GLOBAL, VARE_WANTRES, &items) != VPR_OK) {
|
||||
Parse_Error(PARSE_FATAL, "Error in .for loop items");
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
f->items = Str_Words(items, FALSE);
|
||||
f->items = Str_Words(items, false);
|
||||
free(items);
|
||||
|
||||
if (f->items.len == 1 && f->items.words[0][0] == '\0')
|
||||
@ -189,19 +189,19 @@ ForLoop_ParseItems(ForLoop *f, const char *p)
|
||||
"Wrong number of words (%u) in .for "
|
||||
"substitution list with %u variables",
|
||||
(unsigned)f->items.len, (unsigned)f->vars.len);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
IsFor(const char *p)
|
||||
{
|
||||
return p[0] == 'f' && p[1] == 'o' && p[2] == 'r' && ch_isspace(p[3]);
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
IsEndfor(const char *p)
|
||||
{
|
||||
return p[0] == 'e' && strncmp(p, "endfor", 6) == 0 &&
|
||||
@ -257,9 +257,9 @@ For_Eval(const char *line)
|
||||
|
||||
/*
|
||||
* Add another line to the .for loop that is being built up.
|
||||
* Returns FALSE when the matching .endfor is reached.
|
||||
* Returns false when the matching .endfor is reached.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
For_Accum(const char *line)
|
||||
{
|
||||
const char *p = line;
|
||||
@ -271,7 +271,7 @@ For_Accum(const char *line)
|
||||
if (IsEndfor(p)) {
|
||||
DEBUG1(FOR, "For: end for %d\n", forLevel);
|
||||
if (--forLevel <= 0)
|
||||
return FALSE;
|
||||
return false;
|
||||
} else if (IsFor(p)) {
|
||||
forLevel++;
|
||||
DEBUG1(FOR, "For: new loop %d\n", forLevel);
|
||||
@ -280,7 +280,7 @@ For_Accum(const char *line)
|
||||
|
||||
Buf_AddStr(&accumFor->body, line);
|
||||
Buf_AddByte(&accumFor->body, '\n');
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -319,16 +319,16 @@ for_var_len(const char *var)
|
||||
* The .for loop substitutes the items as ${:U<value>...}, which means
|
||||
* that characters that break this syntax must be backslash-escaped.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
NeedsEscapes(const char *value, char endc)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = value; *p != '\0'; p++) {
|
||||
if (*p == ':' || *p == '$' || *p == '\\' || *p == endc)
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.c,v 1.61 2021/02/01 17:32:10 rillig Exp $ */
|
||||
/* $NetBSD: hash.c,v 1.64 2021/04/11 12:46:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -74,7 +74,7 @@
|
||||
#include "make.h"
|
||||
|
||||
/* "@(#)hash.c 8.1 (Berkeley) 6/6/93" */
|
||||
MAKE_RCSID("$NetBSD: hash.c,v 1.61 2021/02/01 17:32:10 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: hash.c,v 1.64 2021/04/11 12:46:54 rillig Exp $");
|
||||
|
||||
/*
|
||||
* The ratio of # entries to # buckets at which we rebuild the table to
|
||||
@ -84,7 +84,7 @@ MAKE_RCSID("$NetBSD: hash.c,v 1.61 2021/02/01 17:32:10 rillig Exp $");
|
||||
|
||||
/* This hash function matches Gosling's Emacs and java.lang.String. */
|
||||
static unsigned int
|
||||
hash(const char *key, size_t *out_keylen)
|
||||
Hash_String(const char *key, size_t *out_keylen)
|
||||
{
|
||||
unsigned int h;
|
||||
const char *p;
|
||||
@ -98,10 +98,17 @@ hash(const char *key, size_t *out_keylen)
|
||||
return h;
|
||||
}
|
||||
|
||||
/* This hash function matches Gosling's Emacs and java.lang.String. */
|
||||
unsigned int
|
||||
Hash_Hash(const char *key)
|
||||
Hash_Substring(Substring key)
|
||||
{
|
||||
return hash(key, NULL);
|
||||
unsigned int h;
|
||||
const char *p;
|
||||
|
||||
h = 0;
|
||||
for (p = key.start; p != key.end; p++)
|
||||
h = 31 * h + (unsigned char)*p;
|
||||
return h;
|
||||
}
|
||||
|
||||
static HashEntry *
|
||||
@ -126,6 +133,41 @@ HashTable_Find(HashTable *t, unsigned int h, const char *key)
|
||||
return e;
|
||||
}
|
||||
|
||||
static bool
|
||||
HashEntry_KeyEquals(const HashEntry *he, Substring key)
|
||||
{
|
||||
const char *heKey, *p;
|
||||
|
||||
heKey = he->key;
|
||||
for (p = key.start; p != key.end; p++, heKey++)
|
||||
if (*p != *heKey || *heKey == '\0')
|
||||
return false;
|
||||
return *heKey == '\0';
|
||||
}
|
||||
|
||||
static HashEntry *
|
||||
HashTable_FindEntryBySubstring(HashTable *t, Substring key, unsigned int h)
|
||||
{
|
||||
HashEntry *e;
|
||||
unsigned int chainlen = 0;
|
||||
|
||||
#ifdef DEBUG_HASH_LOOKUP
|
||||
DEBUG4(HASH, "%s: %p h=%08x key=%.*s\n", __func__, t, h,
|
||||
(int)Substring_Length(key), key.start);
|
||||
#endif
|
||||
|
||||
for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
|
||||
chainlen++;
|
||||
if (e->key_hash == h && HashEntry_KeyEquals(e, key))
|
||||
break;
|
||||
}
|
||||
|
||||
if (chainlen > t->maxchain)
|
||||
t->maxchain = chainlen;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/* Set up the hash table. */
|
||||
void
|
||||
HashTable_Init(HashTable *t)
|
||||
@ -171,7 +213,7 @@ HashTable_Done(HashTable *t)
|
||||
HashEntry *
|
||||
HashTable_FindEntry(HashTable *t, const char *key)
|
||||
{
|
||||
unsigned int h = hash(key, NULL);
|
||||
unsigned int h = Hash_String(key, NULL);
|
||||
return HashTable_Find(t, h, key);
|
||||
}
|
||||
|
||||
@ -188,9 +230,9 @@ HashTable_FindValue(HashTable *t, const char *key)
|
||||
* or return NULL.
|
||||
*/
|
||||
void *
|
||||
HashTable_FindValueHash(HashTable *t, const char *key, unsigned int h)
|
||||
HashTable_FindValueBySubstringHash(HashTable *t, Substring key, unsigned int h)
|
||||
{
|
||||
HashEntry *he = HashTable_Find(t, h, key);
|
||||
HashEntry *he = HashTable_FindEntryBySubstring(t, key, h);
|
||||
return he != NULL ? he->value : NULL;
|
||||
}
|
||||
|
||||
@ -227,7 +269,7 @@ HashTable_Enlarge(HashTable *t)
|
||||
t->bucketsMask = newMask;
|
||||
t->buckets = newBuckets;
|
||||
DEBUG5(HASH, "%s: %p size=%d entries=%d maxchain=%d\n",
|
||||
__func__, t, t->bucketsSize, t->numEntries, t->maxchain);
|
||||
__func__, (void *)t, t->bucketsSize, t->numEntries, t->maxchain);
|
||||
t->maxchain = 0;
|
||||
}
|
||||
|
||||
@ -236,15 +278,15 @@ HashTable_Enlarge(HashTable *t)
|
||||
* Return in out_isNew whether a new entry has been created.
|
||||
*/
|
||||
HashEntry *
|
||||
HashTable_CreateEntry(HashTable *t, const char *key, Boolean *out_isNew)
|
||||
HashTable_CreateEntry(HashTable *t, const char *key, bool *out_isNew)
|
||||
{
|
||||
size_t keylen;
|
||||
unsigned int h = hash(key, &keylen);
|
||||
unsigned int h = Hash_String(key, &keylen);
|
||||
HashEntry *he = HashTable_Find(t, h, key);
|
||||
|
||||
if (he != NULL) {
|
||||
if (out_isNew != NULL)
|
||||
*out_isNew = FALSE;
|
||||
*out_isNew = false;
|
||||
return he;
|
||||
}
|
||||
|
||||
@ -261,7 +303,7 @@ HashTable_CreateEntry(HashTable *t, const char *key, Boolean *out_isNew)
|
||||
t->numEntries++;
|
||||
|
||||
if (out_isNew != NULL)
|
||||
*out_isNew = TRUE;
|
||||
*out_isNew = true;
|
||||
return he;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.h,v 1.38 2020/12/15 01:23:55 rillig Exp $ */
|
||||
/* $NetBSD: hash.h,v 1.40 2021/04/11 12:46:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -124,9 +124,9 @@ void HashTable_Init(HashTable *);
|
||||
void HashTable_Done(HashTable *);
|
||||
HashEntry *HashTable_FindEntry(HashTable *, const char *);
|
||||
void *HashTable_FindValue(HashTable *, const char *);
|
||||
unsigned int Hash_Hash(const char *);
|
||||
void *HashTable_FindValueHash(HashTable *, const char *, unsigned int);
|
||||
HashEntry *HashTable_CreateEntry(HashTable *, const char *, Boolean *);
|
||||
unsigned int Hash_Substring(Substring);
|
||||
void *HashTable_FindValueBySubstringHash(HashTable *, Substring, unsigned int);
|
||||
HashEntry *HashTable_CreateEntry(HashTable *, const char *, bool *);
|
||||
HashEntry *HashTable_Set(HashTable *, const char *, void *);
|
||||
void HashTable_DeleteEntry(HashTable *, HashEntry *);
|
||||
void HashTable_DebugStats(HashTable *, const char *);
|
||||
@ -146,16 +146,16 @@ HashSet_Done(HashSet *set)
|
||||
HashTable_Done(&set->tbl);
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
HashSet_Add(HashSet *set, const char *key)
|
||||
{
|
||||
Boolean isNew;
|
||||
bool isNew;
|
||||
|
||||
(void)HashTable_CreateEntry(&set->tbl, key, &isNew);
|
||||
return isNew;
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
HashSet_Contains(HashSet *set, const char *key)
|
||||
{
|
||||
return HashTable_FindEntry(&set->tbl, key) != NULL;
|
||||
|
@ -68,19 +68,24 @@ VERSION=`grep '^_MAKE_VERSION' VERSION | sed 's,.*=[[:space:]]*,,'`
|
||||
rm -f *~
|
||||
mkdir -p ../tmp
|
||||
|
||||
# new files are handled automatically
|
||||
# but we need to rm if needed
|
||||
# FILES are kept sorted so we can determine what was added and deleted
|
||||
# but we need to take care dealing with re-ordering
|
||||
(${GIT} diff FILES | sed -n '/^[+-][^+-]/p'; \
|
||||
${GIT} diff mk/FILES | sed -n '/^[+-][^+-]/s,.,&mk/,p' ) > $TF.diffs
|
||||
grep '^+' $TF.diffs | sed 's,^.,,' | sort > $TF.adds
|
||||
grep '^-' $TF.diffs | sed 's,^.,,' | sort > $TF.rms
|
||||
comm -13 $TF.adds $TF.rms > $TF.rm
|
||||
|
||||
if [ -z "$ECHO" ]; then
|
||||
# new files are handled automatically
|
||||
# but we need to rm if needed
|
||||
$GIT diff FILES | sed -n '/^-[^-]/s,^-,,p' > $TF.rm
|
||||
test -s $TF.rm && xargs rm -f < $TF.rm
|
||||
$GIT add -A
|
||||
$GIT diff --staged | tee ../tmp/bmake-import.diff
|
||||
echo "$GIT tag -a vendor/NetBSD/bmake/$VERSION" > ../tmp/bmake-post.sh
|
||||
echo "After you commit, run $here/../tmp/bmake-post.sh"
|
||||
else
|
||||
# FILES is kept sorted so we can determine what was added and deleted
|
||||
$GIT diff FILES | sed -n '/^+[^+]/s,^+,,p' > $TF.add
|
||||
$GIT diff FILES | sed -n '/^-[^-]/s,^-,,p' > $TF.rm
|
||||
comm -23 $TF.adds $TF.rms > $TF.add
|
||||
test -s $TF.rm && { echo Removing:; cat $TF.rm; }
|
||||
test -s $TF.add && { echo Adding:; cat $TF.add; }
|
||||
$GIT diff
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.h,v 1.72 2021/02/05 19:19:17 sjg Exp $ */
|
||||
/* $NetBSD: job.h,v 1.73 2021/04/03 11:08:40 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -157,14 +157,14 @@ typedef struct Job {
|
||||
|
||||
JobStatus status;
|
||||
|
||||
Boolean suspended;
|
||||
bool suspended;
|
||||
|
||||
/* Ignore non-zero exits */
|
||||
Boolean ignerr;
|
||||
bool ignerr;
|
||||
/* Output the command before or instead of running it. */
|
||||
Boolean echo;
|
||||
bool echo;
|
||||
/* Target is a special one. */
|
||||
Boolean special;
|
||||
bool special;
|
||||
|
||||
int inPipe; /* Pipe for reading output from job */
|
||||
int outPipe; /* Pipe for writing control commands */
|
||||
@ -188,22 +188,22 @@ extern int jobTokensRunning; /* tokens currently "out" */
|
||||
|
||||
void Shell_Init(void);
|
||||
const char *Shell_GetNewline(void);
|
||||
void Job_Touch(GNode *, Boolean);
|
||||
Boolean Job_CheckCommands(GNode *, void (*abortProc)(const char *, ...));
|
||||
void Job_Touch(GNode *, bool);
|
||||
bool Job_CheckCommands(GNode *, void (*abortProc)(const char *, ...));
|
||||
void Job_CatchChildren(void);
|
||||
void Job_CatchOutput(void);
|
||||
void Job_Make(GNode *);
|
||||
void Job_Init(void);
|
||||
Boolean Job_ParseShell(char *);
|
||||
bool Job_ParseShell(char *);
|
||||
int Job_Finish(void);
|
||||
void Job_End(void);
|
||||
void Job_Wait(void);
|
||||
void Job_AbortAll(void);
|
||||
void Job_TokenReturn(void);
|
||||
Boolean Job_TokenWithdraw(void);
|
||||
bool Job_TokenWithdraw(void);
|
||||
void Job_ServerStart(int, int, int);
|
||||
void Job_SetPrefix(void);
|
||||
Boolean Job_RunTarget(const char *, const char *);
|
||||
bool Job_RunTarget(const char *, const char *);
|
||||
void Job_FlagsToString(const Job *, char *, size_t);
|
||||
int Job_TempFile(const char *, char *, size_t);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lst.c,v 1.104 2021/02/01 19:39:31 rillig Exp $ */
|
||||
/* $NetBSD: lst.c,v 1.105 2021/03/15 16:45:30 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
#include "make.h"
|
||||
|
||||
MAKE_RCSID("$NetBSD: lst.c,v 1.104 2021/02/01 19:39:31 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: lst.c,v 1.105 2021/03/15 16:45:30 rillig Exp $");
|
||||
|
||||
static ListNode *
|
||||
LstNodeNew(ListNode *prev, ListNode *next, void *datum)
|
||||
@ -205,7 +205,7 @@ Lst_FindDatum(List *list, const void *datum)
|
||||
|
||||
/*
|
||||
* Move all nodes from src to the end of dst.
|
||||
* The source list becomes empty but is not freed.
|
||||
* The source list becomes indeterminate.
|
||||
*/
|
||||
void
|
||||
Lst_MoveAll(List *dst, List *src)
|
||||
@ -219,6 +219,10 @@ Lst_MoveAll(List *dst, List *src)
|
||||
|
||||
dst->last = src->last;
|
||||
}
|
||||
#ifdef CLEANUP
|
||||
src->first = NULL;
|
||||
src->last = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Copy the element data from src to the start of dst. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lst.h,v 1.96 2021/02/01 18:55:15 rillig Exp $ */
|
||||
/* $NetBSD: lst.h,v 1.98 2021/04/03 11:08:40 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -123,15 +123,17 @@ void Lst_Free(List *);
|
||||
MAKE_INLINE void
|
||||
Lst_Init(List *list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
}
|
||||
|
||||
/* Get information about a list */
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
Lst_IsEmpty(List *list)
|
||||
{ return list->first == NULL; }
|
||||
{
|
||||
return list->first == NULL;
|
||||
}
|
||||
|
||||
/* Find the first node that contains the given datum, or NULL. */
|
||||
ListNode *Lst_FindDatum(List *, const void *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: main.c,v 1.533 2021/02/05 19:19:17 sjg Exp $ */
|
||||
/* $NetBSD: main.c,v 1.540 2021/06/18 12:54:17 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -111,7 +111,7 @@
|
||||
#include "trace.h"
|
||||
|
||||
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: main.c,v 1.533 2021/02/05 19:19:17 sjg Exp $");
|
||||
MAKE_RCSID("$NetBSD: main.c,v 1.540 2021/06/18 12:54:17 rillig Exp $");
|
||||
#if defined(MAKE_NATIVE) && !defined(lint)
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
|
||||
"The Regents of the University of California. "
|
||||
@ -125,20 +125,20 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
|
||||
CmdOpts opts;
|
||||
time_t now; /* Time at start of make */
|
||||
GNode *defaultNode; /* .DEFAULT node */
|
||||
Boolean allPrecious; /* .PRECIOUS given on line by itself */
|
||||
Boolean deleteOnError; /* .DELETE_ON_ERROR: set */
|
||||
bool allPrecious; /* .PRECIOUS given on line by itself */
|
||||
bool deleteOnError; /* .DELETE_ON_ERROR: set */
|
||||
|
||||
static int maxJobTokens; /* -j argument */
|
||||
Boolean enterFlagObj; /* -w and objdir != srcdir */
|
||||
bool enterFlagObj; /* -w and objdir != srcdir */
|
||||
|
||||
static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
|
||||
Boolean doing_depend; /* Set while reading .depend */
|
||||
static Boolean jobsRunning; /* TRUE if the jobs might be running */
|
||||
bool doing_depend; /* Set while reading .depend */
|
||||
static bool jobsRunning; /* true if the jobs might be running */
|
||||
static const char *tracefile;
|
||||
static int ReadMakefile(const char *);
|
||||
static void purge_relative_cached_realpaths(void);
|
||||
|
||||
static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
|
||||
static bool ignorePWD; /* if we use -C, PWD is meaningless */
|
||||
static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
|
||||
char curdir[MAXPATHLEN + 1]; /* Startup directory */
|
||||
const char *progname;
|
||||
@ -146,7 +146,7 @@ char *makeDependfile;
|
||||
pid_t myPid;
|
||||
int makelevel;
|
||||
|
||||
Boolean forceJobs = FALSE;
|
||||
bool forceJobs = false;
|
||||
static int main_errors = 0;
|
||||
static HashTable cached_realpaths;
|
||||
|
||||
@ -293,7 +293,7 @@ MainParseArgDebug(const char *argvalue)
|
||||
debug |= DEBUG_JOB;
|
||||
break;
|
||||
case 'L':
|
||||
opts.strict = TRUE;
|
||||
opts.strict = true;
|
||||
break;
|
||||
case 'l':
|
||||
debug |= DEBUG_LOUD;
|
||||
@ -317,7 +317,7 @@ MainParseArgDebug(const char *argvalue)
|
||||
debug |= DEBUG_TARG;
|
||||
break;
|
||||
case 'V':
|
||||
opts.debugVflag = TRUE;
|
||||
opts.debugVflag = true;
|
||||
break;
|
||||
case 'v':
|
||||
debug |= DEBUG_VAR;
|
||||
@ -350,22 +350,22 @@ debug_setbuf:
|
||||
}
|
||||
|
||||
/* Is path relative, or does it contain any relative component "." or ".."? */
|
||||
static Boolean
|
||||
static bool
|
||||
IsRelativePath(const char *path)
|
||||
{
|
||||
const char *cp;
|
||||
const char *p;
|
||||
|
||||
if (path[0] != '/')
|
||||
return TRUE;
|
||||
cp = path;
|
||||
while ((cp = strstr(cp, "/.")) != NULL) {
|
||||
cp += 2;
|
||||
if (*cp == '.')
|
||||
cp++;
|
||||
if (cp[0] == '/' || cp[0] == '\0')
|
||||
return TRUE;
|
||||
return true;
|
||||
p = path;
|
||||
while ((p = strstr(p, "/.")) != NULL) {
|
||||
p += 2;
|
||||
if (*p == '.')
|
||||
p++;
|
||||
if (*p == '/' || *p == '\0')
|
||||
return true;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -388,7 +388,7 @@ MainParseArgChdir(const char *argvalue)
|
||||
sa.st_ino == sb.st_ino &&
|
||||
sa.st_dev == sb.st_dev)
|
||||
strncpy(curdir, argvalue, MAXPATHLEN);
|
||||
ignorePWD = TRUE;
|
||||
ignorePWD = true;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -411,7 +411,7 @@ MainParseArgJobsInternal(const char *argvalue)
|
||||
#endif
|
||||
jp_0 = -1;
|
||||
jp_1 = -1;
|
||||
opts.compatMake = TRUE;
|
||||
opts.compatMake = true;
|
||||
} else {
|
||||
Global_Append(MAKEFLAGS, "-J");
|
||||
Global_Append(MAKEFLAGS, argvalue);
|
||||
@ -423,7 +423,7 @@ MainParseArgJobs(const char *argvalue)
|
||||
{
|
||||
char *p;
|
||||
|
||||
forceJobs = TRUE;
|
||||
forceJobs = true;
|
||||
opts.maxJobs = (int)strtol(argvalue, &p, 0);
|
||||
if (*p != '\0' || opts.maxJobs < 1) {
|
||||
(void)fprintf(stderr,
|
||||
@ -454,14 +454,14 @@ MainParseArgSysInc(const char *argvalue)
|
||||
Global_Append(MAKEFLAGS, argvalue);
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
MainParseArg(char c, const char *argvalue)
|
||||
{
|
||||
switch (c) {
|
||||
case '\0':
|
||||
break;
|
||||
case 'B':
|
||||
opts.compatMake = TRUE;
|
||||
opts.compatMake = true;
|
||||
Global_Append(MAKEFLAGS, "-B");
|
||||
Global_Set(MAKE_MODE, "compat");
|
||||
break;
|
||||
@ -469,7 +469,7 @@ MainParseArg(char c, const char *argvalue)
|
||||
MainParseArgChdir(argvalue);
|
||||
break;
|
||||
case 'D':
|
||||
if (argvalue[0] == '\0') return FALSE;
|
||||
if (argvalue[0] == '\0') return false;
|
||||
Global_SetExpand(argvalue, "1");
|
||||
Global_Append(MAKEFLAGS, "-D");
|
||||
Global_Append(MAKEFLAGS, argvalue);
|
||||
@ -483,12 +483,12 @@ MainParseArg(char c, const char *argvalue)
|
||||
MainParseArgJobsInternal(argvalue);
|
||||
break;
|
||||
case 'N':
|
||||
opts.noExecute = TRUE;
|
||||
opts.noRecursiveExecute = TRUE;
|
||||
opts.noExecute = true;
|
||||
opts.noRecursiveExecute = true;
|
||||
Global_Append(MAKEFLAGS, "-N");
|
||||
break;
|
||||
case 'S':
|
||||
opts.keepgoing = FALSE;
|
||||
opts.keepgoing = false;
|
||||
Global_Append(MAKEFLAGS, "-S");
|
||||
break;
|
||||
case 'T':
|
||||
@ -505,11 +505,11 @@ MainParseArg(char c, const char *argvalue)
|
||||
Global_Append(MAKEFLAGS, argvalue);
|
||||
break;
|
||||
case 'W':
|
||||
opts.parseWarnFatal = TRUE;
|
||||
opts.parseWarnFatal = true;
|
||||
/* XXX: why no Var_Append? */
|
||||
break;
|
||||
case 'X':
|
||||
opts.varNoExportEnv = TRUE;
|
||||
opts.varNoExportEnv = true;
|
||||
Global_Append(MAKEFLAGS, "-X");
|
||||
break;
|
||||
case 'd':
|
||||
@ -523,21 +523,21 @@ MainParseArg(char c, const char *argvalue)
|
||||
MainParseArgDebug(argvalue);
|
||||
break;
|
||||
case 'e':
|
||||
opts.checkEnvFirst = TRUE;
|
||||
opts.checkEnvFirst = true;
|
||||
Global_Append(MAKEFLAGS, "-e");
|
||||
break;
|
||||
case 'f':
|
||||
Lst_Append(&opts.makefiles, bmake_strdup(argvalue));
|
||||
break;
|
||||
case 'i':
|
||||
opts.ignoreErrors = TRUE;
|
||||
opts.ignoreErrors = true;
|
||||
Global_Append(MAKEFLAGS, "-i");
|
||||
break;
|
||||
case 'j':
|
||||
MainParseArgJobs(argvalue);
|
||||
break;
|
||||
case 'k':
|
||||
opts.keepgoing = TRUE;
|
||||
opts.keepgoing = true;
|
||||
Global_Append(MAKEFLAGS, "-k");
|
||||
break;
|
||||
case 'm':
|
||||
@ -545,35 +545,35 @@ MainParseArg(char c, const char *argvalue)
|
||||
/* XXX: why no Var_Append? */
|
||||
break;
|
||||
case 'n':
|
||||
opts.noExecute = TRUE;
|
||||
opts.noExecute = true;
|
||||
Global_Append(MAKEFLAGS, "-n");
|
||||
break;
|
||||
case 'q':
|
||||
opts.queryFlag = TRUE;
|
||||
opts.queryFlag = true;
|
||||
/* Kind of nonsensical, wot? */
|
||||
Global_Append(MAKEFLAGS, "-q");
|
||||
break;
|
||||
case 'r':
|
||||
opts.noBuiltins = TRUE;
|
||||
opts.noBuiltins = true;
|
||||
Global_Append(MAKEFLAGS, "-r");
|
||||
break;
|
||||
case 's':
|
||||
opts.beSilent = TRUE;
|
||||
opts.beSilent = true;
|
||||
Global_Append(MAKEFLAGS, "-s");
|
||||
break;
|
||||
case 't':
|
||||
opts.touchFlag = TRUE;
|
||||
opts.touchFlag = true;
|
||||
Global_Append(MAKEFLAGS, "-t");
|
||||
break;
|
||||
case 'w':
|
||||
opts.enterFlag = TRUE;
|
||||
opts.enterFlag = true;
|
||||
Global_Append(MAKEFLAGS, "-w");
|
||||
break;
|
||||
default:
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -592,13 +592,13 @@ MainParseArgs(int argc, char **argv)
|
||||
int arginc;
|
||||
char *argvalue;
|
||||
char *optscan;
|
||||
Boolean inOption, dashDash = FALSE;
|
||||
bool inOption, dashDash = false;
|
||||
|
||||
const char *optspecs = "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstv:w";
|
||||
/* Can't actually use getopt(3) because rescanning is not portable */
|
||||
|
||||
rearg:
|
||||
inOption = FALSE;
|
||||
inOption = false;
|
||||
optscan = NULL;
|
||||
while (argc > 1) {
|
||||
const char *optspec;
|
||||
@ -610,20 +610,20 @@ rearg:
|
||||
if (c == '\0') {
|
||||
argv++;
|
||||
argc--;
|
||||
inOption = FALSE;
|
||||
inOption = false;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (c != '-' || dashDash)
|
||||
break;
|
||||
inOption = TRUE;
|
||||
inOption = true;
|
||||
c = *optscan++;
|
||||
}
|
||||
/* '-' found at some earlier point */
|
||||
optspec = strchr(optspecs, c);
|
||||
if (c != '\0' && optspec != NULL && optspec[1] == ':') {
|
||||
/* -<something> found, and <something> should have an arg */
|
||||
inOption = FALSE;
|
||||
inOption = false;
|
||||
arginc = 1;
|
||||
argvalue = optscan;
|
||||
if (*argvalue == '\0') {
|
||||
@ -638,10 +638,10 @@ rearg:
|
||||
switch (c) {
|
||||
case '\0':
|
||||
arginc = 1;
|
||||
inOption = FALSE;
|
||||
inOption = false;
|
||||
break;
|
||||
case '-':
|
||||
dashDash = TRUE;
|
||||
dashDash = true;
|
||||
break;
|
||||
default:
|
||||
if (!MainParseArg(c, argvalue))
|
||||
@ -659,7 +659,7 @@ rearg:
|
||||
for (; argc > 1; argv++, argc--) {
|
||||
VarAssign var;
|
||||
if (Parse_IsVar(argv[1], &var)) {
|
||||
Parse_DoVar(&var, SCOPE_CMDLINE);
|
||||
Parse_Var(&var, SCOPE_CMDLINE);
|
||||
} else {
|
||||
if (argv[1][0] == '\0')
|
||||
Punt("illegal (null) argument.");
|
||||
@ -716,7 +716,7 @@ Main_ParseArgLine(const char *line)
|
||||
FStr_Done(&argv0);
|
||||
}
|
||||
|
||||
words = Str_Words(buf, TRUE);
|
||||
words = Str_Words(buf, true);
|
||||
if (words.words == NULL) {
|
||||
Error("Unterminated quoted string [%s]", buf);
|
||||
free(buf);
|
||||
@ -728,14 +728,14 @@ Main_ParseArgLine(const char *line)
|
||||
Words_Free(words);
|
||||
}
|
||||
|
||||
Boolean
|
||||
Main_SetObjdir(Boolean writable, const char *fmt, ...)
|
||||
bool
|
||||
Main_SetObjdir(bool writable, const char *fmt, ...)
|
||||
{
|
||||
struct stat sb;
|
||||
char *path;
|
||||
char buf[MAXPATHLEN + 1];
|
||||
char buf2[MAXPATHLEN + 1];
|
||||
Boolean rc = FALSE;
|
||||
bool rc = false;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
@ -759,24 +759,24 @@ Main_SetObjdir(Boolean writable, const char *fmt, ...)
|
||||
setenv("PWD", objdir, 1);
|
||||
Dir_InitDot();
|
||||
purge_relative_cached_realpaths();
|
||||
rc = TRUE;
|
||||
rc = true;
|
||||
if (opts.enterFlag && strcmp(objdir, curdir) != 0)
|
||||
enterFlagObj = TRUE;
|
||||
enterFlagObj = true;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
SetVarObjdir(Boolean writable, const char *var, const char *suffix)
|
||||
static bool
|
||||
SetVarObjdir(bool writable, const char *var, const char *suffix)
|
||||
{
|
||||
FStr path = Var_Value(SCOPE_CMDLINE, var);
|
||||
FStr xpath;
|
||||
|
||||
if (path.str == NULL || path.str[0] == '\0') {
|
||||
FStr_Done(&path);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* expand variable substitutions */
|
||||
@ -792,7 +792,7 @@ SetVarObjdir(Boolean writable, const char *var, const char *suffix)
|
||||
|
||||
FStr_Done(&xpath);
|
||||
FStr_Done(&path);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -841,8 +841,8 @@ MakeMode(void)
|
||||
|
||||
if (mode[0] != '\0') {
|
||||
if (strstr(mode, "compat") != NULL) {
|
||||
opts.compatMake = TRUE;
|
||||
forceJobs = FALSE;
|
||||
opts.compatMake = true;
|
||||
forceJobs = false;
|
||||
}
|
||||
#if USE_META
|
||||
if (strstr(mode, "meta") != NULL)
|
||||
@ -854,7 +854,7 @@ MakeMode(void)
|
||||
}
|
||||
|
||||
static void
|
||||
PrintVar(const char *varname, Boolean expandVars)
|
||||
PrintVar(const char *varname, bool expandVars)
|
||||
{
|
||||
if (strchr(varname, '$') != NULL) {
|
||||
char *evalue;
|
||||
@ -880,24 +880,22 @@ PrintVar(const char *varname, Boolean expandVars)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a Boolean based on a variable.
|
||||
* Return a bool based on a variable.
|
||||
*
|
||||
* If the knob is not set, return the fallback.
|
||||
* If set, anything that looks or smells like "No", "False", "Off", "0", etc.
|
||||
* is FALSE, otherwise TRUE.
|
||||
* is false, otherwise true.
|
||||
*/
|
||||
Boolean
|
||||
GetBooleanVar(const char *varname, Boolean fallback)
|
||||
bool
|
||||
GetBooleanExpr(const char *expr, bool fallback)
|
||||
{
|
||||
char *expr = str_concat3("${", varname, ":U}");
|
||||
char *value;
|
||||
Boolean res;
|
||||
bool res;
|
||||
|
||||
(void)Var_Subst(expr, SCOPE_GLOBAL, VARE_WANTRES, &value);
|
||||
/* TODO: handle errors */
|
||||
res = ParseBoolean(value, fallback);
|
||||
free(value);
|
||||
free(expr);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -905,14 +903,15 @@ static void
|
||||
doPrintVars(void)
|
||||
{
|
||||
StringListNode *ln;
|
||||
Boolean expandVars;
|
||||
bool expandVars;
|
||||
|
||||
if (opts.printVars == PVM_EXPANDED)
|
||||
expandVars = TRUE;
|
||||
expandVars = true;
|
||||
else if (opts.debugVflag)
|
||||
expandVars = FALSE;
|
||||
expandVars = false;
|
||||
else
|
||||
expandVars = GetBooleanVar(".MAKE.EXPAND_VARIABLES", FALSE);
|
||||
expandVars = GetBooleanExpr("${.MAKE.EXPAND_VARIABLES}",
|
||||
false);
|
||||
|
||||
for (ln = opts.variables.first; ln != NULL; ln = ln->next) {
|
||||
const char *varname = ln->datum;
|
||||
@ -920,11 +919,11 @@ doPrintVars(void)
|
||||
}
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
runTargets(void)
|
||||
{
|
||||
GNodeList targs = LST_INIT; /* target nodes to create */
|
||||
Boolean outOfDate; /* FALSE if all targets up to date */
|
||||
bool outOfDate; /* false if all targets up to date */
|
||||
|
||||
/*
|
||||
* Have now read the entire graph and need to make a list of
|
||||
@ -947,7 +946,7 @@ runTargets(void)
|
||||
*/
|
||||
if (!opts.queryFlag) {
|
||||
Job_Init();
|
||||
jobsRunning = TRUE;
|
||||
jobsRunning = true;
|
||||
}
|
||||
|
||||
/* Traverse the graph, checking on all the targets */
|
||||
@ -958,7 +957,7 @@ runTargets(void)
|
||||
* targets as well as initializing the module.
|
||||
*/
|
||||
Compat_Run(&targs);
|
||||
outOfDate = FALSE;
|
||||
outOfDate = false;
|
||||
}
|
||||
Lst_Done(&targs); /* Don't free the targets themselves. */
|
||||
return outOfDate;
|
||||
@ -1110,11 +1109,11 @@ ignore_pwd:
|
||||
static void
|
||||
InitObjdir(const char *machine, const char *machine_arch)
|
||||
{
|
||||
Boolean writable;
|
||||
bool writable;
|
||||
|
||||
Dir_InitCur(curdir);
|
||||
writable = GetBooleanVar("MAKE_OBJDIR_CHECK_WRITABLE", TRUE);
|
||||
(void)Main_SetObjdir(FALSE, "%s", curdir);
|
||||
writable = GetBooleanExpr("${MAKE_OBJDIR_CHECK_WRITABLE}", true);
|
||||
(void)Main_SetObjdir(false, "%s", curdir);
|
||||
|
||||
if (!SetVarObjdir(writable, "MAKEOBJDIRPREFIX", curdir) &&
|
||||
!SetVarObjdir(writable, "MAKEOBJDIR", "") &&
|
||||
@ -1141,27 +1140,27 @@ UnlimitFiles(void)
|
||||
static void
|
||||
CmdOpts_Init(void)
|
||||
{
|
||||
opts.compatMake = FALSE;
|
||||
opts.compatMake = false;
|
||||
opts.debug = DEBUG_NONE;
|
||||
/* opts.debug_file has already been initialized earlier */
|
||||
opts.strict = FALSE;
|
||||
opts.debugVflag = FALSE;
|
||||
opts.checkEnvFirst = FALSE;
|
||||
opts.strict = false;
|
||||
opts.debugVflag = false;
|
||||
opts.checkEnvFirst = false;
|
||||
Lst_Init(&opts.makefiles);
|
||||
opts.ignoreErrors = FALSE; /* Pay attention to non-zero returns */
|
||||
opts.ignoreErrors = false; /* Pay attention to non-zero returns */
|
||||
opts.maxJobs = 1;
|
||||
opts.keepgoing = FALSE; /* Stop on error */
|
||||
opts.noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
|
||||
opts.noExecute = FALSE; /* Execute all commands */
|
||||
opts.queryFlag = FALSE;
|
||||
opts.noBuiltins = FALSE; /* Read the built-in rules */
|
||||
opts.beSilent = FALSE; /* Print commands as executed */
|
||||
opts.touchFlag = FALSE;
|
||||
opts.keepgoing = false; /* Stop on error */
|
||||
opts.noRecursiveExecute = false; /* Execute all .MAKE targets */
|
||||
opts.noExecute = false; /* Execute all commands */
|
||||
opts.queryFlag = false;
|
||||
opts.noBuiltins = false; /* Read the built-in rules */
|
||||
opts.beSilent = false; /* Print commands as executed */
|
||||
opts.touchFlag = false;
|
||||
opts.printVars = PVM_NONE;
|
||||
Lst_Init(&opts.variables);
|
||||
opts.parseWarnFatal = FALSE;
|
||||
opts.enterFlag = FALSE;
|
||||
opts.varNoExportEnv = FALSE;
|
||||
opts.parseWarnFatal = false;
|
||||
opts.enterFlag = false;
|
||||
opts.varNoExportEnv = false;
|
||||
Lst_Init(&opts.create);
|
||||
}
|
||||
|
||||
@ -1286,7 +1285,7 @@ InitMaxJobs(void)
|
||||
|
||||
opts.maxJobs = n;
|
||||
maxJobTokens = opts.maxJobs;
|
||||
forceJobs = TRUE;
|
||||
forceJobs = true;
|
||||
free(value);
|
||||
}
|
||||
|
||||
@ -1427,12 +1426,12 @@ main_Init(int argc, char **argv)
|
||||
Global_Set(MAKE_DEPENDFILE, ".depend");
|
||||
|
||||
CmdOpts_Init();
|
||||
allPrecious = FALSE; /* Remove targets when interrupted */
|
||||
deleteOnError = FALSE; /* Historical default behavior */
|
||||
jobsRunning = FALSE;
|
||||
allPrecious = false; /* Remove targets when interrupted */
|
||||
deleteOnError = false; /* Historical default behavior */
|
||||
jobsRunning = false;
|
||||
|
||||
maxJobTokens = opts.maxJobs;
|
||||
ignorePWD = FALSE;
|
||||
ignorePWD = false;
|
||||
|
||||
/*
|
||||
* Initialize the parsing, directory and variable modules to prepare
|
||||
@ -1575,9 +1574,9 @@ main_PrepareMaking(void)
|
||||
SCOPE_CMDLINE, VARE_WANTRES, &makeDependfile);
|
||||
if (makeDependfile[0] != '\0') {
|
||||
/* TODO: handle errors */
|
||||
doing_depend = TRUE;
|
||||
doing_depend = true;
|
||||
(void)ReadMakefile(makeDependfile);
|
||||
doing_depend = FALSE;
|
||||
doing_depend = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1599,7 +1598,7 @@ main_PrepareMaking(void)
|
||||
* turn compatibility on.
|
||||
*/
|
||||
if (!opts.compatMake && !forceJobs)
|
||||
opts.compatMake = TRUE;
|
||||
opts.compatMake = true;
|
||||
|
||||
if (!opts.compatMake)
|
||||
Job_ServerStart(maxJobTokens, jp_0, jp_1);
|
||||
@ -1607,7 +1606,7 @@ main_PrepareMaking(void)
|
||||
jp_0, jp_1, opts.maxJobs, maxJobTokens, opts.compatMake ? 1 : 0);
|
||||
|
||||
if (opts.printVars == PVM_NONE)
|
||||
Main_ExportMAKEFLAGS(TRUE); /* initial export */
|
||||
Main_ExportMAKEFLAGS(true); /* initial export */
|
||||
|
||||
InitVpath();
|
||||
|
||||
@ -1615,7 +1614,7 @@ main_PrepareMaking(void)
|
||||
* Now that all search paths have been read for suffixes et al, it's
|
||||
* time to add the default search path to their lists...
|
||||
*/
|
||||
Suff_DoPaths();
|
||||
Suff_ExtendPaths();
|
||||
|
||||
/*
|
||||
* Propagate attributes through :: dependency lists.
|
||||
@ -1632,13 +1631,13 @@ main_PrepareMaking(void)
|
||||
* If the -v or -V options are given, print variables instead.
|
||||
* Return whether any of the targets is out-of-date.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
main_Run(void)
|
||||
{
|
||||
if (opts.printVars != PVM_NONE) {
|
||||
/* print the values of any variables requested by the user */
|
||||
doPrintVars();
|
||||
return FALSE;
|
||||
return false;
|
||||
} else {
|
||||
return runTargets();
|
||||
}
|
||||
@ -1684,7 +1683,7 @@ main_CleanUp(void)
|
||||
|
||||
/* Determine the exit code. */
|
||||
static int
|
||||
main_Exit(Boolean outOfDate)
|
||||
main_Exit(bool outOfDate)
|
||||
{
|
||||
if (opts.strict && (main_errors > 0 || Parse_GetFatals() > 0))
|
||||
return 2; /* Not 1 so -q can distinguish error */
|
||||
@ -1694,7 +1693,7 @@ main_Exit(Boolean outOfDate)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Boolean outOfDate;
|
||||
bool outOfDate;
|
||||
|
||||
main_Init(argc, argv);
|
||||
main_ReadFiles();
|
||||
@ -1862,7 +1861,7 @@ Cmd_Exec(const char *cmd, const char **errfmt)
|
||||
|
||||
/* Wait for the process to exit. */
|
||||
while ((pid = waitpid(cpid, &status, 0)) != cpid && pid >= 0)
|
||||
JobReapChild(pid, status, FALSE);
|
||||
JobReapChild(pid, status, false);
|
||||
|
||||
res_len = buf.len;
|
||||
res = Buf_DoneData(&buf);
|
||||
@ -2107,13 +2106,14 @@ cached_realpath(const char *pathname, char *resolved)
|
||||
* Return true if we should die without noise.
|
||||
* For example our failing child was a sub-make or failure happened elsewhere.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
shouldDieQuietly(GNode *gn, int bf)
|
||||
{
|
||||
static int quietly = -1;
|
||||
|
||||
if (quietly < 0) {
|
||||
if (DEBUG(JOB) || !GetBooleanVar(".MAKE.DIE_QUIETLY", TRUE))
|
||||
if (DEBUG(JOB) ||
|
||||
!GetBooleanExpr("${.MAKE.DIE_QUIETLY}", true))
|
||||
quietly = 0;
|
||||
else if (bf >= 0)
|
||||
quietly = bf;
|
||||
@ -2193,15 +2193,15 @@ PrintOnError(GNode *gn, const char *msg)
|
||||
}
|
||||
|
||||
void
|
||||
Main_ExportMAKEFLAGS(Boolean first)
|
||||
Main_ExportMAKEFLAGS(bool first)
|
||||
{
|
||||
static Boolean once = TRUE;
|
||||
static bool once = true;
|
||||
const char *expr;
|
||||
char *s;
|
||||
|
||||
if (once != first)
|
||||
return;
|
||||
once = FALSE;
|
||||
once = false;
|
||||
|
||||
expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
|
||||
(void)Var_Subst(expr, SCOPE_CMDLINE, VARE_WANTRES, &s);
|
||||
@ -2225,7 +2225,7 @@ getTmpdir(void)
|
||||
return tmpdir;
|
||||
|
||||
/* Honor $TMPDIR but only if it is valid. Ensure it ends with '/'. */
|
||||
(void)Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/",
|
||||
(void)Var_Subst("${TMPDIR:tA:U" _PATH_TMP ":S,/$,,W}/",
|
||||
SCOPE_GLOBAL, VARE_WANTRES, &tmpdir);
|
||||
/* TODO: handle errors */
|
||||
|
||||
@ -2272,18 +2272,18 @@ mkTempFile(const char *pattern, char *tfile, size_t tfile_sz)
|
||||
|
||||
/*
|
||||
* Convert a string representation of a boolean into a boolean value.
|
||||
* Anything that looks like "No", "False", "Off", "0" etc. is FALSE,
|
||||
* the empty string is the fallback, everything else is TRUE.
|
||||
* Anything that looks like "No", "False", "Off", "0" etc. is false,
|
||||
* the empty string is the fallback, everything else is true.
|
||||
*/
|
||||
Boolean
|
||||
ParseBoolean(const char *s, Boolean fallback)
|
||||
bool
|
||||
ParseBoolean(const char *s, bool fallback)
|
||||
{
|
||||
char ch = ch_tolower(s[0]);
|
||||
if (ch == '\0')
|
||||
return fallback;
|
||||
if (ch == '0' || ch == 'f' || ch == 'n')
|
||||
return FALSE;
|
||||
return false;
|
||||
if (ch == 'o')
|
||||
return ch_tolower(s[1]) != 'f';
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.c,v 1.242 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: make.c,v 1.244 2021/04/04 10:05:08 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -72,7 +72,7 @@
|
||||
* Examination of targets and their suitability for creation.
|
||||
*
|
||||
* Interface:
|
||||
* Make_Run Initialize things for the module. Returns TRUE if
|
||||
* Make_Run Initialize things for the module. Returns true if
|
||||
* work was (or would have been) done.
|
||||
*
|
||||
* Make_Update After a target is made, update all its parents.
|
||||
@ -85,7 +85,8 @@
|
||||
* Update the node's youngestChild field based on the
|
||||
* child's modification time.
|
||||
*
|
||||
* Make_DoAllVar Set up the various local variables for a
|
||||
* GNode_SetLocalVars
|
||||
* Set up the various local variables for a
|
||||
* target, including the .ALLSRC variable, making
|
||||
* sure that any variable that needs to exist
|
||||
* at the very least has the empty value.
|
||||
@ -103,7 +104,7 @@
|
||||
#include "job.h"
|
||||
|
||||
/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */
|
||||
MAKE_RCSID("$NetBSD: make.c,v 1.242 2021/02/05 05:15:12 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: make.c,v 1.244 2021/04/04 10:05:08 rillig Exp $");
|
||||
|
||||
/* Sequence # to detect recursion. */
|
||||
static unsigned int checked_seqno = 1;
|
||||
@ -168,7 +169,7 @@ GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,
|
||||
suffix);
|
||||
}
|
||||
|
||||
Boolean
|
||||
bool
|
||||
GNode_ShouldExecute(GNode *gn)
|
||||
{
|
||||
return !((gn->type & OP_MAKE)
|
||||
@ -184,7 +185,7 @@ GNode_UpdateYoungestChild(GNode *gn, GNode *cgn)
|
||||
gn->youngestChild = cgn;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
IsOODateRegular(GNode *gn)
|
||||
{
|
||||
/* These rules are inherited from the original Make. */
|
||||
@ -193,22 +194,22 @@ IsOODateRegular(GNode *gn)
|
||||
if (gn->mtime < gn->youngestChild->mtime) {
|
||||
DEBUG1(MAKE, "modified before source \"%s\"...",
|
||||
GNode_Path(gn->youngestChild));
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gn->mtime == 0 && !(gn->type & OP_OPTIONAL)) {
|
||||
DEBUG0(MAKE, "nonexistent and no sources...");
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gn->type & OP_DOUBLEDEP) {
|
||||
DEBUG0(MAKE, ":: operator and no sources...");
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -223,17 +224,17 @@ IsOODateRegular(GNode *gn)
|
||||
* The mtime field of the node and the youngestChild field of its parents
|
||||
* may be changed.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
GNode_IsOODate(GNode *gn)
|
||||
{
|
||||
Boolean oodate;
|
||||
bool oodate;
|
||||
|
||||
/*
|
||||
* Certain types of targets needn't even be sought as their datedness
|
||||
* doesn't depend on their modification time...
|
||||
*/
|
||||
if (!(gn->type & (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC))) {
|
||||
Dir_UpdateMTime(gn, TRUE);
|
||||
Dir_UpdateMTime(gn, true);
|
||||
if (DEBUG(MAKE)) {
|
||||
if (gn->mtime != 0)
|
||||
debug_printf("modified %s...",
|
||||
@ -267,7 +268,7 @@ GNode_IsOODate(GNode *gn)
|
||||
* no matter *what*.
|
||||
*/
|
||||
DEBUG0(MAKE, ".USE node...");
|
||||
oodate = FALSE;
|
||||
oodate = false;
|
||||
} else if ((gn->type & OP_LIB) && (gn->mtime == 0 || Arch_IsLib(gn))) {
|
||||
DEBUG0(MAKE, "library...");
|
||||
|
||||
@ -302,9 +303,9 @@ GNode_IsOODate(GNode *gn)
|
||||
debug_printf(".EXEC node...");
|
||||
}
|
||||
}
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
} else if (IsOODateRegular(gn)) {
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
} else {
|
||||
/*
|
||||
* When a nonexistent child with no sources
|
||||
@ -351,7 +352,7 @@ PretendAllChildrenAreMade(GNode *pgn)
|
||||
GNode *cgn = ln->datum;
|
||||
|
||||
/* This may also update cgn->path. */
|
||||
Dir_UpdateMTime(cgn, FALSE);
|
||||
Dir_UpdateMTime(cgn, false);
|
||||
GNode_UpdateYoungestChild(pgn, cgn);
|
||||
pgn->unmade--;
|
||||
}
|
||||
@ -443,7 +444,7 @@ Make_HandleUse(GNode *cgn, GNode *pgn)
|
||||
static void
|
||||
MakeHandleUse(GNode *cgn, GNode *pgn, GNodeListNode *ln)
|
||||
{
|
||||
Boolean unmarked;
|
||||
bool unmarked;
|
||||
|
||||
unmarked = !(cgn->type & OP_MARK);
|
||||
cgn->type |= OP_MARK;
|
||||
@ -485,7 +486,7 @@ Make_Recheck(GNode *gn)
|
||||
{
|
||||
time_t mtime;
|
||||
|
||||
Dir_UpdateMTime(gn, TRUE);
|
||||
Dir_UpdateMTime(gn, true);
|
||||
mtime = gn->mtime;
|
||||
|
||||
#ifndef RECHECK
|
||||
@ -576,7 +577,7 @@ UpdateImplicitParentsVars(GNode *cgn, const char *cname)
|
||||
}
|
||||
|
||||
/* See if a .ORDER rule stops us from building this node. */
|
||||
static Boolean
|
||||
static bool
|
||||
IsWaitingForOrder(GNode *gn)
|
||||
{
|
||||
GNodeListNode *ln;
|
||||
@ -590,9 +591,9 @@ IsWaitingForOrder(GNode *gn)
|
||||
DEBUG2(MAKE,
|
||||
"IsWaitingForOrder: Waiting for .ORDER node \"%s%s\"\n",
|
||||
ogn->name, ogn->cohort_num);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void MakeBuildParent(GNode *, GNodeListNode *);
|
||||
@ -868,7 +869,7 @@ MakeAddAllSrc(GNode *cgn, GNode *pgn)
|
||||
* match its ALLSRC variable.
|
||||
*/
|
||||
void
|
||||
Make_DoAllVar(GNode *gn)
|
||||
GNode_SetLocalVars(GNode *gn)
|
||||
{
|
||||
GNodeListNode *ln;
|
||||
|
||||
@ -889,7 +890,7 @@ Make_DoAllVar(GNode *gn)
|
||||
gn->flags |= DONE_ALLSRC;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
MakeBuildChild(GNode *cn, GNodeListNode *toBeMadeNext)
|
||||
{
|
||||
|
||||
@ -899,13 +900,13 @@ MakeBuildChild(GNode *cn, GNodeListNode *toBeMadeNext)
|
||||
GNode_FprintDetails(opts.debug_file, "", cn, "\n");
|
||||
}
|
||||
if (GNode_IsReady(cn))
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
/* If this node is on the RHS of a .ORDER, check LHSs. */
|
||||
if (IsWaitingForOrder(cn)) {
|
||||
/* Can't build this (or anything else in this child list) yet */
|
||||
cn->made = DEFERRED;
|
||||
return FALSE; /* but keep looking */
|
||||
return false; /* but keep looking */
|
||||
}
|
||||
|
||||
DEBUG2(MAKE, "MakeBuildChild: schedule %s%s\n",
|
||||
@ -961,13 +962,13 @@ MakeChildren(GNode *gn)
|
||||
*
|
||||
* If the -q option was given, no job will be started,
|
||||
* but as soon as an out-of-date target is found, this function
|
||||
* returns TRUE. In all other cases, this function returns FALSE.
|
||||
* returns true. In all other cases, this function returns false.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
MakeStartJobs(void)
|
||||
{
|
||||
GNode *gn;
|
||||
Boolean have_token = FALSE;
|
||||
bool have_token = false;
|
||||
|
||||
while (!Lst_IsEmpty(&toBeMade)) {
|
||||
/*
|
||||
@ -976,7 +977,7 @@ MakeStartJobs(void)
|
||||
*/
|
||||
if (!have_token && !Job_TokenWithdraw())
|
||||
break;
|
||||
have_token = TRUE;
|
||||
have_token = true;
|
||||
|
||||
gn = Lst_Dequeue(&toBeMade);
|
||||
DEBUG2(MAKE, "Examining %s%s...\n", gn->name, gn->cohort_num);
|
||||
@ -1022,10 +1023,10 @@ MakeStartJobs(void)
|
||||
if (GNode_IsOODate(gn)) {
|
||||
DEBUG0(MAKE, "out-of-date\n");
|
||||
if (opts.queryFlag)
|
||||
return TRUE;
|
||||
Make_DoAllVar(gn);
|
||||
return true;
|
||||
GNode_SetLocalVars(gn);
|
||||
Job_Make(gn);
|
||||
have_token = FALSE;
|
||||
have_token = false;
|
||||
} else {
|
||||
DEBUG0(MAKE, "up-to-date\n");
|
||||
gn->made = UPTODATE;
|
||||
@ -1037,7 +1038,7 @@ MakeStartJobs(void)
|
||||
* for .TARGET when building up the local
|
||||
* variables of its parent(s)...
|
||||
*/
|
||||
Make_DoAllVar(gn);
|
||||
GNode_SetLocalVars(gn);
|
||||
}
|
||||
Make_Update(gn);
|
||||
}
|
||||
@ -1046,7 +1047,7 @@ MakeStartJobs(void)
|
||||
if (have_token)
|
||||
Job_TokenReturn();
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Print the status of a .ORDER node. */
|
||||
@ -1081,7 +1082,7 @@ static void MakePrintStatusList(GNodeList *, int *);
|
||||
* Print the status of a top-level node, viz. it being up-to-date already
|
||||
* or not created due to an error in a lower level.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
MakePrintStatus(GNode *gn, int *errors)
|
||||
{
|
||||
if (gn->flags & DONECYCLE) {
|
||||
@ -1089,7 +1090,7 @@ MakePrintStatus(GNode *gn, int *errors)
|
||||
* We've completely processed this node before, don't do
|
||||
* it again.
|
||||
*/
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gn->unmade == 0) {
|
||||
@ -1128,7 +1129,7 @@ MakePrintStatus(GNode *gn, int *errors)
|
||||
gn->name, gn->cohort_num);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG3(MAKE, "MakePrintStatus: %s%s has %d unmade children\n",
|
||||
@ -1143,7 +1144,7 @@ MakePrintStatus(GNode *gn, int *errors)
|
||||
MakePrintStatusList(&gn->children, errors);
|
||||
/* Mark that this node needn't be processed again */
|
||||
gn->flags |= DONECYCLE;
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Only output the error once per node */
|
||||
@ -1151,11 +1152,11 @@ MakePrintStatus(GNode *gn, int *errors)
|
||||
Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);
|
||||
if ((*errors)++ > 100)
|
||||
/* Abandon the whole error report */
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
/* Reporting for our children will give the rest of the loop */
|
||||
MakePrintStatusList(&gn->children, errors);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1243,7 +1244,7 @@ Make_ExpandUse(GNodeList *targs)
|
||||
*eon = ')';
|
||||
}
|
||||
|
||||
Dir_UpdateMTime(gn, FALSE);
|
||||
Dir_UpdateMTime(gn, false);
|
||||
Var_Set(gn, TARGET, GNode_Path(gn));
|
||||
UnmarkChildren(gn);
|
||||
HandleUseNodes(gn);
|
||||
@ -1364,14 +1365,14 @@ Make_ProcessWait(GNodeList *targs)
|
||||
* targs the initial list of targets
|
||||
*
|
||||
* Results:
|
||||
* TRUE if work was done. FALSE otherwise.
|
||||
* True if work was done, false otherwise.
|
||||
*
|
||||
* Side Effects:
|
||||
* The make field of all nodes involved in the creation of the given
|
||||
* targets is set to 1. The toBeMade list is set to contain all the
|
||||
* 'leaves' of these subgraphs.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
Make_Run(GNodeList *targs)
|
||||
{
|
||||
int errors; /* Number of errors the Job module reports */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.h,v 1.256 2021/02/05 19:19:17 sjg Exp $ */
|
||||
/* $NetBSD: make.h,v 1.263 2021/06/21 10:33:11 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -136,55 +136,30 @@
|
||||
#endif
|
||||
|
||||
#define MAKE_INLINE static inline MAKE_ATTR_UNUSED
|
||||
#define MAKE_STATIC static MAKE_ATTR_UNUSED
|
||||
|
||||
/*
|
||||
* A boolean type is defined as an integer, not an enum, for historic reasons.
|
||||
* The only allowed values are the constants TRUE and FALSE (1 and 0).
|
||||
*/
|
||||
#if defined(lint) || defined(USE_C99_BOOLEAN)
|
||||
#if __STDC_VERSION__ >= 199901L || defined(lint) || defined(USE_C99_BOOLEAN)
|
||||
#include <stdbool.h>
|
||||
typedef bool Boolean;
|
||||
#define FALSE false
|
||||
#define TRUE true
|
||||
#elif defined(USE_DOUBLE_BOOLEAN)
|
||||
/* During development, to find type mismatches in function declarations. */
|
||||
typedef double Boolean;
|
||||
#define TRUE 1.0
|
||||
#define FALSE 0.0
|
||||
#elif defined(USE_UCHAR_BOOLEAN)
|
||||
/*
|
||||
* During development, to find code that depends on the exact value of TRUE or
|
||||
* that stores other values in Boolean variables.
|
||||
*/
|
||||
typedef unsigned char Boolean;
|
||||
#define TRUE ((unsigned char)0xFF)
|
||||
#define FALSE ((unsigned char)0x00)
|
||||
#elif defined(USE_CHAR_BOOLEAN)
|
||||
/*
|
||||
* During development, to find code that uses a boolean as array index, via
|
||||
* -Wchar-subscripts.
|
||||
*/
|
||||
typedef char Boolean;
|
||||
#define TRUE ((char)-1)
|
||||
#define FALSE ((char)0x00)
|
||||
#elif defined(USE_ENUM_BOOLEAN)
|
||||
typedef enum Boolean { FALSE, TRUE } Boolean;
|
||||
#else
|
||||
typedef int Boolean;
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#ifndef bool
|
||||
typedef unsigned int Boolean;
|
||||
#define bool Boolean
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "lst.h"
|
||||
#include "enum.h"
|
||||
#include "make_malloc.h"
|
||||
#include "str.h"
|
||||
#include "hash.h"
|
||||
#include "make-conf.h"
|
||||
#include "buf.h"
|
||||
#include "make_malloc.h"
|
||||
|
||||
/*
|
||||
* some vendors don't have this --sjg
|
||||
@ -247,6 +222,8 @@ typedef enum GNodeMade {
|
||||
* should be made.
|
||||
*
|
||||
* Some of the OP_ constants can be combined, others cannot.
|
||||
*
|
||||
* See the tests depsrc-*.mk and deptgt-*.mk.
|
||||
*/
|
||||
typedef enum GNodeType {
|
||||
OP_NONE = 0,
|
||||
@ -503,11 +480,11 @@ typedef enum CondEvalResult {
|
||||
*/
|
||||
|
||||
/* True if every target is precious */
|
||||
extern Boolean allPrecious;
|
||||
extern bool allPrecious;
|
||||
/* True if failed targets should be deleted */
|
||||
extern Boolean deleteOnError;
|
||||
/* TRUE while processing .depend */
|
||||
extern Boolean doing_depend;
|
||||
extern bool deleteOnError;
|
||||
/* true while processing .depend */
|
||||
extern bool doing_depend;
|
||||
/* .DEFAULT rule */
|
||||
extern GNode *defaultNode;
|
||||
|
||||
@ -606,7 +583,7 @@ void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
|
||||
do { \
|
||||
if (DEBUG(module)) \
|
||||
debug_printf args; \
|
||||
} while (/*CONSTCOND*/FALSE)
|
||||
} while (/*CONSTCOND*/false)
|
||||
|
||||
#define DEBUG0(module, text) \
|
||||
DEBUG_IMPL(module, ("%s", text))
|
||||
@ -630,7 +607,7 @@ typedef enum PrintVarsMode {
|
||||
/* Command line options */
|
||||
typedef struct CmdOpts {
|
||||
/* -B: whether we are make compatible */
|
||||
Boolean compatMake;
|
||||
bool compatMake;
|
||||
|
||||
/* -d: debug control: There is one bit per module. It is up to the
|
||||
* module what debug information to print. */
|
||||
@ -643,19 +620,19 @@ typedef struct CmdOpts {
|
||||
*
|
||||
* Runs make in strict mode, with additional checks and better error
|
||||
* handling. */
|
||||
Boolean strict;
|
||||
bool strict;
|
||||
|
||||
/* -dV: for the -V option, print unexpanded variable values */
|
||||
Boolean debugVflag;
|
||||
bool debugVflag;
|
||||
|
||||
/* -e: check environment variables before global variables */
|
||||
Boolean checkEnvFirst;
|
||||
bool checkEnvFirst;
|
||||
|
||||
/* -f: the makefiles to read */
|
||||
StringList makefiles;
|
||||
|
||||
/* -i: if true, ignore all errors from shell commands */
|
||||
Boolean ignoreErrors;
|
||||
bool ignoreErrors;
|
||||
|
||||
/* -j: the maximum number of jobs that can run in parallel;
|
||||
* this is coordinated with the submakes */
|
||||
@ -663,29 +640,29 @@ typedef struct CmdOpts {
|
||||
|
||||
/* -k: if true and an error occurs while making a node, continue
|
||||
* making nodes that do not depend on the erroneous node */
|
||||
Boolean keepgoing;
|
||||
bool keepgoing;
|
||||
|
||||
/* -N: execute no commands from the targets */
|
||||
Boolean noRecursiveExecute;
|
||||
bool noRecursiveExecute;
|
||||
|
||||
/* -n: execute almost no commands from the targets */
|
||||
Boolean noExecute;
|
||||
bool noExecute;
|
||||
|
||||
/*
|
||||
* -q: if true, do not really make anything, just see if the targets
|
||||
* are out-of-date
|
||||
*/
|
||||
Boolean queryFlag;
|
||||
bool queryFlag;
|
||||
|
||||
/* -r: raw mode, do not load the builtin rules. */
|
||||
Boolean noBuiltins;
|
||||
bool noBuiltins;
|
||||
|
||||
/* -s: don't echo the shell commands before executing them */
|
||||
Boolean beSilent;
|
||||
bool beSilent;
|
||||
|
||||
/* -t: touch the targets if they are out-of-date, but don't actually
|
||||
* make them */
|
||||
Boolean touchFlag;
|
||||
bool touchFlag;
|
||||
|
||||
/* -[Vv]: print expanded or unexpanded selected variables */
|
||||
PrintVarsMode printVars;
|
||||
@ -693,14 +670,14 @@ typedef struct CmdOpts {
|
||||
StringList variables;
|
||||
|
||||
/* -W: if true, makefile parsing warnings are treated as errors */
|
||||
Boolean parseWarnFatal;
|
||||
bool parseWarnFatal;
|
||||
|
||||
/* -w: print 'Entering' and 'Leaving' for submakes */
|
||||
Boolean enterFlag;
|
||||
bool enterFlag;
|
||||
|
||||
/* -X: if true, do not export variables set on the command line to the
|
||||
* environment. */
|
||||
Boolean varNoExportEnv;
|
||||
bool varNoExportEnv;
|
||||
|
||||
/* The target names specified on the command line.
|
||||
* Used to resolve .if make(...) statements. */
|
||||
@ -713,24 +690,24 @@ extern CmdOpts opts;
|
||||
#include "nonints.h"
|
||||
|
||||
void GNode_UpdateYoungestChild(GNode *, GNode *);
|
||||
Boolean GNode_IsOODate(GNode *);
|
||||
bool GNode_IsOODate(GNode *);
|
||||
void Make_ExpandUse(GNodeList *);
|
||||
time_t Make_Recheck(GNode *);
|
||||
void Make_HandleUse(GNode *, GNode *);
|
||||
void Make_Update(GNode *);
|
||||
void Make_DoAllVar(GNode *);
|
||||
Boolean Make_Run(GNodeList *);
|
||||
Boolean shouldDieQuietly(GNode *, int);
|
||||
void GNode_SetLocalVars(GNode *);
|
||||
bool Make_Run(GNodeList *);
|
||||
bool shouldDieQuietly(GNode *, int);
|
||||
void PrintOnError(GNode *, const char *);
|
||||
void Main_ExportMAKEFLAGS(Boolean);
|
||||
Boolean Main_SetObjdir(Boolean, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
|
||||
void Main_ExportMAKEFLAGS(bool);
|
||||
bool Main_SetObjdir(bool, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
|
||||
int mkTempFile(const char *, char *, size_t);
|
||||
int str2Lst_Append(StringList *, char *);
|
||||
void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
|
||||
Boolean GNode_ShouldExecute(GNode *gn);
|
||||
bool GNode_ShouldExecute(GNode *gn);
|
||||
|
||||
/* See if the node was seen on the left-hand side of a dependency operator. */
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
GNode_IsTarget(const GNode *gn)
|
||||
{
|
||||
return (gn->type & OP_OPMASK) != 0;
|
||||
@ -742,25 +719,25 @@ GNode_Path(const GNode *gn)
|
||||
return gn->path != NULL ? gn->path : gn->name;
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
GNode_IsWaitingFor(const GNode *gn)
|
||||
{
|
||||
return (gn->flags & REMAKE) && gn->made <= REQUESTED;
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
GNode_IsReady(const GNode *gn)
|
||||
{
|
||||
return gn->made > DEFERRED;
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
GNode_IsDone(const GNode *gn)
|
||||
{
|
||||
return gn->made >= MADE;
|
||||
}
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
GNode_IsError(const GNode *gn)
|
||||
{
|
||||
return gn->made == ERROR || gn->made == ABORTED;
|
||||
@ -781,7 +758,7 @@ GNode_VarArchive(GNode *gn) { return GNode_ValueDirect(gn, ARCHIVE); }
|
||||
MAKE_INLINE const char *
|
||||
GNode_VarMember(GNode *gn) { return GNode_ValueDirect(gn, MEMBER); }
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L
|
||||
#define UNCONST(ptr) ({ \
|
||||
union __unconst { \
|
||||
const void *__cp; \
|
||||
@ -809,15 +786,15 @@ GNode_VarMember(GNode *gn) { return GNode_ValueDirect(gn, MEMBER); }
|
||||
#define KILLPG(pid, sig) killpg((pid), (sig))
|
||||
#endif
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
ch_isalnum(char ch) { return isalnum((unsigned char)ch) != 0; }
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
ch_isalpha(char ch) { return isalpha((unsigned char)ch) != 0; }
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
ch_isdigit(char ch) { return isdigit((unsigned char)ch) != 0; }
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
ch_isspace(char ch) { return isspace((unsigned char)ch) != 0; }
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
ch_isupper(char ch) { return isupper((unsigned char)ch) != 0; }
|
||||
MAKE_INLINE char
|
||||
ch_tolower(char ch) { return (char)tolower((unsigned char)ch); }
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.c,v 1.177 2021/02/05 19:19:17 sjg Exp $ */
|
||||
/* $NetBSD: meta.c,v 1.181 2021/04/04 10:05:08 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Implement 'meta' mode.
|
||||
@ -70,20 +70,20 @@ static char *metaIgnorePathsStr; /* string storage for the list */
|
||||
#define MAKE_META_IGNORE_FILTER ".MAKE.META.IGNORE_FILTER"
|
||||
#endif
|
||||
|
||||
Boolean useMeta = FALSE;
|
||||
static Boolean useFilemon = FALSE;
|
||||
static Boolean writeMeta = FALSE;
|
||||
static Boolean metaMissing = FALSE; /* oodate if missing */
|
||||
static Boolean filemonMissing = FALSE; /* oodate if missing */
|
||||
static Boolean metaEnv = FALSE; /* don't save env unless asked */
|
||||
static Boolean metaVerbose = FALSE;
|
||||
static Boolean metaIgnoreCMDs = FALSE; /* ignore CMDs in .meta files */
|
||||
static Boolean metaIgnorePatterns = FALSE; /* do we need to do pattern matches */
|
||||
static Boolean metaIgnoreFilter = FALSE; /* do we have more complex filtering? */
|
||||
static Boolean metaCurdirOk = FALSE; /* write .meta in .CURDIR Ok? */
|
||||
static Boolean metaSilent = FALSE; /* if we have a .meta be SILENT */
|
||||
bool useMeta = false;
|
||||
static bool useFilemon = false;
|
||||
static bool writeMeta = false;
|
||||
static bool metaMissing = false; /* oodate if missing */
|
||||
static bool filemonMissing = false; /* oodate if missing */
|
||||
static bool metaEnv = false; /* don't save env unless asked */
|
||||
static bool metaVerbose = false;
|
||||
static bool metaIgnoreCMDs = false; /* ignore CMDs in .meta files */
|
||||
static bool metaIgnorePatterns = false; /* do we need to do pattern matches */
|
||||
static bool metaIgnoreFilter = false; /* do we have more complex filtering? */
|
||||
static bool metaCurdirOk = false; /* write .meta in .CURDIR Ok? */
|
||||
static bool metaSilent = false; /* if we have a .meta be SILENT */
|
||||
|
||||
extern Boolean forceJobs;
|
||||
extern bool forceJobs;
|
||||
extern char **environ;
|
||||
|
||||
#define MAKE_META_PREFIX ".MAKE.META.PREFIX"
|
||||
@ -133,7 +133,7 @@ meta_open_filemon(BuildMon *pbm)
|
||||
|
||||
pbm->filemon = filemon_open();
|
||||
if (pbm->filemon == NULL) {
|
||||
useFilemon = FALSE;
|
||||
useFilemon = false;
|
||||
warn("Could not open filemon %s", filemon_path());
|
||||
return;
|
||||
}
|
||||
@ -319,7 +319,7 @@ meta_name(char *mname, size_t mnamelen,
|
||||
* Return true if running ${.MAKE}
|
||||
* Bypassed if target is flagged .MAKE
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
is_submake(const char *cmd, GNode *gn)
|
||||
{
|
||||
static const char *p_make = NULL;
|
||||
@ -327,7 +327,7 @@ is_submake(const char *cmd, GNode *gn)
|
||||
char *mp = NULL;
|
||||
char *cp;
|
||||
char *cp2;
|
||||
Boolean rc = FALSE;
|
||||
bool rc = false;
|
||||
|
||||
if (p_make == NULL) {
|
||||
p_make = Var_Value(gn, ".MAKE").str;
|
||||
@ -346,7 +346,7 @@ is_submake(const char *cmd, GNode *gn)
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
rc = TRUE;
|
||||
rc = true;
|
||||
break;
|
||||
}
|
||||
if (cp2 > cmd && rc) {
|
||||
@ -356,7 +356,7 @@ is_submake(const char *cmd, GNode *gn)
|
||||
case '\n':
|
||||
break;
|
||||
default:
|
||||
rc = FALSE; /* no match */
|
||||
rc = false; /* no match */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -365,29 +365,31 @@ is_submake(const char *cmd, GNode *gn)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
any_is_submake(GNode *gn)
|
||||
{
|
||||
StringListNode *ln;
|
||||
|
||||
for (ln = gn->commands.first; ln != NULL; ln = ln->next)
|
||||
if (is_submake(ln->datum, gn))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
printCMD(const char *cmd, FILE *fp, GNode *gn)
|
||||
printCMD(const char *ucmd, FILE *fp, GNode *gn)
|
||||
{
|
||||
char *cmd_freeIt = NULL;
|
||||
FStr xcmd = FStr_InitRefer(ucmd);
|
||||
|
||||
if (strchr(cmd, '$') != NULL) {
|
||||
(void)Var_Subst(cmd, gn, VARE_WANTRES, &cmd_freeIt);
|
||||
if (strchr(ucmd, '$') != NULL) {
|
||||
char *expanded;
|
||||
(void)Var_Subst(ucmd, gn, VARE_WANTRES, &expanded);
|
||||
/* TODO: handle errors */
|
||||
cmd = cmd_freeIt;
|
||||
xcmd = FStr_InitOwn(expanded);
|
||||
}
|
||||
fprintf(fp, "CMD %s\n", cmd);
|
||||
free(cmd_freeIt);
|
||||
|
||||
fprintf(fp, "CMD %s\n", xcmd.str);
|
||||
FStr_Done(&xcmd);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -408,17 +410,17 @@ printCMDs(GNode *gn, FILE *fp)
|
||||
debug_printf("Skipping meta for %s: .%s\n", \
|
||||
gn->name, __STRING(_type)); \
|
||||
} \
|
||||
return FALSE; \
|
||||
return false; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/FALSE)
|
||||
} while (/*CONSTCOND*/false)
|
||||
|
||||
|
||||
/*
|
||||
* Do we need/want a .meta file ?
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
meta_needed(GNode *gn, const char *dname,
|
||||
char *objdir_realpath, Boolean verbose)
|
||||
char *objdir_realpath, bool verbose)
|
||||
{
|
||||
struct cached_stat cst;
|
||||
|
||||
@ -440,13 +442,13 @@ meta_needed(GNode *gn, const char *dname,
|
||||
if (Lst_IsEmpty(&gn->commands)) {
|
||||
if (verbose)
|
||||
debug_printf("Skipping meta for %s: no commands\n", gn->name);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
if ((gn->type & (OP_META|OP_SUBMAKE)) == OP_SUBMAKE) {
|
||||
/* OP_SUBMAKE is a bit too aggressive */
|
||||
if (any_is_submake(gn)) {
|
||||
DEBUG1(META, "Skipping meta for %s: .SUBMAKE\n", gn->name);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,7 +456,7 @@ meta_needed(GNode *gn, const char *dname,
|
||||
if (cached_stat(dname, &cst) != 0) {
|
||||
if (verbose)
|
||||
debug_printf("Skipping meta for %s: no .OBJDIR\n", gn->name);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* make sure these are canonical */
|
||||
@ -466,9 +468,9 @@ meta_needed(GNode *gn, const char *dname,
|
||||
if (verbose)
|
||||
debug_printf("Skipping meta for %s: .OBJDIR == .CURDIR\n",
|
||||
gn->name);
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -490,7 +492,7 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
tname = GNode_VarTarget(gn);
|
||||
|
||||
/* if this succeeds objdir_realpath is realpath of dname */
|
||||
if (!meta_needed(gn, dname.str, objdir_realpath, TRUE))
|
||||
if (!meta_needed(gn, dname.str, objdir_realpath, true))
|
||||
goto out;
|
||||
dname.str = objdir_realpath;
|
||||
|
||||
@ -554,7 +556,7 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
return fp;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
boolValue(char *s)
|
||||
{
|
||||
switch(*s) {
|
||||
@ -563,9 +565,9 @@ boolValue(char *s)
|
||||
case 'n':
|
||||
case 'F':
|
||||
case 'f':
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -591,25 +593,25 @@ meta_init(void)
|
||||
void
|
||||
meta_mode_init(const char *make_mode)
|
||||
{
|
||||
static Boolean once = FALSE;
|
||||
static bool once = false;
|
||||
char *cp;
|
||||
FStr value;
|
||||
|
||||
useMeta = TRUE;
|
||||
useFilemon = TRUE;
|
||||
writeMeta = TRUE;
|
||||
useMeta = true;
|
||||
useFilemon = true;
|
||||
writeMeta = true;
|
||||
|
||||
if (make_mode != NULL) {
|
||||
if (strstr(make_mode, "env") != NULL)
|
||||
metaEnv = TRUE;
|
||||
metaEnv = true;
|
||||
if (strstr(make_mode, "verb") != NULL)
|
||||
metaVerbose = TRUE;
|
||||
metaVerbose = true;
|
||||
if (strstr(make_mode, "read") != NULL)
|
||||
writeMeta = FALSE;
|
||||
writeMeta = false;
|
||||
if (strstr(make_mode, "nofilemon") != NULL)
|
||||
useFilemon = FALSE;
|
||||
useFilemon = false;
|
||||
if (strstr(make_mode, "ignore-cmd") != NULL)
|
||||
metaIgnoreCMDs = TRUE;
|
||||
metaIgnoreCMDs = true;
|
||||
if (useFilemon)
|
||||
get_mode_bf(filemonMissing, "missing-filemon=");
|
||||
get_mode_bf(metaCurdirOk, "curdirok=");
|
||||
@ -628,7 +630,7 @@ meta_mode_init(const char *make_mode)
|
||||
}
|
||||
if (once)
|
||||
return;
|
||||
once = TRUE;
|
||||
once = true;
|
||||
memset(&Mybm, 0, sizeof Mybm);
|
||||
/*
|
||||
* We consider ourselves master of all within ${.MAKE.META.BAILIWICK}
|
||||
@ -652,12 +654,12 @@ meta_mode_init(const char *make_mode)
|
||||
*/
|
||||
value = Var_Value(SCOPE_GLOBAL, MAKE_META_IGNORE_PATTERNS);
|
||||
if (value.str != NULL) {
|
||||
metaIgnorePatterns = TRUE;
|
||||
metaIgnorePatterns = true;
|
||||
FStr_Done(&value);
|
||||
}
|
||||
value = Var_Value(SCOPE_GLOBAL, MAKE_META_IGNORE_FILTER);
|
||||
if (value.str != NULL) {
|
||||
metaIgnoreFilter = TRUE;
|
||||
metaIgnoreFilter = true;
|
||||
FStr_Done(&value);
|
||||
}
|
||||
}
|
||||
@ -774,7 +776,7 @@ meta_job_event(Job *job)
|
||||
}
|
||||
|
||||
void
|
||||
meta_job_error(Job *job, GNode *gn, Boolean ignerr, int status)
|
||||
meta_job_error(Job *job, GNode *gn, bool ignerr, int status)
|
||||
{
|
||||
char cwd[MAXPATHLEN];
|
||||
BuildMon *pbm;
|
||||
@ -944,7 +946,7 @@ fgetLine(char **bufp, size_t *szp, int o, FILE *fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
prefix_match(const char *prefix, const char *path)
|
||||
{
|
||||
size_t n = strlen(prefix);
|
||||
@ -952,35 +954,35 @@ prefix_match(const char *prefix, const char *path)
|
||||
return strncmp(path, prefix, n) == 0;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
has_any_prefix(const char *path, StringList *prefixes)
|
||||
{
|
||||
StringListNode *ln;
|
||||
|
||||
for (ln = prefixes->first; ln != NULL; ln = ln->next)
|
||||
if (prefix_match(ln->datum, path))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See if the path equals prefix or starts with "prefix/". */
|
||||
static Boolean
|
||||
static bool
|
||||
path_starts_with(const char *path, const char *prefix)
|
||||
{
|
||||
size_t n = strlen(prefix);
|
||||
|
||||
if (strncmp(path, prefix, n) != 0)
|
||||
return FALSE;
|
||||
return false;
|
||||
return path[n] == '\0' || path[n] == '/';
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
meta_ignore(GNode *gn, const char *p)
|
||||
{
|
||||
char fname[MAXPATHLEN];
|
||||
|
||||
if (p == NULL)
|
||||
return TRUE;
|
||||
return true;
|
||||
|
||||
if (*p == '/') {
|
||||
cached_realpath(p, fname); /* clean it up */
|
||||
@ -988,7 +990,7 @@ meta_ignore(GNode *gn, const char *p)
|
||||
#ifdef DEBUG_META_MODE
|
||||
DEBUG1(META, "meta_oodate: ignoring path: %s\n", p);
|
||||
#endif
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1011,7 +1013,7 @@ meta_ignore(GNode *gn, const char *p)
|
||||
DEBUG1(META, "meta_oodate: ignoring pattern: %s\n", p);
|
||||
#endif
|
||||
free(pm);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
free(pm);
|
||||
}
|
||||
@ -1030,11 +1032,11 @@ meta_ignore(GNode *gn, const char *p)
|
||||
DEBUG1(META, "meta_oodate: ignoring filtered: %s\n", p);
|
||||
#endif
|
||||
free(fm);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
free(fm);
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1048,11 +1050,11 @@ meta_ignore(GNode *gn, const char *p)
|
||||
/*
|
||||
* It is possible that a .meta file is corrupted,
|
||||
* if we detect this we want to reproduce it.
|
||||
* Setting oodate TRUE will have that effect.
|
||||
* Setting oodate true will have that effect.
|
||||
*/
|
||||
#define CHECK_VALID_META(p) if (!(p != NULL && *p != '\0')) { \
|
||||
warnx("%s: %d: malformed", fname, lineno); \
|
||||
oodate = TRUE; \
|
||||
oodate = true; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
@ -1074,8 +1076,8 @@ append_if_new(StringList *list, const char *str)
|
||||
Lst_Append(list, bmake_strdup(str));
|
||||
}
|
||||
|
||||
Boolean
|
||||
meta_oodate(GNode *gn, Boolean oodate)
|
||||
bool
|
||||
meta_oodate(GNode *gn, bool oodate)
|
||||
{
|
||||
static char *tmpdir = NULL;
|
||||
static char cwd[MAXPATHLEN];
|
||||
@ -1095,9 +1097,9 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
static size_t cwdlen = 0;
|
||||
static size_t tmplen = 0;
|
||||
FILE *fp;
|
||||
Boolean needOODATE = FALSE;
|
||||
bool needOODATE = false;
|
||||
StringList missingFiles;
|
||||
Boolean have_filemon = FALSE;
|
||||
bool have_filemon = false;
|
||||
|
||||
if (oodate)
|
||||
return oodate; /* we're done */
|
||||
@ -1106,7 +1108,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
tname = GNode_VarTarget(gn);
|
||||
|
||||
/* if this succeeds fname3 is realpath of dname */
|
||||
if (!meta_needed(gn, dname.str, fname3, FALSE))
|
||||
if (!meta_needed(gn, dname.str, fname3, false))
|
||||
goto oodate_out;
|
||||
dname.str = fname3;
|
||||
|
||||
@ -1118,7 +1120,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
* requires that all variables are set in the same way that they
|
||||
* would be if the target needs to be re-built.
|
||||
*/
|
||||
Make_DoAllVar(gn);
|
||||
GNode_SetLocalVars(gn);
|
||||
|
||||
meta_name(fname, sizeof fname, dname.str, tname, dname.str);
|
||||
|
||||
@ -1164,7 +1166,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
buf[x - 1] = '\0';
|
||||
else {
|
||||
warnx("%s: %d: line truncated at %u", fname, lineno, x);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
break;
|
||||
}
|
||||
link_src = NULL;
|
||||
@ -1172,11 +1174,11 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
/* Find the start of the build monitor section. */
|
||||
if (!have_filemon) {
|
||||
if (strncmp(buf, "-- filemon", 10) == 0) {
|
||||
have_filemon = TRUE;
|
||||
have_filemon = true;
|
||||
continue;
|
||||
}
|
||||
if (strncmp(buf, "# buildmon", 10) == 0) {
|
||||
have_filemon = TRUE;
|
||||
have_filemon = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1424,7 +1426,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
char *sdirs[4];
|
||||
char **sdp;
|
||||
int sdx = 0;
|
||||
Boolean found = FALSE;
|
||||
bool found = false;
|
||||
|
||||
if (*p == '/') {
|
||||
sdirs[sdx++] = p; /* done */
|
||||
@ -1455,7 +1457,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
fname, lineno, *sdp);
|
||||
#endif
|
||||
if (cached_stat(*sdp, &cst) == 0) {
|
||||
found = TRUE;
|
||||
found = true;
|
||||
p = *sdp;
|
||||
}
|
||||
}
|
||||
@ -1468,7 +1470,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
cst.cst_mtime > gn->mtime) {
|
||||
DEBUG3(META, "%s: %d: file '%s' is newer than the target...\n",
|
||||
fname, lineno, p);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
} else if (S_ISDIR(cst.cst_mode)) {
|
||||
/* Update the latest directory. */
|
||||
cached_realpath(p, latestdir);
|
||||
@ -1500,25 +1502,25 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (cmdNode == NULL) {
|
||||
DEBUG2(META, "%s: %d: there were more build commands in the meta data file than there are now...\n",
|
||||
fname, lineno);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
} else {
|
||||
const char *cp;
|
||||
char *cmd = cmdNode->datum;
|
||||
Boolean hasOODATE = FALSE;
|
||||
bool hasOODATE = false;
|
||||
|
||||
if (strstr(cmd, "$?") != NULL)
|
||||
hasOODATE = TRUE;
|
||||
hasOODATE = true;
|
||||
else if ((cp = strstr(cmd, ".OODATE")) != NULL) {
|
||||
/* check for $[{(].OODATE[:)}] */
|
||||
if (cp > cmd + 2 && cp[-2] == '$')
|
||||
hasOODATE = TRUE;
|
||||
hasOODATE = true;
|
||||
}
|
||||
if (hasOODATE) {
|
||||
needOODATE = TRUE;
|
||||
needOODATE = true;
|
||||
DEBUG2(META, "%s: %d: cannot compare command using .OODATE\n",
|
||||
fname, lineno);
|
||||
}
|
||||
(void)Var_Subst(cmd, gn, VARE_WANTRES|VARE_UNDEFERR, &cmd);
|
||||
(void)Var_Subst(cmd, gn, VARE_UNDEFERR, &cmd);
|
||||
/* TODO: handle errors */
|
||||
|
||||
if ((cp = strchr(cmd, '\n')) != NULL) {
|
||||
@ -1553,7 +1555,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
DEBUG4(META, "%s: %d: a build command has changed\n%s\nvs\n%s\n",
|
||||
fname, lineno, p, cmd);
|
||||
if (!metaIgnoreCMDs)
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
}
|
||||
free(cmd);
|
||||
cmdNode = cmdNode->next;
|
||||
@ -1566,13 +1568,13 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (!oodate && cmdNode != NULL) {
|
||||
DEBUG2(META, "%s: %d: there are extra build commands now that weren't in the meta data file\n",
|
||||
fname, lineno);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
}
|
||||
CHECK_VALID_META(p);
|
||||
if (strcmp(p, cwd) != 0) {
|
||||
DEBUG4(META, "%s: %d: the current working directory has changed from '%s' to '%s'\n",
|
||||
fname, lineno, p, curdir);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1581,11 +1583,11 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (!Lst_IsEmpty(&missingFiles)) {
|
||||
DEBUG2(META, "%s: missing files: %s...\n",
|
||||
fname, (char *)missingFiles.first->datum);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
}
|
||||
if (!oodate && !have_filemon && filemonMissing) {
|
||||
DEBUG1(META, "%s: missing filemon data\n", fname);
|
||||
oodate = TRUE;
|
||||
oodate = true;
|
||||
}
|
||||
} else {
|
||||
if (writeMeta && (metaMissing || (gn->type & OP_META))) {
|
||||
@ -1600,8 +1602,8 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
}
|
||||
if (cp == NULL) {
|
||||
DEBUG1(META, "%s: required but missing\n", fname);
|
||||
oodate = TRUE;
|
||||
needOODATE = TRUE; /* assume the worst */
|
||||
oodate = true;
|
||||
needOODATE = true; /* assume the worst */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1708,7 +1710,7 @@ meta_compat_parent(pid_t child)
|
||||
fflush(stdout);
|
||||
buf[nread] = '\0';
|
||||
meta_job_output(NULL, buf, "");
|
||||
} while (/*CONSTCOND*/FALSE);
|
||||
} while (/*CONSTCOND*/false);
|
||||
if (metafd != -1 && FD_ISSET(metafd, &readfds) != 0) {
|
||||
if (meta_job_event(NULL) <= 0)
|
||||
metafd = -1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.h,v 1.9 2020/12/10 20:49:11 rillig Exp $ */
|
||||
/* $NetBSD: meta.h,v 1.10 2021/04/03 11:08:40 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Things needed for 'meta' mode.
|
||||
@ -48,13 +48,13 @@ void meta_job_child(struct Job *);
|
||||
void meta_job_parent(struct Job *, pid_t);
|
||||
int meta_job_fd(struct Job *);
|
||||
int meta_job_event(struct Job *);
|
||||
void meta_job_error(struct Job *, GNode *, Boolean, int);
|
||||
void meta_job_error(struct Job *, GNode *, bool, int);
|
||||
void meta_job_output(struct Job *, char *, const char *);
|
||||
int meta_cmd_finish(void *);
|
||||
int meta_job_finish(struct Job *);
|
||||
Boolean meta_oodate(GNode *, Boolean);
|
||||
bool meta_oodate(GNode *, bool);
|
||||
void meta_compat_start(void);
|
||||
void meta_compat_child(void);
|
||||
void meta_compat_parent(pid_t);
|
||||
|
||||
extern Boolean useMeta;
|
||||
extern bool useMeta;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: metachar.h,v 1.15 2021/01/19 20:51:46 rillig Exp $ */
|
||||
/* $NetBSD: metachar.h,v 1.16 2021/04/03 11:08:40 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@ extern unsigned char _metachar[];
|
||||
|
||||
#define is_shell_metachar(c) (_metachar[(c) & 0x7f] != 0)
|
||||
|
||||
MAKE_INLINE Boolean
|
||||
MAKE_INLINE bool
|
||||
needshell(const char *cmd)
|
||||
{
|
||||
while (!is_shell_metachar(*cmd) && *cmd != ':' && *cmd != '=')
|
||||
|
@ -1,3 +1,38 @@
|
||||
2021-06-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210616
|
||||
|
||||
* dirdeps.mk: when using .MAKE.DEPENDFILE_PREFERENCE to find
|
||||
depend files to read, anchor MACHINE at , or end of string
|
||||
to avoid prefix match.
|
||||
|
||||
2021-05-04 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210504
|
||||
|
||||
* dirdeps.mk: re-implement ALL_MACHINES support to better
|
||||
cater for local complexities, when ONLY_TARGET_SPEC_LIST
|
||||
is not set. local.dirdeps.mk can set
|
||||
DIRDEPS_ALL_MACHINES_FILTER and/or
|
||||
DIRDEPS_ALL_MACHINES_FILTER_XTRAS to filter the results we get
|
||||
from listing all existing Makefile.depend.*
|
||||
|
||||
2021-04-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210420
|
||||
|
||||
* dirdeps.mk: revert previous - not always safe.
|
||||
|
||||
2021-03-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210321
|
||||
|
||||
* dirdeps.mk: when generating dirdeps.cache
|
||||
we only need to hook the initial DIRDEPS to the
|
||||
dirdeps target. That and any _build_xtra_dirs (like tests which
|
||||
should not be hooked directly to the dependency graph - to avoid
|
||||
cycles)
|
||||
|
||||
2021-01-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210130
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: dirdeps.mk,v 1.133 2021/01/31 04:39:22 sjg Exp $
|
||||
# $Id: dirdeps.mk,v 1.140 2021/06/20 23:42:38 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2021, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
@ -409,23 +409,72 @@ _DIRDEP_USE: .USE .MAKE
|
||||
done
|
||||
|
||||
.ifdef ALL_MACHINES
|
||||
# this is how you limit it to only the machines we have been built for
|
||||
# previously.
|
||||
.if empty(ONLY_TARGET_SPEC_LIST) && empty(ONLY_MACHINE_LIST)
|
||||
.if !empty(ALL_MACHINE_LIST)
|
||||
# ALL_MACHINE_LIST is the list of all legal machines - ignore anything else
|
||||
_machine_list != cd ${_CURDIR} && 'ls' -1 ${ALL_MACHINE_LIST:O:u:@m@${.MAKE.DEPENDFILE:T:R}.$m@} 2> /dev/null; echo
|
||||
.else
|
||||
_machine_list != 'ls' -1 ${_CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.* 2> /dev/null; echo
|
||||
# we start with everything
|
||||
_machine_list != echo; 'ls' -1 ${_CURDIR}/${.MAKE.DEPENDFILE_PREFIX}* 2> /dev/null
|
||||
|
||||
# some things we know we want to ignore
|
||||
DIRDEPS_TARGETS_SKIP_LIST += \
|
||||
*~ \
|
||||
*.bak \
|
||||
*.inc \
|
||||
*.old \
|
||||
*.options \
|
||||
*.orig \
|
||||
*.rej \
|
||||
|
||||
# first trim things we know we want to skip
|
||||
# and provide canonical form
|
||||
_machine_list := ${_machine_list:${DIRDEPS_TARGETS_SKIP_LIST:${M_ListToSkip}}:T:E}
|
||||
|
||||
# cater for local complexities
|
||||
# local.dirdeps.mk can set
|
||||
# DIRDEPS_ALL_MACHINES_FILTER and
|
||||
# DIRDEPS_ALL_MACHINES_FILTER_XTRAS for final tweaks
|
||||
|
||||
.if !empty(ALL_TARGET_SPEC_LIST)
|
||||
.if ${_debug_reldir}
|
||||
.info ALL_TARGET_SPEC_LIST=${ALL_TARGET_SPEC_LIST}
|
||||
.endif
|
||||
_only_machines := ${_machine_list:${NIgnoreFiles:UN*.bak}:E:O:u}
|
||||
DIRDEPS_ALL_MACHINES_FILTER += \
|
||||
@x@$${ALL_TARGET_SPEC_LIST:@s@$${x:M$$s}@}@
|
||||
.elif !empty(ALL_MACHINE_LIST)
|
||||
.if ${_debug_reldir}
|
||||
.info ALL_MACHINE_LIST=${ALL_MACHINE_LIST}
|
||||
.endif
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
# the space below can result in extraneous ':'
|
||||
DIRDEPS_ALL_MACHINES_FILTER += \
|
||||
@x@$${ALL_MACHINE_LIST:@m@$${x:M$$m,*} $${x:M$$m}@}@
|
||||
.else
|
||||
DIRDEPS_ALL_MACHINES_FILTER += \
|
||||
@x@$${ALL_MACHINE_LIST:@m@$${x:M$$m}@}@
|
||||
.endif
|
||||
.endif
|
||||
# add local XTRAS - default to something benign
|
||||
DIRDEPS_ALL_MACHINES_FILTER += \
|
||||
${DIRDEPS_ALL_MACHINES_FILTER_XTRAS:UNbak}
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info _machine_list=${_machine_list}
|
||||
.info DIRDEPS_ALL_MACHINES_FILTER=${DIRDEPS_ALL_MACHINES_FILTER}
|
||||
.endif
|
||||
|
||||
_only_machines := ${_machine_list:${DIRDEPS_ALL_MACHINES_FILTER:ts:}:S,:, ,g}
|
||||
.else
|
||||
_only_machines := ${ONLY_TARGET_SPEC_LIST:U} ${ONLY_MACHINE_LIST:U}
|
||||
.endif
|
||||
|
||||
.if empty(_only_machines)
|
||||
# we must be boot-strapping
|
||||
_only_machines := ${TARGET_MACHINE:U${ALL_MACHINE_LIST:U${DEP_MACHINE}}}
|
||||
_only_machines := ${TARGET_MACHINE:U${ALL_TARGET_SPEC_LIST:U${ALL_MACHINE_LIST:U${DEP_MACHINE}}}}
|
||||
.endif
|
||||
|
||||
# cleanup the result
|
||||
_only_machines := ${_only_machines:O:u}
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: ALL_MACHINES _only_machines=${_only_machines}
|
||||
.endif
|
||||
|
||||
.else # ! ALL_MACHINES
|
||||
@ -452,6 +501,10 @@ _only_machines := ${_only_machines:${NOT_TARGET_SPEC_LIST:${M_ListToSkip}}}
|
||||
# clean up
|
||||
_only_machines := ${_only_machines:O:u}
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _only_machines=${_only_machines}
|
||||
.endif
|
||||
|
||||
# make sure we have a starting place?
|
||||
DIRDEPS ?= ${RELDIR}
|
||||
.endif # target
|
||||
@ -697,6 +750,7 @@ _cache_deps += ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.export _cache_deps
|
||||
x!= echo; for x in $$_cache_deps; do echo " $$x \\"; done >&3
|
||||
.endif
|
||||
# anything in _build_xtra_dirs is hooked to dirdeps: only
|
||||
x!= echo; { echo; echo '${_this_dir}.$m: $${DIRDEPS.${_this_dir}.$m}'; \
|
||||
echo; echo 'dirdeps: ${_this_dir}.$m \'; \
|
||||
for x in $$_build_xtra_dirs; do echo " $$x \\"; done; \
|
||||
@ -735,7 +789,7 @@ DEP_MACHINE := ${_DEP_MACHINE}
|
||||
# Warning: there is an assumption here that MACHINE is always
|
||||
# the first entry in TARGET_SPEC_VARS.
|
||||
# If TARGET_SPEC and MACHINE are insufficient, you have a problem.
|
||||
_m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:S;${MACHINE};${d:E:C/,.*//};:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]}
|
||||
_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:}}
|
||||
@ -801,6 +855,7 @@ _reldir_failed: .NOMETA
|
||||
.endif
|
||||
|
||||
# bootstrapping new dependencies made easy?
|
||||
.if !target(bootstrap-empty)
|
||||
.if !target(bootstrap) && (make(bootstrap) || \
|
||||
make(bootstrap-this) || \
|
||||
make(bootstrap-recurse) || \
|
||||
@ -856,3 +911,4 @@ bootstrap-empty: .NOTMAIN .NOMETA
|
||||
@{ echo DIRDEPS=; echo ".include <dirdeps.mk>"; } > ${_want}
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: dpadd.mk,v 1.28 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: dpadd.mk,v 1.29 2021/04/20 02:30:44 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, Simon J. Gerraty
|
||||
#
|
||||
@ -211,8 +211,9 @@ OBJ_${__lib:T:R} ?= ${__lib:H:S,${OBJTOP},${RELOBJTOP},}
|
||||
# If INCLUDES_libfoo is not set, then we'll use ${SRC_libfoo}/h if it exists,
|
||||
# else just ${SRC_libfoo}.
|
||||
#
|
||||
INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
|
||||
|
||||
.if !empty(SRC_${__lib:T:R})
|
||||
INCLUDES_${__lib:T:R} ?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h:${SRC_${__lib:T:R}}}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# even for staged libs we sometimes
|
||||
|
@ -55,7 +55,7 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: install-mk,v 1.191 2021/01/30 23:16:42 sjg Exp $
|
||||
# $Id: install-mk,v 1.196 2021/06/19 15:30:41 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1994 Simon J. Gerraty
|
||||
#
|
||||
@ -70,7 +70,7 @@
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
MK_VERSION=20210130
|
||||
MK_VERSION=20210616
|
||||
OWNER=
|
||||
GROUP=
|
||||
MODE=444
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.autodep.mk,v 1.53 2020/11/08 05:47:56 sjg Exp $
|
||||
# $Id: meta.autodep.mk,v 1.54 2021/03/06 17:03:18 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
@ -298,16 +298,20 @@ start_utc := ${now_utc}
|
||||
meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \
|
||||
created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}}
|
||||
|
||||
.if !target(_reldir_finish)
|
||||
#.END: _reldir_finish
|
||||
.if target(gendirdeps)
|
||||
_reldir_finish: gendirdeps
|
||||
.endif
|
||||
_reldir_finish: .NOMETA
|
||||
@echo "${TIME_STAMP} Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
.endif
|
||||
|
||||
.if !target(_reldir_failed)
|
||||
#.ERROR: _reldir_failed
|
||||
_reldir_failed: .NOMETA
|
||||
@echo "${TIME_STAMP} Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
.endif
|
||||
|
||||
.if !defined(WITHOUT_META_STATS) && ${.MAKE.LEVEL} > 0
|
||||
.END: _reldir_finish
|
||||
|
@ -37,7 +37,7 @@ We only pay attention to a subset of the information in the
|
||||
|
||||
"""
|
||||
RCSid:
|
||||
$Id: meta2deps.py,v 1.34 2020/10/02 03:11:17 sjg Exp $
|
||||
$Id: meta2deps.py,v 1.38 2021/06/17 05:20:08 sjg Exp $
|
||||
|
||||
Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
Copyright (c) 2011-2017, Juniper Networks, Inc.
|
||||
@ -68,12 +68,6 @@ RCSid:
|
||||
|
||||
import os, re, sys
|
||||
|
||||
def getv(dict, key, d=None):
|
||||
"""Lookup key in dict and return value or the supplied default."""
|
||||
if key in dict:
|
||||
return dict[key]
|
||||
return d
|
||||
|
||||
def resolve(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
|
||||
"""
|
||||
Return an absolute path, resolving via cwd or last_dir if needed.
|
||||
@ -152,7 +146,10 @@ def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
|
||||
return path
|
||||
|
||||
def sort_unique(list, cmp=None, key=None, reverse=False):
|
||||
list.sort(cmp, key, reverse)
|
||||
if sys.version_info[0] == 2:
|
||||
list.sort(cmp, key, reverse)
|
||||
else:
|
||||
list.sort(reverse=reverse)
|
||||
nl = []
|
||||
le = None
|
||||
for e in list:
|
||||
@ -224,22 +221,22 @@ class MetaFile:
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
self.debug = getv(conf, 'debug', 0)
|
||||
self.debug_out = getv(conf, 'debug_out', sys.stderr)
|
||||
self.debug = conf.get('debug', 0)
|
||||
self.debug_out = conf.get('debug_out', sys.stderr)
|
||||
|
||||
self.machine = getv(conf, 'MACHINE', '')
|
||||
self.machine_arch = getv(conf, 'MACHINE_ARCH', '')
|
||||
self.target_spec = getv(conf, 'TARGET_SPEC', '')
|
||||
self.curdir = getv(conf, 'CURDIR')
|
||||
self.reldir = getv(conf, 'RELDIR')
|
||||
self.dpdeps = getv(conf, 'DPDEPS')
|
||||
self.machine = conf.get('MACHINE', '')
|
||||
self.machine_arch = conf.get('MACHINE_ARCH', '')
|
||||
self.target_spec = conf.get('TARGET_SPEC', '')
|
||||
self.curdir = conf.get('CURDIR')
|
||||
self.reldir = conf.get('RELDIR')
|
||||
self.dpdeps = conf.get('DPDEPS')
|
||||
self.line = 0
|
||||
|
||||
if not self.conf:
|
||||
# some of the steps below we want to do only once
|
||||
self.conf = conf
|
||||
self.host_target = getv(conf, 'HOST_TARGET')
|
||||
for srctop in getv(conf, 'SRCTOPS', []):
|
||||
self.host_target = conf.get('HOST_TARGET')
|
||||
for srctop in conf.get('SRCTOPS', []):
|
||||
if srctop[-1] != '/':
|
||||
srctop += '/'
|
||||
if not srctop in self.srctops:
|
||||
@ -256,7 +253,7 @@ class MetaFile:
|
||||
if self.target_spec:
|
||||
trim_list += add_trims(self.target_spec)
|
||||
|
||||
for objroot in getv(conf, 'OBJROOTS', []):
|
||||
for objroot in conf.get('OBJROOTS', []):
|
||||
for e in trim_list:
|
||||
if objroot.endswith(e):
|
||||
# this is not what we want - fix it
|
||||
@ -276,7 +273,7 @@ class MetaFile:
|
||||
self.srctops.sort(reverse=True)
|
||||
self.objroots.sort(reverse=True)
|
||||
|
||||
self.excludes = getv(conf, 'EXCLUDES', [])
|
||||
self.excludes = conf.get('EXCLUDES', [])
|
||||
|
||||
if self.debug:
|
||||
print("host_target=", self.host_target, file=self.debug_out)
|
||||
@ -468,8 +465,8 @@ class MetaFile:
|
||||
if pid != last_pid:
|
||||
if last_pid:
|
||||
pid_last_dir[last_pid] = self.last_dir
|
||||
cwd = getv(pid_cwd, pid, self.cwd)
|
||||
self.last_dir = getv(pid_last_dir, pid, self.cwd)
|
||||
cwd = pid_cwd.get(pid, self.cwd)
|
||||
self.last_dir = pid_last_dir.get(pid, self.cwd)
|
||||
last_pid = pid
|
||||
|
||||
# process operations
|
||||
@ -557,7 +554,10 @@ class MetaFile:
|
||||
# to the src dir, we may need to add dependencies for each
|
||||
rdir = dir
|
||||
dir = abspath(dir, cwd, self.last_dir, self.debug, self.debug_out)
|
||||
rdir = os.path.realpath(dir)
|
||||
if dir:
|
||||
rdir = os.path.realpath(dir)
|
||||
else:
|
||||
dir = rdir
|
||||
if rdir == dir:
|
||||
rdir = None
|
||||
# now put path back together
|
||||
@ -725,7 +725,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
for a in eaten:
|
||||
args.remove(a)
|
||||
|
||||
debug_out = getv(conf, 'debug_out', sys.stderr)
|
||||
debug_out = conf.get('debug_out', sys.stderr)
|
||||
|
||||
if debug:
|
||||
print("config:", file=debug_out)
|
||||
@ -752,9 +752,9 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
|
||||
print(m.src_dirdeps('\nsrc:'))
|
||||
|
||||
dpdeps = getv(conf, 'DPDEPS')
|
||||
dpdeps = conf.get('DPDEPS')
|
||||
if dpdeps:
|
||||
m.file_depends(open(dpdeps, 'wb'))
|
||||
m.file_depends(open(dpdeps, 'w'))
|
||||
|
||||
return m
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: rst2htm.mk,v 1.11 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: rst2htm.mk,v 1.12 2021/05/26 04:20:31 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2009, Simon J. Gerraty
|
||||
#
|
||||
@ -21,7 +21,9 @@ TXTSRCS != 'ls' -1t ${.CURDIR}/*.txt ${.CURDIR}/*.rst 2>/dev/null; echo
|
||||
.endif
|
||||
RSTSRCS ?= ${TXTSRCS}
|
||||
HTMFILES ?= ${RSTSRCS:R:T:O:u:%=%.htm}
|
||||
RST2HTML ?= rst2html.py
|
||||
# can be empty, 4 or 5
|
||||
HTML_VERSION ?=
|
||||
RST2HTML ?= rst2html${HTML_VERSION}.py
|
||||
RST2PDF ?= rst2pdf
|
||||
RST2S5 ?= rst2s5.py
|
||||
# the following will run RST2S5 if the target name contains the word 'slides'
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nonints.h,v 1.202 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: nonints.h,v 1.213 2021/04/11 13:35:56 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -76,14 +76,14 @@
|
||||
void Arch_Init(void);
|
||||
void Arch_End(void);
|
||||
|
||||
Boolean Arch_ParseArchive(char **, GNodeList *, GNode *);
|
||||
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_FindLib(GNode *, SearchPath *);
|
||||
Boolean Arch_LibOODate(GNode *);
|
||||
Boolean Arch_IsLib(GNode *);
|
||||
bool Arch_LibOODate(GNode *);
|
||||
bool Arch_IsLib(GNode *);
|
||||
|
||||
/* compat.c */
|
||||
int Compat_RunCommand(const char *, GNode *, StringListNode *);
|
||||
@ -91,7 +91,7 @@ void Compat_Run(GNodeList *);
|
||||
void Compat_Make(GNode *, GNode *);
|
||||
|
||||
/* cond.c */
|
||||
CondEvalResult Cond_EvalCondition(const char *, Boolean *);
|
||||
CondEvalResult Cond_EvalCondition(const char *, bool *);
|
||||
CondEvalResult Cond_EvalLine(const char *);
|
||||
void Cond_restore_depth(unsigned int);
|
||||
unsigned int Cond_save_depth(void);
|
||||
@ -117,16 +117,16 @@ void SearchPath_Free(SearchPath *);
|
||||
|
||||
/* for.c */
|
||||
int For_Eval(const char *);
|
||||
Boolean For_Accum(const char *);
|
||||
bool For_Accum(const char *);
|
||||
void For_Run(int);
|
||||
|
||||
/* job.c */
|
||||
#ifdef WAIT_T
|
||||
void JobReapChild(pid_t, WAIT_T, Boolean);
|
||||
void JobReapChild(pid_t, WAIT_T, bool);
|
||||
#endif
|
||||
|
||||
/* main.c */
|
||||
Boolean GetBooleanVar(const char *, Boolean);
|
||||
bool GetBooleanExpr(const char *, bool);
|
||||
void Main_ParseArgLine(const char *);
|
||||
char *Cmd_Exec(const char *, const char **);
|
||||
void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
|
||||
@ -137,7 +137,7 @@ void Finish(int) MAKE_ATTR_DEAD;
|
||||
int eunlink(const char *);
|
||||
void execDie(const char *, const char *);
|
||||
char *getTmpdir(void);
|
||||
Boolean ParseBoolean(const char *, Boolean);
|
||||
bool ParseBoolean(const char *, bool);
|
||||
char *cached_realpath(const char *, char *);
|
||||
|
||||
/* parse.c */
|
||||
@ -161,86 +161,14 @@ typedef struct VarAssign {
|
||||
typedef char *(*ReadMoreProc)(void *, size_t *);
|
||||
|
||||
void Parse_Error(ParseErrorLevel, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
|
||||
Boolean Parse_IsVar(const char *, VarAssign *out_var);
|
||||
void Parse_DoVar(VarAssign *, GNode *);
|
||||
bool Parse_IsVar(const char *, VarAssign *out_var);
|
||||
void Parse_Var(VarAssign *, GNode *);
|
||||
void Parse_AddIncludeDir(const char *);
|
||||
void Parse_File(const char *, int);
|
||||
void Parse_SetInput(const char *, int, int, ReadMoreProc, void *);
|
||||
void Parse_MainName(GNodeList *);
|
||||
int Parse_GetFatals(void);
|
||||
|
||||
/* str.c */
|
||||
|
||||
/* A read-only string that may need to be freed after use. */
|
||||
typedef struct FStr {
|
||||
const char *str;
|
||||
void *freeIt;
|
||||
} FStr;
|
||||
|
||||
/* A modifiable string that may need to be freed after use. */
|
||||
typedef struct MFStr {
|
||||
char *str;
|
||||
void *freeIt;
|
||||
} MFStr;
|
||||
|
||||
typedef struct Words {
|
||||
char **words;
|
||||
size_t len;
|
||||
void *freeIt;
|
||||
} Words;
|
||||
|
||||
/* Return a string that is the sole owner of str. */
|
||||
MAKE_INLINE FStr
|
||||
FStr_InitOwn(char *str)
|
||||
{
|
||||
return (FStr){ str, str };
|
||||
}
|
||||
|
||||
/* Return a string that refers to the shared str. */
|
||||
MAKE_INLINE FStr
|
||||
FStr_InitRefer(const char *str)
|
||||
{
|
||||
return (FStr){ str, NULL };
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
FStr_Done(FStr *fstr)
|
||||
{
|
||||
free(fstr->freeIt);
|
||||
}
|
||||
|
||||
/* Return a string that is the sole owner of str. */
|
||||
MAKE_INLINE MFStr
|
||||
MFStr_InitOwn(char *str)
|
||||
{
|
||||
return (MFStr){ str, str };
|
||||
}
|
||||
|
||||
/* Return a string that refers to the shared str. */
|
||||
MAKE_INLINE MFStr
|
||||
MFStr_InitRefer(char *str)
|
||||
{
|
||||
return (MFStr){ str, NULL };
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
MFStr_Done(MFStr *mfstr)
|
||||
{
|
||||
free(mfstr->freeIt);
|
||||
}
|
||||
|
||||
Words Str_Words(const char *, Boolean);
|
||||
MAKE_INLINE void
|
||||
Words_Free(Words w)
|
||||
{
|
||||
free(w.words);
|
||||
free(w.freeIt);
|
||||
}
|
||||
|
||||
char *str_concat2(const char *, const char *);
|
||||
char *str_concat3(const char *, const char *, const char *);
|
||||
char *str_concat4(const char *, const char *, const char *, const char *);
|
||||
Boolean Str_Match(const char *, const char *);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* strlcpy.c */
|
||||
@ -252,12 +180,12 @@ void Suff_Init(void);
|
||||
void Suff_End(void);
|
||||
|
||||
void Suff_ClearSuffixes(void);
|
||||
Boolean Suff_IsTransform(const char *);
|
||||
bool Suff_IsTransform(const char *);
|
||||
GNode *Suff_AddTransform(const char *);
|
||||
void Suff_EndTransform(GNode *);
|
||||
void Suff_AddSuffix(const char *, GNode **);
|
||||
SearchPath *Suff_GetPath(const char *);
|
||||
void Suff_DoPaths(void);
|
||||
void Suff_ExtendPaths(void);
|
||||
void Suff_AddInclude(const char *);
|
||||
void Suff_AddLib(const char *);
|
||||
void Suff_FindDeps(GNode *);
|
||||
@ -277,7 +205,7 @@ GNode *Targ_GetNode(const char *);
|
||||
GNode *Targ_NewInternalNode(const char *);
|
||||
GNode *Targ_GetEndNode(void);
|
||||
void Targ_FindList(GNodeList *, StringList *);
|
||||
Boolean Targ_Precious(const GNode *);
|
||||
bool Targ_Precious(const GNode *);
|
||||
void Targ_SetMain(GNode *);
|
||||
void Targ_PrintCmds(GNode *);
|
||||
void Targ_PrintNode(GNode *, int);
|
||||
@ -292,36 +220,40 @@ const char *GNodeMade_Name(GNodeMade);
|
||||
void Var_Init(void);
|
||||
void Var_End(void);
|
||||
|
||||
typedef enum VarEvalFlags {
|
||||
VARE_NONE = 0,
|
||||
typedef enum VarEvalMode {
|
||||
|
||||
/*
|
||||
* Expand and evaluate variables during parsing.
|
||||
* Only parse the expression but don't evaluate any part of it.
|
||||
*
|
||||
* TODO: Document what Var_Parse and Var_Subst return when this flag
|
||||
* is not set.
|
||||
* TODO: Document what Var_Parse and Var_Subst return in this mode.
|
||||
* As of 2021-03-15, they return unspecified, inconsistent results.
|
||||
*/
|
||||
VARE_WANTRES = 1 << 0,
|
||||
VARE_PARSE_ONLY,
|
||||
|
||||
/* Parse and evaluate the expression. */
|
||||
VARE_WANTRES,
|
||||
|
||||
/*
|
||||
* Treat undefined variables as errors.
|
||||
* Must only be used in combination with VARE_WANTRES.
|
||||
* Parse and evaluate the expression. It is an error if a
|
||||
* subexpression evaluates to undefined.
|
||||
*/
|
||||
VARE_UNDEFERR = 1 << 1,
|
||||
VARE_UNDEFERR,
|
||||
|
||||
/*
|
||||
* Keep '$$' as '$$' instead of reducing it to a single '$'.
|
||||
* Parse and evaluate the expression. Keep '$$' as '$$' instead of
|
||||
* reducing it to a single '$'. Subexpressions that evaluate to
|
||||
* undefined expand to an empty string.
|
||||
*
|
||||
* Used in variable assignments using the ':=' operator. It allows
|
||||
* multiple such assignments to be chained without accidentally
|
||||
* expanding '$$file' to '$file' in the first assignment and
|
||||
* interpreting it as '${f}' followed by 'ile' in the next assignment.
|
||||
*/
|
||||
VARE_KEEP_DOLLAR = 1 << 2,
|
||||
VARE_EVAL_KEEP_DOLLAR,
|
||||
|
||||
/*
|
||||
* Keep undefined variables as-is instead of expanding them to an
|
||||
* empty string.
|
||||
* Parse and evaluate the expression. Keep undefined variables as-is
|
||||
* instead of expanding them to an empty string.
|
||||
*
|
||||
* Example for a ':=' assignment:
|
||||
* CFLAGS = $(.INCLUDES)
|
||||
@ -330,8 +262,14 @@ typedef enum VarEvalFlags {
|
||||
* # way) is still undefined, the updated CFLAGS becomes
|
||||
* # "-I.. $(.INCLUDES)".
|
||||
*/
|
||||
VARE_KEEP_UNDEF = 1 << 3
|
||||
} VarEvalFlags;
|
||||
VARE_EVAL_KEEP_UNDEF,
|
||||
|
||||
/*
|
||||
* Parse and evaluate the expression. Keep '$$' as '$$' and preserve
|
||||
* undefined subexpressions.
|
||||
*/
|
||||
VARE_KEEP_DOLLAR_UNDEF
|
||||
} VarEvalMode;
|
||||
|
||||
typedef enum VarSetFlags {
|
||||
VAR_SET_NONE = 0,
|
||||
@ -361,7 +299,8 @@ typedef enum VarParseResult {
|
||||
* Some callers handle this case differently, so return this
|
||||
* information to them, for now.
|
||||
*
|
||||
* TODO: Replace this with a new flag VARE_KEEP_UNDEFINED.
|
||||
* TODO: Instead of having this special return value, rather ensure
|
||||
* that VARE_EVAL_KEEP_UNDEF is processed properly.
|
||||
*/
|
||||
VPR_UNDEF
|
||||
|
||||
@ -385,18 +324,18 @@ void Var_SetWithFlags(GNode *, const char *, const char *, VarSetFlags);
|
||||
void Var_SetExpandWithFlags(GNode *, const char *, const char *, VarSetFlags);
|
||||
void Var_Append(GNode *, const char *, const char *);
|
||||
void Var_AppendExpand(GNode *, const char *, const char *);
|
||||
Boolean Var_Exists(GNode *, const char *);
|
||||
Boolean Var_ExistsExpand(GNode *, const char *);
|
||||
bool Var_Exists(GNode *, const char *);
|
||||
bool Var_ExistsExpand(GNode *, const char *);
|
||||
FStr Var_Value(GNode *, const char *);
|
||||
const char *GNode_ValueDirect(GNode *, const char *);
|
||||
VarParseResult Var_Parse(const char **, GNode *, VarEvalFlags, FStr *);
|
||||
VarParseResult Var_Subst(const char *, GNode *, VarEvalFlags, char **);
|
||||
VarParseResult Var_Parse(const char **, GNode *, VarEvalMode, FStr *);
|
||||
VarParseResult Var_Subst(const char *, GNode *, VarEvalMode, char **);
|
||||
void Var_Stats(void);
|
||||
void Var_Dump(GNode *);
|
||||
void Var_ReexportVars(void);
|
||||
void Var_Export(VarExportMode, const char *);
|
||||
void Var_ExportVars(const char *);
|
||||
void Var_UnExport(Boolean, const char *);
|
||||
void Var_UnExport(bool, const char *);
|
||||
|
||||
void Global_Set(const char *, const char *);
|
||||
void Global_SetExpand(const char *, const char *);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: str.c,v 1.81 2021/02/01 22:36:28 rillig Exp $ */
|
||||
/* $NetBSD: str.c,v 1.85 2021/05/30 21:16:54 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.81 2021/02/01 22:36:28 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: str.c,v 1.85 2021/05/30 21:16:54 rillig Exp $");
|
||||
|
||||
/* Return the concatenation of s1 and s2, freshly allocated. */
|
||||
char *
|
||||
@ -99,39 +99,23 @@ str_concat3(const char *s1, const char *s2, const char *s3)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return the concatenation of s1, s2, s3 and s4, freshly allocated. */
|
||||
char *
|
||||
str_concat4(const char *s1, const char *s2, const char *s3, const char *s4)
|
||||
{
|
||||
size_t len1 = strlen(s1);
|
||||
size_t len2 = strlen(s2);
|
||||
size_t len3 = strlen(s3);
|
||||
size_t len4 = strlen(s4);
|
||||
char *result = bmake_malloc(len1 + len2 + len3 + len4 + 1);
|
||||
memcpy(result, s1, len1);
|
||||
memcpy(result + len1, s2, len2);
|
||||
memcpy(result + len1 + len2, s3, len3);
|
||||
memcpy(result + len1 + len2 + len3, s4, len4 + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fracture a string into an array of words (as delineated by tabs or spaces)
|
||||
* taking quotation marks into account.
|
||||
*
|
||||
* If expand is TRUE, quotes are removed and escape sequences such as \r, \t,
|
||||
* If expand is true, quotes are removed and escape sequences such as \r, \t,
|
||||
* etc... are expanded. In this case, return NULL on parse errors.
|
||||
*
|
||||
* Returns the fractured words, which must be freed later using Words_Free,
|
||||
* unless the returned Words.words was NULL.
|
||||
*/
|
||||
Words
|
||||
Str_Words(const char *str, Boolean expand)
|
||||
SubstringWords
|
||||
Substring_Words(const char *str, bool expand)
|
||||
{
|
||||
size_t str_len;
|
||||
char *words_buf;
|
||||
size_t words_cap;
|
||||
char **words;
|
||||
Substring *words;
|
||||
size_t words_len;
|
||||
char inquote;
|
||||
char *word_start;
|
||||
@ -146,7 +130,7 @@ Str_Words(const char *str, Boolean expand)
|
||||
words_buf = bmake_malloc(str_len + 1);
|
||||
|
||||
words_cap = str_len / 5 > 50 ? str_len / 5 : 50;
|
||||
words = bmake_malloc((words_cap + 1) * sizeof(char *));
|
||||
words = bmake_malloc((words_cap + 1) * sizeof(words[0]));
|
||||
|
||||
/*
|
||||
* copy the string; at the same time, parse backslashes,
|
||||
@ -205,17 +189,24 @@ Str_Words(const char *str, Boolean expand)
|
||||
*word_end++ = '\0';
|
||||
if (words_len == words_cap) {
|
||||
size_t new_size;
|
||||
words_cap *= 2; /* ramp up fast */
|
||||
new_size = (words_cap + 1) * sizeof(char *);
|
||||
words_cap *= 2;
|
||||
new_size = (words_cap + 1) * sizeof(words[0]);
|
||||
words = bmake_realloc(words, new_size);
|
||||
}
|
||||
words[words_len++] = word_start;
|
||||
words[words_len++] =
|
||||
Substring_Init(word_start, word_end - 1);
|
||||
word_start = NULL;
|
||||
if (ch == '\n' || ch == '\0') {
|
||||
if (expand && inquote != '\0') {
|
||||
SubstringWords res;
|
||||
|
||||
free(words);
|
||||
free(words_buf);
|
||||
return (Words){ NULL, 0, NULL };
|
||||
|
||||
res.words = NULL;
|
||||
res.len = 0;
|
||||
res.freeIt = NULL;
|
||||
return res;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
@ -262,8 +253,40 @@ Str_Words(const char *str, Boolean expand)
|
||||
*word_end++ = ch;
|
||||
}
|
||||
done:
|
||||
words[words_len] = NULL; /* useful for argv */
|
||||
return (Words){ words, words_len, words_buf };
|
||||
words[words_len] = Substring_Init(NULL, NULL); /* useful for argv */
|
||||
|
||||
{
|
||||
SubstringWords result;
|
||||
|
||||
result.words = words;
|
||||
result.len = words_len;
|
||||
result.freeIt = words_buf;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Words
|
||||
Str_Words(const char *str, bool expand)
|
||||
{
|
||||
SubstringWords swords;
|
||||
Words words;
|
||||
size_t i;
|
||||
|
||||
swords = Substring_Words(str, expand);
|
||||
if (swords.words == NULL) {
|
||||
words.words = NULL;
|
||||
words.len = 0;
|
||||
words.freeIt = NULL;
|
||||
return words;
|
||||
}
|
||||
|
||||
words.words = bmake_malloc((swords.len + 1) * sizeof(words.words[0]));
|
||||
words.len = swords.len;
|
||||
words.freeIt = swords.freeIt;
|
||||
for (i = 0; i < swords.len + 1; i++)
|
||||
words.words[i] = UNCONST(swords.words[i].start);
|
||||
free(swords.words);
|
||||
return words;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -272,7 +295,7 @@ done:
|
||||
*
|
||||
* XXX: this function does not detect or report malformed patterns.
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
Str_Match(const char *str, const char *pat)
|
||||
{
|
||||
for (;;) {
|
||||
@ -284,7 +307,7 @@ Str_Match(const char *str, const char *pat)
|
||||
if (*pat == '\0')
|
||||
return *str == '\0';
|
||||
if (*str == '\0' && *pat != '*')
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
/*
|
||||
* A '*' in the pattern matches any substring. We handle this
|
||||
@ -295,13 +318,13 @@ Str_Match(const char *str, const char *pat)
|
||||
while (*pat == '*')
|
||||
pat++;
|
||||
if (*pat == '\0')
|
||||
return TRUE;
|
||||
return true;
|
||||
while (*str != '\0') {
|
||||
if (Str_Match(str, pat))
|
||||
return TRUE;
|
||||
return true;
|
||||
str++;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A '?' in the pattern matches any single character. */
|
||||
@ -315,14 +338,14 @@ Str_Match(const char *str, const char *pat)
|
||||
* character lists, the backslash is an ordinary character.
|
||||
*/
|
||||
if (*pat == '[') {
|
||||
Boolean neg = pat[1] == '^';
|
||||
bool neg = pat[1] == '^';
|
||||
pat += neg ? 2 : 1;
|
||||
|
||||
for (;;) {
|
||||
if (*pat == ']' || *pat == '\0') {
|
||||
if (neg)
|
||||
break;
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* XXX: This naive comparison makes the
|
||||
@ -347,7 +370,7 @@ Str_Match(const char *str, const char *pat)
|
||||
pat++;
|
||||
}
|
||||
if (neg && *pat != ']' && *pat != '\0')
|
||||
return FALSE;
|
||||
return false;
|
||||
while (*pat != ']' && *pat != '\0')
|
||||
pat++;
|
||||
if (*pat == '\0')
|
||||
@ -362,11 +385,11 @@ Str_Match(const char *str, const char *pat)
|
||||
if (*pat == '\\') {
|
||||
pat++;
|
||||
if (*pat == '\0')
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*pat != *str)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
thisCharOK:
|
||||
pat++;
|
||||
|
366
contrib/bmake/str.h
Normal file
366
contrib/bmake/str.h
Normal file
@ -0,0 +1,366 @@
|
||||
/* $NetBSD: str.h,v 1.9 2021/05/30 21:16:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2021 Roland Illig <rillig@NetBSD.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Memory-efficient string handling.
|
||||
*/
|
||||
|
||||
|
||||
/* A read-only string that may need to be freed after use. */
|
||||
typedef struct FStr {
|
||||
const char *str;
|
||||
void *freeIt;
|
||||
} FStr;
|
||||
|
||||
/* A modifiable string that may need to be freed after use. */
|
||||
typedef struct MFStr {
|
||||
char *str;
|
||||
void *freeIt;
|
||||
} MFStr;
|
||||
|
||||
/* A read-only range of a character array, NOT null-terminated. */
|
||||
typedef struct Substring {
|
||||
const char *start;
|
||||
const char *end;
|
||||
} Substring;
|
||||
|
||||
/*
|
||||
* Builds a string, only allocating memory if the string is different from the
|
||||
* expected string.
|
||||
*/
|
||||
typedef struct LazyBuf {
|
||||
char *data;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
const char *expected;
|
||||
void *freeIt;
|
||||
} LazyBuf;
|
||||
|
||||
/* The result of splitting a string into words. */
|
||||
typedef struct Words {
|
||||
char **words;
|
||||
size_t len;
|
||||
void *freeIt;
|
||||
} Words;
|
||||
|
||||
/* The result of splitting a string into words. */
|
||||
typedef struct SubstringWords {
|
||||
Substring *words;
|
||||
size_t len;
|
||||
void *freeIt;
|
||||
} SubstringWords;
|
||||
|
||||
|
||||
MAKE_INLINE FStr
|
||||
FStr_Init(const char *str, void *freeIt)
|
||||
{
|
||||
FStr fstr;
|
||||
fstr.str = str;
|
||||
fstr.freeIt = freeIt;
|
||||
return fstr;
|
||||
}
|
||||
|
||||
/* Return a string that is the sole owner of str. */
|
||||
MAKE_INLINE FStr
|
||||
FStr_InitOwn(char *str)
|
||||
{
|
||||
return FStr_Init(str, str);
|
||||
}
|
||||
|
||||
/* Return a string that refers to the shared str. */
|
||||
MAKE_INLINE FStr
|
||||
FStr_InitRefer(const char *str)
|
||||
{
|
||||
return FStr_Init(str, NULL);
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
FStr_Done(FStr *fstr)
|
||||
{
|
||||
free(fstr->freeIt);
|
||||
#ifdef CLEANUP
|
||||
fstr->str = NULL;
|
||||
fstr->freeIt = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
MAKE_INLINE MFStr
|
||||
MFStr_Init(char *str, void *freeIt)
|
||||
{
|
||||
MFStr mfstr;
|
||||
mfstr.str = str;
|
||||
mfstr.freeIt = freeIt;
|
||||
return mfstr;
|
||||
}
|
||||
|
||||
/* Return a string that is the sole owner of str. */
|
||||
MAKE_INLINE MFStr
|
||||
MFStr_InitOwn(char *str)
|
||||
{
|
||||
return MFStr_Init(str, str);
|
||||
}
|
||||
|
||||
/* Return a string that refers to the shared str. */
|
||||
MAKE_INLINE MFStr
|
||||
MFStr_InitRefer(char *str)
|
||||
{
|
||||
return MFStr_Init(str, NULL);
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
MFStr_Done(MFStr *mfstr)
|
||||
{
|
||||
free(mfstr->freeIt);
|
||||
#ifdef CLEANUP
|
||||
mfstr->str = NULL;
|
||||
mfstr->freeIt = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
MAKE_STATIC Substring
|
||||
Substring_Init(const char *start, const char *end)
|
||||
{
|
||||
Substring sub;
|
||||
|
||||
sub.start = start;
|
||||
sub.end = end;
|
||||
return sub;
|
||||
}
|
||||
|
||||
MAKE_INLINE Substring
|
||||
Substring_InitStr(const char *str)
|
||||
{
|
||||
return Substring_Init(str, str + strlen(str));
|
||||
}
|
||||
|
||||
MAKE_STATIC size_t
|
||||
Substring_Length(Substring sub)
|
||||
{
|
||||
return (size_t)(sub.end - sub.start);
|
||||
}
|
||||
|
||||
MAKE_STATIC bool
|
||||
Substring_IsEmpty(Substring sub)
|
||||
{
|
||||
return sub.start == sub.end;
|
||||
}
|
||||
|
||||
MAKE_INLINE bool
|
||||
Substring_Equals(Substring sub, const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
return Substring_Length(sub) == len &&
|
||||
memcmp(sub.start, str, len) == 0;
|
||||
}
|
||||
|
||||
MAKE_STATIC Substring
|
||||
Substring_Sub(Substring sub, size_t start, size_t end)
|
||||
{
|
||||
assert(start <= Substring_Length(sub));
|
||||
assert(end <= Substring_Length(sub));
|
||||
return Substring_Init(sub.start + start, sub.start + end);
|
||||
}
|
||||
|
||||
MAKE_STATIC bool
|
||||
Substring_HasPrefix(Substring sub, Substring prefix)
|
||||
{
|
||||
return Substring_Length(sub) >= Substring_Length(prefix) &&
|
||||
memcmp(sub.start, prefix.start, Substring_Length(prefix)) == 0;
|
||||
}
|
||||
|
||||
MAKE_STATIC bool
|
||||
Substring_HasSuffix(Substring sub, Substring suffix)
|
||||
{
|
||||
size_t suffixLen = Substring_Length(suffix);
|
||||
return Substring_Length(sub) >= suffixLen &&
|
||||
memcmp(sub.end - suffixLen, suffix.start, suffixLen) == 0;
|
||||
}
|
||||
|
||||
/* Returns an independent, null-terminated copy of the substring. */
|
||||
MAKE_STATIC FStr
|
||||
Substring_Str(Substring sub)
|
||||
{
|
||||
if (Substring_IsEmpty(sub))
|
||||
return FStr_InitRefer("");
|
||||
return FStr_InitOwn(bmake_strsedup(sub.start, sub.end));
|
||||
}
|
||||
|
||||
MAKE_STATIC const char *
|
||||
Substring_SkipFirst(Substring sub, char ch)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = sub.start; p != sub.end; p++)
|
||||
if (*p == ch)
|
||||
return p + 1;
|
||||
return sub.start;
|
||||
}
|
||||
|
||||
MAKE_STATIC const char *
|
||||
Substring_LastIndex(Substring sub, char ch)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = sub.end; p != sub.start; p--)
|
||||
if (p[-1] == ch)
|
||||
return p - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MAKE_STATIC Substring
|
||||
Substring_Dirname(Substring pathname)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = pathname.end; p != pathname.start; p--)
|
||||
if (p[-1] == '/')
|
||||
return Substring_Init(pathname.start, p - 1);
|
||||
return Substring_InitStr(".");
|
||||
}
|
||||
|
||||
MAKE_STATIC Substring
|
||||
Substring_Basename(Substring pathname)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = pathname.end; p != pathname.start; p--)
|
||||
if (p[-1] == '/')
|
||||
return Substring_Init(p, pathname.end);
|
||||
return pathname;
|
||||
}
|
||||
|
||||
|
||||
MAKE_STATIC void
|
||||
LazyBuf_Init(LazyBuf *buf, const char *expected)
|
||||
{
|
||||
buf->data = NULL;
|
||||
buf->len = 0;
|
||||
buf->cap = 0;
|
||||
buf->expected = expected;
|
||||
buf->freeIt = NULL;
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
LazyBuf_Done(LazyBuf *buf)
|
||||
{
|
||||
free(buf->freeIt);
|
||||
}
|
||||
|
||||
MAKE_STATIC void
|
||||
LazyBuf_Add(LazyBuf *buf, char ch)
|
||||
{
|
||||
|
||||
if (buf->data != NULL) {
|
||||
if (buf->len == buf->cap) {
|
||||
buf->cap *= 2;
|
||||
buf->data = bmake_realloc(buf->data, buf->cap);
|
||||
}
|
||||
buf->data[buf->len++] = ch;
|
||||
|
||||
} else if (ch == buf->expected[buf->len]) {
|
||||
buf->len++;
|
||||
return;
|
||||
|
||||
} else {
|
||||
buf->cap = buf->len + 16;
|
||||
buf->data = bmake_malloc(buf->cap);
|
||||
memcpy(buf->data, buf->expected, buf->len);
|
||||
buf->data[buf->len++] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
MAKE_STATIC void
|
||||
LazyBuf_AddStr(LazyBuf *buf, const char *str)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = str; *p != '\0'; p++)
|
||||
LazyBuf_Add(buf, *p);
|
||||
}
|
||||
|
||||
MAKE_STATIC void
|
||||
LazyBuf_AddBytesBetween(LazyBuf *buf, const char *start, const char *end)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = start; p != end; p++)
|
||||
LazyBuf_Add(buf, *p);
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
LazyBuf_AddSubstring(LazyBuf *buf, Substring sub)
|
||||
{
|
||||
LazyBuf_AddBytesBetween(buf, sub.start, sub.end);
|
||||
}
|
||||
|
||||
MAKE_STATIC Substring
|
||||
LazyBuf_Get(const LazyBuf *buf)
|
||||
{
|
||||
const char *start = buf->data != NULL ? buf->data : buf->expected;
|
||||
return Substring_Init(start, start + buf->len);
|
||||
}
|
||||
|
||||
MAKE_STATIC FStr
|
||||
LazyBuf_DoneGet(LazyBuf *buf)
|
||||
{
|
||||
if (buf->data != NULL) {
|
||||
LazyBuf_Add(buf, '\0');
|
||||
return FStr_InitOwn(buf->data);
|
||||
}
|
||||
return Substring_Str(LazyBuf_Get(buf));
|
||||
}
|
||||
|
||||
|
||||
Words Str_Words(const char *, bool);
|
||||
|
||||
MAKE_INLINE void
|
||||
Words_Free(Words w)
|
||||
{
|
||||
free(w.words);
|
||||
free(w.freeIt);
|
||||
}
|
||||
|
||||
|
||||
SubstringWords Substring_Words(const char *, bool);
|
||||
|
||||
MAKE_INLINE void
|
||||
SubstringWords_Free(SubstringWords w)
|
||||
{
|
||||
free(w.words);
|
||||
free(w.freeIt);
|
||||
}
|
||||
|
||||
|
||||
char *str_concat2(const char *, const char *);
|
||||
char *str_concat3(const char *, const char *, const char *);
|
||||
|
||||
bool Str_Match(const char *, const char *);
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: suff.c,v 1.345 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: suff.c,v 1.350 2021/04/04 10:05:08 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -77,7 +77,8 @@
|
||||
*
|
||||
* Suff_End Clean up the module.
|
||||
*
|
||||
* Suff_DoPaths Extend the search path of each suffix to include the
|
||||
* Suff_ExtendPaths
|
||||
* Extend the search path of each suffix to include the
|
||||
* default search path.
|
||||
*
|
||||
* Suff_ClearSuffixes
|
||||
@ -114,7 +115,7 @@
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)suff.c 8.4 (Berkeley) 3/21/94" */
|
||||
MAKE_RCSID("$NetBSD: suff.c,v 1.345 2021/02/05 05:15:12 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: suff.c,v 1.350 2021/04/04 10:05:08 rillig Exp $");
|
||||
|
||||
typedef List SuffixList;
|
||||
typedef ListNode SuffixListNode;
|
||||
@ -328,7 +329,7 @@ Suffix_TrimSuffix(const Suffix *suff, size_t nameLen, const char *nameEnd)
|
||||
suff->name, suff->nameLen);
|
||||
}
|
||||
|
||||
static Boolean
|
||||
static bool
|
||||
Suffix_IsSuffix(const Suffix *suff, size_t nameLen, const char *nameEnd)
|
||||
{
|
||||
return Suffix_TrimSuffix(suff, nameLen, nameEnd) != NULL;
|
||||
@ -509,9 +510,9 @@ Suff_ClearSuffixes(void)
|
||||
* suffixes (the source ".c" and the target ".o"). If there are no such
|
||||
* suffixes, try a single-suffix transformation as well.
|
||||
*
|
||||
* Return TRUE if the string is a valid transformation.
|
||||
* Return true if the string is a valid transformation.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
ParseTransform(const char *str, Suffix **out_src, Suffix **out_targ)
|
||||
{
|
||||
SuffixListNode *ln;
|
||||
@ -536,7 +537,7 @@ ParseTransform(const char *str, Suffix **out_src, Suffix **out_targ)
|
||||
if (targ != NULL) {
|
||||
*out_src = src;
|
||||
*out_targ = targ;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -554,17 +555,17 @@ ParseTransform(const char *str, Suffix **out_src, Suffix **out_targ)
|
||||
*/
|
||||
*out_src = single;
|
||||
*out_targ = nullSuff;
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if the given string is a transformation rule, that is, a
|
||||
* Return true if the given string is a transformation rule, that is, a
|
||||
* concatenation of two known suffixes such as ".c.o" or a single suffix
|
||||
* such as ".o".
|
||||
*/
|
||||
Boolean
|
||||
bool
|
||||
Suff_IsTransform(const char *str)
|
||||
{
|
||||
Suffix *src, *targ;
|
||||
@ -616,7 +617,7 @@ Suff_AddTransform(const char *name)
|
||||
|
||||
{
|
||||
/* TODO: Avoid the redundant parsing here. */
|
||||
Boolean ok = ParseTransform(name, &srcSuff, &targSuff);
|
||||
bool ok = ParseTransform(name, &srcSuff, &targSuff);
|
||||
assert(ok);
|
||||
(void)ok;
|
||||
}
|
||||
@ -725,11 +726,11 @@ RebuildGraph(GNode *transform, Suffix *suff)
|
||||
* becomes the main target.
|
||||
*
|
||||
* Results:
|
||||
* TRUE iff a new main target has been selected.
|
||||
* true iff a new main target has been selected.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
|
||||
Boolean *inout_removedMain)
|
||||
bool *inout_removedMain)
|
||||
{
|
||||
Suffix *srcSuff, *targSuff;
|
||||
char *ptr;
|
||||
@ -740,20 +741,20 @@ UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
|
||||
*inout_main = target;
|
||||
Targ_SetMain(target);
|
||||
/*
|
||||
* XXX: Why could it be a good idea to return TRUE here?
|
||||
* XXX: Why could it be a good idea to return true here?
|
||||
* The main task of this function is to turn ordinary nodes
|
||||
* into transformations, no matter whether or not a new .MAIN
|
||||
* node has been found.
|
||||
*/
|
||||
/*
|
||||
* XXX: Even when changing this to FALSE, none of the existing
|
||||
* XXX: Even when changing this to false, none of the existing
|
||||
* unit tests fails.
|
||||
*/
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target->type == OP_TRANSFORM)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
/*
|
||||
* XXX: What about a transformation ".cpp.c"? If ".c" is added as
|
||||
@ -762,7 +763,7 @@ UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
|
||||
*/
|
||||
ptr = strstr(target->name, suff->name);
|
||||
if (ptr == NULL)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
/*
|
||||
* XXX: In suff-rebuild.mk, in the line '.SUFFIXES: .c .b .a', this
|
||||
@ -773,14 +774,14 @@ UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
|
||||
* amounts of memory.
|
||||
*/
|
||||
if (ptr == target->name)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (ParseTransform(target->name, &srcSuff, &targSuff)) {
|
||||
if (*inout_main == target) {
|
||||
DEBUG1(MAKE,
|
||||
"Setting main node from \"%s\" back to null\n",
|
||||
target->name);
|
||||
*inout_removedMain = TRUE;
|
||||
*inout_removedMain = true;
|
||||
*inout_main = NULL;
|
||||
Targ_SetMain(NULL);
|
||||
}
|
||||
@ -795,7 +796,7 @@ UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
|
||||
srcSuff->name, targSuff->name);
|
||||
Relate(srcSuff, targSuff);
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -808,7 +809,7 @@ UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
|
||||
static void
|
||||
UpdateTargets(GNode **inout_main, Suffix *suff)
|
||||
{
|
||||
Boolean removedMain = FALSE;
|
||||
bool removedMain = false;
|
||||
GNodeListNode *ln;
|
||||
|
||||
for (ln = Targ_List()->first; ln != NULL; ln = ln->next) {
|
||||
@ -876,7 +877,7 @@ Suff_GetPath(const char *sname)
|
||||
* ".LIBS" and the flag is '-L'.
|
||||
*/
|
||||
void
|
||||
Suff_DoPaths(void)
|
||||
Suff_ExtendPaths(void)
|
||||
{
|
||||
SuffixListNode *ln;
|
||||
char *flags;
|
||||
@ -1061,7 +1062,7 @@ CandidateList_AddCandidatesFor(CandidateList *list, Candidate *cand)
|
||||
* Free the first candidate in the list that is not referenced anymore.
|
||||
* Return whether a candidate was removed.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
RemoveCandidate(CandidateList *srcs)
|
||||
{
|
||||
CandidateListNode *ln;
|
||||
@ -1097,7 +1098,7 @@ RemoveCandidate(CandidateList *srcs)
|
||||
Lst_Remove(srcs, ln);
|
||||
free(src->file);
|
||||
free(src);
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
#ifdef DEBUG_SRC
|
||||
else {
|
||||
@ -1108,7 +1109,7 @@ RemoveCandidate(CandidateList *srcs)
|
||||
#endif
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Find the first existing file/target in srcs. */
|
||||
@ -1282,7 +1283,7 @@ ExpandWildcards(GNodeListNode *cln, GNode *pgn)
|
||||
* add those nodes to the members list.
|
||||
*
|
||||
* Unfortunately, we can't use Str_Words because it doesn't understand about
|
||||
* variable specifications with spaces in them.
|
||||
* variable expressions with spaces in them.
|
||||
*/
|
||||
static void
|
||||
ExpandChildrenRegular(char *cp, GNode *pgn, GNodeList *members)
|
||||
@ -1309,7 +1310,7 @@ ExpandChildrenRegular(char *cp, GNode *pgn, GNodeList *members)
|
||||
const char *nested_p = cp;
|
||||
FStr junk;
|
||||
|
||||
(void)Var_Parse(&nested_p, pgn, VARE_NONE, &junk);
|
||||
(void)Var_Parse(&nested_p, pgn, VARE_PARSE_ONLY, &junk);
|
||||
/* TODO: handle errors */
|
||||
if (junk.str == var_Error) {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
@ -1380,7 +1381,7 @@ ExpandChildren(GNodeListNode *cln, GNode *pgn)
|
||||
}
|
||||
|
||||
DEBUG1(SUFF, "Expanding \"%s\"...", cgn->name);
|
||||
(void)Var_Subst(cgn->name, pgn, VARE_WANTRES | VARE_UNDEFERR, &cp);
|
||||
(void)Var_Subst(cgn->name, pgn, VARE_UNDEFERR, &cp);
|
||||
/* TODO: handle errors */
|
||||
|
||||
{
|
||||
@ -1494,9 +1495,9 @@ Suff_FindPath(GNode *gn)
|
||||
* the sources for the transformation rule.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if successful, FALSE if not.
|
||||
* true if successful, false if not.
|
||||
*/
|
||||
static Boolean
|
||||
static bool
|
||||
ApplyTransform(GNode *tgn, GNode *sgn, Suffix *tsuff, Suffix *ssuff)
|
||||
{
|
||||
GNodeListNode *ln;
|
||||
@ -1515,7 +1516,7 @@ ApplyTransform(GNode *tgn, GNode *sgn, Suffix *tsuff, Suffix *ssuff)
|
||||
|
||||
/* This can happen when linking an OP_MEMBER and OP_ARCHV node. */
|
||||
if (gn == NULL)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
DEBUG3(SUFF, "\tapplying %s -> %s to \"%s\"\n",
|
||||
ssuff->name, tsuff->name, tgn->name);
|
||||
@ -1540,7 +1541,7 @@ ApplyTransform(GNode *tgn, GNode *sgn, Suffix *tsuff, Suffix *ssuff)
|
||||
*/
|
||||
Lst_Append(&sgn->implicitParents, tgn);
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: targ.c,v 1.165 2021/02/04 21:42:46 rillig Exp $ */
|
||||
/* $NetBSD: targ.c,v 1.168 2021/04/03 12:01:00 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -93,7 +93,7 @@
|
||||
* Targ_FindList Given a list of names, find nodes for all
|
||||
* of them, creating them as necessary.
|
||||
*
|
||||
* Targ_Precious Return TRUE if the target is precious and
|
||||
* Targ_Precious Return true if the target is precious and
|
||||
* should not be removed if we are interrupted.
|
||||
*
|
||||
* Targ_Propagate Propagate information between related nodes.
|
||||
@ -113,7 +113,7 @@
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: targ.c,v 1.165 2021/02/04 21:42:46 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: targ.c,v 1.168 2021/04/03 12:01:00 rillig Exp $");
|
||||
|
||||
/*
|
||||
* All target nodes that appeared on the left-hand side of one of the
|
||||
@ -246,7 +246,7 @@ GNode_Free(void *gnp)
|
||||
* SCOPE_GLOBAL), it should be safe to free the variables as well,
|
||||
* since each node manages the memory for all its variables itself.
|
||||
*
|
||||
* XXX: The GNodes that are only used as variable scopes (VAR_CMD,
|
||||
* XXX: The GNodes that are only used as variable scopes (SCOPE_CMD,
|
||||
* SCOPE_GLOBAL, SCOPE_INTERNAL) are not freed at all (see Var_End,
|
||||
* where they are not mentioned). These might be freed at all, if
|
||||
* their variable values are indeed not used anywhere else (see
|
||||
@ -283,7 +283,7 @@ Targ_FindNode(const char *name)
|
||||
GNode *
|
||||
Targ_GetNode(const char *name)
|
||||
{
|
||||
Boolean isNew;
|
||||
bool isNew;
|
||||
HashEntry *he = HashTable_CreateEntry(&allTargetsByName, name, &isNew);
|
||||
if (!isNew)
|
||||
return HashEntry_Get(he);
|
||||
@ -347,7 +347,7 @@ Targ_FindList(GNodeList *gns, StringList *names)
|
||||
}
|
||||
|
||||
/* See if the given target is precious. */
|
||||
Boolean
|
||||
bool
|
||||
Targ_Precious(const GNode *gn)
|
||||
{
|
||||
/* XXX: Why are '::' targets precious? */
|
||||
@ -410,7 +410,7 @@ Targ_FmtTime(time_t tm)
|
||||
static char buf[128];
|
||||
|
||||
struct tm *parts = localtime(&tm);
|
||||
(void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
|
||||
(void)strftime(buf, sizeof buf, "%H:%M:%S %b %d, %Y", parts);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $Id: Makefile,v 1.143 2021/02/06 18:31:30 sjg Exp $
|
||||
# $Id: Makefile,v 1.148 2021/06/16 19:18:56 sjg Exp $
|
||||
#
|
||||
# $NetBSD: Makefile,v 1.269 2021/02/06 18:26:03 sjg Exp $
|
||||
# $NetBSD: Makefile,v 1.279 2021/06/16 09:39:48 rillig Exp $
|
||||
#
|
||||
# Unit tests for make(1)
|
||||
#
|
||||
@ -203,7 +203,9 @@ TESTS+= impsrc
|
||||
TESTS+= include-main
|
||||
TESTS+= job-flags
|
||||
#TESTS+= job-output-long-lines
|
||||
TESTS+= job-output-null
|
||||
TESTS+= jobs-empty-commands
|
||||
TESTS+= jobs-empty-commands-error
|
||||
TESTS+= jobs-error-indirect
|
||||
TESTS+= jobs-error-nested
|
||||
TESTS+= jobs-error-nested-make
|
||||
@ -228,6 +230,7 @@ TESTS+= opt-debug-curdir
|
||||
TESTS+= opt-debug-cond
|
||||
TESTS+= opt-debug-dir
|
||||
TESTS+= opt-debug-errors
|
||||
TESTS+= opt-debug-errors-jobs
|
||||
TESTS+= opt-debug-file
|
||||
TESTS+= opt-debug-for
|
||||
TESTS+= opt-debug-graph1
|
||||
@ -321,6 +324,7 @@ TESTS+= var-class-env
|
||||
TESTS+= var-class-global
|
||||
TESTS+= var-class-local
|
||||
TESTS+= var-class-local-legacy
|
||||
TESTS+= var-eval-short
|
||||
TESTS+= var-op
|
||||
TESTS+= var-op-append
|
||||
TESTS+= var-op-assign
|
||||
@ -347,6 +351,7 @@ TESTS+= varmod-indirect
|
||||
TESTS+= varmod-l-name-to-value
|
||||
TESTS+= varmod-localtime
|
||||
TESTS+= varmod-loop
|
||||
TESTS+= varmod-loop-varname
|
||||
TESTS+= varmod-match
|
||||
TESTS+= varmod-match-escape
|
||||
TESTS+= varmod-no-match
|
||||
@ -363,6 +368,7 @@ TESTS+= varmod-select-words
|
||||
TESTS+= varmod-shell
|
||||
TESTS+= varmod-subst
|
||||
TESTS+= varmod-subst-regex
|
||||
TESTS+= varmod-sun-shell
|
||||
TESTS+= varmod-sysv
|
||||
TESTS+= varmod-tail
|
||||
TESTS+= varmod-to-abs
|
||||
@ -484,6 +490,7 @@ SED_CMDS.job-output-long-lines= \
|
||||
${:D marker should always be at the beginning of the line. } \
|
||||
-e '/^aa*--- job-b ---$$/d' \
|
||||
-e '/^bb*--- job-a ---$$/d'
|
||||
SED_CMDS.opt-chdir= -e 's,\(nonexistent\).[1-9][0-9]*,\1,'
|
||||
SED_CMDS.opt-debug-graph1= ${STD_SED_CMDS.dg1}
|
||||
SED_CMDS.opt-debug-graph2= ${STD_SED_CMDS.dg2}
|
||||
SED_CMDS.opt-debug-graph3= ${STD_SED_CMDS.dg3}
|
||||
@ -494,11 +501,12 @@ SED_CMDS.opt-debug-jobs+= -e 's,JobFinish: [0-9][0-9]*,JobFinish: <pid>,'
|
||||
SED_CMDS.opt-debug-jobs+= -e 's,Command: ${.SHELL:T},Command: <shell>,'
|
||||
# The "-q" may be there or not, see jobs.c, variable shells.
|
||||
SED_CMDS.opt-debug-jobs+= -e 's,^\(.Command: <shell>\) -q,\1,'
|
||||
SED_CMDS.opt-debug-lint+= ${STD_SED_CMDS.regex}
|
||||
SED_CMDS.opt-jobs-no-action= ${STD_SED_CMDS.hide-from-output}
|
||||
SED_CMDS.opt-no-action-runflags= ${STD_SED_CMDS.hide-from-output}
|
||||
# For Compat_RunCommand, useShell == FALSE.
|
||||
# For Compat_RunCommand, useShell == false.
|
||||
SED_CMDS.sh-dots= -e 's,^.*\.\.\.:.*,<not found: ...>,'
|
||||
# For Compat_RunCommand, useShell == TRUE.
|
||||
# For Compat_RunCommand, useShell == true.
|
||||
SED_CMDS.sh-dots+= -e 's,^make: exec(\(.*\)) failed (.*)$$,<not found: \1>,'
|
||||
SED_CMDS.sh-dots+= -e 's,^\(\*\*\* Error code \)[1-9][0-9]*,\1<nonzero>,'
|
||||
SED_CMDS.sh-errctl= ${STD_SED_CMDS.dj}
|
||||
@ -509,8 +517,7 @@ SED_CMDS.suff-transform-debug+= ${STD_SED_CMDS.dg1}
|
||||
SED_CMDS.var-op-shell+= ${STD_SED_CMDS.shell}
|
||||
SED_CMDS.var-op-shell+= -e '/command/s,No such.*,not found,'
|
||||
SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,'
|
||||
SED_CMDS.varmod-subst-regex+= \
|
||||
-e 's,\(Regex compilation error:\).*,\1 (details omitted),'
|
||||
SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
|
||||
SED_CMDS.varname-dot-parsedir= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,'
|
||||
SED_CMDS.varname-dot-parsefile= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,'
|
||||
SED_CMDS.varname-dot-shell= -e 's, = /[^ ]*, = (details omitted),g'
|
||||
@ -590,6 +597,11 @@ STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: line [0-9][0-9]*: ,,'
|
||||
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: [0-9][0-9]*: ,,'
|
||||
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: ,,'
|
||||
|
||||
# The actual error messages for a failed regcomp or regexec differ between the
|
||||
# implementations.
|
||||
STD_SED_CMDS.regex= \
|
||||
-e 's,\(Regex compilation error:\).*,\1 (details omitted),'
|
||||
|
||||
# End of the configuration helpers section.
|
||||
|
||||
.-include "Makefile.inc"
|
||||
@ -639,8 +651,10 @@ _MKMSG_TEST= :
|
||||
.if ${.OBJDIR} != ${.CURDIR}
|
||||
# easy
|
||||
TMPDIR:= ${.OBJDIR}/tmp
|
||||
.elif defined(TMPDIR)
|
||||
TMPDIR:= ${TMPDIR}/uid${.MAKE.UID}
|
||||
.else
|
||||
TMPDIR:= ${TMPDIR:U/tmp}/uid${.MAKE.UID}
|
||||
TMPDIR:= /tmp/uid${.MAKE.UID}
|
||||
.endif
|
||||
# make sure it exists
|
||||
.if !exist(${TMPDIR})
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: archive.mk,v 1.11 2020/11/15 14:07:53 rillig Exp $
|
||||
# $NetBSD: archive.mk,v 1.12 2021/04/09 14:42:00 christos Exp $
|
||||
#
|
||||
# Very basic demonstration of handling archives, based on the description
|
||||
# in PSD.doc/tutorial.ms.
|
||||
@ -8,11 +8,11 @@
|
||||
# several other tests.
|
||||
|
||||
ARCHIVE= libprog.a
|
||||
FILES= archive.mk modmisc.mk varmisc.mk
|
||||
FILES= archive.mk archive-suffix.mk modmisc.mk ternary.mk varmisc.mk
|
||||
|
||||
all:
|
||||
.if ${.PARSEDIR:tA} != ${.CURDIR:tA}
|
||||
@cd ${MAKEFILE:H} && cp ${FILES} [at]*.mk ${.CURDIR}
|
||||
@cd ${MAKEFILE:H} && cp ${FILES} ${.CURDIR}
|
||||
.endif
|
||||
# The following targets create and remove files. The filesystem cache in
|
||||
# dir.c would probably not handle this correctly, therefore each of the
|
||||
|
@ -3,7 +3,7 @@ make: Unclosed variable "UNCLOSED"
|
||||
: unclosed-variable
|
||||
make: Unclosed variable expression (expecting '}') for "UNCLOSED"
|
||||
: unclosed-modifier
|
||||
make: Unknown modifier 'Z'
|
||||
make: Unknown modifier "Z"
|
||||
: unknown-modifier eol
|
||||
: end eol
|
||||
exit status 0
|
||||
|
@ -3,7 +3,7 @@ make: Unclosed variable "UNCLOSED"
|
||||
: unclosed-variable
|
||||
make: Unclosed variable expression (expecting '}') for "UNCLOSED"
|
||||
: unclosed-modifier
|
||||
make: Unknown modifier 'Z'
|
||||
make: Unknown modifier "Z"
|
||||
: unknown-modifier
|
||||
: end
|
||||
exit status 2
|
||||
|
@ -3,7 +3,7 @@ make: Unclosed variable "UNCLOSED"
|
||||
: unclosed-variable
|
||||
make: Unclosed variable expression (expecting '}') for "UNCLOSED"
|
||||
: unclosed-modifier
|
||||
make: Unknown modifier 'Z'
|
||||
make: Unknown modifier "Z"
|
||||
: unknown-modifier eol
|
||||
: end eol
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-func-empty.mk,v 1.11 2020/11/28 14:08:37 rillig Exp $
|
||||
# $NetBSD: cond-func-empty.mk,v 1.14 2021/04/11 13:35:56 rillig Exp $
|
||||
#
|
||||
# Tests for the empty() function in .if conditions, which tests a variable
|
||||
# expression for emptiness.
|
||||
@ -42,7 +42,7 @@ WORD= word
|
||||
.endif
|
||||
|
||||
# The :U modifier modifies expressions based on undefined variables
|
||||
# (VAR_JUNK) by adding the VAR_KEEP flag, which marks the expression
|
||||
# (DEF_UNDEF) by adding the DEF_DEFINED flag, which marks the expression
|
||||
# as "being interesting enough to be further processed".
|
||||
#
|
||||
.if empty(UNDEF:S,^$,value,W:Ufallback)
|
||||
@ -93,8 +93,8 @@ WORD= word
|
||||
# neither leading nor trailing spaces are trimmed in the argument of the
|
||||
# function. If the spaces were trimmed, the variable name would be "" and
|
||||
# that variable is indeed undefined. Since ParseEmptyArg calls Var_Parse
|
||||
# without VARE_UNDEFERR, the value of the undefined variable is returned as
|
||||
# an empty string.
|
||||
# without VARE_UNDEFERR, the value of the undefined variable is
|
||||
# returned as an empty string.
|
||||
${:U }= space
|
||||
.if empty( )
|
||||
. error
|
||||
@ -168,7 +168,7 @@ ${:U WORD }= variable name with spaces
|
||||
# parsing it, this unrealistic variable name should have done no harm.
|
||||
#
|
||||
# The variable expression was expanded though, and this was wrong. The
|
||||
# expansion was done without the VARE_WANTRES flag (called VARF_WANTRES back
|
||||
# expansion was done without VARE_WANTRES (called VARF_WANTRES back
|
||||
# then) though. This had the effect that the ${:U1} from the value of VARNAME
|
||||
# expanded to an empty string. This in turn created the seemingly recursive
|
||||
# definition VARNAME=${VARNAME}, and that definition was never meant to be
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-func-make-main.mk,v 1.1 2020/11/22 19:37:27 rillig Exp $
|
||||
# $NetBSD: cond-func-make-main.mk,v 1.2 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Test how accurately the make() function in .if conditions reflects
|
||||
# what is actually made.
|
||||
@ -33,7 +33,7 @@ first-main-target:
|
||||
# the line. This implies that several main targets can be set at the name
|
||||
# time, but they have to be in the same dependency group.
|
||||
#
|
||||
# See ParseDoDependencyTargetSpecial, branch SP_MAIN.
|
||||
# See ParseDependencyTargetSpecial, branch SP_MAIN.
|
||||
.MAIN: dot-main-target-1a dot-main-target-1b
|
||||
|
||||
.if !make(dot-main-target-1a)
|
||||
@ -47,7 +47,7 @@ dot-main-target-{1,2}{a,b}:
|
||||
: Making ${.TARGET}.
|
||||
|
||||
# At this point, the list of targets to be made (opts.create) is not empty
|
||||
# anymore. ParseDoDependencyTargetSpecial therefore treats the .MAIN as if
|
||||
# anymore. ParseDependencyTargetSpecial therefore treats the .MAIN as if
|
||||
# it were an ordinary target. Since .MAIN is not listed as a dependency
|
||||
# anywhere, it is not made.
|
||||
.if target(.MAIN)
|
||||
|
@ -1,4 +1,4 @@
|
||||
make: Bad conditional expression ` != "no"' in != "no"?:
|
||||
make: Bad conditional expression ' != "no"' in ' != "no"?:'
|
||||
yes
|
||||
no
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-short.mk,v 1.15 2020/12/01 19:37:23 rillig Exp $
|
||||
# $NetBSD: cond-short.mk,v 1.16 2021/03/14 11:49:37 rillig Exp $
|
||||
#
|
||||
# Demonstrates that in conditions, the right-hand side of an && or ||
|
||||
# is only evaluated if it can actually influence the result.
|
||||
@ -13,8 +13,11 @@
|
||||
# parse them. They were still evaluated though, the only difference to
|
||||
# relevant variable expressions was that in the irrelevant variable
|
||||
# expressions, undefined variables were allowed.
|
||||
#
|
||||
# See also:
|
||||
# var-eval-short.mk, for short-circuited variable modifiers
|
||||
|
||||
# The && operator.
|
||||
# The && operator:
|
||||
|
||||
.if 0 && ${echo "unexpected and" 1>&2 :L:sh}
|
||||
.endif
|
||||
@ -86,7 +89,7 @@ VAR= # empty again, for the following tests
|
||||
. warning first=${FIRST} last=${LAST} appended=${APPENDED} ran=${RAN}
|
||||
.endif
|
||||
|
||||
# The || operator.
|
||||
# The || operator:
|
||||
|
||||
.if 1 || ${echo "unexpected or" 1>&2 :L:sh}
|
||||
.endif
|
||||
@ -208,9 +211,4 @@ x!= echo '0 || $${iV2:U2} < $${V42}: $x' >&2; echo
|
||||
. error
|
||||
.endif
|
||||
|
||||
# TODO: Test each modifier to make sure it is skipped when it is irrelevant
|
||||
# for the result. Since this test is already quite long, do that in another
|
||||
# test.
|
||||
|
||||
all:
|
||||
@:;:
|
||||
|
@ -1,4 +1,4 @@
|
||||
make: "cond-token-string.mk" line 13: Unknown modifier 'Z'
|
||||
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} == "")
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-token-var.mk,v 1.5 2020/11/15 14:58:14 rillig Exp $
|
||||
# $NetBSD: cond-token-var.mk,v 1.6 2021/04/25 21:05:38 rillig Exp $
|
||||
#
|
||||
# Tests for variable expressions in .if conditions.
|
||||
#
|
||||
@ -46,3 +46,24 @@ DEF= defined
|
||||
# Since the expression is defined now, it doesn't generate any parse error.
|
||||
.if ${UNDEF:U}
|
||||
.endif
|
||||
|
||||
# If the value of the variable expression is a number, it is compared against
|
||||
# zero.
|
||||
.if ${:U0}
|
||||
. error
|
||||
.endif
|
||||
.if !${:U1}
|
||||
. error
|
||||
.endif
|
||||
|
||||
# If the value of the variable expression is not a number, any non-empty
|
||||
# value evaluates to true, even if there is only whitespace.
|
||||
.if ${:U}
|
||||
. error
|
||||
.endif
|
||||
.if !${:U }
|
||||
. error
|
||||
.endif
|
||||
.if !${:Uanything}
|
||||
. error
|
||||
.endif
|
||||
|
@ -17,7 +17,7 @@ Passed:
|
||||
5 is prime
|
||||
|
||||
make: String comparison operator must be either == or !=
|
||||
make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No
|
||||
make: Bad conditional expression '"0" > 0' in '"0" > 0?OK:No'
|
||||
|
||||
OK
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: counter-append.mk,v 1.4 2020/10/17 16:57:17 rillig Exp $
|
||||
# $NetBSD: counter-append.mk,v 1.5 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Demonstrates how to let make count the number of times a variable
|
||||
# is actually accessed, using the ::+= variable modifier.
|
||||
@ -15,7 +15,7 @@ COUNTER= # zero
|
||||
NEXT= ${COUNTER::+=a}${COUNTER:[#]}
|
||||
|
||||
# This variable is first set to empty and then expanded.
|
||||
# See parse.c, function Parse_DoVar, keyword "!Var_Exists".
|
||||
# See parse.c, function Parse_Var, keyword "!Var_Exists".
|
||||
A:= ${NEXT}
|
||||
B:= ${NEXT}
|
||||
C:= ${NEXT}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: counter.mk,v 1.5 2020/10/17 16:57:17 rillig Exp $
|
||||
# $NetBSD: counter.mk,v 1.6 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Demonstrates how to let make count the number of times a variable
|
||||
# is actually accessed, using the ::= variable modifier.
|
||||
@ -15,7 +15,7 @@ COUNTER= # zero
|
||||
NEXT= ${COUNTER::=${COUNTER} a}${COUNTER:[#]}
|
||||
|
||||
# This variable is first set to empty and then expanded.
|
||||
# See parse.c, function Parse_DoVar, keyword "!Var_Exists".
|
||||
# See parse.c, function Parse_Var, keyword "!Var_Exists".
|
||||
A:= ${NEXT}
|
||||
B:= ${NEXT}
|
||||
C:= ${NEXT}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: dep-var.mk,v 1.5 2020/09/13 20:04:26 rillig Exp $
|
||||
# $NetBSD: dep-var.mk,v 1.6 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Tests for variable references in dependency declarations.
|
||||
#
|
||||
@ -79,7 +79,7 @@ all: $$$$)
|
||||
# undefined.
|
||||
#
|
||||
# Since 2020-09-13, this generates a parse error in lint mode (-dL), but not
|
||||
# in normal mode since ParseDoDependency does not handle any errors after
|
||||
# in normal mode since ParseDependency does not handle any errors after
|
||||
# calling Var_Parse.
|
||||
undef1 def2 a-def2-b 1-2-$$INDIRECT_2-2-1 ${:U\$)}:
|
||||
@echo ${.TARGET:Q}
|
||||
|
@ -1,10 +1,10 @@
|
||||
Global:delete DOLLAR (not found)
|
||||
Command:DOLLAR = $$$$
|
||||
Global:.MAKEOVERRIDES = VAR DOLLAR
|
||||
Command: DOLLAR = $$$$
|
||||
Global: .MAKEOVERRIDES = VAR DOLLAR
|
||||
CondParser_Eval: ${DOLLAR} != "\$\$"
|
||||
Var_Parse: ${DOLLAR} != "\$\$" with VARE_UNDEFERR|VARE_WANTRES
|
||||
Var_Parse: ${DOLLAR} != "\$\$" (eval-defined)
|
||||
lhs = "$$", rhs = "$$", op = !=
|
||||
Global:.MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d
|
||||
Global:.MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d 0
|
||||
Global: .MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d
|
||||
Global: .MAKEFLAGS = -r -k -D VAR -D VAR -d cv -d 0
|
||||
make: Unterminated quoted string [make VAR=initial UNBALANCED=']
|
||||
exit status 0
|
||||
|
@ -1 +1,4 @@
|
||||
: 'Making two out of one.'
|
||||
: 'Making three out of two.'
|
||||
: 'Making all out of three.'
|
||||
exit status 0
|
||||
|
@ -1,8 +1,18 @@
|
||||
# $NetBSD: deptgt-order.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
|
||||
# $NetBSD: deptgt-order.mk,v 1.3 2021/06/17 15:25:33 rillig Exp $
|
||||
#
|
||||
# Tests for the special target .ORDER in dependency declarations.
|
||||
|
||||
# TODO: Implementation
|
||||
all one two three: .PHONY
|
||||
|
||||
all:
|
||||
@:;
|
||||
two: one
|
||||
: 'Making $@ out of $>.'
|
||||
three: two
|
||||
: 'Making $@ out of $>.'
|
||||
|
||||
# This .ORDER creates a circular dependency since 'three' depends on 'one'
|
||||
# but 'one' is supposed to be built after 'three'.
|
||||
.ORDER: three one
|
||||
|
||||
# XXX: The circular dependency should be detected here.
|
||||
all: three
|
||||
: 'Making $@ out of $>.'
|
||||
|
@ -1,14 +1,14 @@
|
||||
make: "deptgt.mk" line 10: warning: Extra target ignored
|
||||
make: "deptgt.mk" line 28: Unassociated shell command ": command3 # parse error, since targets == NULL"
|
||||
ParseReadLine (34): '${:U}: empty-source'
|
||||
ParseDoDependency(: empty-source)
|
||||
ParseDependency(: empty-source)
|
||||
ParseReadLine (35): ' : command for empty targets list'
|
||||
ParseReadLine (36): ': empty-source'
|
||||
ParseDoDependency(: empty-source)
|
||||
ParseDependency(: empty-source)
|
||||
ParseReadLine (37): ' : command for empty targets list'
|
||||
ParseReadLine (38): '.MAKEFLAGS: -d0'
|
||||
ParseDoDependency(.MAKEFLAGS: -d0)
|
||||
make: "deptgt.mk" line 46: Unknown modifier 'Z'
|
||||
ParseDependency(.MAKEFLAGS: -d0)
|
||||
make: "deptgt.mk" line 46: Unknown modifier "Z"
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: deptgt.mk,v 1.10 2020/12/27 18:20:26 rillig Exp $
|
||||
# $NetBSD: deptgt.mk,v 1.11 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Tests for special targets like .BEGIN or .SUFFIXES in dependency
|
||||
# declarations.
|
||||
@ -12,7 +12,7 @@
|
||||
# The following lines demonstrate how 'targets' is set and reset during
|
||||
# parsing of dependencies. To see it in action, set breakpoints in:
|
||||
#
|
||||
# ParseDoDependency at the beginning
|
||||
# ParseDependency at the beginning
|
||||
# FinishDependencyGroup at "targets = NULL"
|
||||
# Parse_File at "Lst_Free(targets)"
|
||||
# Parse_File at "targets = Lst_New()"
|
||||
|
@ -1,56 +1,56 @@
|
||||
ParseReadLine (21): 'UT_VAR= <${REF}>'
|
||||
Global:UT_VAR = <${REF}>
|
||||
Global: UT_VAR = <${REF}>
|
||||
ParseReadLine (28): '.export UT_VAR'
|
||||
Global:.MAKE.EXPORTED = UT_VAR
|
||||
Global: .MAKE.EXPORTED = UT_VAR
|
||||
ParseReadLine (32): ': ${UT_VAR:N*}'
|
||||
Var_Parse: ${UT_VAR:N*} with VARE_UNDEFERR|VARE_WANTRES
|
||||
Var_Parse: ${REF}> with VARE_UNDEFERR|VARE_WANTRES
|
||||
Applying ${UT_VAR:N...} to "<>" (VARE_UNDEFERR|VARE_WANTRES, VAR_EXPORTED|VAR_REEXPORT, none)
|
||||
Pattern[UT_VAR] for [<>] is [*]
|
||||
Var_Parse: ${UT_VAR:N*} (eval-defined)
|
||||
Var_Parse: ${REF}> (eval-defined)
|
||||
Evaluating modifier ${UT_VAR:N...} on value "<>"
|
||||
Pattern for ':N' is "*"
|
||||
ModifyWords: split "<>" into 1 words
|
||||
Result of ${UT_VAR:N*} is "" (VARE_UNDEFERR|VARE_WANTRES, VAR_EXPORTED|VAR_REEXPORT, none)
|
||||
ParseDoDependency(: )
|
||||
Result of ${UT_VAR:N*} is ""
|
||||
ParseDependency(: )
|
||||
CondParser_Eval: ${:!echo "\$UT_VAR"!} != "<>"
|
||||
Var_Parse: ${:!echo "\$UT_VAR"!} != "<>" with VARE_UNDEFERR|VARE_WANTRES
|
||||
Applying ${:!...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VES_UNDEF)
|
||||
Var_Parse: ${:!echo "\$UT_VAR"!} != "<>" (eval-defined)
|
||||
Evaluating modifier ${:!...} on value "" (eval-defined, undefined)
|
||||
Modifier part: "echo "$UT_VAR""
|
||||
Var_Parse: ${.MAKE.EXPORTED:O:u} with VARE_WANTRES
|
||||
Applying ${.MAKE.EXPORTED:O} to "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Result of ${.MAKE.EXPORTED:O} is "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Applying ${.MAKE.EXPORTED:u} to "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Result of ${.MAKE.EXPORTED:u} is "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Var_Parse: ${UT_VAR} with VARE_WANTRES
|
||||
Var_Parse: ${REF}> with VARE_WANTRES
|
||||
Result of ${:!echo "\$UT_VAR"!} is "<>" (VARE_UNDEFERR|VARE_WANTRES, none, VES_DEF)
|
||||
Var_Parse: ${.MAKE.EXPORTED:O:u} (eval)
|
||||
Evaluating modifier ${.MAKE.EXPORTED:O} on value "UT_VAR"
|
||||
Result of ${.MAKE.EXPORTED:O} is "UT_VAR"
|
||||
Evaluating modifier ${.MAKE.EXPORTED:u} on value "UT_VAR"
|
||||
Result of ${.MAKE.EXPORTED:u} is "UT_VAR"
|
||||
Var_Parse: ${UT_VAR} (eval)
|
||||
Var_Parse: ${REF}> (eval)
|
||||
Result of ${:!echo "\$UT_VAR"!} is "<>" (eval-defined, defined)
|
||||
lhs = "<>", rhs = "<>", op = !=
|
||||
ParseReadLine (49): ': ${UT_VAR:N*}'
|
||||
Var_Parse: ${UT_VAR:N*} with VARE_UNDEFERR|VARE_WANTRES
|
||||
Var_Parse: ${REF}> with VARE_UNDEFERR|VARE_WANTRES
|
||||
Applying ${UT_VAR:N...} to "<>" (VARE_UNDEFERR|VARE_WANTRES, VAR_EXPORTED|VAR_REEXPORT, none)
|
||||
Pattern[UT_VAR] for [<>] is [*]
|
||||
ParseReadLine (50): ': ${UT_VAR:N*}'
|
||||
Var_Parse: ${UT_VAR:N*} (eval-defined)
|
||||
Var_Parse: ${REF}> (eval-defined)
|
||||
Evaluating modifier ${UT_VAR:N...} on value "<>"
|
||||
Pattern for ':N' is "*"
|
||||
ModifyWords: split "<>" into 1 words
|
||||
Result of ${UT_VAR:N*} is "" (VARE_UNDEFERR|VARE_WANTRES, VAR_EXPORTED|VAR_REEXPORT, none)
|
||||
ParseDoDependency(: )
|
||||
ParseReadLine (53): 'REF= defined'
|
||||
Global:REF = defined
|
||||
Result of ${UT_VAR:N*} is ""
|
||||
ParseDependency(: )
|
||||
ParseReadLine (54): 'REF= defined'
|
||||
Global: REF = defined
|
||||
CondParser_Eval: ${:!echo "\$UT_VAR"!} != "<defined>"
|
||||
Var_Parse: ${:!echo "\$UT_VAR"!} != "<defined>" with VARE_UNDEFERR|VARE_WANTRES
|
||||
Applying ${:!...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VES_UNDEF)
|
||||
Var_Parse: ${:!echo "\$UT_VAR"!} != "<defined>" (eval-defined)
|
||||
Evaluating modifier ${:!...} on value "" (eval-defined, undefined)
|
||||
Modifier part: "echo "$UT_VAR""
|
||||
Var_Parse: ${.MAKE.EXPORTED:O:u} with VARE_WANTRES
|
||||
Applying ${.MAKE.EXPORTED:O} to "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Result of ${.MAKE.EXPORTED:O} is "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Applying ${.MAKE.EXPORTED:u} to "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Result of ${.MAKE.EXPORTED:u} is "UT_VAR" (VARE_WANTRES, none, none)
|
||||
Var_Parse: ${UT_VAR} with VARE_WANTRES
|
||||
Var_Parse: ${REF}> with VARE_WANTRES
|
||||
Result of ${:!echo "\$UT_VAR"!} is "<defined>" (VARE_UNDEFERR|VARE_WANTRES, none, VES_DEF)
|
||||
Var_Parse: ${.MAKE.EXPORTED:O:u} (eval)
|
||||
Evaluating modifier ${.MAKE.EXPORTED:O} on value "UT_VAR"
|
||||
Result of ${.MAKE.EXPORTED:O} is "UT_VAR"
|
||||
Evaluating modifier ${.MAKE.EXPORTED:u} on value "UT_VAR"
|
||||
Result of ${.MAKE.EXPORTED:u} is "UT_VAR"
|
||||
Var_Parse: ${UT_VAR} (eval)
|
||||
Var_Parse: ${REF}> (eval)
|
||||
Result of ${:!echo "\$UT_VAR"!} is "<defined>" (eval-defined, defined)
|
||||
lhs = "<defined>", rhs = "<defined>", op = !=
|
||||
ParseReadLine (61): 'all:'
|
||||
ParseDoDependency(all:)
|
||||
Global:.ALLTARGETS = all
|
||||
ParseReadLine (62): '.MAKEFLAGS: -d0'
|
||||
ParseDoDependency(.MAKEFLAGS: -d0)
|
||||
Global:.MAKEFLAGS = -r -k -d cpv -d
|
||||
Global:.MAKEFLAGS = -r -k -d cpv -d 0
|
||||
ParseReadLine (62): 'all:'
|
||||
ParseDependency(all:)
|
||||
Global: .ALLTARGETS = all
|
||||
ParseReadLine (63): '.MAKEFLAGS: -d0'
|
||||
ParseDependency(.MAKEFLAGS: -d0)
|
||||
Global: .MAKEFLAGS = -r -k -d cpv -d
|
||||
Global: .MAKEFLAGS = -r -k -d cpv -d 0
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: directive-export-impl.mk,v 1.1 2020/12/29 01:45:06 rillig Exp $
|
||||
# $NetBSD: directive-export-impl.mk,v 1.3 2021/04/03 23:08:30 rillig Exp $
|
||||
#
|
||||
# Test for the implementation of exporting variables to child processes.
|
||||
# This involves marking variables for export, actually exporting them,
|
||||
@ -8,8 +8,8 @@
|
||||
# Var_Export
|
||||
# ExportVar
|
||||
# VarExportedMode (global)
|
||||
# VAR_EXPORTED (per variable)
|
||||
# VAR_REEXPORT (per variable)
|
||||
# VarFlags.exported (per variable)
|
||||
# VarFlags.reexport (per variable)
|
||||
# VarExportMode (per call of Var_Export and ExportVar)
|
||||
|
||||
: ${:U:sh} # side effect: initialize .SHELL
|
||||
@ -22,13 +22,13 @@ UT_VAR= <${REF}>
|
||||
|
||||
# At this point, ExportVar("UT_VAR", VEM_PLAIN) is called. Since the
|
||||
# variable value refers to another variable, ExportVar does not actually
|
||||
# export the variable but only marks it as VAR_EXPORTED and VAR_REEXPORT.
|
||||
# After that, ExportVars registers the variable name in .MAKE.EXPORTED.
|
||||
# That's all for now.
|
||||
# export the variable but only marks it as VarFlags.exported and
|
||||
# VarFlags.reexport. After that, ExportVars registers the variable name in
|
||||
# .MAKE.EXPORTED. That's all for now.
|
||||
.export UT_VAR
|
||||
|
||||
# Evaluating this expression shows the variable flags in the debug log,
|
||||
# which are VAR_EXPORTED|VAR_REEXPORT.
|
||||
# The following expression has both flags 'exported' and 'reexport' set.
|
||||
# These flags do not show up anywhere, not even in the debug log.
|
||||
: ${UT_VAR:N*}
|
||||
|
||||
# At the last moment before actually forking off the child process for the
|
||||
@ -43,9 +43,10 @@ UT_VAR= <${REF}>
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Evaluating this expression shows the variable flags in the debug log,
|
||||
# which are still VAR_EXPORTED|VAR_REEXPORT, which means that the variable
|
||||
# is still marked as being re-exported for each child process.
|
||||
# The following expression still has 'exported' and 'reexport' set.
|
||||
# These flags do not show up anywhere though, not even in the debug log.
|
||||
# These flags means that the variable is still marked as being re-exported
|
||||
# for each child process.
|
||||
: ${UT_VAR:N*}
|
||||
|
||||
# Now the referenced variable gets defined. This does not influence anything
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: directive-export.mk,v 1.6 2020/12/13 01:07:54 rillig Exp $
|
||||
# $NetBSD: directive-export.mk,v 1.8 2021/02/16 19:01:18 rillig Exp $
|
||||
#
|
||||
# Tests for the .export directive.
|
||||
#
|
||||
@ -28,8 +28,17 @@ VAR= value $$ ${INDIRECT}
|
||||
. error
|
||||
.endif
|
||||
|
||||
# No argument means to export all variables.
|
||||
# No syntactical argument means to export all variables.
|
||||
.export
|
||||
|
||||
# An empty argument means no additional variables to export.
|
||||
.export ${:U}
|
||||
|
||||
|
||||
# Trigger the "This isn't going to end well" in ExportVarEnv.
|
||||
EMPTY_SHELL= ${:sh}
|
||||
.export EMPTY_SHELL # only marked for export at this point
|
||||
_!= :;: # Force the variable to be actually exported.
|
||||
|
||||
|
||||
all:
|
||||
@:;
|
||||
|
@ -13,7 +13,7 @@ make: "directive-for-errors.mk" line 53: Wrong number of words (5) in .for subst
|
||||
make: "directive-for-errors.mk" line 64: missing `in' in for
|
||||
make: "directive-for-errors.mk" line 66: warning: Should not be reached.
|
||||
make: "directive-for-errors.mk" line 67: for-less endfor
|
||||
make: "directive-for-errors.mk" line 73: Unknown modifier 'Z'
|
||||
make: "directive-for-errors.mk" line 73: Unknown modifier "Z"
|
||||
make: "directive-for-errors.mk" line 74: warning: Should not be reached.
|
||||
make: "directive-for-errors.mk" line 74: warning: Should not be reached.
|
||||
make: "directive-for-errors.mk" line 74: warning: Should not be reached.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: directive-for-errors.mk,v 1.1 2020/12/31 03:05:12 rillig Exp $
|
||||
# $NetBSD: directive-for-errors.mk,v 1.3 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Tests for error handling in .for loops.
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
# XXX: The error message is misleading though. As of 2020-12-31, it says
|
||||
# "Unknown directive "for"", but that directive is actually known. This is
|
||||
# because ForEval does not detect the .for loop as such, so parsing
|
||||
# continues in ParseLine > ParseDependency > ParseDoDependency >
|
||||
# ParseDoDependencyTargets > ParseErrorNoDependency, and there the directive
|
||||
# continues in ParseLine > ParseDependencyLine > ParseDependency >
|
||||
# ParseDependencyTargets > ParseErrorNoDependency, and there the directive
|
||||
# name is parsed a bit differently.
|
||||
.for/i in 1 2 3
|
||||
. warning ${i}
|
||||
|
@ -1,12 +1,12 @@
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info ${:U!"#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
|
||||
make: Unclosed variable specification (expecting '}') for "" (value "!"") modifier U
|
||||
make: Unclosed variable expression, expecting '}' for modifier "U!"" of variable "" with value "!""
|
||||
make: "directive-for-escape.mk" line 19: !"
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info ${:U!"\\\\#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
|
||||
make: Unclosed variable specification (expecting '}') for "" (value "!"\\") modifier U
|
||||
make: Unclosed variable expression, expecting '}' for modifier "U!"\\\\" of variable "" with value "!"\\"
|
||||
make: "directive-for-escape.mk" line 29: !"\\
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
@ -37,19 +37,19 @@ make: "directive-for-escape.mk" line 55: end}
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info ${:Ubegin<${UNDEF:Ufallback:N{{{}}}}>end}
|
||||
make: "directive-for-escape.mk" line 66: begin<fallback>end
|
||||
make: "directive-for-escape.mk" line 67: begin<fallback>end
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info ${:U\$}
|
||||
make: "directive-for-escape.mk" line 74: $
|
||||
make: "directive-for-escape.mk" line 75: $
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info ${NUMBERS} ${:Ureplaced}
|
||||
make: "directive-for-escape.mk" line 82: one two three replaced
|
||||
make: "directive-for-escape.mk" line 83: one two three replaced
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info ${:Ureplaced}
|
||||
make: "directive-for-escape.mk" line 92: replaced
|
||||
make: "directive-for-escape.mk" line 93: replaced
|
||||
For: end for 1
|
||||
For: loop body:
|
||||
. info . $$i: ${:Uinner}
|
||||
@ -62,14 +62,14 @@ For: loop body:
|
||||
. info . $${i2}: ${i2}
|
||||
. info . $${i,}: ${i,}
|
||||
. info . adjacent: ${:Uinner}${:Uinner}${:Uinner:M*}${:Uinner}
|
||||
make: "directive-for-escape.mk" line 100: . $i: inner
|
||||
make: "directive-for-escape.mk" line 101: . ${i}: inner
|
||||
make: "directive-for-escape.mk" line 102: . ${i:M*}: inner
|
||||
make: "directive-for-escape.mk" line 103: . $(i): inner
|
||||
make: "directive-for-escape.mk" line 104: . $(i:M*): inner
|
||||
make: "directive-for-escape.mk" line 105: . ${i${:U}}: outer
|
||||
make: "directive-for-escape.mk" line 106: . ${i\}}: inner}
|
||||
make: "directive-for-escape.mk" line 107: . ${i2}: two
|
||||
make: "directive-for-escape.mk" line 108: . ${i,}: comma
|
||||
make: "directive-for-escape.mk" line 109: . adjacent: innerinnerinnerinner
|
||||
make: "directive-for-escape.mk" line 101: . $i: inner
|
||||
make: "directive-for-escape.mk" line 102: . ${i}: inner
|
||||
make: "directive-for-escape.mk" line 103: . ${i:M*}: inner
|
||||
make: "directive-for-escape.mk" line 104: . $(i): inner
|
||||
make: "directive-for-escape.mk" line 105: . $(i:M*): inner
|
||||
make: "directive-for-escape.mk" line 106: . ${i${:U}}: outer
|
||||
make: "directive-for-escape.mk" line 107: . ${i\}}: inner}
|
||||
make: "directive-for-escape.mk" line 108: . ${i2}: two
|
||||
make: "directive-for-escape.mk" line 109: . ${i,}: comma
|
||||
make: "directive-for-escape.mk" line 110: . adjacent: innerinnerinnerinner
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: directive-for-escape.mk,v 1.6 2021/01/25 19:05:39 rillig Exp $
|
||||
# $NetBSD: directive-for-escape.mk,v 1.7 2021/02/15 07:58:19 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
|
||||
@ -7,8 +7,8 @@
|
||||
|
||||
.MAKEFLAGS: -df
|
||||
|
||||
# Even though the .for loops takes quotes into account when splitting the
|
||||
# string into words, the quotes don't need to be balances, as of 2020-12-31.
|
||||
# Even though the .for loops take quotes into account when splitting the
|
||||
# string into words, the quotes don't need to be balanced, as of 2020-12-31.
|
||||
# This could be considered a bug.
|
||||
ASCII= !"\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
|
||||
|
||||
@ -33,7 +33,7 @@ ASCII.2020-12-31= !"\\\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
|
||||
#
|
||||
# XXX: It is unexpected that the variable V gets expanded in the loop body.
|
||||
# The double '$$' should prevent exactly this. Probably nobody was
|
||||
# adventurous enough to use literal dollar signs in the values for a .for
|
||||
# adventurous enough to use literal dollar signs in the values of a .for
|
||||
# loop.
|
||||
V= value
|
||||
VALUES= $$ $${V} $${V:=-with-modifier} $$(V) $$(V:=-with-modifier)
|
||||
@ -43,14 +43,14 @@ VALUES= $$ $${V} $${V:=-with-modifier} $$(V) $$(V:=-with-modifier)
|
||||
|
||||
# Try to cover the code for nested '{}' in for_var_len, without success.
|
||||
#
|
||||
# The value of VALUES is not meant to be a variable expression. Instead, it
|
||||
# is meant to represent dollar, lbrace, "UNDEF:U", backslash, dollar,
|
||||
# backslash, dollar, space, nested braces, space, "end}".
|
||||
# The value of the variable VALUES is not meant to be a variable expression.
|
||||
# Instead, it is meant to represent literal text, the only escaping mechanism
|
||||
# being that each '$' is written as '$$'.
|
||||
#
|
||||
# The .for loop splits ${VALUES} into 3 words, at the space characters, since
|
||||
# these are not escaped.
|
||||
VALUES= $${UNDEF:U\$$\$$ {{}} end}
|
||||
# XXX: Where does the '\$$\$$' get converted into a single '\$'?
|
||||
# XXX: Where in the code does the '\$\$' get converted into a single '\$'?
|
||||
.for i in ${VALUES}
|
||||
. info $i
|
||||
.endfor
|
||||
@ -59,8 +59,9 @@ VALUES= $${UNDEF:U\$$\$$ {{}} end}
|
||||
#
|
||||
# XXX: It is wrong that for_var_len requires the braces to be balanced.
|
||||
# Each variable modifier has its own inconsistent way of parsing nested
|
||||
# variable expressions, braces and parentheses. The only sensible thing
|
||||
# to do is therefore to let Var_Parse do all the parsing work.
|
||||
# variable expressions, braces and parentheses. (Compare ':M', ':S', and
|
||||
# ':D' for details.) The only sensible thing to do is therefore to let
|
||||
# Var_Parse do all the parsing work.
|
||||
VALUES= begin<$${UNDEF:Ufallback:N{{{}}}}>end
|
||||
.for i in ${VALUES}
|
||||
. info $i
|
||||
|
@ -16,7 +16,7 @@ make: "directive-for.mk" line 140: ][ ][ ][
|
||||
make: "directive-for.mk" line 140: }{ }{ }{
|
||||
make: "directive-for.mk" line 148: outer value value
|
||||
make: "directive-for.mk" line 148: outer "quoted" \"quoted\"
|
||||
make: "directive-for.mk" line 154: Unknown modifier 'Z'
|
||||
make: "directive-for.mk" line 154: Unknown modifier "Z"
|
||||
make: "directive-for.mk" line 155: XXX: Not reached word1
|
||||
make: "directive-for.mk" line 155: XXX: Not reached word3
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
|
@ -1,5 +1,6 @@
|
||||
make: "directive-undef.mk" line 29: The .undef directive requires an argument
|
||||
make: "directive-undef.mk" line 86: Unknown modifier 'Z'
|
||||
make: "directive-undef.mk" line 86: Unknown modifier "Z"
|
||||
make: "directive-undef.mk" line 103: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore.
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: directive-undef.mk,v 1.9 2020/12/22 20:10:21 rillig Exp $
|
||||
# $NetBSD: directive-undef.mk,v 1.10 2021/02/16 18:02:19 rillig Exp $
|
||||
#
|
||||
# Tests for the .undef directive.
|
||||
#
|
||||
@ -86,5 +86,22 @@ ${DOLLAR}= dollar
|
||||
.undef ${VARNAMES:L:Z}
|
||||
|
||||
|
||||
UT_EXPORTED= exported-value
|
||||
.export UT_EXPORTED
|
||||
.if ${:!echo "\${UT_EXPORTED:-not-exported}"!} != "exported-value"
|
||||
. error
|
||||
.endif
|
||||
.if !${.MAKE.EXPORTED:MUT_EXPORTED}
|
||||
. error
|
||||
.endif
|
||||
.undef UT_EXPORTED # XXX: does not update .MAKE.EXPORTED
|
||||
.if ${:!echo "\${UT_EXPORTED:-not-exported}"!} != "not-exported"
|
||||
. error
|
||||
.endif
|
||||
.if ${.MAKE.EXPORTED:MUT_EXPORTED}
|
||||
. warning UT_EXPORTED is still listed in .MAKE.EXPORTED even though $\
|
||||
it is not exported anymore.
|
||||
.endif
|
||||
|
||||
|
||||
all:
|
||||
@:;
|
||||
|
@ -1,18 +1,18 @@
|
||||
make: "directive-unexport-env.mk" line 13: Unknown directive "unexport-en"
|
||||
make: "directive-unexport-env.mk" line 15: Unknown directive "unexport-environment"
|
||||
Global:UT_EXPORTED = value
|
||||
Global:UT_UNEXPORTED = value
|
||||
Global:.MAKE.EXPORTED = UT_EXPORTED
|
||||
Global: UT_EXPORTED = value
|
||||
Global: UT_UNEXPORTED = value
|
||||
Global: .MAKE.EXPORTED = UT_EXPORTED
|
||||
make: "directive-unexport-env.mk" line 21: The directive .unexport-env does not take arguments
|
||||
Var_Parse: ${.MAKE.EXPORTED:O:u} with VARE_WANTRES
|
||||
Applying ${.MAKE.EXPORTED:O} to "UT_EXPORTED" (VARE_WANTRES, none, none)
|
||||
Result of ${.MAKE.EXPORTED:O} is "UT_EXPORTED" (VARE_WANTRES, none, none)
|
||||
Applying ${.MAKE.EXPORTED:u} to "UT_EXPORTED" (VARE_WANTRES, none, none)
|
||||
Result of ${.MAKE.EXPORTED:u} is "UT_EXPORTED" (VARE_WANTRES, none, none)
|
||||
Var_Parse: ${.MAKE.EXPORTED:O:u} (eval)
|
||||
Evaluating modifier ${.MAKE.EXPORTED:O} on value "UT_EXPORTED"
|
||||
Result of ${.MAKE.EXPORTED:O} is "UT_EXPORTED"
|
||||
Evaluating modifier ${.MAKE.EXPORTED:u} on value "UT_EXPORTED"
|
||||
Result of ${.MAKE.EXPORTED:u} is "UT_EXPORTED"
|
||||
Unexporting "UT_EXPORTED"
|
||||
Global:delete .MAKE.EXPORTED
|
||||
Global:.MAKEFLAGS = -r -k -d v -d
|
||||
Global:.MAKEFLAGS = -r -k -d v -d 0
|
||||
Global: .MAKEFLAGS = -r -k -d v -d
|
||||
Global: .MAKEFLAGS = -r -k -d v -d 0
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -2,11 +2,11 @@ make: "directive.mk" line 9: Unknown directive "indented"
|
||||
make: "directive.mk" line 10: Unknown directive "indented"
|
||||
make: "directive.mk" line 11: Unknown directive "indented"
|
||||
make: "directive.mk" line 15: Unknown directive "info"
|
||||
Global:.info =
|
||||
Global:.info = value
|
||||
Global: .info =
|
||||
Global: .info = value
|
||||
make: "directive.mk" line 26: := value
|
||||
Global:.MAKEFLAGS = -r -k -d v -d
|
||||
Global:.MAKEFLAGS = -r -k -d v -d 0
|
||||
Global: .MAKEFLAGS = -r -k -d v -d
|
||||
Global: .MAKEFLAGS = -r -k -d v -d 0
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -9,7 +9,7 @@ make: "include-subsub.mk" line 5: subsub-ok
|
||||
in .for loop from include-sub.mk:29
|
||||
in .include from include-main.mk:27
|
||||
ParseReadLine (6): '.MAKEFLAGS: -d0'
|
||||
ParseDoDependency(.MAKEFLAGS: -d0)
|
||||
ParseDependency(.MAKEFLAGS: -d0)
|
||||
make: "include-sub.mk" line 38: sub-after-ok
|
||||
make: "include-sub.mk" line 45: sub-after-for-ok
|
||||
make: "include-main.mk" line 30: main-after-ok
|
||||
|
4
contrib/bmake/unit-tests/job-output-null.exp
Normal file
4
contrib/bmake/unit-tests/job-output-null.exp
Normal file
@ -0,0 +1,4 @@
|
||||
hello
|
||||
hello
|
||||
hello world without newline, hello world without newline, hello world without newline.
|
||||
exit status 0
|
32
contrib/bmake/unit-tests/job-output-null.mk
Normal file
32
contrib/bmake/unit-tests/job-output-null.mk
Normal file
@ -0,0 +1,32 @@
|
||||
# $NetBSD: job-output-null.mk,v 1.1 2021/04/15 19:02:29 rillig Exp $
|
||||
#
|
||||
# Test how null bytes in the output of a command are handled. Make processes
|
||||
# them using null-terminated strings, which may cut off some of the output.
|
||||
#
|
||||
# As of 2021-04-15, make handles null bytes from the child process
|
||||
# inconsistently. It's an edge case though since typically the child
|
||||
# processes output text.
|
||||
|
||||
.MAKEFLAGS: -j1 # force jobs mode
|
||||
|
||||
all: .PHONY
|
||||
# The null byte from the command output is kept as-is.
|
||||
# See CollectOutput, which looks like it intended to replace these
|
||||
# null bytes with simple spaces.
|
||||
@printf 'hello\0world%s\n' ''
|
||||
|
||||
# Give the parent process a chance to see the above output, but not
|
||||
# yet the output from the next printf command.
|
||||
@sleep 1
|
||||
|
||||
# All null bytes from the command output are kept as-is.
|
||||
@printf 'hello\0world%s\n' '' '' '' '' '' ''
|
||||
|
||||
@sleep 1
|
||||
|
||||
# The null bytes are replaced with spaces since they are not followed
|
||||
# by a newline.
|
||||
#
|
||||
# The three null bytes in a row test whether this output is
|
||||
# compressed to a single space like in DebugFailedTarget. It isn't.
|
||||
@printf 'hello\0world\0without\0\0\0newline%s' ', ' ', ' '.'
|
5
contrib/bmake/unit-tests/jobs-empty-commands-error.exp
Normal file
5
contrib/bmake/unit-tests/jobs-empty-commands-error.exp
Normal file
@ -0,0 +1,5 @@
|
||||
: 'Making existing-target out of nothing.'
|
||||
make: don't know how to make nonexistent-target (continuing)
|
||||
|
||||
make: stopped in unit-tests
|
||||
exit status 2
|
19
contrib/bmake/unit-tests/jobs-empty-commands-error.mk
Normal file
19
contrib/bmake/unit-tests/jobs-empty-commands-error.mk
Normal file
@ -0,0 +1,19 @@
|
||||
# $NetBSD: jobs-empty-commands-error.mk,v 1.1 2021/06/16 09:39:48 rillig Exp $
|
||||
#
|
||||
# In jobs mode, the shell commands for creating a target are written to a
|
||||
# temporary file first, which is then run by the shell. In chains of
|
||||
# dependencies, these files would end up empty. Since job.c 1.399 from
|
||||
# 2021-01-29, these empty files are no longer created.
|
||||
#
|
||||
# After 2021-01-29, before job.c 1.435 2021-06-16, targets that could not be
|
||||
# made led to longer error messages than necessary.
|
||||
|
||||
.MAKEFLAGS: -j1
|
||||
|
||||
all: existing-target
|
||||
|
||||
existing-target:
|
||||
: 'Making $@ out of nothing.'
|
||||
|
||||
all: nonexistent-target
|
||||
: 'Not reached'
|
@ -1,143 +1,136 @@
|
||||
mod-unknown-direct:
|
||||
want: Unknown modifier 'Z'
|
||||
make: Unknown modifier 'Z'
|
||||
make: Unknown modifier "Z"
|
||||
VAR:Z=before--after
|
||||
|
||||
mod-unknown-indirect:
|
||||
want: Unknown modifier 'Z'
|
||||
make: Unknown modifier 'Z'
|
||||
make: Unknown modifier "Z"
|
||||
VAR:Z=before-inner}-after
|
||||
|
||||
unclosed-direct:
|
||||
want: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S
|
||||
make: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S
|
||||
want: Unclosed variable expression, expecting '}' for modifier "S,V,v," of variable "VAR" with value "Thevariable"
|
||||
make: Unclosed variable expression, expecting '}' for modifier "S,V,v," of variable "VAR" with value "Thevariable"
|
||||
VAR:S,V,v,=Thevariable
|
||||
|
||||
unclosed-indirect:
|
||||
want: Unclosed variable specification after complex modifier (expecting '}') for VAR
|
||||
make: Unclosed variable specification after complex modifier (expecting '}') for VAR
|
||||
want: Unclosed variable expression after indirect modifier, expecting '}' for variable "VAR"
|
||||
make: Unclosed variable expression after indirect modifier, expecting '}' for variable "VAR"
|
||||
VAR:S,V,v,=Thevariable
|
||||
|
||||
unfinished-indirect:
|
||||
want: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
VAR:S,V,v=
|
||||
|
||||
unfinished-loop:
|
||||
want: Unfinished modifier for UNDEF ('@' missing)
|
||||
make: Unfinished modifier for UNDEF ('@' missing)
|
||||
make: Unfinished modifier for "UNDEF" ('@' missing)
|
||||
|
||||
want: Unfinished modifier for UNDEF ('@' missing)
|
||||
make: Unfinished modifier for UNDEF ('@' missing)
|
||||
make: Unfinished modifier for "UNDEF" ('@' missing)
|
||||
|
||||
1 2 3
|
||||
|
||||
loop-close:
|
||||
make: Unclosed variable specification (expecting '}') for "UNDEF" (value "1}... 2}... 3}...") modifier @
|
||||
make: Unclosed variable expression, expecting '}' for modifier "@var@${var}}...@" of variable "UNDEF" with value "1}... 2}... 3}..."
|
||||
1}... 2}... 3}...
|
||||
1}... 2}... 3}...
|
||||
|
||||
words:
|
||||
want: Unfinished modifier for UNDEF (']' missing)
|
||||
make: Unfinished modifier for UNDEF (']' missing)
|
||||
make: Unfinished modifier for "UNDEF" (']' missing)
|
||||
|
||||
want: Unfinished modifier for UNDEF (']' missing)
|
||||
make: Unfinished modifier for UNDEF (']' missing)
|
||||
make: Unfinished modifier for "UNDEF" (']' missing)
|
||||
|
||||
13=
|
||||
make: Bad modifier `:[123451234512345123451234512345]' for UNDEF
|
||||
make: Bad modifier ":[123451234512345123451234512345]" for variable "UNDEF"
|
||||
12345=S,^ok,:S,^3ok,}
|
||||
|
||||
exclam:
|
||||
want: Unfinished modifier for VARNAME ('!' missing)
|
||||
make: Unfinished modifier for VARNAME ('!' missing)
|
||||
make: Unfinished modifier for "VARNAME" ('!' missing)
|
||||
|
||||
want: Unfinished modifier for ! ('!' missing)
|
||||
make: Unfinished modifier for ! ('!' missing)
|
||||
make: Unfinished modifier for "!" ('!' missing)
|
||||
|
||||
|
||||
mod-subst-delimiter:
|
||||
make: Missing delimiter for :S modifier
|
||||
make: Missing delimiter for modifier ':S'
|
||||
1:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
2:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
3:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
4:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
5:
|
||||
make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier S
|
||||
make: Unclosed variable expression, expecting '}' for modifier "S,from,to," of variable "VAR" with value "TheVariable"
|
||||
6: TheVariable
|
||||
7: TheVariable
|
||||
|
||||
mod-regex-delimiter:
|
||||
make: Missing delimiter for :C modifier
|
||||
1:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
2:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
3:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
4:
|
||||
make: Unfinished modifier for VAR (',' missing)
|
||||
make: Unfinished modifier for "VAR" (',' missing)
|
||||
5:
|
||||
make: Unclosed variable specification (expecting '}') for "VAR" (value "TheVariable") modifier C
|
||||
make: Unclosed variable expression, expecting '}' for modifier "C,from,to," of variable "VAR" with value "TheVariable"
|
||||
6: TheVariable
|
||||
7: TheVariable
|
||||
|
||||
mod-regex-undefined-subexpression:
|
||||
one one 2 3 5 8 one3 2one 34
|
||||
make: No match for subexpression \2
|
||||
make: No match for subexpression \2
|
||||
make: No match for subexpression \1
|
||||
make: No match for subexpression \2
|
||||
make: No match for subexpression \1
|
||||
()+() ()+() ()+() 3 5 8 (3)+() ()+(1) 34
|
||||
|
||||
mod-ts-parse:
|
||||
112358132134
|
||||
15152535558513521534
|
||||
make: Bad modifier `:ts\65oct' for FIB
|
||||
make: Bad modifier ":ts\65oct" for variable "FIB"
|
||||
65oct}
|
||||
make: Bad modifier `:tsxy' for FIB
|
||||
make: Bad modifier ":ts\65oct" for variable ""
|
||||
65oct}
|
||||
make: Bad modifier ":tsxy" for variable "FIB"
|
||||
xy}
|
||||
|
||||
mod-t-parse:
|
||||
make: Bad modifier `:t' for FIB
|
||||
make: Bad modifier ":t" for variable "FIB"
|
||||
|
||||
make: Bad modifier `:txy' for FIB
|
||||
make: Bad modifier ":txy" for variable "FIB"
|
||||
y}
|
||||
make: Bad modifier `:t' for FIB
|
||||
make: Bad modifier ":t" for variable "FIB"
|
||||
|
||||
make: Bad modifier `:t' for FIB
|
||||
make: Bad modifier ":t" for variable "FIB"
|
||||
M*}
|
||||
|
||||
mod-ifelse-parse:
|
||||
make: Unfinished modifier for FIB (':' missing)
|
||||
make: Unfinished modifier for "FIB" (':' missing)
|
||||
|
||||
make: Unfinished modifier for FIB (':' missing)
|
||||
make: Unfinished modifier for "FIB" (':' missing)
|
||||
|
||||
make: Unfinished modifier for FIB ('}' missing)
|
||||
make: Unfinished modifier for "FIB" ('}' missing)
|
||||
|
||||
make: Unfinished modifier for FIB ('}' missing)
|
||||
make: Unfinished modifier for "FIB" ('}' missing)
|
||||
|
||||
then
|
||||
|
||||
mod-remember-parse:
|
||||
1 1 2 3 5 8 13 21 34
|
||||
make: Unknown modifier '_'
|
||||
make: Unknown modifier "__"
|
||||
|
||||
|
||||
mod-sysv-parse:
|
||||
make: Unknown modifier '3'
|
||||
make: Unclosed variable specification (expecting '}') for "FIB" (value "") modifier 3
|
||||
make: Unknown modifier "3"
|
||||
make: Unclosed variable expression, expecting '}' for modifier "3" of variable "FIB" with value ""
|
||||
|
||||
make: Unknown modifier '3'
|
||||
make: Unclosed variable specification (expecting '}') for "FIB" (value "") modifier 3
|
||||
make: Unknown modifier "3="
|
||||
make: Unclosed variable expression, expecting '}' for modifier "3=" of variable "FIB" with value ""
|
||||
|
||||
make: Unknown modifier '3'
|
||||
make: Unclosed variable specification (expecting '}') for "FIB" (value "") modifier 3
|
||||
make: Unknown modifier "3=x3"
|
||||
make: Unclosed variable expression, expecting '}' for modifier "3=x3" of variable "FIB" with value ""
|
||||
|
||||
1 1 2 x3 5 8 1x3 21 34
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: moderrs.mk,v 1.25 2020/11/15 20:20:58 rillig Exp $
|
||||
# $NetBSD: moderrs.mk,v 1.30 2021/06/21 08:28:37 rillig Exp $
|
||||
#
|
||||
# various modifier error tests
|
||||
|
||||
@ -19,7 +19,6 @@ all: words
|
||||
all: exclam
|
||||
all: mod-subst-delimiter
|
||||
all: mod-regex-delimiter
|
||||
all: mod-regex-undefined-subexpression
|
||||
all: mod-ts-parse
|
||||
all: mod-t-parse
|
||||
all: mod-ifelse-parse
|
||||
@ -35,11 +34,11 @@ mod-unknown-indirect: print-header print-footer
|
||||
@echo 'VAR:${MOD_UNKN}=before-${VAR:${MOD_UNKN}:inner}-after'
|
||||
|
||||
unclosed-direct: print-header print-footer
|
||||
@echo 'want: Unclosed variable specification (expecting $'}$') for "VAR" (value "Thevariable") modifier S'
|
||||
@echo 'want: Unclosed variable expression, expecting $'}$' for modifier "S,V,v," of variable "VAR" with value "Thevariable"'
|
||||
@echo VAR:S,V,v,=${VAR:S,V,v,
|
||||
|
||||
unclosed-indirect: print-header print-footer
|
||||
@echo 'want: Unclosed variable specification after complex modifier (expecting $'}$') for VAR'
|
||||
@echo 'want: Unclosed variable expression after indirect modifier, expecting $'}$' for variable "VAR"'
|
||||
@echo VAR:${MOD_TERM},=${VAR:${MOD_S}
|
||||
|
||||
unfinished-indirect: print-header print-footer
|
||||
@ -119,27 +118,11 @@ mod-regex-delimiter: print-header print-footer
|
||||
@echo 6: ${VAR:C,from,to,
|
||||
@echo 7: ${VAR:C,from,to,}
|
||||
|
||||
# In regular expressions with alternatives, not all capturing groups are
|
||||
# always set; some may be missing. Warn about these.
|
||||
#
|
||||
# Since there is no way to turn off this warning, the combination of
|
||||
# alternative matches and capturing groups is seldom used, if at all.
|
||||
#
|
||||
# A newly added modifier 'U' such as in :C,(a.)|(b.),\1\2,U might be added
|
||||
# for treating undefined capturing groups as empty, but that would create a
|
||||
# syntactical ambiguity since the :S and :C modifiers are open-ended (see
|
||||
# mod-subst-chain). Luckily the modifier :U does not make sense after :C,
|
||||
# therefore this case does not happen in practice.
|
||||
# The sub-modifier for the :S and :C modifiers would have to be chosen
|
||||
# wisely, to not create ambiguities while parsing.
|
||||
mod-regex-undefined-subexpression: print-header print-footer
|
||||
@echo ${FIB:C,1(.*),one\1,} # all ok
|
||||
@echo ${FIB:C,1(.*)|2(.*),(\1)+(\2),:Q} # no match for subexpression
|
||||
|
||||
mod-ts-parse: print-header print-footer
|
||||
@echo ${FIB:ts}
|
||||
@echo ${FIB:ts\65} # octal 065 == U+0035 == '5'
|
||||
@echo ${FIB:ts\65oct} # bad modifier
|
||||
@echo ${:U${FIB}:ts\65oct} # bad modifier, variable name is ""
|
||||
@echo ${FIB:tsxy} # modifier too long
|
||||
|
||||
mod-t-parse: print-header print-footer
|
||||
|
@ -1,6 +1,6 @@
|
||||
make: Bad modifier `:tx' for LIST
|
||||
make: Bad modifier ":tx" for variable "LIST"
|
||||
LIST:tx="}"
|
||||
make: Bad modifier `:ts\X' for LIST
|
||||
make: Bad modifier ":ts\X" for variable "LIST"
|
||||
LIST:ts/x:tu="\X:tu}"
|
||||
FU_mod-ts="a/b/cool"
|
||||
FU_mod-ts:ts:T="cool" == cool?
|
||||
|
@ -1,4 +1,4 @@
|
||||
make: Bad modifier `:[]' for LIST
|
||||
make: Bad modifier ":[]" for variable "LIST"
|
||||
LIST:[]="" is an error
|
||||
LIST:[0]="one two three four five six"
|
||||
LIST:[0x0]="one two three four five six"
|
||||
@ -37,17 +37,17 @@ REALLYSPACE=" "
|
||||
REALLYSPACE:[1]="" == "" ?
|
||||
REALLYSPACE:[*]:[1]=" " == " " ?
|
||||
LIST:[1]="one"
|
||||
make: Bad modifier `:[1.]' for LIST
|
||||
make: Bad modifier ":[1.]" for variable "LIST"
|
||||
LIST:[1.]="" is an error
|
||||
make: Bad modifier `:[1].' for LIST
|
||||
make: Bad modifier ":[1]." for variable "LIST"
|
||||
LIST:[1].="}" is an error
|
||||
LIST:[2]="two"
|
||||
LIST:[6]="six"
|
||||
LIST:[7]=""
|
||||
LIST:[999]=""
|
||||
make: Bad modifier `:[-]' for LIST
|
||||
make: Bad modifier ":[-]" for variable "LIST"
|
||||
LIST:[-]="" is an error
|
||||
make: Bad modifier `:[--]' for LIST
|
||||
make: Bad modifier ":[--]" for variable "LIST"
|
||||
LIST:[--]="" is an error
|
||||
LIST:[-1]="six"
|
||||
LIST:[-2]="five"
|
||||
@ -67,20 +67,22 @@ LIST:[*]:C/ /,/:[2]=""
|
||||
LIST:[*]:C/ /,/:[*]:[2]=""
|
||||
LIST:[*]:C/ /,/:[@]:[2]="three"
|
||||
LONGLIST:[012..0x12]="10 11 12 13 14 15 16 17 18"
|
||||
make: Bad modifier `:[1.]' for LIST
|
||||
make: Bad modifier ":[1.]" for variable "LIST"
|
||||
LIST:[1.]="" is an error
|
||||
make: Bad modifier `:[1..]' for LIST
|
||||
make: Bad modifier ":[1..]" for variable "LIST"
|
||||
LIST:[1..]="" is an error
|
||||
make: Bad modifier ":[1.. ]" for variable "LIST"
|
||||
LIST:[1.. ]="" is an error
|
||||
LIST:[1..1]="one"
|
||||
make: Bad modifier `:[1..1.]' for LIST
|
||||
make: Bad modifier ":[1..1.]" for variable "LIST"
|
||||
LIST:[1..1.]="" is an error
|
||||
LIST:[1..2]="one two"
|
||||
LIST:[2..1]="two one"
|
||||
LIST:[3..-2]="three four five"
|
||||
LIST:[-4..4]="three four"
|
||||
make: Bad modifier `:[0..1]' for LIST
|
||||
make: Bad modifier ":[0..1]" for variable "LIST"
|
||||
LIST:[0..1]="" is an error
|
||||
make: Bad modifier `:[-1..0]' for LIST
|
||||
make: Bad modifier ":[-1..0]" for variable "LIST"
|
||||
LIST:[-1..0]="" is an error
|
||||
LIST:[-1..1]="six five four three two one"
|
||||
LIST:[0..0]="one two three four five six"
|
||||
@ -95,7 +97,7 @@ LIST:[${ONE}]="one"
|
||||
LIST:[${MINUSONE}]="six"
|
||||
LIST:[${STAR}]="one two three four five six"
|
||||
LIST:[${AT}]="one two three four five six"
|
||||
make: Bad modifier `:[${EMPTY' for LIST
|
||||
make: Bad modifier ":[${EMPTY" for variable "LIST"
|
||||
LIST:[${EMPTY}]="" is an error
|
||||
LIST:[${LONGLIST:[21]:S/2//}]="one"
|
||||
LIST:[${LIST:[#]}]="six"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: modword.mk,v 1.5 2020/11/15 20:20:58 rillig Exp $
|
||||
# $NetBSD: modword.mk,v 1.6 2021/03/14 16:00:07 rillig Exp $
|
||||
#
|
||||
# Test behaviour of new :[] modifier
|
||||
# TODO: When was this modifier new?
|
||||
@ -99,6 +99,7 @@ mod-squarebrackets-n:
|
||||
mod-squarebrackets-start-end:
|
||||
@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
|
||||
@echo 'LIST:[1..]="${LIST:[1..]}" is an error'
|
||||
@echo 'LIST:[1.. ]="${LIST:[1.. ]}" is an error'
|
||||
@echo 'LIST:[1..1]="${LIST:[1..1]}"'
|
||||
@echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'
|
||||
@echo 'LIST:[1..2]="${LIST:[1..2]}"'
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: opt-chdir.mk,v 1.5 2020/11/15 05:43:56 sjg Exp $
|
||||
# $NetBSD: opt-chdir.mk,v 1.6 2021/05/18 17:05:45 sjg Exp $
|
||||
#
|
||||
# Tests for the -C command line option, which changes the directory at the
|
||||
# beginning.
|
||||
@ -23,5 +23,7 @@ chdir-root: .PHONY .IGNORE
|
||||
@MAKE_OBJDIR_CHECK_WRITABLE=no ${MAKE} -C / -V 'cwd: $${.CURDIR}'
|
||||
|
||||
# Trying to change to a nonexistent directory exits immediately.
|
||||
# Note: just because the whole point of /nonexistent is that it should
|
||||
# not exist - doesn't mean it doesn't.
|
||||
chdir-nonexistent: .PHONY .IGNORE
|
||||
@${MAKE} -C /nonexistent
|
||||
@${MAKE} -C /nonexistent.${.MAKE.PID}
|
||||
|
48
contrib/bmake/unit-tests/opt-debug-errors-jobs.exp
Normal file
48
contrib/bmake/unit-tests/opt-debug-errors-jobs.exp
Normal file
@ -0,0 +1,48 @@
|
||||
echo '3 spaces'; false
|
||||
3 spaces
|
||||
|
||||
*** Failed target: fail-spaces
|
||||
*** Failed commands:
|
||||
echo '3 spaces'; false
|
||||
*** [fail-spaces] Error code 1
|
||||
|
||||
make: stopped in unit-tests
|
||||
echo \ indented; false
|
||||
indented
|
||||
|
||||
*** Failed target: fail-escaped-space
|
||||
*** Failed commands:
|
||||
echo \ indented; false
|
||||
*** [fail-escaped-space] Error code 1
|
||||
|
||||
make: stopped in unit-tests
|
||||
echo 'line1
|
||||
line2'; false
|
||||
line1
|
||||
line2
|
||||
|
||||
*** Failed target: fail-newline
|
||||
*** Failed commands:
|
||||
echo 'line1${.newline}line2'; false
|
||||
*** [fail-newline] Error code 1
|
||||
|
||||
make: stopped in unit-tests
|
||||
echo 'line1 line2'; false
|
||||
line1 line2
|
||||
|
||||
*** Failed target: fail-multiline
|
||||
*** Failed commands:
|
||||
echo 'line1 line2'; false
|
||||
*** [fail-multiline] Error code 1
|
||||
|
||||
make: stopped in unit-tests
|
||||
echo 'word1' 'word2'; false
|
||||
word1 word2
|
||||
|
||||
*** Failed target: fail-multiline-intention
|
||||
*** Failed commands:
|
||||
echo 'word1' 'word2'; false
|
||||
*** [fail-multiline-intention] Error code 1
|
||||
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
36
contrib/bmake/unit-tests/opt-debug-errors-jobs.mk
Normal file
36
contrib/bmake/unit-tests/opt-debug-errors-jobs.mk
Normal file
@ -0,0 +1,36 @@
|
||||
# $NetBSD: opt-debug-errors-jobs.mk,v 1.1 2021/04/27 16:20:06 rillig Exp $
|
||||
#
|
||||
# Tests for the -de command line option, which adds debug logging for
|
||||
# failed commands and targets; since 2021-04-27 also in jobs mode.
|
||||
|
||||
.MAKEFLAGS: -de -j1
|
||||
|
||||
all: fail-spaces
|
||||
all: fail-escaped-space
|
||||
all: fail-newline
|
||||
all: fail-multiline
|
||||
all: fail-multiline-intention
|
||||
|
||||
fail-spaces:
|
||||
echo '3 spaces'; false
|
||||
|
||||
fail-escaped-space:
|
||||
echo \ indented; false
|
||||
|
||||
fail-newline:
|
||||
echo 'line1${.newline}line2'; false
|
||||
|
||||
# The line continuations in multiline commands are turned into an ordinary
|
||||
# space before the command is actually run.
|
||||
fail-multiline:
|
||||
echo 'line1\
|
||||
line2'; false
|
||||
|
||||
# It is a common style to align the continuation backslashes at the right
|
||||
# of the lines, usually at column 73. All spaces before the continuation
|
||||
# backslash are preserved and are usually outside a shell word and thus
|
||||
# irrelevant. Since "usually" is not "always", these space characters are
|
||||
# not merged into a single space.
|
||||
fail-multiline-intention:
|
||||
echo 'word1' \
|
||||
'word2'; false
|
@ -2,7 +2,7 @@ make: "opt-debug-lint.mk" line 19: Variable "X" is undefined
|
||||
make: "opt-debug-lint.mk" line 41: Variable "UNDEF" is undefined
|
||||
make: "opt-debug-lint.mk" line 61: Missing delimiter ':' after modifier "L"
|
||||
make: "opt-debug-lint.mk" line 61: Missing delimiter ':' after modifier "P"
|
||||
make: "opt-debug-lint.mk" line 69: Unknown modifier '$'
|
||||
make: "opt-debug-lint.mk" line 69: Unknown modifier "${"
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: opt-debug-lint.mk,v 1.12 2020/12/20 19:10:53 rillig Exp $
|
||||
# $NetBSD: opt-debug-lint.mk,v 1.14 2021/03/14 10:57:12 rillig Exp $
|
||||
#
|
||||
# Tests for the -dL command line option, which runs additional checks
|
||||
# to catch common mistakes, such as unclosed variable expressions.
|
||||
@ -77,5 +77,19 @@ ${UNDEF}: ${UNDEF}
|
||||
. error
|
||||
.endif
|
||||
|
||||
all:
|
||||
@:;
|
||||
# In lint mode, the whole variable text is evaluated to check for unclosed
|
||||
# expressions and unknown operators. During this check, the subexpression
|
||||
# '${:U2}' is not expanded, instead it is copied verbatim into the regular
|
||||
# expression, leading to '.*=.{1,${:U2}}$'.
|
||||
#
|
||||
# Before var.c 1.856 from 2021-03-14, this regular expression was then
|
||||
# compiled even though that was not necessary for checking the syntax at the
|
||||
# level of variable expressions. The unexpanded '$' then resulted in a wrong
|
||||
# error message.
|
||||
#
|
||||
# This only happened in lint mode since in default mode the early check for
|
||||
# unclosed expressions and unknown modifiers is skipped.
|
||||
#
|
||||
# See VarCheckSyntax, ApplyModifier_Regex.
|
||||
#
|
||||
VARMOD_REGEX= ${:UA=111 B=222 C=33:C/.*=.{1,${:U2}}$//g}
|
||||
|
@ -1,4 +1,4 @@
|
||||
Global:VAR = value
|
||||
Global:.MAKEFLAGS = -r -k -d v -d
|
||||
Global:.MAKEFLAGS = -r -k -d v -d 0
|
||||
Global: VAR = value
|
||||
Global: .MAKEFLAGS = -r -k -d v -d
|
||||
Global: .MAKEFLAGS = -r -k -d v -d 0
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: opt-file.mk,v 1.11 2020/12/22 08:57:23 rillig Exp $
|
||||
# $NetBSD: opt-file.mk,v 1.12 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Tests for the -f command line option.
|
||||
|
||||
@ -28,10 +28,10 @@ all: file-containing-null-byte
|
||||
# ParseReadLine (1): 'VAR=value\<A5><A5><A5><A5><A5><A5>'
|
||||
# Global:VAR = value\<A5><A5><A5><A5><A5><A5>value\<A5><A5><A5><A5><A5><A5>
|
||||
# ParseReadLine (2): 'alue\<A5><A5><A5><A5><A5><A5>'
|
||||
# ParseDoDependency(alue\<A5><A5><A5><A5><A5><A5>)
|
||||
# ParseDependency(alue\<A5><A5><A5><A5><A5><A5>)
|
||||
# make-2014.01.01.00.00.00: "(stdin)" line 2: Need an operator
|
||||
# ParseReadLine (3): '<A5><A5><A5>ZZZZZZZZZZZZZZZZ'
|
||||
# ParseDoDependency(<A5><A5><A5>ZZZZZZZZZZZZZZZZ)
|
||||
# ParseDependency(<A5><A5><A5>ZZZZZZZZZZZZZZZZ)
|
||||
#
|
||||
file-ending-in-backslash: .PHONY
|
||||
@printf '%s' 'VAR=value\' \
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: opt-jobs-no-action.mk,v 1.8 2020/12/10 23:54:41 rillig Exp $
|
||||
# $NetBSD: opt-jobs-no-action.mk,v 1.9 2021/04/04 09:58:51 rillig Exp $
|
||||
#
|
||||
# Tests for the combination of the options -j and -n, which prints the
|
||||
# commands instead of actually running them.
|
||||
@ -23,7 +23,7 @@
|
||||
# this is handled by the [0] != '\0' checks in Job_ParseShell.
|
||||
# The '\#' is handled by ParseGetLine.
|
||||
# The '\n' is handled by Str_Words in Job_ParseShell.
|
||||
# The '$$' is handled by Var_Subst in ParseDependency.
|
||||
# The '$$' is handled by Var_Subst in ParseDependencyLine.
|
||||
.SHELL: \
|
||||
name=sh \
|
||||
path=${.SHELL} \
|
||||
|
@ -1,12 +1,12 @@
|
||||
# $NetBSD: recursive.mk,v 1.4 2020/11/09 20:50:56 rillig Exp $
|
||||
# $NetBSD: recursive.mk,v 1.5 2021/03/15 12:15:03 rillig Exp $
|
||||
#
|
||||
# In -dL mode, a variable may get expanded before it makes sense.
|
||||
# This would stop make from doing anything since the "recursive" error
|
||||
# is fatal and exits immediately.
|
||||
#
|
||||
# The purpose of evaluating that variable early was just to detect
|
||||
# whether there are unclosed variables. It might be enough to parse the
|
||||
# variable value without VARE_WANTRES for that purpose.
|
||||
# whether there are unclosed variables. The variable value is therefore
|
||||
# parsed with VARE_PARSE_ONLY for that purpose.
|
||||
#
|
||||
# Seen in pkgsrc/x11/libXfixes, and probably many more package that use
|
||||
# GNU Automake.
|
||||
@ -36,4 +36,3 @@ MISSING_BRACE_INDIRECT:= ${:U\${MISSING_BRACE}
|
||||
UNCLOSED= $(MISSING_PAREN
|
||||
UNCLOSED= ${MISSING_BRACE
|
||||
UNCLOSED= ${MISSING_BRACE_INDIRECT}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: sh-jobs.mk,v 1.3 2020/12/11 01:06:10 rillig Exp $
|
||||
# $NetBSD: sh-jobs.mk,v 1.4 2021/04/16 16:49:27 rillig Exp $
|
||||
#
|
||||
# Tests for the "run in jobs mode" part of the "Shell Commands" section
|
||||
# from the manual page.
|
||||
@ -14,14 +14,14 @@ all: .PHONY comment .WAIT comment-with-followup-line .WAIT no-comment
|
||||
# would lead to a syntax error in the generated shell file, at least for
|
||||
# bash and dash, but not for NetBSD sh and ksh.
|
||||
#
|
||||
# See JobPrintCommand, cmdTemplate, runIgnTmpl
|
||||
# See JobWriteCommand, cmdTemplate, runIgnTmpl
|
||||
comment: .PHONY
|
||||
@# comment
|
||||
|
||||
# If a shell command starts with a comment character after stripping the
|
||||
# leading '@', it is run in ignore-errors mode.
|
||||
#
|
||||
# See JobPrintCommand, cmdTemplate, runIgnTmpl
|
||||
# See JobWriteCommand, cmdTemplate, runIgnTmpl
|
||||
comment-with-followup-line: .PHONY
|
||||
@# comment${.newline}echo '$@: This is printed.'; false
|
||||
@true
|
||||
@ -29,7 +29,7 @@ comment-with-followup-line: .PHONY
|
||||
# Without the comment, the commands are run in the default mode, which checks
|
||||
# the exit status of every makefile line.
|
||||
#
|
||||
# See JobPrintCommand, cmdTemplate, runChkTmpl
|
||||
# See JobWriteCommand, cmdTemplate, runChkTmpl
|
||||
no-comment: .PHONY
|
||||
@echo '$@: This is printed.'; false
|
||||
@true
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: shell-csh.mk,v 1.7 2020/12/13 02:09:55 sjg Exp $
|
||||
# $NetBSD: shell-csh.mk,v 1.8 2021/04/04 09:58:51 rillig Exp $
|
||||
#
|
||||
# Tests for using a C shell for running the commands.
|
||||
|
||||
@ -12,7 +12,7 @@ CSH!= which csh 2> /dev/null || true
|
||||
.endif
|
||||
|
||||
# In parallel mode, the shell->noPrint command is filtered from
|
||||
# the output, rather naively (in JobOutput).
|
||||
# the output, rather naively (in PrintOutput).
|
||||
#
|
||||
# Until 2020-10-03, the output in parallel mode was garbled because
|
||||
# the definition of the csh had been wrong since 1993 at least.
|
||||
|
@ -1,19 +1,19 @@
|
||||
ParseReadLine (9): '.SUFFIXES:'
|
||||
ParseDoDependency(.SUFFIXES:)
|
||||
ParseDependency(.SUFFIXES:)
|
||||
Clearing all suffixes
|
||||
ParseReadLine (11): '.SUFFIXES: .a .b .c'
|
||||
ParseDoDependency(.SUFFIXES: .a .b .c)
|
||||
ParseDependency(.SUFFIXES: .a .b .c)
|
||||
Adding suffix ".a"
|
||||
Adding suffix ".b"
|
||||
Adding suffix ".c"
|
||||
ParseReadLine (17): '.a.b:'
|
||||
ParseDoDependency(.a.b:)
|
||||
ParseDependency(.a.b:)
|
||||
defining transformation from `.a' to `.b'
|
||||
inserting ".a" (1) at end of list
|
||||
inserting ".b" (2) at end of list
|
||||
ParseReadLine (21): '.a.c: ${.PREFIX}.dependency'
|
||||
deleting incomplete transformation from `.a' to `.b'
|
||||
ParseDoDependency(.a.c: ${.PREFIX}.dependency)
|
||||
ParseDependency(.a.c: ${.PREFIX}.dependency)
|
||||
defining transformation from `.a' to `.c'
|
||||
inserting ".a" (1) at end of list
|
||||
inserting ".c" (3) at end of list
|
||||
@ -22,7 +22,7 @@ inserting ".c" (3) at end of list
|
||||
# ${.PREFIX}.dependency, unmade, type none, flags none
|
||||
ParseReadLine (23): '.DEFAULT:'
|
||||
transformation .a.c complete
|
||||
ParseDoDependency(.DEFAULT:)
|
||||
ParseDependency(.DEFAULT:)
|
||||
ParseReadLine (24): ' : Making ${.TARGET} from ${.IMPSRC} all ${.ALLSRC} by default.'
|
||||
transformation .DEFAULT complete
|
||||
Wildcard expanding "all"...
|
||||
|
@ -1,12 +1,12 @@
|
||||
ParseReadLine (8): '.1.2 .1.3 .1.4:'
|
||||
ParseDoDependency(.1.2 .1.3 .1.4:)
|
||||
ParseDependency(.1.2 .1.3 .1.4:)
|
||||
Setting main node to ".1.2"
|
||||
ParseReadLine (9): ' : Making ${.TARGET} from ${.IMPSRC}.'
|
||||
ParseReadLine (14): 'next-main:'
|
||||
ParseDoDependency(next-main:)
|
||||
ParseDependency(next-main:)
|
||||
ParseReadLine (15): ' : Making ${.TARGET}'
|
||||
ParseReadLine (19): '.SUFFIXES: .1 .2 .3 .4'
|
||||
ParseDoDependency(.SUFFIXES: .1 .2 .3 .4)
|
||||
ParseDependency(.SUFFIXES: .1 .2 .3 .4)
|
||||
Adding suffix ".1"
|
||||
Adding suffix ".2"
|
||||
Setting main node from ".1.2" back to null
|
||||
@ -27,42 +27,42 @@ inserting ".1" (1) at end of list
|
||||
inserting ".4" (4) at end of list
|
||||
Setting main node to "next-main"
|
||||
ParseReadLine (24): '.SUFFIXES:'
|
||||
ParseDoDependency(.SUFFIXES:)
|
||||
ParseDependency(.SUFFIXES:)
|
||||
Clearing all suffixes
|
||||
ParseReadLine (32): '.SUFFIXES: .4 .3 .2 .1'
|
||||
ParseDoDependency(.SUFFIXES: .4 .3 .2 .1)
|
||||
ParseDependency(.SUFFIXES: .4 .3 .2 .1)
|
||||
Adding suffix ".4"
|
||||
Adding suffix ".3"
|
||||
Adding suffix ".2"
|
||||
Adding suffix ".1"
|
||||
ParseReadLine (33): '.SUFFIXES:'
|
||||
ParseDoDependency(.SUFFIXES:)
|
||||
ParseDependency(.SUFFIXES:)
|
||||
Clearing all suffixes
|
||||
ParseReadLine (34): '.SUFFIXES: .1 .2 .3 .4'
|
||||
ParseDoDependency(.SUFFIXES: .1 .2 .3 .4)
|
||||
ParseDependency(.SUFFIXES: .1 .2 .3 .4)
|
||||
Adding suffix ".1"
|
||||
Adding suffix ".2"
|
||||
Adding suffix ".3"
|
||||
Adding suffix ".4"
|
||||
ParseReadLine (35): '.SUFFIXES:'
|
||||
ParseDoDependency(.SUFFIXES:)
|
||||
ParseDependency(.SUFFIXES:)
|
||||
Clearing all suffixes
|
||||
ParseReadLine (36): '.SUFFIXES: .4 .3 .2 .1'
|
||||
ParseDoDependency(.SUFFIXES: .4 .3 .2 .1)
|
||||
ParseDependency(.SUFFIXES: .4 .3 .2 .1)
|
||||
Adding suffix ".4"
|
||||
Adding suffix ".3"
|
||||
Adding suffix ".2"
|
||||
Adding suffix ".1"
|
||||
ParseReadLine (38): 'suff-main-several.1:'
|
||||
ParseDoDependency(suff-main-several.1:)
|
||||
ParseDependency(suff-main-several.1:)
|
||||
ParseReadLine (39): ' : Making ${.TARGET} out of nothing.'
|
||||
ParseReadLine (40): 'next-main: suff-main-several.{2,3,4}'
|
||||
ParseDoDependency(next-main: suff-main-several.{2,3,4})
|
||||
ParseDependency(next-main: suff-main-several.{2,3,4})
|
||||
# LinkSource: added child next-main - suff-main-several.{2,3,4}
|
||||
# next-main, unmade, type OP_DEPENDS|OP_HAS_COMMANDS, flags none
|
||||
# suff-main-several.{2,3,4}, unmade, type none, flags none
|
||||
ParseReadLine (42): '.MAKEFLAGS: -d0 -dg1'
|
||||
ParseDoDependency(.MAKEFLAGS: -d0 -dg1)
|
||||
ParseDependency(.MAKEFLAGS: -d0 -dg1)
|
||||
#*** Input graph:
|
||||
# .1.2, unmade, type OP_TRANSFORM, flags none
|
||||
# .1.3, unmade, type OP_TRANSFORM, flags none
|
||||
|
@ -1,38 +1,38 @@
|
||||
ParseReadLine (10): '.SUFFIXES:'
|
||||
ParseDoDependency(.SUFFIXES:)
|
||||
ParseDependency(.SUFFIXES:)
|
||||
Clearing all suffixes
|
||||
ParseReadLine (12): '.SUFFIXES: .a .b .c'
|
||||
ParseDoDependency(.SUFFIXES: .a .b .c)
|
||||
ParseDependency(.SUFFIXES: .a .b .c)
|
||||
Adding suffix ".a"
|
||||
Adding suffix ".b"
|
||||
Adding suffix ".c"
|
||||
ParseReadLine (14): 'suff-rebuild-example.a:'
|
||||
ParseDoDependency(suff-rebuild-example.a:)
|
||||
ParseDependency(suff-rebuild-example.a:)
|
||||
Adding "suff-rebuild-example.a" to all targets.
|
||||
ParseReadLine (15): ' : Making ${.TARGET} out of nothing.'
|
||||
ParseReadLine (17): '.a.b:'
|
||||
ParseDoDependency(.a.b:)
|
||||
ParseDependency(.a.b:)
|
||||
defining transformation from `.a' to `.b'
|
||||
inserting ".a" (1) at end of list
|
||||
inserting ".b" (2) at end of list
|
||||
ParseReadLine (18): ' : Making ${.TARGET} from ${.IMPSRC}.'
|
||||
ParseReadLine (19): '.b.c:'
|
||||
transformation .a.b complete
|
||||
ParseDoDependency(.b.c:)
|
||||
ParseDependency(.b.c:)
|
||||
defining transformation from `.b' to `.c'
|
||||
inserting ".b" (2) at end of list
|
||||
inserting ".c" (3) at end of list
|
||||
ParseReadLine (20): ' : Making ${.TARGET} from ${.IMPSRC}.'
|
||||
ParseReadLine (21): '.c:'
|
||||
transformation .b.c complete
|
||||
ParseDoDependency(.c:)
|
||||
ParseDependency(.c:)
|
||||
defining transformation from `.c' to `'
|
||||
inserting ".c" (3) at end of list
|
||||
inserting "" (0) at end of list
|
||||
ParseReadLine (22): ' : Making ${.TARGET} from ${.IMPSRC}.'
|
||||
ParseReadLine (44): '.SUFFIXES: .c .b .a'
|
||||
transformation .c complete
|
||||
ParseDoDependency(.SUFFIXES: .c .b .a)
|
||||
ParseDependency(.SUFFIXES: .c .b .a)
|
||||
Adding ".END" to all targets.
|
||||
Wildcard expanding "all"...
|
||||
SuffFindDeps "all"
|
||||
|
@ -1 +1,4 @@
|
||||
make: "var-class-cmdline.mk" line 67: global
|
||||
make: "var-class-cmdline.mk" line 76: makeflags
|
||||
makeflags
|
||||
exit status 0
|
||||
|
@ -1,8 +1,80 @@
|
||||
# $NetBSD: var-class-cmdline.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
|
||||
# $NetBSD: var-class-cmdline.mk,v 1.5 2021/02/23 21:59:31 rillig Exp $
|
||||
#
|
||||
# Tests for variables specified on the command line.
|
||||
#
|
||||
# Variables that are specified on the command line override those from the
|
||||
# global scope.
|
||||
#
|
||||
# For performance reasons, the actual implementation is more complex than the
|
||||
# above single-sentence rule, in order to avoid unnecessary lookups in scopes,
|
||||
# which before var.c 1.586 from 2020-10-25 calculated the hash value of the
|
||||
# variable name once for each lookup. Instead, when looking up the value of
|
||||
# a variable, the search often starts in the global scope since that is where
|
||||
# most of the variables are stored. This conflicts with the statement that
|
||||
# variables from the cmdline scope override global variables, since after the
|
||||
# common case of finding a variable in the global scope, another lookup would
|
||||
# be needed in the cmdline scope to ensure that there is no overriding
|
||||
# variable there.
|
||||
#
|
||||
# Instead of this costly lookup scheme, make implements it in a different
|
||||
# way:
|
||||
#
|
||||
# Whenever a global variable is created, this creation is ignored if
|
||||
# there is a cmdline variable of the same name.
|
||||
#
|
||||
# Whenever a cmdline variable is created, any global variable of the
|
||||
# same name is deleted.
|
||||
#
|
||||
# Whenever a global variable is deleted, nothing special happens.
|
||||
#
|
||||
# Deleting a cmdline variable is not possible.
|
||||
#
|
||||
# These 4 rules provide the guarantee that whenever a global variable exists,
|
||||
# there cannot be a cmdline variable of the same name. Therefore, after
|
||||
# finding a variable in the global scope, no additional lookup is needed in
|
||||
# the cmdline scope.
|
||||
#
|
||||
# The above ruleset provides the same guarantees as the simple rule "cmdline
|
||||
# overrides global". Due to an implementation mistake, the actual behavior
|
||||
# was not entirely equivalent to the simple rule though. The mistake was
|
||||
# that when a cmdline variable with '$$' in its name was added, a global
|
||||
# variable was deleted, but not with the exact same name as the cmdline
|
||||
# variable. Instead, the name of the global variable was expanded one more
|
||||
# time than the name of the cmdline variable. For variable names that didn't
|
||||
# have a '$$' in their name, it was implemented correctly all the time.
|
||||
#
|
||||
# The bug was added in var.c 1.183 on 2013-07-16, when Var_Set called
|
||||
# Var_Delete to delete the global variable. Just two months earlier, in var.c
|
||||
# 1.174 from 2013-05-18, Var_Delete had started to expand the variable name.
|
||||
# Together, these two changes made the variable name be expanded twice in a
|
||||
# row. This bug was fixed in var.c 1.835 from 2021-02-22.
|
||||
#
|
||||
# Another bug was the wrong assumption that "deleting a cmdline variable is
|
||||
# not possible". Deleting such a variable has been possible since var.c 1.204
|
||||
# from 2016-02-19, when the variable modifier ':@' started to delete the
|
||||
# temporary loop variable after finishing the loop. It was probably not
|
||||
# intended back then that a side effect of this seemingly simple change was
|
||||
# that both global and cmdline variables could now be undefined at will as a
|
||||
# side effect of evaluating a variable expression. As of 2021-02-23, this is
|
||||
# still possible.
|
||||
#
|
||||
# Most cmdline variables are set at the very beginning, when parsing the
|
||||
# command line arguments. Using the special target '.MAKEFLAGS', it is
|
||||
# possible to set cmdline variables at any later time.
|
||||
|
||||
# TODO: Implementation
|
||||
# A normal global variable, without any cmdline variable nearby.
|
||||
VAR= global
|
||||
.info ${VAR}
|
||||
|
||||
all:
|
||||
@:;
|
||||
# The global variable is "overridden" by simply deleting it and then
|
||||
# installing the cmdline variable instead. Since there is no obvious way to
|
||||
# undefine a cmdline variable, there is no need to remember the old value
|
||||
# of the global variable could become visible again.
|
||||
#
|
||||
# See varmod-loop.mk for a non-obvious way to undefine a cmdline variable.
|
||||
.MAKEFLAGS: VAR=makeflags
|
||||
.info ${VAR}
|
||||
|
||||
# If Var_SetWithFlags should ever forget to delete the global variable,
|
||||
# the below line would print "global" instead of the current "makeflags".
|
||||
.MAKEFLAGS: -V VAR
|
||||
|
29
contrib/bmake/unit-tests/var-eval-short.exp
Normal file
29
contrib/bmake/unit-tests/var-eval-short.exp
Normal file
@ -0,0 +1,29 @@
|
||||
make: "var-eval-short.mk" line 41: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar.
|
||||
make: "var-eval-short.mk" line 41: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
|
||||
make: "var-eval-short.mk" line 79: Invalid time value: ${FAIL}}
|
||||
make: "var-eval-short.mk" line 79: Malformed conditional (0 && ${:Uword:gmtime=${FAIL}})
|
||||
make: "var-eval-short.mk" line 93: Invalid time value: ${FAIL}}
|
||||
make: "var-eval-short.mk" line 93: Malformed conditional (0 && ${:Uword:localtime=${FAIL}})
|
||||
CondParser_Eval: 0 && ${0:?${FAIL}then:${FAIL}else}
|
||||
Var_Parse: ${0:?${FAIL}then:${FAIL}else} (parse-only)
|
||||
Parsing modifier ${0:?...}
|
||||
Modifier part: "${FAIL}then"
|
||||
Modifier part: "${FAIL}else"
|
||||
Result of ${0:?${FAIL}then:${FAIL}else} is "" (parse-only, defined)
|
||||
ParseReadLine (158): 'DEFINED= defined'
|
||||
Global: DEFINED = defined
|
||||
CondParser_Eval: 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
|
||||
Var_Parse: ${DEFINED:L:?${FAIL}then:${FAIL}else} (parse-only)
|
||||
Parsing modifier ${DEFINED:L}
|
||||
Result of ${DEFINED:L} is "defined" (parse-only, regular)
|
||||
Parsing modifier ${DEFINED:?...}
|
||||
Modifier part: "${FAIL}then"
|
||||
Modifier part: "${FAIL}else"
|
||||
Result of ${DEFINED:?${FAIL}then:${FAIL}else} is "defined" (parse-only, regular)
|
||||
ParseReadLine (161): '.MAKEFLAGS: -d0'
|
||||
ParseDependency(.MAKEFLAGS: -d0)
|
||||
Global: .MAKEFLAGS = -r -k -d cpv -d
|
||||
Global: .MAKEFLAGS = -r -k -d cpv -d 0
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
163
contrib/bmake/unit-tests/var-eval-short.mk
Normal file
163
contrib/bmake/unit-tests/var-eval-short.mk
Normal file
@ -0,0 +1,163 @@
|
||||
# $NetBSD: var-eval-short.mk,v 1.5 2021/04/04 13:35:26 rillig Exp $
|
||||
#
|
||||
# Tests for each variable modifier to ensure that they only do the minimum
|
||||
# necessary computations. If the result of the expression is not needed, they
|
||||
# should only parse the modifier but not actually evaluate it.
|
||||
#
|
||||
# See also:
|
||||
# var.c, the comment starting with 'The ApplyModifier functions'
|
||||
# ApplyModifier, for the order of the modifiers
|
||||
# ParseModifierPart, for evaluating nested expressions
|
||||
# cond-short.mk
|
||||
|
||||
FAIL= ${:!echo unexpected 1>&2!}
|
||||
|
||||
# The following tests only ensure that nested expressions are not evaluated.
|
||||
# They cannot ensure that any unexpanded text returned from ParseModifierPart
|
||||
# is ignored as well. To do that, it is necessary to step through the code of
|
||||
# each modifier.
|
||||
|
||||
.if 0 && ${FAIL}
|
||||
.endif
|
||||
|
||||
.if 0 && ${VAR::=${FAIL}}
|
||||
.elif defined(VAR)
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 0 && ${${FAIL}:?then:else}
|
||||
.endif
|
||||
|
||||
.if 0 && ${1:?${FAIL}:${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${0:?${FAIL}:${FAIL}}
|
||||
.endif
|
||||
|
||||
# Before var.c 1.870 from 2021-03-14, the expression ${FAIL} was evaluated
|
||||
# after the loop, when undefining the temporary global loop variable.
|
||||
# Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the
|
||||
# variable name.
|
||||
.if 0 && ${:Uword:@${FAIL}@expr@}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:@var@${FAIL}@}
|
||||
.endif
|
||||
|
||||
# Before var.c,v 1.877 from 2021-03-14, the modifier ':[...]' did not expand
|
||||
# the nested expression ${FAIL} and then tried to parse the unexpanded text,
|
||||
# which failed since '$' is not a valid range character.
|
||||
.if 0 && ${:Uword:[${FAIL}]}
|
||||
.endif
|
||||
|
||||
# Before var.c,v 1.867 from 2021-03-14, the modifier ':_' defined the variable
|
||||
# even though the whole expression should have only been parsed, not
|
||||
# evaluated.
|
||||
.if 0 && ${:Uword:_=VAR}
|
||||
.elif defined(VAR)
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Before var.c,v 1.856 from 2021-03-14, the modifier ':C' did not expand the
|
||||
# nested expression ${FAIL} and then tried to compile the unexpanded text as a
|
||||
# regular expression, which failed both because of the '{FAIL}', which is not
|
||||
# a valid repetition, and because of the '****', which are repeated
|
||||
# repetitions as well.
|
||||
# '${FAIL}'
|
||||
.if 0 && ${:Uword:C,${FAIL}****,,}
|
||||
.endif
|
||||
|
||||
DEFINED= # defined
|
||||
.if 0 && ${DEFINED:D${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:E}
|
||||
.endif
|
||||
|
||||
# As of 2021-03-14, the error 'Invalid time value: ${FAIL}}' is ok since
|
||||
# ':gmtime' does not expand its argument.
|
||||
.if 0 && ${:Uword:gmtime=${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:H}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:hash}
|
||||
.endif
|
||||
|
||||
.if 0 && ${value:L}
|
||||
.endif
|
||||
|
||||
# As of 2021-03-14, the error 'Invalid time value: ${FAIL}}' is ok since
|
||||
# ':localtime' does not expand its argument.
|
||||
.if 0 && ${:Uword:localtime=${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:M${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:N${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:O}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:Ox}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:P}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:Q}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:q}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:R}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:range}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:S,${FAIL},${FAIL},}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:sh}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:T}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:ts/}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:U${FAIL}}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:u}
|
||||
.endif
|
||||
|
||||
.if 0 && ${:Uword:word=replacement}
|
||||
.endif
|
||||
|
||||
# Before var.c 1.875 from 2021-03-14, Var_Parse returned "${FAIL}else" for the
|
||||
# irrelevant right-hand side of the condition, even though this was not
|
||||
# necessary. Since the return value from Var_Parse is supposed to be ignored
|
||||
# anyway, and since it is actually ignored in an overly complicated way,
|
||||
# an empty string suffices.
|
||||
.MAKEFLAGS: -dcpv
|
||||
.if 0 && ${0:?${FAIL}then:${FAIL}else}
|
||||
.endif
|
||||
|
||||
# The ':L' is applied before the ':?' modifier, giving the expression a name
|
||||
# and a value, just to see whether this value gets passed through or whether
|
||||
# the parse-only mode results in an empty string (only visible in the debug
|
||||
# log). As of var.c 1.875 from 2021-03-14, the value of the variable gets
|
||||
# through, even though an empty string would suffice.
|
||||
DEFINED= defined
|
||||
.if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
|
||||
.endif
|
||||
.MAKEFLAGS: -d0
|
||||
|
||||
all:
|
@ -1,7 +1,7 @@
|
||||
Var_Parse: ${:U\$\$\$\$\$\$\$\$} with VARE_WANTRES
|
||||
Applying ${:U...} to "" (VARE_WANTRES, none, VES_UNDEF)
|
||||
Result of ${:U\$\$\$\$\$\$\$\$} is "$$$$$$$$" (VARE_WANTRES, none, VES_DEF)
|
||||
Global:VAR.$$$$$$$$ = dollars
|
||||
Global:.MAKEFLAGS = -r -k -d v -d
|
||||
Global:.MAKEFLAGS = -r -k -d v -d 0
|
||||
Var_Parse: ${:U\$\$\$\$\$\$\$\$} (eval)
|
||||
Evaluating modifier ${:U...} on value "" (eval, undefined)
|
||||
Result of ${:U\$\$\$\$\$\$\$\$} is "$$$$$$$$" (eval, defined)
|
||||
Global: VAR.$$$$$$$$ = dollars
|
||||
Global: .MAKEFLAGS = -r -k -d v -d
|
||||
Global: .MAKEFLAGS = -r -k -d v -d 0
|
||||
exit status 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: var-op-append.mk,v 1.8 2021/02/03 08:40:47 rillig Exp $
|
||||
# $NetBSD: var-op-append.mk,v 1.9 2021/04/04 10:13:09 rillig Exp $
|
||||
#
|
||||
# Tests for the += variable assignment operator, which appends to a variable,
|
||||
# creating it if necessary.
|
||||
@ -26,7 +26,7 @@ VAR+= # empty
|
||||
# '+=' assignment operator. As far as possible, the '+' is interpreted as
|
||||
# part of the assignment operator.
|
||||
#
|
||||
# See Parse_DoVar
|
||||
# See Parse_Var
|
||||
C++= value
|
||||
.if ${C+} != "value" || defined(C++)
|
||||
. error
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: var-op-assign.mk,v 1.7 2020/11/15 20:20:58 rillig Exp $
|
||||
# $NetBSD: var-op-assign.mk,v 1.8 2021/03/15 19:15:04 rillig Exp $
|
||||
#
|
||||
# Tests for the = variable assignment operator, which overwrites an existing
|
||||
# variable or creates it.
|
||||
@ -42,7 +42,7 @@ VAR= new value and \# some $$ special characters # comment
|
||||
# This alone would not produce any side-effects, therefore the variable has
|
||||
# a :!...! modifier that executes a shell command. The :!...! modifier turns
|
||||
# an undefined expression into a defined one, see ApplyModifier_ShellCommand,
|
||||
# the call to ApplyModifiersState_Define.
|
||||
# the call to Expr_Define.
|
||||
#
|
||||
# Since the right-hand side of a '=' assignment is not expanded at the time
|
||||
# when the variable is defined, the first command is not run at all.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user