Merge bmake-20211212
commit '2935fe8237c83c1dcb113dd5335733263e68e6fd'
This commit is contained in:
commit
129043849f
@ -1,3 +1,234 @@
|
||||
2021-12-15 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* cond.c: fix mem leak in CondParser_Leaf
|
||||
|
||||
2021-12-12 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211212
|
||||
Merge with NetBSD make, pick up
|
||||
o rename Parse_SetInput to Parse_PushInput
|
||||
o remove remove period from end of error messages and warnings
|
||||
to be more consistent
|
||||
o arch.c: use simpler memory management for parsing archive members
|
||||
o cond.c: rework and reduce recursion
|
||||
o for.c: rename some functions to better reflect purpose
|
||||
o suff.c: add Suff_NamesStr to provide .SUFFIXES as a string.
|
||||
o var.c: in parse errors, mark whitespace more clearly
|
||||
inline ParseEmptyArg into CondParser_FuncCallEmpty
|
||||
minimize calls to LazyBuf_Get in ParseVarnameLong
|
||||
treat .SUFFIXES as a read-only variable
|
||||
|
||||
2021-12-07 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211207
|
||||
Merge with NetBSD make, pick up
|
||||
o inline HashIter_Init
|
||||
o parse.c: inline common subexpression in ParseRawLine
|
||||
o var.c: merge branches for modifiers ':D' and ':U'
|
||||
extract common code into Expr_Words
|
||||
extract common code into Expr_Str
|
||||
move low-level implementation details out of Var_Parse
|
||||
|
||||
2021-12-06 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211206
|
||||
Merge with NetBSD make, pick up
|
||||
o add unit-tests/varmod-loop-delete
|
||||
o for.c: inline Str_Words - reduce memory allocation
|
||||
o parse.c: do not try to expand fixed variable names
|
||||
only allocate the name of an included file if necessary
|
||||
clean up ParseInclude
|
||||
o var.c: fix use-after-free in modifier ':@'
|
||||
save a memory allocation in each modifier ':O' and ':u'
|
||||
save a memory allocation in the modifier ':[...]'
|
||||
in UnexportVars, replace Str_Words with Substring_Words to
|
||||
reduce allocations and copying.
|
||||
|
||||
2021-12-04 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211204
|
||||
Merge with NetBSD make, pick up
|
||||
o flesh out a number of tests
|
||||
o replace enums with bitfields, this simplifies a lot of code.
|
||||
o var.c: refactor ParseModifierPartSubst
|
||||
|
||||
2021-10-24 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211024
|
||||
Merge with NetBSD make, pick up
|
||||
o Punt on write errors - ENOSPC etc.
|
||||
|
||||
2021-10-22 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* configure.in: use_defshell, set both DEFSHELL_INDEX
|
||||
and defshell_path if appropriate.
|
||||
This makes it easier to use say the KSH specification with
|
||||
and alternate path for the shell.
|
||||
|
||||
* configure.in compat.c: for SCO we need to force UseShell
|
||||
|
||||
* configure.in: SCO /bin/sh is not usable, provide a list of
|
||||
alternatives for use as .SHELL.
|
||||
We still have to mark some tests as broken, plus more if we end up
|
||||
with ksh as .SHELL.
|
||||
Issue a warning about skipped tests.
|
||||
|
||||
* boot-strap: leave TOOL_DIFF to configure
|
||||
|
||||
* configure.in: on SCO native cc is not usable,
|
||||
gcc is to be found in /usr/gnu/bin
|
||||
and while ancient is at least able to compile bmake.
|
||||
Thus we add /usr/gnu/bin to PATH if it exists, and later
|
||||
check if $CC would have been found via $PATH.
|
||||
If not we set CC to the full path of $CC.
|
||||
Also gnu diff is known to support -u, so if it exists use it.
|
||||
|
||||
* configure.in: move getopt to AC_REPLACE_FUNCS
|
||||
also add AC_C_INLINE - in an attempt to compile using
|
||||
native cc on SCO.
|
||||
|
||||
* configure.in: check for stresep as well as strsep, since we
|
||||
define the later to the former if necessary, and if we have to
|
||||
provide stresep we also need to provide a prototype.
|
||||
|
||||
* configure.in: we no longer need to worry about
|
||||
sys/cdefs.h providing __RCSID which simplifies things quite a bit.
|
||||
|
||||
* make.h: make sure we have __RCSID
|
||||
|
||||
* unit-tests/Makefile.config.in: add TOOL_DIFF so configure
|
||||
can control it.
|
||||
|
||||
2021-10-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION: 20211020
|
||||
Merge with NetBSD make, pick up
|
||||
o confirm sync of unit-tests
|
||||
|
||||
2021-10-18 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* configure.in: check if timezone Europe/Berlin is supported
|
||||
if not try UTC-1
|
||||
* configure.in: if .OBJDIR is $srcdir/obj we need to create a
|
||||
symlink unit-tests -> ../unit-tests/obj so that
|
||||
unit-tests/Makefile.config is put in the right place.
|
||||
* refine filtering of .OBJDIR in unit-tests
|
||||
|
||||
2021-10-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* Fix unit-tests on Minix 3.2.0
|
||||
o job.c: do not punt if read of token pipe fails for EAGAIN.
|
||||
On Minix at least, we are not ready to read the childExitJob pipe
|
||||
when poll says we are.
|
||||
There should actually be no reason for this pipe to be
|
||||
non-blocking, but while that works fine on {Net,Free}BSD it
|
||||
breaks another test case on Minix.
|
||||
o unit-tests/Makefile: deal with variants of error messages
|
||||
and use of obj as .OBJDIR
|
||||
|
||||
2021-10-14 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* configure.in: add sigaction to AC_REPLACE_FUNCS
|
||||
we also need to check for sigaddset etc just for the benefit of
|
||||
sigact.c
|
||||
|
||||
* Add sigact.c as sigaction.c so this "just works".
|
||||
This should have been done back when bmake_signal started using
|
||||
sigaction (I only just noticed that sigact.c wasn't here ;-)
|
||||
Note: I no longer have access to any system where this would matter.
|
||||
|
||||
2021-10-13 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211011
|
||||
|
||||
* Makefile: cleanup a little
|
||||
|
||||
* configure.in: check for sigsetmask
|
||||
|
||||
2021-10-01 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20211001
|
||||
Merge with NetBSD make, pick up
|
||||
o reduce locations reducing text size
|
||||
o remove unnecessary const
|
||||
o cond.c: fix lint warning on i386
|
||||
do not allow unquoted 'left == right' after modifier ':?'
|
||||
o hash.c: fix build for DEBUG_HASH_LOOKUP
|
||||
o var.c: fix memory leak in error case of the ':?' modifier
|
||||
|
||||
2021-09-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210911
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: replace remaining ModChain_ShouldEval with Expr_ShouldEval
|
||||
|
||||
2021-09-08 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210906
|
||||
Merge with NetBSD make, pick up
|
||||
o more unit tests
|
||||
o lint cleanup
|
||||
o rename some functions to better fit purpose
|
||||
o for.c: cleanup - remove unnecessary optimization
|
||||
fix embedded newlines
|
||||
o parse.c: correct case for CVS/RCS
|
||||
|
||||
2021-08-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210808
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: remove redundant initialization in ApplyModifier_Order
|
||||
|
||||
* mk/options.mk: issue warning for incorrect usage
|
||||
|
||||
2021-08-03 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* var.c: use long for :On if we don't have a 64bit int type
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210803
|
||||
Merge with NetBSD make, pick up
|
||||
o rework varmod-order tests to avoid qsort instability
|
||||
o make.1: clarify :On entry
|
||||
|
||||
2021-07-31 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210731
|
||||
Merge with NetBSD make, pick up
|
||||
o fix some lint issues
|
||||
o more unit tests
|
||||
o var.c: rework of ApplyModifier_Order
|
||||
|
||||
2021-07-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* util.c: add strto*l if HAVE_STRTO*L not defined
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210730
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: add :On and :Orn for numeric sort
|
||||
disabled if no 64bit type available.
|
||||
o _strtol.h: to implement strto*l functions
|
||||
|
||||
2021-07-04 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210704
|
||||
Merge with NetBSD make, pick up
|
||||
o unit-tests: fix some tests to be more portable
|
||||
- job-output-null not all shells do the same number of write calls
|
||||
- objdir-writable if TMPDIR is set; /tmp may not be usable
|
||||
|
||||
2021-07-01 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210701
|
||||
Merge with NetBSD make, pick up
|
||||
o unit-tests: allow for BROKEN_TESTS to list TESTS to be skipped;
|
||||
some tests just cannot work in some environments.
|
||||
o buf.c: simpler upper bound for length in Buf_AddInt
|
||||
o cond.c: fix grammar in error message for malformed conditional
|
||||
o for.c: prevent newline injection (from ${.newline}) in .for loops
|
||||
o var.c: use more practical data type in RegexReplace
|
||||
(avoid need for %zu)
|
||||
extract RegexReplace from ModifyWord_SubstRegex
|
||||
|
||||
2021-06-21 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20210621
|
||||
|
@ -7,6 +7,7 @@ PSD.doc/Makefile
|
||||
PSD.doc/tutorial.ms
|
||||
README
|
||||
VERSION
|
||||
_strtol.h
|
||||
aclocal.m4
|
||||
arch.c
|
||||
bmake.1
|
||||
@ -23,8 +24,6 @@ configure.in
|
||||
dir.c
|
||||
dir.h
|
||||
dirname.c
|
||||
enum.c
|
||||
enum.h
|
||||
filemon/filemon.h
|
||||
filemon/filemon_dev.c
|
||||
filemon/filemon_ktrace.c
|
||||
@ -61,6 +60,8 @@ pathnames.h
|
||||
ranlib.h
|
||||
realpath.c
|
||||
setenv.c
|
||||
sigact.h
|
||||
sigaction.c
|
||||
sigcompat.c
|
||||
str.c
|
||||
str.h
|
||||
@ -322,6 +323,8 @@ unit-tests/directive-for-escape.exp
|
||||
unit-tests/directive-for-escape.mk
|
||||
unit-tests/directive-for-generating-endif.exp
|
||||
unit-tests/directive-for-generating-endif.mk
|
||||
unit-tests/directive-for-if.exp
|
||||
unit-tests/directive-for-if.mk
|
||||
unit-tests/directive-for-lines.exp
|
||||
unit-tests/directive-for-lines.mk
|
||||
unit-tests/directive-for-null.exp
|
||||
@ -684,6 +687,8 @@ unit-tests/varmod-l-name-to-value.exp
|
||||
unit-tests/varmod-l-name-to-value.mk
|
||||
unit-tests/varmod-localtime.exp
|
||||
unit-tests/varmod-localtime.mk
|
||||
unit-tests/varmod-loop-delete.exp
|
||||
unit-tests/varmod-loop-delete.mk
|
||||
unit-tests/varmod-loop-varname.exp
|
||||
unit-tests/varmod-loop-varname.mk
|
||||
unit-tests/varmod-loop.exp
|
||||
@ -694,10 +699,14 @@ unit-tests/varmod-match.exp
|
||||
unit-tests/varmod-match.mk
|
||||
unit-tests/varmod-no-match.exp
|
||||
unit-tests/varmod-no-match.mk
|
||||
unit-tests/varmod-order-numeric.exp
|
||||
unit-tests/varmod-order-numeric.mk
|
||||
unit-tests/varmod-order-reverse.exp
|
||||
unit-tests/varmod-order-reverse.mk
|
||||
unit-tests/varmod-order-shuffle.exp
|
||||
unit-tests/varmod-order-shuffle.mk
|
||||
unit-tests/varmod-order-string.exp
|
||||
unit-tests/varmod-order-string.mk
|
||||
unit-tests/varmod-order.exp
|
||||
unit-tests/varmod-order.mk
|
||||
unit-tests/varmod-path.exp
|
||||
@ -814,6 +823,8 @@ unit-tests/varname-dot-path.exp
|
||||
unit-tests/varname-dot-path.mk
|
||||
unit-tests/varname-dot-shell.exp
|
||||
unit-tests/varname-dot-shell.mk
|
||||
unit-tests/varname-dot-suffixes.exp
|
||||
unit-tests/varname-dot-suffixes.mk
|
||||
unit-tests/varname-dot-targets.exp
|
||||
unit-tests/varname-dot-targets.mk
|
||||
unit-tests/varname-empty.exp
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.114 2020/11/13 21:47:25 sjg Exp $
|
||||
# $Id: Makefile,v 1.117 2021/12/04 18:51:30 sjg Exp $
|
||||
|
||||
PROG= bmake
|
||||
|
||||
@ -8,7 +8,6 @@ SRCS= \
|
||||
compat.c \
|
||||
cond.c \
|
||||
dir.c \
|
||||
enum.c \
|
||||
for.c \
|
||||
hash.c \
|
||||
job.c \
|
||||
@ -92,10 +91,11 @@ isBSD44:=${BSD44_LIST:M${OS}}
|
||||
.if ${isBSD44} == ""
|
||||
MANTARGET= cat
|
||||
INSTALL?=${srcdir}/install-sh
|
||||
.if (${MACHINE} == "sun386")
|
||||
.if ${MACHINE} == "sun386"
|
||||
# even I don't have one of these anymore :-)
|
||||
CFLAGS+= -DPORTAR
|
||||
.elif (${MACHINE} != "sunos")
|
||||
.elif ${OS} != "SunOS"
|
||||
# assume the worst
|
||||
SRCS+= sigcompat.c
|
||||
CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART
|
||||
.endif
|
||||
@ -131,7 +131,7 @@ EXTRACT_MAN=no
|
||||
MAN= ${PROG}.1
|
||||
MAN1= ${MAN}
|
||||
|
||||
.if (${PROG} != "make")
|
||||
.if ${PROG} != "make"
|
||||
CLEANFILES+= my.history
|
||||
.if make(${MAN}) || !exists(${srcdir}/${MAN})
|
||||
my.history:
|
||||
@ -189,11 +189,12 @@ main.o: ${srcdir}/VERSION
|
||||
CONFIGURE_DEPS += ${.CURDIR}/VERSION
|
||||
# we do not need or want the generated makefile
|
||||
CONFIGURE_ARGS += --without-makefile
|
||||
AUTOCONF_GENERATED_MAKEFILE = Makefile.config
|
||||
.include <autoconf.mk>
|
||||
.endif
|
||||
SHARE_MK?=${SHAREDIR}/mk
|
||||
MKSRC=${srcdir}/mk
|
||||
INSTALL?=${srcdir}/install-sh
|
||||
SHARE_MK ?= ${SHAREDIR}/mk
|
||||
MKSRC = ${srcdir}/mk
|
||||
INSTALL ?= ${srcdir}/install-sh
|
||||
|
||||
.if ${MK_INSTALL_MK} == "yes"
|
||||
install: install-mk
|
||||
|
@ -4,7 +4,7 @@ _MAKE_VERSION?=@_MAKE_VERSION@
|
||||
|
||||
prefix?= @prefix@
|
||||
srcdir= @srcdir@
|
||||
CC?= @CC@
|
||||
CC= @CC@
|
||||
@force_machine@MACHINE?= @machine@
|
||||
@force_machine_arch@MACHINE_ARCH?= @machine_arch@
|
||||
DEFAULT_SYS_PATH?= @default_sys_path@
|
||||
|
@ -1,2 +1,2 @@
|
||||
# keep this compatible with sh and make
|
||||
_MAKE_VERSION=20210621
|
||||
_MAKE_VERSION=20211212
|
||||
|
213
contrib/bmake/_strtol.h
Normal file
213
contrib/bmake/_strtol.h
Normal file
@ -0,0 +1,213 @@
|
||||
/* $NetBSD: _strtol.h,v 1.11 2017/07/06 21:08:44 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Original version ID:
|
||||
* NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp
|
||||
*/
|
||||
|
||||
/*
|
||||
* function template for strtol, strtoll and strtoimax.
|
||||
*
|
||||
* parameters:
|
||||
* _FUNCNAME : function name
|
||||
* __INT : return type
|
||||
* __INT_MIN : lower limit of the return type
|
||||
* __INT_MAX : upper limit of the return type
|
||||
*/
|
||||
#if defined(_KERNEL) || defined(_STANDALONE) || defined(HAVE_NBTOOL_CONFIG_H) || defined(BCS_ONLY)
|
||||
__INT
|
||||
_FUNCNAME(const char *nptr, char **endptr, int base)
|
||||
#else
|
||||
#include <locale.h>
|
||||
#include "setlocale_local.h"
|
||||
#define INT_FUNCNAME_(pre, name, post) pre ## name ## post
|
||||
#define INT_FUNCNAME(pre, name, post) INT_FUNCNAME_(pre, name, post)
|
||||
|
||||
static __INT
|
||||
INT_FUNCNAME(_int_, _FUNCNAME, _l)(const char *nptr, char **endptr,
|
||||
int base, locale_t loc)
|
||||
#endif
|
||||
{
|
||||
const char *s;
|
||||
__INT acc, cutoff;
|
||||
unsigned char c;
|
||||
int i, neg, any, cutlim;
|
||||
|
||||
_DIAGASSERT(nptr != NULL);
|
||||
/* endptr may be NULL */
|
||||
|
||||
/* check base value */
|
||||
if (base && (base < 2 || base > 36)) {
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
errno = EINVAL;
|
||||
if (endptr != NULL)
|
||||
/* LINTED interface specification */
|
||||
*endptr = __UNCONST(nptr);
|
||||
return 0;
|
||||
#else
|
||||
panic("%s: invalid base %d", __func__, base);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
s = nptr;
|
||||
#if defined(_KERNEL) || defined(_STANDALONE) || \
|
||||
defined(HAVE_NBTOOL_CONFIG_H) || defined(BCS_ONLY)
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
#else
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace_l(c, loc));
|
||||
#endif
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X') &&
|
||||
((s[1] >= '0' && s[1] <= '9') ||
|
||||
(s[1] >= 'a' && s[1] <= 'f') ||
|
||||
(s[1] >= 'A' && s[1] <= 'F'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
#if 0
|
||||
} else if ((base == 0 || base == 2) &&
|
||||
c == '0' && (*s == 'b' || *s == 'B') &&
|
||||
(s[1] >= '0' && s[1] <= '1')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 2;
|
||||
#endif
|
||||
} else if (base == 0)
|
||||
base = (c == '0' ? 8 : 10);
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = (__INT)(neg ? __INT_MIN : __INT_MAX);
|
||||
cutlim = (int)(cutoff % base);
|
||||
cutoff /= base;
|
||||
if (neg) {
|
||||
if (cutlim > 0) {
|
||||
cutlim -= base;
|
||||
cutoff += 1;
|
||||
}
|
||||
cutlim = -cutlim;
|
||||
}
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (c >= '0' && c <= '9')
|
||||
i = c - '0';
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
i = (c - 'a') + 10;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
i = (c - 'A') + 10;
|
||||
else
|
||||
break;
|
||||
if (i >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (neg) {
|
||||
if (acc < cutoff || (acc == cutoff && i > cutlim)) {
|
||||
acc = __INT_MIN;
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
any = -1;
|
||||
errno = ERANGE;
|
||||
#else
|
||||
any = 0;
|
||||
break;
|
||||
#endif
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc -= i;
|
||||
}
|
||||
} else {
|
||||
if (acc > cutoff || (acc == cutoff && i > cutlim)) {
|
||||
acc = __INT_MAX;
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
any = -1;
|
||||
errno = ERANGE;
|
||||
#else
|
||||
any = 0;
|
||||
break;
|
||||
#endif
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endptr != NULL)
|
||||
/* LINTED interface specification */
|
||||
*endptr = __UNCONST(any ? s - 1 : nptr);
|
||||
return(acc);
|
||||
}
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE) && \
|
||||
!defined(HAVE_NBTOOL_CONFIG_H) && !defined(BCS_ONLY)
|
||||
__INT
|
||||
_FUNCNAME(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return INT_FUNCNAME(_int_, _FUNCNAME, _l)(nptr, endptr, base, _current_locale());
|
||||
}
|
||||
|
||||
__INT
|
||||
INT_FUNCNAME(, _FUNCNAME, _l)(const char *nptr, char **endptr, int base, locale_t loc)
|
||||
{
|
||||
return INT_FUNCNAME(_int_, _FUNCNAME, _l)(nptr, endptr, base, loc);
|
||||
}
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: arch.c,v 1.200 2021/05/30 21:16:54 rillig Exp $ */
|
||||
/* $NetBSD: arch.c,v 1.205 2021/12/12 22:41:47 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -147,7 +147,7 @@ struct ar_hdr {
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */
|
||||
MAKE_RCSID("$NetBSD: arch.c,v 1.200 2021/05/30 21:16:54 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: arch.c,v 1.205 2021/12/12 22:41:47 rillig Exp $");
|
||||
|
||||
typedef struct List ArchList;
|
||||
typedef struct ListNode ArchListNode;
|
||||
@ -250,7 +250,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
char *cp; /* Pointer into line */
|
||||
GNode *gn; /* New node */
|
||||
MFStr libName; /* Library-part of specification */
|
||||
char *memName; /* Member-part of specification */
|
||||
FStr mem; /* Member-part of specification */
|
||||
char saveChar; /* Ending delimiter of member-name */
|
||||
bool expandLibName; /* Whether the parsed libName contains
|
||||
* variable expressions that need to be
|
||||
@ -301,7 +301,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
|
||||
pp_skip_whitespace(&cp);
|
||||
|
||||
memName = cp;
|
||||
mem = FStr_InitRefer(cp);
|
||||
while (*cp != '\0' && *cp != ')' && !ch_isspace(*cp)) {
|
||||
if (*cp == '$') {
|
||||
/* Expand nested variable expressions. */
|
||||
@ -342,7 +342,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
/*
|
||||
* If we didn't move anywhere, we must be done
|
||||
*/
|
||||
if (cp == memName)
|
||||
if (cp == mem.str)
|
||||
break;
|
||||
|
||||
saveChar = *cp;
|
||||
@ -363,22 +363,22 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
*/
|
||||
if (doSubst) {
|
||||
char *fullName;
|
||||
char *p;
|
||||
char *unexpandedMemName = memName;
|
||||
char *p, *expandedMem;
|
||||
const char *unexpandedMem = mem.str;
|
||||
|
||||
(void)Var_Subst(memName, scope, VARE_UNDEFERR,
|
||||
&memName);
|
||||
(void)Var_Subst(mem.str, scope, VARE_UNDEFERR,
|
||||
&expandedMem);
|
||||
/* TODO: handle errors */
|
||||
mem = FStr_InitOwn(expandedMem);
|
||||
|
||||
/*
|
||||
* Now form an archive spec and recurse to deal with
|
||||
* nested variables and multi-word variable values.
|
||||
*/
|
||||
fullName = FullName(libName.str, memName);
|
||||
fullName = FullName(libName.str, mem.str);
|
||||
p = fullName;
|
||||
|
||||
if (strchr(memName, '$') != NULL &&
|
||||
strcmp(memName, unexpandedMemName) == 0) {
|
||||
if (strcmp(mem.str, unexpandedMem) == 0) {
|
||||
/*
|
||||
* Must contain dynamic sources, so we can't
|
||||
* deal with it now. Just create an ARCHV node
|
||||
@ -398,9 +398,9 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
free(fullName);
|
||||
/* XXX: does unexpandedMemName leak? */
|
||||
|
||||
} else if (Dir_HasWildcards(memName)) {
|
||||
} else if (Dir_HasWildcards(mem.str)) {
|
||||
StringList members = LST_INIT;
|
||||
SearchPath_Expand(&dirSearchPath, memName, &members);
|
||||
SearchPath_Expand(&dirSearchPath, mem.str, &members);
|
||||
|
||||
while (!Lst_IsEmpty(&members)) {
|
||||
char *member = Lst_Dequeue(&members);
|
||||
@ -416,7 +416,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
Lst_Done(&members);
|
||||
|
||||
} else {
|
||||
char *fullname = FullName(libName.str, memName);
|
||||
char *fullname = FullName(libName.str, mem.str);
|
||||
gn = Targ_GetNode(fullname);
|
||||
free(fullname);
|
||||
|
||||
@ -430,8 +430,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope)
|
||||
gn->type |= OP_ARCHV;
|
||||
Lst_Append(gns, gn);
|
||||
}
|
||||
if (doSubst)
|
||||
free(memName);
|
||||
FStr_Done(&mem);
|
||||
|
||||
*cp = saveChar;
|
||||
}
|
||||
@ -600,14 +599,14 @@ ArchStatMember(const char *archive, const char *member, bool addToCache)
|
||||
if (strncmp(memName, AR_EFMT1, sizeof AR_EFMT1 - 1) == 0 &&
|
||||
ch_isdigit(memName[sizeof AR_EFMT1 - 1])) {
|
||||
|
||||
int elen = atoi(memName + sizeof AR_EFMT1 - 1);
|
||||
size_t elen = atoi(memName + sizeof AR_EFMT1 - 1);
|
||||
|
||||
if ((unsigned int)elen > MAXPATHLEN)
|
||||
if (elen > MAXPATHLEN)
|
||||
goto badarch;
|
||||
if (fread(memName, (size_t)elen, 1, arch) != 1)
|
||||
if (fread(memName, elen, 1, arch) != 1)
|
||||
goto badarch;
|
||||
memName[elen] = '\0';
|
||||
if (fseek(arch, -elen, SEEK_CUR) != 0)
|
||||
if (fseek(arch, -(long)elen, SEEK_CUR) != 0)
|
||||
goto badarch;
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
debug_printf(
|
||||
@ -839,14 +838,15 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
|
||||
if (strncmp(out_arh->AR_NAME, AR_EFMT1, sizeof AR_EFMT1 - 1) ==
|
||||
0 &&
|
||||
(ch_isdigit(out_arh->AR_NAME[sizeof AR_EFMT1 - 1]))) {
|
||||
int elen = atoi(&out_arh->AR_NAME[sizeof AR_EFMT1 - 1]);
|
||||
size_t elen = atoi(
|
||||
&out_arh->AR_NAME[sizeof AR_EFMT1 - 1]);
|
||||
char ename[MAXPATHLEN + 1];
|
||||
|
||||
if ((unsigned int)elen > MAXPATHLEN) {
|
||||
if (elen > MAXPATHLEN) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
if (fread(ename, (size_t)elen, 1, arch) != 1) {
|
||||
if (fread(ename, elen, 1, arch) != 1) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -859,14 +859,14 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
|
||||
if (strncmp(ename, member, len) == 0) {
|
||||
/* Found as extended name */
|
||||
if (fseek(arch,
|
||||
-(long)sizeof(struct ar_hdr) - elen,
|
||||
SEEK_CUR) != 0) {
|
||||
-(long)(sizeof(struct ar_hdr) - elen),
|
||||
SEEK_CUR) != 0) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
return arch;
|
||||
}
|
||||
if (fseek(arch, -elen, SEEK_CUR) != 0) {
|
||||
if (fseek(arch, -(long)elen, SEEK_CUR) != 0) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -882,7 +882,7 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh,
|
||||
*/
|
||||
out_arh->AR_SIZE[sizeof out_arh->AR_SIZE - 1] = '\0';
|
||||
size = (int)strtol(out_arh->AR_SIZE, NULL, 10);
|
||||
if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) {
|
||||
if (fseek(arch, (size + 1) & ~1L, SEEK_CUR) != 0) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -991,12 +991,12 @@ Arch_UpdateMemberMTime(GNode *gn)
|
||||
const char *nameEnd = strchr(nameStart, ')');
|
||||
size_t nameLen = (size_t)(nameEnd - nameStart);
|
||||
|
||||
if ((pgn->flags & REMAKE) &&
|
||||
if (pgn->flags.remake &&
|
||||
strncmp(nameStart, gn->name, nameLen) == 0) {
|
||||
Arch_UpdateMTime(pgn);
|
||||
gn->mtime = pgn->mtime;
|
||||
}
|
||||
} else if (pgn->flags & REMAKE) {
|
||||
} else if (pgn->flags.remake) {
|
||||
/*
|
||||
* Something which isn't a library depends on the
|
||||
* existence of this target, so it needs to exist.
|
||||
@ -1036,6 +1036,35 @@ Arch_FindLib(GNode *gn, SearchPath *path)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static bool
|
||||
RanlibOODate(const GNode *gn MAKE_ATTR_UNUSED)
|
||||
{
|
||||
#ifdef RANLIBMAG
|
||||
struct ar_hdr *arh; /* Header for __.SYMDEF */
|
||||
int tocModTime; /* The table-of-contents' mod time */
|
||||
|
||||
arh = ArchStatMember(gn->path, RANLIBMAG, false);
|
||||
|
||||
if (arh == NULL) {
|
||||
/* A library without a table of contents is out-of-date. */
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
debug_printf("no toc...");
|
||||
return true;
|
||||
}
|
||||
|
||||
tocModTime = (int)strtol(arh->ar_date, NULL, 10);
|
||||
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
debug_printf("%s modified %s...",
|
||||
RANLIBMAG, Targ_FmtTime(tocModTime));
|
||||
return gn->youngestChild == NULL ||
|
||||
gn->youngestChild->mtime > tocModTime;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Decide if a node with the OP_LIB attribute is out-of-date. Called from
|
||||
* GNode_IsOODate to make its life easier.
|
||||
@ -1069,46 +1098,19 @@ Arch_FindLib(GNode *gn, SearchPath *path)
|
||||
bool
|
||||
Arch_LibOODate(GNode *gn)
|
||||
{
|
||||
bool oodate;
|
||||
|
||||
if (gn->type & OP_PHONY) {
|
||||
oodate = true;
|
||||
return true;
|
||||
} else if (!GNode_IsTarget(gn) && Lst_IsEmpty(&gn->children)) {
|
||||
oodate = false;
|
||||
return false;
|
||||
} else if ((!Lst_IsEmpty(&gn->children) && gn->youngestChild == NULL) ||
|
||||
(gn->mtime > now) ||
|
||||
(gn->youngestChild != NULL &&
|
||||
gn->mtime < gn->youngestChild->mtime)) {
|
||||
oodate = true;
|
||||
return true;
|
||||
} else {
|
||||
#ifdef RANLIBMAG
|
||||
struct ar_hdr *arh; /* Header for __.SYMDEF */
|
||||
int modTimeTOC; /* The table-of-contents' mod time */
|
||||
|
||||
arh = ArchStatMember(gn->path, RANLIBMAG, false);
|
||||
|
||||
if (arh != NULL) {
|
||||
modTimeTOC = (int)strtol(arh->ar_date, NULL, 10);
|
||||
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
debug_printf("%s modified %s...",
|
||||
RANLIBMAG,
|
||||
Targ_FmtTime(modTimeTOC));
|
||||
oodate = gn->youngestChild == NULL ||
|
||||
gn->youngestChild->mtime > modTimeTOC;
|
||||
} else {
|
||||
/*
|
||||
* A library without a table of contents is out-of-date.
|
||||
*/
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
debug_printf("no toc...");
|
||||
oodate = true;
|
||||
}
|
||||
#else
|
||||
oodate = false;
|
||||
#endif
|
||||
return RanlibOODate(gn);
|
||||
}
|
||||
return oodate;
|
||||
}
|
||||
|
||||
/* Initialize the archives module. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: make.1,v 1.296 2021/02/04 21:42:46 rillig Exp $
|
||||
.\" $NetBSD: make.1,v 1.300 2021/12/12 20:45:48 sjg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\"
|
||||
.Dd December 22, 2020
|
||||
.Dd December 12, 2021
|
||||
.Dt BMAKE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1163,6 +1163,9 @@ executes.
|
||||
.It Ev .SHELL
|
||||
The pathname of the shell used to run target scripts.
|
||||
It is read-only.
|
||||
.It Ev .SUFFIXES
|
||||
The list of known suffixes.
|
||||
It is read-only.
|
||||
.It Ev .TARGETS
|
||||
The list of targets explicitly specified on the command line, if any.
|
||||
.It Ev VPATH
|
||||
@ -1233,8 +1236,20 @@ but selects all words which do not match
|
||||
.Ar pattern .
|
||||
.It Cm \&:O
|
||||
Orders every word in variable alphabetically.
|
||||
.It Cm \&:On
|
||||
Orders every word in variable numerically.
|
||||
A number followed by one of
|
||||
.Ql k ,
|
||||
.Ql M
|
||||
or
|
||||
.Ql G
|
||||
is multiplied by the appropriate factor (1024 (k), 1048576 (M), or
|
||||
1073741824 (G)).
|
||||
Both upper- and lower-case letters are accepted.
|
||||
.It Cm \&:Or
|
||||
Orders every word in variable in reverse alphabetical order.
|
||||
.It Cm \&:Orn
|
||||
Orders every word in variable in reverse numerical order.
|
||||
.It Cm \&:Ox
|
||||
Shuffles the words in variable.
|
||||
The results will be different each time you are referring to the
|
||||
|
@ -757,6 +757,8 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
.SHELL The pathname of the shell used to run target scripts. It
|
||||
is read-only.
|
||||
|
||||
.SUFFIXES The list of known suffixes. It is read-only.
|
||||
|
||||
.TARGETS The list of targets explicitly specified on the command
|
||||
line, if any.
|
||||
|
||||
@ -809,8 +811,16 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
[1m:O [22mOrders every word in variable alphabetically.
|
||||
|
||||
[1m:On [22mOrders every word in variable numerically. A number followed by one
|
||||
of `k', `M' or `G' is multiplied by the appropriate factor (1024
|
||||
(k), 1048576 (M), or 1073741824 (G)). Both upper- and lower-case
|
||||
letters are accepted.
|
||||
|
||||
[1m:Or [22mOrders every word in variable in reverse alphabetical order.
|
||||
|
||||
[1m:Orn[0m
|
||||
Orders every word in variable in reverse numerical order.
|
||||
|
||||
[1m:Ox [22mShuffles the words in variable. The results will be different each
|
||||
time you are referring to the modified variable; use the assignment
|
||||
with expansion (`[1m:=[22m') to prevent such behavior. For example,
|
||||
@ -1581,4 +1591,4 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
There is no way of escaping a space character in a filename.
|
||||
|
||||
FreeBSD 13.0 December 22, 2020 FreeBSD 13.0
|
||||
FreeBSD 13.0 December 12, 2021 FreeBSD 13.0
|
||||
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 81 KiB |
@ -119,7 +119,7 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: boot-strap,v 1.54 2020/11/13 21:47:25 sjg Exp $
|
||||
# $Id: boot-strap,v 1.57 2021/10/22 20:32:21 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2001 Simon J. Gerraty
|
||||
#
|
||||
@ -405,17 +405,6 @@ Bmake() {
|
||||
)
|
||||
}
|
||||
|
||||
# there is actually a shell where type is not a builtin
|
||||
# if type is missing, which(1) had better exists!
|
||||
if (type cat) > /dev/null 2>&1; then
|
||||
which() {
|
||||
type "$@" | sed 's,[()],,g;s,^[^/][^/]*,,;q'
|
||||
}
|
||||
fi
|
||||
# make sure test below uses the same diff that configure did
|
||||
TOOL_DIFF=`which diff`
|
||||
export TOOL_DIFF
|
||||
|
||||
op_configure() {
|
||||
$srcdir/configure $CONFIGURE_ARGS || exit 1
|
||||
}
|
||||
@ -431,7 +420,7 @@ op_build() {
|
||||
|
||||
op_test() {
|
||||
[ -x bmake ] || op_build
|
||||
Bmake test || exit 1
|
||||
Bmake test "$@" || exit 1
|
||||
}
|
||||
|
||||
op_clean() {
|
||||
@ -483,5 +472,5 @@ You may need the -r or -R option to more/less to view it correctly.
|
||||
EOM
|
||||
}
|
||||
|
||||
op_$op
|
||||
op_$op "$@"
|
||||
exit 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: bsd.after-import.mk,v 1.16 2020/07/12 03:39:01 sjg Exp $
|
||||
# $Id: bsd.after-import.mk,v 1.17 2021/10/22 06:31:32 sjg Exp $
|
||||
|
||||
# This makefile is for use when integrating bmake into a BSD build
|
||||
# system. Use this makefile after importing bmake.
|
||||
@ -59,6 +59,7 @@ bootstrap: ${BMAKE_SRC}/boot-strap ${MAKEFILE}
|
||||
# Makefiles need a little more tweaking than say config.h
|
||||
MAKEFILE_SED = sed -e '/^MACHINE/d' \
|
||||
-e '/include.*VERSION/d' \
|
||||
-e '/^CC=/s,=,?=,' \
|
||||
-e '/^PROG/ { s,=,?=,;s,bmake,$${.CURDIR:T},; }' \
|
||||
-e 's,^.-include,.sinclude,' \
|
||||
-e '/^\..*include *</ { s,<,<bsd.,;/autoconf/d; }' \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.c,v 1.51 2021/01/30 21:18:14 rillig Exp $ */
|
||||
/* $NetBSD: buf.c,v 1.53 2021/11/28 22:48:06 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -75,7 +75,7 @@
|
||||
#include "make.h"
|
||||
|
||||
/* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */
|
||||
MAKE_RCSID("$NetBSD: buf.c,v 1.51 2021/01/30 21:18:14 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: buf.c,v 1.53 2021/11/28 22:48:06 rillig Exp $");
|
||||
|
||||
/* Make space in the buffer for adding at least 16 more bytes. */
|
||||
void
|
||||
@ -122,19 +122,22 @@ Buf_AddStr(Buffer *buf, const char *str)
|
||||
void
|
||||
Buf_AddInt(Buffer *buf, int n)
|
||||
{
|
||||
enum {
|
||||
bits = sizeof(int) * CHAR_BIT,
|
||||
max_octal_digits = (bits + 2) / 3,
|
||||
max_decimal_digits = /* at most */ max_octal_digits,
|
||||
max_sign_chars = 1,
|
||||
str_size = max_sign_chars + max_decimal_digits + 1
|
||||
};
|
||||
char str[str_size];
|
||||
char str[sizeof(int) * CHAR_BIT + 1];
|
||||
|
||||
size_t len = (size_t)snprintf(str, sizeof str, "%d", n);
|
||||
Buf_AddBytes(buf, str, len);
|
||||
}
|
||||
|
||||
void
|
||||
Buf_AddFlag(Buffer *buf, bool flag, const char *name)
|
||||
{
|
||||
if (flag) {
|
||||
if (buf->len > 0)
|
||||
Buf_AddByte(buf, '|');
|
||||
Buf_AddBytes(buf, name, strlen(name));
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the buffer as empty, so it can be filled with data again. */
|
||||
void
|
||||
Buf_Empty(Buffer *buf)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.h,v 1.43 2021/04/03 11:08:40 rillig Exp $ */
|
||||
/* $NetBSD: buf.h,v 1.44 2021/11/28 22:48:06 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -111,6 +111,7 @@ void Buf_AddBytes(Buffer *, const char *, size_t);
|
||||
void Buf_AddBytesBetween(Buffer *, const char *, const char *);
|
||||
void Buf_AddStr(Buffer *, const char *);
|
||||
void Buf_AddInt(Buffer *, int);
|
||||
void Buf_AddFlag(Buffer *, bool, const char *);
|
||||
void Buf_Empty(Buffer *);
|
||||
void Buf_Init(Buffer *);
|
||||
void Buf_InitSize(Buffer *, size_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.c,v 1.227 2021/04/27 15:19:25 christos Exp $ */
|
||||
/* $NetBSD: compat.c,v 1.229 2021/11/28 23:12:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -99,7 +99,7 @@
|
||||
#include "pathnames.h"
|
||||
|
||||
/* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: compat.c,v 1.227 2021/04/27 15:19:25 christos Exp $");
|
||||
MAKE_RCSID("$NetBSD: compat.c,v 1.229 2021/11/28 23:12:51 rillig Exp $");
|
||||
|
||||
static GNode *curTarg = NULL;
|
||||
static pid_t compatChild;
|
||||
@ -187,7 +187,7 @@ DebugFailedTarget(const char *cmd, const GNode *gn)
|
||||
static bool
|
||||
UseShell(const char *cmd MAKE_ATTR_UNUSED)
|
||||
{
|
||||
#if !defined(MAKE_NATIVE)
|
||||
#if defined(FORCE_USE_SHELL) || !defined(MAKE_NATIVE)
|
||||
/*
|
||||
* In a non-native build, the host environment might be weird enough
|
||||
* that it's necessary to go through a shell to get the correct
|
||||
@ -240,7 +240,7 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln)
|
||||
* using a shell */
|
||||
const char *volatile cmd = cmdp;
|
||||
|
||||
silent = (gn->type & OP_SILENT) != 0;
|
||||
silent = (gn->type & OP_SILENT) != OP_NONE;
|
||||
errCheck = !(gn->type & OP_IGNORE);
|
||||
doIt = false;
|
||||
|
||||
@ -497,7 +497,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
* again. This is our signal to not attempt to do anything but abort
|
||||
* our parent as well.
|
||||
*/
|
||||
gn->flags |= REMAKE;
|
||||
gn->flags.remake = true;
|
||||
gn->made = BEINGMADE;
|
||||
|
||||
if (!(gn->type & OP_MADE))
|
||||
@ -505,9 +505,9 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
|
||||
MakeNodes(&gn->children, gn);
|
||||
|
||||
if (!(gn->flags & REMAKE)) {
|
||||
if (!gn->flags.remake) {
|
||||
gn->made = ABORTED;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
pgn->flags.remake = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -565,7 +565,7 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
RunCommands(gn);
|
||||
curTarg = NULL;
|
||||
} else {
|
||||
Job_Touch(gn, (gn->type & OP_SILENT) != 0);
|
||||
Job_Touch(gn, (gn->type & OP_SILENT) != OP_NONE);
|
||||
}
|
||||
} else {
|
||||
gn->made = ERROR;
|
||||
@ -585,13 +585,13 @@ MakeUnmade(GNode *gn, GNode *pgn)
|
||||
*/
|
||||
gn->made = MADE;
|
||||
if (Make_Recheck(gn) == 0)
|
||||
pgn->flags |= FORCE;
|
||||
pgn->flags.force = true;
|
||||
if (!(gn->type & OP_EXEC)) {
|
||||
pgn->flags |= CHILDMADE;
|
||||
pgn->flags.childMade = true;
|
||||
GNode_UpdateYoungestChild(pgn, gn);
|
||||
}
|
||||
} else if (opts.keepgoing) {
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
pgn->flags.remake = false;
|
||||
} else {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
@ -612,11 +612,11 @@ MakeOther(GNode *gn, GNode *pgn)
|
||||
case BEINGMADE:
|
||||
Error("Graph cycles through %s", gn->name);
|
||||
gn->made = ERROR;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
pgn->flags.remake = false;
|
||||
break;
|
||||
case MADE:
|
||||
if (!(gn->type & OP_EXEC)) {
|
||||
pgn->flags |= CHILDMADE;
|
||||
pgn->flags.childMade = true;
|
||||
GNode_UpdateYoungestChild(pgn, gn);
|
||||
}
|
||||
break;
|
||||
@ -663,7 +663,7 @@ Compat_Make(GNode *gn, GNode *pgn)
|
||||
* Already had an error when making this.
|
||||
* Tell the parent to abort.
|
||||
*/
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
pgn->flags.remake = false;
|
||||
} else {
|
||||
MakeOther(gn, pgn);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cond.c,v 1.267 2021/06/11 14:52:03 rillig Exp $ */
|
||||
/* $NetBSD: cond.c,v 1.302 2021/12/12 09:36:00 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -95,14 +95,12 @@
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
|
||||
MAKE_RCSID("$NetBSD: cond.c,v 1.267 2021/06/11 14:52:03 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: cond.c,v 1.302 2021/12/12 09:36:00 rillig Exp $");
|
||||
|
||||
/*
|
||||
* The parsing of conditional expressions is based on this grammar:
|
||||
* Or -> And '||' Or
|
||||
* Or -> And
|
||||
* And -> Term '&&' And
|
||||
* And -> Term
|
||||
* Or -> And ('||' And)*
|
||||
* And -> Term ('&&' Term)*
|
||||
* Term -> Function '(' Argument ')'
|
||||
* Term -> Leaf Operator Leaf
|
||||
* Term -> Leaf
|
||||
@ -151,9 +149,23 @@ typedef struct CondParser {
|
||||
bool plain;
|
||||
|
||||
/* The function to apply on unquoted bare words. */
|
||||
bool (*evalBare)(size_t, const char *);
|
||||
bool (*evalBare)(const char *);
|
||||
bool negateEvalBare;
|
||||
|
||||
/*
|
||||
* Whether the left-hand side of a comparison may be an unquoted
|
||||
* string. This is allowed for expressions of the form
|
||||
* ${condition:?:}, see ApplyModifier_IfElse. Such a condition is
|
||||
* expanded before it is evaluated, due to ease of implementation.
|
||||
* This means that at the point where the condition is evaluated,
|
||||
* make cannot know anymore whether the left-hand side had originally
|
||||
* been a variable expression or a plain word.
|
||||
*
|
||||
* In all other contexts, the left-hand side must either be a
|
||||
* variable expression, a quoted string or a number.
|
||||
*/
|
||||
bool leftUnquotedOK;
|
||||
|
||||
const char *p; /* The remaining condition to parse */
|
||||
Token curr; /* Single push-back token used in parsing */
|
||||
|
||||
@ -171,24 +183,13 @@ static CondResult CondParser_Or(CondParser *par, bool);
|
||||
static unsigned int cond_depth = 0; /* current .if nesting level */
|
||||
static unsigned int cond_min_depth = 0; /* depth at makefile open */
|
||||
|
||||
static const char *opname[] = { "<", "<=", ">", ">=", "==", "!=" };
|
||||
|
||||
/*
|
||||
* Indicate when we should be strict about lhs of comparisons.
|
||||
* In strict mode, the lhs must be a variable expression or a string literal
|
||||
* in quotes. In non-strict mode it may also be an unquoted string literal.
|
||||
*
|
||||
* True when CondEvalExpression is called from Cond_EvalLine (.if etc).
|
||||
* False when CondEvalExpression is called from ApplyModifier_IfElse
|
||||
* since lhs is already expanded, and at that point we cannot tell if
|
||||
* it was a variable reference or not.
|
||||
*/
|
||||
static bool lhsStrict;
|
||||
/* Names for ComparisonOp. */
|
||||
static const char opname[][3] = { "<", "<=", ">", ">=", "==", "!=" };
|
||||
|
||||
static bool
|
||||
is_token(const char *str, const char *tok, size_t len)
|
||||
is_token(const char *str, const char *tok, unsigned char len)
|
||||
{
|
||||
return strncmp(str, tok, len) == 0 && !ch_isalpha(str[len]);
|
||||
return strncmp(str, tok, (size_t)len) == 0 && !ch_isalpha(str[len]);
|
||||
}
|
||||
|
||||
static Token
|
||||
@ -197,16 +198,6 @@ ToToken(bool cond)
|
||||
return cond ? TOK_TRUE : TOK_FALSE;
|
||||
}
|
||||
|
||||
/* Push back the most recent token read. We only need one level of this. */
|
||||
static void
|
||||
CondParser_PushBack(CondParser *par, Token t)
|
||||
{
|
||||
assert(par->curr == TOK_NONE);
|
||||
assert(t != TOK_NONE);
|
||||
|
||||
par->curr = t;
|
||||
}
|
||||
|
||||
static void
|
||||
CondParser_SkipWhitespace(CondParser *par)
|
||||
{
|
||||
@ -214,7 +205,9 @@ CondParser_SkipWhitespace(CondParser *par)
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the argument of a built-in function.
|
||||
* Parse a single word, taking into account balanced parentheses as well as
|
||||
* embedded expressions. Used for the argument of a built-in function as
|
||||
* well as for bare words, which are then passed to the default function.
|
||||
*
|
||||
* Arguments:
|
||||
* *pp initially points at the '(',
|
||||
@ -223,12 +216,12 @@ CondParser_SkipWhitespace(CondParser *par)
|
||||
* *out_arg receives the argument as string.
|
||||
*
|
||||
* func says whether the argument belongs to an actual function, or
|
||||
* whether the parsed argument is passed to the default function.
|
||||
* NULL when parsing a bare word.
|
||||
*
|
||||
* Return the length of the argument, or 0 on error.
|
||||
* Return the length of the argument, or an ambiguous 0 on error.
|
||||
*/
|
||||
static size_t
|
||||
ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func,
|
||||
ParseWord(CondParser *par, const char **pp, bool doEval, const char *func,
|
||||
char **out_arg)
|
||||
{
|
||||
const char *p = *pp;
|
||||
@ -239,11 +232,6 @@ ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func,
|
||||
if (func != NULL)
|
||||
p++; /* Skip opening '(' - verified by caller */
|
||||
|
||||
if (*p == '\0') {
|
||||
*out_arg = NULL; /* Missing closing parenthesis: */
|
||||
return 0; /* .if defined( */
|
||||
}
|
||||
|
||||
cpp_skip_hspace(&p);
|
||||
|
||||
Buf_InitSize(&argBuf, 16);
|
||||
@ -299,9 +287,8 @@ ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func,
|
||||
}
|
||||
|
||||
/* Test whether the given variable is defined. */
|
||||
/*ARGSUSED*/
|
||||
static bool
|
||||
FuncDefined(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
FuncDefined(const char *arg)
|
||||
{
|
||||
FStr value = Var_Value(SCOPE_CMDLINE, arg);
|
||||
bool result = value.str != NULL;
|
||||
@ -309,10 +296,9 @@ FuncDefined(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* See if the given target is being made. */
|
||||
/*ARGSUSED*/
|
||||
/* See if the given target is requested to be made. */
|
||||
static bool
|
||||
FuncMake(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
FuncMake(const char *arg)
|
||||
{
|
||||
StringListNode *ln;
|
||||
|
||||
@ -323,9 +309,8 @@ FuncMake(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
}
|
||||
|
||||
/* See if the given file exists. */
|
||||
/*ARGSUSED*/
|
||||
static bool
|
||||
FuncExists(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
FuncExists(const char *arg)
|
||||
{
|
||||
bool result;
|
||||
char *path;
|
||||
@ -339,9 +324,8 @@ FuncExists(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
}
|
||||
|
||||
/* See if the given node exists and is an actual target. */
|
||||
/*ARGSUSED*/
|
||||
static bool
|
||||
FuncTarget(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
FuncTarget(const char *arg)
|
||||
{
|
||||
GNode *gn = Targ_FindNode(arg);
|
||||
return gn != NULL && GNode_IsTarget(gn);
|
||||
@ -351,9 +335,8 @@ FuncTarget(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
* See if the given node exists and is an actual target with commands
|
||||
* associated with it.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static bool
|
||||
FuncCommands(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
|
||||
FuncCommands(const char *arg)
|
||||
{
|
||||
GNode *gn = Targ_FindNode(arg);
|
||||
return gn != NULL && GNode_IsTarget(gn) && !Lst_IsEmpty(&gn->commands);
|
||||
@ -375,12 +358,12 @@ TryParseNumber(const char *str, double *out_value)
|
||||
unsigned long ul_val;
|
||||
double dbl_val;
|
||||
|
||||
errno = 0;
|
||||
if (str[0] == '\0') { /* XXX: why is an empty string a number? */
|
||||
*out_value = 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
ul_val = strtoul(str, &end, str[1] == 'x' ? 16 : 10);
|
||||
if (*end == '\0' && errno != ERANGE) {
|
||||
*out_value = str[0] == '-' ? -(double)-ul_val : (double)ul_val;
|
||||
@ -412,17 +395,16 @@ is_separator(char ch)
|
||||
*/
|
||||
static bool
|
||||
CondParser_StringExpr(CondParser *par, const char *start,
|
||||
bool const doEval, bool const quoted,
|
||||
Buffer *buf, FStr *const inout_str)
|
||||
bool doEval, bool quoted,
|
||||
Buffer *buf, FStr *inout_str)
|
||||
{
|
||||
VarEvalMode emode;
|
||||
const char *nested_p;
|
||||
bool atStart;
|
||||
VarParseResult parseResult;
|
||||
|
||||
/* if we are in quotes, an undefined variable is ok */
|
||||
emode = doEval && !quoted ? VARE_UNDEFERR
|
||||
: doEval ? VARE_WANTRES
|
||||
emode = doEval && quoted ? VARE_WANTRES
|
||||
: doEval ? VARE_UNDEFERR
|
||||
: VARE_PARSE_ONLY;
|
||||
|
||||
nested_p = par->p;
|
||||
@ -477,7 +459,7 @@ CondParser_StringExpr(CondParser *par, const char *start,
|
||||
* Sets out_quoted if the leaf was a quoted string literal.
|
||||
*/
|
||||
static void
|
||||
CondParser_Leaf(CondParser *par, bool doEval, bool strictLHS,
|
||||
CondParser_Leaf(CondParser *par, bool doEval, bool unquotedOK,
|
||||
FStr *out_str, bool *out_quoted)
|
||||
{
|
||||
Buffer buf;
|
||||
@ -525,11 +507,11 @@ CondParser_Leaf(CondParser *par, bool doEval, bool strictLHS,
|
||||
goto cleanup;
|
||||
continue;
|
||||
default:
|
||||
if (strictLHS && !quoted && *start != '$' &&
|
||||
if (!unquotedOK && !quoted && *start != '$' &&
|
||||
!ch_isdigit(*start)) {
|
||||
/*
|
||||
* The left-hand side must be quoted,
|
||||
* a variable reference or a number.
|
||||
* a variable expression or a number.
|
||||
*/
|
||||
str = FStr_InitRefer(NULL);
|
||||
goto cleanup;
|
||||
@ -541,15 +523,16 @@ CondParser_Leaf(CondParser *par, bool doEval, bool strictLHS,
|
||||
}
|
||||
got_str:
|
||||
str = FStr_InitOwn(buf.data);
|
||||
buf.data = NULL;
|
||||
cleanup:
|
||||
Buf_DoneData(&buf); /* XXX: memory leak on failure? */
|
||||
Buf_Done(&buf);
|
||||
*out_str = str;
|
||||
}
|
||||
|
||||
static bool
|
||||
EvalBare(const CondParser *par, const char *arg, size_t arglen)
|
||||
EvalBare(const CondParser *par, const char *arg)
|
||||
{
|
||||
bool res = par->evalBare(arglen, arg);
|
||||
bool res = par->evalBare(arg);
|
||||
return par->negateEvalBare ? !res : res;
|
||||
}
|
||||
|
||||
@ -573,11 +556,14 @@ EvalNotEmpty(CondParser *par, const char *value, bool quoted)
|
||||
/* For .if ${...}, check for non-empty string. This is different from
|
||||
* the evaluation function from that .if variant, which would test
|
||||
* whether a variable of the given name were defined. */
|
||||
/* XXX: Whitespace should count as empty, just as in ParseEmptyArg. */
|
||||
/*
|
||||
* XXX: Whitespace should count as empty, just as in
|
||||
* CondParser_FuncCallEmpty.
|
||||
*/
|
||||
if (par->plain)
|
||||
return value[0] != '\0';
|
||||
|
||||
return EvalBare(par, value, strlen(value));
|
||||
return EvalBare(par, value);
|
||||
}
|
||||
|
||||
/* Evaluate a numerical comparison, such as in ".if ${VAR} >= 9". */
|
||||
@ -682,11 +668,7 @@ CondParser_Comparison(CondParser *par, bool doEval)
|
||||
ComparisonOp op;
|
||||
bool lhsQuoted, rhsQuoted;
|
||||
|
||||
/*
|
||||
* Parse the variable spec and skip over it, saving its
|
||||
* value in lhs.
|
||||
*/
|
||||
CondParser_Leaf(par, doEval, lhsStrict, &lhs, &lhsQuoted);
|
||||
CondParser_Leaf(par, doEval, par->leftUnquotedOK, &lhs, &lhsQuoted);
|
||||
if (lhs.str == NULL)
|
||||
goto done_lhs;
|
||||
|
||||
@ -702,12 +684,12 @@ CondParser_Comparison(CondParser *par, bool doEval)
|
||||
|
||||
if (par->p[0] == '\0') {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Missing right-hand-side of operator '%s'", opname[op]);
|
||||
"Missing right-hand side of operator '%s'", opname[op]);
|
||||
par->printedError = true;
|
||||
goto done_lhs;
|
||||
}
|
||||
|
||||
CondParser_Leaf(par, doEval, false, &rhs, &rhsQuoted);
|
||||
CondParser_Leaf(par, doEval, true, &rhs, &rhsQuoted);
|
||||
if (rhs.str == NULL)
|
||||
goto done_rhs;
|
||||
|
||||
@ -729,50 +711,37 @@ CondParser_Comparison(CondParser *par, bool doEval)
|
||||
* The argument to empty() is a variable name, optionally followed by
|
||||
* variable modifiers.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static size_t
|
||||
ParseEmptyArg(CondParser *par MAKE_ATTR_UNUSED, const char **pp,
|
||||
bool doEval, const char *func MAKE_ATTR_UNUSED,
|
||||
char **out_arg)
|
||||
static bool
|
||||
CondParser_FuncCallEmpty(CondParser *par, bool doEval, Token *out_token)
|
||||
{
|
||||
const char *cp = par->p;
|
||||
Token tok;
|
||||
FStr val;
|
||||
size_t magic_res;
|
||||
|
||||
/* We do all the work here and return the result as the length */
|
||||
*out_arg = NULL;
|
||||
if (!is_token(cp, "empty", 5))
|
||||
return false;
|
||||
cp += 5;
|
||||
|
||||
(*pp)--; /* Make (*pp)[1] point to the '('. */
|
||||
(void)Var_Parse(pp, SCOPE_CMDLINE,
|
||||
cpp_skip_whitespace(&cp);
|
||||
if (*cp != '(')
|
||||
return false;
|
||||
|
||||
cp--; /* Make cp[1] point to the '('. */
|
||||
(void)Var_Parse(&cp, SCOPE_CMDLINE,
|
||||
doEval ? VARE_WANTRES : VARE_PARSE_ONLY, &val);
|
||||
/* TODO: handle errors */
|
||||
/* If successful, *pp points beyond the closing ')' now. */
|
||||
|
||||
if (val.str == var_Error) {
|
||||
FStr_Done(&val);
|
||||
return (size_t)-1;
|
||||
if (val.str == var_Error)
|
||||
tok = TOK_ERROR;
|
||||
else {
|
||||
cpp_skip_whitespace(&val.str);
|
||||
tok = val.str[0] != '\0' && doEval ? TOK_FALSE : TOK_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* A variable is empty when it just contains spaces...
|
||||
* 4/15/92, christos
|
||||
*/
|
||||
cpp_skip_whitespace(&val.str);
|
||||
|
||||
/*
|
||||
* For consistency with the other functions we can't generate the
|
||||
* true/false here.
|
||||
*/
|
||||
magic_res = val.str[0] != '\0' ? 2 : 1;
|
||||
FStr_Done(&val);
|
||||
return magic_res;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static bool
|
||||
FuncEmpty(size_t arglen, const char *arg MAKE_ATTR_UNUSED)
|
||||
{
|
||||
/* Magic values ahead, see ParseEmptyArg. */
|
||||
return arglen == 1;
|
||||
*out_token = tok;
|
||||
par->p = cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parse a function call expression, such as 'defined(${file})'. */
|
||||
@ -780,61 +749,51 @@ static bool
|
||||
CondParser_FuncCall(CondParser *par, bool doEval, Token *out_token)
|
||||
{
|
||||
static const struct fn_def {
|
||||
const char *fn_name;
|
||||
size_t fn_name_len;
|
||||
size_t (*fn_parse)(CondParser *, const char **, bool,
|
||||
const char *, char **);
|
||||
bool (*fn_eval)(size_t, const char *);
|
||||
const char fn_name[9];
|
||||
unsigned char fn_name_len;
|
||||
bool (*fn_eval)(const char *);
|
||||
} fns[] = {
|
||||
{ "defined", 7, ParseFuncArg, FuncDefined },
|
||||
{ "make", 4, ParseFuncArg, FuncMake },
|
||||
{ "exists", 6, ParseFuncArg, FuncExists },
|
||||
{ "empty", 5, ParseEmptyArg, FuncEmpty },
|
||||
{ "target", 6, ParseFuncArg, FuncTarget },
|
||||
{ "commands", 8, ParseFuncArg, FuncCommands }
|
||||
{ "defined", 7, FuncDefined },
|
||||
{ "make", 4, FuncMake },
|
||||
{ "exists", 6, FuncExists },
|
||||
{ "target", 6, FuncTarget },
|
||||
{ "commands", 8, FuncCommands }
|
||||
};
|
||||
const struct fn_def *fn;
|
||||
char *arg = NULL;
|
||||
size_t arglen;
|
||||
const char *cp = par->p;
|
||||
const struct fn_def *fns_end = fns + sizeof fns / sizeof fns[0];
|
||||
const struct fn_def *last_fn = fns + sizeof fns / sizeof fns[0] - 1;
|
||||
|
||||
for (fn = fns; fn != fns_end; fn++) {
|
||||
if (!is_token(cp, fn->fn_name, fn->fn_name_len))
|
||||
continue;
|
||||
for (fn = fns; !is_token(cp, fn->fn_name, fn->fn_name_len); fn++)
|
||||
if (fn == last_fn)
|
||||
return false;
|
||||
|
||||
cp += fn->fn_name_len;
|
||||
cpp_skip_whitespace(&cp);
|
||||
if (*cp != '(')
|
||||
break;
|
||||
cp += fn->fn_name_len;
|
||||
cpp_skip_whitespace(&cp);
|
||||
if (*cp != '(')
|
||||
return false;
|
||||
|
||||
arglen = fn->fn_parse(par, &cp, doEval, fn->fn_name, &arg);
|
||||
if (arglen == 0 || arglen == (size_t)-1) {
|
||||
par->p = cp;
|
||||
*out_token = arglen == 0 ? TOK_FALSE : TOK_ERROR;
|
||||
return true;
|
||||
}
|
||||
arglen = ParseWord(par, &cp, doEval, fn->fn_name, &arg);
|
||||
*out_token = ToToken(arglen != 0 && (!doEval || fn->fn_eval(arg)));
|
||||
|
||||
/* Evaluate the argument using the required function. */
|
||||
*out_token = ToToken(!doEval || fn->fn_eval(arglen, arg));
|
||||
free(arg);
|
||||
par->p = cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
free(arg);
|
||||
par->p = cp;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a comparison such as '${VAR} == "value"', or a simple leaf without
|
||||
* Parse a comparison that neither starts with '"' nor '$', such as the
|
||||
* unusual 'bare == right' or '3 == ${VAR}', or a simple leaf without
|
||||
* operator, which is a number, a variable expression or a string literal.
|
||||
*
|
||||
* TODO: Can this be merged into CondParser_Comparison?
|
||||
*/
|
||||
static Token
|
||||
CondParser_ComparisonOrLeaf(CondParser *par, bool doEval)
|
||||
{
|
||||
Token t;
|
||||
char *arg = NULL;
|
||||
size_t arglen;
|
||||
const char *cp;
|
||||
const char *cp1;
|
||||
|
||||
@ -855,7 +814,7 @@ CondParser_ComparisonOrLeaf(CondParser *par, bool doEval)
|
||||
* XXX: Is it possible to have a variable expression evaluated twice
|
||||
* at this point?
|
||||
*/
|
||||
arglen = ParseFuncArg(par, &cp, doEval, NULL, &arg);
|
||||
(void)ParseWord(par, &cp, doEval, NULL, &arg);
|
||||
cp1 = cp;
|
||||
cpp_skip_whitespace(&cp1);
|
||||
if (*cp1 == '=' || *cp1 == '!' || *cp1 == '<' || *cp1 == '>')
|
||||
@ -868,7 +827,7 @@ CondParser_ComparisonOrLeaf(CondParser *par, bool doEval)
|
||||
* after .if must have been taken literally, so the argument cannot
|
||||
* be empty - even if it contained a variable expansion.
|
||||
*/
|
||||
t = ToToken(!doEval || EvalBare(par, arg, arglen));
|
||||
t = ToToken(!doEval || EvalBare(par, arg));
|
||||
free(arg);
|
||||
return t;
|
||||
}
|
||||
@ -934,12 +893,30 @@ CondParser_Token(CondParser *par, bool doEval)
|
||||
return CondParser_Comparison(par, doEval);
|
||||
|
||||
default:
|
||||
if (CondParser_FuncCallEmpty(par, doEval, &t))
|
||||
return t;
|
||||
if (CondParser_FuncCall(par, doEval, &t))
|
||||
return t;
|
||||
return CondParser_ComparisonOrLeaf(par, doEval);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the next token if it equals t. */
|
||||
static bool
|
||||
CondParser_Skip(CondParser *par, Token t)
|
||||
{
|
||||
Token actual;
|
||||
|
||||
actual = CondParser_Token(par, false);
|
||||
if (actual == t)
|
||||
return true;
|
||||
|
||||
assert(par->curr == TOK_NONE);
|
||||
assert(actual != TOK_NONE);
|
||||
par->curr = actual;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Term -> '(' Or ')'
|
||||
* Term -> '!' Term
|
||||
@ -980,56 +957,44 @@ CondParser_Term(CondParser *par, bool doEval)
|
||||
}
|
||||
|
||||
/*
|
||||
* And -> Term '&&' And
|
||||
* And -> Term
|
||||
* And -> Term ('&&' Term)*
|
||||
*/
|
||||
static CondResult
|
||||
CondParser_And(CondParser *par, bool doEval)
|
||||
{
|
||||
CondResult res;
|
||||
Token op;
|
||||
CondResult res, rhs;
|
||||
|
||||
res = CondParser_Term(par, doEval);
|
||||
if (res == CR_ERROR)
|
||||
return CR_ERROR;
|
||||
|
||||
op = CondParser_Token(par, doEval);
|
||||
if (op == TOK_AND) {
|
||||
if (res == CR_TRUE)
|
||||
return CondParser_And(par, doEval);
|
||||
if (CondParser_And(par, false) == CR_ERROR)
|
||||
res = CR_TRUE;
|
||||
do {
|
||||
if ((rhs = CondParser_Term(par, doEval)) == CR_ERROR)
|
||||
return CR_ERROR;
|
||||
return res;
|
||||
}
|
||||
if (rhs == CR_FALSE) {
|
||||
res = CR_FALSE;
|
||||
doEval = false;
|
||||
}
|
||||
} while (CondParser_Skip(par, TOK_AND));
|
||||
|
||||
CondParser_PushBack(par, op);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Or -> And '||' Or
|
||||
* Or -> And
|
||||
* Or -> And ('||' And)*
|
||||
*/
|
||||
static CondResult
|
||||
CondParser_Or(CondParser *par, bool doEval)
|
||||
{
|
||||
CondResult res;
|
||||
Token op;
|
||||
CondResult res, rhs;
|
||||
|
||||
res = CondParser_And(par, doEval);
|
||||
if (res == CR_ERROR)
|
||||
return CR_ERROR;
|
||||
|
||||
op = CondParser_Token(par, doEval);
|
||||
if (op == TOK_OR) {
|
||||
if (res == CR_FALSE)
|
||||
return CondParser_Or(par, doEval);
|
||||
if (CondParser_Or(par, false) == CR_ERROR)
|
||||
res = CR_FALSE;
|
||||
do {
|
||||
if ((rhs = CondParser_And(par, doEval)) == CR_ERROR)
|
||||
return CR_ERROR;
|
||||
return res;
|
||||
}
|
||||
if (rhs == CR_TRUE) {
|
||||
res = CR_TRUE;
|
||||
doEval = false;
|
||||
}
|
||||
} while (CondParser_Skip(par, TOK_OR));
|
||||
|
||||
CondParser_PushBack(par, op);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1060,23 +1025,22 @@ CondParser_Eval(CondParser *par, bool *out_value)
|
||||
* COND_PARSE if the condition was valid grammatically
|
||||
* COND_INVALID if not a valid conditional.
|
||||
*
|
||||
* (*value) is set to the boolean value of the condition
|
||||
* *out_value is set to the boolean value of the condition
|
||||
*/
|
||||
static CondEvalResult
|
||||
CondEvalExpression(const char *cond, bool *out_value, bool plain,
|
||||
bool (*evalBare)(size_t, const char *), bool negate,
|
||||
bool eprint, bool strictLHS)
|
||||
bool (*evalBare)(const char *), bool negate,
|
||||
bool eprint, bool leftUnquotedOK)
|
||||
{
|
||||
CondParser par;
|
||||
CondEvalResult rval;
|
||||
|
||||
lhsStrict = strictLHS;
|
||||
|
||||
cpp_skip_hspace(&cond);
|
||||
|
||||
par.plain = plain;
|
||||
par.evalBare = evalBare;
|
||||
par.negateEvalBare = negate;
|
||||
par.leftUnquotedOK = leftUnquotedOK;
|
||||
par.p = cond;
|
||||
par.curr = TOK_NONE;
|
||||
par.printedError = false;
|
||||
@ -1097,7 +1061,7 @@ CondEvalResult
|
||||
Cond_EvalCondition(const char *cond, bool *out_value)
|
||||
{
|
||||
return CondEvalExpression(cond, out_value, true,
|
||||
FuncDefined, false, false, false);
|
||||
FuncDefined, false, false, true);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1109,7 +1073,7 @@ IsEndif(const char *p)
|
||||
|
||||
static bool
|
||||
DetermineKindOfConditional(const char **pp, bool *out_plain,
|
||||
bool (**out_evalBare)(size_t, const char *),
|
||||
bool (**out_evalBare)(const char *),
|
||||
bool *out_negate)
|
||||
{
|
||||
const char *p = *pp;
|
||||
@ -1198,7 +1162,7 @@ Cond_EvalLine(const char *line)
|
||||
static unsigned int cond_states_cap = 128;
|
||||
|
||||
bool plain;
|
||||
bool (*evalBare)(size_t, const char *);
|
||||
bool (*evalBare)(const char *);
|
||||
bool negate;
|
||||
bool isElif;
|
||||
bool value;
|
||||
@ -1217,7 +1181,7 @@ Cond_EvalLine(const char *line)
|
||||
if (IsEndif(p)) { /* It is an '.endif'. */
|
||||
if (p[5] != '\0') {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"The .endif directive does not take arguments.");
|
||||
"The .endif directive does not take arguments");
|
||||
}
|
||||
|
||||
if (cond_depth == cond_min_depth) {
|
||||
@ -1236,7 +1200,7 @@ Cond_EvalLine(const char *line)
|
||||
if (p[1] != 'l') {
|
||||
/*
|
||||
* Unknown directive. It might still be a
|
||||
* transformation rule like '.elisp.scm',
|
||||
* transformation rule like '.err.txt',
|
||||
* therefore no error message here.
|
||||
*/
|
||||
return COND_INVALID;
|
||||
@ -1248,8 +1212,8 @@ Cond_EvalLine(const char *line)
|
||||
|
||||
if (p[2] != '\0')
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"The .else directive "
|
||||
"does not take arguments.");
|
||||
"The .else directive "
|
||||
"does not take arguments");
|
||||
|
||||
if (cond_depth == cond_min_depth) {
|
||||
Parse_Error(PARSE_FATAL, "if-less else");
|
||||
@ -1328,7 +1292,7 @@ Cond_EvalLine(const char *line)
|
||||
|
||||
/* And evaluate the conditional expression */
|
||||
if (CondEvalExpression(p, &value, plain, evalBare, negate,
|
||||
true, true) == COND_INVALID) {
|
||||
true, false) == COND_INVALID) {
|
||||
/* Syntax error in conditional, error message already output. */
|
||||
/* Skip everything to matching .endif */
|
||||
/* XXX: An extra '.else' is not detected in this case. */
|
||||
|
@ -9,6 +9,9 @@
|
||||
/* Shell spec to use by default */
|
||||
#undef DEFSHELL_INDEX
|
||||
|
||||
/* Path of default shell */
|
||||
#undef DEFSHELL_PATH
|
||||
|
||||
/* Define to 1 if you have the <ar.h> header file. */
|
||||
#undef HAVE_AR_H
|
||||
|
||||
@ -65,6 +68,9 @@
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if the system has the type `long long int'. */
|
||||
#undef HAVE_LONG_LONG_INT
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
@ -98,15 +104,36 @@
|
||||
/* Define to 1 if you have the `setpgid' function. */
|
||||
#undef HAVE_SETPGID
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#undef HAVE_SETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `sigaddset' function. */
|
||||
#undef HAVE_SIGADDSET
|
||||
|
||||
/* Define to 1 if you have the `sigpending' function. */
|
||||
#undef HAVE_SIGPENDING
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
#undef HAVE_SIGPROCMASK
|
||||
|
||||
/* Define to 1 if you have the `sigsetmask' function. */
|
||||
#undef HAVE_SIGSETMASK
|
||||
|
||||
/* Define to 1 if you have the `sigsuspend' function. */
|
||||
#undef HAVE_SIGSUSPEND
|
||||
|
||||
/* Define to 1 if you have the `sigvec' function. */
|
||||
#undef HAVE_SIGVEC
|
||||
|
||||
/* Define to 1 if the system has the type `sig_atomic_t'. */
|
||||
#undef HAVE_SIG_ATOMIC_T
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
@ -143,6 +170,12 @@
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#undef HAVE_STRTOL
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||
|
||||
@ -197,6 +230,9 @@
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned long long int'. */
|
||||
#undef HAVE_UNSIGNED_LONG_LONG_INT
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
@ -324,6 +360,16 @@
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef int64_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef mode_t
|
||||
|
||||
|
479
contrib/bmake/configure
vendored
479
contrib/bmake/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for bmake 20210201.
|
||||
# Generated by GNU Autoconf 2.69 for bmake 20211020.
|
||||
#
|
||||
# Report bugs to <sjg@NetBSD.org>.
|
||||
#
|
||||
@ -580,8 +580,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='bmake'
|
||||
PACKAGE_TARNAME='bmake'
|
||||
PACKAGE_VERSION='20210201'
|
||||
PACKAGE_STRING='bmake 20210201'
|
||||
PACKAGE_VERSION='20211020'
|
||||
PACKAGE_STRING='bmake 20211020'
|
||||
PACKAGE_BUGREPORT='sjg@NetBSD.org'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -622,11 +622,13 @@ ac_includes_default="\
|
||||
#endif"
|
||||
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
UTC_1
|
||||
_MAKE_VERSION
|
||||
filemon_h
|
||||
use_filemon
|
||||
use_meta
|
||||
diff_u
|
||||
diff
|
||||
GCC
|
||||
INSTALL
|
||||
default_sys_path
|
||||
@ -1255,7 +1257,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures bmake 20210201 to adapt to many kinds of systems.
|
||||
\`configure' configures bmake 20211020 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1316,7 +1318,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of bmake 20210201:";;
|
||||
short | recursive ) echo "Configuration of bmake 20211020:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1422,7 +1424,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
bmake configure 20210201
|
||||
bmake configure 20211020
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -1721,6 +1723,82 @@ fi
|
||||
|
||||
} # ac_fn_c_try_link
|
||||
|
||||
# ac_fn_c_find_intX_t LINENO BITS VAR
|
||||
# -----------------------------------
|
||||
# Finds a signed integer type with width BITS, setting cache variable VAR
|
||||
# accordingly.
|
||||
ac_fn_c_find_intX_t ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
|
||||
$as_echo_n "checking for int$2_t... " >&6; }
|
||||
if eval \${$3+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
eval "$3=no"
|
||||
# Order is important - never check a type that is potentially smaller
|
||||
# than half of the expected target width.
|
||||
for ac_type in int$2_t 'int' 'long int' \
|
||||
'long long int' 'short int' 'signed char'; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
enum { N = $2 / 2 - 1 };
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
enum { N = $2 / 2 - 1 };
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
|
||||
< ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
|
||||
test_array [0] = 0;
|
||||
return test_array [0];
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
else
|
||||
case $ac_type in #(
|
||||
int$2_t) :
|
||||
eval "$3=yes" ;; #(
|
||||
*) :
|
||||
eval "$3=\$ac_type" ;;
|
||||
esac
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
if eval test \"x\$"$3"\" = x"no"; then :
|
||||
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
eval ac_res=\$$3
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
$as_echo "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
|
||||
} # ac_fn_c_find_intX_t
|
||||
|
||||
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
|
||||
# -------------------------------------------
|
||||
# Tests whether TYPE exists after having included INCLUDES, setting cache
|
||||
@ -2002,7 +2080,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by bmake $as_me 20210201, which was
|
||||
It was created by bmake $as_me 20211020, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2355,26 +2433,41 @@ ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
case "$srcdir" in
|
||||
/*) ;;
|
||||
*) srcdir=`cd $srcdir && pwd`;;
|
||||
*) srcdir=`cd $srcdir && 'pwd'`;;
|
||||
esac
|
||||
|
||||
. $srcdir/VERSION
|
||||
OS=`uname -s`
|
||||
|
||||
use_defshell() {
|
||||
case "$defshell_path$DEFSHELL_INDEX" in
|
||||
"") ;;
|
||||
*) return 0;;
|
||||
esac
|
||||
case "$1" in
|
||||
*csh) # we must be desperate
|
||||
DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;;
|
||||
*ksh)
|
||||
DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
|
||||
sh|/bin/sh)
|
||||
DEFSHELL_INDEX=DEFSHELL_INDEX_SH;;
|
||||
*) DEFSHELL_INDEX=DEFSHELL_INDEX_CUSTOM
|
||||
defshell_path=$1
|
||||
;;
|
||||
esac
|
||||
case "$1" in
|
||||
/bin/*) ;;
|
||||
*/*) defshell_path=$1;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check whether --with-defshell was given.
|
||||
if test "${with_defshell+set}" = set; then :
|
||||
withval=$with_defshell; case "${withval}" in
|
||||
yes) as_fn_error $? "bad value ${withval} given for bmake DEFSHELL" "$LINENO" 5 ;;
|
||||
no) ;;
|
||||
*) case "$with_defshell" in
|
||||
sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway
|
||||
ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
|
||||
csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right?
|
||||
*) defshell_path=$with_defshell;; # better be sh compatible!
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
*) use_defshell $with_defshell;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "$OS" in
|
||||
@ -2446,6 +2539,37 @@ yes)
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
case "$OS" in
|
||||
Minix) CPPFLAGS="${CPPFLAGS} -D_NETBSD_SOURCE"
|
||||
test -x /usr/pkg/bin/clang && CC=${CC:-clang}
|
||||
;;
|
||||
SCO_SV) # /bin/sh is not usable
|
||||
ALT_DEF_SHELLS="/bin/lsh /usr/bin/bash /bin/ksh"
|
||||
CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL"
|
||||
;;
|
||||
esac
|
||||
echo $ECHO_N "checking whether system has timezone Europe/Berlin... $ECHO_C" >&6
|
||||
if test -f /usr/share/zoneinfo/Europe/Berlin; then
|
||||
echo yes >&6
|
||||
# seems a safe bet
|
||||
UTC_1=Europe/Berlin
|
||||
else
|
||||
utcH=`TZ=UTC date +%H 2> /dev/null`
|
||||
utc_1H=`TZ=UTC-1 date +%H 2> /dev/null`
|
||||
if test ${utcH-0} -lt ${utc_1H-0}; then
|
||||
UTC_1=UTC-1
|
||||
echo no, using UTC-1 >&6
|
||||
else
|
||||
echo no >&6
|
||||
fi
|
||||
fi
|
||||
oldPATH=$PATH
|
||||
for d in /usr/gnu/bin
|
||||
do
|
||||
test -d $d || continue
|
||||
PATH=$PATH:$d
|
||||
done
|
||||
export PATH
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
@ -4543,7 +4667,29 @@ if test $bmake_path_max -gt 1024; then
|
||||
bmake_path_max=1024
|
||||
fi
|
||||
echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
|
||||
|
||||
if (type cat) > /dev/null 2>&1; then
|
||||
: which
|
||||
which() {
|
||||
type "$@" | sed 's,[()],,g;s,^[^/][^/]*,,;q'
|
||||
}
|
||||
fi
|
||||
case "$CC" in
|
||||
/*) ;;
|
||||
*)
|
||||
for x in $CC
|
||||
do
|
||||
_cc=`which $x`
|
||||
break
|
||||
done
|
||||
if test -x ${_cc:-/dev/null}; then
|
||||
_cc_dir=`dirname $_cc`
|
||||
case ":$oldPATH:" in
|
||||
*:$_cc_dir:*) ;;
|
||||
*) CC=$_cc_dir/$CC;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
|
||||
$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
|
||||
if ${ac_cv_header_sys_wait_h+:} false; then :
|
||||
@ -4803,22 +4949,6 @@ done
|
||||
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "sys/cdefs.h" "ac_cv_header_sys_cdefs_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sys_cdefs_h" = xyes; then :
|
||||
echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __RCSID
|
||||
yes
|
||||
#endif
|
||||
|
||||
_ACEOF
|
||||
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
$EGREP "yes" >/dev/null 2>&1; then :
|
||||
echo yes >&6
|
||||
else
|
||||
echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H"
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
||||
else
|
||||
CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`"
|
||||
@ -5175,6 +5305,176 @@ $as_echo "#define const /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
|
||||
$as_echo_n "checking for inline... " >&6; }
|
||||
if ${ac_cv_c_inline+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_cv_c_inline=no
|
||||
for ac_kw in inline __inline__ __inline; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#ifndef __cplusplus
|
||||
typedef int foo_t;
|
||||
static $ac_kw foo_t static_foo () {return 0; }
|
||||
$ac_kw foo_t foo () {return 0; }
|
||||
#endif
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_cv_c_inline=$ac_kw
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
test "$ac_cv_c_inline" != no && break
|
||||
done
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
|
||||
$as_echo "$ac_cv_c_inline" >&6; }
|
||||
|
||||
case $ac_cv_c_inline in
|
||||
inline | yes) ;;
|
||||
*)
|
||||
case $ac_cv_c_inline in
|
||||
no) ac_val=;;
|
||||
*) ac_val=$ac_cv_c_inline;;
|
||||
esac
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#ifndef __cplusplus
|
||||
#define inline $ac_val
|
||||
#endif
|
||||
_ACEOF
|
||||
;;
|
||||
esac
|
||||
|
||||
ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
|
||||
case $ac_cv_c_int64_t in #(
|
||||
no|yes) ;; #(
|
||||
*)
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define int64_t $ac_cv_c_int64_t
|
||||
_ACEOF
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
|
||||
$as_echo_n "checking for unsigned long long int... " >&6; }
|
||||
if ${ac_cv_type_unsigned_long_long_int+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_cv_type_unsigned_long_long_int=yes
|
||||
if test "x${ac_cv_prog_cc_c99-no}" = xno; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* For now, do not test the preprocessor; as of 2007 there are too many
|
||||
implementations with broken preprocessors. Perhaps this can
|
||||
be revisited in 2012. In the meantime, code should not expect
|
||||
#if to work with literals wider than 32 bits. */
|
||||
/* Test literals. */
|
||||
long long int ll = 9223372036854775807ll;
|
||||
long long int nll = -9223372036854775807LL;
|
||||
unsigned long long int ull = 18446744073709551615ULL;
|
||||
/* Test constant expressions. */
|
||||
typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
|
||||
? 1 : -1)];
|
||||
typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
|
||||
? 1 : -1)];
|
||||
int i = 63;
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* Test availability of runtime routines for shift and division. */
|
||||
long long int llmax = 9223372036854775807ll;
|
||||
unsigned long long int ullmax = 18446744073709551615ull;
|
||||
return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
|
||||
| (llmax / ll) | (llmax % ll)
|
||||
| (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
|
||||
| (ullmax / ull) | (ullmax % ull));
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
|
||||
else
|
||||
ac_cv_type_unsigned_long_long_int=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
|
||||
$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
|
||||
if test $ac_cv_type_unsigned_long_long_int = yes; then
|
||||
|
||||
$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
|
||||
$as_echo_n "checking for long long int... " >&6; }
|
||||
if ${ac_cv_type_long_long_int+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_cv_type_long_long_int=yes
|
||||
if test "x${ac_cv_prog_cc_c99-no}" = xno; then
|
||||
ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
|
||||
if test $ac_cv_type_long_long_int = yes; then
|
||||
if test "$cross_compiling" = yes; then :
|
||||
:
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <limits.h>
|
||||
#ifndef LLONG_MAX
|
||||
# define HALF \
|
||||
(1LL << (sizeof (long long int) * CHAR_BIT - 2))
|
||||
# define LLONG_MAX (HALF - 1 + HALF)
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
long long int n = 1;
|
||||
int i;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
long long int m = n << i;
|
||||
if (m >> i != n)
|
||||
return 1;
|
||||
if (LLONG_MAX / 2 < m)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_run "$LINENO"; then :
|
||||
|
||||
else
|
||||
ac_cv_type_long_long_int=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
|
||||
$as_echo "$ac_cv_type_long_long_int" >&6; }
|
||||
if test $ac_cv_type_long_long_int = yes; then
|
||||
|
||||
$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_mode_t" = xyes; then :
|
||||
|
||||
@ -5332,9 +5632,9 @@ ac_fn_c_check_type "$LINENO" "sig_atomic_t" "ac_cv_type_sig_atomic_t" "
|
||||
"
|
||||
if test "x$ac_cv_type_sig_atomic_t" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
$as_echo "#define sig_atomic_t int" >>confdefs.h
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
@ -5674,7 +5974,6 @@ for ac_func in \
|
||||
errx \
|
||||
getcwd \
|
||||
getenv \
|
||||
getopt \
|
||||
getwd \
|
||||
killpg \
|
||||
mmap \
|
||||
@ -5682,15 +5981,23 @@ for ac_func in \
|
||||
select \
|
||||
setenv \
|
||||
setpgid \
|
||||
setrlimit \
|
||||
setsid \
|
||||
sigaction \
|
||||
sigaddset \
|
||||
sigpending \
|
||||
sigprocmask \
|
||||
sigsetmask \
|
||||
sigsuspend \
|
||||
sigvec \
|
||||
snprintf \
|
||||
strerror \
|
||||
stresep \
|
||||
strftime \
|
||||
strsep \
|
||||
strtod \
|
||||
strtol \
|
||||
strtoll \
|
||||
strtoul \
|
||||
sysctl \
|
||||
unsetenv \
|
||||
vsnprintf \
|
||||
@ -5712,6 +6019,19 @@ fi
|
||||
done
|
||||
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "getopt" "ac_cv_func_getopt"
|
||||
if test "x$ac_cv_func_getopt" = xyes; then :
|
||||
$as_echo "#define HAVE_GETOPT 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" getopt.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS getopt.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath"
|
||||
if test "x$ac_cv_func_realpath" = xyes; then :
|
||||
$as_echo "#define HAVE_REALPATH 1" >>confdefs.h
|
||||
@ -5738,6 +6058,19 @@ esac
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction"
|
||||
if test "x$ac_cv_func_sigaction" = xyes; then :
|
||||
$as_echo "#define HAVE_SIGACTION 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" sigaction.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS sigaction.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "stresep" "ac_cv_func_stresep"
|
||||
if test "x$ac_cv_func_stresep" = xyes; then :
|
||||
$as_echo "#define HAVE_STRESEP 1" >>confdefs.h
|
||||
@ -6006,13 +6339,19 @@ $as_echo "#define __func__ __FUNCTION__" >>confdefs.h
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
|
||||
if diff -u /dev/null /dev/null > /dev/null 2>&1; then
|
||||
diff_u=-u
|
||||
echo yes >&6
|
||||
if test -x /usr/gnu/bin/diff; then
|
||||
diff=/usr/gnu/bin/diff
|
||||
diff_u=-u
|
||||
else
|
||||
diff_u=
|
||||
echo no >&6
|
||||
diff=${diff:-diff}
|
||||
echo $ECHO_N "checking if $diff -u works... $ECHO_C" >&6
|
||||
if $diff -u /dev/null /dev/null > /dev/null 2>&1; then
|
||||
diff_u=-u
|
||||
echo yes >&6
|
||||
else
|
||||
diff_u=
|
||||
echo no >&6
|
||||
fi
|
||||
fi
|
||||
echo "checking for MACHINE & MACHINE_ARCH..." >&6
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
@ -6140,24 +6479,46 @@ do
|
||||
done
|
||||
mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"`
|
||||
echo "Using: MKSRC=$mksrc" 1>&6
|
||||
if test -x /usr/xpg4/bin/sh; then
|
||||
defshell_path=${defshell_path:-/usr/xpg4/bin/sh}
|
||||
fi
|
||||
if test -n "$defshell_path"; then
|
||||
for sh in /usr/xpg4/bin/sh $ALT_DEF_SHELLS
|
||||
do
|
||||
test -x $sh || continue
|
||||
use_defshell $sh
|
||||
break
|
||||
done
|
||||
case "$defshell_path$DEFSHELL_INDEX" in
|
||||
"") ;;
|
||||
*DEFSHELL_INDEX_CUSTOM)
|
||||
echo "Using: SHELL=$defshell_path" >&6
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DEFSHELL_CUSTOM "$defshell_path"
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
if test -n "$DEFSHELL_INDEX"; then
|
||||
;;
|
||||
/*INDEX*)
|
||||
echo "Using: SHELL=$DEFSHELL_INDEX ($defshell_path)" | sed 's,DEFSHELL_INDEX_,,' >&6
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DEFSHELL_INDEX $DEFSHELL_INDEX
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DEFSHELL_PATH "$defshell_path"
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
*)
|
||||
echo "Using: SHELL=$DEFSHELL_INDEX" | sed 's,DEFSHELL_INDEX_,,' >&6
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DEFSHELL_INDEX $DEFSHELL_INDEX
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -6175,6 +6536,18 @@ bm_outfiles="Makefile.config unit-tests/Makefile.config make-bootstrap.sh"
|
||||
if test $use_makefile = yes; then
|
||||
bm_outfiles="makefile $bm_outfiles"
|
||||
fi
|
||||
|
||||
here=`'pwd'`
|
||||
: srcdir=$srcdir
|
||||
: here= $here
|
||||
case "$here" in
|
||||
$srcdir/obj*) # make sure we put unit-tests/Makefile.config in the right place
|
||||
obj=`basename $here`
|
||||
mkdir -p $srcdir/unit-tests/$obj
|
||||
test -d unit-tests || ln -s ../unit-tests/$obj unit-tests
|
||||
;;
|
||||
esac
|
||||
|
||||
ac_config_files="$ac_config_files $bm_outfiles"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
@ -6684,7 +7057,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by bmake $as_me 20210201, which was
|
||||
This file was extended by bmake $as_me 20211020, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -6746,7 +7119,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
bmake config.status 20210201
|
||||
bmake config.status 20211020
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
@ -1,37 +1,53 @@
|
||||
dnl
|
||||
dnl RCSid:
|
||||
dnl $Id: configure.in,v 1.70 2021/02/01 18:29:26 sjg Exp $
|
||||
dnl $Id: configure.in,v 1.85 2021/10/23 20:57:08 sjg Exp $
|
||||
dnl
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
dnl
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT([bmake], [20210201], [sjg@NetBSD.org])
|
||||
AC_INIT([bmake], [20211020], [sjg@NetBSD.org])
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
dnl make srcdir absolute
|
||||
case "$srcdir" in
|
||||
/*) ;;
|
||||
*) srcdir=`cd $srcdir && pwd`;;
|
||||
*) srcdir=`cd $srcdir && 'pwd'`;;
|
||||
esac
|
||||
|
||||
dnl get _MAKE_VERSION
|
||||
. $srcdir/VERSION
|
||||
OS=`uname -s`
|
||||
|
||||
dnl function to set DEFSHELL_INDEX
|
||||
use_defshell() {
|
||||
case "$defshell_path$DEFSHELL_INDEX" in
|
||||
"") ;;
|
||||
*) return 0;;
|
||||
esac
|
||||
case "$1" in
|
||||
*csh) # we must be desperate
|
||||
DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;;
|
||||
*ksh)
|
||||
DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
|
||||
sh|/bin/sh)
|
||||
DEFSHELL_INDEX=DEFSHELL_INDEX_SH;;
|
||||
*) DEFSHELL_INDEX=DEFSHELL_INDEX_CUSTOM
|
||||
defshell_path=$1
|
||||
;;
|
||||
esac
|
||||
case "$1" in
|
||||
/bin/*) ;;
|
||||
*/*) defshell_path=$1;;
|
||||
esac
|
||||
}
|
||||
dnl
|
||||
AC_ARG_WITH(defshell,
|
||||
[ --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions],
|
||||
[case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} given for bmake DEFSHELL) ;;
|
||||
no) ;;
|
||||
*) case "$with_defshell" in
|
||||
sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway
|
||||
ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
|
||||
csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right?
|
||||
*) defshell_path=$with_defshell;; # better be sh compatible!
|
||||
esac
|
||||
;;
|
||||
esac])
|
||||
*) use_defshell $with_defshell;;
|
||||
esac])
|
||||
dnl
|
||||
case "$OS" in
|
||||
CYGWIN*|MINGW*) use_makefile=no;;
|
||||
@ -97,6 +113,45 @@ yes)
|
||||
esac
|
||||
dnl
|
||||
dnl Check for OS problems
|
||||
dnl
|
||||
dnl Minix 3 at least has bugs in headers where _NETBSD_SOURCE
|
||||
dnl is needed for compilation
|
||||
case "$OS" in
|
||||
Minix) CPPFLAGS="${CPPFLAGS} -D_NETBSD_SOURCE"
|
||||
test -x /usr/pkg/bin/clang && CC=${CC:-clang}
|
||||
;;
|
||||
SCO_SV) # /bin/sh is not usable
|
||||
ALT_DEF_SHELLS="/bin/lsh /usr/bin/bash /bin/ksh"
|
||||
CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL"
|
||||
;;
|
||||
esac
|
||||
dnl
|
||||
dnl Not everyone groks TZ=Europe/Berlin
|
||||
dnl which is used by the localtime tests
|
||||
echo $ECHO_N "checking whether system has timezone Europe/Berlin... $ECHO_C" >&6
|
||||
if test -f /usr/share/zoneinfo/Europe/Berlin; then
|
||||
echo yes >&6
|
||||
# seems a safe bet
|
||||
UTC_1=Europe/Berlin
|
||||
else
|
||||
utcH=`TZ=UTC date +%H 2> /dev/null`
|
||||
utc_1H=`TZ=UTC-1 date +%H 2> /dev/null`
|
||||
if test ${utcH-0} -lt ${utc_1H-0}; then
|
||||
UTC_1=UTC-1
|
||||
echo no, using UTC-1 >&6
|
||||
else
|
||||
echo no >&6
|
||||
fi
|
||||
fi
|
||||
dnl
|
||||
dnl Add some places to look for compilers
|
||||
oldPATH=$PATH
|
||||
for d in /usr/gnu/bin
|
||||
do
|
||||
test -d $d || continue
|
||||
PATH=$PATH:$d
|
||||
done
|
||||
export PATH
|
||||
dnl Solaris's signal.h only privides sigset_t etc if one of
|
||||
dnl _EXTENSIONS_ _POSIX_C_SOURCE or _XOPEN_SOURCE are defined.
|
||||
dnl The later two seem to cause more problems than they solve so if we
|
||||
@ -126,7 +181,33 @@ AC_SUBST(bmake_path_max)dnl
|
||||
dnl
|
||||
dnl AC_C_CROSS
|
||||
dnl
|
||||
|
||||
dnl if type does not work which(1) had better!
|
||||
dnl note we cannot rely on type returning non-zero on failure
|
||||
if (type cat) > /dev/null 2>&1; then
|
||||
: which
|
||||
which() {
|
||||
type "$@" | sed 's,[[()]],,g;s,^[[^/]][[^/]]*,,;q'
|
||||
}
|
||||
fi
|
||||
dnl if CC is somewhere that was not in PATH we need its full path
|
||||
dnl watch out for included flags!
|
||||
case "$CC" in
|
||||
/*) ;;
|
||||
*)
|
||||
for x in $CC
|
||||
do
|
||||
_cc=`which $x`
|
||||
break
|
||||
done
|
||||
if test -x ${_cc:-/dev/null}; then
|
||||
_cc_dir=`dirname $_cc`
|
||||
case ":$oldPATH:" in
|
||||
*:$_cc_dir:*) ;;
|
||||
*) CC=$_cc_dir/$CC;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_DIRENT
|
||||
@ -158,24 +239,16 @@ AC_CHECK_HEADERS( \
|
||||
|
||||
dnl Both *BSD and Linux have sys/cdefs.h, most do not.
|
||||
dnl If it is missing, we add -I${srcdir}/missing to CFLAGS
|
||||
dnl also if sys/cdefs.h does not have __RCSID we need to use ours
|
||||
dnl but we need to include the host's one too *sigh*
|
||||
AC_CHECK_HEADER(sys/cdefs.h,
|
||||
echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6
|
||||
AC_EGREP_CPP(yes,
|
||||
[#include <sys/cdefs.h>
|
||||
#ifdef __RCSID
|
||||
yes
|
||||
#endif
|
||||
],
|
||||
echo yes >&6,
|
||||
echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H"),
|
||||
AC_CHECK_HEADER(sys/cdefs.h,,
|
||||
CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`")
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C___ATTRIBUTE__
|
||||
AC_C_BIGENDIAN
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_TYPE_INT64_T
|
||||
AC_TYPE_LONG_LONG_INT
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
@ -187,9 +260,8 @@ AC_STRUCT_TM
|
||||
|
||||
dnl we need sig_atomic_t
|
||||
AH_TEMPLATE([sig_atomic_t],[type that signal handlers can safely frob])
|
||||
AC_CHECK_TYPE(sig_atomic_t,,[
|
||||
AC_DEFINE([sig_atomic_t],[int],)
|
||||
],[
|
||||
AC_CHECK_TYPES([sig_atomic_t],[],[],
|
||||
[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
@ -207,7 +279,6 @@ AC_CHECK_FUNCS( \
|
||||
errx \
|
||||
getcwd \
|
||||
getenv \
|
||||
getopt \
|
||||
getwd \
|
||||
killpg \
|
||||
mmap \
|
||||
@ -215,15 +286,23 @@ AC_CHECK_FUNCS( \
|
||||
select \
|
||||
setenv \
|
||||
setpgid \
|
||||
setrlimit \
|
||||
setsid \
|
||||
sigaction \
|
||||
sigaddset \
|
||||
sigpending \
|
||||
sigprocmask \
|
||||
sigsetmask \
|
||||
sigsuspend \
|
||||
sigvec \
|
||||
snprintf \
|
||||
strerror \
|
||||
stresep \
|
||||
strftime \
|
||||
strsep \
|
||||
strtod \
|
||||
strtol \
|
||||
strtoll \
|
||||
strtoul \
|
||||
sysctl \
|
||||
unsetenv \
|
||||
vsnprintf \
|
||||
@ -236,8 +315,10 @@ AC_CHECK_FUNCS( \
|
||||
|
||||
dnl functions which we may need to provide
|
||||
AC_REPLACE_FUNCS( \
|
||||
getopt \
|
||||
realpath \
|
||||
dirname \
|
||||
sigaction \
|
||||
stresep \
|
||||
strlcpy \
|
||||
)
|
||||
@ -261,13 +342,20 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[[const char *func = __func__;]])],,
|
||||
AC_DEFINE(__func__, __FUNCTION__, C99 function name))
|
||||
dnl
|
||||
dnl we want this for unit-tests/Makefile
|
||||
echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
|
||||
if diff -u /dev/null /dev/null > /dev/null 2>&1; then
|
||||
diff_u=-u
|
||||
echo yes >&6
|
||||
dnl GNU diff is known to support -u
|
||||
if test -x /usr/gnu/bin/diff; then
|
||||
diff=/usr/gnu/bin/diff
|
||||
diff_u=-u
|
||||
else
|
||||
diff_u=
|
||||
echo no >&6
|
||||
diff=${diff:-diff}
|
||||
echo $ECHO_N "checking if $diff -u works... $ECHO_C" >&6
|
||||
if $diff -u /dev/null /dev/null > /dev/null 2>&1; then
|
||||
diff_u=-u
|
||||
echo yes >&6
|
||||
else
|
||||
diff_u=
|
||||
echo no >&6
|
||||
fi
|
||||
fi
|
||||
dnl
|
||||
dnl AC_* don't quite cut it.
|
||||
@ -404,16 +492,28 @@ done
|
||||
mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"`
|
||||
echo "Using: MKSRC=$mksrc" 1>&6
|
||||
dnl On some systems we want a different default shell by default
|
||||
if test -x /usr/xpg4/bin/sh; then
|
||||
defshell_path=${defshell_path:-/usr/xpg4/bin/sh}
|
||||
fi
|
||||
if test -n "$defshell_path"; then
|
||||
for sh in /usr/xpg4/bin/sh $ALT_DEF_SHELLS
|
||||
do
|
||||
test -x $sh || continue
|
||||
use_defshell $sh
|
||||
break
|
||||
done
|
||||
case "$defshell_path$DEFSHELL_INDEX" in
|
||||
"") ;;
|
||||
*DEFSHELL_INDEX_CUSTOM)
|
||||
echo "Using: SHELL=$defshell_path" >&6
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_CUSTOM, "$defshell_path", Path of default shell)
|
||||
fi
|
||||
if test -n "$DEFSHELL_INDEX"; then
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_INDEX, $DEFSHELL_INDEX, Shell spec to use by default)
|
||||
fi
|
||||
;;
|
||||
/*INDEX*)
|
||||
echo "Using: SHELL=$DEFSHELL_INDEX ($defshell_path)" | sed 's,DEFSHELL_INDEX_,,' >&6
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_INDEX, $DEFSHELL_INDEX, Shell spec to use by default)
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_PATH, "$defshell_path", Path of default shell)
|
||||
;;
|
||||
*)
|
||||
echo "Using: SHELL=$DEFSHELL_INDEX" | sed 's,DEFSHELL_INDEX_,,' >&6
|
||||
AC_DEFINE_UNQUOTED(DEFSHELL_INDEX, $DEFSHELL_INDEX, Shell spec to use by default)
|
||||
;;
|
||||
esac
|
||||
dnl
|
||||
AC_SUBST(machine)
|
||||
AC_SUBST(force_machine)
|
||||
@ -423,15 +523,29 @@ AC_SUBST(mksrc)
|
||||
AC_SUBST(default_sys_path)
|
||||
AC_SUBST(INSTALL)
|
||||
AC_SUBST(GCC)
|
||||
AC_SUBST(diff)
|
||||
AC_SUBST(diff_u)
|
||||
AC_SUBST(use_meta)
|
||||
AC_SUBST(use_filemon)
|
||||
AC_SUBST(filemon_h)
|
||||
AC_SUBST(_MAKE_VERSION)
|
||||
AC_SUBST(UTC_1)
|
||||
bm_outfiles="Makefile.config unit-tests/Makefile.config make-bootstrap.sh"
|
||||
if test $use_makefile = yes; then
|
||||
bm_outfiles="makefile $bm_outfiles"
|
||||
fi
|
||||
|
||||
here=`'pwd'`
|
||||
: srcdir=$srcdir
|
||||
: here= $here
|
||||
case "$here" in
|
||||
$srcdir/obj*) # make sure we put unit-tests/Makefile.config in the right place
|
||||
obj=`basename $here`
|
||||
mkdir -p $srcdir/unit-tests/$obj
|
||||
test -d unit-tests || ln -s ../unit-tests/$obj unit-tests
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_OUTPUT($bm_outfiles)
|
||||
cat <<EOF
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $ */
|
||||
/* $NetBSD: dir.c,v 1.275 2021/11/28 21:46:17 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -138,7 +138,7 @@
|
||||
#include "job.h"
|
||||
|
||||
/* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */
|
||||
MAKE_RCSID("$NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: dir.c,v 1.275 2021/11/28 21:46:17 rillig Exp $");
|
||||
|
||||
/*
|
||||
* A search path is a list of CachedDir structures. A CachedDir has in it the
|
||||
@ -246,12 +246,6 @@ typedef struct OpenDirs {
|
||||
HashTable /* of CachedDirListNode */ table;
|
||||
} OpenDirs;
|
||||
|
||||
typedef enum CachedStatsFlags {
|
||||
CST_NONE = 0,
|
||||
CST_LSTAT = 1 << 0, /* call lstat(2) instead of stat(2) */
|
||||
CST_UPDATE = 1 << 1 /* ignore existing cached entry */
|
||||
} CachedStatsFlags;
|
||||
|
||||
|
||||
SearchPath dirSearchPath = { LST_INIT }; /* main search path */
|
||||
|
||||
@ -419,9 +413,9 @@ OpenDirs_Remove(OpenDirs *odirs, const char *name)
|
||||
*/
|
||||
static int
|
||||
cached_stats(const char *pathname, struct cached_stat *out_cst,
|
||||
CachedStatsFlags flags)
|
||||
bool useLstat, bool forceRefresh)
|
||||
{
|
||||
HashTable *tbl = flags & CST_LSTAT ? &lmtimes : &mtimes;
|
||||
HashTable *tbl = useLstat ? &lmtimes : &mtimes;
|
||||
struct stat sys_st;
|
||||
struct cached_stat *cst;
|
||||
int rc;
|
||||
@ -430,14 +424,14 @@ cached_stats(const char *pathname, struct cached_stat *out_cst,
|
||||
return -1; /* This can happen in meta mode. */
|
||||
|
||||
cst = HashTable_FindValue(tbl, pathname);
|
||||
if (cst != NULL && !(flags & CST_UPDATE)) {
|
||||
if (cst != NULL && !forceRefresh) {
|
||||
*out_cst = *cst;
|
||||
DEBUG2(DIR, "Using cached time %s for %s\n",
|
||||
Targ_FmtTime(cst->cst_mtime), pathname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = (flags & CST_LSTAT ? lstat : stat)(pathname, &sys_st);
|
||||
rc = (useLstat ? lstat : stat)(pathname, &sys_st);
|
||||
if (rc == -1)
|
||||
return -1; /* don't cache negative lookups */
|
||||
|
||||
@ -462,13 +456,13 @@ cached_stats(const char *pathname, struct cached_stat *out_cst,
|
||||
int
|
||||
cached_stat(const char *pathname, struct cached_stat *cst)
|
||||
{
|
||||
return cached_stats(pathname, cst, CST_NONE);
|
||||
return cached_stats(pathname, cst, false, false);
|
||||
}
|
||||
|
||||
int
|
||||
cached_lstat(const char *pathname, struct cached_stat *cst)
|
||||
{
|
||||
return cached_stats(pathname, cst, CST_LSTAT);
|
||||
return cached_stats(pathname, cst, true, false);
|
||||
}
|
||||
|
||||
/* Initialize the directories module. */
|
||||
@ -1127,9 +1121,8 @@ FindFileRelative(SearchPath *path, bool seenDotLast,
|
||||
}
|
||||
|
||||
static bool
|
||||
FindFileAbsolute(SearchPath *path, bool const seenDotLast,
|
||||
const char *const name, const char *const base,
|
||||
char **out_file)
|
||||
FindFileAbsolute(SearchPath *path, bool seenDotLast,
|
||||
const char *name, const char *base, char **out_file)
|
||||
{
|
||||
char *file;
|
||||
SearchPathNode *ln;
|
||||
@ -1448,7 +1441,7 @@ ResolveFullName(GNode *gn)
|
||||
|
||||
fullName = Dir_FindFile(gn->name, Suff_FindPath(gn));
|
||||
|
||||
if (fullName == NULL && gn->flags & FROM_DEPEND &&
|
||||
if (fullName == NULL && gn->flags.fromDepend &&
|
||||
!Lst_IsEmpty(&gn->implicitParents))
|
||||
fullName = ResolveMovedDepends(gn);
|
||||
|
||||
@ -1471,7 +1464,7 @@ ResolveFullName(GNode *gn)
|
||||
* The found file is stored in gn->path, unless the node already had a path.
|
||||
*/
|
||||
void
|
||||
Dir_UpdateMTime(GNode *gn, bool recheck)
|
||||
Dir_UpdateMTime(GNode *gn, bool forceRefresh)
|
||||
{
|
||||
char *fullName;
|
||||
struct cached_stat cst;
|
||||
@ -1488,7 +1481,7 @@ Dir_UpdateMTime(GNode *gn, bool recheck)
|
||||
|
||||
fullName = ResolveFullName(gn);
|
||||
|
||||
if (cached_stats(fullName, &cst, recheck ? CST_UPDATE : CST_NONE) < 0) {
|
||||
if (cached_stats(fullName, &cst, false, forceRefresh) < 0) {
|
||||
if (gn->type & OP_MEMBER) {
|
||||
if (fullName != gn->path)
|
||||
free(fullName);
|
||||
|
@ -1,80 +0,0 @@
|
||||
/* $NetBSD: enum.c,v 1.15 2021/02/02 17:56:31 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "make.h"
|
||||
|
||||
MAKE_RCSID("$NetBSD: enum.c,v 1.15 2021/02/02 17:56:31 rillig Exp $");
|
||||
|
||||
/*
|
||||
* Convert a bitset into a string representation, showing the names of the
|
||||
* individual bits.
|
||||
*
|
||||
* Optionally, shortcuts for groups of bits can be added. To have an effect,
|
||||
* they need to be listed before their individual bits.
|
||||
*/
|
||||
const char *
|
||||
Enum_FlagsToString(char *buf, size_t buf_size,
|
||||
int value, const EnumToStringSpec *spec)
|
||||
{
|
||||
const char *buf_start = buf;
|
||||
const char *sep = "";
|
||||
size_t sep_len = 0;
|
||||
|
||||
for (; spec->es_value != 0; spec++) {
|
||||
size_t name_len;
|
||||
|
||||
if ((value & spec->es_value) != spec->es_value)
|
||||
continue;
|
||||
value &= ~spec->es_value;
|
||||
|
||||
assert(buf_size >= sep_len + 1);
|
||||
memcpy(buf, sep, sep_len);
|
||||
buf += sep_len;
|
||||
buf_size -= sep_len;
|
||||
|
||||
name_len = strlen(spec->es_name);
|
||||
assert(buf_size >= name_len + 1);
|
||||
memcpy(buf, spec->es_name, name_len);
|
||||
buf += name_len;
|
||||
buf_size -= name_len;
|
||||
|
||||
sep = ENUM__SEP;
|
||||
sep_len = sizeof ENUM__SEP - 1;
|
||||
}
|
||||
|
||||
/* If this assertion fails, the listed enum values are incomplete. */
|
||||
assert(value == 0);
|
||||
|
||||
if (buf == buf_start)
|
||||
return "none";
|
||||
|
||||
assert(buf_size >= 1);
|
||||
buf[0] = '\0';
|
||||
return buf_start;
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
/* $NetBSD: enum.h,v 1.19 2021/03/15 16:00:05 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_ENUM_H
|
||||
#define MAKE_ENUM_H
|
||||
|
||||
/* Generate string representations for bitmasks and simple enums. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct EnumToStringSpec {
|
||||
int es_value;
|
||||
const char *es_name;
|
||||
} EnumToStringSpec;
|
||||
|
||||
|
||||
const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
|
||||
|
||||
/* For Enum_FlagsToString, the separator between flags. */
|
||||
#define ENUM__SEP "|"
|
||||
|
||||
/*
|
||||
* Generate the string that joins all possible flags, to see how large the
|
||||
* buffer must be.
|
||||
*/
|
||||
#define ENUM__JOIN_STR_1(v1) \
|
||||
#v1
|
||||
#define ENUM__JOIN_STR_2(v1, v2) \
|
||||
ENUM__JOIN_STR_1(v1) ENUM__SEP \
|
||||
ENUM__JOIN_STR_1(v2)
|
||||
#define ENUM__JOIN_STR_4(v1, v2, v3, v4) \
|
||||
ENUM__JOIN_STR_2(v1, v2) ENUM__SEP \
|
||||
ENUM__JOIN_STR_2(v3, v4)
|
||||
#define ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4) ENUM__SEP \
|
||||
ENUM__JOIN_STR_4(v5, v6, v7, v8)
|
||||
#define ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16) \
|
||||
ENUM__JOIN_STR_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \
|
||||
ENUM__JOIN_STR_8(v09, v10, v11, v12, v13, v14, v15, v16)
|
||||
|
||||
#define ENUM__JOIN_2(part1, part2) \
|
||||
part1 ENUM__SEP part2
|
||||
#define ENUM__JOIN_3(part1, part2, part3) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3
|
||||
#define ENUM__JOIN_4(part1, part2, part3, part4) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4
|
||||
#define ENUM__JOIN_5(part1, part2, part3, part4, part5) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4 ENUM__SEP part5
|
||||
|
||||
/* List the pairs of enum value and corresponding name. */
|
||||
#define ENUM__SPEC_1(v1) \
|
||||
{ v1, #v1 }
|
||||
#define ENUM__SPEC_2(v1, v2) \
|
||||
ENUM__SPEC_1(v1), \
|
||||
ENUM__SPEC_1(v2)
|
||||
#define ENUM__SPEC_4(v1, v2, v3, v4) \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_2(v3, v4)
|
||||
#define ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)
|
||||
#define ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16) \
|
||||
ENUM__SPEC_8(v01, v02, v03, v04, v05, v06, v07, v08), \
|
||||
ENUM__SPEC_8(v09, v10, v11, v12, v13, v14, v15, v16)
|
||||
|
||||
#define ENUM__SPECS_2(part1, part2) \
|
||||
{ part1, part2, { 0, "" } }
|
||||
#define ENUM__SPECS_3(part1, part2, part3) \
|
||||
{ part1, part2, part3, { 0, "" } }
|
||||
#define ENUM__SPECS_4(part1, part2, part3, part4) \
|
||||
{ part1, part2, part3, part4, { 0, "" } }
|
||||
#define ENUM__SPECS_5(part1, part2, part3, part4, part5) \
|
||||
{ part1, part2, part3, part4, part5, { 0, "" } }
|
||||
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString. */
|
||||
#define ENUM__FLAGS_RTTI(typnam, specs, joined) \
|
||||
static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
|
||||
enum { typnam ## _ ## ToStringSize = sizeof (joined) }; \
|
||||
MAKE_INLINE const char *typnam ## _ToString(char *buf, typnam value) \
|
||||
{ return Enum_FlagsToString(buf, typnam ## _ ## ToStringSize, \
|
||||
value, typnam ## _ ## ToStringSpecs); \
|
||||
} \
|
||||
extern void enum_flags_rtti_dummy(void)
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 3 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_3(typnam, v1, v2, v3) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_1(v3)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_2(v1, v2), \
|
||||
ENUM__JOIN_STR_1(v3)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 6 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_6(typnam, v1, v2, v3, v4, v5, v6) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_2(v5, v6)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4), \
|
||||
ENUM__JOIN_STR_2(v5, v6)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 9 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_9(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \
|
||||
ENUM__SPEC_1(v9)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8), \
|
||||
ENUM__JOIN_STR_1(v9)))
|
||||
|
||||
/*
|
||||
* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 31 flags.
|
||||
*/
|
||||
#define ENUM_FLAGS_RTTI_31(typnam, \
|
||||
v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16, \
|
||||
v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_5( \
|
||||
ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__SPEC_8(v17, v18, v19, v20, v21, v22, v23, v24), \
|
||||
ENUM__SPEC_4(v25, v26, v27, v28), \
|
||||
ENUM__SPEC_2(v29, v30), \
|
||||
ENUM__SPEC_1(v31)), \
|
||||
ENUM__JOIN_5( \
|
||||
ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__JOIN_STR_8(v17, v18, v19, v20, v21, v22, v23, v24), \
|
||||
ENUM__JOIN_STR_4(v25, v26, v27, v28), \
|
||||
ENUM__JOIN_STR_2(v29, v30), \
|
||||
ENUM__JOIN_STR_1(v31)))
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: filemon_ktrace.c,v 1.14 2021/02/01 21:34:41 rillig Exp $ */
|
||||
/* $NetBSD: filemon_ktrace.c,v 1.15 2021/07/31 09:30:17 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||
@ -227,7 +227,6 @@ filemon_open(void)
|
||||
/* Success! */
|
||||
return F;
|
||||
|
||||
(void)fclose(F->in);
|
||||
fail1: (void)close(ktrpipe[0]);
|
||||
(void)close(ktrpipe[1]);
|
||||
fail0: free(F);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: for.c,v 1.142 2021/04/03 11:08:40 rillig Exp $ */
|
||||
/* $NetBSD: for.c,v 1.150 2021/12/12 15:44:41 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, The Regents of the University of California.
|
||||
@ -45,9 +45,9 @@
|
||||
*
|
||||
* After reaching the .endfor, the values from the .for line are grouped
|
||||
* according to the number of variables. For each such group, the unexpanded
|
||||
* body is scanned for variable expressions, and those that match the variable
|
||||
* names are replaced with expressions of the form ${:U...} or $(:U...).
|
||||
* After that, the body is treated like a file from an .include directive.
|
||||
* body is scanned for variable expressions, and those that match the
|
||||
* variable names are replaced with expressions of the form ${:U...}. After
|
||||
* that, the body is treated like a file from an .include directive.
|
||||
*
|
||||
* Interface:
|
||||
* For_Eval Evaluate the loop in the passed line.
|
||||
@ -58,7 +58,7 @@
|
||||
#include "make.h"
|
||||
|
||||
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
|
||||
MAKE_RCSID("$NetBSD: for.c,v 1.142 2021/04/03 11:08:40 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: for.c,v 1.150 2021/12/12 15:44:41 rillig Exp $");
|
||||
|
||||
|
||||
/* One of the variables to the left of the "in" in a .for loop. */
|
||||
@ -70,17 +70,13 @@ typedef struct ForVar {
|
||||
typedef struct ForLoop {
|
||||
Buffer body; /* Unexpanded body of the loop */
|
||||
Vector /* of ForVar */ vars; /* Iteration variables */
|
||||
Words items; /* Substitution items */
|
||||
SubstringWords items; /* Substitution items */
|
||||
Buffer curBody; /* Expanded body of the current iteration */
|
||||
/* Is any of the names 1 character long? If so, when the variable values
|
||||
* are substituted, the parser must handle $V expressions as well, not
|
||||
* only ${V} and $(V). */
|
||||
bool short_var;
|
||||
unsigned int sub_next; /* Where to continue iterating */
|
||||
unsigned int nextItem; /* Where to continue iterating */
|
||||
} ForLoop;
|
||||
|
||||
|
||||
static ForLoop *accumFor; /* Loop being accumulated */
|
||||
static ForLoop *accumFor; /* Loop being accumulated */
|
||||
static int forLevel = 0; /* Nesting level */
|
||||
|
||||
|
||||
@ -91,11 +87,9 @@ ForLoop_New(void)
|
||||
|
||||
Buf_Init(&f->body);
|
||||
Vector_Init(&f->vars, sizeof(ForVar));
|
||||
f->items.words = NULL;
|
||||
f->items.freeIt = NULL;
|
||||
SubstringWords_Init(&f->items);
|
||||
Buf_Init(&f->curBody);
|
||||
f->short_var = false;
|
||||
f->sub_next = 0;
|
||||
f->nextItem = 0;
|
||||
|
||||
return f;
|
||||
}
|
||||
@ -111,7 +105,7 @@ ForLoop_Free(ForLoop *f)
|
||||
}
|
||||
Vector_Done(&f->vars);
|
||||
|
||||
Words_Free(f->items);
|
||||
SubstringWords_Free(f->items);
|
||||
Buf_Done(&f->curBody);
|
||||
|
||||
free(f);
|
||||
@ -150,8 +144,6 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp)
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
if (len == 1)
|
||||
f->short_var = true;
|
||||
|
||||
ForLoop_AddVar(f, p, len);
|
||||
p += len;
|
||||
@ -178,10 +170,10 @@ ForLoop_ParseItems(ForLoop *f, const char *p)
|
||||
return false;
|
||||
}
|
||||
|
||||
f->items = Str_Words(items, false);
|
||||
f->items = Substring_Words(items, false);
|
||||
free(items);
|
||||
|
||||
if (f->items.len == 1 && f->items.words[0][0] == '\0')
|
||||
if (f->items.len == 1 && Substring_IsEmpty(f->items.words[0]))
|
||||
f->items.len = 0; /* .for var in ${:U} */
|
||||
|
||||
if (f->items.len != 0 && f->items.len % f->vars.len != 0) {
|
||||
@ -285,33 +277,32 @@ For_Accum(const char *line)
|
||||
|
||||
|
||||
static size_t
|
||||
for_var_len(const char *var)
|
||||
ExprLen(const char *s, const char *e)
|
||||
{
|
||||
char ch, var_start, var_end;
|
||||
char expr_open, expr_close;
|
||||
int depth;
|
||||
size_t len;
|
||||
const char *p;
|
||||
|
||||
var_start = *var;
|
||||
if (var_start == '\0')
|
||||
/* just escape the $ */
|
||||
return 0;
|
||||
if (s == e)
|
||||
return 0; /* just escape the '$' */
|
||||
|
||||
if (var_start == '(')
|
||||
var_end = ')';
|
||||
else if (var_start == '{')
|
||||
var_end = '}';
|
||||
expr_open = s[0];
|
||||
if (expr_open == '(')
|
||||
expr_close = ')';
|
||||
else if (expr_open == '{')
|
||||
expr_close = '}';
|
||||
else
|
||||
return 1; /* Single char variable */
|
||||
|
||||
depth = 1;
|
||||
for (len = 1; (ch = var[len++]) != '\0';) {
|
||||
if (ch == var_start)
|
||||
for (p = s + 1; p != e; p++) {
|
||||
if (*p == expr_open)
|
||||
depth++;
|
||||
else if (ch == var_end && --depth == 0)
|
||||
return len;
|
||||
else if (*p == expr_close && --depth == 0)
|
||||
return (size_t)(p + 1 - s);
|
||||
}
|
||||
|
||||
/* Variable end not found, escape the $ */
|
||||
/* Expression end not found, escape the $ */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -320,12 +311,13 @@ for_var_len(const char *var)
|
||||
* that characters that break this syntax must be backslash-escaped.
|
||||
*/
|
||||
static bool
|
||||
NeedsEscapes(const char *value, char endc)
|
||||
NeedsEscapes(Substring value, char endc)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = value; *p != '\0'; p++) {
|
||||
if (*p == ':' || *p == '$' || *p == '\\' || *p == endc)
|
||||
for (p = value.start; p != value.end; p++) {
|
||||
if (*p == ':' || *p == '$' || *p == '\\' || *p == endc ||
|
||||
*p == '\n')
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -338,34 +330,44 @@ NeedsEscapes(const char *value, char endc)
|
||||
* The result is later unescaped by ApplyModifier_Defined.
|
||||
*/
|
||||
static void
|
||||
Buf_AddEscaped(Buffer *cmds, const char *item, char endc)
|
||||
Buf_AddEscaped(Buffer *cmds, Substring item, char endc)
|
||||
{
|
||||
const char *p;
|
||||
char ch;
|
||||
|
||||
if (!NeedsEscapes(item, endc)) {
|
||||
Buf_AddStr(cmds, item);
|
||||
Buf_AddBytesBetween(cmds, item.start, item.end);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Escape ':', '$', '\\' and 'endc' - these will be removed later by
|
||||
* :U processing, see ApplyModifier_Defined. */
|
||||
while ((ch = *item++) != '\0') {
|
||||
for (p = item.start; p != item.end; p++) {
|
||||
ch = *p;
|
||||
if (ch == '$') {
|
||||
size_t len = for_var_len(item);
|
||||
size_t len = ExprLen(p + 1, item.end);
|
||||
if (len != 0) {
|
||||
Buf_AddBytes(cmds, item - 1, len + 1);
|
||||
item += len;
|
||||
/*
|
||||
* XXX: Should a '\' be added here?
|
||||
* See directive-for-escape.mk, ExprLen.
|
||||
*/
|
||||
Buf_AddBytes(cmds, p, 1 + len);
|
||||
p += len;
|
||||
continue;
|
||||
}
|
||||
Buf_AddByte(cmds, '\\');
|
||||
} else if (ch == ':' || ch == '\\' || ch == endc)
|
||||
Buf_AddByte(cmds, '\\');
|
||||
else if (ch == '\n') {
|
||||
Parse_Error(PARSE_FATAL, "newline in .for value");
|
||||
ch = ' '; /* prevent newline injection */
|
||||
}
|
||||
Buf_AddByte(cmds, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* While expanding the body of a .for loop, replace the variable name of an
|
||||
* When expanding the body of a .for loop, replace the variable name of an
|
||||
* expression like ${i} or ${i:...} or $(i) or $(i:...) with ":Uvalue".
|
||||
*/
|
||||
static void
|
||||
@ -376,8 +378,8 @@ ForLoop_SubstVarLong(ForLoop *f, const char **pp, const char *bodyEnd,
|
||||
const char *p = *pp;
|
||||
|
||||
for (i = 0; i < f->vars.len; i++) {
|
||||
ForVar *forVar = Vector_Get(&f->vars, i);
|
||||
char *varname = forVar->name;
|
||||
const ForVar *forVar = Vector_Get(&f->vars, i);
|
||||
const char *varname = forVar->name;
|
||||
size_t varnameLen = forVar->nameLen;
|
||||
|
||||
if (varnameLen >= (size_t)(bodyEnd - p))
|
||||
@ -396,7 +398,7 @@ ForLoop_SubstVarLong(ForLoop *f, const char **pp, const char *bodyEnd,
|
||||
Buf_AddBytesBetween(&f->curBody, *inout_mark, p);
|
||||
Buf_AddStr(&f->curBody, ":U");
|
||||
Buf_AddEscaped(&f->curBody,
|
||||
f->items.words[f->sub_next + i], endc);
|
||||
f->items.words[f->nextItem + i], endc);
|
||||
|
||||
p += varnameLen;
|
||||
*inout_mark = p;
|
||||
@ -406,18 +408,18 @@ ForLoop_SubstVarLong(ForLoop *f, const char **pp, const char *bodyEnd,
|
||||
}
|
||||
|
||||
/*
|
||||
* While expanding the body of a .for loop, replace single-character
|
||||
* When expanding the body of a .for loop, replace single-character
|
||||
* variable expressions like $i with their ${:U...} expansion.
|
||||
*/
|
||||
static void
|
||||
ForLoop_SubstVarShort(ForLoop *f, const char *p, const char **inout_mark)
|
||||
{
|
||||
const char ch = *p;
|
||||
ForVar *vars;
|
||||
const ForVar *vars;
|
||||
size_t i;
|
||||
|
||||
/* Skip $$ and stupid ones. */
|
||||
if (!f->short_var || strchr("}):$", ch) != NULL)
|
||||
if (ch == '}' || ch == ')' || ch == ':' || ch == '$')
|
||||
return;
|
||||
|
||||
vars = Vector_Get(&f->vars, 0);
|
||||
@ -429,10 +431,12 @@ ForLoop_SubstVarShort(ForLoop *f, const char *p, const char **inout_mark)
|
||||
return;
|
||||
|
||||
found:
|
||||
Buf_AddBytesBetween(&f->curBody, *inout_mark, p);
|
||||
*inout_mark = p + 1;
|
||||
|
||||
/* Replace $<ch> with ${:U<value>} */
|
||||
Buf_AddBytesBetween(&f->curBody, *inout_mark, p), *inout_mark = p + 1;
|
||||
Buf_AddStr(&f->curBody, "{:U");
|
||||
Buf_AddEscaped(&f->curBody, f->items.words[f->sub_next + i], '}');
|
||||
Buf_AddEscaped(&f->curBody, f->items.words[f->nextItem + i], '}');
|
||||
Buf_AddByte(&f->curBody, '}');
|
||||
}
|
||||
|
||||
@ -446,14 +450,14 @@ ForLoop_SubstVarShort(ForLoop *f, const char *p, const char **inout_mark)
|
||||
* defined, see unit-tests/varname-empty.mk for more details.
|
||||
*
|
||||
* The detection of substitutions of the loop control variables is naive.
|
||||
* Many of the modifiers use '\' to escape '$' (not '$'), so it is possible
|
||||
* to contrive a makefile where an unwanted substitution happens.
|
||||
* Many of the modifiers use '\$' instead of '$$' to escape '$', so it is
|
||||
* possible to contrive a makefile where an unwanted substitution happens.
|
||||
*/
|
||||
static void
|
||||
ForLoop_SubstBody(ForLoop *f)
|
||||
{
|
||||
const char *p, *bodyEnd;
|
||||
const char *mark; /* where the last replacement left off */
|
||||
const char *mark; /* where the last substitution left off */
|
||||
|
||||
Buf_Empty(&f->curBody);
|
||||
|
||||
@ -461,9 +465,9 @@ ForLoop_SubstBody(ForLoop *f)
|
||||
bodyEnd = f->body.data + f->body.len;
|
||||
for (p = mark; (p = strchr(p, '$')) != NULL;) {
|
||||
if (p[1] == '{' || p[1] == '(') {
|
||||
char endc = p[1] == '{' ? '}' : ')';
|
||||
p += 2;
|
||||
ForLoop_SubstVarLong(f, &p, bodyEnd,
|
||||
p[-1] == '{' ? '}' : ')', &mark);
|
||||
ForLoop_SubstVarLong(f, &p, bodyEnd, endc, &mark);
|
||||
} else if (p[1] != '\0') {
|
||||
ForLoop_SubstVarShort(f, p + 1, &mark);
|
||||
p += 2;
|
||||
@ -483,7 +487,7 @@ ForReadMore(void *v_arg, size_t *out_len)
|
||||
{
|
||||
ForLoop *f = v_arg;
|
||||
|
||||
if (f->sub_next == f->items.len) {
|
||||
if (f->nextItem == f->items.len) {
|
||||
/* No more iterations */
|
||||
ForLoop_Free(f);
|
||||
return NULL;
|
||||
@ -491,7 +495,7 @@ ForReadMore(void *v_arg, size_t *out_len)
|
||||
|
||||
ForLoop_SubstBody(f);
|
||||
DEBUG1(FOR, "For: loop body:\n%s", f->curBody.data);
|
||||
f->sub_next += (unsigned int)f->vars.len;
|
||||
f->nextItem += (unsigned int)f->vars.len;
|
||||
|
||||
*out_len = f->curBody.len;
|
||||
return f->curBody.data;
|
||||
@ -513,5 +517,5 @@ For_Run(int lineno)
|
||||
return;
|
||||
}
|
||||
|
||||
Parse_SetInput(NULL, lineno, -1, ForReadMore, f);
|
||||
Parse_PushInput(NULL, lineno, -1, ForReadMore, f);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.c,v 1.64 2021/04/11 12:46:54 rillig Exp $ */
|
||||
/* $NetBSD: hash.c,v 1.66 2021/12/07 21:58:01 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -74,7 +74,7 @@
|
||||
#include "make.h"
|
||||
|
||||
/* "@(#)hash.c 8.1 (Berkeley) 6/6/93" */
|
||||
MAKE_RCSID("$NetBSD: hash.c,v 1.64 2021/04/11 12:46:54 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: hash.c,v 1.66 2021/12/07 21:58:01 rillig Exp $");
|
||||
|
||||
/*
|
||||
* The ratio of # entries to # buckets at which we rebuild the table to
|
||||
@ -152,7 +152,7 @@ HashTable_FindEntryBySubstring(HashTable *t, Substring key, unsigned int h)
|
||||
unsigned int chainlen = 0;
|
||||
|
||||
#ifdef DEBUG_HASH_LOOKUP
|
||||
DEBUG4(HASH, "%s: %p h=%08x key=%.*s\n", __func__, t, h,
|
||||
DEBUG5(HASH, "%s: %p h=%08x key=%.*s\n", __func__, t, h,
|
||||
(int)Substring_Length(key), key.start);
|
||||
#endif
|
||||
|
||||
@ -333,15 +333,6 @@ HashTable_DeleteEntry(HashTable *t, HashEntry *he)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Set things up for iterating over all entries in the hash table. */
|
||||
void
|
||||
HashIter_Init(HashIter *hi, HashTable *t)
|
||||
{
|
||||
hi->table = t;
|
||||
hi->nextBucket = 0;
|
||||
hi->entry = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next entry in the hash table, or NULL if the end of the table
|
||||
* is reached.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.h,v 1.40 2021/04/11 12:46:54 rillig Exp $ */
|
||||
/* $NetBSD: hash.h,v 1.41 2021/12/07 21:58:01 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -120,6 +120,15 @@ HashEntry_Set(HashEntry *h, void *datum)
|
||||
h->value = datum;
|
||||
}
|
||||
|
||||
/* Set things up for iterating over all entries in the hash table. */
|
||||
MAKE_INLINE void
|
||||
HashIter_Init(HashIter *hi, HashTable *t)
|
||||
{
|
||||
hi->table = t;
|
||||
hi->nextBucket = 0;
|
||||
hi->entry = NULL;
|
||||
}
|
||||
|
||||
void HashTable_Init(HashTable *);
|
||||
void HashTable_Done(HashTable *);
|
||||
HashEntry *HashTable_FindEntry(HashTable *, const char *);
|
||||
|
@ -26,6 +26,7 @@ option_parsing() {
|
||||
*=*) eval "$1"; shift;;
|
||||
--) shift; break;;
|
||||
-a) TARBALL=$2; shift 2;;
|
||||
-d) RM=echo; shift;;
|
||||
-n) ECHO=echo; shift;;
|
||||
-P) PR=$2; shift 2;;
|
||||
-r) REVIEWER=$2; shift 2;;
|
||||
@ -55,6 +56,7 @@ TF=/tmp/.$USER.$$
|
||||
Cd `dirname $0`
|
||||
test -s ${TARBALL:-/dev/null} || Error need TARBALL
|
||||
here=`pwd`
|
||||
SB=${SB:-`dirname $here`}
|
||||
# thing should match what the TARBALL contains
|
||||
thing=`basename $here`
|
||||
|
||||
@ -66,7 +68,7 @@ esac
|
||||
VERSION=`grep '^_MAKE_VERSION' VERSION | sed 's,.*=[[:space:]]*,,'`
|
||||
|
||||
rm -f *~
|
||||
mkdir -p ../tmp
|
||||
mkdir -p $SB/tmp
|
||||
|
||||
# new files are handled automatically
|
||||
# but we need to rm if needed
|
||||
@ -81,12 +83,15 @@ comm -13 $TF.adds $TF.rms > $TF.rm
|
||||
if [ -z "$ECHO" ]; then
|
||||
test -s $TF.rm && xargs rm -f < $TF.rm
|
||||
$GIT add -A
|
||||
$GIT diff --staged | tee ../tmp/bmake-import.diff
|
||||
echo "$GIT tag -a vendor/NetBSD/bmake/$VERSION" > ../tmp/bmake-post.sh
|
||||
echo "After you commit, run $here/../tmp/bmake-post.sh"
|
||||
$GIT diff --staged | tee $SB/tmp/bmake-import.diff
|
||||
{ echo "$GIT tag -a vendor/NetBSD/bmake/$VERSION"
|
||||
echo "echo \"When ready do: $GIT push --follow-tags\""
|
||||
} > $SB/tmp/bmake-post.sh
|
||||
echo "After you commit, run $SB/tmp/bmake-post.sh"
|
||||
else
|
||||
comm -23 $TF.adds $TF.rms > $TF.add
|
||||
test -s $TF.rm && { echo Removing:; cat $TF.rm; }
|
||||
test -s $TF.add && { echo Adding:; cat $TF.add; }
|
||||
$GIT diff
|
||||
fi
|
||||
${RM:-rm} -f $TF.*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.c,v 1.435 2021/06/16 09:47:51 rillig Exp $ */
|
||||
/* $NetBSD: job.c,v 1.440 2021/11/28 19:51:06 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -155,7 +155,7 @@
|
||||
#include "trace.h"
|
||||
|
||||
/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: job.c,v 1.435 2021/06/16 09:47:51 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: job.c,v 1.440 2021/11/28 19:51:06 rillig Exp $");
|
||||
|
||||
/*
|
||||
* A shell defines how the commands are run. All commands for a target are
|
||||
@ -794,8 +794,8 @@ ShellWriter_WriteFmt(ShellWriter *wr, const char *fmt, const char *arg)
|
||||
DEBUG1(JOB, fmt, arg);
|
||||
|
||||
(void)fprintf(wr->f, fmt, arg);
|
||||
/* XXX: Is flushing needed in any case, or only if f == stdout? */
|
||||
(void)fflush(wr->f);
|
||||
if (wr->f == stdout)
|
||||
(void)fflush(wr->f);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1097,10 +1097,20 @@ DebugFailedJob(const Job *job)
|
||||
if (!DEBUG(ERROR))
|
||||
return;
|
||||
|
||||
debug_printf("\n*** Failed target: %s\n*** Failed commands:\n",
|
||||
job->node->name);
|
||||
for (ln = job->node->commands.first; ln != NULL; ln = ln->next)
|
||||
debug_printf("\t%s\n", (const char *)ln->datum);
|
||||
debug_printf("\n");
|
||||
debug_printf("*** Failed target: %s\n", job->node->name);
|
||||
debug_printf("*** Failed commands:\n");
|
||||
for (ln = job->node->commands.first; ln != NULL; ln = ln->next) {
|
||||
const char *cmd = ln->datum;
|
||||
debug_printf("\t%s\n", cmd);
|
||||
|
||||
if (strchr(cmd, '$') != NULL) {
|
||||
char *xcmd;
|
||||
(void)Var_Subst(cmd, job->node, VARE_WANTRES, &xcmd);
|
||||
debug_printf("\t=> %s\n", xcmd);
|
||||
free(xcmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1192,7 +1202,9 @@ JobFinish (Job *job, WAIT_T status)
|
||||
|
||||
JobClosePipes(job);
|
||||
if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
|
||||
(void)fclose(job->cmdFILE);
|
||||
if (fclose(job->cmdFILE) != 0)
|
||||
Punt("Cannot write shell script for '%s': %s",
|
||||
job->node->name, strerror(errno));
|
||||
job->cmdFILE = NULL;
|
||||
}
|
||||
done = true;
|
||||
@ -1384,7 +1396,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
|
||||
* this node's parents so they never get examined.
|
||||
*/
|
||||
|
||||
if (gn->flags & FROM_DEPEND) {
|
||||
if (gn->flags.fromDepend) {
|
||||
if (!Job_RunTarget(".STALE", gn->fname))
|
||||
fprintf(stdout,
|
||||
"%s: %s, %d: ignoring stale %s for %s\n",
|
||||
@ -1558,7 +1570,9 @@ JobExec(Job *job, char **argv)
|
||||
watchfd(job);
|
||||
|
||||
if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
|
||||
(void)fclose(job->cmdFILE);
|
||||
if (fclose(job->cmdFILE) != 0)
|
||||
Punt("Cannot write shell script for '%s': %s",
|
||||
job->node->name, strerror(errno));
|
||||
job->cmdFILE = NULL;
|
||||
}
|
||||
|
||||
@ -2128,7 +2142,7 @@ Job_CatchOutput(void)
|
||||
JobRestartJobs();
|
||||
} else if (count == 0)
|
||||
Punt("unexpected eof on token pipe");
|
||||
else
|
||||
else if (errno != EAGAIN)
|
||||
Punt("token pipe read: %s", strerror(errno));
|
||||
nready--;
|
||||
}
|
||||
@ -2182,8 +2196,11 @@ InitShellNameAndPath(void)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEFSHELL_PATH
|
||||
shellPath = DEFSHELL_PATH;
|
||||
#else
|
||||
shellPath = str_concat3(_PATH_DEFSHELLDIR, "/", shellName);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lst.h,v 1.98 2021/04/03 11:08:40 rillig Exp $ */
|
||||
/* $NetBSD: lst.h,v 1.99 2021/12/05 10:11:31 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -142,9 +142,9 @@ ListNode *Lst_FindDatum(List *, const void *);
|
||||
|
||||
/* Insert a datum before the given node. */
|
||||
void Lst_InsertBefore(List *, ListNode *, void *);
|
||||
/* Place a datum at the front of the list. */
|
||||
/* Add a datum at the front of the list. */
|
||||
void Lst_Prepend(List *, void *);
|
||||
/* Place a datum at the end of the list. */
|
||||
/* Add a datum at the end of the list. */
|
||||
void Lst_Append(List *, void *);
|
||||
/* Remove the node from the list. */
|
||||
void Lst_Remove(List *, ListNode *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: main.c,v 1.540 2021/06/18 12:54:17 rillig Exp $ */
|
||||
/* $NetBSD: main.c,v 1.541 2021/08/14 13:32:12 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -111,7 +111,7 @@
|
||||
#include "trace.h"
|
||||
|
||||
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: main.c,v 1.540 2021/06/18 12:54:17 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: main.c,v 1.541 2021/08/14 13:32:12 rillig Exp $");
|
||||
#if defined(MAKE_NATIVE) && !defined(lint)
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
|
||||
"The Regents of the University of California. "
|
||||
@ -1127,7 +1127,7 @@ InitObjdir(const char *machine, const char *machine_arch)
|
||||
static void
|
||||
UnlimitFiles(void)
|
||||
{
|
||||
#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
|
||||
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
|
||||
struct rlimit rl;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
|
||||
rl.rlim_cur != rl.rlim_max) {
|
||||
@ -1685,7 +1685,7 @@ main_CleanUp(void)
|
||||
static int
|
||||
main_Exit(bool outOfDate)
|
||||
{
|
||||
if (opts.strict && (main_errors > 0 || Parse_GetFatals() > 0))
|
||||
if (opts.strict && (main_errors > 0 || Parse_NumErrors() > 0))
|
||||
return 2; /* Not 1 so -q can distinguish error */
|
||||
return outOfDate ? 1 : 0;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ do_link() {
|
||||
${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
|
||||
}
|
||||
|
||||
BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o enum.o for.o getopt hash.o \
|
||||
BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o hash.o \
|
||||
lst.o make.o make_malloc.o metachar.o parse.o sigcompat.o str.o \
|
||||
suff.o targ.o trace.o var.o util.o"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: make.1,v 1.296 2021/02/04 21:42:46 rillig Exp $
|
||||
.\" $NetBSD: make.1,v 1.300 2021/12/12 20:45:48 sjg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\"
|
||||
.Dd December 22, 2020
|
||||
.Dd December 12, 2021
|
||||
.Dt MAKE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1174,6 +1174,9 @@ executes.
|
||||
.It Ev .SHELL
|
||||
The pathname of the shell used to run target scripts.
|
||||
It is read-only.
|
||||
.It Ev .SUFFIXES
|
||||
The list of known suffixes.
|
||||
It is read-only.
|
||||
.It Ev .TARGETS
|
||||
The list of targets explicitly specified on the command line, if any.
|
||||
.It Ev VPATH
|
||||
@ -1244,8 +1247,20 @@ but selects all words which do not match
|
||||
.Ar pattern .
|
||||
.It Cm \&:O
|
||||
Orders every word in variable alphabetically.
|
||||
.It Cm \&:On
|
||||
Orders every word in variable numerically.
|
||||
A number followed by one of
|
||||
.Ql k ,
|
||||
.Ql M
|
||||
or
|
||||
.Ql G
|
||||
is multiplied by the appropriate factor (1024 (k), 1048576 (M), or
|
||||
1073741824 (G)).
|
||||
Both upper- and lower-case letters are accepted.
|
||||
.It Cm \&:Or
|
||||
Orders every word in variable in reverse alphabetical order.
|
||||
.It Cm \&:Orn
|
||||
Orders every word in variable in reverse numerical order.
|
||||
.It Cm \&:Ox
|
||||
Shuffles the words in variable.
|
||||
The results will be different each time you are referring to the
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.c,v 1.244 2021/04/04 10:05:08 rillig Exp $ */
|
||||
/* $NetBSD: make.c,v 1.248 2021/11/28 23:12:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -104,7 +104,7 @@
|
||||
#include "job.h"
|
||||
|
||||
/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */
|
||||
MAKE_RCSID("$NetBSD: make.c,v 1.244 2021/04/04 10:05:08 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: make.c,v 1.248 2021/11/28 23:12:51 rillig Exp $");
|
||||
|
||||
/* Sequence # to detect recursion. */
|
||||
static unsigned int checked_seqno = 1;
|
||||
@ -138,35 +138,83 @@ make_abort(GNode *gn, int lineno)
|
||||
abort();
|
||||
}
|
||||
|
||||
ENUM_FLAGS_RTTI_31(GNodeType,
|
||||
OP_DEPENDS, OP_FORCE, OP_DOUBLEDEP,
|
||||
/* OP_OPMASK is omitted since it combines other flags */
|
||||
OP_OPTIONAL, OP_USE, OP_EXEC, OP_IGNORE,
|
||||
OP_PRECIOUS, OP_SILENT, OP_MAKE, OP_JOIN,
|
||||
OP_MADE, OP_SPECIAL, OP_USEBEFORE, OP_INVISIBLE,
|
||||
OP_NOTMAIN, OP_PHONY, OP_NOPATH, OP_WAIT,
|
||||
OP_NOMETA, OP_META, OP_NOMETA_CMP, OP_SUBMAKE,
|
||||
OP_TRANSFORM, OP_MEMBER, OP_LIB, OP_ARCHV,
|
||||
OP_HAS_COMMANDS, OP_SAVE_CMDS, OP_DEPS_FOUND, OP_MARK);
|
||||
static const char *
|
||||
GNodeType_ToString(GNodeType type, void **freeIt)
|
||||
{
|
||||
Buffer buf;
|
||||
|
||||
ENUM_FLAGS_RTTI_9(GNodeFlags,
|
||||
REMAKE, CHILDMADE, FORCE, DONE_WAIT,
|
||||
DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE,
|
||||
DONECYCLE);
|
||||
Buf_InitSize(&buf, 32);
|
||||
#define ADD(flag) Buf_AddFlag(&buf, (type & (flag)) != OP_NONE, #flag)
|
||||
ADD(OP_DEPENDS);
|
||||
ADD(OP_FORCE);
|
||||
ADD(OP_DOUBLEDEP);
|
||||
ADD(OP_OPTIONAL);
|
||||
ADD(OP_USE);
|
||||
ADD(OP_EXEC);
|
||||
ADD(OP_IGNORE);
|
||||
ADD(OP_PRECIOUS);
|
||||
ADD(OP_SILENT);
|
||||
ADD(OP_MAKE);
|
||||
ADD(OP_JOIN);
|
||||
ADD(OP_MADE);
|
||||
ADD(OP_SPECIAL);
|
||||
ADD(OP_USEBEFORE);
|
||||
ADD(OP_INVISIBLE);
|
||||
ADD(OP_NOTMAIN);
|
||||
ADD(OP_PHONY);
|
||||
ADD(OP_NOPATH);
|
||||
ADD(OP_WAIT);
|
||||
ADD(OP_NOMETA);
|
||||
ADD(OP_META);
|
||||
ADD(OP_NOMETA_CMP);
|
||||
ADD(OP_SUBMAKE);
|
||||
ADD(OP_TRANSFORM);
|
||||
ADD(OP_MEMBER);
|
||||
ADD(OP_LIB);
|
||||
ADD(OP_ARCHV);
|
||||
ADD(OP_HAS_COMMANDS);
|
||||
ADD(OP_SAVE_CMDS);
|
||||
ADD(OP_DEPS_FOUND);
|
||||
ADD(OP_MARK);
|
||||
#undef ADD
|
||||
return buf.len == 0 ? "none" : (*freeIt = Buf_DoneData(&buf));
|
||||
}
|
||||
|
||||
static const char *
|
||||
GNodeFlags_ToString(GNodeFlags flags, void **freeIt)
|
||||
{
|
||||
Buffer buf;
|
||||
|
||||
Buf_InitSize(&buf, 32);
|
||||
#define ADD(flag, name) Buf_AddFlag(&buf, flags.flag, name)
|
||||
ADD(remake, "REMAKE");
|
||||
ADD(childMade, "CHILDMADE");
|
||||
ADD(force, "FORCE");
|
||||
ADD(doneWait, "DONE_WAIT");
|
||||
ADD(doneOrder, "DONE_ORDER");
|
||||
ADD(fromDepend, "FROM_DEPEND");
|
||||
ADD(doneAllsrc, "DONE_ALLSRC");
|
||||
ADD(cycle, "CYCLE");
|
||||
ADD(doneCycle, "DONECYCLE");
|
||||
#undef ADD
|
||||
return buf.len == 0 ? "none" : (*freeIt = Buf_DoneData(&buf));
|
||||
}
|
||||
|
||||
void
|
||||
GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,
|
||||
const char *suffix)
|
||||
{
|
||||
char type_buf[GNodeType_ToStringSize];
|
||||
char flags_buf[GNodeFlags_ToStringSize];
|
||||
void *type_freeIt = NULL;
|
||||
void *flags_freeIt = NULL;
|
||||
|
||||
fprintf(f, "%s%s, type %s, flags %s%s",
|
||||
prefix,
|
||||
GNodeMade_Name(gn->made),
|
||||
GNodeType_ToString(type_buf, gn->type),
|
||||
GNodeFlags_ToString(flags_buf, gn->flags),
|
||||
GNodeType_ToString(gn->type, &type_freeIt),
|
||||
GNodeFlags_ToString(gn->flags, &flags_freeIt),
|
||||
suffix);
|
||||
free(type_freeIt);
|
||||
free(flags_freeIt);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -286,8 +334,8 @@ GNode_IsOODate(GNode *gn)
|
||||
*/
|
||||
DEBUG0(MAKE, ".JOIN node...");
|
||||
DEBUG1(MAKE, "source %smade...",
|
||||
gn->flags & CHILDMADE ? "" : "not ");
|
||||
oodate = (gn->flags & CHILDMADE) != 0;
|
||||
gn->flags.childMade ? "" : "not ");
|
||||
oodate = gn->flags.childMade;
|
||||
} else if (gn->type & (OP_FORCE | OP_EXEC | OP_PHONY)) {
|
||||
/*
|
||||
* A node which is the object of the force (!) operator or
|
||||
@ -315,10 +363,10 @@ GNode_IsOODate(GNode *gn)
|
||||
* child after it was considered made.
|
||||
*/
|
||||
if (DEBUG(MAKE)) {
|
||||
if (gn->flags & FORCE)
|
||||
if (gn->flags.force)
|
||||
debug_printf("non existing child...");
|
||||
}
|
||||
oodate = (gn->flags & FORCE) != 0;
|
||||
oodate = gn->flags.force;
|
||||
}
|
||||
|
||||
#ifdef USE_META
|
||||
@ -568,7 +616,7 @@ UpdateImplicitParentsVars(GNode *cgn, const char *cname)
|
||||
|
||||
for (ln = cgn->implicitParents.first; ln != NULL; ln = ln->next) {
|
||||
GNode *pgn = ln->datum;
|
||||
if (pgn->flags & REMAKE) {
|
||||
if (pgn->flags.remake) {
|
||||
Var_Set(pgn, IMPSRC, cname);
|
||||
if (cpref != NULL)
|
||||
Var_Set(pgn, PREFIX, cpref);
|
||||
@ -585,7 +633,7 @@ IsWaitingForOrder(GNode *gn)
|
||||
for (ln = gn->order_pred.first; ln != NULL; ln = ln->next) {
|
||||
GNode *ogn = ln->datum;
|
||||
|
||||
if (GNode_IsDone(ogn) || !(ogn->flags & REMAKE))
|
||||
if (GNode_IsDone(ogn) || !ogn->flags.remake)
|
||||
continue;
|
||||
|
||||
DEBUG2(MAKE,
|
||||
@ -684,13 +732,13 @@ Make_Update(GNode *cgn)
|
||||
debug_printf(", unmade %d ", pgn->unmade - 1);
|
||||
}
|
||||
|
||||
if (!(pgn->flags & REMAKE)) {
|
||||
if (!pgn->flags.remake) {
|
||||
/* This parent isn't needed */
|
||||
DEBUG0(MAKE, "- not needed\n");
|
||||
continue;
|
||||
}
|
||||
if (mtime == 0 && !(cgn->type & OP_WAIT))
|
||||
pgn->flags |= FORCE;
|
||||
pgn->flags.force = true;
|
||||
|
||||
/*
|
||||
* If the parent has the .MADE attribute, its timestamp got
|
||||
@ -707,7 +755,7 @@ Make_Update(GNode *cgn)
|
||||
|
||||
if (!(cgn->type & (OP_EXEC | OP_USE | OP_USEBEFORE))) {
|
||||
if (cgn->made == MADE)
|
||||
pgn->flags |= CHILDMADE;
|
||||
pgn->flags.childMade = true;
|
||||
GNode_UpdateYoungestChild(pgn, cgn);
|
||||
}
|
||||
|
||||
@ -740,7 +788,7 @@ Make_Update(GNode *cgn)
|
||||
* nodes.
|
||||
*/
|
||||
if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)
|
||||
&& !(centurion->flags & DONE_ORDER)) {
|
||||
&& !centurion->flags.doneOrder) {
|
||||
DEBUG0(MAKE, "- unmade children\n");
|
||||
continue;
|
||||
}
|
||||
@ -873,7 +921,7 @@ GNode_SetLocalVars(GNode *gn)
|
||||
{
|
||||
GNodeListNode *ln;
|
||||
|
||||
if (gn->flags & DONE_ALLSRC)
|
||||
if (gn->flags.doneAllsrc)
|
||||
return;
|
||||
|
||||
UnmarkChildren(gn);
|
||||
@ -887,7 +935,7 @@ GNode_SetLocalVars(GNode *gn)
|
||||
|
||||
if (gn->type & OP_JOIN)
|
||||
Var_Set(gn, TARGET, GNode_VarAllsrc(gn));
|
||||
gn->flags |= DONE_ALLSRC;
|
||||
gn->flags.doneAllsrc = true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -942,7 +990,7 @@ MakeBuildParent(GNode *pn, GNodeListNode *toBeMadeNext)
|
||||
|
||||
if (!MakeBuildChild(pn, toBeMadeNext)) {
|
||||
/* When this node is built, reschedule its parents. */
|
||||
pn->flags |= DONE_ORDER;
|
||||
pn->flags.doneOrder = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1085,7 +1133,7 @@ static void MakePrintStatusList(GNodeList *, int *);
|
||||
static bool
|
||||
MakePrintStatus(GNode *gn, int *errors)
|
||||
{
|
||||
if (gn->flags & DONECYCLE) {
|
||||
if (gn->flags.doneCycle) {
|
||||
/*
|
||||
* We've completely processed this node before, don't do
|
||||
* it again.
|
||||
@ -1094,7 +1142,7 @@ MakePrintStatus(GNode *gn, int *errors)
|
||||
}
|
||||
|
||||
if (gn->unmade == 0) {
|
||||
gn->flags |= DONECYCLE;
|
||||
gn->flags.doneCycle = true;
|
||||
switch (gn->made) {
|
||||
case UPTODATE:
|
||||
printf("`%s%s' is up to date.\n", gn->name,
|
||||
@ -1138,17 +1186,17 @@ MakePrintStatus(GNode *gn, int *errors)
|
||||
* If printing cycles and came to one that has unmade children,
|
||||
* print out the cycle by recursing on its children.
|
||||
*/
|
||||
if (!(gn->flags & CYCLE)) {
|
||||
if (!gn->flags.cycle) {
|
||||
/* First time we've seen this node, check all children */
|
||||
gn->flags |= CYCLE;
|
||||
gn->flags.cycle = true;
|
||||
MakePrintStatusList(&gn->children, errors);
|
||||
/* Mark that this node needn't be processed again */
|
||||
gn->flags |= DONECYCLE;
|
||||
gn->flags.doneCycle = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Only output the error once per node */
|
||||
gn->flags |= DONECYCLE;
|
||||
gn->flags.doneCycle = true;
|
||||
Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);
|
||||
if ((*errors)++ > 100)
|
||||
/* Abandon the whole error report */
|
||||
@ -1177,7 +1225,7 @@ ExamineLater(GNodeList *examine, GNodeList *toBeExamined)
|
||||
for (ln = toBeExamined->first; ln != NULL; ln = ln->next) {
|
||||
GNode *gn = ln->datum;
|
||||
|
||||
if (gn->flags & REMAKE)
|
||||
if (gn->flags.remake)
|
||||
continue;
|
||||
if (gn->type & (OP_USE | OP_USEBEFORE))
|
||||
continue;
|
||||
@ -1213,10 +1261,10 @@ Make_ExpandUse(GNodeList *targs)
|
||||
while (!Lst_IsEmpty(&examine)) {
|
||||
GNode *gn = Lst_Dequeue(&examine);
|
||||
|
||||
if (gn->flags & REMAKE)
|
||||
if (gn->flags.remake)
|
||||
/* We've looked at this one already */
|
||||
continue;
|
||||
gn->flags |= REMAKE;
|
||||
gn->flags.remake = true;
|
||||
DEBUG2(MAKE, "Make_ExpandUse: examine %s%s\n",
|
||||
gn->name, gn->cohort_num);
|
||||
|
||||
@ -1301,7 +1349,7 @@ Make_ProcessWait(GNodeList *targs)
|
||||
*/
|
||||
|
||||
pgn = GNode_New(".MAIN");
|
||||
pgn->flags = REMAKE;
|
||||
pgn->flags.remake = true;
|
||||
pgn->type = OP_PHONY | OP_DEPENDS;
|
||||
/* Get it displayed in the diag dumps */
|
||||
Lst_Prepend(Targ_List(), pgn);
|
||||
@ -1329,9 +1377,9 @@ Make_ProcessWait(GNodeList *targs)
|
||||
pgn = Lst_Dequeue(&examine);
|
||||
|
||||
/* We only want to process each child-list once */
|
||||
if (pgn->flags & DONE_WAIT)
|
||||
if (pgn->flags.doneWait)
|
||||
continue;
|
||||
pgn->flags |= DONE_WAIT;
|
||||
pgn->flags.doneWait = true;
|
||||
DEBUG1(MAKE, "Make_ProcessWait: examine %s\n", pgn->name);
|
||||
|
||||
if (pgn->type & OP_DOUBLEDEP)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.h,v 1.263 2021/06/21 10:33:11 rillig Exp $ */
|
||||
/* $NetBSD: make.h,v 1.270 2021/11/28 23:12:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -136,25 +136,38 @@
|
||||
#endif
|
||||
|
||||
#define MAKE_INLINE static inline MAKE_ATTR_UNUSED
|
||||
|
||||
/* MAKE_STATIC marks a function that may or may not be inlined. */
|
||||
#if defined(lint)
|
||||
/* As of 2021-07-31, NetBSD lint ignores __attribute__((unused)). */
|
||||
#define MAKE_STATIC MAKE_INLINE
|
||||
#else
|
||||
#define MAKE_STATIC static MAKE_ATTR_UNUSED
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ >= 199901L || defined(lint) || defined(USE_C99_BOOLEAN)
|
||||
#include <stdbool.h>
|
||||
#elif defined(__bool_true_false_are_defined)
|
||||
/*
|
||||
* All files of make must be compiled with the same definition of bool.
|
||||
* Since one of the files includes <stdbool.h>, that means the header is
|
||||
* available on this platform. Recompile everything with -DUSE_C99_BOOLEAN.
|
||||
*/
|
||||
#error "<stdbool.h> is included in pre-C99 mode"
|
||||
#elif defined(bool) || defined(true) || defined(false)
|
||||
/*
|
||||
* In pre-C99 mode, make does not expect that bool is already defined.
|
||||
* You need to ensure that all translation units use the same definition for
|
||||
* bool.
|
||||
*/
|
||||
#error "bool/true/false is defined in pre-C99 mode"
|
||||
#else
|
||||
#ifndef bool
|
||||
typedef unsigned int Boolean;
|
||||
#define bool Boolean
|
||||
#endif
|
||||
#ifndef true
|
||||
typedef unsigned char bool;
|
||||
#define true 1
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "lst.h"
|
||||
#include "enum.h"
|
||||
#include "make_malloc.h"
|
||||
#include "str.h"
|
||||
#include "hash.h"
|
||||
@ -324,26 +337,25 @@ typedef enum GNodeType {
|
||||
OP_NOTARGET = OP_NOTMAIN | OP_USE | OP_EXEC | OP_TRANSFORM
|
||||
} GNodeType;
|
||||
|
||||
typedef enum GNodeFlags {
|
||||
GNF_NONE = 0,
|
||||
typedef struct GNodeFlags {
|
||||
/* this target needs to be (re)made */
|
||||
REMAKE = 1 << 0,
|
||||
bool remake:1;
|
||||
/* children of this target were made */
|
||||
CHILDMADE = 1 << 1,
|
||||
bool childMade:1;
|
||||
/* children don't exist, and we pretend made */
|
||||
FORCE = 1 << 2,
|
||||
bool force:1;
|
||||
/* Set by Make_ProcessWait() */
|
||||
DONE_WAIT = 1 << 3,
|
||||
bool doneWait:1;
|
||||
/* Build requested by .ORDER processing */
|
||||
DONE_ORDER = 1 << 4,
|
||||
bool doneOrder:1;
|
||||
/* Node created from .depend */
|
||||
FROM_DEPEND = 1 << 5,
|
||||
bool fromDepend:1;
|
||||
/* We do it once only */
|
||||
DONE_ALLSRC = 1 << 6,
|
||||
bool doneAllsrc:1;
|
||||
/* Used by MakePrintStatus */
|
||||
CYCLE = 1 << 12,
|
||||
bool cycle:1;
|
||||
/* Used by MakePrintStatus */
|
||||
DONECYCLE = 1 << 13
|
||||
bool doneCycle:1;
|
||||
} GNodeFlags;
|
||||
|
||||
typedef struct List StringList;
|
||||
@ -583,7 +595,7 @@ void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
|
||||
do { \
|
||||
if (DEBUG(module)) \
|
||||
debug_printf args; \
|
||||
} while (/*CONSTCOND*/false)
|
||||
} while (false)
|
||||
|
||||
#define DEBUG0(module, text) \
|
||||
DEBUG_IMPL(module, ("%s", text))
|
||||
@ -710,7 +722,7 @@ bool GNode_ShouldExecute(GNode *gn);
|
||||
MAKE_INLINE bool
|
||||
GNode_IsTarget(const GNode *gn)
|
||||
{
|
||||
return (gn->type & OP_OPMASK) != 0;
|
||||
return (gn->type & OP_OPMASK) != OP_NONE;
|
||||
}
|
||||
|
||||
MAKE_INLINE const char *
|
||||
@ -722,7 +734,7 @@ GNode_Path(const GNode *gn)
|
||||
MAKE_INLINE bool
|
||||
GNode_IsWaitingFor(const GNode *gn)
|
||||
{
|
||||
return (gn->flags & REMAKE) && gn->made <= REQUESTED;
|
||||
return gn->flags.remake && gn->made <= REQUESTED;
|
||||
}
|
||||
|
||||
MAKE_INLINE bool
|
||||
@ -758,16 +770,13 @@ GNode_VarArchive(GNode *gn) { return GNode_ValueDirect(gn, ARCHIVE); }
|
||||
MAKE_INLINE const char *
|
||||
GNode_VarMember(GNode *gn) { return GNode_ValueDirect(gn, MEMBER); }
|
||||
|
||||
#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L
|
||||
#define UNCONST(ptr) ({ \
|
||||
union __unconst { \
|
||||
const void *__cp; \
|
||||
void *__p; \
|
||||
} __d; \
|
||||
__d.__cp = ptr, __d.__p; })
|
||||
#else
|
||||
#define UNCONST(ptr) (void *)(ptr)
|
||||
#endif
|
||||
MAKE_INLINE void *
|
||||
UNCONST(const void *ptr)
|
||||
{
|
||||
void *ret;
|
||||
memcpy(&ret, &ptr, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
|
||||
#ifdef HAVE_LIMITS_H
|
||||
@ -833,6 +842,16 @@ pp_skip_hspace(char **pp)
|
||||
# define MAKE_RCSID(id) extern void do_not_define_rcsid(void)
|
||||
#elif defined(MAKE_NATIVE)
|
||||
# include <sys/cdefs.h>
|
||||
# ifndef __IDSTRING
|
||||
# define __IDSTRING(name,string) \
|
||||
static const char name[] MAKE_ATTR_UNUSED = string
|
||||
# endif
|
||||
# ifndef __RCSID
|
||||
# define __RCSID(s) __IDSTRING(rcsid,s)
|
||||
# endif
|
||||
# ifndef __COPYRIGHT
|
||||
# define __COPYRIGHT(s) __IDSTRING(copyright,s)
|
||||
# endif
|
||||
# define MAKE_RCSID(id) __RCSID(id)
|
||||
#elif defined(MAKE_ALL_IN_ONE) && defined(__COUNTER__)
|
||||
# define MAKE_RCSID_CONCAT(x, y) CONCAT(x, y)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.c,v 1.181 2021/04/04 10:05:08 rillig Exp $ */
|
||||
/* $NetBSD: meta.c,v 1.185 2021/11/27 22:04:02 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Implement 'meta' mode.
|
||||
@ -98,6 +98,9 @@ extern char **environ;
|
||||
#if !defined(HAVE_STRSEP)
|
||||
# define strsep(s, d) stresep((s), (d), '\0')
|
||||
#endif
|
||||
#if !defined(HAVE_STRESEP)
|
||||
char * stresep(char **, const char *, int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Filemon is a kernel module which snoops certain syscalls.
|
||||
@ -149,11 +152,11 @@ meta_open_filemon(BuildMon *pbm)
|
||||
else
|
||||
pbm->mon_fd = mkTempFile("filemon.XXXXXX", NULL, 0);
|
||||
if ((dupfd = dup(pbm->mon_fd)) == -1) {
|
||||
err(1, "Could not dup filemon output!");
|
||||
Punt("Could not dup filemon output: %s", strerror(errno));
|
||||
}
|
||||
(void)fcntl(dupfd, F_SETFD, FD_CLOEXEC);
|
||||
if (filemon_setfd(pbm->filemon, dupfd) == -1) {
|
||||
err(1, "Could not set filemon file descriptor!");
|
||||
Punt("Could not set filemon file descriptor: %s", strerror(errno));
|
||||
}
|
||||
/* we don't need these once we exec */
|
||||
(void)fcntl(pbm->mon_fd, F_SETFD, FD_CLOEXEC);
|
||||
@ -191,7 +194,9 @@ filemon_read(FILE *mfp, int fd)
|
||||
error = EIO;
|
||||
}
|
||||
}
|
||||
fflush(mfp);
|
||||
if (fflush(mfp) != 0)
|
||||
Punt("Cannot write filemon data to meta file: %s",
|
||||
strerror(errno));
|
||||
if (close(fd) < 0)
|
||||
error = errno;
|
||||
return error;
|
||||
@ -248,8 +253,8 @@ meta_name(char *mname, size_t mnamelen,
|
||||
const char *cwd)
|
||||
{
|
||||
char buf[MAXPATHLEN];
|
||||
char *rp;
|
||||
char *cp;
|
||||
char *rp, *cp;
|
||||
const char *tname_base;
|
||||
char *tp;
|
||||
char *dtp;
|
||||
size_t ldname;
|
||||
@ -261,13 +266,13 @@ meta_name(char *mname, size_t mnamelen,
|
||||
* So we use realpath() just to get the dirname, and leave the
|
||||
* basename as given to us.
|
||||
*/
|
||||
if ((cp = strrchr(tname, '/')) != NULL) {
|
||||
if ((tname_base = strrchr(tname, '/')) != NULL) {
|
||||
if (cached_realpath(tname, buf) != NULL) {
|
||||
if ((rp = strrchr(buf, '/')) != NULL) {
|
||||
rp++;
|
||||
cp++;
|
||||
if (strcmp(cp, rp) != 0)
|
||||
strlcpy(rp, cp, sizeof buf - (size_t)(rp - buf));
|
||||
tname_base++;
|
||||
if (strcmp(tname_base, rp) != 0)
|
||||
strlcpy(rp, tname_base, sizeof buf - (size_t)(rp - buf));
|
||||
}
|
||||
tname = buf;
|
||||
} else {
|
||||
@ -325,8 +330,7 @@ is_submake(const char *cmd, GNode *gn)
|
||||
static const char *p_make = NULL;
|
||||
static size_t p_len;
|
||||
char *mp = NULL;
|
||||
char *cp;
|
||||
char *cp2;
|
||||
const char *cp, *cp2;
|
||||
bool rc = false;
|
||||
|
||||
if (p_make == NULL) {
|
||||
@ -412,7 +416,7 @@ printCMDs(GNode *gn, FILE *fp)
|
||||
} \
|
||||
return false; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/false)
|
||||
} while (false)
|
||||
|
||||
|
||||
/*
|
||||
@ -523,7 +527,7 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
#endif
|
||||
|
||||
if ((fp = fopen(fname, "w")) == NULL)
|
||||
err(1, "Could not open meta file '%s'", fname);
|
||||
Punt("Could not open meta file '%s': %s", fname, strerror(errno));
|
||||
|
||||
fprintf(fp, "# Meta data file %s\n", fname);
|
||||
|
||||
@ -541,7 +545,9 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
}
|
||||
|
||||
fprintf(fp, "-- command output --\n");
|
||||
fflush(fp);
|
||||
if (fflush(fp) != 0)
|
||||
Punt("Cannot write expanded command to meta file: %s",
|
||||
strerror(errno));
|
||||
|
||||
Global_Append(".MAKE.META.FILES", fname);
|
||||
Global_Append(".MAKE.META.CREATED", fname);
|
||||
@ -557,9 +563,9 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
}
|
||||
|
||||
static bool
|
||||
boolValue(char *s)
|
||||
boolValue(const char *s)
|
||||
{
|
||||
switch(*s) {
|
||||
switch (*s) {
|
||||
case '0':
|
||||
case 'N':
|
||||
case 'n':
|
||||
@ -594,7 +600,7 @@ void
|
||||
meta_mode_init(const char *make_mode)
|
||||
{
|
||||
static bool once = false;
|
||||
char *cp;
|
||||
const char *cp;
|
||||
FStr value;
|
||||
|
||||
useMeta = true;
|
||||
@ -715,7 +721,7 @@ meta_job_child(Job *job)
|
||||
|
||||
pid = getpid();
|
||||
if (filemon_setpid_child(pbm->filemon, pid) == -1) {
|
||||
err(1, "Could not set filemon pid!");
|
||||
Punt("Could not set filemon pid: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -855,8 +861,10 @@ meta_cmd_finish(void *pbmp)
|
||||
if (pbm->filemon != NULL) {
|
||||
while (filemon_process(pbm->filemon) > 0)
|
||||
continue;
|
||||
if (filemon_close(pbm->filemon) == -1)
|
||||
if (filemon_close(pbm->filemon) == -1) {
|
||||
error = errno;
|
||||
Punt("filemon failed: %s", strerror(errno));
|
||||
}
|
||||
x = filemon_read(pbm->mfp, pbm->mon_fd);
|
||||
if (error == 0 && x != 0)
|
||||
error = x;
|
||||
@ -1710,7 +1718,7 @@ meta_compat_parent(pid_t child)
|
||||
fflush(stdout);
|
||||
buf[nread] = '\0';
|
||||
meta_job_output(NULL, buf, "");
|
||||
} while (/*CONSTCOND*/false);
|
||||
} while (false);
|
||||
if (metafd != -1 && FD_ISSET(metafd, &readfds) != 0) {
|
||||
if (meta_job_event(NULL) <= 0)
|
||||
metafd = -1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: metachar.c,v 1.9 2021/01/19 20:51:46 rillig Exp $ */
|
||||
/* $NetBSD: metachar.c,v 1.10 2021/06/21 18:54:41 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
#include "metachar.h"
|
||||
|
||||
MAKE_RCSID("$NetBSD: metachar.c,v 1.9 2021/01/19 20:51:46 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: metachar.c,v 1.10 2021/06/21 18:54:41 rillig Exp $");
|
||||
|
||||
/*
|
||||
* The following array is used to make a fast determination of which
|
||||
@ -48,7 +48,7 @@ MAKE_RCSID("$NetBSD: metachar.c,v 1.9 2021/01/19 20:51:46 rillig Exp $");
|
||||
* directly by us.
|
||||
*/
|
||||
|
||||
unsigned char _metachar[128] = {
|
||||
const unsigned char _metachar[128] = {
|
||||
/* nul soh stx etx eot enq ack bel */
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* bs ht nl vt np cr so si */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: metachar.h,v 1.16 2021/04/03 11:08:40 rillig Exp $ */
|
||||
/* $NetBSD: metachar.h,v 1.17 2021/06/21 18:54:41 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@ -33,9 +33,13 @@
|
||||
|
||||
#include "make.h"
|
||||
|
||||
extern unsigned char _metachar[];
|
||||
extern const unsigned char _metachar[];
|
||||
|
||||
#define is_shell_metachar(c) (_metachar[(c) & 0x7f] != 0)
|
||||
MAKE_INLINE bool
|
||||
is_shell_metachar(char c)
|
||||
{
|
||||
return _metachar[c & 0x7f] != 0;
|
||||
}
|
||||
|
||||
MAKE_INLINE bool
|
||||
needshell(const char *cmd)
|
||||
|
@ -1,3 +1,107 @@
|
||||
2021-12-12 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* sys.mk: simplify; include meta.sys.mk if MK_META_MODE is yes.
|
||||
|
||||
* meta.sys.mk: do not check for /dev/filemon if .MAKE.PATH_FILEMON
|
||||
is something else.
|
||||
|
||||
* meta.autodep.mk: we can now reference ${.SUFFIXES}
|
||||
|
||||
* meta2deps.py: derive a list of dirdep extensions from
|
||||
TARGET_SPEC to trim from dirdeps.
|
||||
|
||||
* dirdeps.mk: flip the computation of qualified vs unqualified
|
||||
dirdeps - it is much simpler to check for unqualified first.
|
||||
|
||||
2021-12-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20211212
|
||||
|
||||
* auto.dep.mk: rearrange so that the trivial implementation
|
||||
for recent bmake is more obvious.
|
||||
|
||||
2021-12-07 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20211207
|
||||
|
||||
* Ensure guard targets are .NOTMAIN
|
||||
|
||||
* meta.sys.mk: check for nofilemon support when we skip level 0
|
||||
|
||||
* auto.dep.mk: make this usable in meta mode
|
||||
for platforms that cannot use meta.autodep.mk
|
||||
|
||||
* meta2deps.py: avoid confusion if MACHINE and another
|
||||
TARGET_SPEC_VAR have same value.
|
||||
|
||||
2021-11-27 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: when building dirdeps.cache, minimize the amount of
|
||||
data put into env, by stripping ${SRCTOP}/ from each entry.
|
||||
A long sandbox name can double the amount of memory consumed and
|
||||
in extreme cases cause failure.
|
||||
While we are at it, strip ${SRCTOP}/ from a lot of the debug output.
|
||||
|
||||
2021-11-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20211111
|
||||
|
||||
* meta.stage.mk (LN_CP_SCRIPT): if staging to NFS cp -p can fail
|
||||
so fallback to cp if necessary.
|
||||
|
||||
2021-10-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* man.mk (CMT2DOC): use cmt2doc.py rather than the 30 year
|
||||
old cmt2doc.pl
|
||||
|
||||
2021-10-24 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* meta.stage.mk: stage_as_and_symlink use ${STAGE_LINK_AS_$f:U$f}
|
||||
as the symlink (rare)
|
||||
|
||||
2021-10-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* autoconf.mk: if AUTOCONF_GENERATED_MAKEFILE is set and has not
|
||||
been read, throw an error after running configure telling user to
|
||||
restart.
|
||||
|
||||
2021-10-13 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20211011
|
||||
|
||||
* Add support for SCO_SV
|
||||
|
||||
2021-10-01 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20211001
|
||||
|
||||
* man.mk: use MAN_SUFFIXES and CMT2DOC_SUFFIXES for more
|
||||
flexibility
|
||||
|
||||
2021-09-13 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* options.mk (describe-options): print options and their values
|
||||
and optional description
|
||||
|
||||
2021-09-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210911
|
||||
|
||||
* options.mk (show-options): print options and their values
|
||||
|
||||
2021-09-08 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210909
|
||||
|
||||
* lib.mk: apply patch from <daniel@octaforge.org>
|
||||
to fix shared libs on Linux
|
||||
|
||||
2021-08-08 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210808
|
||||
|
||||
* options.mk: issue warning for WITH_*=no
|
||||
|
||||
2021-06-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20210616
|
||||
|
@ -54,6 +54,7 @@ sys/Linux.mk
|
||||
sys/NetBSD.mk
|
||||
sys/OSF1.mk
|
||||
sys/OpenBSD.mk
|
||||
sys/SCO_SV.mk
|
||||
sys/SunOS.mk
|
||||
sys/UnixWare.mk
|
||||
target-flags.mk
|
||||
|
@ -1,8 +1,8 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: auto.dep.mk,v 1.6 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: auto.dep.mk,v 1.10 2021/12/11 18:57:41 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
# @(#) Copyright (c) 2010-2021, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
@ -30,39 +30,24 @@
|
||||
# dep.mk will handle that itself.
|
||||
#
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
# this what bmake > 20100401 will look for
|
||||
.MAKE.DEPENDFILE ?= .depend
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
# set this to -MMD to ignore /usr/include
|
||||
# actually it ignores <> so may not be a great idea
|
||||
CFLAGS_MD ?= -MD
|
||||
# -MF etc not available on all gcc versions.
|
||||
.if ${COMPILER_TYPE:Ugcc} == "gcc" && ${COMPILER_VERSION:U0} < 30000
|
||||
CFLAGS_MF=
|
||||
.endif
|
||||
CFLAGS_MF ?= -MF ${.TARGET:T}.d -MT ${.TARGET:T}
|
||||
CFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
CXXFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
|
||||
CLEANFILES += .depend ${.MAKE.DEPENDFILE} *.d
|
||||
CLEANFILES += .depend *.d
|
||||
|
||||
.if ${MAKE_VERSION} < 20160218
|
||||
# skip generating dependfile for misc targets
|
||||
.if ${.TARGETS:Uall:M*all} != ""
|
||||
.END: ${.MAKE.DEPENDFILE}
|
||||
.endif
|
||||
.if ${MAKE_VERSION} >= 20160218
|
||||
|
||||
# doing 'make depend' isn't a big win with this model
|
||||
.if !target(depend)
|
||||
depend: ${.MAKE.DEPENDFILE}
|
||||
.endif
|
||||
|
||||
# this is trivial
|
||||
${.MAKE.DEPENDFILE}: ${OBJS} ${POBJS} ${SOBJS}
|
||||
-@for f in ${.ALLSRC:M*o:T:O:u:%=%.d}; do \
|
||||
echo ".-include \"$$f\""; \
|
||||
done > $@
|
||||
.else
|
||||
# we have .dinclude
|
||||
# we have .dinclude and this is all that is required
|
||||
.if empty(_SKIP_BUILD)
|
||||
_all_objs = ${OBJS} ${POBJS} ${SOBJS}
|
||||
.for d in ${_all_objs:M*o:T:O:u:%=%.d}
|
||||
@ -70,5 +55,34 @@ _all_objs = ${OBJS} ${POBJS} ${SOBJS}
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.else # we lack .dinclude
|
||||
|
||||
.if ${.MAKE.MODE:Unormal:Mmeta} != ""
|
||||
# ignore .MAKE.DEPENDFILE
|
||||
DEPENDFILE = .depend
|
||||
.else
|
||||
# this what bmake > 20100401 will look for
|
||||
.MAKE.DEPENDFILE ?= .depend
|
||||
DEPENDFILE ?= ${.MAKE.DEPENDFILE}
|
||||
.endif
|
||||
|
||||
CLEANFILES += ${DEPENDFILE}
|
||||
|
||||
# skip generating dependfile for misc targets
|
||||
.if ${.TARGETS:Uall:M*all} != ""
|
||||
.END: ${DEPENDFILE}
|
||||
.endif
|
||||
|
||||
# doing 'make depend' isn't a big win with this model
|
||||
.if !target(depend)
|
||||
depend: ${DEPENDFILE}
|
||||
.endif
|
||||
|
||||
# this is trivial
|
||||
${DEPENDFILE}: ${OBJS} ${POBJS} ${SOBJS}
|
||||
-@for f in ${.ALLSRC:M*o:T:O:u:%=%.d}; do \
|
||||
echo ".-include \"$$f\""; \
|
||||
done > $@
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: autoconf.mk,v 1.10 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: autoconf.mk,v 1.16 2021/10/19 17:36:06 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1996-2009, Simon J. Gerraty
|
||||
#
|
||||
@ -13,32 +13,37 @@
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.NOPATH: config.h config.status
|
||||
.NOPATH: config.h config.gen config.recheck config.status
|
||||
|
||||
CONFIGURE_DEPS += ${.CURDIR}/config.h.in ${.CURDIR}/configure
|
||||
|
||||
.if !target(config.h)
|
||||
config.h: ${CONFIGURE_DEPS} config.status
|
||||
config.h: .NOTMAIN ${CONFIGURE_DEPS} config.status
|
||||
./config.status
|
||||
.if !empty(AUTOCONF_GENERATED_MAKEFILE) && ${AUTOCONF_GENERATED_MAKEFILE:T:@m@${"${.MAKE.MAKEFILES:T:M$m}":?yes:no}@:Mno} != ""
|
||||
@echo Generated ${AUTOCONF_GENERATED_MAKEFILE}, you need to restart; exit 1
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !target(config.status)
|
||||
# avoid the targets behaving differently
|
||||
config.status: .NOTMAIN
|
||||
.if exists(${.OBJDIR}/config.status)
|
||||
config.status: config.recheck
|
||||
.else
|
||||
config.status: config.gen
|
||||
.endif
|
||||
|
||||
config.recheck: ${CONFIGURE_DEPS}
|
||||
config.recheck: .NOTMAIN ${CONFIGURE_DEPS} config.gen
|
||||
./config.status --recheck
|
||||
@touch $@
|
||||
|
||||
config.gen: ${CONFIGURE_DEPS}
|
||||
config.gen: .NOTMAIN ${CONFIGURE_DEPS}
|
||||
CC="${CC} ${CCMODE}" ${.CURDIR}/configure --no-create ${CONFIGURE_ARGS}
|
||||
@touch $@ config.recheck
|
||||
|
||||
CLEANFILES+= config.recheck config.gen config.status *.meta
|
||||
CLEANFILES+= config.recheck config.gen config.status *.meta \
|
||||
${AUTOCONF_GENERATED_MAKEFILE:U}
|
||||
.endif
|
||||
|
||||
# avoid things blowing up if these are not here...
|
||||
@ -67,14 +72,14 @@ ACLOCAL += aclocal.m4
|
||||
ACCONFIG += acconfig.h
|
||||
.endif
|
||||
|
||||
config.h.in: ${.CURDIR}/configure.in ${ACCONFIG}
|
||||
config.h.in: .NOTMAIN ${.CURDIR}/configure.in ${ACCONFIG}
|
||||
(cd ${.CURDIR} && ${AUTOHEADER})
|
||||
|
||||
configure: ${.CURDIR}/configure.in ${ACLOCAL}
|
||||
configure: .NOTMAIN ${.CURDIR}/configure.in ${ACLOCAL}
|
||||
(cd ${.CURDIR} && ${AUTOCONF})
|
||||
|
||||
AUTOCONF_INPUTS += configure
|
||||
autoconf-input: ${AUTOCONF_INPUTS}
|
||||
autoconf-input: .NOTMAIN ${AUTOCONF_INPUTS}
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: autodep.mk,v 1.38 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: autodep.mk,v 1.40 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, Simon J. Gerraty
|
||||
#
|
||||
@ -20,7 +20,7 @@
|
||||
# dependencies are normally updated as part of compilation.
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
DEPENDFILE?= .depend
|
||||
.for d in ${DEPENDFILE:N.depend}
|
||||
@ -67,6 +67,9 @@ __dependsrcs= ${__dependsrcsx:O:u}
|
||||
CFLAGS_MD?=-MD
|
||||
# -MF etc not available on all gcc versions.
|
||||
# we "fix" the .o later
|
||||
.if ${COMPILER_TYPE:Ugcc} == "gcc" && ${COMPILER_VERSION:U0} < 30000
|
||||
CFLAGS_MF=
|
||||
.endif
|
||||
CFLAGS_MF?=-MF ${.TARGET:T:R}.d -MT ${.TARGET:T:R}.o
|
||||
CFLAGS+= ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
RM?= rm
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: compiler.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: compiler.mk,v 1.10 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019, Simon J. Gerraty
|
||||
#
|
||||
@ -14,7 +14,7 @@
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.if ${MACHINE} == "common"
|
||||
COMPILER_TYPE = none
|
||||
@ -22,12 +22,12 @@ COMPILER_VERSION = 0
|
||||
.endif
|
||||
.if empty(COMPILER_TYPE) || empty(COMPILER_VERSION)
|
||||
# gcc does not always say gcc
|
||||
_v != ${CC} --version 2> /dev/null | \
|
||||
egrep -i 'clang|cc|[1-9]\.[0-9]|Free Software Foundation'
|
||||
_v != (${CC} --version) 2> /dev/null | \
|
||||
egrep -i 'clang|cc|[1-9]\.[0-9]|Free Software Foundation'; echo
|
||||
.if empty(COMPILER_TYPE)
|
||||
.if ${_v:Mclang} != ""
|
||||
COMPILER_TYPE = clang
|
||||
.elif ${_v:M[Gg][Cc][Cc]} != "" || ${_v:MFoundation*} != ""
|
||||
.elif ${_v:M[Gg][Cc][Cc]} != "" || ${_v:MFoundation*} != "" || ${CC:T:M*gcc*} != ""
|
||||
COMPILER_TYPE = gcc
|
||||
.endif
|
||||
.endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: dep.mk,v 1.17 2014/08/04 05:12:27 sjg Exp $
|
||||
# $Id: dep.mk,v 1.18 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
# handle Proc*C as well...
|
||||
.if defined(SRCS)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: dirdeps.mk,v 1.140 2021/06/20 23:42:38 sjg Exp $
|
||||
# $Id: dirdeps.mk,v 1.147 2021/12/14 02:09:53 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2021, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
@ -66,6 +66,10 @@
|
||||
# processing is recursive and results in .MAKE.LEVEL 0 learning the
|
||||
# dependencies of the tree wrt the initial directory (_DEP_RELDIR).
|
||||
#
|
||||
# NOTE: given the extent of processing that DIRDEPS undergoes it
|
||||
# is important that any variables in entries use :U to guard
|
||||
# against surprises when undefined.
|
||||
#
|
||||
# TARGET_SPEC_VARS
|
||||
# The default value is just MACHINE, and for most environments
|
||||
# this is sufficient. The _DIRDEP_USE target actually sets
|
||||
@ -399,7 +403,7 @@ DIRDEP_LOADAVG_REPORT = \
|
||||
_DIRDEP_USE: .USE .MAKE
|
||||
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
|
||||
test -s ${.TARGET:R}/$$m || continue; \
|
||||
echo "${TRACER}Checking ${.TARGET:S,${SRCTOP}/,,} for ${.TARGET:E} ..."; \
|
||||
echo "${TRACER}Checking ${.TARGET:S,^${SRCTOP}/,,} for ${.TARGET:E} ..."; \
|
||||
${DIRDEP_USE_PRELUDE} \
|
||||
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
|
||||
TARGET_SPEC=${.TARGET:E} \
|
||||
@ -562,7 +566,7 @@ ${DIRDEPS_CACHE}: .META .NOMETA_CMP
|
||||
${"${DEBUG_DIRDEPS:Nno}":?DEBUG_DIRDEPS='${DEBUG_DIRDEPS}':} \
|
||||
${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \
|
||||
${.MAKEFLAGS:tW:S,-d ,-d,g:tw:M-d*} \
|
||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g;s,_{,$${,g' >> ${.TARGET}.new && \
|
||||
3>&1 1>&2 | sed 's,${SRCTOP},_{SRCTOP},g;s,_{,$${,g' >> ${.TARGET}.new && \
|
||||
mv ${.TARGET}.new ${.TARGET}
|
||||
|
||||
.endif
|
||||
@ -638,6 +642,7 @@ _build_dirs += ${_machines:@m@${_CURDIR}.$m@}
|
||||
.endif
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: nDIRDEPS=${DIRDEPS:[#]}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}'
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}'
|
||||
.endif
|
||||
@ -656,11 +661,10 @@ DEP_DIRDEPS_FILTER = U
|
||||
# this is what we start with
|
||||
__depdirs := ${DIRDEPS:${NSkipDir}:${DEP_DIRDEPS_FILTER:ts:}:C,//+,/,g:O:u:@d@${SRCTOP}/$d@}
|
||||
|
||||
# some entries may be qualified with .<machine>
|
||||
# the :M*/*/*.* just tries to limit the dirs we check to likely ones.
|
||||
# the ${d:E:M*/*} ensures we don't consider junos/usr.sbin/mgd
|
||||
__qual_depdirs := ${__depdirs:M*/*/*.*:@d@${exists($d):?:${"${d:E:M*/*}":?:${exists(${d:R}):?$d:}}}@}
|
||||
__unqual_depdirs := ${__depdirs:${__qual_depdirs:Uno:${M_ListToSkip}}}
|
||||
# some entries may be qualified with .<machine> or .<target_spec>
|
||||
# we can tell the unqualified ones easily - because they exist
|
||||
__unqual_depdirs := ${__depdirs:@d@${exists($d):?$d:}@}
|
||||
__qual_depdirs := ${__depdirs:${__unqual_depdirs:Uno:${M_ListToSkip}}}
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# if it was called out - we likely need it.
|
||||
@ -671,9 +675,9 @@ __qual_depdirs += ${__hostdpadd}
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info DEP_DIRDEPS_FILTER=${DEP_DIRDEPS_FILTER:ts:}
|
||||
.info depdirs=${__depdirs}
|
||||
.info qualified=${__qual_depdirs}
|
||||
.info unqualified=${__unqual_depdirs}
|
||||
.info depdirs=${__depdirs:S,^${SRCTOP}/,,}
|
||||
.info qualified=${__qual_depdirs:S,^${SRCTOP}/,,}
|
||||
.info unqualified=${__unqual_depdirs:S,^${SRCTOP}/,,}
|
||||
.endif
|
||||
|
||||
# _build_dirs is what we will feed to _DIRDEP_USE
|
||||
@ -694,13 +698,14 @@ _build_all_dirs := ${_build_all_dirs:O:u}
|
||||
# Normally if doing make -V something,
|
||||
# we do not want to waste time chasing DIRDEPS
|
||||
# but if we want to count the number of Makefile.depend* read, we do.
|
||||
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == ""
|
||||
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS:U}} == ""
|
||||
.if !empty(_build_all_dirs)
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
x!= echo; { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; } >&3
|
||||
# guard against _new_dirdeps being too big for a single command line
|
||||
_new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@}
|
||||
.export _build_xtra_dirs _new_dirdeps
|
||||
_new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@:S,^${SRCTOP}/,,}
|
||||
_cache_xtra_deps := ${_build_xtra_dirs:S,^${SRCTOP}/,,}
|
||||
.export _cache_xtra_deps _new_dirdeps
|
||||
.if !empty(DEP_EXPORT_VARS)
|
||||
# Discouraged, but there are always exceptions.
|
||||
# Handle it here rather than explain how.
|
||||
@ -713,7 +718,7 @@ dirdeps: ${_build_all_dirs}
|
||||
${_build_all_dirs}: _DIRDEP_USE
|
||||
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs}
|
||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs:S,^${SRCTOP}/,,}
|
||||
.endif
|
||||
|
||||
.if !empty(DEP_EXPORT_VARS)
|
||||
@ -724,37 +729,37 @@ DEP_EXPORT_VARS=
|
||||
# this builds the dependency graph
|
||||
.for m in ${_machines}
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" && !empty(_build_dirs)
|
||||
x!= echo; { echo; echo 'DIRDEPS.${_this_dir}.$m = \'; } >&3
|
||||
_cache_deps =
|
||||
x!= echo; { echo; echo 'DIRDEPS.${_this_dir}.$m = \'; } >&3
|
||||
.endif
|
||||
# it would be nice to do :N${.TARGET}
|
||||
.if !empty(__qual_depdirs)
|
||||
.for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m}
|
||||
.if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
_cache_deps += ${_build_dirs:M*.$q}
|
||||
_cache_deps += ${_build_dirs:M*.$q:S,^${SRCTOP}/,,}
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
.if ${_debug_reldir}
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m:S,^${SRCTOP}/,,}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
.if !empty(_build_dirs)
|
||||
_cache_deps += ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
_cache_deps += ${_build_dirs:M*.$m:N${_this_dir}.$m:S,^${SRCTOP}/,,}
|
||||
.if !empty(_cache_deps)
|
||||
.export _cache_deps
|
||||
x!= echo; for x in $$_cache_deps; do echo " $$x \\"; done >&3
|
||||
x!= echo; for x in $$_cache_deps; do echo " _{SRCTOP}/$$x \\"; done >&3
|
||||
.endif
|
||||
# anything in _build_xtra_dirs is hooked to dirdeps: only
|
||||
# anything in _{build,env}_xtra_dirs is hooked to dirdeps: only
|
||||
x!= echo; { echo; echo '${_this_dir}.$m: $${DIRDEPS.${_this_dir}.$m}'; \
|
||||
echo; echo 'dirdeps: ${_this_dir}.$m \'; \
|
||||
for x in $$_build_xtra_dirs; do echo " $$x \\"; done; \
|
||||
echo; for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; } >&3
|
||||
for x in $$_cache_xtra_deps; do echo " _{SRCTOP}/$$x \\"; done; \
|
||||
echo; for x in $$_new_dirdeps; do echo "_{SRCTOP}/$$x: _DIRDEP_USE"; done; } >&3
|
||||
.endif
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
@ -769,7 +774,7 @@ ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
# once only
|
||||
_dirdeps_checked.$d:
|
||||
.if ${_debug_search}
|
||||
.info checking $d
|
||||
.info checking ${d:S,^${SRCTOP}/,,}
|
||||
.endif
|
||||
# Note: _build_all_dirs is fully qualifed so d:R is always the directory
|
||||
.if exists(${d:R})
|
||||
@ -798,7 +803,7 @@ _qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}}
|
||||
.endif
|
||||
# set this "just in case"
|
||||
# we can skip :tA since we computed the path above
|
||||
DEP_RELDIR := ${_m:H:S,${SRCTOP}/,,}
|
||||
DEP_RELDIR := ${_m:H:S,^${SRCTOP}/,,}
|
||||
# and reset this
|
||||
DIRDEPS =
|
||||
.if ${_debug_reldir} && ${_qm} != ${_m}
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: doc.mk,v 1.7 2019/06/09 16:22:08 sjg Exp $
|
||||
# $Id: doc.mk,v 1.8 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: dpadd.mk,v 1.29 2021/04/20 02:30:44 sjg Exp $
|
||||
# $Id: dpadd.mk,v 1.30 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, Simon J. Gerraty
|
||||
#
|
||||
@ -77,7 +77,7 @@
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
# sometimes we play games with .CURDIR etc
|
||||
# _* hold the original values of .*
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: final.mk,v 1.9 2018/01/24 22:57:11 sjg Exp $
|
||||
# $Id: final.mk,v 1.10 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
# provide a hook for folk who want to do scary stuff
|
||||
.-include <${.CURDIR:H}/Makefile-final.inc>
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: init.mk,v 1.25 2020/11/27 17:59:46 sjg Exp $
|
||||
# $Id: init.mk,v 1.26 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2002, Simon J. Gerraty
|
||||
#
|
||||
@ -14,7 +14,7 @@
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.if ${MAKE_VERSION:U0} > 20100408
|
||||
_this_mk_dir := ${.PARSEDIR:tA}
|
||||
|
@ -55,7 +55,7 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: install-mk,v 1.196 2021/06/19 15:30:41 sjg Exp $
|
||||
# $Id: install-mk,v 1.206 2021/12/11 18:57:41 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1994 Simon J. Gerraty
|
||||
#
|
||||
@ -70,7 +70,7 @@
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
MK_VERSION=20210616
|
||||
MK_VERSION=20211212
|
||||
OWNER=
|
||||
GROUP=
|
||||
MODE=444
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: java.mk,v 1.15 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: java.mk,v 1.16 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
# @(#) Copyright (c) 1998-2001, Simon J. Gerraty
|
||||
#
|
||||
@ -16,7 +16,7 @@
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: ldorder.mk,v 1.25 2018/04/24 23:50:26 sjg Exp $
|
||||
# $Id: ldorder.mk,v 1.26 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2015, Simon J. Gerraty
|
||||
#
|
||||
@ -130,7 +130,7 @@ ${_ldorder}: ${_ldorders}
|
||||
# it can also add to CFLAGS etc.
|
||||
.for __inc in ${LDORDER_LIBS:S,$,.${LDORDER_INC},}
|
||||
.if !target(__${__inc}__)
|
||||
__${__inc}__:
|
||||
__${__inc}__: .NOTMAIN
|
||||
# make sure this is reset
|
||||
LDORDER_LIBS =
|
||||
_ldorders =
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: lib.mk,v 1.71 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: lib.mk,v 1.73 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
@ -170,7 +170,7 @@ LD_solib= lib${LIB}_pic.a
|
||||
.elif ${TARGET_OSNAME} == "Linux"
|
||||
SHLIB_LD = ${CC}
|
||||
# this is ambiguous of course
|
||||
LD_shared=-shared -Wl,"-soname lib${LIB}.so.${SHLIB_MAJOR}"
|
||||
LD_shared=-shared -Wl,-soname,lib${LIB}.so.${SHLIB_MAJOR}
|
||||
LD_solib= -Wl,--whole-archive lib${LIB}_pic.a -Wl,--no-whole-archive
|
||||
.if ${COMPILER_TYPE} == "gcc"
|
||||
# Linux uses GNU ld, which is a multi-pass linker
|
||||
|
@ -1,9 +1,12 @@
|
||||
# $Id: man.mk,v 1.20 2012/12/13 01:51:01 sjg Exp $
|
||||
# $Id: man.mk,v 1.25 2021/10/31 03:03:14 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
OPTIONS_DEFAULT_NO += CMT2DOC
|
||||
|
||||
.include <init.mk>
|
||||
.include <options.mk>
|
||||
|
||||
# unlike bsd.man.mk we handle 3 approaches
|
||||
# 1. install unformated nroff (default)
|
||||
@ -21,45 +24,38 @@ NROFF?= nroff
|
||||
MANDIR?= /usr/share/man
|
||||
MANDOC?= man
|
||||
|
||||
.SUFFIXES: .1 .2 .3 .4 .5 .6 .7 .8 .9 .cat1 .cat2 .cat3 .cat4 .cat5 .cat6 \
|
||||
.cat7 .cat8 .cat9
|
||||
MAN_SUFFIXES?= .1 .2 .3 .4 .5 .6 .7 .8 .9
|
||||
.SUFFIXES: ${MAN_SUFFIXES}
|
||||
.if ${MANTARGET} == "cat"
|
||||
.SUFFIXES: ${MAN_SUFFIXES:S,.,.cat,}
|
||||
.endif
|
||||
|
||||
.9.cat9 .8.cat8 .7.cat7 .6.cat6 .5.cat5 .4.cat4 .3.cat3 .2.cat2 .1.cat1:
|
||||
${MAN_SUFFIXES:@s@$s${s:S,.,.cat,}@}:
|
||||
@echo "${NROFF} -${MANDOC} ${.IMPSRC} > ${.TARGET:T}"
|
||||
@${NROFF} -${MANDOC} ${.IMPSRC} > ${.TARGET:T} || ( rm -f ${.TARGET:T} ; false )
|
||||
@${NROFF} -${MANDOC} ${.IMPSRC} > ${.TARGET:T}.new && \
|
||||
mv ${.TARGET:T}.new ${.TARGET:T}
|
||||
|
||||
.if defined(MAN) && !empty(MAN)
|
||||
|
||||
# we use cmt2doc.pl to extract manpages from source
|
||||
# this is triggered by the setting of EXTRACT_MAN or MAN being set but
|
||||
# not existsing.
|
||||
|
||||
.if !exists(${MAN:[1]}) && !target(${MAN:[1]})
|
||||
.if defined(EXTRACT_MAN) && ${EXTRACT_MAN} == "no"
|
||||
MAN=
|
||||
.else
|
||||
.if exists(/usr/local/share/bin/cmt2doc.pl)
|
||||
CMT2DOC?= cmt2doc.pl
|
||||
.if ${MK_CMT2DOC} == "yes"
|
||||
# use cmt2doc.py to extract manpages from source
|
||||
CMT2DOC?= cmt2doc.py
|
||||
CMT2DOC_OPTS?= ${CMT2DOC_ORGOPT} -pmS${.TARGET:E}
|
||||
.endif
|
||||
.ifdef CMT2DOC
|
||||
.c.8 .c.5 .c.3 .c.4 .c.1 \
|
||||
.cc.8 .cc.5 .cc.3 .cc.4 .cc.1 \
|
||||
.h.8 .h.5 .h.3 .h.4 .h.1 \
|
||||
.sh.8 .sh.5 .sh.3 .sh.4 .sh.1 \
|
||||
.pl.8 .pl.5 .pl.3 .pl.4 .pl.1:
|
||||
CMT2DOC_SUFFIXES+= .c .h .sh .pl .py
|
||||
|
||||
.SUFFIXES: ${CMT2DOC_SUFFIXES}
|
||||
|
||||
${CMT2DOC_SUFFIXES:@s@${MAN_SUFFIXES:@m@$s$m@}@}:
|
||||
@echo "${CMT2DOC} ${.IMPSRC} > ${.TARGET:T}"
|
||||
@${CMT2DOC} ${CMT2DOC_OPTS} ${.IMPSRC} > ${.TARGET:T} || ( rm -f ${.TARGET:T} ; false )
|
||||
.else
|
||||
MAN=
|
||||
.endif
|
||||
.endif
|
||||
@${CMT2DOC} ${CMT2DOC_OPTS} ${.IMPSRC} > ${.TARGET:T}.new && \
|
||||
mv ${.TARGET:T}.new ${.TARGET:T}
|
||||
|
||||
.endif
|
||||
|
||||
_mandir=${DESTDIR}${MANDIR}/${MANTARGET}`echo $$page | sed -e 's/.*\.cat/./' -e 's/.*\.//'`
|
||||
.if ${MANTARGET} == "cat"
|
||||
_mfromdir?=.
|
||||
MANALL= ${MAN:S/.1$/.cat1/g:S/.2$/.cat2/g:S/.3$/.cat3/g:S/.4$/.cat4/g:S/.5$/.cat5/g:S/.6$/.cat6/g:S/.7$/.cat7/g:S/.8$/.cat8/g:S/.9$/.cat9/g}
|
||||
MANALL= ${MAN:${MAN_SUFFIXES:S,.,,:@m@S/.$m/.cat$m/@:ts:}}
|
||||
.if ${MCATEXT} == ""
|
||||
_minstpage=`echo $$page | sed 's/\.cat/./'`
|
||||
.else
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.autodep.mk,v 1.54 2021/03/06 17:03:18 sjg Exp $
|
||||
# $Id: meta.autodep.mk,v 1.55 2021/12/13 08:12:01 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
@ -23,8 +23,12 @@ __${_this}__: .NOTMAIN
|
||||
PICO?= .pico
|
||||
|
||||
.if defined(SRCS)
|
||||
.if ${MAKE_VERSION:U0} >= 20211212
|
||||
OBJ_EXTENSIONS += ${.SUFFIXES:M*o}
|
||||
.else
|
||||
# it would be nice to be able to query .SUFFIXES
|
||||
OBJ_EXTENSIONS+= .o .po .lo ${PICO}
|
||||
OBJ_EXTENSIONS += .o .po .lo ${PICO}
|
||||
.endif
|
||||
|
||||
# explicit dependencies help short-circuit .SUFFIX searches
|
||||
SRCS_DEP_FILTER+= N*.[hly]
|
||||
@ -163,7 +167,11 @@ _depend = .depend
|
||||
# it would be nice to be able to get .SUFFIXES as ${.SUFFIXES}
|
||||
# we actually only care about the .SUFFIXES of files that might be
|
||||
# generated by tools like yacc.
|
||||
.if ${MAKE_VERSION:U0} >= 20211212
|
||||
DEPEND_SUFFIXES += ${.SUFFIXES:N.sh:N*[0-9aFfglopmnrSsty]}
|
||||
.else
|
||||
DEPEND_SUFFIXES += .c .h .cpp .hpp .cxx .hxx .cc .hh
|
||||
.endif
|
||||
.depend: .NOMETA $${.MAKE.META.CREATED} ${_this}
|
||||
@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} | \
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.stage.mk,v 1.61 2021/01/31 04:43:12 sjg Exp $
|
||||
# $Id: meta.stage.mk,v 1.64 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2011-2017, Simon J. Gerraty
|
||||
#
|
||||
@ -66,7 +66,7 @@ GENDIRDEPS_FILTER += Nnot-empty-is-important \
|
||||
LN_CP_SCRIPT = LnCp() { \
|
||||
rm -f $$2 2> /dev/null; \
|
||||
{ [ -z "$$mode" ] && ${LN:Uln} $$1 $$2 2> /dev/null; } || \
|
||||
cp -p $$1 $$2; }
|
||||
cp -p $$1 $$2 2> /dev/null || cp $$1 $$2; }
|
||||
|
||||
# a staging conflict should cause an error
|
||||
# a warning is handy when bootstapping different options.
|
||||
@ -264,7 +264,8 @@ CLEANFILES += ${STAGE_AS_SETS:@s@stage*$s@}
|
||||
# sometimes things need to be renamed as they are staged
|
||||
# each ${file} will be staged as ${STAGE_AS_${file:T}}
|
||||
# one could achieve the same with SYMLINKS
|
||||
# stage_as_and_symlink makes the original name a symlink to the new name
|
||||
# stage_as_and_symlink makes the original name (or ${STAGE_LINK_AS_${name}})
|
||||
# a symlink to the new name
|
||||
# it is the same as using stage_as and stage_symlinks but ensures
|
||||
# both operations happen together
|
||||
.for s in ${STAGE_AS_SETS:O:u}
|
||||
@ -294,7 +295,7 @@ STAGE_AS_AND_SYMLINK.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
|
||||
stage_as_and_symlink: stage_as_and_symlink.$s
|
||||
stage_as_and_symlink.$s: .dirdep
|
||||
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:O:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:O:@f@${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}} $f@}
|
||||
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:O:@f@${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}} ${STAGE_LINK_AS_${f}:U$f}@}
|
||||
@touch $@
|
||||
.endif
|
||||
.endif
|
||||
@ -306,7 +307,7 @@ CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes
|
||||
|
||||
# this lot also only makes sense the first time...
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
# stage_*links usually needs to follow any others.
|
||||
# for non-jobs mode the order here matters
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: meta.sys.mk,v 1.38 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: meta.sys.mk,v 1.42 2021/12/13 05:50:55 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
# @(#) Copyright (c) 2010-2021, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
@ -30,21 +30,31 @@ SYS_MK_DIR := ${_PARSEDIR}
|
||||
.endif
|
||||
|
||||
META_MODE += meta verbose
|
||||
.if ${MAKE_VERSION:U0} > 20130323 && empty(.MAKE.PATH_FILEMON)
|
||||
# we do not support filemon
|
||||
META_MODE += nofilemon
|
||||
MKDEP_MK ?= auto.dep.mk
|
||||
.endif
|
||||
|
||||
.MAKE.MODE ?= ${META_MODE}
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
_filemon := ${.MAKE.PATH_FILEMON:U/dev/filemon}
|
||||
|
||||
.if empty(UPDATE_DEPENDFILE)
|
||||
_make_mode := ${.MAKE.MODE} ${META_MODE}
|
||||
.if ${_make_mode:M*read*} != "" || ${_make_mode:M*nofilemon*} != ""
|
||||
# tell everyone we are not updating Makefile.depend*
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.export UPDATE_DEPENDFILE
|
||||
.endif
|
||||
.if ${UPDATE_DEPENDFILE:Uyes:tl} == "no" && !exists(/dev/filemon)
|
||||
.if ${_filemon:T:Mfilemon} == "filemon"
|
||||
.if ${UPDATE_DEPENDFILE:Uyes:tl} == "no" && !exists(${_filemon})
|
||||
# we should not get upset
|
||||
META_MODE += nofilemon
|
||||
.export META_MODE
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if !defined(NO_SILENT)
|
||||
.if ${MAKE_VERSION} > 20110818
|
||||
@ -106,7 +116,7 @@ _metaError: .NOMETA .NOTMAIN
|
||||
|
||||
# Are we, after all, in meta mode?
|
||||
.if ${.MAKE.MODE:Uno:Mmeta*} != ""
|
||||
MKDEP_MK = meta.autodep.mk
|
||||
MKDEP_MK ?= meta.autodep.mk
|
||||
|
||||
.if ${.MAKE.MAKEFILES:M*sys.dependfile.mk} == ""
|
||||
# this does all the smarts of setting .MAKE.DEPENDFILE
|
||||
@ -140,12 +150,13 @@ META_NOECHO= :
|
||||
.warning Setting UPDATE_DEPENDFILE=NO due to -k
|
||||
UPDATE_DEPENDFILE= NO
|
||||
.export UPDATE_DEPENDFILE
|
||||
.elif !exists(/dev/filemon)
|
||||
.error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded.
|
||||
.elif ${_filemon:T} == "filemon" && !exists(${_filemon})
|
||||
.error ${.newline}ERROR: The filemon module (${_filemon}) is not loaded.
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
.if ${MK_DIRDEPS_BUILD:Uyes} == "yes"
|
||||
# make sure dirdeps target exists and do it first
|
||||
all: dirdeps .WAIT
|
||||
dirdeps:
|
||||
@ -156,6 +167,7 @@ dirdeps:
|
||||
# by default dirdeps is all we want at level0
|
||||
.MAIN: dirdeps
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endif
|
||||
.else
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
"""
|
||||
RCSid:
|
||||
$Id: meta2deps.py,v 1.38 2021/06/17 05:20:08 sjg Exp $
|
||||
$Id: meta2deps.py,v 1.40 2021/12/13 19:32:46 sjg Exp $
|
||||
|
||||
Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
Copyright (c) 2011-2017, Juniper Networks, Inc.
|
||||
@ -165,6 +165,19 @@ def add_trims(x):
|
||||
x + '/',
|
||||
x]
|
||||
|
||||
def target_spec_exts(target_spec):
|
||||
"""return a list of dirdep extensions that could match target_spec"""
|
||||
|
||||
if target_spec.find(',') < 0:
|
||||
return ['.'+target_spec]
|
||||
w = target_spec.split(',')
|
||||
n = len(w)
|
||||
e = []
|
||||
while n > 0:
|
||||
e.append('.'+','.join(w[0:n]))
|
||||
n -= 1
|
||||
return e
|
||||
|
||||
class MetaFile:
|
||||
"""class to parse meta files generated by bmake."""
|
||||
|
||||
@ -226,7 +239,8 @@ def __init__(self, name, conf={}):
|
||||
|
||||
self.machine = conf.get('MACHINE', '')
|
||||
self.machine_arch = conf.get('MACHINE_ARCH', '')
|
||||
self.target_spec = conf.get('TARGET_SPEC', '')
|
||||
self.target_spec = conf.get('TARGET_SPEC', self.machine)
|
||||
self.exts = target_spec_exts(self.target_spec)
|
||||
self.curdir = conf.get('CURDIR')
|
||||
self.reldir = conf.get('RELDIR')
|
||||
self.dpdeps = conf.get('DPDEPS')
|
||||
@ -250,7 +264,7 @@ def __init__(self, name, conf={}):
|
||||
trim_list = add_trims(self.machine)
|
||||
if self.machine == 'host':
|
||||
trim_list += add_trims(self.host_target)
|
||||
if self.target_spec:
|
||||
if self.target_spec != self.machine:
|
||||
trim_list += add_trims(self.target_spec)
|
||||
|
||||
for objroot in conf.get('OBJROOTS', []):
|
||||
@ -280,6 +294,7 @@ def __init__(self, name, conf={}):
|
||||
print("srctops=", self.srctops, file=self.debug_out)
|
||||
print("objroots=", self.objroots, file=self.debug_out)
|
||||
print("excludes=", self.excludes, file=self.debug_out)
|
||||
print("ext_list=", self.exts, file=self.debug_out)
|
||||
|
||||
self.dirdep_re = re.compile(r'([^/]+)/(.+)')
|
||||
|
||||
@ -355,10 +370,10 @@ def find_obj(self, objroot, dir, path, input):
|
||||
ddep = open(ddepf, 'r').readline().strip('# \n')
|
||||
if self.debug > 1:
|
||||
print("found %s: %s\n" % (ddepf, ddep), file=self.debug_out)
|
||||
if ddep.endswith(self.machine):
|
||||
ddep = ddep[0:-(1+len(self.machine))]
|
||||
elif self.target_spec and ddep.endswith(self.target_spec):
|
||||
ddep = ddep[0:-(1+len(self.target_spec))]
|
||||
for e in self.exts:
|
||||
if ddep.endswith(e):
|
||||
ddep = ddep[0:-len(e)]
|
||||
break
|
||||
|
||||
if not ddep:
|
||||
# no .dirdeps, so remember that we've seen the raw input
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: obj.mk,v 1.16 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: obj.mk,v 1.17 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, Simon J. Gerraty
|
||||
#
|
||||
@ -14,7 +14,7 @@
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE:S,bsd.,,}__)
|
||||
__${.PARSEFILE:S,bsd.,,}__:
|
||||
__${.PARSEFILE:S,bsd.,,}__: .NOTMAIN
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options.mk,v 1.13 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: options.mk,v 1.19 2021/10/03 16:29:51 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2012, Simon J. Gerraty
|
||||
#
|
||||
@ -26,8 +26,8 @@
|
||||
# User sets WITH_* and WITHOUT_* to indicate what they want.
|
||||
# We set ${OPTION_PREFIX:UMK_}* which is then all we need care about.
|
||||
OPTIONS_DEFAULT_VALUES += \
|
||||
${OPTIONS_DEFAULT_NO:O:u:S,$,/no,} \
|
||||
${OPTIONS_DEFAULT_YES:O:u:S,$,/yes,}
|
||||
${OPTIONS_DEFAULT_NO:U:O:u:S,$,/no,} \
|
||||
${OPTIONS_DEFAULT_YES:U:O:u:S,$,/yes,}
|
||||
|
||||
OPTION_PREFIX ?= MK_
|
||||
|
||||
@ -36,6 +36,10 @@ OPTION_PREFIX ?= MK_
|
||||
# DOMINANT_* is set to "yes"
|
||||
# Otherwise WITH_* and WITHOUT_* override the default.
|
||||
.for o in ${OPTIONS_DEFAULT_VALUES:M*/*}
|
||||
.if defined(WITH_${o:H}) && ${WITH_${o:H}} == "no"
|
||||
# a common miss-use - point out correct usage
|
||||
.warning use WITHOUT_${o:H}=1 not WITH_${o:H}=no
|
||||
.endif
|
||||
.if defined(NO_${o:H}) || defined(NO${o:H})
|
||||
# we cannot do it
|
||||
${OPTION_PREFIX}${o:H} ?= no
|
||||
@ -77,6 +81,32 @@ ${OPTION_PREFIX}${o:H} ?= no
|
||||
${OPTION_PREFIX}${o:H} ?= ${${OPTION_PREFIX}${o:T}}
|
||||
.endif
|
||||
.endfor
|
||||
.undef OPTIONS_DEFAULT_VALUES
|
||||
|
||||
# allow displaying/describing set options
|
||||
.set_options := ${.set_options} \
|
||||
${OPTIONS_DEFAULT_VALUES:H:N.} \
|
||||
${OPTIONS_DEFAULT_DEPENDENT:U:H:N.} \
|
||||
|
||||
# this can be used in .info as well as target below
|
||||
OPTIONS_SHOW ?= ${.set_options:O:u:@o@${OPTION_PREFIX}$o=${${OPTION_PREFIX}$o}@}
|
||||
# prefix for variables describing options
|
||||
OPTION_DESCRIPTION_PREFIX ?= DESCRIPTION_
|
||||
OPTION_DESCRIPTION_SEPARATOR ?= ==
|
||||
|
||||
OPTIONS_DESCRIBE ?= ${.set_options:O:u:@o@${OPTION_PREFIX}$o=${${OPTION_PREFIX}$o}${${OPTION_DESCRIPTION_PREFIX}$o:S,^, ${OPTION_DESCRIPTION_SEPARATOR} ,1}${.newline}@}
|
||||
|
||||
.if !commands(show-options)
|
||||
show-options: .NOTMAIN .PHONY
|
||||
@echo; echo "${OPTIONS_SHOW:ts\n}"; echo
|
||||
.endif
|
||||
|
||||
.if !commands(describe-options)
|
||||
describe-options: .NOTMAIN .PHONY
|
||||
@echo; echo "${OPTIONS_DESCRIBE}"; echo
|
||||
.endif
|
||||
|
||||
# we expect to be included more than once
|
||||
.undef OPTIONS_DEFAULT_DEPENDENT
|
||||
.undef OPTIONS_DEFAULT_NO
|
||||
.undef OPTIONS_DEFAULT_VALUES
|
||||
.undef OPTIONS_DEFAULT_YES
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: own.mk,v 1.42 2020/11/27 18:00:08 sjg Exp $
|
||||
# $Id: own.mk,v 1.44 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.if !target(__init.mk__)
|
||||
.include "init.mk"
|
||||
@ -257,11 +257,13 @@ MK_NLS= no
|
||||
.if ${MK_META_MODE:Uno} == "yes"
|
||||
# should all be set by sys.mk if not default
|
||||
TARGET_SPEC_VARS ?= MACHINE
|
||||
.if ${MAKE_VERSION} >= 20120325
|
||||
.if ${TARGET_SPEC_VARS:[#]} > 1
|
||||
TARGET_SPEC_VARS_REV := ${TARGET_SPEC_VARS:[-1..1]}
|
||||
.else
|
||||
TARGET_SPEC_VARS_REV = ${TARGET_SPEC_VARS}
|
||||
.endif
|
||||
.endif
|
||||
.if ${MK_STAGING} == "yes"
|
||||
STAGE_ROOT?= ${OBJROOT}/stage
|
||||
STAGE_OBJTOP?= ${STAGE_ROOT}/${TARGET_SPEC_VARS_REV:ts/}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: prlist.mk,v 1.4 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: prlist.mk,v 1.5 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2006, Simon J. Gerraty
|
||||
#
|
||||
@ -14,7 +14,7 @@
|
||||
#
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
# this needs to be included after all the lists it will process
|
||||
# are defined - which is why it is a separate file.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $Id: prog.mk,v 1.36 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: prog.mk,v 1.37 2021/12/08 05:56:50 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
__${.PARSEFILE}__: .NOTMAIN
|
||||
|
||||
.include <init.mk>
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#
|
||||
|
||||
# RCSid:
|
||||
# $Id: stage-install.sh,v 1.9 2020/08/28 01:04:13 sjg Exp $
|
||||
# $Id: stage-install.sh,v 1.10 2021/11/17 07:06:31 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2013-2020, Simon J. Gerraty
|
||||
#
|
||||
@ -117,8 +117,12 @@ StageDirdep() {
|
||||
t=$1
|
||||
if [ -s $t.dirdep ]; then
|
||||
cmp -s $_DIRDEP $t.dirdep && return
|
||||
echo "ERROR: $t installed by `cat $t.dirdep` not `cat $_DIRDEP`" >&2
|
||||
exit 1
|
||||
case "${STAGE_CONFLICT:-error}" in
|
||||
[Ee]*) STAGE_CONFLICT=ERROR action=exit;;
|
||||
*) STAGE_CONFLICT=WARNING action=: ;;
|
||||
esac
|
||||
echo "$STAGE_CONFLICT: $t installed by `cat $t.dirdep` not `cat $_DIRDEP`" >&2
|
||||
$action 1
|
||||
fi
|
||||
LnCp $_DIRDEP $t.dirdep || exit 1
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: sys.mk,v 1.52 2020/12/22 20:44:24 sjg Exp $
|
||||
# $Id: sys.mk,v 1.53 2021/12/13 05:50:13 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
|
||||
#
|
||||
@ -81,11 +81,10 @@ OPTIONS_DEFAULT_DEPENDENT += \
|
||||
|
||||
.-include <options.mk>
|
||||
|
||||
.if ${MK_DIRDEPS_BUILD:Uno} == "yes"
|
||||
MK_META_MODE = yes
|
||||
# :Uno incase options.mk not installed
|
||||
.if ${MK_META_MODE:Uno} == "yes"
|
||||
.-include <meta.sys.mk>
|
||||
.elif ${MK_META_MODE:Uno} == "yes"
|
||||
.MAKE.MODE = meta verbose ${META_MODE}
|
||||
.MAKE.MODE ?= meta verbose {META_MODE}
|
||||
.endif
|
||||
# make sure we have a harmless value
|
||||
.MAKE.MODE ?= normal
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: sys.vars.mk,v 1.6 2020/10/28 20:50:04 sjg Exp $
|
||||
# $Id: sys.vars.mk,v 1.7 2021/12/08 05:56:50 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
|
||||
#
|
||||
@ -19,7 +19,7 @@
|
||||
#
|
||||
# _this ?= ${.PARSEFILE}
|
||||
# .if !target(__${_this}__)
|
||||
# __${_this}__:
|
||||
# __${_this}__: .NOTMAIN
|
||||
#
|
||||
.if ${MAKE_VERSION:U0} > 20100408
|
||||
_this = ${.PARSEDIR:tA}/${.PARSEFILE}
|
||||
|
13
contrib/bmake/mk/sys/SCO_SV.mk
Normal file
13
contrib/bmake/mk/sys/SCO_SV.mk
Normal file
@ -0,0 +1,13 @@
|
||||
# $Id: SCO_SV.mk,v 1.1 2021/10/13 16:45:52 sjg Exp $
|
||||
|
||||
OS = SCO_SV
|
||||
OS_DEF_FLAG := -D${OS}
|
||||
|
||||
CC ?= gcc
|
||||
CXX ?= g++
|
||||
DEV_TOOLS_PREFIX ?= /usr/xdev
|
||||
FC ?= gfortran
|
||||
INSTALL ?= /usr/gnu/bin/install
|
||||
LD ?= gcc
|
||||
|
||||
.include "UnixWare.mk"
|
@ -1,16 +1,18 @@
|
||||
# $Id: UnixWare.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
# $Id: UnixWare.mk,v 1.8 2021/10/13 16:45:52 sjg Exp $
|
||||
# based on "Id: SunOS.5.sys.mk,v 1.6 2003/09/30 16:42:23 sjg Exp "
|
||||
# $NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
|
||||
# @(#)sys.mk 5.11 (Berkeley) 3/13/91
|
||||
|
||||
OS ?= UnixWare
|
||||
OS_DEF_FLAG ?= -DUNIXWARE
|
||||
unix ?= We run ${OS}.
|
||||
ROOT_GROUP ?= root
|
||||
DEV_TOOLS_PREFIX ?= /usr/local
|
||||
|
||||
# can't fine one anywhere, so just stop the dependency
|
||||
# can't find one anywhere, so just stop the dependency
|
||||
LIBCRT0 ?= /dev/null
|
||||
|
||||
PATH ?=/usr/sbin:/usr/bin:/usr/ccs/bin:/usr/ccs/lib:/usr/ucb:/usr/local/bin
|
||||
PATH ?= /usr/sbin:/usr/bin:/usr/ccs/bin:/usr/ccs/lib:/usr/ucb:${DEV_TOOLS_PREFIX}/bin
|
||||
|
||||
.SUFFIXES: .out .a .ln .o .c ${CXX_SUFFIXES} .F .f .r .y .l .s .S .cl .p .h .sh .m4
|
||||
|
||||
@ -32,8 +34,8 @@ COMPILE.S ?= ${CC} ${AFLAGS} ${CPPFLAGS} -c
|
||||
LINK.S ?= ${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
# at least gcc 2.95 on UnixWare has no internal macro to identify the system
|
||||
.if exists(/usr/local/bin/gcc)
|
||||
CC ?= gcc -pipe -DUNIXWARE
|
||||
.if exists(${DEV_TOOLS_PREFIX}/bin/gcc)
|
||||
CC ?= gcc -pipe ${OS_DEF_FLAG}
|
||||
DBG ?= -O -g
|
||||
STATIC ?= -static
|
||||
.else
|
||||
@ -45,8 +47,8 @@ CFLAGS ?= ${DBG}
|
||||
COMPILE.c ?= ${CC} ${CFLAGS} ${CPPFLAGS} -c
|
||||
LINK.c ?= ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
.if exists(/usr/local/bin/g++)
|
||||
CXX ?= g++ -DUNIXWARE
|
||||
.if exists(${DEV_TOOLS_PREFIX}/bin/g++)
|
||||
CXX ?= g++ ${OS_DEF_FLAG}
|
||||
.else
|
||||
CXX ?= c++ # XXX: don't know about UDK compilers
|
||||
.endif
|
||||
@ -54,13 +56,17 @@ CXXFLAGS ?= ${CFLAGS}
|
||||
COMPILE.cc ?= ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c
|
||||
LINK.cc ?= ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS}
|
||||
|
||||
.if exists(${DEV_TOOLS_PREFIX}/bin/cpp)
|
||||
CPP ?= cpp
|
||||
.else
|
||||
CPP ?= /usr/ccs/lib/cpp
|
||||
.endif
|
||||
.if defined(DESTDIR)
|
||||
CPPFLAGS+= -nostdinc -idirafter ${DESTDIR}/usr/include
|
||||
.endif
|
||||
|
||||
MK_DEP ?= mkdeps.sh -N
|
||||
.if exists(/usr/local/bin/g77)
|
||||
.if exists(${DEV_TOOLS_PREFIX}/bin/g77)
|
||||
FC ?= g77
|
||||
.else
|
||||
FC ?= f77 # XXX: don't know about UDK compilers
|
||||
@ -125,7 +131,7 @@ SIZE ?= size
|
||||
|
||||
TSORT ?= tsort
|
||||
|
||||
.if exists(/usr/local/bin/bison)
|
||||
.if exists(${DEV_TOOLS_PREFIX}/bin/bison)
|
||||
YACC ?= bison -y
|
||||
.else
|
||||
YACC ?= yacc
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nonints.h,v 1.213 2021/04/11 13:35:56 rillig Exp $ */
|
||||
/* $NetBSD: nonints.h,v 1.217 2021/12/12 20:45:48 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -165,9 +165,9 @@ bool Parse_IsVar(const char *, VarAssign *out_var);
|
||||
void Parse_Var(VarAssign *, GNode *);
|
||||
void Parse_AddIncludeDir(const char *);
|
||||
void Parse_File(const char *, int);
|
||||
void Parse_SetInput(const char *, int, int, ReadMoreProc, void *);
|
||||
void Parse_PushInput(const char *, int, int, ReadMoreProc, void *);
|
||||
void Parse_MainName(GNodeList *);
|
||||
int Parse_GetFatals(void);
|
||||
int Parse_NumErrors(void);
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
@ -192,6 +192,7 @@ void Suff_FindDeps(GNode *);
|
||||
SearchPath *Suff_FindPath(GNode *);
|
||||
void Suff_SetNull(const char *);
|
||||
void Suff_PrintAll(void);
|
||||
const char *Suff_NamesStr(void);
|
||||
|
||||
/* targ.c */
|
||||
void Targ_Init(void);
|
||||
@ -211,7 +212,7 @@ void Targ_PrintCmds(GNode *);
|
||||
void Targ_PrintNode(GNode *, int);
|
||||
void Targ_PrintNodes(GNodeList *, int);
|
||||
const char *Targ_FmtTime(time_t);
|
||||
void Targ_PrintType(int);
|
||||
void Targ_PrintType(GNodeType);
|
||||
void Targ_PrintGraph(int);
|
||||
void Targ_Propagate(void);
|
||||
const char *GNodeMade_Name(GNodeMade);
|
||||
|
@ -17,7 +17,7 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: os.sh,v 1.56 2020/08/05 23:25:22 sjg Exp $
|
||||
# $Id: os.sh,v 1.59 2021/11/14 04:18:00 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1994 Simon J. Gerraty
|
||||
#
|
||||
@ -172,7 +172,7 @@ Interix)
|
||||
MACHINE=i386
|
||||
MACHINE_ARCH=i386
|
||||
;;
|
||||
UnixWare)
|
||||
UnixWare|SCO_SV)
|
||||
OSREL=`uname -v`
|
||||
OSMAJOR=`IFS=.; set $OSREL; echo $1`
|
||||
MACHINE_ARCH=`uname -m`
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.c,v 1.560 2021/06/21 10:42:06 rillig Exp $ */
|
||||
/* $NetBSD: parse.c,v 1.574 2021/12/12 15:44:41 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -124,7 +124,7 @@
|
||||
#include "pathnames.h"
|
||||
|
||||
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: parse.c,v 1.560 2021/06/21 10:42:06 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: parse.c,v 1.574 2021/12/12 15:44:41 rillig Exp $");
|
||||
|
||||
/* types and constants */
|
||||
|
||||
@ -139,10 +139,14 @@ typedef struct IFile {
|
||||
unsigned int cond_depth; /* 'if' nesting when file opened */
|
||||
bool depending; /* state of doing_depend on EOF */
|
||||
|
||||
/* The buffer from which the file's content is read. */
|
||||
/*
|
||||
* The buffer from which the file's content is read. The buffer
|
||||
* always ends with '\n', the buffer is not null-terminated, that is,
|
||||
* buf_end[0] is already out of bounds.
|
||||
*/
|
||||
char *buf_freeIt;
|
||||
char *buf_ptr; /* next char to be read */
|
||||
char *buf_end;
|
||||
char *buf_end; /* buf_end[-1] == '\n' */
|
||||
|
||||
/* Function to read more data, with a single opaque argument. */
|
||||
ReadMoreProc readMore;
|
||||
@ -233,7 +237,7 @@ static GNode *order_pred;
|
||||
/* parser state */
|
||||
|
||||
/* number of fatal errors */
|
||||
static int fatals = 0;
|
||||
static int parseErrors = 0;
|
||||
|
||||
/*
|
||||
* Variables for doing includes
|
||||
@ -276,7 +280,7 @@ SearchPath *defSysIncPath; /* default for sysIncPath */
|
||||
* keyword is used as a source ("0" if the keyword isn't special as a source)
|
||||
*/
|
||||
static const struct {
|
||||
const char *name; /* Name of keyword */
|
||||
const char name[17]; /* Name of keyword */
|
||||
ParseSpecial spec; /* Type when used as a target */
|
||||
GNodeType op; /* Operator when used as a source */
|
||||
} parseKeywords[] = {
|
||||
@ -329,8 +333,6 @@ static const struct {
|
||||
/* file loader */
|
||||
|
||||
struct loadedfile {
|
||||
/* XXX: What is the lifetime of this path? Who manages the memory? */
|
||||
const char *path; /* name, for error reports */
|
||||
char *buf; /* contents buffer */
|
||||
size_t len; /* length of contents */
|
||||
bool used; /* XXX: have we used the data yet */
|
||||
@ -338,12 +340,11 @@ struct loadedfile {
|
||||
|
||||
/* XXX: What is the lifetime of the path? Who manages the memory? */
|
||||
static struct loadedfile *
|
||||
loadedfile_create(const char *path, char *buf, size_t buflen)
|
||||
loadedfile_create(char *buf, size_t buflen)
|
||||
{
|
||||
struct loadedfile *lf;
|
||||
|
||||
lf = bmake_malloc(sizeof *lf);
|
||||
lf->path = path == NULL ? "(stdin)" : path;
|
||||
lf->buf = buf;
|
||||
lf->len = buflen;
|
||||
lf->used = false;
|
||||
@ -468,8 +469,7 @@ loadfile(const char *path, int fd)
|
||||
close(fd);
|
||||
|
||||
{
|
||||
struct loadedfile *lf = loadedfile_create(path,
|
||||
buf.data, buf.len);
|
||||
struct loadedfile *lf = loadedfile_create(buf.data, buf.len);
|
||||
Buf_DoneData(&buf);
|
||||
return lf;
|
||||
}
|
||||
@ -545,7 +545,7 @@ ParseIsEscaped(const char *line, const char *c)
|
||||
* was first defined.
|
||||
*/
|
||||
static void
|
||||
ParseMark(GNode *gn)
|
||||
RememberLocation(GNode *gn)
|
||||
{
|
||||
IFile *curFile = CurFile();
|
||||
gn->fname = curFile->fname;
|
||||
@ -628,7 +628,7 @@ ParseVErrorInternal(FILE *f, const char *fname, size_t lineno,
|
||||
goto print_stack_trace;
|
||||
if (type == PARSE_WARNING && !opts.parseWarnFatal)
|
||||
goto print_stack_trace;
|
||||
fatals++;
|
||||
parseErrors++;
|
||||
if (type == PARSE_WARNING && !fatal_warning_error_printed) {
|
||||
Error("parsing warnings being treated as errors");
|
||||
fatal_warning_error_printed = true;
|
||||
@ -797,7 +797,7 @@ TryApplyDependencyOperator(GNode *gn, GNodeType op)
|
||||
|
||||
cohort = Targ_NewInternalNode(gn->name);
|
||||
if (doing_depend)
|
||||
ParseMark(cohort);
|
||||
RememberLocation(cohort);
|
||||
/*
|
||||
* Make the cohort invisible as well to avoid duplicating it
|
||||
* into other variables. True, parents of this target won't
|
||||
@ -852,7 +852,7 @@ ParseDependencySourceWait(bool isSpecial)
|
||||
snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
|
||||
gn = Targ_NewInternalNode(wait_src);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
RememberLocation(gn);
|
||||
gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
|
||||
LinkToTargets(gn, isSpecial);
|
||||
|
||||
@ -912,7 +912,7 @@ ParseDependencySourceOrder(const char *src)
|
||||
*/
|
||||
gn = Targ_GetNode(src);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
RememberLocation(gn);
|
||||
if (order_pred != NULL) {
|
||||
Lst_Append(&order_pred->order_succ, gn);
|
||||
Lst_Append(&gn->order_pred, order_pred);
|
||||
@ -949,7 +949,7 @@ ParseDependencySourceOther(const char *src, GNodeType tOp,
|
||||
/* Find/create the 'src' node and attach to all targets */
|
||||
gn = Targ_GetNode(src);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
RememberLocation(gn);
|
||||
if (tOp != OP_NONE)
|
||||
gn->type |= tOp;
|
||||
else
|
||||
@ -1019,7 +1019,7 @@ ParseErrorNoDependency(const char *lstart)
|
||||
(strncmp(lstart, "======", 6) == 0) ||
|
||||
(strncmp(lstart, ">>>>>>", 6) == 0))
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Makefile appears to contain unresolved cvs/rcs/??? merge conflicts");
|
||||
"Makefile appears to contain unresolved CVS/RCS/??? merge conflicts");
|
||||
else if (lstart[0] == '.') {
|
||||
const char *dirstart = lstart + 1;
|
||||
const char *dirend;
|
||||
@ -1100,7 +1100,7 @@ ParseDependencyTargetSpecial(ParseSpecial *inout_specType,
|
||||
case SP_INTERRUPT: {
|
||||
GNode *gn = Targ_GetNode(targetName);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
RememberLocation(gn);
|
||||
gn->type |= OP_NOTMAIN | OP_SPECIAL;
|
||||
Lst_Append(targets, gn);
|
||||
break;
|
||||
@ -1230,7 +1230,7 @@ ParseDependencyTargetMundane(char *targetName, StringList *curTargs)
|
||||
? Suff_AddTransform(targName)
|
||||
: Targ_GetNode(targName);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
RememberLocation(gn);
|
||||
|
||||
Lst_Append(targets, gn);
|
||||
}
|
||||
@ -1612,10 +1612,8 @@ ParseDependencySourcesMundane(char *start, char *end,
|
||||
* See the tests depsrc-*.mk.
|
||||
*/
|
||||
static void
|
||||
ParseDependencySources(char *const line, char *const cp,
|
||||
GNodeType const tOp,
|
||||
ParseSpecial const specType,
|
||||
SearchPathList ** inout_paths)
|
||||
ParseDependencySources(char *line, char *cp, GNodeType tOp,
|
||||
ParseSpecial specType, SearchPathList **inout_paths)
|
||||
{
|
||||
if (line[0] == '\0') {
|
||||
ParseDependencySourcesEmpty(specType, *inout_paths);
|
||||
@ -2099,7 +2097,7 @@ ParseAddCmd(GNode *gn, char *cmd)
|
||||
Lst_Append(&gn->commands, cmd);
|
||||
if (MaybeSubMake(cmd))
|
||||
gn->type |= OP_SUBMAKE;
|
||||
ParseMark(gn);
|
||||
RememberLocation(gn);
|
||||
} else {
|
||||
#if 0
|
||||
/* XXX: We cannot do this until we fix the tree */
|
||||
@ -2132,7 +2130,7 @@ Parse_AddIncludeDir(const char *dir)
|
||||
/*
|
||||
* Handle one of the .[-ds]include directives by remembering the current file
|
||||
* and pushing the included file on the stack. After the included file has
|
||||
* finished, parsing continues with the including file; see Parse_SetInput
|
||||
* finished, parsing continues with the including file; see Parse_PushInput
|
||||
* and ParseEOF.
|
||||
*
|
||||
* System includes are looked up in sysIncPath, any other includes are looked
|
||||
@ -2140,7 +2138,7 @@ Parse_AddIncludeDir(const char *dir)
|
||||
* line options.
|
||||
*/
|
||||
static void
|
||||
IncludeFile(char *file, bool isSystem, bool depinc, bool silent)
|
||||
IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
|
||||
{
|
||||
struct loadedfile *lf;
|
||||
char *fullname; /* full pathname of file */
|
||||
@ -2239,60 +2237,63 @@ IncludeFile(char *file, bool isSystem, bool depinc, bool silent)
|
||||
lf = loadfile(fullname, fd);
|
||||
|
||||
/* Start reading from this file next */
|
||||
Parse_SetInput(fullname, 0, -1, loadedfile_readMore, lf);
|
||||
Parse_PushInput(fullname, 0, -1, loadedfile_readMore, lf);
|
||||
CurFile()->lf = lf;
|
||||
if (depinc)
|
||||
doing_depend = depinc; /* only turn it on */
|
||||
/* TODO: consider free(fullname); */
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a directive like '.include' or '.-include'.
|
||||
*
|
||||
* .include "user-makefile.mk"
|
||||
* .include <system-makefile.mk>
|
||||
*/
|
||||
static void
|
||||
ParseInclude(char *directive)
|
||||
{
|
||||
char endc; /* the character which ends the file spec */
|
||||
char *cp; /* current position in file spec */
|
||||
char endc; /* '>' or '"' */
|
||||
char *p;
|
||||
bool silent = directive[0] != 'i';
|
||||
char *file = directive + (silent ? 8 : 7);
|
||||
FStr file;
|
||||
|
||||
/* Skip to delimiter character so we know where to look */
|
||||
pp_skip_hspace(&file);
|
||||
p = directive + (silent ? 8 : 7);
|
||||
pp_skip_hspace(&p);
|
||||
|
||||
if (*file != '"' && *file != '<') {
|
||||
if (*p != '"' && *p != '<') {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
".include filename must be delimited by '\"' or '<'");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the search path on which to find the include file based on the
|
||||
* characters which bracket its name. Angle-brackets imply it's
|
||||
* a system Makefile while double-quotes imply it's a user makefile
|
||||
*/
|
||||
if (*file == '<')
|
||||
if (*p++ == '<')
|
||||
endc = '>';
|
||||
else
|
||||
endc = '"';
|
||||
file = FStr_InitRefer(p);
|
||||
|
||||
/* Skip to matching delimiter */
|
||||
for (cp = ++file; *cp != '\0' && *cp != endc; cp++)
|
||||
continue;
|
||||
while (*p != '\0' && *p != endc)
|
||||
p++;
|
||||
|
||||
if (*cp != endc) {
|
||||
if (*p != endc) {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Unclosed .include filename. '%c' expected", endc);
|
||||
return;
|
||||
}
|
||||
|
||||
*cp = '\0';
|
||||
*p = '\0';
|
||||
|
||||
/*
|
||||
* Substitute for any variables in the filename before trying to
|
||||
* find the file.
|
||||
*/
|
||||
(void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &file);
|
||||
/* TODO: handle errors */
|
||||
if (strchr(file.str, '$') != NULL) {
|
||||
char *xfile;
|
||||
Var_Subst(file.str, SCOPE_CMDLINE, VARE_WANTRES, &xfile);
|
||||
/* TODO: handle errors */
|
||||
file = FStr_InitOwn(xfile);
|
||||
}
|
||||
|
||||
IncludeFile(file, endc == '>', directive[0] == 'd', silent);
|
||||
free(file);
|
||||
IncludeFile(file.str, endc == '>', directive[0] == 'd', silent);
|
||||
FStr_Done(&file);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2314,8 +2315,8 @@ SetFilenameVars(const char *filename, const char *dirvar, const char *filevar)
|
||||
basename = slash + 1;
|
||||
}
|
||||
|
||||
Global_SetExpand(dirvar, dirname.str);
|
||||
Global_SetExpand(filevar, basename);
|
||||
Global_Set(dirvar, dirname.str);
|
||||
Global_Set(filevar, basename);
|
||||
|
||||
DEBUG5(PARSE, "%s: ${%s} = `%s' ${%s} = `%s'\n",
|
||||
__func__, dirvar, dirname.str, filevar, basename);
|
||||
@ -2418,7 +2419,7 @@ ParseTrackInput(const char *name)
|
||||
* The given file is added to the includes stack.
|
||||
*/
|
||||
void
|
||||
Parse_SetInput(const char *name, int lineno, int fd,
|
||||
Parse_PushInput(const char *name, int lineno, int fd,
|
||||
ReadMoreProc readMore, void *readMoreArg)
|
||||
{
|
||||
IFile *curFile;
|
||||
@ -2431,7 +2432,7 @@ Parse_SetInput(const char *name, int lineno, int fd,
|
||||
else
|
||||
ParseTrackInput(name);
|
||||
|
||||
DEBUG3(PARSE, "Parse_SetInput: %s %s, line %d\n",
|
||||
DEBUG3(PARSE, "Parse_PushInput: %s %s, line %d\n",
|
||||
readMore == loadedfile_readMore ? "file" : ".for loop in",
|
||||
name, lineno);
|
||||
|
||||
@ -2649,13 +2650,15 @@ typedef enum ParseRawLineResult {
|
||||
|
||||
/*
|
||||
* Parse until the end of a line, taking into account lines that end with
|
||||
* backslash-newline.
|
||||
* backslash-newline. The resulting line goes from out_line to out_line_end;
|
||||
* the line is not null-terminated.
|
||||
*/
|
||||
static ParseRawLineResult
|
||||
ParseRawLine(IFile *curFile, char **out_line, char **out_line_end,
|
||||
char **out_firstBackslash, char **out_firstComment)
|
||||
{
|
||||
char *line = curFile->buf_ptr;
|
||||
char *buf_end = curFile->buf_end;
|
||||
char *p = line;
|
||||
char *line_end = line;
|
||||
char *firstBackslash = NULL;
|
||||
@ -2667,14 +2670,14 @@ ParseRawLine(IFile *curFile, char **out_line, char **out_line_end,
|
||||
for (;;) {
|
||||
char ch;
|
||||
|
||||
if (p == curFile->buf_end) {
|
||||
if (p == buf_end) {
|
||||
res = PRLR_EOF;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = *p;
|
||||
if (ch == '\0' ||
|
||||
(ch == '\\' && p + 1 < curFile->buf_end && p[1] == '\0')) {
|
||||
(ch == '\\' && p + 1 < buf_end && p[1] == '\0')) {
|
||||
Parse_Error(PARSE_FATAL, "Zero byte read from file");
|
||||
return PRLR_ERROR;
|
||||
}
|
||||
@ -2685,7 +2688,7 @@ ParseRawLine(IFile *curFile, char **out_line, char **out_line_end,
|
||||
firstBackslash = p;
|
||||
if (p[1] == '\n') {
|
||||
curFile->lineno++;
|
||||
if (p + 2 == curFile->buf_end) {
|
||||
if (p + 2 == buf_end) {
|
||||
line_end = p;
|
||||
*line_end = '\n';
|
||||
p += 2;
|
||||
@ -2694,7 +2697,7 @@ ParseRawLine(IFile *curFile, char **out_line, char **out_line_end,
|
||||
}
|
||||
p += 2;
|
||||
line_end = p;
|
||||
assert(p <= curFile->buf_end);
|
||||
assert(p <= buf_end);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2904,7 +2907,7 @@ ParseForLoop(const char *line)
|
||||
line = ParseGetLine(GLM_FOR_BODY);
|
||||
if (line == NULL) {
|
||||
Parse_Error(PARSE_FATAL,
|
||||
"Unexpected end of file in for loop.");
|
||||
"Unexpected end of file in .for loop");
|
||||
break;
|
||||
}
|
||||
} while (For_Accum(line));
|
||||
@ -3012,12 +3015,6 @@ ParseLine_ShellCommand(const char *p)
|
||||
}
|
||||
}
|
||||
|
||||
MAKE_INLINE bool
|
||||
IsDirective(const char *dir, size_t dirlen, const char *name)
|
||||
{
|
||||
return dirlen == strlen(name) && memcmp(dir, name, dirlen) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the line starts with one of the known directives, and if so, handle
|
||||
* the directive.
|
||||
@ -3026,8 +3023,8 @@ static bool
|
||||
ParseDirective(char *line)
|
||||
{
|
||||
char *cp = line + 1;
|
||||
const char *dir, *arg;
|
||||
size_t dirlen;
|
||||
const char *arg;
|
||||
Substring dir;
|
||||
|
||||
pp_skip_whitespace(&cp);
|
||||
if (IsInclude(cp, false)) {
|
||||
@ -3035,10 +3032,10 @@ ParseDirective(char *line)
|
||||
return true;
|
||||
}
|
||||
|
||||
dir = cp;
|
||||
dir.start = cp;
|
||||
while (ch_isalpha(*cp) || *cp == '-')
|
||||
cp++;
|
||||
dirlen = (size_t)(cp - dir);
|
||||
dir.end = cp;
|
||||
|
||||
if (*cp != '\0' && !ch_isspace(*cp))
|
||||
return false;
|
||||
@ -3046,31 +3043,31 @@ ParseDirective(char *line)
|
||||
pp_skip_whitespace(&cp);
|
||||
arg = cp;
|
||||
|
||||
if (IsDirective(dir, dirlen, "undef")) {
|
||||
Var_Undef(cp);
|
||||
if (Substring_Equals(dir, "undef")) {
|
||||
Var_Undef(arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "export")) {
|
||||
} else if (Substring_Equals(dir, "export")) {
|
||||
Var_Export(VEM_PLAIN, arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "export-env")) {
|
||||
} else if (Substring_Equals(dir, "export-env")) {
|
||||
Var_Export(VEM_ENV, arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "export-literal")) {
|
||||
} else if (Substring_Equals(dir, "export-literal")) {
|
||||
Var_Export(VEM_LITERAL, arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "unexport")) {
|
||||
} else if (Substring_Equals(dir, "unexport")) {
|
||||
Var_UnExport(false, arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "unexport-env")) {
|
||||
} else if (Substring_Equals(dir, "unexport-env")) {
|
||||
Var_UnExport(true, arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "info")) {
|
||||
} else if (Substring_Equals(dir, "info")) {
|
||||
ParseMessage(PARSE_INFO, "info", arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "warning")) {
|
||||
} else if (Substring_Equals(dir, "warning")) {
|
||||
ParseMessage(PARSE_WARNING, "warning", arg);
|
||||
return true;
|
||||
} else if (IsDirective(dir, dirlen, "error")) {
|
||||
} else if (Substring_Equals(dir, "error")) {
|
||||
ParseMessage(PARSE_FATAL, "error", arg);
|
||||
return true;
|
||||
}
|
||||
@ -3251,7 +3248,7 @@ Parse_File(const char *name, int fd)
|
||||
if (name == NULL)
|
||||
name = "(stdin)";
|
||||
|
||||
Parse_SetInput(name, 0, -1, loadedfile_readMore, lf);
|
||||
Parse_PushInput(name, 0, -1, loadedfile_readMore, lf);
|
||||
CurFile()->lf = lf;
|
||||
|
||||
do {
|
||||
@ -3265,7 +3262,7 @@ Parse_File(const char *name, int fd)
|
||||
|
||||
FinishDependencyGroup();
|
||||
|
||||
if (fatals != 0) {
|
||||
if (parseErrors != 0) {
|
||||
(void)fflush(stdout);
|
||||
(void)fprintf(stderr,
|
||||
"%s: Fatal errors encountered -- cannot continue",
|
||||
@ -3320,7 +3317,7 @@ Parse_MainName(GNodeList *mainList)
|
||||
}
|
||||
|
||||
int
|
||||
Parse_GetFatals(void)
|
||||
Parse_NumErrors(void)
|
||||
{
|
||||
return fatals;
|
||||
return parseErrors;
|
||||
}
|
||||
|
104
contrib/bmake/sigact.h
Normal file
104
contrib/bmake/sigact.h
Normal file
@ -0,0 +1,104 @@
|
||||
/* NAME:
|
||||
* sigact.h - sigaction et al
|
||||
*
|
||||
* SYNOPSIS:
|
||||
* #include "sigact.h"
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* This header is the interface to a fake sigaction(2)
|
||||
* implementation. It provides a POSIX compliant interface
|
||||
* to whatever signal handling mechanisms are available.
|
||||
* It also provides a Signal() function that is implemented
|
||||
* in terms of sigaction().
|
||||
* If not using signal(2) as part of the underlying
|
||||
* implementation (USE_SIGNAL or USE_SIGMASK), and
|
||||
* NO_SIGNAL is not defined, it also provides a signal()
|
||||
* function that calls Signal().
|
||||
*
|
||||
* SEE ALSO:
|
||||
* sigact.c
|
||||
*/
|
||||
/*
|
||||
* RCSid:
|
||||
* $Id: sigact.h,v 1.4 2021/10/14 19:39:17 sjg Exp $
|
||||
*/
|
||||
#ifndef _SIGACT_H
|
||||
#define _SIGACT_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* most modern systems use void for signal handlers but
|
||||
* not all.
|
||||
*/
|
||||
#ifndef SIG_HDLR
|
||||
# define SIG_HDLR void
|
||||
#endif
|
||||
|
||||
/*
|
||||
* if you want to install this header as signal.h,
|
||||
* modify this to pick up the original signal.h
|
||||
*/
|
||||
#ifndef SIGKILL
|
||||
# include <signal.h>
|
||||
#endif
|
||||
#ifndef SIGKILL
|
||||
# include <sys/signal.h>
|
||||
#endif
|
||||
|
||||
#ifndef SIG_ERR
|
||||
# define SIG_ERR (SIG_HDLR (*)())-1
|
||||
#endif
|
||||
#ifndef BADSIG
|
||||
# define BADSIG SIG_ERR
|
||||
#endif
|
||||
|
||||
#ifndef SA_NOCLDSTOP
|
||||
/* we assume we need the fake sigaction */
|
||||
/* sa_flags */
|
||||
#define SA_NOCLDSTOP 1 /* don't send SIGCHLD on child stop */
|
||||
#define SA_RESTART 2 /* re-start I/O */
|
||||
|
||||
/* sigprocmask flags */
|
||||
#define SIG_BLOCK 1
|
||||
#define SIG_UNBLOCK 2
|
||||
#define SIG_SETMASK 4
|
||||
|
||||
/*
|
||||
* this is a bit untidy
|
||||
*/
|
||||
#ifdef _SIGSET_T_
|
||||
typedef _SIGSET_T_ sigset_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* POSIX sa_handler should return void, but since we are
|
||||
* implementing in terms of something else, it may
|
||||
* be appropriate to use the normal SIG_HDLR return type
|
||||
*/
|
||||
struct sigaction
|
||||
{
|
||||
SIG_HDLR (*sa_handler)();
|
||||
sigset_t sa_mask;
|
||||
int sa_flags;
|
||||
};
|
||||
|
||||
|
||||
int sigaction ( int /*sig*/, const struct sigaction */*act*/, struct sigaction */*oact*/ );
|
||||
int sigaddset ( sigset_t */*mask*/, int /*sig*/ );
|
||||
int sigdelset ( sigset_t */*mask*/, int /*sig*/ );
|
||||
int sigemptyset ( sigset_t */*mask*/ );
|
||||
int sigfillset ( sigset_t */*mask*/ );
|
||||
int sigismember ( const sigset_t */*mask*/, int /*sig*/ );
|
||||
int sigpending ( sigset_t */*set*/ );
|
||||
int sigprocmask ( int how, const sigset_t */*set*/, sigset_t */*oset*/ );
|
||||
int sigsuspend ( sigset_t */*mask*/ );
|
||||
|
||||
#ifndef sigmask
|
||||
# define sigmask(s) (1<<((s)-1) & (32 - 1)) /* convert SIGnum to mask */
|
||||
#endif
|
||||
#if !defined(NSIG) && defined(_NSIG)
|
||||
# define NSIG _NSIG
|
||||
#endif
|
||||
#endif /* ! SA_NOCLDSTOP */
|
||||
#endif /* _SIGACT_H */
|
397
contrib/bmake/sigaction.c
Normal file
397
contrib/bmake/sigaction.c
Normal file
@ -0,0 +1,397 @@
|
||||
/* NAME:
|
||||
* sigact.c - fake sigaction(2)
|
||||
*
|
||||
* SYNOPSIS:
|
||||
* #include "sigact.h"
|
||||
*
|
||||
* int sigaction(int sig, struct sigaction *act,
|
||||
* struct sigaction *oact);
|
||||
* int sigaddset(sigset_t *mask, int sig);
|
||||
* int sigdelset(sigset_t *mask, int sig);
|
||||
* int sigemptyset(sigset_t *mask);
|
||||
* int sigfillset(sigset_t *mask);
|
||||
* int sigismember(sigset_t *mask, int sig);
|
||||
* int sigpending(sigset_t *set);
|
||||
* int sigprocmask(int how, sigset_t *set, sigset_t *oset);
|
||||
* int sigsuspend(sigset_t *mask);
|
||||
*
|
||||
* SIG_HDLR (*Signal(int sig, SIG_HDLR (*disp)(int)))(int);
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* This is a fake sigaction implementation. It uses
|
||||
* sigsetmask(2) et al or sigset(2) and friends if
|
||||
* available, otherwise it just uses signal(2). If it
|
||||
* thinks sigaction(2) really exists it compiles to "almost"
|
||||
* nothing.
|
||||
*
|
||||
* In any case it provides a Signal() function that is
|
||||
* implemented in terms of sigaction().
|
||||
* If not using signal(2) as part of the underlying
|
||||
* implementation (USE_SIGNAL or USE_SIGMASK), and
|
||||
* NO_SIGNAL is not defined, it also provides a signal()
|
||||
* function that calls Signal().
|
||||
*
|
||||
* The need for all this mucking about is the problems
|
||||
* caused by mixing various signal handling mechanisms in
|
||||
* the one process. This module allows for a consistent
|
||||
* POSIX compliant interface to whatever is actually
|
||||
* available.
|
||||
*
|
||||
* sigaction() allows the caller to examine and/or set the
|
||||
* action to be associated with a given signal. "act" and
|
||||
* "oact" are pointers to 'sigaction structs':
|
||||
*.nf
|
||||
*
|
||||
* struct sigaction
|
||||
* {
|
||||
* SIG_HDLR (*sa_handler)();
|
||||
* sigset_t sa_mask;
|
||||
* int sa_flags;
|
||||
* };
|
||||
*.fi
|
||||
*
|
||||
* SIG_HDLR is normally 'void' in the POSIX implementation
|
||||
* and for most current systems. On some older UNIX
|
||||
* systems, signal handlers do not return 'void', so
|
||||
* this implementation keeps 'sa_handler' inline with the
|
||||
* hosts normal signal handling conventions.
|
||||
* 'sa_mask' controls which signals will be blocked while
|
||||
* the selected signal handler is active. It is not used
|
||||
* in this implementation.
|
||||
* 'sa_flags' controls various semantics such as whether
|
||||
* system calls should be automagically restarted
|
||||
* (SA_RESTART) etc. It is not used in this
|
||||
* implementation.
|
||||
* Either "act" or "oact" may be NULL in which case the
|
||||
* appropriate operation is skipped.
|
||||
*
|
||||
* sigaddset() adds "sig" to the sigset_t pointed to by "mask".
|
||||
*
|
||||
* sigdelset() removes "sig" from the sigset_t pointed to
|
||||
* by "mask".
|
||||
*
|
||||
* sigemptyset() makes the sigset_t pointed to by "mask" empty.
|
||||
*
|
||||
* sigfillset() makes the sigset_t pointed to by "mask"
|
||||
* full ie. match all signals.
|
||||
*
|
||||
* sigismember() returns true if "sig" is found in "*mask".
|
||||
*
|
||||
* sigpending() is supposed to return "set" loaded with the
|
||||
* set of signals that are blocked and pending for the
|
||||
* calling process. It does nothing in this impementation.
|
||||
*
|
||||
* sigprocmask() is used to examine and/or change the
|
||||
* signal mask for the calling process. Either "set" or
|
||||
* "oset" may be NULL in which case the appropriate
|
||||
* operation is skipped. "how" may be one of SIG_BLOCK,
|
||||
* SIG_UNBLOCK or SIG_SETMASK. If this package is built
|
||||
* with USE_SIGNAL, then this routine achieves nothing.
|
||||
*
|
||||
* sigsuspend() sets the signal mask to "*mask" and waits
|
||||
* for a signal to be delivered after which the previous
|
||||
* mask is restored.
|
||||
*
|
||||
*
|
||||
* RETURN VALUE:
|
||||
* 0==success, -1==failure
|
||||
*
|
||||
* BUGS:
|
||||
* Since we fake most of this, don't expect fancy usage to
|
||||
* work.
|
||||
*
|
||||
* AUTHOR:
|
||||
* Simon J. Gerraty <sjg@crufty.net>
|
||||
*/
|
||||
/* COPYRIGHT:
|
||||
* @(#)Copyright (c) 1992-2021, Simon J. Gerraty
|
||||
*
|
||||
* This is free software. It comes with NO WARRANTY.
|
||||
* Permission to use, modify and distribute this source code
|
||||
* is granted subject to the following conditions.
|
||||
* 1/ that that the above copyright notice and this notice
|
||||
* are preserved in all copies and that due credit be given
|
||||
* to the author.
|
||||
* 2/ that any changes to this code are clearly commented
|
||||
* as such so that the author does get blamed for bugs
|
||||
* other than his own.
|
||||
*
|
||||
* Please send copies of changes and bug-fixes to:
|
||||
* sjg@crufty.net
|
||||
*
|
||||
*/
|
||||
#ifndef lint
|
||||
static char *RCSid = "$Id: sigact.c,v 1.8 2021/10/14 19:39:17 sjg Exp $";
|
||||
#endif
|
||||
|
||||
#undef _ANSI_SOURCE /* causes problems */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
# ifdef NO_SIGSET
|
||||
# undef HAVE_SIGSET
|
||||
# endif
|
||||
# ifndef HAVE_SIGACTION
|
||||
# ifdef HAVE_SIGSETMASK
|
||||
# define USE_SIGMASK
|
||||
# else
|
||||
# ifdef HAVE_SIGSET
|
||||
# define USE_SIGSET
|
||||
# else
|
||||
# define USE_SIGNAL
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* some systems have a faulty sigaction() implementation!
|
||||
* Allow us to bypass it.
|
||||
* Or they may have installed sigact.h as signal.h which is why
|
||||
* we have SA_NOCLDSTOP defined.
|
||||
*/
|
||||
#if !defined(SA_NOCLDSTOP) || defined(_SIGACT_H) || defined(USE_SIGNAL) || defined(USE_SIGSET) || defined(USE_SIGMASK)
|
||||
|
||||
/*
|
||||
* if we haven't been told,
|
||||
* try and guess what we should implement with.
|
||||
*/
|
||||
#if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL)
|
||||
# if defined(sigmask) || defined(BSD) || defined(_BSD) && !defined(BSD41)
|
||||
# define USE_SIGMASK
|
||||
# else
|
||||
# ifndef NO_SIGSET
|
||||
# define USE_SIGSET
|
||||
# else
|
||||
# define USE_SIGNAL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
/*
|
||||
* if we still don't know, we're in trouble
|
||||
*/
|
||||
#if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL)
|
||||
error must know what to implement with
|
||||
#endif
|
||||
|
||||
#include "sigact.h"
|
||||
|
||||
/*
|
||||
* in case signal() has been mapped to our Signal().
|
||||
*/
|
||||
#undef signal
|
||||
|
||||
|
||||
int
|
||||
sigaction(int sig,
|
||||
const struct sigaction *act,
|
||||
struct sigaction *oact)
|
||||
{
|
||||
SIG_HDLR(*oldh) ();
|
||||
|
||||
if (act) {
|
||||
#ifdef USE_SIGSET
|
||||
oldh = sigset(sig, act->sa_handler);
|
||||
#else
|
||||
oldh = signal(sig, act->sa_handler);
|
||||
#endif
|
||||
} else {
|
||||
if (oact) {
|
||||
#ifdef USE_SIGSET
|
||||
oldh = sigset(sig, SIG_IGN);
|
||||
#else
|
||||
oldh = signal(sig, SIG_IGN);
|
||||
#endif
|
||||
if (oldh != SIG_IGN && oldh != SIG_ERR) {
|
||||
#ifdef USE_SIGSET
|
||||
(void) sigset(sig, oldh);
|
||||
#else
|
||||
(void) signal(sig, oldh);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oact) {
|
||||
oact->sa_handler = oldh;
|
||||
}
|
||||
return 0; /* hey we're faking it */
|
||||
}
|
||||
|
||||
#ifndef HAVE_SIGADDSET
|
||||
int
|
||||
sigaddset(sigset_t *mask, int sig)
|
||||
{
|
||||
*mask |= sigmask(sig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sigdelset(sigset_t *mask, int sig)
|
||||
{
|
||||
*mask &= ~(sigmask(sig));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sigemptyset(sigset_t *mask)
|
||||
{
|
||||
*mask = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sigfillset(sigset_t *mask)
|
||||
{
|
||||
*mask = ~0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sigismember(const sigset_t *mask, int sig)
|
||||
{
|
||||
return ((*mask) & sigmask(sig));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SIGPENDING
|
||||
int
|
||||
sigpending(sigset_t *set)
|
||||
{
|
||||
return 0; /* faking it! */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SIGPROCMASK
|
||||
int
|
||||
sigprocmask(int how, const sigset_t *set, sigset_t *oset)
|
||||
{
|
||||
#ifdef USE_SIGSET
|
||||
int i;
|
||||
#endif
|
||||
static sigset_t sm;
|
||||
static int once = 0;
|
||||
|
||||
if (!once) {
|
||||
/*
|
||||
* initally we clear sm,
|
||||
* there after, it represents the last
|
||||
* thing we did.
|
||||
*/
|
||||
once++;
|
||||
#ifdef USE_SIGMASK
|
||||
sm = sigblock(0);
|
||||
#else
|
||||
sm = 0;
|
||||
#endif
|
||||
}
|
||||
if (oset)
|
||||
*oset = sm;
|
||||
if (set) {
|
||||
switch (how) {
|
||||
case SIG_BLOCK:
|
||||
sm |= *set;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
sm &= ~(*set);
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
sm = *set;
|
||||
break;
|
||||
}
|
||||
#ifdef USE_SIGMASK
|
||||
(void) sigsetmask(sm);
|
||||
#else
|
||||
#ifdef USE_SIGSET
|
||||
for (i = 1; i < NSIG; i++) {
|
||||
if (how == SIG_UNBLOCK) {
|
||||
if (*set & sigmask(i))
|
||||
sigrelse(i);
|
||||
} else
|
||||
if (sm & sigmask(i)) {
|
||||
sighold(i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SIGSUSPEND
|
||||
int
|
||||
sigsuspend(sigset_t *mask)
|
||||
{
|
||||
#ifdef USE_SIGMASK
|
||||
sigpause(*mask);
|
||||
#else
|
||||
int i;
|
||||
|
||||
#ifdef USE_SIGSET
|
||||
|
||||
for (i = 1; i < NSIG; i++) {
|
||||
if (*mask & sigmask(i)) {
|
||||
/* not the same sigpause() as above! */
|
||||
sigpause(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else /* signal(2) only */
|
||||
SIG_HDLR(*oldh) ();
|
||||
|
||||
/*
|
||||
* make sure that signals in mask will not
|
||||
* be ignored.
|
||||
*/
|
||||
for (i = 1; i < NSIG; i++) {
|
||||
if (*mask & sigmask(i)) {
|
||||
if ((oldh = signal(i, SIG_DFL)) != SIG_ERR &&
|
||||
oldh != SIG_IGN &&
|
||||
oldh != SIG_DFL)
|
||||
(void) signal(i, oldh); /* restore handler */
|
||||
}
|
||||
}
|
||||
pause(); /* wait for a signal */
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* ! SA_NOCLDSTOP */
|
||||
|
||||
#if 0
|
||||
#if !defined(SIG_HDLR)
|
||||
#define SIG_HDLR void
|
||||
#endif
|
||||
#if !defined(SIG_ERR)
|
||||
#define SIG_ERR (SIG_HDLR (*)())-1
|
||||
#endif
|
||||
|
||||
#if !defined(USE_SIGNAL) && !defined(USE_SIGMASK) && !defined(NO_SIGNAL)
|
||||
/*
|
||||
* ensure we avoid signal mayhem
|
||||
*/
|
||||
|
||||
extern void (*Signal (int sig, void (*handler) (int)))(int);
|
||||
|
||||
SIG_HDLR(*signal(int sig, SIG_HDLR(*handler)(int))
|
||||
{
|
||||
return (Signal(sig, handler));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This lot (for GNU-Emacs) goes at the end of the file. */
|
||||
/*
|
||||
* Local Variables:
|
||||
* version-control:t
|
||||
* comment-column:40
|
||||
* End:
|
||||
*/
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: str.c,v 1.85 2021/05/30 21:16:54 rillig Exp $ */
|
||||
/* $NetBSD: str.c,v 1.86 2021/06/21 16:59:18 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -71,7 +71,7 @@
|
||||
#include "make.h"
|
||||
|
||||
/* "@(#)str.c 5.8 (Berkeley) 6/1/90" */
|
||||
MAKE_RCSID("$NetBSD: str.c,v 1.85 2021/05/30 21:16:54 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: str.c,v 1.86 2021/06/21 16:59:18 rillig Exp $");
|
||||
|
||||
/* Return the concatenation of s1 and s2, freshly allocated. */
|
||||
char *
|
||||
@ -188,10 +188,9 @@ Substring_Words(const char *str, bool expand)
|
||||
|
||||
*word_end++ = '\0';
|
||||
if (words_len == words_cap) {
|
||||
size_t new_size;
|
||||
words_cap *= 2;
|
||||
new_size = (words_cap + 1) * sizeof(words[0]);
|
||||
words = bmake_realloc(words, new_size);
|
||||
words = bmake_realloc(words,
|
||||
(words_cap + 1) * sizeof(words[0]));
|
||||
}
|
||||
words[words_len++] =
|
||||
Substring_Init(word_start, word_end - 1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: str.h,v 1.9 2021/05/30 21:16:54 rillig Exp $ */
|
||||
/* $NetBSD: str.h,v 1.12 2021/12/12 13:43:47 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2021 Roland Illig <rillig@NetBSD.org>
|
||||
@ -60,7 +60,6 @@ typedef struct LazyBuf {
|
||||
size_t len;
|
||||
size_t cap;
|
||||
const char *expected;
|
||||
void *freeIt;
|
||||
} LazyBuf;
|
||||
|
||||
/* The result of splitting a string into words. */
|
||||
@ -182,6 +181,14 @@ Substring_Equals(Substring sub, const char *str)
|
||||
memcmp(sub.start, str, len) == 0;
|
||||
}
|
||||
|
||||
MAKE_INLINE bool
|
||||
Substring_Eq(Substring sub, Substring str)
|
||||
{
|
||||
size_t len = Substring_Length(sub);
|
||||
return len == Substring_Length(str) &&
|
||||
memcmp(sub.start, str.start, len) == 0;
|
||||
}
|
||||
|
||||
MAKE_STATIC Substring
|
||||
Substring_Sub(Substring sub, size_t start, size_t end)
|
||||
{
|
||||
@ -266,13 +273,12 @@ LazyBuf_Init(LazyBuf *buf, const char *expected)
|
||||
buf->len = 0;
|
||||
buf->cap = 0;
|
||||
buf->expected = expected;
|
||||
buf->freeIt = NULL;
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
LazyBuf_Done(LazyBuf *buf)
|
||||
{
|
||||
free(buf->freeIt);
|
||||
free(buf->data);
|
||||
}
|
||||
|
||||
MAKE_STATIC void
|
||||
@ -329,6 +335,11 @@ LazyBuf_Get(const LazyBuf *buf)
|
||||
return Substring_Init(start, start + buf->len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the content of the buffer as a newly allocated string.
|
||||
*
|
||||
* See LazyBuf_Get to avoid unnecessary memory allocations.
|
||||
*/
|
||||
MAKE_STATIC FStr
|
||||
LazyBuf_DoneGet(LazyBuf *buf)
|
||||
{
|
||||
@ -352,6 +363,14 @@ Words_Free(Words w)
|
||||
|
||||
SubstringWords Substring_Words(const char *, bool);
|
||||
|
||||
MAKE_INLINE void
|
||||
SubstringWords_Init(SubstringWords *w)
|
||||
{
|
||||
w->words = NULL;
|
||||
w->len = 0;
|
||||
w->freeIt = NULL;
|
||||
}
|
||||
|
||||
MAKE_INLINE void
|
||||
SubstringWords_Free(SubstringWords w)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: suff.c,v 1.350 2021/04/04 10:05:08 rillig Exp $ */
|
||||
/* $NetBSD: suff.c,v 1.357 2021/12/12 20:45:48 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -115,7 +115,7 @@
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)suff.c 8.4 (Berkeley) 3/21/94" */
|
||||
MAKE_RCSID("$NetBSD: suff.c,v 1.350 2021/04/04 10:05:08 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: suff.c,v 1.357 2021/12/12 20:45:48 sjg Exp $");
|
||||
|
||||
typedef List SuffixList;
|
||||
typedef ListNode SuffixListNode;
|
||||
@ -142,37 +142,6 @@ static GNodeList transforms = LST_INIT;
|
||||
*/
|
||||
static int sNum = 0;
|
||||
|
||||
typedef enum SuffixFlags {
|
||||
SUFF_NONE = 0,
|
||||
|
||||
/*
|
||||
* This suffix marks include files. Their search path ends up in the
|
||||
* undocumented special variable '.INCLUDES'.
|
||||
*/
|
||||
SUFF_INCLUDE = 1 << 0,
|
||||
|
||||
/*
|
||||
* This suffix marks library files. Their search path ends up in the
|
||||
* undocumented special variable '.LIBS'.
|
||||
*/
|
||||
SUFF_LIBRARY = 1 << 1,
|
||||
|
||||
/*
|
||||
* The empty suffix.
|
||||
*
|
||||
* XXX: What is the difference between the empty suffix and the null
|
||||
* suffix?
|
||||
*
|
||||
* XXX: Why is SUFF_NULL needed at all? Wouldn't nameLen == 0 mean
|
||||
* the same?
|
||||
*/
|
||||
SUFF_NULL = 1 << 2
|
||||
|
||||
} SuffixFlags;
|
||||
|
||||
ENUM_FLAGS_RTTI_3(SuffixFlags,
|
||||
SUFF_INCLUDE, SUFF_LIBRARY, SUFF_NULL);
|
||||
|
||||
typedef List SuffixListList;
|
||||
|
||||
/*
|
||||
@ -184,24 +153,45 @@ typedef struct Suffix {
|
||||
char *name;
|
||||
/* Length of the name, to avoid strlen calls */
|
||||
size_t nameLen;
|
||||
/* Type of suffix */
|
||||
SuffixFlags flags;
|
||||
/*
|
||||
* This suffix marks include files. Their search path ends up in the
|
||||
* undocumented special variable '.INCLUDES'.
|
||||
*/
|
||||
bool include:1;
|
||||
/*
|
||||
* This suffix marks library files. Their search path ends up in the
|
||||
* undocumented special variable '.LIBS'.
|
||||
*/
|
||||
bool library:1;
|
||||
/*
|
||||
* The empty suffix.
|
||||
*
|
||||
* XXX: What is the difference between the empty suffix and the null
|
||||
* suffix?
|
||||
*
|
||||
* XXX: Why is SUFF_NULL needed at all? Wouldn't nameLen == 0 mean
|
||||
* the same?
|
||||
*/
|
||||
bool isNull:1;
|
||||
/* The path along which files of this suffix may be found */
|
||||
SearchPath *searchPath;
|
||||
|
||||
/* The suffix number; TODO: document the purpose of this number */
|
||||
int sNum;
|
||||
/* Reference count of list membership and several other places */
|
||||
int refCount;
|
||||
|
||||
/* Suffixes we have a transformation to */
|
||||
SuffixList parents;
|
||||
/* Suffixes we have a transformation from */
|
||||
SuffixList children;
|
||||
|
||||
/* Lists in which this suffix is referenced.
|
||||
/*
|
||||
* Lists in which this suffix is referenced.
|
||||
*
|
||||
* XXX: These lists are used nowhere, they are just appended to, for
|
||||
* no apparent reason. They do have the side effect of increasing
|
||||
* refCount though. */
|
||||
* refCount though.
|
||||
*/
|
||||
SuffixListList ref;
|
||||
} Suffix;
|
||||
|
||||
@ -475,7 +465,9 @@ Suffix_New(const char *name)
|
||||
Lst_Init(&suff->parents);
|
||||
Lst_Init(&suff->ref);
|
||||
suff->sNum = sNum++;
|
||||
suff->flags = SUFF_NONE;
|
||||
suff->include = false;
|
||||
suff->library = false;
|
||||
suff->isNull = false;
|
||||
suff->refCount = 1; /* XXX: why 1? It's not assigned anywhere yet. */
|
||||
|
||||
return suff;
|
||||
@ -502,7 +494,9 @@ Suff_ClearSuffixes(void)
|
||||
emptySuff = nullSuff = Suffix_New("");
|
||||
|
||||
SearchPath_AddAll(nullSuff->searchPath, &dirSearchPath);
|
||||
nullSuff->flags = SUFF_NULL;
|
||||
nullSuff->include = false;
|
||||
nullSuff->library = false;
|
||||
nullSuff->isNull = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -619,6 +613,7 @@ Suff_AddTransform(const char *name)
|
||||
/* TODO: Avoid the redundant parsing here. */
|
||||
bool ok = ParseTransform(name, &srcSuff, &targSuff);
|
||||
assert(ok);
|
||||
/* LINTED 129 *//* expression has null effect */
|
||||
(void)ok;
|
||||
}
|
||||
|
||||
@ -888,12 +883,12 @@ Suff_ExtendPaths(void)
|
||||
Suffix *suff = ln->datum;
|
||||
if (!Lst_IsEmpty(&suff->searchPath->dirs)) {
|
||||
#ifdef INCLUDES
|
||||
if (suff->flags & SUFF_INCLUDE)
|
||||
if (suff->include)
|
||||
SearchPath_AddAll(includesPath,
|
||||
suff->searchPath);
|
||||
#endif
|
||||
#ifdef LIBRARIES
|
||||
if (suff->flags & SUFF_LIBRARY)
|
||||
if (suff->library)
|
||||
SearchPath_AddAll(libsPath, suff->searchPath);
|
||||
#endif
|
||||
SearchPath_AddAll(suff->searchPath, &dirSearchPath);
|
||||
@ -926,7 +921,7 @@ Suff_AddInclude(const char *suffName)
|
||||
{
|
||||
Suffix *suff = FindSuffixByName(suffName);
|
||||
if (suff != NULL)
|
||||
suff->flags |= SUFF_INCLUDE;
|
||||
suff->include = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -940,7 +935,7 @@ Suff_AddLib(const char *suffName)
|
||||
{
|
||||
Suffix *suff = FindSuffixByName(suffName);
|
||||
if (suff != NULL)
|
||||
suff->flags |= SUFF_LIBRARY;
|
||||
suff->library = true;
|
||||
}
|
||||
|
||||
/********** Implicit Source Search Functions *********/
|
||||
@ -1043,7 +1038,7 @@ CandidateList_AddCandidatesFor(CandidateList *list, Candidate *cand)
|
||||
for (ln = cand->suff->children.first; ln != NULL; ln = ln->next) {
|
||||
Suffix *suff = ln->datum;
|
||||
|
||||
if ((suff->flags & SUFF_NULL) && suff->name[0] != '\0') {
|
||||
if (suff->isNull && suff->name[0] != '\0') {
|
||||
/*
|
||||
* If the suffix has been marked as the NULL suffix,
|
||||
* also create a candidate for a file with no suffix
|
||||
@ -1918,7 +1913,7 @@ FindDepsRegular(GNode *gn, CandidateSearcher *cs)
|
||||
* If the suffix indicates that the target is a library, mark that in
|
||||
* the node's type field.
|
||||
*/
|
||||
if (targ->suff->flags & SUFF_LIBRARY)
|
||||
if (targ->suff->library)
|
||||
gn->type |= OP_LIB;
|
||||
|
||||
/*
|
||||
@ -2077,14 +2072,14 @@ Suff_SetNull(const char *name)
|
||||
Suffix *suff = FindSuffixByName(name);
|
||||
if (suff == NULL) {
|
||||
Parse_Error(PARSE_WARNING,
|
||||
"Desired null suffix %s not defined.",
|
||||
"Desired null suffix %s not defined",
|
||||
name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nullSuff != NULL)
|
||||
nullSuff->flags &= ~(unsigned)SUFF_NULL;
|
||||
suff->flags |= SUFF_NULL;
|
||||
nullSuff->isNull = false;
|
||||
suff->isNull = true;
|
||||
/* XXX: Here's where the transformation mangling would take place. */
|
||||
nullSuff = suff;
|
||||
}
|
||||
@ -2117,31 +2112,36 @@ Suff_End(void)
|
||||
|
||||
|
||||
static void
|
||||
PrintSuffNames(const char *prefix, SuffixList *suffs)
|
||||
PrintSuffNames(const char *prefix, const SuffixList *suffs)
|
||||
{
|
||||
SuffixListNode *ln;
|
||||
|
||||
debug_printf("#\t%s: ", prefix);
|
||||
for (ln = suffs->first; ln != NULL; ln = ln->next) {
|
||||
Suffix *suff = ln->datum;
|
||||
const Suffix *suff = ln->datum;
|
||||
debug_printf("%s ", suff->name);
|
||||
}
|
||||
debug_printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
Suffix_Print(Suffix *suff)
|
||||
Suffix_Print(const Suffix *suff)
|
||||
{
|
||||
Buffer buf;
|
||||
|
||||
Buf_InitSize(&buf, 16);
|
||||
Buf_AddFlag(&buf, suff->include, "SUFF_INCLUDE");
|
||||
Buf_AddFlag(&buf, suff->library, "SUFF_LIBRARY");
|
||||
Buf_AddFlag(&buf, suff->isNull, "SUFF_NULL");
|
||||
|
||||
debug_printf("# \"%s\" (num %d, ref %d)",
|
||||
suff->name, suff->sNum, suff->refCount);
|
||||
if (suff->flags != 0) {
|
||||
char flags_buf[SuffixFlags_ToStringSize];
|
||||
|
||||
debug_printf(" (%s)",
|
||||
SuffixFlags_ToString(flags_buf, suff->flags));
|
||||
}
|
||||
if (buf.len > 0)
|
||||
debug_printf(" (%s)", buf.data);
|
||||
debug_printf("\n");
|
||||
|
||||
Buf_Done(&buf);
|
||||
|
||||
PrintSuffNames("To", &suff->parents);
|
||||
PrintSuffNames("From", &suff->children);
|
||||
|
||||
@ -2177,3 +2177,20 @@ Suff_PrintAll(void)
|
||||
PrintTransformation(ln->datum);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
Suff_NamesStr(void)
|
||||
{
|
||||
Buffer buf;
|
||||
SuffixListNode *ln;
|
||||
Suffix *suff;
|
||||
|
||||
Buf_InitSize(&buf, 16);
|
||||
for (ln = sufflist.first; ln != NULL; ln = ln->next) {
|
||||
suff = ln->datum;
|
||||
if (ln != sufflist.first)
|
||||
Buf_AddByte(&buf, ' ');
|
||||
Buf_AddStr(&buf, suff->name);
|
||||
}
|
||||
return Buf_DoneData(&buf);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: targ.c,v 1.168 2021/04/03 12:01:00 rillig Exp $ */
|
||||
/* $NetBSD: targ.c,v 1.173 2021/11/28 19:51:06 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -113,7 +113,7 @@
|
||||
#include "dir.h"
|
||||
|
||||
/* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */
|
||||
MAKE_RCSID("$NetBSD: targ.c,v 1.168 2021/04/03 12:01:00 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: targ.c,v 1.173 2021/11/28 19:51:06 rillig Exp $");
|
||||
|
||||
/*
|
||||
* All target nodes that appeared on the left-hand side of one of the
|
||||
@ -187,7 +187,7 @@ GNode_New(const char *name)
|
||||
gn->uname = NULL;
|
||||
gn->path = NULL;
|
||||
gn->type = name[0] == '-' && name[1] == 'l' ? OP_LIB : OP_NONE;
|
||||
gn->flags = GNF_NONE;
|
||||
memset(&gn->flags, 0, sizeof(gn->flags));
|
||||
gn->made = UNMADE;
|
||||
gn->unmade = 0;
|
||||
gn->mtime = 0;
|
||||
@ -309,7 +309,7 @@ Targ_NewInternalNode(const char *name)
|
||||
Lst_Append(&allTargets, gn);
|
||||
DEBUG1(TARG, "Adding \"%s\" to all targets.\n", gn->name);
|
||||
if (doing_depend)
|
||||
gn->flags |= FROM_DEPEND;
|
||||
gn->flags.fromDepend = true;
|
||||
return gn;
|
||||
}
|
||||
|
||||
@ -416,36 +416,37 @@ Targ_FmtTime(time_t tm)
|
||||
|
||||
/* Print out a type field giving only those attributes the user can set. */
|
||||
void
|
||||
Targ_PrintType(int type)
|
||||
Targ_PrintType(GNodeType type)
|
||||
{
|
||||
int tbit;
|
||||
static const struct {
|
||||
GNodeType bit;
|
||||
bool internal;
|
||||
const char name[10];
|
||||
} names[] = {
|
||||
{ OP_MEMBER, true, "MEMBER" },
|
||||
{ OP_LIB, true, "LIB" },
|
||||
{ OP_ARCHV, true, "ARCHV" },
|
||||
{ OP_PHONY, true, "PHONY" },
|
||||
{ OP_NOTMAIN, false, "NOTMAIN" },
|
||||
{ OP_INVISIBLE, false, "INVISIBLE" },
|
||||
{ OP_MADE, true, "MADE" },
|
||||
{ OP_JOIN, false, "JOIN" },
|
||||
{ OP_MAKE, false, "MAKE" },
|
||||
{ OP_SILENT, false, "SILENT" },
|
||||
{ OP_PRECIOUS, false, "PRECIOUS" },
|
||||
{ OP_IGNORE, false, "IGNORE" },
|
||||
{ OP_EXEC, false, "EXEC" },
|
||||
{ OP_USE, false, "USE" },
|
||||
{ OP_OPTIONAL, false, "OPTIONAL" },
|
||||
};
|
||||
size_t i;
|
||||
|
||||
type &= ~OP_OPMASK;
|
||||
|
||||
while (type != 0) {
|
||||
tbit = 1 << (ffs(type) - 1);
|
||||
type &= ~tbit;
|
||||
|
||||
switch (tbit) {
|
||||
#define PRINTBIT(bit, attr) case bit: debug_printf(" " attr); break
|
||||
#define PRINTDBIT(bit, attr) case bit: DEBUG0(TARG, " " attr); break
|
||||
PRINTBIT(OP_OPTIONAL, ".OPTIONAL");
|
||||
PRINTBIT(OP_USE, ".USE");
|
||||
PRINTBIT(OP_EXEC, ".EXEC");
|
||||
PRINTBIT(OP_IGNORE, ".IGNORE");
|
||||
PRINTBIT(OP_PRECIOUS, ".PRECIOUS");
|
||||
PRINTBIT(OP_SILENT, ".SILENT");
|
||||
PRINTBIT(OP_MAKE, ".MAKE");
|
||||
PRINTBIT(OP_JOIN, ".JOIN");
|
||||
PRINTBIT(OP_INVISIBLE, ".INVISIBLE");
|
||||
PRINTBIT(OP_NOTMAIN, ".NOTMAIN");
|
||||
PRINTDBIT(OP_LIB, ".LIB");
|
||||
PRINTDBIT(OP_MEMBER, ".MEMBER");
|
||||
PRINTDBIT(OP_ARCHV, ".ARCHV");
|
||||
PRINTDBIT(OP_MADE, ".MADE");
|
||||
PRINTDBIT(OP_PHONY, ".PHONY");
|
||||
#undef PRINTBIT
|
||||
#undef PRINTDBIT
|
||||
for (i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
|
||||
if (type & names[i].bit) {
|
||||
if (names[i].internal)
|
||||
DEBUG1(TARG, " .%s", names[i].name);
|
||||
else
|
||||
debug_printf(" .%s", names[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,13 +481,27 @@ GNode_OpName(const GNode *gn)
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool
|
||||
GNodeFlags_IsNone(GNodeFlags flags)
|
||||
{
|
||||
return !flags.remake
|
||||
&& !flags.childMade
|
||||
&& !flags.force
|
||||
&& !flags.doneWait
|
||||
&& !flags.doneOrder
|
||||
&& !flags.fromDepend
|
||||
&& !flags.doneAllsrc
|
||||
&& !flags.cycle
|
||||
&& !flags.doneCycle;
|
||||
}
|
||||
|
||||
/* Print the contents of a node. */
|
||||
void
|
||||
Targ_PrintNode(GNode *gn, int pass)
|
||||
{
|
||||
debug_printf("# %s%s", gn->name, gn->cohort_num);
|
||||
GNode_FprintDetails(opts.debug_file, ", ", gn, "\n");
|
||||
if (gn->flags == 0)
|
||||
if (GNodeFlags_IsNone(gn->flags))
|
||||
return;
|
||||
|
||||
if (!GNode_IsTarget(gn))
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: trace.c,v 1.28 2021/02/05 05:15:12 rillig Exp $ */
|
||||
/* $NetBSD: trace.c,v 1.29 2021/09/21 23:06:18 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -48,13 +48,13 @@
|
||||
#include "job.h"
|
||||
#include "trace.h"
|
||||
|
||||
MAKE_RCSID("$NetBSD: trace.c,v 1.28 2021/02/05 05:15:12 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: trace.c,v 1.29 2021/09/21 23:06:18 rillig Exp $");
|
||||
|
||||
static FILE *trfile;
|
||||
static pid_t trpid;
|
||||
const char *trwd;
|
||||
|
||||
static const char *evname[] = {
|
||||
static const char evname[][4] = {
|
||||
"BEG",
|
||||
"END",
|
||||
"ERR",
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $Id: Makefile,v 1.148 2021/06/16 19:18:56 sjg Exp $
|
||||
# $Id: Makefile,v 1.164 2021/12/12 22:50:00 sjg Exp $
|
||||
#
|
||||
# $NetBSD: Makefile,v 1.279 2021/06/16 09:39:48 rillig Exp $
|
||||
# $NetBSD: Makefile,v 1.288 2021/12/12 22:16:48 rillig Exp $
|
||||
#
|
||||
# Unit tests for make(1)
|
||||
#
|
||||
@ -167,6 +167,7 @@ TESTS+= directive-for
|
||||
TESTS+= directive-for-errors
|
||||
TESTS+= directive-for-escape
|
||||
TESTS+= directive-for-generating-endif
|
||||
TESTS+= directive-for-if
|
||||
TESTS+= directive-for-lines
|
||||
TESTS+= directive-for-null
|
||||
TESTS+= directive-hyphen-include
|
||||
@ -351,13 +352,16 @@ TESTS+= varmod-indirect
|
||||
TESTS+= varmod-l-name-to-value
|
||||
TESTS+= varmod-localtime
|
||||
TESTS+= varmod-loop
|
||||
TESTS+= varmod-loop-delete
|
||||
TESTS+= varmod-loop-varname
|
||||
TESTS+= varmod-match
|
||||
TESTS+= varmod-match-escape
|
||||
TESTS+= varmod-no-match
|
||||
TESTS+= varmod-order
|
||||
TESTS+= varmod-order-numeric
|
||||
TESTS+= varmod-order-reverse
|
||||
TESTS+= varmod-order-shuffle
|
||||
TESTS+= varmod-order-string
|
||||
TESTS+= varmod-path
|
||||
TESTS+= varmod-quote
|
||||
TESTS+= varmod-quote-dollar
|
||||
@ -415,6 +419,7 @@ TESTS+= varname-dot-parsedir
|
||||
TESTS+= varname-dot-parsefile
|
||||
TESTS+= varname-dot-path
|
||||
TESTS+= varname-dot-shell
|
||||
TESTS+= varname-dot-suffixes
|
||||
TESTS+= varname-dot-targets
|
||||
TESTS+= varname-empty
|
||||
TESTS+= varname-make
|
||||
@ -430,12 +435,41 @@ TESTS+= varparse-mod
|
||||
TESTS+= varparse-undef-partial
|
||||
TESTS+= varquote
|
||||
|
||||
# for now at least
|
||||
.if ${.SHELL:T} == "ksh"
|
||||
BROKEN_TESTS+= sh-flags
|
||||
.endif
|
||||
.if ${.MAKE.OS:NDarwin} == ""
|
||||
BROKEN_TESTS+= shell-ksh
|
||||
.endif
|
||||
.if ${.MAKE.OS} == "SCO_SV"
|
||||
BROKEN_TESTS+= \
|
||||
opt-debug-graph[23] \
|
||||
varmod-localtime \
|
||||
varmod-to-separator \
|
||||
|
||||
.if ${.SHELL:T} == "bash"
|
||||
BROKEN_TESTS+= job-output-null
|
||||
.else
|
||||
BROKEN_TESTS+= \
|
||||
cmd-interrupt \
|
||||
job-flags \
|
||||
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# Some tests just do not work on some platforms or environments
|
||||
# so allow for some filtering.
|
||||
.if !empty(BROKEN_TESTS)
|
||||
.warning Skipping broken tests: ${BROKEN_TESTS:O:u}
|
||||
TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}}
|
||||
.endif
|
||||
|
||||
# Ideas for more tests:
|
||||
# char-0020-space.mk
|
||||
# char-005C-backslash.mk
|
||||
# escape-cond-str.mk
|
||||
# escape-cond-func-arg.mk
|
||||
# escape-cond-func-arg.mk
|
||||
# escape-varmod.mk
|
||||
# escape-varmod-define.mk
|
||||
# escape-varmod-match.mk
|
||||
@ -457,7 +491,7 @@ ENV.envfirst= FROM_ENV=value-from-env
|
||||
ENV.varmisc= FROM_ENV=env
|
||||
ENV.varmisc+= FROM_ENV_BEFORE=env
|
||||
ENV.varmisc+= FROM_ENV_AFTER=env
|
||||
ENV.varmod-localtime+= TZ=Europe/Berlin
|
||||
ENV.varmod-localtime+= TZ=${UTC_1:UEurope/Berlin}
|
||||
ENV.varname-vpath+= VPATH=varname-vpath.dir:varname-vpath.dir2
|
||||
|
||||
# Override make flags for some of the tests; default is -k.
|
||||
@ -490,7 +524,10 @@ SED_CMDS.job-output-long-lines= \
|
||||
${:D marker should always be at the beginning of the line. } \
|
||||
-e '/^aa*--- job-b ---$$/d' \
|
||||
-e '/^bb*--- job-a ---$$/d'
|
||||
SED_CMDS.opt-chdir= -e 's,\(nonexistent\).[1-9][0-9]*,\1,'
|
||||
SED_CMDS.opt-chdir= -e 's,\(nonexistent\).[1-9][0-9]*,\1,' \
|
||||
-e '/name/s,file,File,' \
|
||||
-e 's,no such,No such,' \
|
||||
-e 's,Filename,File name,'
|
||||
SED_CMDS.opt-debug-graph1= ${STD_SED_CMDS.dg1}
|
||||
SED_CMDS.opt-debug-graph2= ${STD_SED_CMDS.dg2}
|
||||
SED_CMDS.opt-debug-graph3= ${STD_SED_CMDS.dg3}
|
||||
@ -511,11 +548,13 @@ SED_CMDS.sh-dots+= -e 's,^make: exec(\(.*\)) failed (.*)$$,<not found: \1>,'
|
||||
SED_CMDS.sh-dots+= -e 's,^\(\*\*\* Error code \)[1-9][0-9]*,\1<nonzero>,'
|
||||
SED_CMDS.sh-errctl= ${STD_SED_CMDS.dj}
|
||||
SED_CMDS.sh-flags= ${STD_SED_CMDS.hide-from-output}
|
||||
SED_CMDS.shell-csh= ${STD_SED_CMDS.white-space}
|
||||
SED_CMDS.suff-main+= ${STD_SED_CMDS.dg1}
|
||||
SED_CMDS.suff-main-several+= ${STD_SED_CMDS.dg1}
|
||||
SED_CMDS.suff-transform-debug+= ${STD_SED_CMDS.dg1}
|
||||
SED_CMDS.var-op-shell+= ${STD_SED_CMDS.shell}
|
||||
SED_CMDS.var-op-shell+= -e '/command/s,No such.*,not found,'
|
||||
SED_CMDS.var-op-shell+= ${STD_SED_CMDS.white-space}
|
||||
SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,'
|
||||
SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
|
||||
SED_CMDS.varname-dot-parsedir= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,'
|
||||
@ -523,9 +562,7 @@ SED_CMDS.varname-dot-parsefile= -e '/in some cases/ s,^make: "[^"]*,make: "<norm
|
||||
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= -e 's,${.CURDIR},<curdir>,g'
|
||||
SED_CMDS.varname-empty+= -e '/\.PARSEDIR/d'
|
||||
SED_CMDS.varname-empty+= -e '/\.SHELL/d'
|
||||
SED_CMDS.varname-empty= ${.OBJDIR .PARSEDIR .PATH .SHELL:L:@v@-e '/\\$v/d'@}
|
||||
|
||||
# Some tests need an additional round of postprocessing.
|
||||
POSTPROC.deptgt-suffixes= awk '/^\#\*\*\* Suffixes/,/^never-stop/'
|
||||
@ -541,7 +578,7 @@ unexport-env.rawout: export.mk
|
||||
# Some standard sed commands, to be used in the SED_CMDS above.
|
||||
|
||||
# Omit details such as process IDs from the output of the -dg1 option.
|
||||
STD_SED_CMDS.dg1= -e 's,${.CURDIR}$$,<curdir>,'
|
||||
STD_SED_CMDS.dg1= -e '/\#.* \.$$/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 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,'
|
||||
@ -597,6 +634,8 @@ 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}: ,,'
|
||||
|
||||
STD_SED_CMDS.white-space= -e 's, *, ,g' -e 's, *$$,,'
|
||||
|
||||
# The actual error messages for a failed regcomp or regexec differ between the
|
||||
# implementations.
|
||||
STD_SED_CMDS.regex= \
|
||||
@ -661,7 +700,8 @@ TMPDIR:= /tmp/uid${.MAKE.UID}
|
||||
x!= echo; mkdir -p ${TMPDIR}
|
||||
.endif
|
||||
|
||||
MAKE_TEST_ENV?= MALLOC_OPTIONS="JA" # for jemalloc
|
||||
MAKE_TEST_ENV= MALLOC_OPTIONS="JA" # for jemalloc 100
|
||||
MAKE_TEST_ENV+= MALLOC_CONF="junk:true" # for jemalloc 510
|
||||
MAKE_TEST_ENV+= TMPDIR=${TMPDIR}
|
||||
|
||||
.if ${.MAKE.OS} == "NetBSD"
|
||||
@ -697,13 +737,22 @@ _SED_CMDS+= -e 's,^usage: ${TEST_MAKE:T:S,.,\\.,g} ,usage: make ,'
|
||||
# replace anything after 'stopped in' with unit-tests
|
||||
_SED_CMDS+= -e '/stopped/s, /.*, unit-tests,'
|
||||
_SED_CMDS+= -e 's,${TMPDIR},TMPDIR,g'
|
||||
# strip ${.CURDIR}/ from the output
|
||||
_SED_CMDS+= -e 's,${.CURDIR:S,.,\\.,g}/,,g'
|
||||
# canonicalize ${.OBJDIR} and ${.CURDIR}
|
||||
.if ${.OBJDIR} != ${.CURDIR}
|
||||
# yes this is inaccurate but none of the tests expect <objdir> anywhere
|
||||
# which we get depending on how MAKEOBJDIR is set.
|
||||
_SED_CMDS+= -e 's,${.OBJDIR},<curdir>,g'
|
||||
.endif
|
||||
_SED_CMDS+= -e 's,${.CURDIR},<curdir>,g'
|
||||
_SED_CMDS+= -e 's,<curdir>/,,g'
|
||||
_SED_CMDS+= -e 's,${UNIT_TESTS:S,.,\\.,g}/,,g'
|
||||
# on AT&T derrived systems; false exits 255 not 1
|
||||
# on AT&T derived systems: false exits 255 not 1
|
||||
.if ${.MAKE.OS:N*BSD} != ""
|
||||
_SED_CMDS+= -e 's,\(Error code\) 255,\1 1,'
|
||||
.endif
|
||||
.if ${.SHELL:T} == "ksh"
|
||||
_SED_CMDS+= -e '/^set [+-]v/d'
|
||||
.endif
|
||||
|
||||
.rawout.out:
|
||||
@${TOOL_SED} ${_SED_CMDS} ${SED_CMDS.${.PREFIX:T}} \
|
||||
|
@ -1,4 +1,6 @@
|
||||
# $Id: Makefile.config.in,v 1.1 2018/12/30 17:14:24 sjg Exp $
|
||||
# $Id: Makefile.config.in,v 1.3 2021/10/22 07:48:57 sjg Exp $
|
||||
|
||||
srcdir= @srcdir@
|
||||
TOOL_DIFF?= @diff@
|
||||
DIFF_FLAGS?= @diff_u@
|
||||
UTC_1= @UTC_1@
|
||||
|
@ -6,6 +6,10 @@ CondParser_Eval: !(${:UNaN} == NaN)
|
||||
lhs = "NaN", rhs = "NaN", op = ==
|
||||
CondParser_Eval: 123 ! 123
|
||||
make: "cond-cmp-numeric.mk" line 34: Malformed conditional (123 ! 123)
|
||||
CondParser_Eval: ${:U 123} < 124
|
||||
lhs = 123.000000, rhs = 124.000000, op = <
|
||||
CondParser_Eval: ${:U123 } < 124
|
||||
make: "cond-cmp-numeric.mk" line 50: String comparison operator must be either == or !=
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-cmp-numeric.mk,v 1.4 2020/11/08 22:56:16 rillig Exp $
|
||||
# $NetBSD: cond-cmp-numeric.mk,v 1.5 2021/07/29 06:31:18 rillig Exp $
|
||||
#
|
||||
# Tests for numeric comparisons in .if conditions.
|
||||
|
||||
@ -37,5 +37,21 @@
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Leading spaces are allowed for numbers.
|
||||
# See EvalCompare and TryParseNumber.
|
||||
.if ${:U 123} < 124
|
||||
.else
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Trailing spaces are NOT allowed for numbers.
|
||||
# See EvalCompare and TryParseNumber.
|
||||
# expect+1: String comparison operator must be either == or !=
|
||||
.if ${:U123 } < 124
|
||||
. error
|
||||
.else
|
||||
. error
|
||||
.endif
|
||||
|
||||
all:
|
||||
@:;
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-cmp-string.mk,v 1.14 2021/01/19 19:54:57 rillig Exp $
|
||||
# $NetBSD: cond-cmp-string.mk,v 1.15 2021/12/11 09:53:53 rillig Exp $
|
||||
#
|
||||
# Tests for string comparisons in .if conditions.
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
# starting point for variable expressions. Applying the :U modifier to such
|
||||
# an undefined expression turns it into a defined expression.
|
||||
#
|
||||
# See ApplyModifier_Defined and VEF_DEF.
|
||||
# See ApplyModifier_Defined and DEF_DEFINED.
|
||||
.if ${:Ustr} != "str"
|
||||
. error
|
||||
.endif
|
||||
|
@ -1,8 +1,5 @@
|
||||
side effect
|
||||
make: "cond-eof.mk" line 15: Malformed conditional (0 ${SIDE_EFFECT} ${SIDE_EFFECT2})
|
||||
side effect
|
||||
make: "cond-eof.mk" line 17: Malformed conditional (1 ${SIDE_EFFECT} ${SIDE_EFFECT2})
|
||||
side effect
|
||||
make: "cond-eof.mk" line 19: Malformed conditional ((0) ${SIDE_EFFECT} ${SIDE_EFFECT2})
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-eof.mk,v 1.2 2020/12/14 20:28:09 rillig Exp $
|
||||
# $NetBSD: cond-eof.mk,v 1.3 2021/12/10 23:12:44 rillig Exp $
|
||||
#
|
||||
# Tests for parsing conditions, especially the end of such conditions, which
|
||||
# are represented as the token TOK_EOF.
|
||||
@ -7,11 +7,11 @@ SIDE_EFFECT= ${:!echo 'side effect' 1>&2!}
|
||||
SIDE_EFFECT2= ${:!echo 'side effect 2' 1>&2!}
|
||||
|
||||
# In the following conditions, ${SIDE_EFFECT} is the position of the first
|
||||
# parse error. It is always fully evaluated, even if it were not necessary
|
||||
# to expand the variable expression. This is because these syntax errors are
|
||||
# an edge case that does not occur during normal operation, therefore there
|
||||
# is no need to optimize for this case, and it would slow down the common
|
||||
# case as well.
|
||||
# parse error. Before cond.c 1.286 from 2021-12-10, it was always fully
|
||||
# evaluated, even if it was not necessary to expand the variable expression.
|
||||
# These syntax errors are an edge case that does not occur during normal
|
||||
# operation. Still, it is easy to avoid evaluating these expressions, just in
|
||||
# case they have side effects.
|
||||
.if 0 ${SIDE_EFFECT} ${SIDE_EFFECT2}
|
||||
.endif
|
||||
.if 1 ${SIDE_EFFECT} ${SIDE_EFFECT2}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-func-defined.mk,v 1.7 2020/11/15 14:07:53 rillig Exp $
|
||||
# $NetBSD: cond-func-defined.mk,v 1.8 2021/12/12 08:55:28 rillig Exp $
|
||||
#
|
||||
# Tests for the defined() function in .if conditions.
|
||||
|
||||
@ -29,7 +29,7 @@ ${:UA B}= variable name with spaces
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Parse error: missing closing parenthesis; see ParseFuncArg.
|
||||
# Parse error: missing closing parenthesis; see ParseWord.
|
||||
.if defined(DEF
|
||||
. error
|
||||
.else
|
||||
|
@ -1,5 +1,5 @@
|
||||
make: "cond-func-empty.mk" line 152: Unclosed variable "WORD"
|
||||
make: "cond-func-empty.mk" line 152: Malformed conditional (empty(WORD)
|
||||
make: "cond-func-empty.mk" line 149: Unclosed variable "WORD"
|
||||
make: "cond-func-empty.mk" line 149: Malformed conditional (empty(WORD)
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
# $NetBSD: cond-func-empty.mk,v 1.14 2021/04/11 13:35:56 rillig Exp $
|
||||
# $NetBSD: cond-func-empty.mk,v 1.16 2021/12/11 10:41:31 rillig Exp $
|
||||
#
|
||||
# Tests for the empty() function in .if conditions, which tests a variable
|
||||
# expression for emptiness.
|
||||
#
|
||||
# Note that the argument in the parentheses is indeed a variable name,
|
||||
# optionally followed by variable modifiers.
|
||||
# Note that the argument in the parentheses is a variable name, not a variable
|
||||
# expression, optionally followed by variable modifiers.
|
||||
#
|
||||
|
||||
.undef UNDEF
|
||||
@ -25,14 +25,10 @@ WORD= word
|
||||
.endif
|
||||
|
||||
# The :S modifier replaces the empty value with an actual word. The
|
||||
# expression is now no longer empty, but it is still possible to see whether
|
||||
# the expression was based on an undefined variable. The expression has the
|
||||
# flag VEF_UNDEF.
|
||||
#
|
||||
# The expression does not have the flag VEF_DEF though, therefore it is still
|
||||
# considered undefined. Yes, indeed, undefined but not empty. There are a
|
||||
# few variable modifiers that turn an undefined expression into a defined
|
||||
# expression, among them :U and :D, but not :S.
|
||||
# expression is now no longer empty, but it is still based on an undefined
|
||||
# variable (DEF_UNDEF). There are a few variable modifiers that turn an
|
||||
# undefined expression into a defined expression, among them :U and :D, but
|
||||
# not :S.
|
||||
#
|
||||
# XXX: This is hard to explain to someone who doesn't know these
|
||||
# implementation details.
|
||||
@ -41,19 +37,19 @@ WORD= word
|
||||
. error
|
||||
.endif
|
||||
|
||||
# The :U modifier modifies expressions based on undefined variables
|
||||
# (DEF_UNDEF) by adding the DEF_DEFINED flag, which marks the expression
|
||||
# as "being interesting enough to be further processed".
|
||||
# The :U modifier changes the state of a previously undefined expression from
|
||||
# DEF_UNDEF to DEF_DEFINED. This marks the expression as "being interesting
|
||||
# enough to be further processed".
|
||||
#
|
||||
.if empty(UNDEF:S,^$,value,W:Ufallback)
|
||||
. error
|
||||
.endif
|
||||
|
||||
# And now to the surprising part. Applying the following :S modifier to the
|
||||
# undefined expression makes it non-empty, but the marker VEF_UNDEF is
|
||||
# preserved nevertheless. The :U modifier that follows only looks at the
|
||||
# VEF_UNDEF flag to decide whether the variable is defined or not. This kind
|
||||
# of makes sense since the :U modifier tests the _variable_, not the
|
||||
# undefined expression makes it non-empty, but the expression is still in
|
||||
# state DEF_UNDEF. The :U modifier that follows only looks at the state
|
||||
# DEF_UNDEF to decide whether the variable is defined or not. This kind of
|
||||
# makes sense since the :U modifier tests the _variable_, not the
|
||||
# _expression_.
|
||||
#
|
||||
# But since the variable was undefined to begin with, the fallback value from
|
||||
@ -78,12 +74,13 @@ WORD= word
|
||||
. error
|
||||
.endif
|
||||
|
||||
# The empty variable named "" gets a fallback value of " ", which counts as
|
||||
# empty.
|
||||
# The following example constructs an expression with the variable name ""
|
||||
# and the value " ". This expression counts as empty since the value contains
|
||||
# only whitespace.
|
||||
#
|
||||
# Contrary to the other functions in conditionals, the trailing space is not
|
||||
# stripped off, as can be seen in the -dv debug log. If the space had been
|
||||
# stripped, it wouldn't make a difference in this case.
|
||||
# stripped, it wouldn't make a difference in this case, but in other cases.
|
||||
#
|
||||
.if !empty(:U )
|
||||
. error
|
||||
@ -92,8 +89,8 @@ WORD= word
|
||||
# Now the variable named " " gets a non-empty value, which demonstrates that
|
||||
# neither leading nor trailing spaces are trimmed in the argument of the
|
||||
# function. If the spaces were trimmed, the variable name would be "" and
|
||||
# that variable is indeed undefined. Since ParseEmptyArg calls Var_Parse
|
||||
# without VARE_UNDEFERR, the value of the undefined variable is
|
||||
# that variable is indeed undefined. Since CondParser_FuncCallEmpty calls
|
||||
# Var_Parse without VARE_UNDEFERR, the value of the undefined variable is
|
||||
# returned as an empty string.
|
||||
${:U }= space
|
||||
.if empty( )
|
||||
@ -129,8 +126,8 @@ ${:U }= space
|
||||
#
|
||||
# If everything goes well, the argument expands to "WORD", and that variable
|
||||
# is defined at the beginning of this file. The surrounding 'W' and 'D'
|
||||
# ensure that the parser in ParseEmptyArg has the correct position, both
|
||||
# before and after the call to Var_Parse.
|
||||
# ensure that CondParser_FuncCallEmpty keeps track of the parsing position,
|
||||
# both before and after the call to Var_Parse.
|
||||
.if empty(W${:UOR}D)
|
||||
. error
|
||||
.endif
|
||||
@ -155,17 +152,29 @@ ${:U WORD }= variable name with spaces
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Between 2020-06-28 and var.c 1.226 from 2020-07-02, this paragraph generated
|
||||
# a wrong error message "Variable VARNAME is recursive".
|
||||
# Since cond.c 1.76 from 2020-06-28 and before var.c 1.226 from 2020-07-02,
|
||||
# the following example generated a wrong error message "Variable VARNAME is
|
||||
# recursive".
|
||||
#
|
||||
# The bug was that the !empty() condition was evaluated, even though this was
|
||||
# not necessary since the defined() condition already evaluated to false.
|
||||
# Since at least 1993, the manual page claimed that irrelevant parts of
|
||||
# conditions were not evaluated, but that was wrong for a long time. The
|
||||
# expressions in irrelevant parts of the condition were actually evaluated,
|
||||
# they just allowed undefined variables to be used in the conditions, and the
|
||||
# result of evaluating them was not used further. These unnecessary
|
||||
# evaluations were fixed in several commits, starting with var.c 1.226 from
|
||||
# 2020-07-02.
|
||||
#
|
||||
# In this example, the variable "VARNAME2" is not defined, so evaluation of
|
||||
# the condition should have stopped at this point, and the rest of the
|
||||
# condition should have been processed in parse-only mode. The right-hand
|
||||
# side containing the '!empty' was evaluated though, as it had always been.
|
||||
#
|
||||
# When evaluating the !empty condition, the variable name was parsed as
|
||||
# "VARNAME${:U2}", but without expanding any nested variable expression, in
|
||||
# this case the ${:U2}. Therefore, the variable name came out as simply
|
||||
# "VARNAME". Since this variable name should have been discarded quickly after
|
||||
# parsing it, this unrealistic variable name should have done no harm.
|
||||
# this case the ${:U2}. The expression '${:U2}' was replaced with an empty
|
||||
# string, the resulting variable name was thus "VARNAME". This conceptually
|
||||
# wrong variable name should have been discarded quickly after parsing it, to
|
||||
# prevent it from doing any harm.
|
||||
#
|
||||
# The variable expression was expanded though, and this was wrong. The
|
||||
# expansion was done without VARE_WANTRES (called VARF_WANTRES back
|
||||
|
@ -6,7 +6,7 @@ make: "cond-func.mk" line 102: A plain function name is parsed as !empty(...).
|
||||
make: "cond-func.mk" line 109: A plain function name is parsed as !empty(...).
|
||||
make: "cond-func.mk" line 119: Symbols may start with a function name.
|
||||
make: "cond-func.mk" line 124: Symbols may start with a function name.
|
||||
make: "cond-func.mk" line 130: Malformed conditional (defined()
|
||||
make: "cond-func.mk" line 130: Missing closing parenthesis for defined()
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,7 @@
|
||||
make: "cond-op-and.mk" line 43: Malformed conditional (0 &&& 0)
|
||||
make: "cond-op-and.mk" line 36: Malformed conditional (0 || (${DEF} && ${UNDEF}))
|
||||
make: "cond-op-and.mk" line 40: Malformed conditional (0 || (${UNDEF} && ${UNDEF}))
|
||||
make: "cond-op-and.mk" line 42: Malformed conditional (0 || (!${UNDEF} && ${UNDEF}))
|
||||
make: "cond-op-and.mk" line 71: Malformed conditional (0 &&& 0)
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-op-and.mk,v 1.5 2020/10/24 08:46:08 rillig Exp $
|
||||
# $NetBSD: cond-op-and.mk,v 1.6 2021/12/10 19:14:35 rillig Exp $
|
||||
#
|
||||
# Tests for the && operator in .if conditions.
|
||||
|
||||
@ -18,11 +18,39 @@
|
||||
. error
|
||||
.endif
|
||||
|
||||
|
||||
# The right-hand side is not evaluated since the left-hand side is already
|
||||
# false.
|
||||
.if 0 && ${UNDEF}
|
||||
.endif
|
||||
|
||||
# When an outer condition makes the inner '&&' condition irrelevant, neither
|
||||
# of its operands must be evaluated.
|
||||
#
|
||||
.if 1 || (${UNDEF} && ${UNDEF})
|
||||
.endif
|
||||
|
||||
# Test combinations of outer '||' with inner '&&', to ensure that the operands
|
||||
# of the inner '&&' are only evaluated if necessary.
|
||||
DEF= defined
|
||||
.if 0 || (${DEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 0 || (!${DEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 0 || (${UNDEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 0 || (!${UNDEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 1 || (${DEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 1 || (!${DEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 1 || (${UNDEF} && ${UNDEF})
|
||||
.endif
|
||||
.if 1 || (!${UNDEF} && ${UNDEF})
|
||||
.endif
|
||||
|
||||
|
||||
# The && operator may be abbreviated as &. This is not widely known though
|
||||
# and is also not documented in the manual page.
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
make: "cond-op-or.mk" line 43: Malformed conditional (0 ||| 0)
|
||||
make: "cond-op-or.mk" line 46: Malformed conditional (1 && (!${DEF} || ${UNDEF}))
|
||||
make: "cond-op-or.mk" line 48: Malformed conditional (1 && (${UNDEF} || ${UNDEF}))
|
||||
make: "cond-op-or.mk" line 50: Malformed conditional (1 && (!${UNDEF} || ${UNDEF}))
|
||||
make: "cond-op-or.mk" line 71: Malformed conditional (0 ||| 0)
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-op-or.mk,v 1.6 2020/10/24 08:46:08 rillig Exp $
|
||||
# $NetBSD: cond-op-or.mk,v 1.8 2021/12/10 19:14:35 rillig Exp $
|
||||
#
|
||||
# Tests for the || operator in .if conditions.
|
||||
|
||||
@ -18,11 +18,39 @@
|
||||
. error
|
||||
.endif
|
||||
|
||||
|
||||
# The right-hand side is not evaluated since the left-hand side is already
|
||||
# true.
|
||||
.if 1 || ${UNDEF}
|
||||
.endif
|
||||
|
||||
# When an outer condition makes the inner '||' condition irrelevant, neither
|
||||
# of its operands must be evaluated. This had been wrong in cond.c 1.283 from
|
||||
# 2021-12-09 and was reverted in cond.c 1.284 an hour later.
|
||||
.if 0 && (!defined(UNDEF) || ${UNDEF})
|
||||
.endif
|
||||
|
||||
# Test combinations of outer '&&' with inner '||', to ensure that the operands
|
||||
# of the inner '||' is only evaluated if necessary.
|
||||
DEF= defined
|
||||
.if 0 && (${DEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 0 && (!${DEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 0 && (${UNDEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 0 && (!${UNDEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 1 && (${DEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 1 && (!${DEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 1 && (${UNDEF} || ${UNDEF})
|
||||
.endif
|
||||
.if 1 && (!${UNDEF} || ${UNDEF})
|
||||
.endif
|
||||
|
||||
|
||||
# The || operator may be abbreviated as |. This is not widely known though
|
||||
# and is also not documented in the manual page.
|
||||
|
||||
|
@ -1,20 +1,22 @@
|
||||
make: "cond-op.mk" line 50: Malformed conditional ("!word" == !word)
|
||||
make: "cond-op.mk" line 75: Malformed conditional (0 ${ERR::=evaluated})
|
||||
make: "cond-op.mk" line 79: After detecting a parse error, the rest is evaluated.
|
||||
make: "cond-op.mk" line 83: Parsing continues until here.
|
||||
make: "cond-op.mk" line 86: A B C => (A || B) && C A || B && C A || (B && C)
|
||||
make: "cond-op.mk" line 93: 0 0 0 => 0 0 0
|
||||
make: "cond-op.mk" line 93: 0 0 1 => 0 0 0
|
||||
make: "cond-op.mk" line 93: 0 1 0 => 0 0 0
|
||||
make: "cond-op.mk" line 93: 0 1 1 => 1 1 1
|
||||
make: "cond-op.mk" line 93: 1 0 0 => 0 1 1
|
||||
make: "cond-op.mk" line 93: 1 0 1 => 1 1 1
|
||||
make: "cond-op.mk" line 93: 1 1 0 => 0 1 1
|
||||
make: "cond-op.mk" line 93: 1 1 1 => 1 1 1
|
||||
make: "cond-op.mk" line 104: Malformed conditional (1 &&)
|
||||
make: "cond-op.mk" line 112: Malformed conditional (0 &&)
|
||||
make: "cond-op.mk" line 120: Malformed conditional (1 ||)
|
||||
make: "cond-op.mk" line 129: Malformed conditional (0 ||)
|
||||
make: "cond-op.mk" line 76: Malformed conditional (0 ${ERR::=evaluated})
|
||||
make: "cond-op.mk" line 80: A misplaced expression after 0 is not evaluated.
|
||||
make: "cond-op.mk" line 84: Malformed conditional (1 ${ERR::=evaluated})
|
||||
make: "cond-op.mk" line 88: A misplaced expression after 1 is not evaluated.
|
||||
make: "cond-op.mk" line 92: Parsing continues until here.
|
||||
make: "cond-op.mk" line 95: A B C => (A || B) && C A || B && C A || (B && C)
|
||||
make: "cond-op.mk" line 102: 0 0 0 => 0 0 0
|
||||
make: "cond-op.mk" line 102: 0 0 1 => 0 0 0
|
||||
make: "cond-op.mk" line 102: 0 1 0 => 0 0 0
|
||||
make: "cond-op.mk" line 102: 0 1 1 => 1 1 1
|
||||
make: "cond-op.mk" line 102: 1 0 0 => 0 1 1
|
||||
make: "cond-op.mk" line 102: 1 0 1 => 1 1 1
|
||||
make: "cond-op.mk" line 102: 1 1 0 => 0 1 1
|
||||
make: "cond-op.mk" line 102: 1 1 1 => 1 1 1
|
||||
make: "cond-op.mk" line 113: Malformed conditional (1 &&)
|
||||
make: "cond-op.mk" line 121: Malformed conditional (0 &&)
|
||||
make: "cond-op.mk" line 129: Malformed conditional (1 ||)
|
||||
make: "cond-op.mk" line 138: Malformed conditional (0 ||)
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-op.mk,v 1.13 2021/01/19 18:20:30 rillig Exp $
|
||||
# $NetBSD: cond-op.mk,v 1.15 2021/12/10 23:12:44 rillig Exp $
|
||||
#
|
||||
# Tests for operators like &&, ||, ! in .if conditions.
|
||||
#
|
||||
@ -58,25 +58,34 @@
|
||||
. error
|
||||
.endif
|
||||
|
||||
# As soon as the parser sees the '$', it knows that the condition will
|
||||
# be malformed. Therefore there is no point in evaluating it.
|
||||
# In the following malformed conditions, as soon as the parser sees the '$'
|
||||
# after the '0' or the '1', it knows that the condition will be malformed.
|
||||
# Therefore there is no point in evaluating the misplaced expression.
|
||||
#
|
||||
# As of 2021-01-20, that part of the condition is evaluated nevertheless,
|
||||
# since CondParser_Or just requests the next token, without restricting
|
||||
# the token to the expected tokens. If the parser were to restrict the
|
||||
# valid follow tokens for the token "0" to those that can actually produce
|
||||
# a correct condition (which in this case would be comparison operators,
|
||||
# TOK_AND, TOK_OR or TOK_RPAREN), the variable expression would not have
|
||||
# to be evaluated.
|
||||
# Before cond.c 1.286 from 2021-12-10, the extra expression was evaluated
|
||||
# nevertheless, since CondParser_Or and CondParser_And asked for the expanded
|
||||
# next token, even though in this position of the condition, only comparison
|
||||
# operators, TOK_AND, TOK_OR or TOK_RPAREN are allowed.
|
||||
#
|
||||
# This would add a good deal of complexity to the code though, for almost
|
||||
# no benefit, especially since most expressions and conditions are side
|
||||
# effect free.
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
.undef ERR
|
||||
.if 0 ${ERR::=evaluated}
|
||||
. error
|
||||
.endif
|
||||
.if ${ERR:Uundefined} == evaluated
|
||||
. info After detecting a parse error, the rest is evaluated.
|
||||
.if ${ERR:Uundefined} == undefined
|
||||
. info A misplaced expression after 0 is not evaluated.
|
||||
.endif
|
||||
|
||||
.undef ERR
|
||||
.if 1 ${ERR::=evaluated}
|
||||
. error
|
||||
.endif
|
||||
.if ${ERR:Uundefined} == undefined
|
||||
. info A misplaced expression after 1 is not evaluated.
|
||||
.endif
|
||||
|
||||
# Just in case that parsing should ever stop on the first error.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: cond-short.mk,v 1.16 2021/03/14 11:49:37 rillig Exp $
|
||||
# $NetBSD: cond-short.mk,v 1.18 2021/12/12 09:49:09 rillig Exp $
|
||||
#
|
||||
# Demonstrates that in conditions, the right-hand side of an && or ||
|
||||
# is only evaluated if it can actually influence the result.
|
||||
@ -12,7 +12,20 @@
|
||||
# possible to skip evaluation of irrelevant variable expressions and only
|
||||
# parse them. They were still evaluated though, the only difference to
|
||||
# relevant variable expressions was that in the irrelevant variable
|
||||
# expressions, undefined variables were allowed.
|
||||
# expressions, undefined variables were allowed. This allowed for conditions
|
||||
# like 'defined(VAR) && ${VAR:S,from,to,} != ""', which no longer produced an
|
||||
# error message 'Malformed conditional', but it still evaluated the
|
||||
# expression, even though the expression was irrelevant.
|
||||
#
|
||||
# Since the initial commit on 1993-03-21, the manual page has been saying that
|
||||
# make 'will only evaluate a conditional as far as is necessary to determine',
|
||||
# but that was wrong. The code in cond.c 1.1 from 1993-03-21 looks good since
|
||||
# it calls Var_Parse(condExpr, VAR_CMD, doEval,&varSpecLen,&doFree), but the
|
||||
# definition of Var_Parse does not call the third parameter 'doEval', as would
|
||||
# be expected, but instead 'err', accompanied by the comment 'TRUE if
|
||||
# undefined variables are an error'. This subtle difference between 'do not
|
||||
# evaluate at all' and 'allow undefined variables' led to the unexpected
|
||||
# evaluation.
|
||||
#
|
||||
# See also:
|
||||
# var-eval-short.mk, for short-circuited variable modifiers
|
||||
@ -211,4 +224,56 @@ x!= echo '0 || $${iV2:U2} < $${V42}: $x' >&2; echo
|
||||
. error
|
||||
.endif
|
||||
|
||||
|
||||
# Ensure that irrelevant conditions do not influence the result of the whole
|
||||
# condition. As of cond.c 1.302 from 2021-12-11, an irrelevant function call
|
||||
# evaluates to true (see CondParser_FuncCall and CondParser_FuncCallEmpty), an
|
||||
# irrelevant comparison evaluates to false (see CondParser_Comparison).
|
||||
#
|
||||
# An irrelevant true bubbles up to the outermost CondParser_And, where it is
|
||||
# ignored. An irrelevant false bubbles up to the outermost CondParser_Or,
|
||||
# where it is ignored.
|
||||
#
|
||||
# If the condition parser should ever be restructured, the bubbling up of the
|
||||
# irrelevant evaluation results might show up accidentally. Prevent this.
|
||||
DEF= defined
|
||||
.undef UNDEF
|
||||
|
||||
.if 0 && defined(DEF)
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 1 && defined(DEF)
|
||||
.else
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 0 && defined(UNDEF)
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 1 && defined(UNDEF)
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 0 || defined(DEF)
|
||||
.else
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 1 || defined(DEF)
|
||||
.else
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 0 || defined(UNDEF)
|
||||
. error
|
||||
.endif
|
||||
|
||||
.if 1 || defined(UNDEF)
|
||||
.else
|
||||
. error
|
||||
.endif
|
||||
|
||||
|
||||
all:
|
||||
|
@ -27,28 +27,35 @@ lhs = "var&&name", rhs = "var&&name", op = !=
|
||||
CondParser_Eval: ${:Uvar}||name != "var||name"
|
||||
lhs = "var||name", rhs = "var||name", op = !=
|
||||
CondParser_Eval: bare
|
||||
make: "cond-token-plain.mk" line 102: A bare word is treated like defined(...), and the variable 'bare' is not defined.
|
||||
make: "cond-token-plain.mk" line 106: A bare word is treated like defined(...), and the variable 'bare' is not defined.
|
||||
CondParser_Eval: VAR
|
||||
make: "cond-token-plain.mk" line 107: A bare word is treated like defined(...).
|
||||
make: "cond-token-plain.mk" line 111: A bare word is treated like defined(...).
|
||||
CondParser_Eval: V${:UA}R
|
||||
make: "cond-token-plain.mk" line 114: ok
|
||||
make: "cond-token-plain.mk" line 118: ok
|
||||
CondParser_Eval: V${UNDEF}AR
|
||||
make: "cond-token-plain.mk" line 122: Undefined variables in bare words expand to an empty string.
|
||||
make: "cond-token-plain.mk" line 126: Undefined variables in bare words expand to an empty string.
|
||||
CondParser_Eval: 0${:Ux00}
|
||||
make: "cond-token-plain.mk" line 130: Numbers can be composed from literals and variable expressions.
|
||||
CondParser_Eval: 0${:Ux01}
|
||||
make: "cond-token-plain.mk" line 134: Numbers can be composed from literals and variable expressions.
|
||||
CondParser_Eval: 0${:Ux01}
|
||||
make: "cond-token-plain.mk" line 138: Numbers can be composed from literals and variable expressions.
|
||||
CondParser_Eval: "" ==
|
||||
make: "cond-token-plain.mk" line 140: Missing right-hand-side of operator '=='
|
||||
make: "cond-token-plain.mk" line 144: Missing right-hand side of operator '=='
|
||||
CondParser_Eval: == ""
|
||||
make: "cond-token-plain.mk" line 148: Malformed conditional (== "")
|
||||
make: "cond-token-plain.mk" line 152: Malformed conditional (== "")
|
||||
CondParser_Eval: \\
|
||||
make: "cond-token-plain.mk" line 163: The variable '\\' is not defined.
|
||||
make: "cond-token-plain.mk" line 167: The variable '\\' is not defined.
|
||||
CondParser_Eval: \\
|
||||
make: "cond-token-plain.mk" line 168: Now the variable '\\' is defined.
|
||||
make: "cond-token-plain.mk" line 172: Now the variable '\\' is defined.
|
||||
CondParser_Eval: "unquoted\"quoted" != unquoted"quoted
|
||||
lhs = "unquoted"quoted", rhs = "unquoted"quoted", op = !=
|
||||
CondParser_Eval: $$$$$$$$ != ""
|
||||
CondParser_Eval: left == right
|
||||
make: "cond-token-plain.mk" line 195: Malformed conditional (left == right)
|
||||
CondParser_Eval: ${0:?:} || left == right
|
||||
CondParser_Eval: 0
|
||||
make: "cond-token-plain.mk" line 201: Malformed conditional (${0:?:} || left == right)
|
||||
CondParser_Eval: left == right || ${0:?:}
|
||||
make: "cond-token-plain.mk" line 206: Malformed conditional (left == right || ${0:?:})
|
||||
make: Fatal errors encountered -- cannot continue
|
||||
make: stopped in unit-tests
|
||||
exit status 1
|
||||
|
@ -1,17 +1,18 @@
|
||||
# $NetBSD: cond-token-plain.mk,v 1.10 2021/01/21 14:08:09 rillig Exp $
|
||||
# $NetBSD: cond-token-plain.mk,v 1.14 2021/12/12 09:36:00 rillig Exp $
|
||||
#
|
||||
# Tests for plain tokens (that is, string literals without quotes)
|
||||
# in .if conditions.
|
||||
# in .if conditions. These are also called bare words.
|
||||
|
||||
.MAKEFLAGS: -dc
|
||||
|
||||
# The word 'value' after the '!=' is a bare word.
|
||||
.if ${:Uvalue} != value
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Malformed condition since comment parsing is done in an early phase
|
||||
# and removes the '#' and everything behind it long before the condition
|
||||
# parser gets to see it.
|
||||
# Using a '#' in a string literal in a condition leads to a malformed
|
||||
# condition since comment parsing is done in an early phase and removes the
|
||||
# '#' and everything after it long before the condition parser gets to see it.
|
||||
#
|
||||
# XXX: The error message is missing for this malformed condition.
|
||||
# The right-hand side of the comparison is just a '"', before unescaping.
|
||||
@ -32,7 +33,10 @@
|
||||
# in a very early parsing phase.
|
||||
#
|
||||
# See https://gnats.netbsd.org/19596 for example makefiles demonstrating the
|
||||
# original problems. This workaround is probably not needed anymore.
|
||||
# original problems. At that time, the parser didn't recognize the comment in
|
||||
# the line '.else # comment3'. This workaround is not needed anymore since
|
||||
# comments are stripped in an earlier phase. See "case '#'" in
|
||||
# CondParser_Token.
|
||||
#
|
||||
# XXX: Missing error message for the malformed condition. The right-hand
|
||||
# side before unescaping is double-quotes, backslash, backslash.
|
||||
@ -152,7 +156,7 @@ VAR= defined
|
||||
.endif
|
||||
|
||||
# The '\\' is not a line continuation. Neither is it an unquoted string
|
||||
# literal. Instead, it is parsed as a function argument (ParseFuncArg),
|
||||
# literal. Instead, it is parsed as a bare word (ParseWord),
|
||||
# and in that context, the backslash is just an ordinary character. The
|
||||
# function argument thus stays '\\' (2 backslashes). This string is passed
|
||||
# to FuncDefined, and since there is no variable named '\\', the condition
|
||||
@ -185,6 +189,23 @@ ${:U\\\\}= backslash
|
||||
. error
|
||||
.endif
|
||||
|
||||
# In a condition in an .if directive, the left-hand side must not be an
|
||||
# unquoted string literal.
|
||||
# expect+1: Malformed conditional (left == right)
|
||||
.if left == right
|
||||
.endif
|
||||
# Before cond.c 1.276 from 2021-09-21, a variable expression containing the
|
||||
# modifier ':?:' allowed unquoted string literals for the rest of the
|
||||
# condition. This was an unintended implementation mistake.
|
||||
# expect+1: Malformed conditional (${0:?:} || left == right)
|
||||
.if ${0:?:} || left == right
|
||||
.endif
|
||||
# This affected only the comparisons after the expression, so the following
|
||||
# was still a syntax error.
|
||||
# expect+1: Malformed conditional (left == right || ${0:?:})
|
||||
.if left == right || ${0:?:}
|
||||
.endif
|
||||
|
||||
# See cond-token-string.mk for similar tests where the condition is enclosed
|
||||
# in "quotes".
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
Default command is making 'not-a-target' from 'not-a-target'.
|
||||
exit status 0
|
||||
|
@ -1,8 +1,17 @@
|
||||
# $NetBSD: deptgt-default.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
|
||||
# $NetBSD: deptgt-default.mk,v 1.3 2021/12/01 23:56:29 rillig Exp $
|
||||
#
|
||||
# Tests for the special target .DEFAULT in dependency declarations.
|
||||
# Tests for the special target .DEFAULT in dependency declarations, which
|
||||
# attaches its associated commands to all targets that don't specify any way
|
||||
# to create them.
|
||||
|
||||
# TODO: Implementation
|
||||
all: test-default not-a-target
|
||||
|
||||
test-default: .PHONY
|
||||
|
||||
has-commands: .PHONY
|
||||
@echo 'Making ${.TARGET} from ${.IMPSRC}.'
|
||||
|
||||
.DEFAULT: dependency-is-ignored
|
||||
@echo "Default command is making '${.TARGET}' from '${.IMPSRC}'."
|
||||
|
||||
all:
|
||||
@:;
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: deptgt-makeflags.mk,v 1.6 2020/11/15 20:20:58 rillig Exp $
|
||||
# $NetBSD: deptgt-makeflags.mk,v 1.7 2021/11/29 00:17:10 rillig Exp $
|
||||
#
|
||||
# Tests for the special target .MAKEFLAGS in dependency declarations,
|
||||
# which adds command line options later, at parse time.
|
||||
@ -65,7 +65,7 @@
|
||||
.endif
|
||||
|
||||
# Next try at defining another newline variable. Since whitespace around the
|
||||
# variable value is trimmed, two empty variable expressions surround the
|
||||
# variable value is trimmed, two empty variable expressions ${:U} surround the
|
||||
# literal newline now. This prevents the newline from being skipped during
|
||||
# parsing. The ':=' assignment operator expands the empty variable
|
||||
# expressions, leaving only the newline as the variable value.
|
||||
@ -81,6 +81,31 @@
|
||||
.endif
|
||||
#.MAKEFLAGS: -d0
|
||||
|
||||
# Now do the same for the other escape sequences; see Substring_Words.
|
||||
.MAKEFLAGS: CHAR_BS:="$${:U}\b$${:U}"
|
||||
.MAKEFLAGS: CHAR_FF:="$${:U}\f$${:U}"
|
||||
.MAKEFLAGS: CHAR_NL:="$${:U}\n$${:U}"
|
||||
.MAKEFLAGS: CHAR_CR:="$${:U}\r$${:U}"
|
||||
.MAKEFLAGS: CHAR_TAB:="$${:U}\t$${:U}"
|
||||
|
||||
# Note: backspace is not whitespace, it is a control character.
|
||||
.if ${CHAR_BS:C,^[[:cntrl:]]$,found,W} != "found"
|
||||
. error
|
||||
.endif
|
||||
.if ${CHAR_FF:C,^[[:space:]]$,found,W} != "found"
|
||||
. error
|
||||
.endif
|
||||
.if ${CHAR_NL:C,^[[:space:]]$,found,W} != "found"
|
||||
. error
|
||||
.endif
|
||||
.if ${CHAR_CR:C,^[[:space:]]$,found,W} != "found"
|
||||
. error
|
||||
.endif
|
||||
.if ${CHAR_TAB:C,^[[:space:]]$,found,W} != "found"
|
||||
. error
|
||||
.endif
|
||||
|
||||
|
||||
# Unbalanced quotes produce an error message. If they occur anywhere in the
|
||||
# command line, the whole command line is skipped.
|
||||
.MAKEFLAGS: VAR=previous
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user