Merge/update to bmake-20230126

This commit is contained in:
Simon J. Gerraty 2023-01-27 16:33:01 -08:00
commit 4fde40d9b5
114 changed files with 7377 additions and 5424 deletions

View file

@ -1,3 +1,132 @@
2023-01-26 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230126
Merge with NetBSD make, pick up
o variables like .newline and .MAKE.{GID,PID,PPID,UID}
should be read-only.
2023-01-23 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230123
Merge with NetBSD make, pick up
o .[NO]READONLY: for control of read-only variables
o .SYSPATH: for controlling the path searched for makefiles
2023-01-20 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230120
Merge with NetBSD make, pick up
o allow for white-space between command specifiers @+-
o add more details to warning 'Extra targets ignored'
2023-01-12 Simon J Gerraty <sjg@beast.crufty.net>
* machine.sh: leverage os.sh rather than duplicate
also dispence with the $OS.$MACHINE values - we have $HOST_TARGET
for that purpose for the past decade or so.
We invariably get MACHINE and MACHINE_ARCH at runtime anyway.
2023-01-02 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230101
Merge with NetBSD make, pick up
o cleanup comments, inline some LazyBuf_ methods
o unit-tests/ add/improve comments in tests
o make.1: sync list of built-in variables with reality
sort list of built-in variables
reduce indentation of the long list of variable names
use consistent markup for boolean flags
move description of .MAKE.MODE below the .MAKE.META block
clarify in which case an expression may omit braces
2022-11-08 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20221024
Merge with NetBSD make, pick up
o change return type of unlink_file back to int
2022-10-07 Simon J Gerraty <sjg@beast.crufty.net>
* Makefile: Darwin and Linux can handle MANTARGET=man
2022-09-28 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220928
Merge with NetBSD make, pick up
o fix more ignored returns from snprintf
o compile with higher warnings
2022-09-26 Simon J Gerraty <sjg@beast.crufty.net>
* main.c meta.c: do not ignore return from snprintf
* meta.c strlcpy.c: we need prototype for strlcpy
* sigcompat.c: fix unused function warnings
2022-09-24 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220924
Merge with NetBSD make, pick up
o fix bug in .break reset of conditional depth
o overhaul and simplify tracking of conditional depth
2022-09-17 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220912
Merge with NetBSD make, pick up
o man page updates
2022-09-09 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220909
Merge with NetBSD make, pick up
o update unit-tests to handle deprecation of egrep
o cond.c: add more details to error message for numeric comparison
* configure.in: allow for deprecation of egrep
* Makefile: Linux can handle MANTARGET=man
2022-09-03 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220903
Merge with NetBSD make, pick up
o job.c: fix handling of null bytes in output
2022-09-02 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220902
Merge with NetBSD make, pick up
o Allow .break to terminate a .for loop early
2022-09-01 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220901
Merge with NetBSD make, pick up
o var.c: fix out-of-bounds errors when parsing
2022-08-24 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220824
Merge with NetBSD make, pick up
o var.c: revert change to modifier parsing that breaks
shell variable references within ':@var@body@'
o adjust unit-tests
2022-08-18 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220818
Merge with NetBSD make, pick up
o fix exit status for '-q' (since 1994)
2022-08-08 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220808
Merge with NetBSD make, pick up
o var.c: fix parsing of modifiers containing unbalanced subexpressions
extract parsing of ':D' and ':U' modifiers into separate function
2022-07-26 Simon J Gerraty <sjg@beast.crufty.net> 2022-07-26 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20220726 * VERSION (_MAKE_VERSION): 20220726

View file

@ -322,6 +322,8 @@ unit-tests/directive-export-literal.exp
unit-tests/directive-export-literal.mk unit-tests/directive-export-literal.mk
unit-tests/directive-export.exp unit-tests/directive-export.exp
unit-tests/directive-export.mk unit-tests/directive-export.mk
unit-tests/directive-for-break.exp
unit-tests/directive-for-break.mk
unit-tests/directive-for-empty.exp unit-tests/directive-for-empty.exp
unit-tests/directive-for-empty.mk unit-tests/directive-for-empty.mk
unit-tests/directive-for-errors.exp unit-tests/directive-for-errors.exp
@ -402,8 +404,8 @@ unit-tests/impsrc.exp
unit-tests/impsrc.mk unit-tests/impsrc.mk
unit-tests/include-main.exp unit-tests/include-main.exp
unit-tests/include-main.mk unit-tests/include-main.mk
unit-tests/include-sub.mk unit-tests/include-sub.inc
unit-tests/include-subsub.mk unit-tests/include-subsub.inc
unit-tests/job-flags.exp unit-tests/job-flags.exp
unit-tests/job-flags.mk unit-tests/job-flags.mk
unit-tests/job-output-long-lines.exp unit-tests/job-output-long-lines.exp
@ -650,6 +652,8 @@ unit-tests/var-op-sunsh.exp
unit-tests/var-op-sunsh.mk unit-tests/var-op-sunsh.mk
unit-tests/var-op.exp unit-tests/var-op.exp
unit-tests/var-op.mk unit-tests/var-op.mk
unit-tests/var-readonly.exp
unit-tests/var-readonly.mk
unit-tests/var-recursive.exp unit-tests/var-recursive.exp
unit-tests/var-recursive.mk unit-tests/var-recursive.mk
unit-tests/var-scope-cmdline.exp unit-tests/var-scope-cmdline.exp

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.120 2022/07/26 23:02:54 sjg Exp $ # $Id: Makefile,v 1.122 2022/10/08 02:53:30 sjg Exp $
PROG= bmake PROG= bmake
@ -88,7 +88,7 @@ OS := ${.MAKE.OS:U${uname -s:L:sh}}
# are we 4.4BSD ? # are we 4.4BSD ?
isBSD44:=${BSD44_LIST:M${OS}} isBSD44:=${BSD44_LIST:M${OS}}
.if ${isBSD44} == "" .if ${isBSD44} == "" && ${OS:NDarwin:NLinux} != ""
MANTARGET= cat MANTARGET= cat
INSTALL?=${srcdir}/install-sh INSTALL?=${srcdir}/install-sh
.if ${MACHINE} == "sun386" .if ${MACHINE} == "sun386"

View file

@ -9,6 +9,7 @@ CC= @CC@
@force_machine_arch@MACHINE_ARCH?= @machine_arch@ @force_machine_arch@MACHINE_ARCH?= @machine_arch@
DEFAULT_SYS_PATH?= @default_sys_path@ DEFAULT_SYS_PATH?= @default_sys_path@
EGREP = @egrep@
CPPFLAGS+= @CPPFLAGS@ CPPFLAGS+= @CPPFLAGS@
CFLAGS+= ${CPPFLAGS} @DEFS@ CFLAGS+= ${CPPFLAGS} @DEFS@
LDFLAGS+= @LDFLAGS@ LDFLAGS+= @LDFLAGS@

View file

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

View file

@ -1,4 +1,4 @@
/* $NetBSD: arch.c,v 1.210 2022/01/15 18:34:41 rillig Exp $ */ /* $NetBSD: arch.c,v 1.212 2022/12/07 10:28:48 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -147,7 +147,7 @@ struct ar_hdr {
#include "dir.h" #include "dir.h"
/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */ /* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: arch.c,v 1.210 2022/01/15 18:34:41 rillig Exp $"); MAKE_RCSID("$NetBSD: arch.c,v 1.212 2022/12/07 10:28:48 rillig Exp $");
typedef struct List ArchList; typedef struct List ArchList;
typedef struct ListNode ArchListNode; typedef struct ListNode ArchListNode;
@ -353,11 +353,10 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
*/ */
/* /*
* If member contains variables, try and substitute for them. * If member contains variables, try and substitute for them.
* This will slow down archive specs with dynamic sources, of * This slows down archive specs with dynamic sources, since
* course, since we'll be (non-)substituting them three * they are (non-)substituted three times, but we need to do
* times, but them's the breaks -- we need to do this since * this since SuffExpandChildren calls us, otherwise we could
* SuffExpandChildren calls us, otherwise we could assume the * assume the substitutions would be taken care of later.
* thing would be taken care of later.
*/ */
if (doSubst) { if (doSubst) {
char *fullName; char *fullName;
@ -594,7 +593,8 @@ ArchStatMember(const char *archive, const char *member, bool addToCache)
if (strncmp(memName, AR_EFMT1, sizeof AR_EFMT1 - 1) == 0 && if (strncmp(memName, AR_EFMT1, sizeof AR_EFMT1 - 1) == 0 &&
ch_isdigit(memName[sizeof AR_EFMT1 - 1])) { ch_isdigit(memName[sizeof AR_EFMT1 - 1])) {
size_t elen = atoi(memName + sizeof AR_EFMT1 - 1); size_t elen = (size_t)atoi(
memName + sizeof AR_EFMT1 - 1);
if (elen > MAXPATHLEN) if (elen > MAXPATHLEN)
goto badarch; goto badarch;
@ -836,7 +836,7 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
if (strncmp(out_arh->AR_NAME, AR_EFMT1, sizeof AR_EFMT1 - 1) == if (strncmp(out_arh->AR_NAME, AR_EFMT1, sizeof AR_EFMT1 - 1) ==
0 && 0 &&
(ch_isdigit(out_arh->AR_NAME[sizeof AR_EFMT1 - 1]))) { (ch_isdigit(out_arh->AR_NAME[sizeof AR_EFMT1 - 1]))) {
size_t elen = atoi( size_t elen = (size_t)atoi(
&out_arh->AR_NAME[sizeof AR_EFMT1 - 1]); &out_arh->AR_NAME[sizeof AR_EFMT1 - 1]);
char ename[MAXPATHLEN + 1]; char ename[MAXPATHLEN + 1];

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 84 KiB

View file

@ -1,4 +1,4 @@
/* $NetBSD: compat.c,v 1.240 2022/05/07 17:49:47 rillig Exp $ */ /* $NetBSD: compat.c,v 1.244 2023/01/17 21:35:19 christos Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -94,15 +94,15 @@
#include "pathnames.h" #include "pathnames.h"
/* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */ /* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: compat.c,v 1.240 2022/05/07 17:49:47 rillig Exp $"); MAKE_RCSID("$NetBSD: compat.c,v 1.244 2023/01/17 21:35:19 christos Exp $");
static GNode *curTarg = NULL; static GNode *curTarg = NULL;
static pid_t compatChild; static pid_t compatChild;
static int compatSigno; static int compatSigno;
/* /*
* CompatDeleteTarget -- delete the file of a failed, interrupted, or * Delete the file of a failed, interrupted, or otherwise duffed target,
* otherwise duffed target if not inhibited by .PRECIOUS. * unless inhibited by .PRECIOUS.
*/ */
static void static void
CompatDeleteTarget(GNode *gn) CompatDeleteTarget(GNode *gn)
@ -110,7 +110,7 @@ CompatDeleteTarget(GNode *gn)
if (gn != NULL && !GNode_IsPrecious(gn)) { if (gn != NULL && !GNode_IsPrecious(gn)) {
const char *file = GNode_VarTarget(gn); const char *file = GNode_VarTarget(gn);
if (!opts.noExecute && unlink_file(file)) { if (!opts.noExecute && unlink_file(file) == 0) {
Error("*** %s removed", file); Error("*** %s removed", file);
} }
} }
@ -283,7 +283,8 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
doIt = true; doIt = true;
if (shellName == NULL) /* we came here from jobs */ if (shellName == NULL) /* we came here from jobs */
Shell_Init(); Shell_Init();
} else } else if (!ch_isspace(*cmd))
/* Ignore whitespace for compatibility with gnu make */
break; break;
cmd++; cmd++;
} }
@ -573,7 +574,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
* to tell him/her "yes". * to tell him/her "yes".
*/ */
DEBUG0(MAKE, "out-of-date.\n"); DEBUG0(MAKE, "out-of-date.\n");
if (opts.query) if (opts.query && gn != Targ_GetEndNode())
exit(1); exit(1);
/* /*

View file

@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.334 2022/04/15 09:33:20 rillig Exp $ */ /* $NetBSD: cond.c,v 1.342 2022/09/24 16:13:48 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -81,12 +81,9 @@
* of one of the .if directives or the condition in a * of one of the .if directives or the condition in a
* ':?then:else' variable modifier. * ':?then:else' variable modifier.
* *
* Cond_save_depth * Cond_EndFile
* Cond_restore_depth * At the end of reading a makefile, ensure that the
* Save and restore the nesting of the conditions, at * conditional directives are well-balanced.
* the start and end of including another makefile, to
* ensure that in each makefile the conditional
* directives are well-balanced.
*/ */
#include <errno.h> #include <errno.h>
@ -95,7 +92,7 @@
#include "dir.h" #include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: cond.c,v 1.334 2022/04/15 09:33:20 rillig Exp $"); MAKE_RCSID("$NetBSD: cond.c,v 1.342 2022/09/24 16:13:48 rillig Exp $");
/* /*
* Conditional expressions conform to this grammar: * Conditional expressions conform to this grammar:
@ -178,8 +175,7 @@ typedef struct CondParser {
static CondResult CondParser_Or(CondParser *par, bool); static CondResult CondParser_Or(CondParser *par, bool);
static unsigned int cond_depth = 0; /* current .if nesting level */ unsigned int cond_depth = 0; /* current .if nesting level */
static unsigned int cond_min_depth = 0; /* depth at makefile open */
/* Names for ComparisonOp. */ /* Names for ComparisonOp. */
static const char opname[][3] = { "<", "<=", ">", ">=", "==", "!=" }; static const char opname[][3] = { "<", "<=", ">", ">=", "==", "!=" };
@ -570,10 +566,10 @@ EvalCompareNum(double lhs, ComparisonOp op, double rhs)
return lhs > rhs; return lhs > rhs;
case GE: case GE:
return lhs >= rhs; return lhs >= rhs;
case NE: case EQ:
return lhs != rhs;
default:
return lhs == rhs; return lhs == rhs;
default:
return lhs != rhs;
} }
} }
@ -583,7 +579,9 @@ EvalCompareStr(CondParser *par, const char *lhs,
{ {
if (op != EQ && op != NE) { if (op != EQ && op != NE) {
Parse_Error(PARSE_FATAL, Parse_Error(PARSE_FATAL,
"String comparison operator must be either == or !="); "Comparison with '%s' requires both operands "
"'%s' and '%s' to be numeric",
opname[op], lhs, rhs);
par->printedError = true; par->printedError = true;
return TOK_ERROR; return TOK_ERROR;
} }
@ -1135,7 +1133,7 @@ Cond_EvalLine(const char *line)
"The .endif directive does not take arguments"); "The .endif directive does not take arguments");
} }
if (cond_depth == cond_min_depth) { if (cond_depth == CurFile_CondMinDepth()) {
Parse_Error(PARSE_FATAL, "if-less endif"); Parse_Error(PARSE_FATAL, "if-less endif");
return CR_TRUE; return CR_TRUE;
} }
@ -1165,7 +1163,7 @@ Cond_EvalLine(const char *line)
"The .else directive " "The .else directive "
"does not take arguments"); "does not take arguments");
if (cond_depth == cond_min_depth) { if (cond_depth == CurFile_CondMinDepth()) {
Parse_Error(PARSE_FATAL, "if-less else"); Parse_Error(PARSE_FATAL, "if-less else");
return CR_TRUE; return CR_TRUE;
} }
@ -1200,7 +1198,7 @@ Cond_EvalLine(const char *line)
return CR_ERROR; return CR_ERROR;
if (isElif) { if (isElif) {
if (cond_depth == cond_min_depth) { if (cond_depth == CurFile_CondMinDepth()) {
Parse_Error(PARSE_FATAL, "if-less elif"); Parse_Error(PARSE_FATAL, "if-less elif");
return CR_TRUE; return CR_TRUE;
} }
@ -1254,24 +1252,13 @@ Cond_EvalLine(const char *line)
} }
void void
Cond_restore_depth(unsigned int saved_depth) Cond_EndFile(void)
{ {
unsigned int open_conds = cond_depth - cond_min_depth; unsigned int open_conds = cond_depth - CurFile_CondMinDepth();
if (open_conds != 0 || saved_depth > cond_depth) { if (open_conds != 0) {
Parse_Error(PARSE_FATAL, "%u open conditional%s", Parse_Error(PARSE_FATAL, "%u open conditional%s",
open_conds, open_conds == 1 ? "" : "s"); open_conds, open_conds == 1 ? "" : "s");
cond_depth = cond_min_depth; cond_depth = CurFile_CondMinDepth();
} }
cond_min_depth = saved_depth;
}
unsigned int
Cond_save_depth(void)
{
unsigned int depth = cond_min_depth;
cond_min_depth = cond_depth;
return depth;
} }

View file

@ -71,8 +71,8 @@
/* Define to 1 if the system has the type `long long int'. */ /* Define to 1 if the system has the type `long long int'. */
#undef HAVE_LONG_LONG_INT #undef HAVE_LONG_LONG_INT
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <minix/config.h> header file. */
#undef HAVE_MEMORY_H #undef HAVE_MINIX_CONFIG_H
/* Define to 1 if you have the `mmap' function. */ /* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP #undef HAVE_MMAP
@ -140,6 +140,9 @@
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H #undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */ /* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H #undef HAVE_STDLIB_H
@ -176,13 +179,6 @@
/* Define to 1 if you have the `strtoul' function. */ /* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL #undef HAVE_STRTOUL
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
#undef HAVE_ST_RDEV
/* Define to 1 if you have the `sysctl' function. */ /* Define to 1 if you have the `sysctl' function. */
#undef HAVE_SYSCTL #undef HAVE_SYSCTL
@ -263,6 +259,9 @@
/* Define to 1 if you have the `warnx' function. */ /* Define to 1 if you have the `warnx' function. */
#undef HAVE_WARNX #undef HAVE_WARNX
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define to 1 if `fork' works. */ /* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK #undef HAVE_WORKING_FORK
@ -290,18 +289,14 @@
/* Define to the version of this package. */ /* Define to the version of this package. */
#undef PACKAGE_VERSION #undef PACKAGE_VERSION
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ /* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN #undef STAT_MACROS_BROKEN
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS #undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your <sys/time.h> declares `struct tm'. */ /* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME #undef TM_IN_SYS_TIME
@ -309,21 +304,87 @@
#ifndef _ALL_SOURCE #ifndef _ALL_SOURCE
# undef _ALL_SOURCE # undef _ALL_SOURCE
#endif #endif
/* Enable general extensions on macOS. */
#ifndef _DARWIN_C_SOURCE
# undef _DARWIN_C_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Enable GNU extensions on systems that have them. */ /* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
# undef _GNU_SOURCE # undef _GNU_SOURCE
#endif #endif
/* Enable threading extensions on Solaris. */ /* Enable X/Open compliant socket functions that do not require linking
with -lxnet on HP-UX 11.11. */
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
# undef _HPUX_ALT_XOPEN_SOCKET_API
#endif
/* Identify the host operating system as Minix.
This macro does not affect the system headers' behavior.
A future release of Autoconf may stop defining this macro. */
#ifndef _MINIX
# undef _MINIX
#endif
/* Enable general extensions on NetBSD.
Enable NetBSD compatibility extensions on Minix. */
#ifndef _NETBSD_SOURCE
# undef _NETBSD_SOURCE
#endif
/* Enable OpenBSD compatibility extensions on NetBSD.
Oddly enough, this does nothing on OpenBSD. */
#ifndef _OPENBSD_SOURCE
# undef _OPENBSD_SOURCE
#endif
/* Define to 1 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_SOURCE
# undef _POSIX_SOURCE
#endif
/* Define to 2 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_1_SOURCE
# undef _POSIX_1_SOURCE
#endif
/* Enable POSIX-compatible threading on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS #ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS
#endif #endif
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
# undef __STDC_WANT_IEC_60559_BFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
#ifndef __STDC_WANT_LIB_EXT2__
# undef __STDC_WANT_LIB_EXT2__
#endif
/* Enable extensions specified by ISO/IEC 24747:2009. */
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
# undef __STDC_WANT_MATH_SPEC_FUNCS__
#endif
/* Enable extensions on HP NonStop. */ /* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE #ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE # undef _TANDEM_SOURCE
#endif #endif
/* Enable general extensions on Solaris. */ /* Enable X/Open extensions. Define to 500 only if necessary
#ifndef __EXTENSIONS__ to make mbstate_t available. */
# undef __EXTENSIONS__ #ifndef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
#endif #endif
@ -339,16 +400,6 @@
# endif # endif
#endif #endif
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, /* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */ #define below would cause a syntax error. */
@ -376,7 +427,7 @@
/* Define to `long int' if <sys/types.h> does not define. */ /* Define to `long int' if <sys/types.h> does not define. */
#undef off_t #undef off_t
/* Define to `int' if <sys/types.h> does not define. */ /* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t #undef pid_t
/* type that signal handlers can safely frob */ /* type that signal handlers can safely frob */

5241
contrib/bmake/configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,11 @@
dnl dnl
dnl RCSid: dnl RCSid:
dnl $Id: configure.in,v 1.85 2021/10/23 20:57:08 sjg Exp $ dnl $Id: configure.in,v 1.87 2022/09/09 20:00:53 sjg Exp $
dnl dnl
dnl Process this file with autoconf to produce a configure script dnl Process this file with autoconf to produce a configure script
dnl dnl
AC_PREREQ(2.50) AC_PREREQ([2.71])
AC_INIT([bmake], [20211020], [sjg@NetBSD.org]) AC_INIT([bmake],[20220909],[sjg@NetBSD.org])
AC_CONFIG_HEADERS(config.h) AC_CONFIG_HEADERS(config.h)
dnl make srcdir absolute dnl make srcdir absolute
@ -159,8 +159,6 @@ dnl see _EXTENSIONS_ we use it.
AC_USE_SYSTEM_EXTENSIONS AC_USE_SYSTEM_EXTENSIONS
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC AC_PROG_CC
AC_PROG_CC_C99
dnl AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL AC_PROG_INSTALL
dnl Executable suffix - normally empty; .exe on os2. dnl Executable suffix - normally empty; .exe on os2.
AC_SUBST(ac_exe_suffix)dnl AC_SUBST(ac_exe_suffix)dnl
@ -179,8 +177,6 @@ fi
echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6 echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
AC_SUBST(bmake_path_max)dnl AC_SUBST(bmake_path_max)dnl
dnl dnl
dnl AC_C_CROSS
dnl
dnl if type does not work which(1) had better! dnl if type does not work which(1) had better!
dnl note we cannot rely on type returning non-zero on failure dnl note we cannot rely on type returning non-zero on failure
if (type cat) > /dev/null 2>&1; then if (type cat) > /dev/null 2>&1; then
@ -254,8 +250,15 @@ AC_TYPE_OFF_T
AC_TYPE_PID_T AC_TYPE_PID_T
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_TYPE_UINT32_T AC_TYPE_UINT32_T
AC_DECL_SYS_SIGLIST AC_CHECK_DECLS([sys_siglist],[],[],[#include <signal.h>
AC_HEADER_TIME /* NetBSD declares sys_siglist in unistd.h. */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
])
AC_CHECK_HEADERS_ONCE([sys/time.h])
AC_STRUCT_TM AC_STRUCT_TM
dnl we need sig_atomic_t dnl we need sig_atomic_t
@ -269,8 +272,7 @@ AC_CHECK_TYPES([sig_atomic_t],[],[],
]) ])
dnl Checks for library functions. dnl Checks for library functions.
AC_TYPE_SIGNAL AC_FUNC_FORK
AC_FUNC_VFORK
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_FUNC_WAIT3 AC_FUNC_WAIT3
dnl Keep this list sorted dnl Keep this list sorted
@ -334,7 +336,6 @@ dnl
dnl Structures dnl Structures
dnl dnl
AC_HEADER_STAT AC_HEADER_STAT
AC_STRUCT_ST_RDEV
dnl dnl
echo "checking if compiler supports __func__" >&6 echo "checking if compiler supports __func__" >&6
AC_LANG(C) AC_LANG(C)
@ -373,7 +374,7 @@ machine_arch=MACHINE_ARCH
EOF EOF
default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep machine= | tr -d ' "'` grep machine= | tr -d ' "'`
rm -rf conftest* rm -rf conftest*
if test "$default_machine"; then if test "$default_machine"; then
eval "$default_machine" eval "$default_machine"
@ -515,6 +516,13 @@ AC_DEFINE_UNQUOTED(DEFSHELL_PATH, "$defshell_path", Path of default shell)
;; ;;
esac esac
dnl dnl
dnl Some systems have deprecated egrep in favor of grep -E
case "`echo bmake | egrep 'a|b' 2>&1`" in
bmake) egrep=egrep;;
*) egrep='grep -E';;
esac
dnl
AC_SUBST(egrep)
AC_SUBST(machine) AC_SUBST(machine)
AC_SUBST(force_machine) AC_SUBST(force_machine)
AC_SUBST(machine_arch) AC_SUBST(machine_arch)
@ -546,7 +554,8 @@ $srcdir/obj*) # make sure we put unit-tests/Makefile.config in the right place
;; ;;
esac esac
AC_OUTPUT($bm_outfiles) AC_CONFIG_FILES([$bm_outfiles])
AC_OUTPUT
cat <<EOF cat <<EOF
You can now run You can now run

View file

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.279 2022/05/07 21:19:43 rillig Exp $ */ /* $NetBSD: dir.c,v 1.280 2023/01/24 00:24:02 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -138,7 +138,7 @@
#include "job.h" #include "job.h"
/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */ /* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: dir.c,v 1.279 2022/05/07 21:19:43 rillig Exp $"); MAKE_RCSID("$NetBSD: dir.c,v 1.280 2023/01/24 00:24:02 sjg Exp $");
/* /*
* A search path is a list of CachedDir structures. A CachedDir has in it the * A search path is a list of CachedDir structures. A CachedDir has in it the
@ -577,6 +577,21 @@ Dir_SetPATH(void)
} }
} }
void
Dir_SetSYSPATH(void)
{
CachedDirListNode *ln;
Var_ReadOnly(".SYSPATH", false);
Global_Delete(".SYSPATH");
for (ln = sysIncPath->dirs.first; ln != NULL; ln = ln->next) {
CachedDir *dir = ln->datum;
Global_Append(".SYSPATH", dir->name);
}
Var_ReadOnly(".SYSPATH", true);
}
/* /*
* See if the given name has any wildcard characters in it and all braces and * See if the given name has any wildcard characters in it and all braces and
* brackets are properly balanced. * brackets are properly balanced.

View file

@ -1,4 +1,4 @@
/* $NetBSD: dir.h,v 1.46 2021/12/15 12:08:25 rillig Exp $ */ /* $NetBSD: dir.h,v 1.47 2023/01/24 00:24:02 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -82,6 +82,7 @@ void Dir_InitCur(const char *);
void Dir_InitDot(void); void Dir_InitDot(void);
void Dir_End(void); void Dir_End(void);
void Dir_SetPATH(void); void Dir_SetPATH(void);
void Dir_SetSYSPATH(void);
bool Dir_HasWildcards(const char *) MAKE_ATTR_USE; bool Dir_HasWildcards(const char *) MAKE_ATTR_USE;
void SearchPath_Expand(SearchPath *, const char *, StringList *); void SearchPath_Expand(SearchPath *, const char *, StringList *);
char *Dir_FindFile(const char *, SearchPath *) MAKE_ATTR_USE; char *Dir_FindFile(const char *, SearchPath *) MAKE_ATTR_USE;

View file

@ -1,6 +1,13 @@
: :
re=$1; shift re=$1; shift
# some Linux systems have deprecated egrep in favor of grep -E
# but not everyone supports that
case "`echo bmake | egrep 'a|b' 2>&1`" in
bmake) ;;
*) egrep() { grep -E "$@"; }
esac
for lib in $* for lib in $*
do do
found=`nm $lib | egrep "$re"` found=`nm $lib | egrep "$re"`

View file

@ -1,4 +1,4 @@
/* $NetBSD: for.c,v 1.168 2022/06/12 16:09:21 rillig Exp $ */ /* $NetBSD: for.c,v 1.170 2022/09/03 00:50:07 rillig Exp $ */
/* /*
* Copyright (c) 1992, The Regents of the University of California. * Copyright (c) 1992, The Regents of the University of California.
@ -58,7 +58,7 @@
#include "make.h" #include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: for.c,v 1.168 2022/06/12 16:09:21 rillig Exp $"); MAKE_RCSID("$NetBSD: for.c,v 1.170 2022/09/03 00:50:07 rillig Exp $");
typedef struct ForLoop { typedef struct ForLoop {
@ -490,6 +490,13 @@ For_NextIteration(ForLoop *f, Buffer *body)
return true; return true;
} }
/* Break out of the .for loop. */
void
For_Break(ForLoop *f)
{
f->nextItem = (unsigned int)f->items.len;
}
/* Run the .for loop, imitating the actions of an include file. */ /* Run the .for loop, imitating the actions of an include file. */
void void
For_Run(unsigned headLineno, unsigned bodyReadLines) For_Run(unsigned headLineno, unsigned bodyReadLines)

View file

@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.453 2022/05/07 08:01:20 rillig Exp $ */ /* $NetBSD: job.c,v 1.457 2023/01/17 21:35:19 christos Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -155,7 +155,7 @@
#include "trace.h" #include "trace.h"
/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: job.c,v 1.453 2022/05/07 08:01:20 rillig Exp $"); MAKE_RCSID("$NetBSD: job.c,v 1.457 2023/01/17 21:35:19 christos Exp $");
/* /*
* A shell defines how the commands are run. All commands for a target are * A shell defines how the commands are run. All commands for a target are
@ -541,7 +541,7 @@ JobDeleteTarget(GNode *gn)
return; return;
file = GNode_Path(gn); file = GNode_Path(gn);
if (unlink_file(file)) if (unlink_file(file) == 0)
Error("*** %s removed", file); Error("*** %s removed", file);
} }
@ -761,7 +761,8 @@ ParseCommandFlags(char **pp, CommandFlags *out_cmdFlags)
out_cmdFlags->ignerr = true; out_cmdFlags->ignerr = true;
else if (*p == '+') else if (*p == '+')
out_cmdFlags->always = true; out_cmdFlags->always = true;
else else if (!ch_isspace(*p))
/* Ignore whitespace for compatibility with gnu make */
break; break;
p++; p++;
} }
@ -1868,46 +1869,36 @@ CollectOutput(Job *job, bool finish)
if (nRead < 0) { if (nRead < 0) {
if (errno == EAGAIN) if (errno == EAGAIN)
return; return;
if (DEBUG(JOB)) { if (DEBUG(JOB))
perror("CollectOutput(piperead)"); perror("CollectOutput(piperead)");
}
nr = 0; nr = 0;
} else { } else
nr = (size_t)nRead; nr = (size_t)nRead;
}
if (nr == 0)
finish = false; /* stop looping */
/* /*
* If we hit the end-of-file (the job is dead), we must flush its * If we hit the end-of-file (the job is dead), we must flush its
* remaining output, so pretend we read a newline if there's any * remaining output, so pretend we read a newline if there's any
* output remaining in the buffer. * output remaining in the buffer.
* Also clear the 'finish' flag so we stop looping.
*/ */
if (nr == 0 && job->curPos != 0) { if (nr == 0 && job->curPos != 0) {
job->outBuf[job->curPos] = '\n'; job->outBuf[job->curPos] = '\n';
nr = 1; nr = 1;
finish = false;
} else if (nr == 0) {
finish = false;
} }
/*
* Look for the last newline in the bytes we just got. If there is
* one, break out of the loop with 'i' as its index and gotNL set
* true.
*/
max = job->curPos + nr; max = job->curPos + nr;
for (i = job->curPos; i < max; i++)
if (job->outBuf[i] == '\0')
job->outBuf[i] = ' ';
/* Look for the last newline in the bytes we just got. */
for (i = job->curPos + nr - 1; for (i = job->curPos + nr - 1;
i >= job->curPos && i != (size_t)-1; i--) { i >= job->curPos && i != (size_t)-1; i--) {
if (job->outBuf[i] == '\n') { if (job->outBuf[i] == '\n') {
gotNL = true; gotNL = true;
break; break;
} else if (job->outBuf[i] == '\0') {
/*
* FIXME: The null characters are only replaced with
* space _after_ the last '\n'. Everywhere else they
* hide the rest of the command output.
*/
job->outBuf[i] = ' ';
} }
} }

View file

@ -1,10 +1,12 @@
: :
# derrived from /etc/rc_d/os.sh # This is mostly redundant.
# These days I use the pseudo machine "host" when building for host
# and $TARGET_HOST for its objdir
# RCSid: # RCSid:
# $Id: machine.sh,v 1.18 2017/08/13 19:11:28 sjg Exp $ # $Id: machine.sh,v 1.19 2023/01/17 18:30:21 sjg Exp $
# #
# @(#) Copyright (c) 1994-2002 Simon J. Gerraty # @(#) Copyright (c) 1994-2023 Simon J. Gerraty
# #
# This file is provided in the hope that it will # This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY. # be of use. There is absolutely NO WARRANTY.
@ -17,82 +19,23 @@
# sjg@crufty.net # sjg@crufty.net
# #
OS=`uname` # leverage os.sh
OSREL=`uname -r` Mydir=`dirname $0`
OSMAJOR=`IFS=.; set $OSREL; echo $1` . $Mydir/os.sh
machine=`uname -p 2>/dev/null || uname -m`
MACHINE=
# there is at least one case of `uname -p` outputting
# a bunch of usless drivel
case "$machine" in
unknown|*[!A-Za-z0-9_-]*)
machine=`uname -m`
;;
esac
# Great! Solaris keeps moving arch(1)
# we need this here, and it is not always available...
Which() {
# some shells cannot correctly handle `IFS`
# in conjunction with the for loop.
_dirs=`IFS=:; echo ${2:-$PATH}`
for d in $_dirs
do
test -x $d/$1 && { echo $d/$1; break; }
done
}
# some further overrides - mostly for MACHINE_ACH
case $OS in case $OS in
AIX) # from http://gnats.netbsd.org/29386 AIX) # from http://gnats.netbsd.org/29386
OSMAJOR=`uname -v`
OSMINOR=`uname -r`
MACHINE=$OS$OSMAJOR.$OSMINOR
MACHINE_ARCH=`bootinfo -T` MACHINE_ARCH=`bootinfo -T`
;; ;;
OpenBSD)
MACHINE=$OS$OSMAJOR.$machine
arch=`Which arch /usr/bin:/usr/ucb:$PATH`
MACHINE_ARCH=`$arch -s`;
;;
Bitrig) Bitrig)
MACHINE=$OS$OSMAJOR.$machine MACHINE_ARCH=$MACHINE;
MACHINE_ARCH=`uname -m`;
;;
*BSD)
MACHINE=$OS$OSMAJOR.$machine
;;
SunOS)
arch=`Which arch /usr/bin:/usr/ucb:$PATH`
test "$arch" && machine_arch=`$arch`
case "$OSREL" in
4.0*) MACHINE_ARCH=$machine_arch MACHINE=$machine_arch;;
4*) MACHINE_ARCH=$machine_arch;;
esac
;; ;;
HP-UX) HP-UX)
MACHINE_ARCH=`IFS="/-."; set $machine; echo $1` MACHINE_ARCH=`IFS="/-."; set $MACHINE; echo $1`
;; ;;
Interix)
MACHINE=i386
MACHINE_ARCH=i386
;;
UnixWare)
OSREL=`uname -v`
OSMAJOR=`IFS=.; set $OSREL; echo $1`
MACHINE_ARCH=`uname -m`
;;
Linux)
case "$machine" in
i?86) MACHINE_ARCH=i386;;# does anyone really care about 686 vs 586?
esac
;;
esac esac
MACHINE=${MACHINE:-$OS$OSMAJOR}
MACHINE_ARCH=${MACHINE_ARCH:-$machine}
( (
case "$0" in case "$0" in
arch*) echo $MACHINE_ARCH;; arch*) echo $MACHINE_ARCH;;
@ -103,4 +46,4 @@ arch*) echo $MACHINE_ARCH;;
esac esac
;; ;;
esac esac
) | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ) | toLower

View file

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.582 2022/05/07 17:49:47 rillig Exp $ */ /* $NetBSD: main.c,v 1.589 2023/01/26 20:48:17 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -111,7 +111,7 @@
#include "trace.h" #include "trace.h"
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */ /* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: main.c,v 1.582 2022/05/07 17:49:47 rillig Exp $"); MAKE_RCSID("$NetBSD: main.c,v 1.589 2023/01/26 20:48:17 sjg Exp $");
#if defined(MAKE_NATIVE) && !defined(lint) #if defined(MAKE_NATIVE) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
"The Regents of the University of California. " "The Regents of the University of California. "
@ -432,6 +432,7 @@ MainParseArgSysInc(const char *argvalue)
} }
Global_Append(MAKEFLAGS, "-m"); Global_Append(MAKEFLAGS, "-m");
Global_Append(MAKEFLAGS, argvalue); Global_Append(MAKEFLAGS, argvalue);
Dir_SetSYSPATH();
} }
static bool static bool
@ -722,8 +723,10 @@ Main_SetObjdir(bool writable, const char *fmt, ...)
va_end(ap); va_end(ap);
if (path[0] != '/') { if (path[0] != '/') {
snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path); if (snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path) <= MAXPATHLEN)
path = buf2; path = buf2;
else
return false;
} }
/* look for the directory and try to chdir there */ /* look for the directory and try to chdir there */
@ -1370,19 +1373,19 @@ main_Init(int argc, char **argv)
*/ */
Targ_Init(); Targ_Init();
Var_Init(); Var_Init();
Global_Set(".MAKE.OS", utsname.sysname); Global_Set_ReadOnly(".MAKE.OS", utsname.sysname);
Global_Set("MACHINE", machine); Global_Set("MACHINE", machine);
Global_Set("MACHINE_ARCH", machine_arch); Global_Set("MACHINE_ARCH", machine_arch);
#ifdef MAKE_VERSION #ifdef MAKE_VERSION
Global_Set("MAKE_VERSION", MAKE_VERSION); Global_Set("MAKE_VERSION", MAKE_VERSION);
#endif #endif
Global_Set(".newline", "\n"); /* handy for :@ loops */ Global_Set_ReadOnly(".newline", "\n"); /* handy for :@ loops */
#ifndef MAKEFILE_PREFERENCE_LIST #ifndef MAKEFILE_PREFERENCE_LIST
/* This is the traditional preference for makefiles. */ /* This is the traditional preference for makefiles. */
# define MAKEFILE_PREFERENCE_LIST "makefile Makefile" # define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
#endif #endif
Global_Set(MAKE_MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST); Global_Set(MAKE_MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST);
Global_Set(MAKE_DEPENDFILE, ".depend"); Global_Set(".MAKE.DEPENDFILE", ".depend");
CmdOpts_Init(); CmdOpts_Init();
allPrecious = false; /* Remove targets when interrupted */ allPrecious = false; /* Remove targets when interrupted */
@ -1410,7 +1413,7 @@ main_Init(int argc, char **argv)
Global_Set(MAKEOVERRIDES, ""); Global_Set(MAKEOVERRIDES, "");
Global_Set("MFLAGS", ""); Global_Set("MFLAGS", "");
Global_Set(".ALLTARGETS", ""); Global_Set(".ALLTARGETS", "");
Var_Set(SCOPE_CMDLINE, MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV); Var_Set(SCOPE_CMDLINE, ".MAKE.LEVEL.ENV", MAKE_LEVEL_ENV);
/* Set some other useful variables. */ /* Set some other useful variables. */
{ {
@ -1422,13 +1425,13 @@ main_Init(int argc, char **argv)
snprintf(buf, sizeof buf, "%d", makelevel); snprintf(buf, sizeof buf, "%d", makelevel);
Global_Set(MAKE_LEVEL, buf); Global_Set(MAKE_LEVEL, buf);
snprintf(buf, sizeof buf, "%u", myPid); snprintf(buf, sizeof buf, "%u", myPid);
Global_Set(".MAKE.PID", buf); Global_Set_ReadOnly(".MAKE.PID", buf);
snprintf(buf, sizeof buf, "%u", getppid()); snprintf(buf, sizeof buf, "%u", getppid());
Global_Set(".MAKE.PPID", buf); Global_Set_ReadOnly(".MAKE.PPID", buf);
snprintf(buf, sizeof buf, "%u", getuid()); snprintf(buf, sizeof buf, "%u", getuid());
Global_Set(".MAKE.UID", buf); Global_Set_ReadOnly(".MAKE.UID", buf);
snprintf(buf, sizeof buf, "%u", getgid()); snprintf(buf, sizeof buf, "%u", getgid());
Global_Set(".MAKE.GID", buf); Global_Set_ReadOnly(".MAKE.GID", buf);
} }
if (makelevel > 0) { if (makelevel > 0) {
char pn[1024]; char pn[1024];
@ -1502,6 +1505,10 @@ static void
main_ReadFiles(void) main_ReadFiles(void)
{ {
if (Lst_IsEmpty(&sysIncPath->dirs))
SearchPath_AddAll(sysIncPath, defSysIncPath);
Dir_SetSYSPATH();
if (!opts.noBuiltins) if (!opts.noBuiltins)
ReadBuiltinRules(); ReadBuiltinRules();
@ -1906,19 +1913,23 @@ Finish(int errs)
Fatal("%d error%s", errs, errs == 1 ? "" : "s"); Fatal("%d error%s", errs, errs == 1 ? "" : "s");
} }
bool int
unlink_file(const char *file) unlink_file(const char *file)
{ {
struct stat st; struct stat st;
if (lstat(file, &st) == -1) if (lstat(file, &st) == -1)
return false; return -1;
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
/*
* POSIX says for unlink: "The path argument shall not name
* a directory unless [...]".
*/
errno = EISDIR; errno = EISDIR;
return false; return -1;
} }
return unlink(file) == 0; return unlink(file);
} }
static void static void

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $NetBSD: make.c,v 1.255 2022/05/07 17:49:47 rillig Exp $ */ /* $NetBSD: make.c,v 1.258 2022/12/05 23:28:08 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -104,7 +104,7 @@
#include "job.h" #include "job.h"
/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */ /* "@(#)make.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: make.c,v 1.255 2022/05/07 17:49:47 rillig Exp $"); MAKE_RCSID("$NetBSD: make.c,v 1.258 2022/12/05 23:28:08 rillig Exp $");
/* Sequence # to detect recursion. */ /* Sequence # to detect recursion. */
static unsigned int checked_seqno = 1; static unsigned int checked_seqno = 1;
@ -175,17 +175,15 @@ GNodeFlags_ToString(GNodeFlags flags, void **freeIt)
Buffer buf; Buffer buf;
Buf_InitSize(&buf, 32); Buf_InitSize(&buf, 32);
#define ADD(flag, name) Buf_AddFlag(&buf, flags.flag, name) Buf_AddFlag(&buf, flags.remake, "REMAKE");
ADD(remake, "REMAKE"); Buf_AddFlag(&buf, flags.childMade, "CHILDMADE");
ADD(childMade, "CHILDMADE"); Buf_AddFlag(&buf, flags.force, "FORCE");
ADD(force, "FORCE"); Buf_AddFlag(&buf, flags.doneWait, "DONE_WAIT");
ADD(doneWait, "DONE_WAIT"); Buf_AddFlag(&buf, flags.doneOrder, "DONE_ORDER");
ADD(doneOrder, "DONE_ORDER"); Buf_AddFlag(&buf, flags.fromDepend, "FROM_DEPEND");
ADD(fromDepend, "FROM_DEPEND"); Buf_AddFlag(&buf, flags.doneAllsrc, "DONE_ALLSRC");
ADD(doneAllsrc, "DONE_ALLSRC"); Buf_AddFlag(&buf, flags.cycle, "CYCLE");
ADD(cycle, "CYCLE"); Buf_AddFlag(&buf, flags.doneCycle, "DONECYCLE");
ADD(doneCycle, "DONECYCLE");
#undef ADD
return buf.len == 0 ? "none" : (*freeIt = Buf_DoneData(&buf)); return buf.len == 0 ? "none" : (*freeIt = Buf_DoneData(&buf));
} }
@ -462,7 +460,7 @@ Make_HandleUse(GNode *cgn, GNode *pgn)
} }
pgn->type |= pgn->type |=
cgn->type & ~(OP_OPMASK | OP_USE | OP_USEBEFORE | OP_TRANSFORM); cgn->type & (unsigned)~(OP_OPMASK | OP_USE | OP_USEBEFORE | OP_TRANSFORM);
} }
/* /*
@ -820,7 +818,7 @@ UnmarkChildren(GNode *gn)
for (ln = gn->children.first; ln != NULL; ln = ln->next) { for (ln = gn->children.first; ln != NULL; ln = ln->next) {
GNode *child = ln->datum; GNode *child = ln->datum;
child->type &= ~OP_MARK; child->type &= (unsigned)~OP_MARK;
} }
} }
@ -1077,7 +1075,7 @@ MakeStartJobs(void)
if (GNode_IsOODate(gn)) { if (GNode_IsOODate(gn)) {
DEBUG0(MAKE, "out-of-date\n"); DEBUG0(MAKE, "out-of-date\n");
if (opts.query) if (opts.query)
return true; return strcmp(gn->name, ".MAIN") != 0;
GNode_SetLocalVars(gn); GNode_SetLocalVars(gn);
Job_Make(gn); Job_Make(gn);
have_token = false; have_token = false;

View file

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.303 2022/06/12 13:37:32 rillig Exp $ */ /* $NetBSD: make.h,v 1.311 2023/01/26 20:48:17 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -632,7 +632,6 @@ extern pid_t myPid;
#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all loaded makefiles */ #define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all loaded makefiles */
#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */ #define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
#define MAKE_MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE" #define MAKE_MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
#define MAKE_MODE ".MAKE.MODE" #define MAKE_MODE ".MAKE.MODE"
#ifndef MAKE_LEVEL_ENV #ifndef MAKE_LEVEL_ENV
# define MAKE_LEVEL_ENV "MAKELEVEL" # define MAKE_LEVEL_ENV "MAKELEVEL"
@ -813,10 +812,10 @@ void Compat_MakeAll(GNodeList *);
void Compat_Make(GNode *, GNode *); void Compat_Make(GNode *, GNode *);
/* cond.c */ /* cond.c */
extern unsigned int cond_depth;
CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE; CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE;
CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE; CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE;
void Cond_restore_depth(unsigned int); void Cond_EndFile(void);
unsigned int Cond_save_depth(void) MAKE_ATTR_USE;
/* dir.c; see also dir.h */ /* dir.c; see also dir.h */
@ -845,6 +844,7 @@ void For_Run(unsigned, unsigned);
bool For_NextIteration(struct ForLoop *, Buffer *); bool For_NextIteration(struct ForLoop *, Buffer *);
char *ForLoop_Details(struct ForLoop *); char *ForLoop_Details(struct ForLoop *);
void ForLoop_Free(struct ForLoop *); void ForLoop_Free(struct ForLoop *);
void For_Break(struct ForLoop *);
/* job.c */ /* job.c */
void JobReapChild(pid_t, int, bool); void JobReapChild(pid_t, int, bool);
@ -857,7 +857,7 @@ void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD; void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
void DieHorribly(void) MAKE_ATTR_DEAD; void DieHorribly(void) MAKE_ATTR_DEAD;
void Finish(int) MAKE_ATTR_DEAD; void Finish(int) MAKE_ATTR_DEAD;
bool unlink_file(const char *) MAKE_ATTR_USE; int unlink_file(const char *) MAKE_ATTR_USE;
void execDie(const char *, const char *); void execDie(const char *, const char *);
char *getTmpdir(void) MAKE_ATTR_USE; char *getTmpdir(void) MAKE_ATTR_USE;
bool ParseBoolean(const char *, bool) MAKE_ATTR_USE; bool ParseBoolean(const char *, bool) MAKE_ATTR_USE;
@ -878,6 +878,7 @@ void Parse_PushInput(const char *, unsigned, unsigned, Buffer,
struct ForLoop *); struct ForLoop *);
void Parse_MainName(GNodeList *); void Parse_MainName(GNodeList *);
int Parse_NumErrors(void) MAKE_ATTR_USE; int Parse_NumErrors(void) MAKE_ATTR_USE;
unsigned int CurFile_CondMinDepth(void) MAKE_ATTR_USE;
/* suff.c */ /* suff.c */
@ -1041,10 +1042,12 @@ void Var_ReexportVars(void);
void Var_Export(VarExportMode, const char *); void Var_Export(VarExportMode, const char *);
void Var_ExportVars(const char *); void Var_ExportVars(const char *);
void Var_UnExport(bool, const char *); void Var_UnExport(bool, const char *);
void Var_ReadOnly(const char *, bool);
void Global_Set(const char *, const char *); void Global_Set(const char *, const char *);
void Global_Append(const char *, const char *); void Global_Append(const char *, const char *);
void Global_Delete(const char *); void Global_Delete(const char *);
void Global_Set_ReadOnly(const char *, const char *);
/* util.c */ /* util.c */
typedef void (*SignalProc)(int); typedef void (*SignalProc)(int);
@ -1068,6 +1071,10 @@ int str2Lst_Append(StringList *, char *);
void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *); void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
bool GNode_ShouldExecute(GNode *gn) MAKE_ATTR_USE; bool GNode_ShouldExecute(GNode *gn) MAKE_ATTR_USE;
#ifndef HAVE_STRLCPY
size_t strlcpy(char *, const char *, size_t);
#endif
/* See if the node was seen on the left-hand side of a dependency operator. */ /* See if the node was seen on the left-hand side of a dependency operator. */
MAKE_INLINE bool MAKE_ATTR_USE MAKE_INLINE bool MAKE_ATTR_USE
GNode_IsTarget(const GNode *gn) GNode_IsTarget(const GNode *gn)

View file

@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.200 2022/04/15 12:28:16 rillig Exp $ */ /* $NetBSD: meta.c,v 1.201 2022/09/28 16:34:47 sjg Exp $ */
/* /*
* Implement 'meta' mode. * Implement 'meta' mode.
@ -281,15 +281,19 @@ meta_name(char *mname, size_t mnamelen,
/* on some systems dirname may modify its arg */ /* on some systems dirname may modify its arg */
tp = bmake_strdup(tname); tp = bmake_strdup(tname);
dtp = dirname(tp); dtp = dirname(tp);
if (strcmp(dname, dtp) == 0) if (strcmp(dname, dtp) == 0) {
snprintf(mname, mnamelen, "%s.meta", tname); if (snprintf(mname, mnamelen, "%s.meta", tname) >= (int)mnamelen)
else { mname[mnamelen - 1] = '\0';
} else {
int x;
ldname = strlen(dname); ldname = strlen(dname);
if (strncmp(dname, dtp, ldname) == 0 && dtp[ldname] == '/') if (strncmp(dname, dtp, ldname) == 0 && dtp[ldname] == '/')
snprintf(mname, mnamelen, "%s/%s.meta", dname, &tname[ldname+1]); x = snprintf(mname, mnamelen, "%s/%s.meta", dname, &tname[ldname+1]);
else else
snprintf(mname, mnamelen, "%s/%s.meta", dname, tname); x = snprintf(mname, mnamelen, "%s/%s.meta", dname, tname);
if (x >= (int)mnamelen)
mname[mnamelen - 1] = '\0';
/* /*
* Replace path separators in the file name after the * Replace path separators in the file name after the
* current object directory path. * current object directory path.
@ -769,7 +773,9 @@ meta_job_error(Job *job, GNode *gn, bool ignerr, int status)
} }
if (gn != NULL) if (gn != NULL)
Global_Set(".ERROR_TARGET", GNode_Path(gn)); Global_Set(".ERROR_TARGET", GNode_Path(gn));
getcwd(cwd, sizeof cwd); if (getcwd(cwd, sizeof cwd) == NULL)
Punt("Cannot get cwd: %s", strerror(errno));
Global_Set(".ERROR_CWD", cwd); Global_Set(".ERROR_CWD", cwd);
if (pbm->meta_fname[0] != '\0') { if (pbm->meta_fname[0] != '\0') {
Global_Set(".ERROR_META_FILE", pbm->meta_fname); Global_Set(".ERROR_META_FILE", pbm->meta_fname);
@ -1443,18 +1449,18 @@ meta_oodate(GNode *gn, bool oodate)
continue; /* no point */ continue; /* no point */
/* Check vs latestdir */ /* Check vs latestdir */
snprintf(fname1, sizeof fname1, "%s/%s", latestdir, p); if (snprintf(fname1, sizeof fname1, "%s/%s", latestdir, p) < (int)(sizeof fname1))
sdirs[sdx++] = fname1; sdirs[sdx++] = fname1;
if (strcmp(latestdir, lcwd) != 0) { if (strcmp(latestdir, lcwd) != 0) {
/* Check vs lcwd */ /* Check vs lcwd */
snprintf(fname2, sizeof fname2, "%s/%s", lcwd, p); if (snprintf(fname2, sizeof fname2, "%s/%s", lcwd, p) < (int)(sizeof fname2))
sdirs[sdx++] = fname2; sdirs[sdx++] = fname2;
} }
if (strcmp(lcwd, cwd) != 0) { if (strcmp(lcwd, cwd) != 0) {
/* Check vs cwd */ /* Check vs cwd */
snprintf(fname3, sizeof fname3, "%s/%s", cwd, p); if (snprintf(fname3, sizeof fname3, "%s/%s", cwd, p) < (int)(sizeof fname3))
sdirs[sdx++] = fname3; sdirs[sdx++] = fname3;
} }
} }
sdirs[sdx++] = NULL; sdirs[sdx++] = NULL;

View file

@ -1,3 +1,35 @@
2023-01-20 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20230120
* sys.vars.mk: add M_On and M_Onr also cleanup to be more
consistent wrt testing MAKE_VERSION
2023-01-12 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20230112
* meta2deps.{py,sh}: assert if filemon data is truncated
we should see the '# Bye bye' record - assert if we do not.
2022-09-09 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220909
* sys/Linux.mk set EGREP to grep -E to avoid deprecation warnings
2022-09-06 Simon J Gerraty <sjg@beast.crufty.net>
* dirdeps-options.mk: explain the need to use
${DEP_${TARGET_SPEC_VAR}:U${TARGET_SPEC_VAR}} when refering to
${TARGET_SPEC_VAR}
2022-09-03 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220903
* M_cmpv handle more than 3 dots and clear leading 0's
2022-07-20 Simon J Gerraty <sjg@beast.crufty.net> 2022-07-20 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20220720 * install-mk (MK_VERSION): 20220720

View file

@ -1,4 +1,4 @@
# $Id: compiler.mk,v 1.10 2021/12/08 05:56:50 sjg Exp $ # $Id: compiler.mk,v 1.11 2022/09/09 17:44:29 sjg Exp $
# #
# @(#) Copyright (c) 2019, Simon J. Gerraty # @(#) Copyright (c) 2019, Simon J. Gerraty
# #
@ -23,7 +23,7 @@ COMPILER_VERSION = 0
.if empty(COMPILER_TYPE) || empty(COMPILER_VERSION) .if empty(COMPILER_TYPE) || empty(COMPILER_VERSION)
# gcc does not always say gcc # gcc does not always say gcc
_v != (${CC} --version) 2> /dev/null | \ _v != (${CC} --version) 2> /dev/null | \
egrep -i 'clang|cc|[1-9]\.[0-9]|Free Software Foundation'; echo ${EGREP:Uegrep} -i 'clang|cc|[1-9]\.[0-9]|Free Software Foundation'; echo
.if empty(COMPILER_TYPE) .if empty(COMPILER_TYPE)
.if ${_v:Mclang} != "" .if ${_v:Mclang} != ""
COMPILER_TYPE = clang COMPILER_TYPE = clang

View file

@ -1,4 +1,4 @@
# $Id: dirdeps-options.mk,v 1.20 2022/03/17 20:11:36 sjg Exp $ # $Id: dirdeps-options.mk,v 1.21 2022/09/06 22:18:45 sjg Exp $
# #
# @(#) Copyright (c) 2018-2022, Simon J. Gerraty # @(#) Copyright (c) 2018-2022, Simon J. Gerraty
# #
@ -42,6 +42,13 @@
# so we qualify MK_FOO with .${TARGET_SPEC} and each component # so we qualify MK_FOO with .${TARGET_SPEC} and each component
# TARGET_SPEC_VAR (in reverse order) before using MK_FOO. # TARGET_SPEC_VAR (in reverse order) before using MK_FOO.
# #
# Because Makefile.depend.options are processed at both level 0 (when
# computing DIRDEPS to build) and higher (when updating
# Makefile.depend* after successful build), it is important that
# all references to TARGET_SPEC_VARs should use the syntax
# ${DEP_${TARGET_SPEC_VAR}:U${TARGET_SPEC_VAR}} to ensure correct
# behavior.
#
# This should have been set by Makefile.depend.options # This should have been set by Makefile.depend.options
# before including us # before including us

View file

@ -1,4 +1,4 @@
# $Id: dirdeps.mk,v 1.151 2022/01/28 01:13:14 sjg Exp $ # $Id: dirdeps.mk,v 1.152 2022/08/01 23:09:19 sjg Exp $
# Copyright (c) 2010-2022, Simon J. Gerraty # Copyright (c) 2010-2022, Simon J. Gerraty
# Copyright (c) 2010-2018, Juniper Networks, Inc. # Copyright (c) 2010-2018, Juniper Networks, Inc.
@ -401,7 +401,7 @@ DIRDEP_LOADAVG_LAST = 0
# Note: expr(1) will exit 1 if the expression evaluates to 0 # Note: expr(1) will exit 1 if the expression evaluates to 0
# hence the || true # hence the || true
DIRDEP_LOADAVG_REPORT = \ DIRDEP_LOADAVG_REPORT = \
test -z "${"${expr ${now_utc} - ${DIRDEP_LOADAVG_INTEVAL:U60} - ${DIRDEP_LOADAVG_LAST} || true:L:sh:N-*}":?yes${DIRDEP_LOADAVG_LAST::=${now_utc}}:}" || \ test -z "${"${expr ${now_utc} - ${DIRDEP_LOADAVG_INTERVAL:U60} - ${DIRDEP_LOADAVG_LAST} || true:L:sh:N-*}":?yes${DIRDEP_LOADAVG_LAST::=${now_utc}}:}" || \
echo "${TRACER}`${DIRDEP_LOADAVG_CMD}`" echo "${TRACER}`${DIRDEP_LOADAVG_CMD}`"
# we suppress SUBDIR when visiting the leaves # we suppress SUBDIR when visiting the leaves

View file

@ -1,4 +1,4 @@
# $Id: gendirdeps.mk,v 1.47 2022/04/23 21:37:03 sjg Exp $ # $Id: gendirdeps.mk,v 1.48 2022/09/09 17:44:29 sjg Exp $
# Copyright (c) 2011-2020, Simon J. Gerraty # Copyright (c) 2011-2020, Simon J. Gerraty
# Copyright (c) 2010-2018, Juniper Networks, Inc. # Copyright (c) 2010-2018, Juniper Networks, Inc.
@ -88,7 +88,7 @@ META_FILES := ${META_FILES:T:O:u}
# they should all be absolute paths # they should all be absolute paths
SKIP_GENDIRDEPS ?= SKIP_GENDIRDEPS ?=
.if !empty(SKIP_GENDIRDEPS) .if !empty(SKIP_GENDIRDEPS)
_skip_gendirdeps = egrep -v '^(${SKIP_GENDIRDEPS:O:u:ts|})' | _skip_gendirdeps = ${EGREP:Uegrep} -v '^(${SKIP_GENDIRDEPS:O:u:ts|})' |
.else .else
_skip_gendirdeps = _skip_gendirdeps =
.endif .endif

View file

@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net> # Simon J. Gerraty <sjg@crufty.net>
# RCSid: # RCSid:
# $Id: install-mk,v 1.220 2022/07/22 20:08:56 sjg Exp $ # $Id: install-mk,v 1.224 2023/01/20 17:34:06 sjg Exp $
# #
# @(#) Copyright (c) 1994 Simon J. Gerraty # @(#) Copyright (c) 1994 Simon J. Gerraty
# #
@ -70,7 +70,7 @@
# sjg@crufty.net # sjg@crufty.net
# #
MK_VERSION=20220720 MK_VERSION=20230120
OWNER= OWNER=
GROUP= GROUP=
MODE=444 MODE=444
@ -131,6 +131,12 @@ realpath() {
echo $1 echo $1
} }
# some Linux systems have deprecated egrep in favor of grep -E
case "`echo bmake | egrep 'a' 2>&1`" in
*"grep -E"*) egrep='grep -E';;
*) egrep=egrep;;
esac
if [ -s $SYS_MK -a -d $dest ]; then if [ -s $SYS_MK -a -d $dest ]; then
# if this is a BSD system we don't want to touch $SYS_MK # if this is a BSD system we don't want to touch $SYS_MK
dest=`realpath $dest` dest=`realpath $dest`
@ -160,8 +166,8 @@ if [ $mksrc = $dest ]; then
SKIP_MKFILES=: SKIP_MKFILES=:
else else
# we do not install the examples # we do not install the examples
mk_files=`grep '^[a-z].*\.mk' FILES | egrep -v '(examples/|^sys\.mk|sys/)'` mk_files=`grep '^[a-z].*\.mk' FILES | $egrep -v '(examples/|^sys\.mk|sys/)'`
mk_scripts=`egrep '^[a-z].*\.(sh|py)' FILES | egrep -v '/'` mk_scripts=`$egrep '^[a-z].*\.(sh|py)' FILES | $egrep -v '/'`
sys_mk_files=`grep 'sys/.*\.mk' FILES` sys_mk_files=`grep 'sys/.*\.mk' FILES`
SKIP_MKFILES= SKIP_MKFILES=
[ -z "$SKIP_SYS_MK" ] && mk_files="sys.mk $mk_files" [ -z "$SKIP_SYS_MK" ] && mk_files="sys.mk $mk_files"

View file

@ -1,4 +1,4 @@
# $Id: meta.autodep.mk,v 1.55 2021/12/13 08:12:01 sjg Exp $ # $Id: meta.autodep.mk,v 1.56 2022/09/09 17:44:29 sjg Exp $
# #
# @(#) Copyright (c) 2010, Simon J. Gerraty # @(#) Copyright (c) 2010, Simon J. Gerraty
@ -174,7 +174,7 @@ DEPEND_SUFFIXES += .c .h .cpp .hpp .cxx .hxx .cc .hh
.endif .endif
.depend: .NOMETA $${.MAKE.META.CREATED} ${_this} .depend: .NOMETA $${.MAKE.META.CREATED} ${_this}
@echo "Updating $@: ${.OODATE:T:[1..8]}" @echo "Updating $@: ${.OODATE:T:[1..8]}"
@egrep -i '^R .*\.(${DEPEND_SUFFIXES:tl:O:u:S,^.,,:ts|})$$' /dev/null ${.MAKE.META.FILES:T:O:u:${META_FILE_FILTER:ts:}:M*o.meta} | \ @${EGREP:Uegrep} -i '^R .*\.(${DEPEND_SUFFIXES:tl:O:u:S,^.,,:ts|})$$' /dev/null ${.MAKE.META.FILES:T:O:u:${META_FILE_FILTER:ts:}:M*o.meta} | \
sed -e 's, \./, ,${OBJDIR_REFS:O:u:@d@;s, $d/, ,@};/\//d' \ sed -e 's, \./, ,${OBJDIR_REFS:O:u:@d@;s, $d/, ,@};/\//d' \
-e 's,^\([^/][^/]*\).meta...[0-9]* ,\1: ,' | \ -e 's,^\([^/][^/]*\).meta...[0-9]* ,\1: ,' | \
sort -u | \ sort -u | \

View file

@ -1,4 +1,4 @@
# $Id: meta.stage.mk,v 1.64 2021/12/08 05:56:50 sjg Exp $ # $Id: meta.stage.mk,v 1.65 2022/09/09 17:44:29 sjg Exp $
# #
# @(#) Copyright (c) 2011-2017, Simon J. Gerraty # @(#) Copyright (c) 2011-2017, Simon J. Gerraty
# #
@ -354,7 +354,7 @@ all: stale_staged
# get a list of paths that we have previously staged to those same dirs # get a list of paths that we have previously staged to those same dirs
# anything in the 2nd list but not the first is stale - remove it. # anything in the 2nd list but not the first is stale - remove it.
stale_staged: staging .NOMETA stale_staged: staging .NOMETA
@egrep '^[WL] .*${STAGE_OBJTOP}' /dev/null ${.MAKE.META.FILES:M*stage_*} | \ @${EGREP:Uegrep} '^[WL] .*${STAGE_OBJTOP}' /dev/null ${.MAKE.META.FILES:M*stage_*} | \
sed "/\.dirdep/d;s,.* '*\(${STAGE_OBJTOP}/[^ '][^ ']*\).*,\1," | \ sed "/\.dirdep/d;s,.* '*\(${STAGE_OBJTOP}/[^ '][^ ']*\).*,\1," | \
sort > ${.TARGET}.staged1 sort > ${.TARGET}.staged1
@grep -l '${_dirdep}' /dev/null ${_STAGED_DIRS:M${STAGE_OBJTOP}*:O:u:@d@$d/*.dirdep@} | \ @grep -l '${_dirdep}' /dev/null ${_STAGED_DIRS:M${STAGE_OBJTOP}*:O:u:@d@$d/*.dirdep@} | \

View file

@ -37,7 +37,7 @@
""" """
RCSid: RCSid:
$Id: meta2deps.py,v 1.44 2022/01/29 02:42:01 sjg Exp $ $Id: meta2deps.py,v 1.45 2023/01/18 01:35:24 sjg Exp $
Copyright (c) 2011-2020, Simon J. Gerraty Copyright (c) 2011-2020, Simon J. Gerraty
Copyright (c) 2011-2017, Juniper Networks, Inc. Copyright (c) 2011-2017, Juniper Networks, Inc.
@ -448,12 +448,13 @@ def parse(self, name=None, file=None):
pid_cwd = {} pid_cwd = {}
pid_last_dir = {} pid_last_dir = {}
last_pid = 0 last_pid = 0
eof_token = False
self.line = 0 self.line = 0
if self.curdir: if self.curdir:
self.seenit(self.curdir) # we ignore this self.seenit(self.curdir) # we ignore this
interesting = 'CEFLRVX' interesting = '#CEFLRVX'
for line in f: for line in f:
self.line += 1 self.line += 1
# ignore anything we don't care about # ignore anything we don't care about
@ -480,6 +481,12 @@ def parse(self, name=None, file=None):
print("%s: CWD=%s" % (self.name, cwd), file=self.debug_out) print("%s: CWD=%s" % (self.name, cwd), file=self.debug_out)
continue continue
if w[0] == '#':
# check the file has not been truncated
if line.find('Bye') > 0:
eof_token = True
continue
pid = int(w[1]) pid = int(w[1])
if pid != last_pid: if pid != last_pid:
if last_pid: if last_pid:
@ -535,7 +542,11 @@ def parse(self, name=None, file=None):
continue continue
self.parse_path(path, cwd, w[0], w) self.parse_path(path, cwd, w[0], w)
assert(version > 0) if version == 0:
raise AssertionError('missing filemon data')
if not eof_token:
raise AssertionError('truncated filemon data')
setid_pids = [] setid_pids = []
# self.pids should be empty! # self.pids should be empty!
for pid,path in self.pids.items(): for pid,path in self.pids.items():

View file

@ -75,7 +75,7 @@
# RCSid: # RCSid:
# $Id: meta2deps.sh,v 1.18 2022/01/28 21:17:43 sjg Exp $ # $Id: meta2deps.sh,v 1.20 2023/01/18 01:35:24 sjg Exp $
# Copyright (c) 2010-2013, Juniper Networks, Inc. # Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved. # All rights reserved.
@ -137,6 +137,13 @@ add_list() {
eval "$name=\"$list\"" eval "$name=\"$list\""
} }
# some Linux systems have deprecated egrep in favor of grep -E
# but not everyone supports that
case "`echo bmake | egrep 'a|b' 2>&1`" in
bmake) ;;
*) egrep() { grep -E "$@"; }
esac
_excludes_f() { _excludes_f() {
egrep -v "$EXCLUDES" egrep -v "$EXCLUDES"
} }
@ -239,8 +246,8 @@ meta2deps() {
;; ;;
*) cat /dev/null "$@";; *) cat /dev/null "$@";;
esac 2> /dev/null | esac 2> /dev/null |
sed -e 's,^CWD,C C,;/^[CREFLMVX] /!d' -e "s,',,g" | sed -e 's,^CWD,C C,;/^[#CREFLMVX] /!d' -e "s,',,g" |
$_excludes | ( version=no epids= xpids= $_excludes | ( version=no epids= xpids= eof_token=no
while read op pid path junk while read op pid path junk
do do
: op=$op pid=$pid path=$path : op=$op pid=$pid path=$path
@ -258,10 +265,15 @@ meta2deps() {
*) ;; *) ;;
esac esac
version=0 version=0
case "$eof_token" in
no) ;; # ignore
0) error "truncated filemon data";;
esac
eof_token=0
continue continue
;; ;;
$pid,$pid) ;; $pid,$pid) ;;
*) [1-9]*)
case "$lpid" in case "$lpid" in
"") ;; "") ;;
*) eval ldir_$lpid=$ldir;; *) eval ldir_$lpid=$ldir;;
@ -289,6 +301,8 @@ meta2deps() {
eval cwd_$path=$cwd ldir_$path=$ldir eval cwd_$path=$cwd ldir_$path=$ldir
continue continue
;; ;;
\#,bye) eof_token=1; continue;;
\#*) continue;;
*) dir=${path%/*} *) dir=${path%/*}
case "$op" in case "$op" in
E) # setid apps get no tracing so we won't see eXit E) # setid apps get no tracing so we won't see eXit
@ -392,6 +406,10 @@ meta2deps() {
case "$version" in case "$version" in
0) error "no filemon data";; 0) error "no filemon data";;
esac esac
: eof_token=$eof_token
case "$eof_token" in
0) error "truncated filemon data";;
esac
for p in $epids for p in $epids
do do
: p=$p : p=$p

View file

@ -1,4 +1,4 @@
# $Id: sys.clean-env.mk,v 1.24 2022/01/15 17:34:42 sjg Exp $ # $Id: sys.clean-env.mk,v 1.25 2022/09/09 17:44:29 sjg Exp $
# #
# @(#) Copyright (c) 2009, Simon J. Gerraty # @(#) Copyright (c) 2009, Simon J. Gerraty
# #
@ -68,7 +68,7 @@ MAKE_ENV_SAVE_VAR_LIST += \
USER \ USER \
${_env_vars:${MAKE_ENV_SAVE_EXCLUDE_LIST:${M_ListToSkip}}} ${_env_vars:${MAKE_ENV_SAVE_EXCLUDE_LIST:${M_ListToSkip}}}
_env_vars != env | egrep '^(${MAKE_ENV_SAVE_PREFIX_LIST:ts|})' | sed 's,=.*,,'; echo _env_vars != env | ${EGREP:Uegrep} '^(${MAKE_ENV_SAVE_PREFIX_LIST:ts|})' | sed 's,=.*,,'; echo
_export_list = _export_list =
.for v in ${MAKE_ENV_SAVE_VAR_LIST:O:u} .for v in ${MAKE_ENV_SAVE_VAR_LIST:O:u}
@ -125,6 +125,6 @@ MAKEOBJDIR = ${.CURDIR:S,${SRCTOP},${OBJTOP},}
.endif .endif
#.info ${_tricky_env_vars:@v@${.newline}$v=${$v}@} #.info ${_tricky_env_vars:@v@${.newline}$v=${$v}@}
#showenv: #showenv:
# @env | egrep 'OBJ|SRC' # @env | ${EGREP:Uegrep} 'OBJ|SRC'
.endif # MAKEOBJDIR .endif # MAKEOBJDIR
.endif # level 0 .endif # level 0

View file

@ -1,4 +1,4 @@
# $Id: sys.mk,v 1.53 2021/12/13 05:50:13 sjg Exp $ # $Id: sys.mk,v 1.54 2022/09/09 17:44:29 sjg Exp $
# #
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty # @(#) Copyright (c) 2003-2009, Simon J. Gerraty
# #
@ -68,6 +68,9 @@ SYS_OS_MK := ${_sys_mk}
.export SYS_OS_MK .export SYS_OS_MK
.endif .endif
# some sys/ may have set this to grep -E
EGREP ?= egrep
# some options we need to know early # some options we need to know early
OPTIONS_DEFAULT_NO += \ OPTIONS_DEFAULT_NO += \
DIRDEPS_BUILD \ DIRDEPS_BUILD \

View file

@ -1,6 +1,6 @@
# $Id: sys.vars.mk,v 1.9 2022/02/05 19:04:53 sjg Exp $ # $Id: sys.vars.mk,v 1.12 2023/01/20 17:34:06 sjg Exp $
# #
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty # @(#) Copyright (c) 2003-2023, Simon J. Gerraty
# #
# This file is provided in the hope that it will # This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY. # be of use. There is absolutely NO WARRANTY.
@ -17,15 +17,10 @@
# It relies on the fact that conditionals and dependencies are resolved # It relies on the fact that conditionals and dependencies are resolved
# at the time they are read. # at the time they are read.
# #
# _this ?= ${.PARSEFILE} # _this ?= ${.PARSEDIR:tA}/${.PARSEFILE}
# .if !target(__${_this}__) # .if !target(__${_this}__)
# __${_this}__: .NOTMAIN # __${_this}__: .NOTMAIN
# #
.if ${MAKE_VERSION:U0} > 20100408
_this = ${.PARSEDIR:tA}/${.PARSEFILE}
.else
_this = ${.PARSEDIR}/${.PARSEFILE}
.endif
# if this is an ancient version of bmake # if this is an ancient version of bmake
MAKE_VERSION ?= 0 MAKE_VERSION ?= 0
@ -34,12 +29,18 @@ MAKE_VERSION ?= 0
MAKE_VERSION := ${MAKE_VERSION:[1]:C,.*-,,} MAKE_VERSION := ${MAKE_VERSION:[1]:C,.*-,,}
.endif .endif
.if ${MAKE_VERSION} < 20100414
_this = ${.PARSEDIR}/${.PARSEFILE}
.else
_this = ${.PARSEDIR:tA}/${.PARSEFILE}
.endif
# some useful modifiers # some useful modifiers
# A useful trick for testing multiple :M's against something # A useful trick for testing multiple :M's against something
# :L says to use the variable's name as its value - ie. literal # :L says to use the variable's name as its value - ie. literal
# got = ${clean* destroy:${M_ListToMatch:S,V,.TARGETS,}} # got = ${clean* destroy:${M_ListToMatch:S,V,.TARGETS,}}
M_ListToMatch = L:@m@$${V:M$$m}@ M_ListToMatch = L:@m@$${V:U:M$$m}@
# match against our initial targets (see above) # match against our initial targets (see above)
M_L_TARGETS = ${M_ListToMatch:S,V,_TARGETS,} M_L_TARGETS = ${M_ListToMatch:S,V,_TARGETS,}
@ -79,35 +80,44 @@ M_JOT = [1]:@x@i=1;while [ $$$$i -le $$x ]; do echo $$$$i; i=$$$$((i + 1)); done
.endif .endif
# ${LIST:${M_RANGE}} is 1 2 3 4 5 if LIST has 5 words # ${LIST:${M_RANGE}} is 1 2 3 4 5 if LIST has 5 words
.if ${MAKE_VERSION} >= 20170130 .if ${MAKE_VERSION} < 20170130
M_RANGE = range
.else
M_RANGE = [#]:${M_JOT} M_RANGE = [#]:${M_JOT}
.else
M_RANGE = range
.endif .endif
# convert a path to a valid shell variable # convert a path to a valid shell variable
M_P2V = tu:C,[./-],_,g M_P2V = tu:C,[./-],_,g
# convert path to absolute # convert path to absolute
.if ${MAKE_VERSION:U0} > 20100408 .if ${MAKE_VERSION} < 20100414
M_tA = tA
.else
M_tA = C,.*,('cd' & \&\& 'pwd') 2> /dev/null || echo &,:sh M_tA = C,.*,('cd' & \&\& 'pwd') 2> /dev/null || echo &,:sh
.endif .else
M_tA = tA
.if ${MAKE_VERSION:U0} >= 20170130
# M_cmpv allows comparing dotted versions like 3.1.2
# ${3.1.2:L:${M_cmpv}} -> 3001002
# we use big jumps to handle 3 digits per dot:
# ${123.456.789:L:${M_cmpv}} -> 123456789
M_cmpv.units = 1 1000 1000000
M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
.endif .endif
# absoulte path to what we are reading. # absoulte path to what we are reading.
_PARSEDIR = ${.PARSEDIR:${M_tA}} _PARSEDIR = ${.PARSEDIR:${M_tA}}
.if ${MAKE_VERSION} >= 20170130
# M_cmpv allows comparing dotted versions like 3.1.2
# ${3.1.2:L:${M_cmpv}} -> 3001002
# we use big jumps to handle 3 digits per dot:
# ${123.456.789:L:${M_cmpv}} -> 123456789
M_cmpv.units = 1 1000 1000000 1000000000 1000000000000
M_cmpv = S,., ,g:C,^0*([0-9]),\1,:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
.endif
# many projects use MAJOR MINOR PATCH versioning # many projects use MAJOR MINOR PATCH versioning
# ${OPENSSL:${M_M.M.P_VERSION}} is equivalent to # ${OPENSSL:${M_M.M.P_VERSION}} is equivalent to
# ${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_PATCH_VERSION} # ${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_PATCH_VERSION}
M_M.M.P_VERSION = L:@v@$${MAJOR MINOR PATCH:L:@t@$${$$v_$$t_VERSION:U0}@}@:ts. M_M.M.P_VERSION = L:@v@$${MAJOR MINOR PATCH:L:@t@$${$$v_$$t_VERSION:U0}@}@:ts.
# numeric sort
.if ${MAKE_VERSION} < 20210803
M_On = O
M_Onr = O
.else
M_On = On
M_Onr = Onr
.endif

View file

@ -1,4 +1,4 @@
# $Id: Linux.mk,v 1.15 2022/03/25 23:43:06 sjg Exp $ # $Id: Linux.mk,v 1.16 2022/09/09 17:44:29 sjg Exp $
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $ # $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
# @(#)sys.mk 5.11 (Berkeley) 3/13/91 # @(#)sys.mk 5.11 (Berkeley) 3/13/91
@ -186,3 +186,7 @@ ${CXX_SUFFIXES:%=%.a}:
rm -f ${.TARGET} rm -f ${.TARGET}
cp ${.IMPSRC} ${.TARGET} cp ${.IMPSRC} ${.TARGET}
chmod a+x ${.TARGET} chmod a+x ${.TARGET}
# egrep is deprecated
EGREP = grep -E

View file

@ -40,7 +40,7 @@
# #
# RCSid: # RCSid:
# $Id: mkdeps.sh,v 1.23 2002/11/29 06:58:59 sjg Exp $ # $Id: mkdeps.sh,v 1.24 2022/09/09 18:44:56 sjg Exp $
# #
# @(#) Copyright (c) 1993 Simon J. Gerraty # @(#) Copyright (c) 1993 Simon J. Gerraty
# #
@ -119,6 +119,13 @@ else
fi fi
fi fi
# some Linux systems have deprecated egrep in favor of grep -E
# but not everyone supports that
case "`echo bmake | egrep 'a|b' 2>&1`" in
bmake) ;;
*) egrep() { grep -E "$@"; }
esac
clean_up() { clean_up() {
trap "" 2 3 trap "" 2 3
trap 0 trap 0

20
contrib/bmake/os.sh Executable file → Normal file
View file

@ -17,7 +17,7 @@
# Simon J. Gerraty <sjg@crufty.net> # Simon J. Gerraty <sjg@crufty.net>
# RCSid: # RCSid:
# $Id: os.sh,v 1.59 2021/11/14 04:18:00 sjg Exp $ # $Id: os.sh,v 1.62 2023/01/17 18:30:21 sjg Exp $
# #
# @(#) Copyright (c) 1994 Simon J. Gerraty # @(#) Copyright (c) 1994 Simon J. Gerraty
# #
@ -78,10 +78,11 @@ toLower() {
} }
K= K=
case $OS in case "$OS" in
AIX) # everyone loves to be different... AIX) # everyone loves to be different...
OSMAJOR=`uname -v` OSMAJOR=`uname -v`
OSREL="$OSMAJOR.`uname -r`" OSMINOR=`uname -r`
OSREL="$OSMAJOR.$OSMINOR"
LOCAL_FS=jfs LOCAL_FS=jfs
PS_AXC=-e PS_AXC=-e
SHARE_ARCH=$OS/$OSMAJOR.X SHARE_ARCH=$OS/$OSMAJOR.X
@ -229,16 +230,21 @@ HOST_TARGET=`echo ${OS}${OSMAJOR}-$HOST_ARCH | tr -d / | toLower`
HOST_TARGET32=`echo ${OS}${OSMAJOR}-$HOST_ARCH32 | tr -d / | toLower` HOST_TARGET32=`echo ${OS}${OSMAJOR}-$HOST_ARCH32 | tr -d / | toLower`
export HOST_TARGET HOST_TARGET32 export HOST_TARGET HOST_TARGET32
case `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac case `echo -n .` in -n*) echo_n=; echo_c="\c";; *) echo_n=-n; echo_c=;; esac
Echo() { Echo() {
case "$1" in case "$1" in
-n) _n=$N _c=$C; shift;; -n) shift; echo $echo_n "$@$echo_c";;
*) _n= _c=;; *) echo "$@";;
esac esac
echo $_n "$@" $_c
} }
# for systems that deprecate egrep
case "`echo egrep | egrep 'e|g' 2>&1`" in
egrep) ;;
*) egrep() { grep -E "$@"; };;
esac
export HOSTNAME HOST export HOSTNAME HOST
export OS MACHINE MACHINE_ARCH OSREL OSMAJOR LOCAL_FS TMP_DIRS MAILER N C K PS_AXC export OS MACHINE MACHINE_ARCH OSREL OSMAJOR LOCAL_FS TMP_DIRS MAILER N C K PS_AXC
export LN SHARE_ARCH TR export LN SHARE_ARCH TR

View file

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.681 2022/07/24 20:25:23 rillig Exp $ */ /* $NetBSD: parse.c,v 1.692 2023/01/24 00:24:02 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -121,7 +121,7 @@
#include "pathnames.h" #include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: parse.c,v 1.681 2022/07/24 20:25:23 rillig Exp $"); MAKE_RCSID("$NetBSD: parse.c,v 1.692 2023/01/24 00:24:02 sjg Exp $");
/* /*
* A file being read. * A file being read.
@ -135,7 +135,8 @@ typedef struct IncludedFile {
unsigned forBodyReadLines; /* the number of physical lines that have unsigned forBodyReadLines; /* the number of physical lines that have
* been read from the file above the body of * been read from the file above the body of
* the .for loop */ * the .for loop */
unsigned int cond_depth; /* 'if' nesting when file opened */ unsigned int condMinDepth; /* depth of nested 'if' directives, at the
* beginning of the file */
bool depending; /* state of doing_depend on EOF */ bool depending; /* state of doing_depend on EOF */
Buffer buf; /* the file's content or the body of the .for Buffer buf; /* the file's content or the body of the .for
@ -164,6 +165,7 @@ typedef enum ParseSpecial {
SP_NOMETA, /* .NOMETA */ SP_NOMETA, /* .NOMETA */
SP_NOMETA_CMP, /* .NOMETA_CMP */ SP_NOMETA_CMP, /* .NOMETA_CMP */
SP_NOPATH, /* .NOPATH */ SP_NOPATH, /* .NOPATH */
SP_NOREADONLY, /* .NOREADONLY */
SP_NOT, /* Not special */ SP_NOT, /* Not special */
SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */ SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */
SP_NULL, /* .NULL; not mentioned in the manual page */ SP_NULL, /* .NULL; not mentioned in the manual page */
@ -176,11 +178,13 @@ typedef enum ParseSpecial {
SP_POSIX, /* .POSIX; not mentioned in the manual page */ SP_POSIX, /* .POSIX; not mentioned in the manual page */
#endif #endif
SP_PRECIOUS, /* .PRECIOUS */ SP_PRECIOUS, /* .PRECIOUS */
SP_READONLY, /* .READONLY */
SP_SHELL, /* .SHELL */ SP_SHELL, /* .SHELL */
SP_SILENT, /* .SILENT */ SP_SILENT, /* .SILENT */
SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */ SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */
SP_STALE, /* .STALE */ SP_STALE, /* .STALE */
SP_SUFFIXES, /* .SUFFIXES */ SP_SUFFIXES, /* .SUFFIXES */
SP_SYSPATH, /* .SYSPATH */
SP_WAIT /* .WAIT */ SP_WAIT /* .WAIT */
} ParseSpecial; } ParseSpecial;
@ -284,6 +288,7 @@ static const struct {
{ ".NOMETA", SP_NOMETA, OP_NOMETA }, { ".NOMETA", SP_NOMETA, OP_NOMETA },
{ ".NOMETA_CMP", SP_NOMETA_CMP, OP_NOMETA_CMP }, { ".NOMETA_CMP", SP_NOMETA_CMP, OP_NOMETA_CMP },
{ ".NOPATH", SP_NOPATH, OP_NOPATH }, { ".NOPATH", SP_NOPATH, OP_NOPATH },
{ ".NOREADONLY", SP_NOREADONLY, OP_NONE },
{ ".NOTMAIN", SP_ATTRIBUTE, OP_NOTMAIN }, { ".NOTMAIN", SP_ATTRIBUTE, OP_NOTMAIN },
{ ".NOTPARALLEL", SP_NOTPARALLEL, OP_NONE }, { ".NOTPARALLEL", SP_NOTPARALLEL, OP_NONE },
{ ".NO_PARALLEL", SP_NOTPARALLEL, OP_NONE }, { ".NO_PARALLEL", SP_NOTPARALLEL, OP_NONE },
@ -298,12 +303,14 @@ static const struct {
{ ".POSIX", SP_POSIX, OP_NONE }, { ".POSIX", SP_POSIX, OP_NONE },
#endif #endif
{ ".PRECIOUS", SP_PRECIOUS, OP_PRECIOUS }, { ".PRECIOUS", SP_PRECIOUS, OP_PRECIOUS },
{ ".READONLY", SP_READONLY, OP_NONE },
{ ".RECURSIVE", SP_ATTRIBUTE, OP_MAKE }, { ".RECURSIVE", SP_ATTRIBUTE, OP_MAKE },
{ ".SHELL", SP_SHELL, OP_NONE }, { ".SHELL", SP_SHELL, OP_NONE },
{ ".SILENT", SP_SILENT, OP_SILENT }, { ".SILENT", SP_SILENT, OP_SILENT },
{ ".SINGLESHELL", SP_SINGLESHELL, OP_NONE }, { ".SINGLESHELL", SP_SINGLESHELL, OP_NONE },
{ ".STALE", SP_STALE, OP_NONE }, { ".STALE", SP_STALE, OP_NONE },
{ ".SUFFIXES", SP_SUFFIXES, OP_NONE }, { ".SUFFIXES", SP_SUFFIXES, OP_NONE },
{ ".SYSPATH", SP_SYSPATH, OP_NONE },
{ ".USE", SP_ATTRIBUTE, OP_USE }, { ".USE", SP_ATTRIBUTE, OP_USE },
{ ".USEBEFORE", SP_ATTRIBUTE, OP_USEBEFORE }, { ".USEBEFORE", SP_ATTRIBUTE, OP_USEBEFORE },
{ ".WAIT", SP_WAIT, OP_NONE }, { ".WAIT", SP_WAIT, OP_NONE },
@ -314,6 +321,7 @@ enum PosixState posix_state = PS_NOT_YET;
static IncludedFile * static IncludedFile *
GetInclude(size_t i) GetInclude(size_t i)
{ {
assert(i < includes.len);
return Vector_Get(&includes, i); return Vector_Get(&includes, i);
} }
@ -324,6 +332,12 @@ CurFile(void)
return GetInclude(includes.len - 1); return GetInclude(includes.len - 1);
} }
unsigned int
CurFile_CondMinDepth(void)
{
return CurFile()->condMinDepth;
}
static Buffer static Buffer
LoadFile(const char *path, int fd) LoadFile(const char *path, int fd)
{ {
@ -376,11 +390,11 @@ PrintStackTrace(bool includingInnermost)
const IncludedFile *entries; const IncludedFile *entries;
size_t i, n; size_t i, n;
entries = GetInclude(0);
n = includes.len; n = includes.len;
if (n == 0) if (n == 0)
return; return;
entries = GetInclude(0);
if (!includingInnermost && entries[n - 1].forLoop == NULL) if (!includingInnermost && entries[n - 1].forLoop == NULL)
n--; /* already in the diagnostic */ n--; /* already in the diagnostic */
@ -661,7 +675,7 @@ TryApplyDependencyOperator(GNode *gn, GNodeType op)
* Propagate copied bits to the initial node. They'll be * Propagate copied bits to the initial node. They'll be
* propagated back to the rest of the cohorts later. * propagated back to the rest of the cohorts later.
*/ */
gn->type |= op & ~OP_OPMASK; gn->type |= op & (unsigned)~OP_OPMASK;
cohort = Targ_NewInternalNode(gn->name); cohort = Targ_NewInternalNode(gn->name);
if (doing_depend) if (doing_depend)
@ -927,6 +941,11 @@ HandleDependencyTargetSpecial(const char *targetName,
*inout_paths = Lst_New(); *inout_paths = Lst_New();
Lst_Append(*inout_paths, &dirSearchPath); Lst_Append(*inout_paths, &dirSearchPath);
break; break;
case SP_SYSPATH:
if (*inout_paths == NULL)
*inout_paths = Lst_New();
Lst_Append(*inout_paths, sysIncPath);
break;
case SP_MAIN: case SP_MAIN:
/* /*
* Allow targets from the command line to override the * Allow targets from the command line to override the
@ -1080,8 +1099,12 @@ SkipExtraTargets(char **pp, const char *lstart)
warning = true; warning = true;
p++; p++;
} }
if (warning) if (warning) {
Parse_Error(PARSE_WARNING, "Extra target ignored"); const char *start = *pp;
cpp_skip_whitespace(&start);
Parse_Error(PARSE_WARNING, "Extra target '%.*s' ignored",
(int)(p - start), start);
}
*pp += p - *pp; *pp += p - *pp;
} }
@ -1129,15 +1152,17 @@ ParseDependencyOp(char **pp)
} }
static void static void
ClearPaths(SearchPathList *paths) ClearPaths(ParseSpecial special, SearchPathList *paths)
{ {
if (paths != NULL) { if (paths != NULL) {
SearchPathListNode *ln; SearchPathListNode *ln;
for (ln = paths->first; ln != NULL; ln = ln->next) for (ln = paths->first; ln != NULL; ln = ln->next)
SearchPath_Clear(ln->datum); SearchPath_Clear(ln->datum);
} }
if (special == SP_SYSPATH)
Dir_SetPATH(); Dir_SetSYSPATH();
else
Dir_SetPATH();
} }
static char * static char *
@ -1258,7 +1283,8 @@ HandleDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths)
opts.silent = true; opts.silent = true;
break; break;
case SP_PATH: case SP_PATH:
ClearPaths(paths); case SP_SYSPATH:
ClearPaths(special, paths);
break; break;
#ifdef POSIX #ifdef POSIX
case SP_POSIX: case SP_POSIX:
@ -1310,12 +1336,21 @@ ParseDependencySourceSpecial(ParseSpecial special, const char *word,
case SP_LIBS: case SP_LIBS:
Suff_AddLib(word); Suff_AddLib(word);
break; break;
case SP_NOREADONLY:
Var_ReadOnly(word, false);
break;
case SP_NULL: case SP_NULL:
Suff_SetNull(word); Suff_SetNull(word);
break; break;
case SP_OBJDIR: case SP_OBJDIR:
Main_SetObjdir(false, "%s", word); Main_SetObjdir(false, "%s", word);
break; break;
case SP_READONLY:
Var_ReadOnly(word, true);
break;
case SP_SYSPATH:
AddToPaths(word, paths);
break;
default: default:
break; break;
} }
@ -1343,26 +1378,26 @@ ApplyDependencyTarget(char *name, char *nameEnd, ParseSpecial *inout_special,
} }
static bool static bool
ParseDependencyTargets(char **inout_cp, ParseDependencyTargets(char **pp,
const char *lstart, const char *lstart,
ParseSpecial *inout_special, ParseSpecial *inout_special,
GNodeType *inout_targetAttr, GNodeType *inout_targetAttr,
SearchPathList **inout_paths) SearchPathList **inout_paths)
{ {
char *cp = *inout_cp; char *p = *pp;
for (;;) { for (;;) {
char *tgt = cp; char *tgt = p;
ParseDependencyTargetWord(&cp, lstart); ParseDependencyTargetWord(&p, lstart);
/* /*
* If the word is followed by a left parenthesis, it's the * If the word is followed by a left parenthesis, it's the
* name of one or more files inside an archive. * name of one or more files inside an archive.
*/ */
if (!IsEscaped(lstart, cp) && *cp == '(') { if (!IsEscaped(lstart, p) && *p == '(') {
cp = tgt; p = tgt;
if (!Arch_ParseArchive(&cp, targets, SCOPE_CMDLINE)) { if (!Arch_ParseArchive(&p, targets, SCOPE_CMDLINE)) {
Parse_Error(PARSE_FATAL, Parse_Error(PARSE_FATAL,
"Error in archive specification: \"%s\"", "Error in archive specification: \"%s\"",
tgt); tgt);
@ -1371,27 +1406,27 @@ ParseDependencyTargets(char **inout_cp,
continue; continue;
} }
if (*cp == '\0') { if (*p == '\0') {
InvalidLineType(lstart); InvalidLineType(lstart);
return false; return false;
} }
if (!ApplyDependencyTarget(tgt, cp, inout_special, if (!ApplyDependencyTarget(tgt, p, inout_special,
inout_targetAttr, inout_paths)) inout_targetAttr, inout_paths))
return false; return false;
if (*inout_special != SP_NOT && *inout_special != SP_PATH) if (*inout_special != SP_NOT && *inout_special != SP_PATH)
SkipExtraTargets(&cp, lstart); SkipExtraTargets(&p, lstart);
else else
pp_skip_whitespace(&cp); pp_skip_whitespace(&p);
if (*cp == '\0') if (*p == '\0')
break; break;
if ((*cp == '!' || *cp == ':') && !IsEscaped(lstart, cp)) if ((*p == '!' || *p == ':') && !IsEscaped(lstart, p))
break; break;
} }
*inout_cp = cp; *pp = p;
return true; return true;
} }
@ -1528,9 +1563,16 @@ ParseDependencySources(char *p, GNodeType targetAttr,
} }
/* Now go for the sources. */ /* Now go for the sources. */
if (special == SP_SUFFIXES || special == SP_PATH || switch (special) {
special == SP_INCLUDES || special == SP_LIBS || case SP_INCLUDES:
special == SP_NULL || special == SP_OBJDIR) { case SP_LIBS:
case SP_NOREADONLY:
case SP_NULL:
case SP_OBJDIR:
case SP_PATH:
case SP_READONLY:
case SP_SUFFIXES:
case SP_SYSPATH:
ParseDependencySourcesSpecial(p, special, *inout_paths); ParseDependencySourcesSpecial(p, special, *inout_paths);
if (*inout_paths != NULL) { if (*inout_paths != NULL) {
Lst_Free(*inout_paths); Lst_Free(*inout_paths);
@ -1538,10 +1580,14 @@ ParseDependencySources(char *p, GNodeType targetAttr,
} }
if (special == SP_PATH) if (special == SP_PATH)
Dir_SetPATH(); Dir_SetPATH();
} else { if (special == SP_SYSPATH)
Dir_SetSYSPATH();
break;
default:
assert(*inout_paths == NULL); assert(*inout_paths == NULL);
if (!ParseDependencySourcesMundane(p, special, targetAttr)) if (!ParseDependencySourcesMundane(p, special, targetAttr))
return; return;
break;
} }
MaybeUpdateMainTarget(); MaybeUpdateMainTarget();
@ -2155,7 +2201,7 @@ Parse_PushInput(const char *name, unsigned lineno, unsigned readLines,
curFile->buf_ptr = curFile->buf.data; curFile->buf_ptr = curFile->buf.data;
curFile->buf_end = curFile->buf.data + curFile->buf.len; curFile->buf_end = curFile->buf.data + curFile->buf.len;
curFile->cond_depth = Cond_save_depth(); curFile->condMinDepth = cond_depth;
SetParseFile(name); SetParseFile(name);
} }
@ -2288,11 +2334,7 @@ ParseEOF(void)
return true; return true;
} }
/* Cond_EndFile();
* Ensure the makefile (or .for loop) didn't have mismatched
* conditionals.
*/
Cond_restore_depth(curFile->cond_depth);
FStr_Done(&curFile->name); FStr_Done(&curFile->name);
Buf_Done(&curFile->buf); Buf_Done(&curFile->buf);
@ -2677,6 +2719,20 @@ ParseLine_ShellCommand(const char *p)
} }
} }
static void
HandleBreak(void)
{
IncludedFile *curFile = CurFile();
if (curFile->forLoop != NULL) {
/* pretend we reached EOF */
For_Break(curFile->forLoop);
cond_depth = CurFile_CondMinDepth();
ParseEOF();
} else
Parse_Error(PARSE_FATAL, "break outside of for loop");
}
/* /*
* See if the line starts with one of the known directives, and if so, handle * See if the line starts with one of the known directives, and if so, handle
* the directive. * the directive.
@ -2705,7 +2761,9 @@ ParseDirective(char *line)
pp_skip_whitespace(&cp); pp_skip_whitespace(&cp);
arg = cp; arg = cp;
if (Substring_Equals(dir, "undef")) if (Substring_Equals(dir, "break"))
HandleBreak();
else if (Substring_Equals(dir, "undef"))
Var_Undef(arg); Var_Undef(arg);
else if (Substring_Equals(dir, "export")) else if (Substring_Equals(dir, "export"))
Var_Export(VEM_PLAIN, arg); Var_Export(VEM_PLAIN, arg);

View file

@ -104,7 +104,7 @@
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)sigcompat.c 5.3 (Berkeley) 2/24/91";*/ /*static char *sccsid = "from: @(#)sigcompat.c 5.3 (Berkeley) 2/24/91";*/
static char *rcsid = "$Id: sigcompat.c,v 1.23 2011/02/14 00:07:11 sjg Exp $"; static char *rcsid = "$Id: sigcompat.c,v 1.24 2022/09/26 17:38:10 sjg Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#undef signal #undef signal
@ -204,7 +204,7 @@ SIG_HDLR(*signal(int sig, SIG_HDLR(*handler)(int)))(int)
#ifdef SIGSET_T_INT #ifdef SIGSET_T_INT
# define ss2m(ss) (MASK_T) *(ss) # define ss2m(ss) (MASK_T) *(ss)
# define m2ss(ss, m) *ss = (sigset_t) *(m) # define m2ss(ss, m) *ss = (sigset_t) *(m)
#else #elif !defined(HAVE_SIGSETMASK) || defined(FORCE_POSIX_SIGNALS)
static MASK_T static MASK_T
ss2m(sigset_t *ss) ss2m(sigset_t *ss)
{ {

View file

@ -1,4 +1,4 @@
/* $NetBSD: str.c,v 1.93 2022/06/11 09:24:07 rillig Exp $ */ /* $NetBSD: str.c,v 1.94 2022/12/07 10:28:48 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -71,7 +71,7 @@
#include "make.h" #include "make.h"
/* "@(#)str.c 5.8 (Berkeley) 6/1/90" */ /* "@(#)str.c 5.8 (Berkeley) 6/1/90" */
MAKE_RCSID("$NetBSD: str.c,v 1.93 2022/06/11 09:24:07 rillig Exp $"); MAKE_RCSID("$NetBSD: str.c,v 1.94 2022/12/07 10:28:48 rillig Exp $");
static HashTable interned_strings; static HashTable interned_strings;
@ -313,8 +313,8 @@ in_range(char e1, char c, char e2)
} }
/* /*
* Str_Match -- Test if a string matches a pattern like "*.[ch]". * Test if a string matches a pattern like "*.[ch]". The pattern matching
* The following special characters are known *?\[] (as in fnmatch(3)). * characters are '*', '?' and '[]', as in fnmatch(3).
* *
* XXX: this function does not detect or report malformed patterns. * XXX: this function does not detect or report malformed patterns.
* *

View file

@ -1,4 +1,4 @@
/* $NetBSD: str.h,v 1.15 2021/12/15 10:57:01 rillig Exp $ */ /* $NetBSD: str.h,v 1.16 2022/12/05 23:41:24 rillig Exp $ */
/* /*
Copyright (c) 2021 Roland Illig <rillig@NetBSD.org> Copyright (c) 2021 Roland Illig <rillig@NetBSD.org>
@ -273,19 +273,13 @@ LazyBuf_AddStr(LazyBuf *buf, const char *str)
LazyBuf_Add(buf, *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 MAKE_INLINE void
LazyBuf_AddSubstring(LazyBuf *buf, Substring sub) LazyBuf_AddSubstring(LazyBuf *buf, Substring sub)
{ {
LazyBuf_AddBytesBetween(buf, sub.start, sub.end); const char *p;
for (p = sub.start; p != sub.end; p++)
LazyBuf_Add(buf, *p);
} }
MAKE_STATIC Substring MAKE_STATIC Substring

View file

@ -17,9 +17,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef HAVE_CONFIG_H #include "make.h"
# include <config.h>
#endif
#ifndef HAVE_STRLCPY #ifndef HAVE_STRLCPY
#include <sys/cdefs.h> #include <sys/cdefs.h>

View file

@ -1,4 +1,4 @@
/* $NetBSD: targ.c,v 1.177 2022/04/15 12:19:28 rillig Exp $ */ /* $NetBSD: targ.c,v 1.179 2022/12/06 00:12:44 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
@ -107,7 +107,7 @@
#include "dir.h" #include "dir.h"
/* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */ /* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: targ.c,v 1.177 2022/04/15 12:19:28 rillig Exp $"); MAKE_RCSID("$NetBSD: targ.c,v 1.179 2022/12/06 00:12:44 rillig Exp $");
/* /*
* All target nodes that appeared on the left-hand side of one of the * All target nodes that appeared on the left-hand side of one of the
@ -159,17 +159,17 @@ Targ_List(void)
/* /*
* Create a new graph node, but don't register it anywhere. * Create a new graph node, but don't register it anywhere.
* *
* Graph nodes that appear on the left-hand side of a dependency line such * Graph nodes that occur on the left-hand side of a dependency line such
* as "target: source" are called targets. XXX: In some cases (like the * as "target: source" are called targets. XXX: In some cases (like the
* .ALLTARGETS variable), all nodes are called targets as well, even if they * .ALLTARGETS variable), other nodes are called targets as well, even if
* never appear on the left-hand side. This is a mistake. * they never occur on the left-hand side of a dependency line.
* *
* Typical names for graph nodes are: * Typical names for graph nodes are:
* "src.c" (an ordinary file) * "src.c" an ordinary file
* "clean" (a .PHONY target) * "clean" a .PHONY target
* ".END" (a special hook target) * ".END" a special hook target
* "-lm" (a library) * "-lm" a library
* "libc.a(isspace.o)" (an archive member) * "libm.a(sin.o)" an archive member
*/ */
GNode * GNode *
GNode_New(const char *name) GNode_New(const char *name)
@ -242,9 +242,9 @@ GNode_Free(void *gnp)
* *
* XXX: The GNodes that are only used as variable scopes (SCOPE_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, * SCOPE_GLOBAL, SCOPE_INTERNAL) are not freed at all (see Var_End,
* where they are not mentioned). These might be freed at all, if * where they are not mentioned). These may be freed if their
* their variable values are indeed not used anywhere else (see * variable values are indeed not used anywhere else (see Trace_Init
* Trace_Init for the only suspicious use). * for the only suspicious use).
*/ */
HashTable_Done(&gn->vars); HashTable_Done(&gn->vars);
@ -599,7 +599,7 @@ Targ_Propagate(void)
for (cln = gn->cohorts.first; cln != NULL; cln = cln->next) { for (cln = gn->cohorts.first; cln != NULL; cln = cln->next) {
GNode *cohort = cln->datum; GNode *cohort = cln->datum;
cohort->type |= type & ~OP_OPMASK; cohort->type |= type & (unsigned)~OP_OPMASK;
} }
} }
} }

View file

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.182 2022/07/26 19:39:32 sjg Exp $ # $Id: Makefile,v 1.191 2023/01/24 06:09:49 sjg Exp $
# #
# $NetBSD: Makefile,v 1.318 2022/06/10 21:28:50 rillig Exp $ # $NetBSD: Makefile,v 1.331 2023/01/24 00:24:02 sjg Exp $
# #
# Unit tests for make(1) # Unit tests for make(1)
# #
@ -25,10 +25,6 @@
# named makefile (*.mk), with its own set of expected results (*.exp), # named makefile (*.mk), with its own set of expected results (*.exp),
# and it should be added to the TESTS list. # and it should be added to the TESTS list.
# #
# A few *.mk files are helper files for other tests (such as include-sub.mk)
# and are thus not added to TESTS. Such files must be ignored in
# src/tests/usr.bin/make/t_make.sh.
#
.MAIN: all .MAIN: all
@ -167,6 +163,7 @@ TESTS+= directive-export-impl
TESTS+= directive-export-gmake TESTS+= directive-export-gmake
TESTS+= directive-export-literal TESTS+= directive-export-literal
TESTS+= directive-for TESTS+= directive-for
TESTS+= directive-for-break
TESTS+= directive-for-empty TESTS+= directive-for-empty
TESTS+= directive-for-errors TESTS+= directive-for-errors
TESTS+= directive-for-escape TESTS+= directive-for-escape
@ -324,6 +321,7 @@ TESTS+= ternary
TESTS+= unexport TESTS+= unexport
TESTS+= unexport-env TESTS+= unexport-env
TESTS+= use-inference TESTS+= use-inference
TESTS+= var-readonly
TESTS+= var-scope TESTS+= var-scope
TESTS+= var-scope-cmdline TESTS+= var-scope-cmdline
TESTS+= var-scope-env TESTS+= var-scope-env
@ -500,7 +498,7 @@ TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}}
ENV.depsrc-optional+= TZ=UTC ENV.depsrc-optional+= TZ=UTC
ENV.deptgt-phony+= MAKESYSPATH=. ENV.deptgt-phony+= MAKESYSPATH=.
ENV.directive-undef= ENV_VAR=env-value ENV.directive-undef= ENV_VAR=env-value
ENV.envfirst= FROM_ENV=value-from-env ENV.opt-env= FROM_ENV=value-from-env
ENV.opt-m-include-dir= ${MAKEOBJDIR:DMAKEOBJDIR=${MAKEOBJDIR}} ENV.opt-m-include-dir= ${MAKEOBJDIR:DMAKEOBJDIR=${MAKEOBJDIR}}
ENV.varmisc= FROM_ENV=env ENV.varmisc= FROM_ENV=env
ENV.varmisc+= FROM_ENV_BEFORE=env ENV.varmisc+= FROM_ENV_BEFORE=env
@ -563,6 +561,7 @@ SED_CMDS.sh-dots+= -e 's,^\(\*\*\* Error code \)[1-9][0-9]*,\1<nonzero>,'
SED_CMDS.sh-errctl= ${STD_SED_CMDS.dj} SED_CMDS.sh-errctl= ${STD_SED_CMDS.dj}
SED_CMDS.sh-flags= ${STD_SED_CMDS.hide-from-output} SED_CMDS.sh-flags= ${STD_SED_CMDS.hide-from-output}
SED_CMDS.shell-csh= ${STD_SED_CMDS.white-space} SED_CMDS.shell-csh= ${STD_SED_CMDS.white-space}
SED_CMDS.sh-leading-hyphen= ${STD_SED_CMDS.shell}
SED_CMDS.suff-main+= ${STD_SED_CMDS.dg1} SED_CMDS.suff-main+= ${STD_SED_CMDS.dg1}
SED_CMDS.suff-main-several+= ${STD_SED_CMDS.dg1} SED_CMDS.suff-main-several+= ${STD_SED_CMDS.dg1}
SED_CMDS.suff-transform-debug+= ${STD_SED_CMDS.dg1} SED_CMDS.suff-transform-debug+= ${STD_SED_CMDS.dg1}
@ -571,12 +570,13 @@ SED_CMDS.var-op-shell+= -e '/command/s,No such.*,not found,'
SED_CMDS.var-op-shell+= ${STD_SED_CMDS.white-space} SED_CMDS.var-op-shell+= ${STD_SED_CMDS.white-space}
SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,' SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,'
SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex} SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
SED_CMDS.varparse-errors+= ${STD_SED_CMDS.timestamp}
SED_CMDS.varname-dot-parsedir= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,' 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-parsefile= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,'
SED_CMDS.varname-dot-shell= -e 's, = /[^ ]*, = (details omitted),g' SED_CMDS.varname-dot-shell= -e 's, = /[^ ]*, = (details omitted),g'
SED_CMDS.varname-dot-shell+= -e 's,"/[^" ]*","(details omitted)",g' SED_CMDS.varname-dot-shell+= -e 's,"/[^" ]*","(details omitted)",g'
SED_CMDS.varname-dot-shell+= -e 's,\[/[^] ]*\],[(details omitted)],g' SED_CMDS.varname-dot-shell+= -e 's,\[/[^] ]*\],[(details omitted)],g'
SED_CMDS.varname-empty= ${.OBJDIR .PARSEDIR .PATH .SHELL:L:@v@-e '/\\$v/d'@} SED_CMDS.varname-empty= ${.OBJDIR .PARSEDIR .PATH .SHELL .SYSPATH:L:@v@-e '/\\$v/d'@}
# Some tests need an additional round of postprocessing. # Some tests need an additional round of postprocessing.
POSTPROC.depsrc-wait= sed -e '/^---/d' -e 's,^\(: Making 3[abc]\)[123]$$,\1,' POSTPROC.depsrc-wait= sed -e '/^---/d' -e 's,^\(: Making 3[abc]\)[123]$$,\1,'
@ -601,13 +601,14 @@ STD_SED_CMDS.dd+= -e '/^CachedDir /d'
# Omit details such as process IDs from the output of the -dg1 option. # Omit details such as process IDs from the output of the -dg1 option.
STD_SED_CMDS.dg1= -e '/\#.* \.$$/d' STD_SED_CMDS.dg1= -e '/\#.* \.$$/d'
STD_SED_CMDS.dg1+= -e '/\.MAKE.PATH_FILEMON/d' STD_SED_CMDS.dg1+= -e '/\.MAKE.PATH_FILEMON/d'
STD_SED_CMDS.dg1+= -e '/^MAKE_VERSION/d;/^\#.*\/mk/d' STD_SED_CMDS.dg1+= -e '/^\#.*\/mk/d'
STD_SED_CMDS.dg1+= -e 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,' STD_SED_CMDS.dg1+= -e 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MACHINE[_ARCH]* *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(MACHINE[_ARCH]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MAKE *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.SHELL *=\) .*,\1 <details omitted>,' STD_SED_CMDS.dg1+= -e 's,^\(\.SHELL *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e '/\.SYSPATH/d'
STD_SED_CMDS.dg2= ${STD_SED_CMDS.dg1} STD_SED_CMDS.dg2= ${STD_SED_CMDS.dg1}
STD_SED_CMDS.dg2+= -e 's,\(last modified\) ..:..:.. ... ..\, ....,\1 <timestamp>,' STD_SED_CMDS.dg2+= -e 's,\(last modified\) ..:..:.. ... ..\, ....,\1 <timestamp>,'
@ -651,9 +652,11 @@ STD_SED_CMDS.hide-from-output= \
# bash 5.1.0 bash: line 1: /nonexistent: No such file or directory # bash 5.1.0 bash: line 1: /nonexistent: No such file or directory
# dash dash: 1: cannot open /nonexistent: No such file # dash dash: 1: cannot open /nonexistent: No such file
# #
STD_SED_CMDS.shell+= -e 's,^${.SHELL},${.SHELL:T},'
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: line [0-9][0-9]*: ,,' 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}: [0-9][0-9]*: ,,'
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: ,,' STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: ,,'
STD_SED_CMDS.shell+= -e 's,: command not found,: not found,'
STD_SED_CMDS.white-space= -e 's, *, ,g' -e 's, *$$,,' STD_SED_CMDS.white-space= -e 's, *, ,g' -e 's, *$$,,'
@ -662,6 +665,11 @@ STD_SED_CMDS.white-space= -e 's, *, ,g' -e 's, *$$,,'
STD_SED_CMDS.regex= \ STD_SED_CMDS.regex= \
-e 's,\(Regex compilation error:\).*,\1 (details omitted),' -e 's,\(Regex compilation error:\).*,\1 (details omitted),'
# Normalize timestamps from ':gmtime' or ':localtime' to '<timestamp>'.
# See STD_SED_CMDS.dg2 for timestamps from the debug log.
STD_SED_CMDS.timestamp= \
-e 's,[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [12][0-9][0-9][0-9],<timestamp>,'
# End of the configuration helpers section. # End of the configuration helpers section.
.-include "Makefile.inc" .-include "Makefile.inc"
@ -721,7 +729,17 @@ TMPDIR:= /tmp/uid${.MAKE.UID}
_!= mkdir -p ${TMPDIR} _!= mkdir -p ${TMPDIR}
.endif .endif
MAKE_TEST_ENV= MALLOC_OPTIONS="JA" # for jemalloc 100 # Some Linux systems such as Fedora have deprecated egrep in favor of grep -E.
.if ${.MAKE.OS:NLinux} == ""
EGREP= grep -E
.endif
# Keep the classical definition for all other systems. Just as the bmake code
# is kept compatible with C90, the tests are kept compatible with systems that
# are several decades old and don't follow modern POSIX standards.
EGREP?= egrep
MAKE_TEST_ENV= EGREP="${EGREP}"
MAKE_TEST_ENV+= MALLOC_OPTIONS="JA" # for jemalloc 100
MAKE_TEST_ENV+= MALLOC_CONF="junk:true" # for jemalloc 510 MAKE_TEST_ENV+= MALLOC_CONF="junk:true" # for jemalloc 510
MAKE_TEST_ENV+= TMPDIR=${TMPDIR} MAKE_TEST_ENV+= TMPDIR=${TMPDIR}
@ -769,6 +787,9 @@ _SED_CMDS+= -e 's,${.OBJDIR},<curdir>,g'
_SED_CMDS+= -e 's,${.CURDIR},<curdir>,g' _SED_CMDS+= -e 's,${.CURDIR},<curdir>,g'
_SED_CMDS+= -e 's,<curdir>/,,g' _SED_CMDS+= -e 's,<curdir>/,,g'
_SED_CMDS+= -e 's,${UNIT_TESTS:S,.,\\.,g}/,,g' _SED_CMDS+= -e 's,${UNIT_TESTS:S,.,\\.,g}/,,g'
_SED_CMDS+= -e '/MAKE_VERSION/d'
_SED_CMDS+= -e '/EGREP=/d'
# on AT&T derived systems: false exits 255 not 1 # on AT&T derived systems: false exits 255 not 1
.if ${.MAKE.OS:N*BSD} != "" .if ${.MAKE.OS:N*BSD} != ""
_SED_CMDS+= -e 's,\(Error code\) 255,\1 1,' _SED_CMDS+= -e 's,\(Error code\) 255,\1 1,'

View file

@ -1,6 +1,7 @@
# $Id: Makefile.config.in,v 1.3 2021/10/22 07:48:57 sjg Exp $ # $Id: Makefile.config.in,v 1.4 2022/09/09 18:44:56 sjg Exp $
srcdir= @srcdir@ srcdir= @srcdir@
EGREP= @egrep@
TOOL_DIFF?= @diff@ TOOL_DIFF?= @diff@
DIFF_FLAGS?= @diff_u@ DIFF_FLAGS?= @diff_u@
UTC_1= @UTC_1@ UTC_1= @UTC_1@

View file

@ -1,9 +1,9 @@
: undefined eol : undefined--eol
make: Unclosed variable "UNCLOSED" make: Unclosed variable "UNCLOSED"
: unclosed-variable : unclosed-variable-
make: Unclosed variable expression (expecting '}') for "UNCLOSED" make: Unclosed variable expression (expecting '}') for "UNCLOSED"
: unclosed-modifier : unclosed-modifier-
make: Unknown modifier "Z" make: Unknown modifier "Z"
: unknown-modifier eol : unknown-modifier--eol
: end eol : end-eol
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: cmd-errors-jobs.mk,v 1.1 2020/12/27 05:11:40 rillig Exp $ # $NetBSD: cmd-errors-jobs.mk,v 1.2 2022/09/25 12:51:37 rillig Exp $
# #
# Demonstrate how errors in variable expansions affect whether the commands # Demonstrate how errors in variable expansions affect whether the commands
# are actually executed in jobs mode. # are actually executed in jobs mode.
@ -9,24 +9,24 @@ all: undefined unclosed-variable unclosed-modifier unknown-modifier end
# Undefined variables are not an error. They expand to empty strings. # Undefined variables are not an error. They expand to empty strings.
undefined: undefined:
: $@ ${UNDEFINED} eol : $@-${UNDEFINED}-eol
# XXX: As of 2020-11-01, this command is executed even though it contains # XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors. # parse errors.
unclosed-variable: unclosed-variable:
: $@ ${UNCLOSED : $@-${UNCLOSED
# XXX: As of 2020-11-01, this command is executed even though it contains # XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors. # parse errors.
unclosed-modifier: unclosed-modifier:
: $@ ${UNCLOSED: : $@-${UNCLOSED:
# XXX: As of 2020-11-01, this command is executed even though it contains # XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors. # parse errors.
unknown-modifier: unknown-modifier:
: $@ ${UNKNOWN:Z} eol : $@-${UNKNOWN:Z}-eol
end: end:
: $@ eol : $@-eol
# XXX: As of 2020-11-02, despite the parse errors, the exit status is 0. # XXX: As of 2020-11-02, despite the parse errors, the exit status is 0.

View file

@ -1,9 +1,9 @@
: undefined eol : undefined--eol
make: Unclosed variable "UNCLOSED" make: Unclosed variable "UNCLOSED"
: unclosed-variable : unclosed-variable-
make: Unclosed variable expression (expecting '}') for "UNCLOSED" make: Unclosed variable expression (expecting '}') for "UNCLOSED"
: unclosed-modifier : unclosed-modifier-
make: Unknown modifier "Z" make: Unknown modifier "Z"
: unknown-modifier eol : unknown-modifier--eol
: end eol : end-eol
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: cmd-errors.mk,v 1.4 2020/12/27 05:11:40 rillig Exp $ # $NetBSD: cmd-errors.mk,v 1.5 2022/09/25 12:51:37 rillig Exp $
# #
# Demonstrate how errors in variable expansions affect whether the commands # Demonstrate how errors in variable expansions affect whether the commands
# are actually executed in compat mode. # are actually executed in compat mode.
@ -7,24 +7,24 @@ all: undefined unclosed-variable unclosed-modifier unknown-modifier end
# Undefined variables are not an error. They expand to empty strings. # Undefined variables are not an error. They expand to empty strings.
undefined: undefined:
: $@ ${UNDEFINED} eol : $@-${UNDEFINED}-eol
# XXX: As of 2020-11-01, this command is executed even though it contains # XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors. # parse errors.
unclosed-variable: unclosed-variable:
: $@ ${UNCLOSED : $@-${UNCLOSED
# XXX: As of 2020-11-01, this command is executed even though it contains # XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors. # parse errors.
unclosed-modifier: unclosed-modifier:
: $@ ${UNCLOSED: : $@-${UNCLOSED:
# XXX: As of 2020-11-01, this command is executed even though it contains # XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors. # parse errors.
unknown-modifier: unknown-modifier:
: $@ ${UNKNOWN:Z} eol : $@-${UNKNOWN:Z}-eol
end: end:
: $@ eol : $@-eol
# XXX: As of 2020-11-02, despite the parse errors, the exit status is 0. # XXX: As of 2020-11-02, despite the parse errors, the exit status is 0.

View file

@ -1,7 +1,7 @@
CondParser_Eval: !(${:UINF} > 1e100) CondParser_Eval: !(${:UINF} > 1e100)
make: "cond-cmp-numeric.mk" line 11: String comparison operator must be either == or != make: "cond-cmp-numeric.mk" line 11: Comparison with '>' requires both operands 'INF' and '1e100' to be numeric
CondParser_Eval: ${:UNaN} > NaN CondParser_Eval: ${:UNaN} > NaN
make: "cond-cmp-numeric.mk" line 16: String comparison operator must be either == or != make: "cond-cmp-numeric.mk" line 16: Comparison with '>' requires both operands 'NaN' and 'NaN' to be numeric
CondParser_Eval: !(${:UNaN} == NaN) CondParser_Eval: !(${:UNaN} == NaN)
Comparing "NaN" == "NaN" Comparing "NaN" == "NaN"
CondParser_Eval: 123 ! 123 CondParser_Eval: 123 ! 123
@ -9,7 +9,7 @@ make: "cond-cmp-numeric.mk" line 34: Malformed conditional (123 ! 123)
CondParser_Eval: ${:U 123} < 124 CondParser_Eval: ${:U 123} < 124
Comparing 123.000000 < 124.000000 Comparing 123.000000 < 124.000000
CondParser_Eval: ${:U123 } < 124 CondParser_Eval: ${:U123 } < 124
make: "cond-cmp-numeric.mk" line 50: String comparison operator must be either == or != make: "cond-cmp-numeric.mk" line 50: Comparison with '<' requires both operands '123 ' and '124' to be numeric
make: Fatal errors encountered -- cannot continue make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests make: stopped in unit-tests
exit status 1 exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric.mk,v 1.5 2021/07/29 06:31:18 rillig Exp $ # $NetBSD: cond-cmp-numeric.mk,v 1.6 2022/09/04 22:55:00 rillig Exp $
# #
# Tests for numeric comparisons in .if conditions. # Tests for numeric comparisons in .if conditions.
@ -46,7 +46,7 @@
# Trailing spaces are NOT allowed for numbers. # Trailing spaces are NOT allowed for numbers.
# See EvalCompare and TryParseNumber. # See EvalCompare and TryParseNumber.
# expect+1: String comparison operator must be either == or != # expect+1: Comparison with '<' requires both operands '123 ' and '124' to be numeric
.if ${:U123 } < 124 .if ${:U123 } < 124
. error . error
.else .else

View file

@ -2,10 +2,10 @@ make: "cond-cmp-string.mk" line 18: Malformed conditional (str != str)
make: "cond-cmp-string.mk" line 42: Malformed conditional ("string" != "str""ing") make: "cond-cmp-string.mk" line 42: Malformed conditional ("string" != "str""ing")
make: "cond-cmp-string.mk" line 49: Malformed conditional (!("value" = "value")) make: "cond-cmp-string.mk" line 49: Malformed conditional (!("value" = "value"))
make: "cond-cmp-string.mk" line 56: Malformed conditional (!("value" === "value")) make: "cond-cmp-string.mk" line 56: Malformed conditional (!("value" === "value"))
make: "cond-cmp-string.mk" line 113: String comparison operator must be either == or != make: "cond-cmp-string.mk" line 113: Comparison with '<' requires both operands 'string' and 'string' to be numeric
make: "cond-cmp-string.mk" line 120: String comparison operator must be either == or != make: "cond-cmp-string.mk" line 120: Comparison with '<=' requires both operands 'string' and 'string' to be numeric
make: "cond-cmp-string.mk" line 127: String comparison operator must be either == or != make: "cond-cmp-string.mk" line 127: Comparison with '>' requires both operands 'string' and 'string' to be numeric
make: "cond-cmp-string.mk" line 134: String comparison operator must be either == or != make: "cond-cmp-string.mk" line 134: Comparison with '>=' requires both operands 'string' and 'string' to be numeric
make: Fatal errors encountered -- cannot continue make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests make: stopped in unit-tests
exit status 1 exit status 1

View file

@ -1,11 +1,11 @@
# $NetBSD: cond-cmp-unary.mk,v 1.2 2020/11/11 07:30:11 rillig Exp $ # $NetBSD: cond-cmp-unary.mk,v 1.3 2022/09/08 05:43:20 rillig Exp $
# #
# Tests for unary comparisons in .if conditions, that is, comparisons with # Tests for unary comparisons in .if conditions, that is, comparisons with
# a single operand. If the operand is a number, it is compared to zero, # a single operand. If the operand is a number, it is compared to zero,
# if it is a string, it is tested for emptiness. # if it is a string, it is tested for emptiness.
# The number 0 evaluates to false. # The number 0 in all its various representations evaluates to false.
.if 0 .if 0 || 0.0 || 0e0 || 0.0e0 || 0.0e10
. error . error
.endif .endif
@ -55,4 +55,20 @@
. error . error
.endif .endif
# The condition '${VAR:M*}' is almost equivalent to '${VAR:M*} != ""'. The
# only case where they differ is for a single word whose numeric value is zero.
.if ${:U0:M*}
. error
.endif
.if ${:U0:M*} == ""
. error
.endif
# Multiple words cannot be parsed as a single number, thus evaluating to true.
.if !${:U0 0:M*}
. error
.endif
.if ${:U0 0:M*} == ""
. error
.endif
all: # nothing all: # nothing

View file

@ -1,7 +1,7 @@
make: "cond-op-parentheses.mk" line 19: String comparison operator must be either == or != make: "cond-op-parentheses.mk" line 22: Comparison with '>' requires both operands '3' and '(2' to be numeric
make: "cond-op-parentheses.mk" line 22: Malformed conditional ((3) > 2) make: "cond-op-parentheses.mk" line 25: Malformed conditional ((3) > 2)
make: "cond-op-parentheses.mk" line 40: Malformed conditional (() make: "cond-op-parentheses.mk" line 43: Malformed conditional (()
make: "cond-op-parentheses.mk" line 53: Malformed conditional ()) make: "cond-op-parentheses.mk" line 56: Malformed conditional ())
make: Fatal errors encountered -- cannot continue make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests make: stopped in unit-tests
exit status 1 exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-op-parentheses.mk,v 1.5 2022/01/22 21:50:41 rillig Exp $ # $NetBSD: cond-op-parentheses.mk,v 1.6 2022/09/04 22:55:00 rillig Exp $
# #
# Tests for parentheses in .if conditions, which group expressions to override # Tests for parentheses in .if conditions, which group expressions to override
# the precedence of the operators '!', '&&' and '||'. Parentheses cannot be # the precedence of the operators '!', '&&' and '||'. Parentheses cannot be
@ -15,7 +15,10 @@
# Parentheses cannot enclose numbers as there is no need for it. Make does # Parentheses cannot enclose numbers as there is no need for it. Make does
# not implement any arithmetic functions in its condition parser. If # not implement any arithmetic functions in its condition parser. If
# absolutely necessary, use expr(1). # absolutely necessary, use expr(1).
# expect+1: String comparison operator must be either == or != #
# XXX: It's inconsistent that the right operand has unbalanced parentheses.
#
# expect+1: Comparison with '>' requires both operands '3' and '(2' to be numeric
.if 3 > (2) .if 3 > (2)
.endif .endif
# expect+1: Malformed conditional ((3) > 2) # expect+1: Malformed conditional ((3) > 2)

View file

@ -9,11 +9,11 @@ Comparing "\" != "\"
CondParser_Eval: ${:U#hash} != #hash CondParser_Eval: ${:U#hash} != #hash
Comparing "#hash" != "#hash" Comparing "#hash" != "#hash"
CondParser_Eval: 0 # This is treated as a comment, but why? CondParser_Eval: 0 # This is treated as a comment, but why?
CondParser_Eval: ${0 # comment :?yes:no} != no CondParser_Eval: ${0 # comment:?yes:no} != no
CondParser_Eval: 0 # comment CondParser_Eval: 0 # comment
Comparing "no" != "no" Comparing "no" != "no"
CondParser_Eval: ${1 # comment :?yes:no} != yes CondParser_Eval: ${1 # comment:?yes:no} != yes
CondParser_Eval: 1 # comment CondParser_Eval: 1 # comment
Comparing "yes" != "yes" Comparing "yes" != "yes"
CondParser_Eval: ${UNDEF:Uundefined}!=undefined CondParser_Eval: ${UNDEF:Uundefined}!=undefined
Comparing "undefined" != "undefined" Comparing "undefined" != "undefined"

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-token-plain.mk,v 1.15 2021/12/30 02:14:55 rillig Exp $ # $NetBSD: cond-token-plain.mk,v 1.16 2022/09/25 12:51:37 rillig Exp $
# #
# Tests for plain tokens (that is, string literals without quotes) # Tests for plain tokens (that is, string literals without quotes)
# in .if conditions. These are also called bare words. # in .if conditions. These are also called bare words.
@ -63,10 +63,10 @@
# anybody really use this? This is neither documented nor obvious since # anybody really use this? This is neither documented nor obvious since
# the '#' is escaped. It's much clearer to write a comment in the line # the '#' is escaped. It's much clearer to write a comment in the line
# above the condition. # above the condition.
.if ${0 \# comment :?yes:no} != no .if ${0 \# comment:?yes:no} != no
. error . error
.endif .endif
.if ${1 \# comment :?yes:no} != yes .if ${1 \# comment:?yes:no} != yes
. error . error
.endif .endif

View file

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

View file

@ -1,4 +1,4 @@
# $NetBSD: deptgt.mk,v 1.12 2021/12/13 23:38:54 rillig Exp $ # $NetBSD: deptgt.mk,v 1.13 2023/01/03 00:00:45 rillig Exp $
# #
# Tests for special targets like .BEGIN or .SUFFIXES in dependency # Tests for special targets like .BEGIN or .SUFFIXES in dependency
# declarations. # declarations.
@ -45,7 +45,7 @@ ${:U}: empty-source
# that nobody uses it. # that nobody uses it.
$$$$$$$${:U:Z}: $$$$$$$${:U:Z}:
# expect+1: warning: Extra target ignored # expect+1: warning: Extra target 'ordinary' ignored
.END ordinary: .END ordinary:
# expect+1: warning: Extra target (ordinary) ignored # expect+1: warning: Extra target (ordinary) ignored

View file

@ -1,8 +1,10 @@
# $NetBSD: dir.mk,v 1.9 2021/01/23 10:48:49 rillig Exp $ # $NetBSD: dir.mk,v 1.10 2023/01/24 00:24:02 sjg Exp $
# #
# Tests for dir.c. # Tests for dir.c.
.MAKEFLAGS: -m / # hide /usr/share/mk from the debug log # hide /usr/share/mk from the debug log
.SYSPATH:
.SYSPATH: /
# Dependency lines may use braces for expansion. # Dependency lines may use braces for expansion.
# See DirExpandCurly for the implementation. # See DirExpandCurly for the implementation.

View file

@ -0,0 +1,4 @@
make: "directive-for-break.mk" line 45: break outside of for loop
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -0,0 +1,60 @@
# $NetBSD: directive-for-break.mk,v 1.3 2022/09/24 10:52:05 rillig Exp $
#
# Tests for .break in .for loops, which immediately terminates processing of
# the surrounding .for loop.
# .break terminates the loop early.
# This is usually done within a conditional.
.for i in 1 2 3 4 5 6 7 8
. if $i == 3
I= $i
. break
I= unreached
. endif
.endfor
.if $I != "3"
. error
.endif
# The .break only breaks out of the immediately surrounding .for loop, any
# other .for loops are continued normally.
.for outer in o1 o2 o3
. for inner in i1 i2 i3
. if ${outer} == o2 && ${inner} == i2
. break
. endif
COMBINED+= ${outer}-${inner}
. endfor
.endfor
# Only o2-i2 and o2-i3 are missing.
.if ${COMBINED} != "o1-i1 o1-i2 o1-i3 o2-i1 o3-i1 o3-i2 o3-i3"
. error
.endif
# A .break outside the context of a .for loop is an error.
.if $I == 0
# No parse error, even though the .break occurs outside a .for loop, since
# lines from inactive branches are only parsed as far as necessary to see
# whether they belong to an .if/.elif/.else/.endif chain.
. break
.else
# expect+1: break outside of for loop
. break
.endif
# Since cond.c 1.335 from 2022-09-02 and before cond.c 1.338 from 2022-09-23,
# the following paragraph generated the wrong error message '4294967294 open
# conditionals'.
.if 1
. if 2
. for var in value
. if 3
. break
. endif
. endfor
. endif
.endif

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-for.mk,v 1.13 2022/01/15 12:35:18 rillig Exp $ # $NetBSD: directive-for.mk,v 1.15 2022/10/01 09:23:04 rillig Exp $
# #
# Tests for the .for directive. # Tests for the .for directive.
# #
@ -228,3 +228,19 @@ var= outer
endfor endfor
.endfor .endfor
.MAKEFLAGS: -d0 .MAKEFLAGS: -d0
# When there is a variable definition 'scope=cmdline' from the command line
# (which has higher precedence than global variables) and a .for loop iterates
# over a variable of the same name, the expression '${scope}' expands to the
# value from the .for loop. This is because when the body of the .for loop is
# expanded, the expression '${scope}' is textually replaced with ${:Uloop}',
# without resolving any other variable names (ForLoop_SubstBody). Later, when
# the body of the .for loop is actually interpreted, the body text doesn't
# contain the word 'scope' anymore.
.MAKEFLAGS: scope=cmdline
.for scope in loop
. if ${scope} != "loop"
. error
. endif
.endfor

View file

@ -1,4 +1,4 @@
# $NetBSD: export.mk,v 1.11 2021/12/05 14:57:36 rillig Exp $ # $NetBSD: export.mk,v 1.12 2022/09/09 18:36:15 sjg Exp $
UT_TEST= export UT_TEST= export
UT_FOO= foo${BAR} UT_FOO= foo${BAR}
@ -40,7 +40,7 @@ BAR= bar is ${UT_FU}
.MAKE.EXPORTED+= UT_ZOO UT_TEST .MAKE.EXPORTED+= UT_ZOO UT_TEST
FILTER_CMD?= egrep -v '^(MAKEFLAGS|MALLOC_.*|PATH|PWD|SHLVL|_|&)=' FILTER_CMD?= ${EGREP} -v '^(MAKEFLAGS|MALLOC_.*|PATH|PWD|SHLVL|_|&)='
all: all:
@env | ${FILTER_CMD} | sort @env | ${FILTER_CMD} | sort

View file

@ -1,4 +1,4 @@
# $NetBSD: hanoi-include.mk,v 1.3 2022/05/08 07:27:50 rillig Exp $ # $NetBSD: hanoi-include.mk,v 1.4 2023/01/19 22:48:42 rillig Exp $
# #
# Implements the Towers of Hanoi puzzle, demonstrating a bunch of more or less # Implements the Towers of Hanoi puzzle, demonstrating a bunch of more or less
# useful programming techniques: # useful programming techniques:
@ -21,22 +21,28 @@ FROM?= A # ... from this stack ...
VIA?= B # ... via this stack ... VIA?= B # ... via this stack ...
TO?= C # ... to this stack. TO?= C # ... to this stack.
.if $N == 1 # Since make has no built-in arithmetic functions, convert N to a list of
# words and use the built-in word counting instead.
.if ${N:[#]} == 1
N:= count ${:U:${:Urange=$N}} # 'count' + one word for every disk
.endif
.if ${N:[#]} == 2
. for from to in ${FROM} ${TO} . for from to in ${FROM} ${TO}
all:: all::
@echo "Move the upper disk from stack ${from} to stack ${to}." @echo "Move the upper disk from stack ${from} to stack ${to}."
. endfor . endfor
.else .else
_:= ${N::!=expr $N - 1} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}} _:= ${N::=${N:[1..-2]}} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}}
. include "${.PARSEDIR}/${.PARSEFILE}" . include "${.PARSEDIR}/${.PARSEFILE}"
_:= ${N::!=expr $N + 1} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}} _:= ${N::+=D} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}}
. for from to in ${FROM} ${TO} . for from to in ${FROM} ${TO}
all:: all::
@echo "Move the upper disk from stack ${from} to stack ${to}." @echo "Move the upper disk from stack ${from} to stack ${to}."
. endfor . endfor
_:= ${N::!=expr $N - 1} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}} _:= ${N::=${N:[1..-2]}} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}}
. include "${.PARSEDIR}/${.PARSEFILE}" . include "${.PARSEDIR}/${.PARSEFILE}"
_:= ${N::!=expr $N + 1} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}} _:= ${N::+=D} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}}
.endif .endif

View file

@ -1,17 +1,17 @@
make: "include-main.mk" line 14: main-before-ok make: "include-main.mk" line 14: main-before-ok
make: "include-main.mk" line 21: main-before-for-ok make: "include-main.mk" line 21: main-before-for-ok
make: "include-sub.mk" line 4: sub-before-ok make: "include-sub.inc" line 4: sub-before-ok
make: "include-sub.mk" line 14: sub-before-for-ok make: "include-sub.inc" line 14: sub-before-for-ok
Parsing line 5: . info subsub-ok Parsing line 5: . info subsub-ok
make: "include-subsub.mk" line 5: subsub-ok make: "include-subsub.inc" line 5: subsub-ok
in .for loop from include-sub.mk:31 with i = include in .for loop from include-sub.inc:31 with i = include
in .for loop from include-sub.mk:30 with i = nested in .for loop from include-sub.inc:30 with i = nested
in .for loop from include-sub.mk:29 with i = deeply in .for loop from include-sub.inc:29 with i = deeply
in include-main.mk:27 in include-main.mk:27
Parsing line 6: .MAKEFLAGS: -d0 Parsing line 6: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0) ParseDependency(.MAKEFLAGS: -d0)
make: "include-sub.mk" line 38: sub-after-ok make: "include-sub.inc" line 38: sub-after-ok
make: "include-sub.mk" line 45: sub-after-for-ok make: "include-sub.inc" line 45: sub-after-for-ok
make: "include-main.mk" line 30: main-after-ok make: "include-main.mk" line 30: main-after-ok
make: "include-main.mk" line 37: main-after-for-ok make: "include-main.mk" line 37: main-after-for-ok
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: include-main.mk,v 1.7 2022/01/08 23:41:43 rillig Exp $ # $NetBSD: include-main.mk,v 1.8 2023/01/19 23:26:14 rillig Exp $
# #
# Until 2020-09-05, the .INCLUDEDFROMFILE magic variable did not behave # Until 2020-09-05, the .INCLUDEDFROMFILE magic variable did not behave
# as described in the manual page. # as described in the manual page.
@ -24,7 +24,7 @@
. endif . endif
.endfor .endfor
.include "include-sub.mk" .include "include-sub.inc"
.if !defined(.INCLUDEDFROMFILE) .if !defined(.INCLUDEDFROMFILE)
. info main-after-ok . info main-after-ok

View file

@ -1,4 +1,4 @@
# $NetBSD: include-sub.mk,v 1.9 2022/01/08 23:41:43 rillig Exp $ # $NetBSD: include-sub.inc,v 1.1 2023/01/19 23:26:14 rillig Exp $
.if ${.INCLUDEDFROMFILE} == "include-main.mk" .if ${.INCLUDEDFROMFILE} == "include-main.mk"
. info sub-before-ok . info sub-before-ok
@ -29,7 +29,7 @@
.for i in deeply .for i in deeply
. for i in nested . for i in nested
. for i in include . for i in include
.include "include-subsub.mk" .include "include-subsub.inc"
. endfor . endfor
. endfor . endfor
.endfor .endfor

View file

@ -0,0 +1,9 @@
# $NetBSD: include-subsub.inc,v 1.1 2023/01/19 23:26:14 rillig Exp $
.if ${.INCLUDEDFROMFILE} == "include-sub.inc"
.MAKEFLAGS: -dp
. info subsub-ok
.MAKEFLAGS: -d0
.else
. warning subsub-fail(${.INCLUDEDFROMFILE})
.endif

View file

@ -1,9 +0,0 @@
# $NetBSD: include-subsub.mk,v 1.4 2021/01/26 23:44:56 rillig Exp $
.if ${.INCLUDEDFROMFILE} == "include-sub.mk"
.MAKEFLAGS: -dp
. info subsub-ok
.MAKEFLAGS: -d0
.else
. warning subsub-fail(${.INCLUDEDFROMFILE})
.endif

View file

@ -1,4 +1,6 @@
1 1 trailing
2a 2a trailing
2b trailing
2c trailing
3a without newline, 3b without newline. 3a without newline, 3b without newline.
exit status 0 exit status 0

View file

@ -1,11 +1,11 @@
# $NetBSD: job-output-null.mk,v 1.3 2021/09/12 10:26:49 rillig Exp $ # $NetBSD: job-output-null.mk,v 1.4 2022/09/03 08:03:27 rillig Exp $
# #
# Test how null bytes in the output of a command are handled. Make processes # 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. # 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 # Before job.c 1.454 from 2022-09-03, make handled null bytes in the output
# inconsistently. It's an edge case though since typically the child # from the child process inconsistently. It's an edge case though since
# processes output text. # typically the child processes output text.
# Note: The printf commands used in this test must only use a single format # Note: The printf commands used in this test must only use a single format
# string, without parameters. This is because it is implementation-dependent # string, without parameters. This is because it is implementation-dependent
@ -16,30 +16,40 @@
# NetBSD /bin/ksh 3 x write("fmt") (via /bin/printf) # NetBSD /bin/ksh 3 x write("fmt") (via /bin/printf)
# Bash 5 3 x write("fmt") # Bash 5 3 x write("fmt")
# #
# In the latter case the output may arrive in parts, which in this test makes # In the latter case the output may arrive in 1 to 3 parts, depending on the
# a crucial difference since the outcome of the test depends on whether there # exact timing, which in this test makes a crucial difference since before
# is a '\n' in each of the blocks from the output. # job.c 1.454 from 2022-09-03, the outcome of the test depended on whether
# there was a '\n' in each of the blocks from the output. Depending on the
# exact timing, the output of that test varied, its possible values were '2a',
# '2a 2b', '2a 2c', '2a 2b 2c'.
.MAKEFLAGS: -j1 # force jobs mode .MAKEFLAGS: -j1 # force jobs mode
all: .PHONY all: .PHONY
# The null byte from the command output is kept as-is. # The null byte from the command output is replaced with a single
# See CollectOutput, which looks like it intended to replace these # space by CollectOutput.
# null bytes with simple spaces.
@printf '1\0trailing\n' @printf '1\0trailing\n'
# expect: 1 trailing
# Give the parent process a chance to see the above output, but not # Give the parent process a chance to see the above output, but not
# yet the output from the next printf command. # yet the output from the next printf command.
@sleep 1 @sleep 1
# All null bytes from the command output are kept as-is. # Each null byte from the command output is replaced with a single
# space.
@printf '2a\0trailing\n''2b\0trailing\n''2c\0trailing\n' @printf '2a\0trailing\n''2b\0trailing\n''2c\0trailing\n'
# expect: 2a trailing
# expect: 2b trailing
# expect: 2c trailing
@sleep 1 @sleep 1
# The null bytes are replaced with spaces since they are not followed # Each null byte from the command output is replaced with a single
# by a newline. # space. Because there is no trailing newline in the output, these
# null bytes were replaced with spaces even before job.c 1.454 from
# 2022-09-03, unlike in the cases above.
# #
# The three null bytes in a row test whether this output is # The three null bytes in a row test whether this output is
# compressed to a single space like in DebugFailedTarget. It isn't. # compressed to a single space like in DebugFailedTarget. It isn't.
@printf '3a\0without\0\0\0newline, 3b\0without\0\0\0newline.' @printf '3a\0without\0\0\0newline, 3b\0without\0\0\0newline.'
# expect: 3a without newline, 3b without newline.

View file

@ -1,4 +1,4 @@
# $NetBSD: make-exported.mk,v 1.6 2020/10/05 19:27:48 rillig Exp $ # $NetBSD: make-exported.mk,v 1.7 2022/09/09 18:36:15 sjg Exp $
# #
# As of 2020-08-09, the code in Var_Export is shared between the .export # As of 2020-08-09, the code in Var_Export is shared between the .export
# directive and the .MAKE.EXPORTED variable. This leads to non-obvious # directive and the .MAKE.EXPORTED variable. This leads to non-obvious
@ -22,4 +22,4 @@ UT_VAR= ${UNEXPANDED}
.MAKE.EXPORTED= -literal UT_VAR .MAKE.EXPORTED= -literal UT_VAR
all: all:
@env | sort | egrep '^UT_|make-exported-value' || true @env | sort | ${EGREP} '^UT_|make-exported-value' || true

View file

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

View file

@ -1,2 +1,24 @@
Making commands:
command during parsing command during parsing
exit status 1 commands: query status 1
Making opt-query-file.out-of-date in compat mode:
opt-query-file.out-of-date in compat mode: query status 1
Making opt-query-file.up-to-date in compat mode:
`opt-query-file.up-to-date' is up to date.
opt-query-file.up-to-date in compat mode: query status 0
Making phony in compat mode:
phony in compat mode: query status 1
Making opt-query-file.out-of-date in jobs mode:
opt-query-file.out-of-date in jobs mode: query status 1
Making opt-query-file.up-to-date in jobs mode:
opt-query-file.up-to-date in jobs mode: query status 0
Making phony in jobs mode:
phony in jobs mode: query status 1
exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: opt-query.mk,v 1.4 2020/11/09 20:50:56 rillig Exp $ # $NetBSD: opt-query.mk,v 1.7 2022/08/18 05:37:05 rillig Exp $
# #
# Tests for the -q command line option. # Tests for the -q command line option.
# #
@ -6,7 +6,57 @@
# None of the commands in the targets are run, not even those that are # None of the commands in the targets are run, not even those that are
# prefixed with '+'. # prefixed with '+'.
.MAKEFLAGS: -q # This test consists of several parts:
#
# main Delegates to the actual tests.
#
# commands Ensures that none of the targets is made.
#
# variants Ensures that the up-to-date status is correctly
# reported in both compat and jobs mode, and for several
# kinds of make targets.
PART?= main
.if ${PART} == "main"
all: .PHONY variants cleanup
_!= touch -f opt-query-file.up-to-date
variants: .PHONY
. for target in commands
@echo 'Making ${target}':
@${MAKE} -r -f ${MAKEFILE} -q ${mode:Mjobs:%=-j1} ${target} PART=commands \
&& echo "${target}: query status $$?" \
|| echo "${target}: query status $$?"
@echo
. endfor
. for mode in compat jobs
. for target in opt-query-file.out-of-date opt-query-file.up-to-date phony
@echo 'Making ${target} in ${mode} mode':
@${MAKE} -r -f ${MAKEFILE} -q ${mode:Mjobs:%=-j1} ${target} PART=variants \
&& echo "${target} in ${mode} mode: query status $$?" \
|| echo "${target} in ${mode} mode: query status $$?"
@echo
. endfor
. endfor
# Between 1994 and before 2022-08-17, the exit status for '-q' was always 1,
# the cause for that exit code varied over time though.
#
# expect: opt-query-file.out-of-date in compat mode: query status 1
# expect: opt-query-file.up-to-date in compat mode: query status 0
# expect: phony in compat mode: query status 1
# expect: opt-query-file.out-of-date in jobs mode: query status 1
# expect: opt-query-file.up-to-date in jobs mode: query status 0
# expect: phony in jobs mode: query status 1
cleanup: .PHONY
@rm -f opt-query-file.up-to-date
.elif ${PART} == "commands"
# This command cannot be prevented from being run since it is used at parse # This command cannot be prevented from being run since it is used at parse
# time, and any later variable assignments may depend on its result. # time, and any later variable assignments may depend on its result.
@ -18,9 +68,18 @@
@+echo '$@: run always' @+echo '$@: run always'
# None of these commands are run. # None of these commands are run.
all: commands:
@echo '$@: hidden command' @echo '$@: hidden command'
@+echo '$@: run always' @+echo '$@: run always'
# The exit status 1 is because the "commands" target has to be made, that is,
# The exit status 1 is because the "all" target has to be made, that is,
# it is not up-to-date. # it is not up-to-date.
.elif ${PART} == "variants"
opt-query-file.out-of-date: ${MAKEFILE}
opt-query-file.up-to-date: ${MAKEFILE}
phony: .PHONY
.else
. error Invalid part '${PART}'
.endif

View file

@ -1 +1,5 @@
exit status 0 make: Unfinished modifier for "BRACE_GROUP" (',' missing)
make: "parse-var.mk" line 130: Malformed conditional (0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,})
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,13 +1,135 @@
# $NetBSD: parse-var.mk,v 1.1 2020/10/04 06:53:15 rillig Exp $ # $NetBSD: parse-var.mk,v 1.6 2022/09/25 21:26:23 rillig Exp $
#
# Tests for parsing variable expressions.
#
# TODO: Add systematic tests for all of the below combinations.
#
# Written form:
# short form
# long form with braces endc == '}'
# long form with parentheses endc == ')'
# indirect modifiers endc == '\0'
#
# Based on:
# undefined variable
# global variable
# command-line variable
# environment variable
# target-local variable
# legacy variable '@F'
#
# VarEvalMode:
# parse
# eval
# eval-undeferr
# eval-keep-dollar
# eval-keep-undef
# eval-keep-dollar-undef
#
# Global mode:
# without -dL
# with -dL
#
# Modifiers:
# no
# yes, stay undefined
# convert to defined
# indirect modifiers, involving changes to VarEvalMode
#
# Error conditions:
# for the short form, EOF after the '$'
# for the short form, each character
# for the long forms, EOF right after '${'
# for the long forms, EOF after the variable name
# for the long forms, EOF after the ':'
# for the long forms, EOF after parsing a modifier
# for the long forms, ':}'
# for each modifier: syntactic error
# for each modifier: evaluation error
#
# Context:
# in a condition, only operand, unquoted
# in a condition, only operand, quoted
# in a condition, left-hand side, unquoted
# in a condition, left-hand side, quoted
# in a condition, right-hand side, unquoted
# in a condition, right-hand side, quoted
# left-hand side of a variable assignment
# right-hand side of a ':=' variable assignment
# right-hand side of a '!=' variable assignment
# shell command in a target
# .info directive
# dependency line
# items in a .for loop
# everywhere else Var_Parse is called
#
# Further influences:
# multi-level evaluations like 'other=${OTHER}' with OTHER='$$ ${THIRD}'
#
# Effects:
# How much does the parsing position advance (pp)?
# What's the value of the expression (out_val)?
# What's the status after parsing the expression (VarParseResult)?
# What error messages are printed (Parse_Error)?
# What no-effect error messages are printed (Error)?
# What error messages should be printed but aren't?
# What other side effects are there?
.MAKEFLAGS: -dL .MAKEFLAGS: -dL
# In variable assignments, there may be spaces on the left-hand side of the # In variable assignments, there may be spaces in the middle of the left-hand
# assignment, but only if they occur inside variable expressions. # side of the assignment, but only if they occur inside variable expressions.
# Leading spaces (but not tabs) are possible but unusual.
# Trailing spaces are common in some coding styles, others omit them.
VAR.${:U param }= value VAR.${:U param }= value
.if ${VAR.${:U param }} != "value" .if ${VAR.${:U param }} != "value"
. error . error
.endif .endif
all: # XXX: The following paragraph already uses past tense, in the hope that the
@:; # parsing behavior can be cleaned up soon.
# Since var.c 1.323 from 2020-07-26 18:11 and except for var.c 1.1028 from
# 2022-08-08, the exact way of parsing an expression depended on whether the
# expression was actually evaluated or merely parsed.
#
# If it was evaluated, nested expressions were parsed correctly, parsing each
# modifier according to its exact definition (see varmod.mk).
#
# If the expression was merely parsed but not evaluated (for example, because
# its value would not influence the outcome of the condition, or during the
# first pass of the ':@var@body@' modifier), and the expression contained a
# modifier, and that modifier contained a nested expression, the nested
# expression was not parsed correctly. Instead, make only counted the opening
# and closing delimiters, which failed for nested modifiers with unbalanced
# braces.
#
# This naive brace counting was implemented in ParseModifierPartDollar. As of
# var.c 1.1029, there are still several other places that merely count braces
# instead of properly parsing subexpressions.
#.MAKEFLAGS: -dcpv
# Keep these braces outside the conditions below, to keep them simple to
# understand. If the BRACE_PAIR had been replaced with ':U{}', the '}' would
# have to be escaped, but not the '{'. This asymmetry would have made the
# example even more complicated to understand.
BRACE_PAIR= {}
# In this test word, the '{{}' in the middle will be replaced.
BRACE_GROUP= {{{{}}}}
# The inner ':S' modifier turns the word '{}' into '{{}'.
# The outer ':S' modifier then replaces '{{}' with '<lbraces>'.
# In the first case, the outer expression is relevant and is parsed correctly.
.if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
.endif
# In the second case, the outer expression was irrelevant. In this case, in
# the parts of the outer ':S' modifier, make only counted the braces, and since
# the inner expression '${BRACE_PAIR:...}' contains more '{' than '}', parsing
# failed with the error message 'Unfinished modifier for "BRACE_GROUP"'. Fixed
# in var.c 1.1028 from 2022-08-08, reverted in var.c 1.1029 from 2022-08-23.
.if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
.endif
#.MAKEFLAGS: -d0
all: .PHONY

View file

@ -3,4 +3,5 @@ space after @
echo 'echoed' echo 'echoed'
echoed echoed
3 3
whitespace in leading part
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: sh-leading-at.mk,v 1.5 2020/11/15 20:20:58 rillig Exp $ # $NetBSD: sh-leading-at.mk,v 1.6 2023/01/19 19:55:27 rillig Exp $
# #
# Tests for shell commands preceded by an '@', to suppress printing # Tests for shell commands preceded by an '@', to suppress printing
# the command to stdout. # the command to stdout.
@ -16,3 +16,7 @@ all:
# The leading '@' can be repeated. # The leading '@' can be repeated.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@echo '3' @@@echo '3'
# Since 2023-01-17, the leading '@', '+' and '-' may contain
# whitespace, for compatibility with GNU make.
@ @ @ echo 'whitespace in leading part'

View file

@ -1 +1,11 @@
true
false
*** Error code 1 (ignored)
unknown-command 'needed for needshell in compat.c'
unknown-command: not found
*** Error code 127 (ignored)
unknown-long-option 'needed for needshell in compat.c'
unknown-long-option: not found
whitespace in leading part
*** Error code 127 (ignored)
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: sh-leading-hyphen.mk,v 1.3 2020/11/15 20:20:58 rillig Exp $ # $NetBSD: sh-leading-hyphen.mk,v 1.4 2023/01/19 19:55:27 rillig Exp $
# #
# Tests for shell commands preceded by a '-', to ignore the exit status of # Tests for shell commands preceded by a '-', to ignore the exit status of
# the command line. # the command line.
@ -11,4 +11,19 @@
# TODO: Implementation # TODO: Implementation
all: all:
@:; -true
-false
# An undefined variable expands to an empty string, without warning.
# This is used in practice for prefixing tool names or for DESTDIR.
# The '-' before 'unknown' is interpreted by make as '.IGNORE' flag.
${UNDEF}-unknown-command 'needed for needshell in compat.c'
# Expanding undefined variables may lead to strange error messages
# when the shell interprets single-character options as commands
# instead.
${UNDEF} --unknown-long-option 'needed for needshell in compat.c'
# Since 2023-01-17, the leading '@', '+' and '-' may contain
# whitespace, for compatibility with GNU make.
- - - @echo 'whitespace in leading part'

View file

@ -1,4 +1,6 @@
echo 'this command is not run' echo 'this command is not run'
echo 'this command is run' echo 'this command is run'
this command is run this command is run
echo 'whitespace in leading part'
whitespace in leading part
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: sh-leading-plus.mk,v 1.4 2020/11/09 20:50:56 rillig Exp $ # $NetBSD: sh-leading-plus.mk,v 1.5 2023/01/19 19:55:27 rillig Exp $
# #
# Tests for shell commands preceded by a '+', to run them even if # Tests for shell commands preceded by a '+', to run them even if
# the command line option -n is given. # the command line option -n is given.
@ -8,3 +8,7 @@
all: all:
@echo 'this command is not run' @echo 'this command is not run'
@+echo 'this command is run' @+echo 'this command is run'
# Since 2023-01-17, the leading '@', '+' and '-' may contain
# whitespace, for compatibility with GNU make.
+ + + @echo 'whitespace in leading part'

View file

@ -1,7 +1,7 @@
make: "var-op-expand.mk" line 265: Unknown modifier "s,value,replaced," make: "var-op-expand.mk" line 274: Unknown modifier "s,value,replaced,"
make: "var-op-expand.mk" line 268: warning: XXX Neither branch should be taken. make: "var-op-expand.mk" line 277: warning: XXX Neither branch should be taken.
make: "var-op-expand.mk" line 273: Unknown modifier "s,value,replaced," make: "var-op-expand.mk" line 282: Unknown modifier "s,value,replaced,"
make: "var-op-expand.mk" line 274: warning: XXX Neither branch should be taken. make: "var-op-expand.mk" line 283: warning: XXX Neither branch should be taken.
make: Fatal errors encountered -- cannot continue make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests make: stopped in unit-tests
exit status 1 exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: var-op-expand.mk,v 1.16 2021/12/28 10:47:00 rillig Exp $ # $NetBSD: var-op-expand.mk,v 1.17 2022/09/08 20:23:45 rillig Exp $
# #
# Tests for the := variable assignment operator, which expands its # Tests for the := variable assignment operator, which expands its
# right-hand side. # right-hand side.
@ -37,7 +37,7 @@ VAR:= $$ $$$$ $$$$$$$$
.endif .endif
# reference to a variable containing a literal dollar sign # reference to a variable containing literal dollar signs
REF= $$ $$$$ $$$$$$$$ REF= $$ $$$$ $$$$$$$$
VAR:= ${REF} VAR:= ${REF}
REF= too late REF= too late
@ -49,6 +49,9 @@ REF= too late
# reference to an undefined variable # reference to an undefined variable
.undef UNDEF .undef UNDEF
VAR:= <${UNDEF}> VAR:= <${UNDEF}>
.if ${VAR} != "<>"
. error
.endif
UNDEF= after UNDEF= after
.if ${VAR} != "<after>" .if ${VAR} != "<after>"
. error . error
@ -68,6 +71,9 @@ REF= too late
# expression with an indirect modifier referring to an undefined variable # expression with an indirect modifier referring to an undefined variable
.undef UNDEF .undef UNDEF
VAR:= ${:${UNDEF}} VAR:= ${:${UNDEF}}
.if ${VAR} != ""
. error
.endif
UNDEF= Uwas undefined UNDEF= Uwas undefined
.if ${VAR} != "was undefined" .if ${VAR} != "was undefined"
. error . error
@ -99,6 +105,9 @@ UNDEF= Uwas undefined
REF2= <${REF3}> REF2= <${REF3}>
REF= ${REF2} REF= ${REF2}
VAR:= ${REF} VAR:= ${REF}
.if ${VAR} != "<>"
. error
.endif
REF3= too late REF3= too late
.if ${VAR} != "<too late>" .if ${VAR} != "<too late>"
. error . error

View file

@ -0,0 +1 @@
exit status 0

View file

@ -0,0 +1,20 @@
# $NetBSD: var-readonly.mk,v 1.1 2023/01/24 00:20:00 sjg Exp $
# the answer
N = 42
.READONLY: N
# this should be ignored
N = 666
.if ${N} != 42
.error N ($N) should be 42
.endif
.NOREADONLY: N
# now we can change it
N = 69
.if ${N} == 42
.error N should not be 42
.endif
all:

View file

@ -1 +1,6 @@
: LEN4=undef_
: XY=undef_
: AF=undef_
: %D=undef_ %F=undef_
: @D=._ @F=all_
exit status 0 exit status 0

View file

@ -1,8 +1,17 @@
# $NetBSD: var-scope-local-legacy.mk,v 1.1 2022/01/23 16:25:54 rillig Exp $ # $NetBSD: var-scope-local-legacy.mk,v 1.2 2022/09/27 19:18:45 rillig Exp $
# #
# Tests for legacy target-local variables, such as ${<F} or ${@D}. # Tests for legacy target-local variables, such as ${<F} or ${@D}.
# TODO: Implementation all: .PHONY
# Only variables of length 2 can be legacy, this one cannot.
all: : LEN4=${LEN4:Uundef}_
@:; # The second character of the name must be 'D' or 'F'.
: XY=${XY:Uundef}_
# The first character must name one of the 7 predefined local
# variables, 'A' is not such a character.
: AF=${AF:Uundef}_
# The variable '.MEMBER' is undefined, therefore '%D' and '%F' are
# undefined as well.
: %D=${%D:Uundef}_ %F=${%F:Uundef}_
# The directory name of the target is '.', its basename is 'all'.
: @D=${@D:Uundef}_ @F=${@F:Uundef}_

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-defined.mk,v 1.12 2021/11/30 23:52:19 rillig Exp $ # $NetBSD: varmod-defined.mk,v 1.13 2022/08/24 20:22:10 rillig Exp $
# #
# Tests for the :D variable modifier, which returns the given string # Tests for the :D variable modifier, which returns the given string
# if the variable is defined. It is closely related to the :U modifier. # if the variable is defined. It is closely related to the :U modifier.
@ -104,5 +104,13 @@ VAR:= ${VAR:D${8_DOLLARS}}
VAR:= ${VAR:@var@${8_DOLLARS}@} VAR:= ${VAR:@var@${8_DOLLARS}@}
.MAKEFLAGS: -d0 .MAKEFLAGS: -d0
all:
@:; # Before var.c 1.1030 from 2022-08-24, the following expression caused an
# out-of-bounds read when parsing the indirect ':D' modifier.
M_U_backslash:= ${:UU\\}
.if ${:${M_U_backslash}} != "\\"
. error
.endif
all: .PHONY

View file

@ -11,12 +11,12 @@ Comparing 1.000000 == 0.000000
make: Bad conditional expression '1 == == 2' in '1 == == 2?yes:no' make: Bad conditional expression '1 == == 2' in '1 == == 2?yes:no'
Comparing "" != "" Comparing "" != ""
make: "varmod-ifelse.mk" line 92: warning: Oops, the parse error should have been propagated. make: "varmod-ifelse.mk" line 92: warning: Oops, the parse error should have been propagated.
CondParser_Eval: ${ ${:U\$}{VAR} == value :?ok:bad} != "ok" CondParser_Eval: ${ ${:U\$}{VAR} == value:?ok:bad} != "ok"
CondParser_Eval: ${VAR} == value CondParser_Eval: ${VAR} == value
Comparing "value" == "value" Comparing "value" == "value"
Comparing "ok" != "ok" Comparing "ok" != "ok"
make: "varmod-ifelse.mk" line 153: no. make: "varmod-ifelse.mk" line 153: no.
make: "varmod-ifelse.mk" line 154: String comparison operator must be either == or != make: "varmod-ifelse.mk" line 154: Comparison with '>=' requires both operands 'no' and '10' to be numeric
make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no' make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no'
make: "varmod-ifelse.mk" line 154: . make: "varmod-ifelse.mk" line 154: .
make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no' make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no'

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-ifelse.mk,v 1.19 2022/05/08 06:51:27 rillig Exp $ # $NetBSD: varmod-ifelse.mk,v 1.20 2022/09/25 12:51:37 rillig Exp $
# #
# Tests for the ${cond:?then:else} variable modifier, which evaluates either # Tests for the ${cond:?then:else} variable modifier, which evaluates either
# the then-expression or the else-expression, depending on the condition. # the then-expression or the else-expression, depending on the condition.
@ -106,7 +106,7 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
# from the parser of the .for loop body. See ForLoop_SubstVarLong. # from the parser of the .for loop body. See ForLoop_SubstVarLong.
.MAKEFLAGS: -dc .MAKEFLAGS: -dc
VAR= value VAR= value
.if ${ ${:U\$}{VAR} == value :?ok:bad} != "ok" .if ${ ${:U\$}{VAR} == value:?ok:bad} != "ok"
. error . error
.endif .endif
.MAKEFLAGS: -d0 .MAKEFLAGS: -d0

View file

@ -13,4 +13,10 @@ mod-loop-dollar:$3$:
mod-loop-dollar:$${word}$$: mod-loop-dollar:$${word}$$:
mod-loop-dollar:$$5$$: mod-loop-dollar:$$5$$:
mod-loop-dollar:$$${word}$$$: mod-loop-dollar:$$${word}$$$:
: t=$(( ${t:-0} + 1 ))
: dollar=end
: backslash=\ end
: dollar=$ at=@ backslash=\ end
: dollar=$$ at=@@ backslash=\\ end
: dollar=$$ at=@@ backslash=\\ end
exit status 0 exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-loop.mk,v 1.18 2021/12/05 15:20:13 rillig Exp $ # $NetBSD: varmod-loop.mk,v 1.21 2022/08/23 21:13:46 rillig Exp $
# #
# Tests for the :@var@...${var}...@ variable modifier. # Tests for the :@var@...${var}...@ variable modifier.
@ -186,4 +186,49 @@ CMDLINE= global # needed for deleting the environment
. error # 'CMDLINE' is gone now from all scopes . error # 'CMDLINE' is gone now from all scopes
.endif .endif
# In the loop body text of the ':@' modifier, a literal '$' is written as '$$',
# not '\$'. In the following example, each '$$' turns into a single '$',
# except for '$i', which is replaced with the then-current value '1' of the
# iteration variable.
#
# XXX: was broken in var.c 1.1028 from 2022-08-08, reverted in var.c 1.1029
# from 2022-08-23; see parse-var.mk, keyword 'BRACE_GROUP'.
all: varmod-loop-literal-dollar
varmod-loop-literal-dollar: .PHONY
: ${:U1:@i@ t=$$(( $${t:-0} + $i ))@}
# When parsing the loop body, each '\$', '\@' and '\\' is unescaped to '$',
# '@' and '\'; all other backslashes are retained.
#
# In practice, the '$' is not escaped as '\$', as there is a second round of
# unescaping '$$' to '$' later when the loop body is expanded after setting the
# iteration variable.
#
# After the iteration variable has been set, the loop body is expanded with
# this unescaping, regardless of whether .MAKE.SAVE_DOLLARS is set or not:
# $$ a literal '$'
# $x, ${var}, $(var) a nested expression
# any other character itself
all: escape-modifier
escape-modifier: .PHONY
# In the first round, '\$ ' is unescaped to '$ ', and since the
# variable named ' ' is not defined, the expression '$ ' expands to an
# empty string.
# expect: : dollar=end
: ${:U1:@i@ dollar=\$ end@}
# Like in other modifiers, '\ ' is preserved, since ' ' is not one of
# the characters that _must_ be escaped.
# expect: : backslash=\ end
: ${:U1:@i@ backslash=\ end@}
# expect: : dollar=$ at=@ backslash=\ end
: ${:U1:@i@ dollar=\$\$ at=\@ backslash=\\ end@}
# expect: : dollar=$$ at=@@ backslash=\\ end
: ${:U1:@i@ dollar=\$\$\$\$ at=\@\@ backslash=\\\\ end@}
# expect: : dollar=$$ at=@@ backslash=\\ end
: ${:U1:@i@ dollar=$$$$ at=\@\@ backslash=\\\\ end@}
all: .PHONY all: .PHONY

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-match.mk,v 1.11 2022/06/11 09:15:49 rillig Exp $ # $NetBSD: varmod-match.mk,v 1.12 2022/08/24 21:03:57 rillig Exp $
# #
# Tests for the :M variable modifier, which filters words that match the # Tests for the :M variable modifier, which filters words that match the
# given pattern. # given pattern.
@ -280,3 +280,13 @@ n= 2
.if ${PRIMES:M${:U2}} != "2" .if ${PRIMES:M${:U2}} != "2"
. error . error
.endif .endif
# Before var.c 1.1031 from 2022-08-24, the following expressions caused an
# out-of-bounds read beyond the indirect ':M' modifiers.
.if ${:U:${:UM\\}} # The ':M' pattern need not be unescaped, the
. error # resulting pattern is '\', it never matches
.endif # anything.
.if ${:U:${:UM\\\:\\}} # The ':M' pattern must be unescaped, the
. error # resulting pattern is ':\', it never matches
.endif # anything.

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-order-numeric.mk,v 1.7 2022/02/09 21:09:24 rillig Exp $ # $NetBSD: varmod-order-numeric.mk,v 1.8 2022/09/27 19:18:45 rillig Exp $
# #
# Tests for the variable modifiers ':On', which returns the words, sorted in # Tests for the variable modifiers ':On', which returns the words, sorted in
# ascending numeric order, and for ':Orn' and ':Onr', which additionally # ascending numeric order, and for ':Orn' and ':Onr', which additionally
@ -50,4 +50,10 @@ MIXED_BASE= 0 010 0x7 9
. error ${MIXED_BASE:On} . error ${MIXED_BASE:On}
.endif .endif
# The measurement units for suffixes are k, M, G, but not T.
# The string '3T' evaluates to 3, the string 'x' evaluates as '0'.
.if ${4 3T 2M x:L:On} != "x 3T 4 2M"
. error
.endif
all: all:

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