Merge bmake-20230909

Merge commit '1012cf15f75d1e9048779abd07270a37cdba590a'
This commit is contained in:
Simon J. Gerraty 2023-09-17 18:05:19 -07:00
commit 9887588385
81 changed files with 1307 additions and 406 deletions

View file

@ -1,3 +1,81 @@
2023-09-09 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230909
Merge with NetBSD make, pick up
o main.c: allow -j to compute a multiple of ncpu
If _SC_NPROCESSORS_ONLN is supported; and -j arg is a floating
point number or ends in 'C' compute .MAKE.JOBS as a multiple of
_SC_NPROCESSORS_ONLN
.MAKE.JOBS.C will be "yes" if -jC is supported
2023-08-20 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230820
Merge with NetBSD make, pick up
o make.1: note that :localtime is better for %s
o parse.c: improve error messages for invalid input.
o var.c: fix for %s:L:gmtime - set TZ=UTC and use localtime to get
correct result, it is still better to use %s:L:localtime.
2023-08-18 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230818
Merge with NetBSD make, pick up
o meta.c: meta_ignore - check raw path against metaIgnorePaths
to potentially skip call to realpath.
o var.c: be strict when parsing the argument of the ':mtime' modifier
o unit-tests/varmod-mtime.mk: document why '${%s:L:localtime}'
should be used to get an equivalent value to time(3).
2023-08-16 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230816
Merge with NetBSD make, pick up
o cond.c: clean up multiple-inclusion guards
2023-07-25 Simon J Gerraty <sjg@beast.crufty.net>
* unit-tests/Makefile: addd varmod-localtime to BROKEN_TESTS
if configure cannot work out how to control TZ.
Remove varmod-localtime from BROKEN_TESTS for IRIX*
2023-07-24 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230723
* configure.in: fix the test for wether TZ=Europe/Berlin works.
Depending on the time of year, if run between 22:00 and 00:00 UTC
the check in configure would fail incorrectly.
Take the day into account as well.
2023-07-18 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230711
Merge with NetBSD make, pick up
o make.1: clean up wording, clarify scope of '!' in conditions
2023-07-15 Simon J Gerraty <sjg@beast.crufty.net>
* make-bootstrap.sh.in: set prefix
If configure is run using ksh we get unexpanded ${prefix} in
DEFAULT_SYS_PATH, by ensuring prefix is set we should still get
correct result.
2023-07-13 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230711
bump version for IRIX tweaks
* make.h: undef OP_NONE if defined
* unit-tests/Makefile: set BROKEN_TESTS for IRIX
* configure.in: override INSTALL on IRIX
2023-06-27 Simon J Gerraty <sjg@beast.crufty.net>
* boot-strap op_test: ensure we set TEST_MAKE as we want it.
2023-06-22 Simon J Gerraty <sjg@beast.crufty.net>
* VERSION (_MAKE_VERSION): 20230622

View file

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

View file

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.366 2023/05/10 18:22:33 sjg Exp $
.\" $NetBSD: make.1,v 1.371 2023/09/10 21:52:36 rillig 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 May 10, 2023
.Dd September 9, 2023
.Dt BMAKE 1
.Os
.Sh NAME
@ -267,6 +267,12 @@ cooperate to avoid overloading the system.
Specify the maximum number of jobs that
.Nm
may have running at any one time.
If
.Ar max_jobs
is a floating point number, or ends with
.Ql C ,
then the value is multiplied by the number of CPUs reported online by
.Xr sysconf 3 .
The value of
.Ar max_jobs
is saved in
@ -971,6 +977,11 @@ making it easier to track the degree of parallelism being achieved.
The argument to the
.Fl j
option.
.It Va .MAKE.JOBS.C
A read-only boolean that indicates whether the
.Fl j
option supports use of
.Ql C .
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
@ -1497,6 +1508,10 @@ The value is interpreted as a format string for
using
.Xr gmtime 3 ,
producing the formatted timestamp.
Note: the
.Ql %s
format should only be used with
.Sq Cm \&:localtime .
If a
.Ar timestamp
value is not provided or is 0, the current time is used.
@ -2069,7 +2084,7 @@ only evaluates a conditional as far as is necessary to determine its value.
Parentheses can be used to override the operator precedence.
The boolean operator
.Sq Ic \&!
may be used to logically negate an entire conditional.
may be used to logically negate an expression, typically a function call.
It is of higher precedence than
.Sq Ic \&&& .
.Pp
@ -2119,9 +2134,9 @@ may also be an arithmetic or string comparison.
Variable expansion is performed on both sides of the comparison.
If both sides are numeric and neither is enclosed in quotes,
the comparison is done numerically, otherwise lexicographically.
A string is interpreted as hexadecimal integer if it is preceded by
A string is interpreted as a hexadecimal integer if it is preceded by
.Li 0x ,
otherwise it is a decimal floating-point number;
otherwise it is interpreted as a decimal floating-point number;
octal numbers are not supported.
.Pp
All comparisons may use the operators
@ -2142,7 +2157,7 @@ and its numeric value (if any) is not zero.
When
.Nm
is evaluating one of these conditional expressions, and it encounters
a (whitespace separated) word it doesn't recognize, either the
a (whitespace-separated) word it doesn't recognize, either the
.Dq make
or
.Dq defined
@ -2165,12 +2180,13 @@ function is applied.
.Pp
If the conditional evaluates to true,
parsing of the makefile continues as before.
If it evaluates to false, the following lines are skipped.
In both cases, this continues until the corresponding
If it evaluates to false, the following lines until the corresponding
.Sq Ic .elif
variant,
.Sq Ic .else
or
.Sq Ic .endif
is found.
are skipped.
.Ss For loops
For loops are typically used to apply a set of rules to a list of files.
The syntax of a for loop is:

View file

@ -157,15 +157,17 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
-j max_jobs
Specify the maximum number of jobs that bmake may have running at
any one time. The value of max_jobs is saved in .MAKE.JOBS.
Turns compatibility mode off, unless the -B option is also speci-
fied. When compatibility mode is off, all commands associated
with a target are executed in a single shell invocation as op-
posed to the traditional one shell invocation per line. This can
break traditional scripts which change directories on each com-
mand invocation and then expect to start with a fresh environment
on the next line. It is more efficient to correct the scripts
rather than turn backwards compatibility on.
any one time. If max_jobs is a floating point number, or ends
with `C', then the value is multiplied by the number of CPUs re-
ported online by sysconf(3). The value of max_jobs is saved in
.MAKE.JOBS. Turns compatibility mode off, unless the -B option
is also specified. When compatibility mode is off, all commands
associated with a target are executed in a single shell invoca-
tion as opposed to the traditional one shell invocation per line.
This can break traditional scripts which change directories on
each command invocation and then expect to start with a fresh en-
vironment on the next line. It is more efficient to correct the
scripts rather than turn backwards compatibility on.
A job token pool with max_jobs tokens is used to control the to-
tal number of jobs running. Each instance of bmake will wait for
@ -625,6 +627,10 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
.MAKE.JOBS
The argument to the -j option.
.MAKE.JOBS.C
A read-only boolean that indicates whether the -j option supports
use of `C'.
.MAKE.LEVEL
The recursion depth of bmake. The top-level instance of bmake
has level 0, and each child make has its parent level plus 1.
@ -972,8 +978,9 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
:gmtime[=timestamp]
The value is interpreted as a format string for strftime(3), using
gmtime(3), producing the formatted timestamp. If a timestamp value
is not provided or is 0, the current time is used.
gmtime(3), producing the formatted timestamp. Note: the `%s' format
should only be used with `:localtime'. If a timestamp value is not
provided or is 0, the current time is used.
:hash
Computes a 32-bit hash of the value and encodes it as 8 hex digits.
@ -1313,8 +1320,8 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
bmake only evaluates a conditional as far as is necessary to determine
its value. Parentheses can be used to override the operator precedence.
The boolean operator `!' may be used to logically negate an entire condi-
tional. It is of higher precedence than `&&'.
The boolean operator `!' may be used to logically negate an expression,
typically a function call. It is of higher precedence than `&&'.
The value of expression may be any of the following function call expres-
sions:
@ -1346,9 +1353,9 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
Expression may also be an arithmetic or string comparison. Variable ex-
pansion is performed on both sides of the comparison. If both sides are
numeric and neither is enclosed in quotes, the comparison is done numeri-
cally, otherwise lexicographically. A string is interpreted as hexadeci-
mal integer if it is preceded by 0x, otherwise it is a decimal floating-
point number; octal numbers are not supported.
cally, otherwise lexicographically. A string is interpreted as a hexa-
decimal integer if it is preceded by 0x, otherwise it is interpreted as a
decimal floating-point number; octal numbers are not supported.
All comparisons may use the operators `==' and `!='. Numeric comparisons
may also use the operators `<', `<=', `>' and `>='.
@ -1358,16 +1365,15 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
any) is not zero.
When bmake is evaluating one of these conditional expressions, and it en-
counters a (whitespace separated) word it doesn't recognize, either the
counters a (whitespace-separated) word it doesn't recognize, either the
"make" or "defined" function is applied to it, depending on the form of
the conditional. If the form is `.ifdef', `.ifndef' or `.if', the
"defined" function is applied. Similarly, if the form is `.ifmake' or
`.ifnmake', the "make" function is applied.
If the conditional evaluates to true, parsing of the makefile continues
as before. If it evaluates to false, the following lines are skipped.
In both cases, this continues until the corresponding `.else' or `.endif'
is found.
as before. If it evaluates to false, the following lines until the cor-
responding `.elif' variant, `.else' or `.endif' are skipped.
For loops
For loops are typically used to apply a set of rules to a list of files.
@ -1753,4 +1759,4 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
attempt to suppress a cascade of unnecessary errors, can result in a
seemingly unexplained `*** Error code 6'
FreeBSD 13.0 May 10, 2023 FreeBSD 13.0
FreeBSD 13.0 September 9, 2023 FreeBSD 13.0

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View file

@ -119,7 +119,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: boot-strap,v 1.57 2021/10/22 20:32:21 sjg Exp $
# $Id: boot-strap,v 1.58 2023/06/27 21:02:19 sjg Exp $
#
# @(#) Copyright (c) 2001 Simon J. Gerraty
#
@ -420,7 +420,7 @@ op_build() {
op_test() {
[ -x bmake ] || op_build
Bmake test "$@" TEST_MAKE=$objdir/bmake || exit 1
Bmake test TEST_MAKE=$objdir/bmake "$@" || exit 1
}
op_clean() {

View file

@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.353 2023/06/23 05:21:10 rillig Exp $ */
/* $NetBSD: cond.c,v 1.354 2023/08/11 04:56:31 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -92,7 +92,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: cond.c,v 1.353 2023/06/23 05:21:10 rillig Exp $");
MAKE_RCSID("$NetBSD: cond.c,v 1.354 2023/08/11 04:56:31 rillig Exp $");
/*
* Conditional expressions conform to this grammar:
@ -224,17 +224,13 @@ ParseWord(const char **pp, bool doEval)
if ((ch == '&' || ch == '|') && paren_depth == 0)
break;
if (ch == '$') {
/*
* Parse the variable expression and install it as
* part of the argument if it's valid. We tell
* Var_Parse to complain on an undefined variable,
* (XXX: but Var_Parse ignores that request)
* so we don't need to do it. Nor do we return an
* error, though perhaps we should.
*/
VarEvalMode emode = doEval
? VARE_UNDEFERR
: VARE_PARSE_ONLY;
/*
* TODO: make Var_Parse complain about undefined
* variables.
*/
FStr nestedVal = Var_Parse(&p, SCOPE_CMDLINE, emode);
/* TODO: handle errors */
Buf_AddStr(&word, nestedVal.str);
@ -1267,7 +1263,6 @@ Cond_ExtractGuard(const char *line)
{
const char *p, *varname;
Substring dir;
enum GuardKind kind;
Guard *guard;
p = line + 1; /* skip the '.' */
@ -1288,10 +1283,9 @@ Cond_ExtractGuard(const char *line)
const char *arg_p = p;
free(ParseWord(&p, false));
if (strcmp(p, ")") == 0) {
char *target = ParseWord(&arg_p, true);
guard = bmake_malloc(sizeof(*guard));
guard->kind = GK_TARGET;
guard->name = target;
guard->name = ParseWord(&arg_p, true);
return guard;
}
}
@ -1302,9 +1296,8 @@ Cond_ExtractGuard(const char *line)
return NULL;
found_variable:
kind = GK_VARIABLE;
guard = bmake_malloc(sizeof(*guard));
guard->kind = kind;
guard->kind = GK_VARIABLE;
guard->name = bmake_strsedup(varname, p);
return guard;
}

View file

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for bmake 20220909.
# Generated by GNU Autoconf 2.71 for bmake 20230723.
#
# Report bugs to <sjg@NetBSD.org>.
#
@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='bmake'
PACKAGE_TARNAME='bmake'
PACKAGE_VERSION='20220909'
PACKAGE_STRING='bmake 20220909'
PACKAGE_VERSION='20230723'
PACKAGE_STRING='bmake 20230723'
PACKAGE_BUGREPORT='sjg@NetBSD.org'
PACKAGE_URL=''
@ -1290,7 +1290,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 20220909 to adapt to many kinds of systems.
\`configure' configures bmake 20230723 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1352,7 +1352,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of bmake 20220909:";;
short | recursive ) echo "Configuration of bmake 20230723:";;
esac
cat <<\_ACEOF
@ -1367,7 +1367,10 @@ Optional Features:
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions
--with-defshell=[name=]SHELL use SHELL by default
optional 'name' can be 'sh' to indicate SHELL is sh compatible
eg. --with-defshell=sh=/bin/bsh
use just 'sh' or 'ksh' to pick the internal definitions
--without-makefile disable use of generated makefile
--without-meta disable use of meta-mode
--with-filemon={no,dev,ktrace,path/filemon.h} indicate filemon method for meta-mode. Path to filemon.h implies dev
@ -1458,7 +1461,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
bmake configure 20220909
bmake configure 20230723
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@ -1965,7 +1968,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 20220909, which was
It was created by bmake $as_me 20230723, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@ -2748,15 +2751,24 @@ use_defshell() {
DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;;
*ksh)
DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
sh|/bin/sh)
sh|/bin/sh|*/bsh)
DEFSHELL_INDEX=DEFSHELL_INDEX_SH;;
*=*) # eg. sh=/bin/bsh
eval `IFS="="; set -- $1; echo name=$1 defshell_path=$2`
case "$name" in
csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;;
ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;;
*) DEFSHELL_INDEX=DEFSHELL_INDEX_CUSTOM;;
esac
;;
*) DEFSHELL_INDEX=DEFSHELL_INDEX_CUSTOM
defshell_path=$1
;;
esac
case "$1" in
/bin/*) ;;
*/*) defshell_path=$1;;
case "$defshell_path,$1" in
,/bin/*) ;;
,*/*) defshell_path=$1;;
esac
}
@ -2851,21 +2863,22 @@ SCO_SV) # /bin/sh is not usable
CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL"
;;
esac
# Not everyone groks TZ=Europe/Berlin
# 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
eval `TZ=UTC date '+utc_H=%H utc_d=%d' 2> /dev/null`
eval `TZ=Europe/Berlin date '+utc1_H=%H utc1_d=%d' 2> /dev/null`
if test ${utc_d-0} -lt ${utc1_d-0} -o ${utc_H-0} -lt ${utc1_H-0}; 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
eval `TZ=UTC-1 date '+utc1_H=%H utc1_d=%d' 2> /dev/null`
if test ${utc_d-0} -lt ${utc1_d-0} -o ${utc_H-0} -lt ${utc1_H-0}; then
UTC_1=UTC-1
echo no, using UTC-1 >&6
else
echo no >&6
fi
fi
test "x$UTC_1" = x && echo no >&6
oldPATH=$PATH
for d in /usr/gnu/bin
do
@ -4870,6 +4883,10 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
# We have to override that on some systems
case "$OS" in
IRIX*) ac_INSTALL=$srcdir/install-sh;;
esac
if test -x /usr/bin/getconf; then
bmake_path_max=`getconf PATH_MAX / 2> /dev/null`
# only a numeric response is useful
@ -4881,6 +4898,8 @@ if test $bmake_path_max -gt 1024; then
bmake_path_max=1024
fi
echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
# if type does not work which(1) had better!
# note we cannot rely on type returning non-zero on failure
if (type cat) > /dev/null 2>&1; then
: which
which() {
@ -7555,7 +7574,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 20220909, which was
This file was extended by bmake $as_me 20230723, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -7619,7 +7638,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
bmake config.status 20220909
bmake config.status 20230723
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"

View file

@ -1,11 +1,11 @@
dnl
dnl RCSid:
dnl $Id: configure.in,v 1.87 2022/09/09 20:00:53 sjg Exp $
dnl $Id: configure.in,v 1.97 2023/07/25 20:12:32 sjg Exp $
dnl
dnl Process this file with autoconf to produce a configure script
dnl
AC_PREREQ([2.71])
AC_INIT([bmake],[20220909],[sjg@NetBSD.org])
AC_INIT([bmake],[20230723],[sjg@NetBSD.org])
AC_CONFIG_HEADERS(config.h)
dnl make srcdir absolute
@ -29,20 +29,32 @@ use_defshell() {
DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;;
*ksh)
DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
sh|/bin/sh)
sh|/bin/sh|*/bsh)
DEFSHELL_INDEX=DEFSHELL_INDEX_SH;;
*=*) # eg. sh=/bin/bsh
eval `IFS="="; set -- $1; echo name=$1 defshell_path=$2`
case "$name" in
csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;;
ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;;
*) DEFSHELL_INDEX=DEFSHELL_INDEX_CUSTOM;;
esac
;;
*) DEFSHELL_INDEX=DEFSHELL_INDEX_CUSTOM
defshell_path=$1
;;
esac
case "$1" in
/bin/*) ;;
*/*) defshell_path=$1;;
case "$defshell_path,$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],
[ --with-defshell=[[name=]]SHELL use SHELL by default
optional 'name' can be 'sh' to indicate SHELL is sh compatible
eg. --with-defshell=sh=/bin/bsh
use just 'sh' or 'ksh' to pick the internal definitions],
[case "${withval}" in
yes) AC_MSG_ERROR(bad value ${withval} given for bmake DEFSHELL) ;;
no) ;;
@ -126,23 +138,22 @@ SCO_SV) # /bin/sh is not usable
;;
esac
dnl
dnl Not everyone groks TZ=Europe/Berlin
dnl which is used by the localtime tests
# Not everyone groks TZ=Europe/Berlin
# 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
eval `TZ=UTC date '+utc_H=%H utc_d=%d' 2> /dev/null`
eval `TZ=Europe/Berlin date '+utc1_H=%H utc1_d=%d' 2> /dev/null`
if test ${utc_d-0} -lt ${utc1_d-0} -o ${utc_H-0} -lt ${utc1_H-0}; 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
eval `TZ=UTC-1 date '+utc1_H=%H utc1_d=%d' 2> /dev/null`
if test ${utc_d-0} -lt ${utc1_d-0} -o ${utc_H-0} -lt ${utc1_H-0}; then
UTC_1=UTC-1
echo no, using UTC-1 >&6
else
echo no >&6
fi
fi
test "x$UTC_1" = x && echo no >&6
dnl
dnl Add some places to look for compilers
oldPATH=$PATH
@ -160,6 +171,10 @@ AC_USE_SYSTEM_EXTENSIONS
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# We have to override that on some systems
case "$OS" in
IRIX*) ac_INSTALL=$srcdir/install-sh;;
esac
dnl Executable suffix - normally empty; .exe on os2.
AC_SUBST(ac_exe_suffix)dnl
dnl
@ -177,8 +192,8 @@ fi
echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
AC_SUBST(bmake_path_max)dnl
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 does not work which(1) had better!
# note we cannot rely on type returning non-zero on failure
if (type cat) > /dev/null 2>&1; then
: which
which() {

View file

@ -4,6 +4,7 @@
ECHO=
GIT=${GIT:-git}
PAGER=${PAGER:-${LESS:-${MORE:-more}}}
# For consistency...
Error() {
@ -80,14 +81,41 @@ grep '^+' $TF.diffs | sed 's,^.,,' | sort > $TF.adds
grep '^-' $TF.diffs | sed 's,^.,,' | sort > $TF.rms
comm -13 $TF.adds $TF.rms > $TF.rm
post=$SB/tmp/bmake-post.sh
# this is similar to what generates the mail to bmake-announce
gen_import_F() {
echo Import bmake-$VERSION
if [ -s $post ]; then
last=`sed -n '/ tag/s,.*/,bmake-,p' $post`
else
last="last import"
fi
for C in ChangeLog */ChangeLog
do
$GIT diff --staged $C |
sed -n '/^@@/d;/^\+\+\+/d;/^\+/s,^.,,p' > $TF.C
test -s $TF.C || continue
echo
echo $C since $last
echo
cat $TF.C
done
}
if [ -z "$ECHO" ]; then
test -s $TF.rm && xargs rm -f < $TF.rm
$GIT add -A
$GIT diff --staged | tee $SB/tmp/bmake-import.diff
gen_import_F > $SB/tmp/bmake-import.F
$GIT diff --staged > $SB/tmp/bmake-import.diff
$PAGER $SB/tmp/bmake-import.F $SB/tmp/bmake-import.diff
{ echo "$GIT tag -a -m \"Tag bmake/$VERSION\" 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"
} > $post
echo "Edit $SB/tmp/bmake-import.F as needed, then:"
echo "$GIT commit -F $SB/tmp/bmake-import.F"
echo "After you commit, run $post"
else
comm -23 $TF.adds $TF.rms > $TF.add
test -s $TF.rm && { echo Removing:; cat $TF.rm; }

View file

@ -1,4 +1,5 @@
:
#!/bin/sh
# NAME:
# install.sh - portable version of install(1)
#
@ -46,14 +47,14 @@
# BUGS:
# The '-i' option is to save your sanity when 'bsd.prog.mk'
# insists on haveing a '-o' "owner" option which is doomed to
# fail on many systems. We ignore '-b', '-B' and '-c' options.
# fail on many systems. We ignore '-b' and '-c' options.
#
# AUTHOR:
# Simon J. Gerraty <sjg@crufty.net>
#
# RCSid:
# $Id: install-sh,v 1.22 2023/01/28 16:21:19 sjg Exp $
# $Id: install-sh,v 1.25 2023/07/15 05:33:38 sjg Exp $
#
# @(#) Copyright (c) 1993-2023 Simon J. Gerraty
#
@ -73,6 +74,7 @@ set -- `getopt B:bpxCNcsdo:g:m:i:f: $*`
Mydir=`dirname $0`
[ -s $Mydir/.installrc ] && . $Mydir/.installrc
OLD_EXT=.old
owner=:
group=:
mode=:
@ -89,6 +91,7 @@ while :
do
case "$1" in
--) shift; break;;
-[bc]) ;; # ignore
-p) CP_p=-p;;
-x) set -x;;
-B) OLD_EXT=$2; shift;;
@ -155,7 +158,7 @@ add_path /usr/sbin
case "$owner" in
:) ;;
*)
*) # some systems put chown in odd places
add_path /etc
add_path /usr/etc
;;
@ -185,16 +188,16 @@ if [ "$mkdirs" ]; then
fi
# install files
if [ $# -gt 2 ]; then
dest_dir=yes
elif [ $# -eq 1 ]; then
if [ $# -eq 1 ]; then
echo "what should I do with $*?" >&2
exit 1
fi
# get list of files
files=
while [ $# -gt 1 ]
do
test "x$files" = x || dest_dir=yes
files="$files $1"
shift
done
@ -202,7 +205,6 @@ done
dest=$1
shift
if [ "$dest_dir" = yes -a ! -d $dest ]; then
echo "no directory $dest" >&2
exit 1
@ -218,7 +220,7 @@ do
fi
$newer $f $t || continue
$compare $f $t || continue
[ -f $t ] && { mv -f $t $t.old || exit 1; }
[ -f $t ] && { mv -f $t $t$OLD_EXT || exit 1; }
{ cp $CP_p $f $t && Setem $t; } || exit 1
done
exit 0

View file

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.593 2023/03/28 14:39:31 rillig Exp $ */
/* $NetBSD: main.c,v 1.599 2023/09/10 21:52:36 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.593 2023/03/28 14:39:31 rillig Exp $");
MAKE_RCSID("$NetBSD: main.c,v 1.599 2023/09/10 21:52:36 rillig Exp $");
#if defined(MAKE_NATIVE) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
"The Regents of the University of California. "
@ -399,21 +399,44 @@ MainParseArgJobsInternal(const char *argvalue)
}
static void
MainParseArgJobs(const char *argvalue)
MainParseArgJobs(const char *arg)
{
char *p;
const char *p;
char *end;
char v[12];
forceJobs = true;
opts.maxJobs = (int)strtol(argvalue, &p, 0);
opts.maxJobs = (int)strtol(arg, &end, 0);
p = arg + (end - arg);
#ifdef _SC_NPROCESSORS_ONLN
if (*p != '\0') {
double d;
if (*p == 'C') {
d = (opts.maxJobs > 0) ? opts.maxJobs : 1;
} else if (*p == '.') {
d = strtod(arg, &end);
p = arg + (end - arg);
} else
d = 0;
if (d > 0) {
p = "";
opts.maxJobs = (int)sysconf(_SC_NPROCESSORS_ONLN);
opts.maxJobs = (int)(d * (double)opts.maxJobs);
}
}
#endif
if (*p != '\0' || opts.maxJobs < 1) {
(void)fprintf(stderr,
"%s: illegal argument to -j -- must be positive integer!\n",
progname);
"%s: argument '%s' to option '-j' "
"must be a positive number\n",
progname, arg);
exit(2); /* Not 1 so -q can distinguish error */
}
snprintf(v, sizeof(v), "%d", opts.maxJobs);
Global_Append(MAKEFLAGS, "-j");
Global_Append(MAKEFLAGS, argvalue);
Global_Set(".MAKE.JOBS", argvalue);
Global_Append(MAKEFLAGS, v);
Global_Set(".MAKE.JOBS", v);
maxJobTokens = opts.maxJobs;
}
@ -1386,6 +1409,12 @@ main_Init(int argc, char **argv)
#endif
Global_Set(".MAKE.MAKEFILE_PREFERENCE", MAKEFILE_PREFERENCE_LIST);
Global_Set(".MAKE.DEPENDFILE", ".depend");
/* Tell makefiles like jobs.mk whether we support -jC */
#ifdef _SC_NPROCESSORS_ONLN
Global_Set_ReadOnly(".MAKE.JOBS.C", "yes");
#else
Global_Set_ReadOnly(".MAKE.JOBS.C", "no");
#endif
CmdOpts_Init();
allPrecious = false; /* Remove targets when interrupted */

View file

@ -2,6 +2,7 @@
set -e
prefix=@prefix@
srcdir=@srcdir@
DEFAULT_SYS_PATH="@default_sys_path@"

View file

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.366 2023/05/10 18:22:33 sjg Exp $
.\" $NetBSD: make.1,v 1.371 2023/09/10 21:52:36 rillig 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 May 10, 2023
.Dd September 9, 2023
.Dt MAKE 1
.Os
.Sh NAME
@ -267,6 +267,12 @@ cooperate to avoid overloading the system.
Specify the maximum number of jobs that
.Nm
may have running at any one time.
If
.Ar max_jobs
is a floating point number, or ends with
.Ql C ,
then the value is multiplied by the number of CPUs reported online by
.Xr sysconf 3 .
The value of
.Ar max_jobs
is saved in
@ -982,6 +988,11 @@ making it easier to track the degree of parallelism being achieved.
The argument to the
.Fl j
option.
.It Va .MAKE.JOBS.C
A read-only boolean that indicates whether the
.Fl j
option supports use of
.Ql C .
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
@ -1508,6 +1519,10 @@ The value is interpreted as a format string for
using
.Xr gmtime 3 ,
producing the formatted timestamp.
Note: the
.Ql %s
format should only be used with
.Sq Cm \&:localtime .
If a
.Ar timestamp
value is not provided or is 0, the current time is used.
@ -2080,7 +2095,7 @@ only evaluates a conditional as far as is necessary to determine its value.
Parentheses can be used to override the operator precedence.
The boolean operator
.Sq Ic \&!
may be used to logically negate an entire conditional.
may be used to logically negate an expression, typically a function call.
It is of higher precedence than
.Sq Ic \&&& .
.Pp
@ -2130,9 +2145,9 @@ may also be an arithmetic or string comparison.
Variable expansion is performed on both sides of the comparison.
If both sides are numeric and neither is enclosed in quotes,
the comparison is done numerically, otherwise lexicographically.
A string is interpreted as hexadecimal integer if it is preceded by
A string is interpreted as a hexadecimal integer if it is preceded by
.Li 0x ,
otherwise it is a decimal floating-point number;
otherwise it is interpreted as a decimal floating-point number;
octal numbers are not supported.
.Pp
All comparisons may use the operators
@ -2153,7 +2168,7 @@ and its numeric value (if any) is not zero.
When
.Nm
is evaluating one of these conditional expressions, and it encounters
a (whitespace separated) word it doesn't recognize, either the
a (whitespace-separated) word it doesn't recognize, either the
.Dq make
or
.Dq defined
@ -2176,12 +2191,13 @@ function is applied.
.Pp
If the conditional evaluates to true,
parsing of the makefile continues as before.
If it evaluates to false, the following lines are skipped.
In both cases, this continues until the corresponding
If it evaluates to false, the following lines until the corresponding
.Sq Ic .elif
variant,
.Sq Ic .else
or
.Sq Ic .endif
is found.
are skipped.
.Ss For loops
For loops are typically used to apply a set of rules to a list of files.
The syntax of a for loop is:

View file

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.323 2023/06/20 09:25:33 rillig Exp $ */
/* $NetBSD: make.h,v 1.325 2023/09/10 11:52:29 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -195,6 +195,13 @@ typedef unsigned char bool;
# define POSIX_SIGNALS
#endif
/*
* IRIX defines OP_NONE in sys/fcntl.h
*/
#if defined(OP_NONE)
# undef OP_NONE
#endif
/*
* The typical flow of states is:
*
@ -1214,8 +1221,8 @@ pp_skip_hspace(char **pp)
}
#if defined(lint)
extern void do_not_define_rcsid(void); /* for lint */
# define MAKE_RCSID(id) extern void do_not_define_rcsid(void)
void do_not_define_rcsid(void); /* for lint */
# define MAKE_RCSID(id) void do_not_define_rcsid(void)
#elif defined(MAKE_NATIVE)
# include <sys/cdefs.h>
# ifndef __IDSTRING
@ -1234,7 +1241,7 @@ extern void do_not_define_rcsid(void); /* for lint */
# define MAKE_RCSID(id) static volatile char \
MAKE_RCSID_CONCAT(rcsid_, __COUNTER__)[] = id
#elif defined(MAKE_ALL_IN_ONE)
# define MAKE_RCSID(id) extern void do_not_define_rcsid(void)
# define MAKE_RCSID(id) void do_not_define_rcsid(void)
#else
# define MAKE_RCSID(id) static volatile char rcsid[] = id
#endif

View file

@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.205 2023/03/28 14:39:31 rillig Exp $ */
/* $NetBSD: meta.c,v 1.206 2023/08/19 00:09:17 sjg Exp $ */
/*
* Implement 'meta' mode.
@ -939,6 +939,13 @@ meta_ignore(GNode *gn, const char *p)
return true;
if (*p == '/') {
/* first try the raw path "as is" */
if (has_any_prefix(p, &metaIgnorePaths)) {
#ifdef DEBUG_META_MODE
DEBUG1(META, "meta_oodate: ignoring path: %s\n", p);
#endif
return true;
}
cached_realpath(p, fname); /* clean it up */
if (has_any_prefix(fname, &metaIgnorePaths)) {
#ifdef DEBUG_META_MODE

View file

@ -1,3 +1,46 @@
2023-09-09 Simon J Gerraty <sjg@beast.crufty.net>
* jobs.mk (JOB_MAX): use -jC if we can
we actually use JOB_MAX_C which defaults to 1.33C
2023-08-18 Simon J Gerraty <sjg@beast.crufty.net>
* now_utc: %s only works with :localtime
2023-07-14 Simon J Gerraty <sjg@beast.crufty.net>
* install-sh: ignore -c as claimed and only insist on
a directory for destination when more than one file to copy.
* sys.mk: when looking for SYS_OS_MK try ${.MAKE.OS} and
${.MAKE.OS:S,64,,} early (so we find sys/IRIX.mk for IRIX64)
2023-07-13 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20230711
* sys.mk: set SYS_MK and INSTALL_SH for systems with incompatible
install(1)
* sys/IRIX.mk: when setting ROOT_GROUP only match the first :0:
set INSTALL to install-sh rather than pathname that may not exist
(yet).
2023-07-07 Simon J Gerraty <sjg@beast.crufty.net>
* dirdeps.mk: pass DIRDEP_TARGETS to DIRDEP_MAKE
normally this is empty - for the default target, but there are
use-cases where we might set it to something else.
2023-07-04 Simon J Gerraty <sjg@beast.crufty.net>
* install-mk (MK_VERSION): 20230704
* dirdeps.mk: apply DEBUG_DIRDEPS_LIST_FILTER to lists we output
when DEBUG_DIRDEPS is in effect.
Eg. DEBUG_DIRDEPS_LIST_FILTER=ts\n
can greatly improve readability.
2023-05-25 Simon J Gerraty <sjg@beast.crufty.net>
* meta.autodep.mk (beforegendirdeps): allow tasks to be done

View file

@ -19,6 +19,7 @@ host.libnames.mk
inc.mk
init.mk
install-mk
install-sh
java.mk
jobs.mk
ldorder.mk

View file

@ -1,4 +1,4 @@
# $Id: dirdeps.mk,v 1.162 2023/05/15 17:37:46 sjg Exp $
# $Id: dirdeps.mk,v 1.165 2023/08/19 17:35:32 sjg Exp $
# SPDX-License-Identifier: BSD-2-Clause
#
@ -155,7 +155,7 @@
# if any test fails, but without the risk of introducing
# circular dependencies.
now_utc ?= ${%s:L:gmtime}
now_utc ?= ${%s:L:localtime}
.if !defined(start_utc)
start_utc := ${now_utc}
.endif
@ -415,6 +415,8 @@ DIRDEPS_FILTER += M${_DEP_RELDIR}
# this is what we run below
DIRDEP_MAKE ?= ${.MAKE}
DIRDEP_DIR ?= ${.TARGET:R}
# we normally want the default target
DIRDEP_TARGETS ?=
# if you want us to report load averages during build
# DIRDEP_USE_PRELUDE += ${DIRDEP_LOADAVG_REPORT};
@ -442,7 +444,7 @@ _DIRDEP_USE: .USE .MAKE
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
TARGET_SPEC=${.TARGET:E} \
MACHINE=${.TARGET:E} \
${DIRDEP_MAKE} -C ${DIRDEP_DIR} || exit 1; \
${DIRDEP_MAKE} -C ${DIRDEP_DIR} ${DIRDEP_TARGETS} || exit 1; \
break; \
done
@ -680,7 +682,7 @@ _build_dirs += ${_machines:@m@${_CURDIR}.$m@}
.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}: DIRDEPS=${DIRDEPS:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}'
.endif
@ -712,9 +714,9 @@ __qual_depdirs += ${__hostdpadd}
.if ${_debug_reldir}
.info DEP_DIRDEPS_FILTER=${DEP_DIRDEPS_FILTER:ts:}
.info depdirs=${__depdirs:S,^${SRCTOP}/,,}
.info qualified=${__qual_depdirs:S,^${SRCTOP}/,,}
.info unqualified=${__unqual_depdirs:S,^${SRCTOP}/,,}
.info depdirs=${__depdirs:S,^${SRCTOP}/,,:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.info qualified=${__qual_depdirs:S,^${SRCTOP}/,,:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.info unqualified=${__unqual_depdirs:S,^${SRCTOP}/,,:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.endif
# _build_dirs is what we will feed to _DIRDEP_USE
@ -726,14 +728,14 @@ _build_dirs += \
# qualify everything now
.if ${_debug_reldir}
.info _build_dirs=${_build_dirs}
.info _build_dirs=${_build_dirs:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.endif
# make sure we do not mess with qualifying "host" entries
_build_dirs := ${_build_dirs:M*.host*:${M_dep_qual_fixes.host:ts:}} \
${_build_dirs:N*.host*:${M_dep_qual_fixes:ts:}}
_build_dirs := ${_build_dirs:O:u}
.if ${_debug_reldir}
.info _build_dirs=${_build_dirs}
.info _build_dirs=${_build_dirs:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.endif
.endif # empty DIRDEPS
@ -767,7 +769,7 @@ dirdeps: ${_build_all_dirs}
${_build_all_dirs}: _DIRDEP_USE
.if ${_debug_reldir}
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs:S,^${SRCTOP}/,,}
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs:S,^${SRCTOP}/,,:${DEBUG_DIRDEPS_LIST_FILTER:U:N/:ts:}}
.endif
.if !empty(DIRDEPS_EXPORT_VARS) || !empty(DEP_EXPORT_VARS)

View file

@ -59,7 +59,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
# $Id: install-mk,v 1.239 2023/05/29 18:04:48 sjg Exp $
# $Id: install-mk,v 1.242 2023/09/09 16:00:16 sjg Exp $
#
# @(#) Copyright (c) 1994-2023 Simon J. Gerraty
#
@ -74,7 +74,7 @@
# sjg@crufty.net
#
MK_VERSION=20230601
MK_VERSION=20230909
OWNER=
GROUP=
MODE=444
@ -174,7 +174,7 @@ if [ $mksrc = $dest ]; then
else
# we do not install the examples
mk_files=`grep '^[a-z].*\.mk' FILES | $egrep -v '(examples/|^sys\.mk|sys/)'`
mk_scripts=`$egrep '^[a-z].*\.(sh|py)' FILES | $egrep -v '/'`
mk_scripts=`$egrep '^[a-z].*[.-](sh|py)' FILES | $egrep -v '/'`
sys_mk_files=`grep 'sys/.*\.mk' FILES`
SKIP_MKFILES=
[ -z "$SKIP_SYS_MK" ] && mk_files="sys.mk $mk_files"

226
contrib/bmake/mk/install-sh Executable file
View file

@ -0,0 +1,226 @@
#!/bin/sh
# NAME:
# install.sh - portable version of install(1)
#
# SYNOPSIS:
# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ...
# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ...
#
# DESCRIPTION:
# Compatible with BSD install(1). Except that '-c' is always
# true and we always move an already installed target aside as
# this is important on many systems. Recent BSD install(1)
# versions have a '-b' option for this.
#
#
# OPTIONS:
# -b move previous target file aside (always true).
#
# -B "suffix"
# use "suffix" instead of .old for saving existing target.
#
# -c copy rather than move the file into place (always true).
#
# -C compare. Only install if target is missing or
# different.
#
# -N newer. Only install if target is missing or older.
#
# -s strip target
#
# -o "owner"
# make target owned by "owner"
#
# -g "group"
# make target group owned by "group"
#
# -m "mode"
# set permissions to "mode"
#
# -f "flags"
# Pass "flags" onto chflags(1)
#
# -i "errs"
# Ignore errors from steps indicated by "errs" (``s,o,g,m'').
#
# BUGS:
# The '-i' option is to save your sanity when 'bsd.prog.mk'
# insists on haveing a '-o' "owner" option which is doomed to
# fail on many systems. We ignore '-b' and '-c' options.
#
# AUTHOR:
# Simon J. Gerraty <sjg@crufty.net>
#
# RCSid:
# $Id: install-sh,v 1.25 2023/07/15 05:33:38 sjg Exp $
#
# @(#) Copyright (c) 1993-2023 Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
# Permission to copy, redistribute or otherwise
# use this file is hereby granted provided that
# the above copyright notice and this notice are
# left intact.
#
# Please send copies of changes and bug-fixes to:
# sjg@crufty.net
#
set -- `getopt B:bpxCNcsdo:g:m:i:f: $*`
Mydir=`dirname $0`
[ -s $Mydir/.installrc ] && . $Mydir/.installrc
OLD_EXT=.old
owner=:
group=:
mode=:
MODE=0
strip=:
mkdirs=
compare=:
newer=:
chflags=:
LS_1=
CP_p=
while :
do
case "$1" in
--) shift; break;;
-[bc]) ;; # ignore
-p) CP_p=-p;;
-x) set -x;;
-B) OLD_EXT=$2; shift;;
-C) compare=Different;;
-N) newer=Newer;
# check if /bin/ls supports -1
'ls' -1 $0 > /dev/null 2>&1 && LS_1=1
;;
-o) owner="${CHOWN:-chown} $2 "; shift;;
-g) group="${CHGRP:-chgrp} $2 "; shift;;
-m) MODE=$2 mode="${CHMOD:-chmod} $2 "; shift;;
-s) strip=${STRIP:-strip};;
-d) mkdirs="mkdir -p";;
-i) ignore_err="$ignore_err$2"; shift;;
-f) chflags="${CHFLAGS:-chflags} $2 "; shift;;
*) break;;
esac
shift
done
Newer() {
n=`'ls' -t$LS_1 $* 2> /dev/null | head -1`
[ $1 = $n ]
}
Different() {
cmp -s $*
[ $? != 0 ]
}
Err() {
case "$ignore_err" in
*$1*) ;;
*) exit 1;;
esac
}
Setem() {
# the order is important
if [ ! -d $1 ]; then
$strip $1 || Err s
fi
$group $1 || Err g
$owner $1 || Err o
$mode $1 || Err m
$chflags $1 || Err f
return 0
}
# a bug in HP-UX's /bin/sh, means we need to re-set $*
# after any calls to add_path()
args="$*"
add_path () {
test -d $1 || return
case ":$PATH:" in
*:$1:*) return;;
esac
PATH=$PATH:$1
}
add_path /sbin
add_path /usr/sbin
case "$owner" in
:) ;;
*) # some systems put chown in odd places
add_path /etc
add_path /usr/etc
;;
esac
# restore saved $*
set -- $args
# make directories if needed
# and ensure mode etc are as desired
if [ "$mkdirs" ]; then
case "$MODE" in
[1-7]*)
# make sure umask is compatible
case "$MODE" in
????*) MODE=`echo $MODE | sed 's,.*\(...\)$,\1,'`;;
esac
umask `expr 0777 - 0$MODE |
sed 's,^,000,;s,^.*\(...\)$,\1,'`;;
esac
for d in $*
do
[ ! -d $d ] && $mkdirs $d
Setem $d
done
exit 0 # that's all we do
fi
# install files
if [ $# -eq 1 ]; then
echo "what should I do with $*?" >&2
exit 1
fi
# get list of files
files=
while [ $# -gt 1 ]
do
test "x$files" = x || dest_dir=yes
files="$files $1"
shift
done
# last one is dest
dest=$1
shift
if [ "$dest_dir" = yes -a ! -d $dest ]; then
echo "no directory $dest" >&2
exit 1
fi
for f in $files
do
b=`basename $f`
if [ -d $dest ]; then
t=$dest/$b
else
t=$dest
fi
$newer $f $t || continue
$compare $f $t || continue
[ -f $t ] && { mv -f $t $t$OLD_EXT || exit 1; }
{ cp $CP_p $f $t && Setem $t; } || exit 1
done
exit 0

View file

@ -1,4 +1,4 @@
# $Id: jobs.mk,v 1.9 2023/04/27 18:10:27 sjg Exp $
# $Id: jobs.mk,v 1.14 2023/09/11 16:52:44 sjg Exp $
#
# @(#) Copyright (c) 2012-2023, Simon J. Gerraty
#
@ -29,11 +29,14 @@
#
# ${MAKE} -j${JOB_MAX} target > ${JOB_LOGDIR}/target.log 2>&1
#
# JOB_MAX defaults to 8 but should normally be derrived based on the
# number of cpus available. The wrapper script 'mk' makes that easy.
# JOB_MAX should be something like 1.2 - 1.5 times the number of
# available CPUs.
# If bmake sets .MAKE.JOBS.C=yes we can use -jC and
# JOB_MAX defaults to JOB_MAX_C (default 1.33C).
# Otherwise we use 8.
#
now_utc ?= ${%s:L:gmtime}
now_utc ?= ${%s:L:localtime}
.if !defined(start_utc)
start_utc := ${now_utc}
.endif
@ -70,14 +73,19 @@ NEWLOG = :
.endif
.if ${.MAKE.JOBS:U0} > 0
JOB_MAX= ${.MAKE.JOBS}
JOB_MAX = ${.MAKE.JOBS}
.else
# This should be derrived from number of cpu's
JOB_MAX?= 8
JOB_ARGS+= -j${JOB_MAX}
.if ${.MAKE.JOBS.C:Uno} == "yes"
# 1.2 - 1.5 times nCPU works well on most machines that support -jC
JOB_MAX_C ?= 1.33C
JOB_MAX ?= ${JOB_MAX_C}
.endif
JOB_MAX ?= 8
JOB_ARGS += -j${JOB_MAX}
.endif
# we need to reset .MAKE.LEVEL to 0 do that
# we need to reset .MAKE.LEVEL to 0 so that
# build orchestration works as expected (DIRDEPS_BUILD)
${.TARGETS:M*-jobs}:
@${NEWLOG} ${JOB_NEWLOG_ARGS} ${JOB_LOG}

View file

@ -1,4 +1,4 @@
# $Id: lib.mk,v 1.74 2023/04/20 23:45:56 sjg Exp $
# $Id: lib.mk,v 1.75 2023/09/11 05:20:23 sjg Exp $
.if !target(__${.PARSEFILE}__)
__${.PARSEFILE}__: .NOTMAIN
@ -604,6 +604,10 @@ realinstall: beforeinstall
.if !empty(LIB)
STAGE_LIBDIR?= ${STAGE_OBJTOP}${LIBDIR}
stage_libs: ${_LIBS}
__libtoken ?= __lib${LIB:C,[^a-zA-Z0-9_],_,g}__
__libtoken := ${__libtoken}
COPTS += -D${__libtoken}
.endif
.include <final.mk>

View file

@ -1,4 +1,4 @@
# $Id: meta.autodep.mk,v 1.58 2023/05/25 22:33:23 sjg Exp $
# $Id: meta.autodep.mk,v 1.59 2023/08/19 17:35:32 sjg Exp $
#
# @(#) Copyright (c) 2010, Simon J. Gerraty
@ -305,7 +305,7 @@ ${_DEPENDFILE}: .PRECIOUS
CLEANFILES += *.meta filemon.* *.db
# these make it easy to gather some stats
now_utc = ${%s:L:gmtime}
now_utc = ${%s:L:localtime}
start_utc := ${now_utc}
meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \

View file

@ -69,6 +69,14 @@ mk-files
This section provides a brief description of some of the ``*.mk``
files.
The makefiles ``lib.mk``, ``prog.mk``, ``init.mk``, ``own.mk``,
``dep.mk`` and ``man.mk`` are more or less equivalent to ``bsd.*.mk``
found in BSD, and when installed on non-BSD platforms get symlinked as
``bsd.*.mk`` as well.
The other makefiles (apart from ``sys.mk``) can be used in conjunction
with ``bsd.*.mk`` on BSD.
sys.mk
------
@ -330,6 +338,9 @@ auto.obj.mk
Creates object dirs and leverages the ``.OBJDIR`` target introduced
some years ago to NetBSD make, to use them.
Note that if ``auto.obj.mk`` is to be used it should be included
early - before bmake has established ``.PATH``, thus we include it
from ``sys.mk`` rather than ``obj.mk``.
subdir.mk
---------
@ -536,7 +547,6 @@ We have the following makefiles which are relevant to
share/mk/auto.obj.mk
share/mk/dirdeps-cache-update.mk
share/mk/dirdeps-only.mk
share/mk/dirdeps-options.mk
share/mk/dirdeps-targets.mk
share/mk/dirdeps.mk
@ -573,7 +583,7 @@ destination directory, and unless told not to, create ``bsd.*.mk`` links
for ``lib.mk`` etc.
If you just want to create the ``bsd.*.mk`` links in the directory
where you unpacked the tar file, you can::
where you unpacked the tar file, you can use::
./mk/install-mk ./mk
@ -587,5 +597,5 @@ where you unpacked the tar file, you can::
.. _`netbsd-meta-mode`: https://www.crufty.net/sjg/docs/netbsd-meta-mode.htm
:Author: sjg@crufty.net
:Revision: $Id: mk-files.txt,v 1.23 2023/05/11 22:55:08 sjg Exp $
:Revision: $Id: mk-files.txt,v 1.25 2023/07/14 23:51:11 sjg Exp $
:Copyright: Crufty.NET

View file

@ -1,4 +1,4 @@
# $Id: rst2htm.mk,v 1.12 2021/05/26 04:20:31 sjg Exp $
# $Id: rst2htm.mk,v 1.13 2023/09/13 18:55:42 sjg Exp $
#
# @(#) Copyright (c) 2009, Simon J. Gerraty
#
@ -16,11 +16,15 @@
# convert reStructuredText to HTML, using rst2html.py from
# docutils - http://docutils.sourceforge.net/
# pickup customizations
.-include <local.rst2htm.mk>
.if empty(TXTSRCS)
TXTSRCS != 'ls' -1t ${.CURDIR}/*.txt ${.CURDIR}/*.rst 2>/dev/null; echo
.endif
RSTSRCS ?= ${TXTSRCS}
HTMFILES ?= ${RSTSRCS:R:T:O:u:%=%.htm}
PDFFILES ?= ${RSTSRCS:R:T:O:u:%=%.pdf}
# can be empty, 4 or 5
HTML_VERSION ?=
RST2HTML ?= rst2html${HTML_VERSION}.py
@ -37,7 +41,7 @@ RST2PDF_FLAGS ?= ${"${.TARGET:T:M*slides*}":?${RST2PDF_SLIDES_FLAGS}:${RST2PDF_D
RST_SUFFIXES ?= .rst .txt
CLEANFILES += ${HTMFILES}
CLEANFILES += ${HTMFILES} ${PDFFILES}
html: ${HTMFILES}

View file

@ -1,6 +1,6 @@
# $Id: sys.mk,v 1.55 2023/05/10 19:23:26 sjg Exp $
# $Id: sys.mk,v 1.57 2023/07/14 16:30:37 sjg Exp $
#
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
# @(#) Copyright (c) 2003-2023, Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
@ -15,6 +15,9 @@
# Avoid putting anything platform specific in here.
# just in case we are an older bmake
.MAKE.OS ?= ${HOST_OS}
# _DEBUG_MAKE_FLAGS etc.
.include <sys.debug.mk>
@ -44,12 +47,18 @@ _TARGETS := ${.TARGETS}
CXX_SUFFIXES += .cc .cpp .cxx .C
CXX_SUFFIXES := ${CXX_SUFFIXES:O:u}
SYS_MK ?= ${.PARSEDIR:tA}/${.PARSEFILE}
SYS_MK := ${SYS_MK}
# for systems that have an incompatible install
INSTALL_SH ?= ${SYS_MK:H}/install-sh
# find the OS specifics
.if defined(SYS_OS_MK)
.include <${SYS_OS_MK}>
.else
_sys_mk =
.for x in ${HOST_OSTYPE} ${HOST_TARGET} ${HOST_OS} ${MACHINE} Generic
.for x in ${HOST_TARGET} ${.MAKE.OS} ${.MAKE.OS:S,64,,} ${HOST_OSTYPE} ${MACHINE} Generic
.if empty(_sys_mk)
.-include <sys/$x.mk>
_sys_mk := ${.MAKE.MAKEFILES:M*/$x.mk}
@ -62,6 +71,9 @@ _sys_mk := sys/${_sys_mk:T}
.-include <$x.sys.mk>
_sys_mk := ${.MAKE.MAKEFILES:M*/$x.sys.mk:T}
.endif
.if !empty(_sys_mk) && ${MAKE_VERSION} >= 20220924
.break
.endif
.endfor
SYS_OS_MK := ${_sys_mk}
@ -116,7 +128,7 @@ MACHINE_ARCH = ${MACHINE_ARCH.${MACHINE}}
.endif
.ifndef ROOT_GROUP
ROOT_GROUP != sed -n /:0:/s/:.*//p /etc/group
ROOT_GROUP != sed -n '/:0:/{s/:.*//p;q;}' /etc/group
.export ROOT_GROUP
.endif

View file

@ -1,14 +1,12 @@
# $NetBSD: IRIX.sys.mk,v 1.2 2002/12/24 23:03:27 jschauma Exp $
# @(#)sys.mk 8.2 (Berkeley) 3/21/94
.if ${.PARSEFILE} == "sys.mk"
.ifndef ROOT_GROUP
OS!= uname -s
ROOT_GROUP!= sed -n /:0:/s/:.*//p /etc/group
.MAKEOVERRIDES+= OS ROOT_GROUP
OS != uname -s
ROOT_GROUP != sed -n '/:0:/{s/:.*//p;q;}' /etc/group
.export OS ROOT_GROUP
.endif
unix ?= We run ${OS}.
.endif
.SUFFIXES: .out .a .ln .o .s .S .c ${CXX_SUFFIXES} .F .f .r .y .l .cl .p .h
.SUFFIXES: .sh .m4
@ -56,11 +54,12 @@ LINK.F ?= ${FC} ${FFLAGS} ${CPPFLAGS} ${LDFLAGS}
COMPILE.r ?= ${FC} ${FFLAGS} ${RFLAGS} -c
LINK.r ?= ${FC} ${FFLAGS} ${RFLAGS} ${LDFLAGS}
INSTALL ?= ${PREFIX}/bin/install-sh
INSTALL_SH ?= install-sh
INSTALL = ${INSTALL_SH}
LEX ?= lex
LFLAGS ?=
LEX.l ?= ${LEX} ${LFLAGS}
LEX.l ?= ${LEX} ${LFLAGS}
LD ?= ld
LDFLAGS ?=

View file

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.704 2023/06/23 06:08:56 rillig Exp $ */
/* $NetBSD: parse.c,v 1.706 2023/08/19 11:09:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -121,7 +121,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: parse.c,v 1.704 2023/06/23 06:08:56 rillig Exp $");
MAKE_RCSID("$NetBSD: parse.c,v 1.706 2023/08/19 11:09:02 rillig Exp $");
/* Detects a multiple-inclusion guard in a makefile. */
typedef enum {
@ -887,14 +887,10 @@ MaybeUpdateMainTarget(void)
}
static void
InvalidLineType(const char *line)
InvalidLineType(const char *line, const char *unexpanded_line)
{
if (strncmp(line, "<<<<<<", 6) == 0 ||
strncmp(line, ">>>>>>", 6) == 0)
Parse_Error(PARSE_FATAL,
"Makefile appears to contain unresolved CVS/RCS/??? merge conflicts");
else if (line[0] == '.') {
const char *dirstart = line + 1;
if (unexpanded_line[0] == '.') {
const char *dirstart = unexpanded_line + 1;
const char *dirend;
cpp_skip_whitespace(&dirstart);
dirend = dirstart;
@ -902,8 +898,11 @@ InvalidLineType(const char *line)
dirend++;
Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"",
(int)(dirend - dirstart), dirstart);
} else
Parse_Error(PARSE_FATAL, "Invalid line type");
} else if (strcmp(line, unexpanded_line) == 0)
Parse_Error(PARSE_FATAL, "Invalid line '%s'", line);
else
Parse_Error(PARSE_FATAL, "Invalid line '%s', expanded to '%s'",
unexpanded_line, line);
}
static void
@ -1414,7 +1413,8 @@ ParseDependencyTargets(char **pp,
const char *lstart,
ParseSpecial *inout_special,
GNodeType *inout_targetAttr,
SearchPathList **inout_paths)
SearchPathList **inout_paths,
const char *unexpanded_line)
{
char *p = *pp;
@ -1439,7 +1439,7 @@ ParseDependencyTargets(char **pp,
}
if (*p == '\0') {
InvalidLineType(lstart);
InvalidLineType(lstart, unexpanded_line);
return false;
}
@ -1649,7 +1649,7 @@ ParseDependencySources(char *p, GNodeType targetAttr,
* Upon return, the value of the line is unspecified.
*/
static void
ParseDependency(char *line)
ParseDependency(char *line, const char *unexpanded_line)
{
char *p;
SearchPathList *paths; /* search paths to alter when parsing a list
@ -1666,7 +1666,8 @@ ParseDependency(char *line)
targetAttr = OP_NONE;
special = SP_NOT;
if (!ParseDependencyTargets(&p, line, &special, &targetAttr, &paths))
if (!ParseDependencyTargets(&p, line, &special, &targetAttr, &paths,
unexpanded_line))
goto out;
if (!Lst_IsEmpty(targets))
@ -1674,7 +1675,7 @@ ParseDependency(char *line)
op = ParseDependencyOp(&p);
if (op == OP_NONE) {
InvalidLineType(line);
InvalidLineType(line, unexpanded_line);
goto out;
}
ApplyDependencyOperator(op);
@ -2964,7 +2965,7 @@ ParseDependencyLine(char *line)
Lst_Free(targets);
targets = Lst_New();
ParseDependency(expanded_line);
ParseDependency(expanded_line, line);
free(expanded_line);
if (shellcmd != NULL)

View file

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.199 2023/06/20 17:27:20 sjg Exp $
# $Id: Makefile,v 1.207 2023/09/09 16:44:03 sjg Exp $
#
# $NetBSD: Makefile,v 1.339 2023/06/20 09:25:34 rillig Exp $
# $NetBSD: Makefile,v 1.341 2023/09/09 16:41:04 sjg Exp $
#
# Unit tests for make(1)
#
@ -469,10 +469,26 @@ BROKEN_TESTS+= opt-debug-x-trace
BROKEN_TESTS+= sh-flags
.endif
.if ${UTC_1:Uno} == ""
# this will not work if UTC_1 is set empty
BROKEN_TESTS+= varmod-localtime
.endif
.if ${.MAKE.OS:NDarwin} == ""
BROKEN_TESTS+= shell-ksh
.endif
.if ${.MAKE.OS:MIRIX*} != ""
BROKEN_TESTS+= \
cmd-interrupt \
deptgt-interrupt \
job-output-null \
opt-chdir \
opt-debug-x-trace \
sh-leading-hyphen \
.endif
.if ${.MAKE.OS} == "SCO_SV"
BROKEN_TESTS+= \
opt-debug-graph[23] \
@ -600,6 +616,7 @@ 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-mtime+= -e "s,': .*,': <ENOENT>,"
SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
SED_CMDS.varparse-errors+= ${STD_SED_CMDS.timestamp}
SED_CMDS.varname-dot-make-meta-ignore_filter+= ${SED_CMDS.meta-ignore}
@ -639,6 +656,7 @@ STD_SED_CMDS.dg1+= -e '/^\#.*\/mk/d'
STD_SED_CMDS.dg1+= -e 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.JOBS\.C *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MACHINE[_ARCH]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.SHELL *=\) .*,\1 <details omitted>,'

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-eq.mk,v 1.6 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: cond-cmp-numeric-eq.mk,v 1.7 2023/09/07 05:36:33 rillig Exp $
#
# Tests for numeric comparisons with the == operator in .if conditions.
@ -40,7 +40,7 @@
. error
.endif
# As of 2020-08-23, numeric comparison is implemented as parsing both sides
# Numeric comparison works by parsing both sides
# as double, and then performing a normal comparison. The range of double is
# typically 16 or 17 significant digits, therefore these two numbers seem to
# be equal.
@ -78,6 +78,3 @@
.else
. error
.endif
all:
@:;

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-ge.mk,v 1.2 2020/10/24 08:46:08 rillig Exp $
# $NetBSD: cond-cmp-numeric-ge.mk,v 1.3 2023/09/07 05:36:33 rillig Exp $
#
# Tests for numeric comparisons with the >= operator in .if conditions.
@ -62,7 +62,7 @@
. error
.endif
# As of 2020-08-23, numeric comparison is implemented as parsing both sides
# Numeric comparison works by parsing both sides
# as double, and then performing a normal comparison. The range of double is
# typically 16 or 17 significant digits, therefore these two numbers seem to
# be equal.

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-gt.mk,v 1.2 2020/10/24 08:46:08 rillig Exp $
# $NetBSD: cond-cmp-numeric-gt.mk,v 1.3 2023/09/07 05:36:33 rillig Exp $
#
# Tests for numeric comparisons with the > operator in .if conditions.
@ -61,11 +61,11 @@
. error
.endif
# As of 2020-08-23, numeric comparison is implemented as parsing both sides
# Numeric comparison works by parsing both sides
# as double, and then performing a normal comparison. The range of double is
# typically 16 or 17 significant digits, therefore these two numbers seem to
# be equal.
.if 1.000000000000000001 > 1.000000000000000002
.if 1.000000000000000002 > 1.000000000000000001
. error
.endif

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-le.mk,v 1.2 2020/10/24 08:46:08 rillig Exp $
# $NetBSD: cond-cmp-numeric-le.mk,v 1.3 2023/09/07 05:36:33 rillig Exp $
#
# Tests for numeric comparisons with the <= operator in .if conditions.
@ -62,7 +62,7 @@
. error
.endif
# As of 2020-08-23, numeric comparison is implemented as parsing both sides
# Numeric comparison works by parsing both sides
# as double, and then performing a normal comparison. The range of double is
# typically 16 or 17 significant digits, therefore these two numbers seem to
# be equal.

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-lt.mk,v 1.2 2020/10/24 08:46:08 rillig Exp $
# $NetBSD: cond-cmp-numeric-lt.mk,v 1.3 2023/09/07 05:36:33 rillig Exp $
#
# Tests for numeric comparisons with the < operator in .if conditions.
@ -61,7 +61,7 @@
. error
.endif
# As of 2020-08-23, numeric comparison is implemented as parsing both sides
# Numeric comparison works by parsing both sides
# as double, and then performing a normal comparison. The range of double is
# typically 16 or 17 significant digits, therefore these two numbers seem to
# be equal.

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-cmp-numeric-ne.mk,v 1.2 2020/10/24 08:46:08 rillig Exp $
# $NetBSD: cond-cmp-numeric-ne.mk,v 1.3 2023/09/07 05:36:33 rillig Exp $
#
# Tests for numeric comparisons with the != operator in .if conditions.
@ -37,7 +37,7 @@
. error
.endif
# As of 2020-08-23, numeric comparison is implemented as parsing both sides
# Numeric comparison works by parsing both sides
# as double, and then performing a normal comparison. The range of double is
# typically 16 or 17 significant digits, therefore these two numbers seem to
# be equal.

View file

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

View file

@ -1,18 +1,19 @@
# $NetBSD: cond-func-empty.mk,v 1.20 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: cond-func-empty.mk,v 1.22 2023/08/11 05:01:12 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 a variable name, not a variable
# expression, optionally followed by variable modifiers.
# expression. That name may be followed by ':...' modifiers.
#
.undef UNDEF
EMPTY= # empty
SPACE= ${:U }
ZERO= 0
WORD= word
# An undefined variable is empty.
# An undefined variable counts as empty.
.if !empty(UNDEF)
. error
.endif
@ -78,6 +79,17 @@ WORD= word
. error
.endif
# The variable ZERO has the numeric value 0, but is not empty. This is a
# subtle difference between using either 'empty(ZERO)' or the expression
# '${ZERO}' in a condition.
.if empty(ZERO)
. error
.elif ${ZERO}
. error
.elif ${ZERO} == ""
. error
.endif
# The following example constructs an expression with the variable name ""
# and the value " ". This expression counts as empty since the value contains
# only whitespace.
@ -101,7 +113,9 @@ ${:U }= space
. error
.endif
# The value of the following expression is " word", which is not empty.
# The value of the following expression is " word", which is not empty. To be
# empty, _all_ characters in the expression value have to be whitespace, not
# only the first.
.if empty(:U word)
. error
.endif
@ -128,15 +142,15 @@ ${:U }= space
# argument are properly parsed. Typical use cases for this are .for loops,
# which are expanded to exactly these ${:U} expressions.
#
# 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 CondParser_FuncCallEmpty keeps track of the parsing position,
# both before and after the call to Var_Parse.
# The argument expands to "WORD", and that variable is defined at the
# beginning of this file. The surrounding 'W' and 'D' 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
# There may be spaces at the outside of the parentheses.
# There may be spaces outside the parentheses.
# Spaces inside the parentheses are interpreted as part of the variable name.
.if ! empty ( WORD )
. error
@ -181,8 +195,8 @@ ${:U WORD }= variable name with spaces
# 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
# then) though. This had the effect that the ${:U1} from the value of VARNAME
# expansion was done without VARE_WANTRES (called VARF_WANTRES back then)
# though. This had the effect that the ${:U1} from the value of VARNAME
# expanded to an empty string. This in turn created the seemingly recursive
# definition VARNAME=${VARNAME}, and that definition was never meant to be
# expanded.

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-op-and.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: cond-op-and.mk,v 1.8 2023/08/15 21:27:09 rillig Exp $
#
# Tests for the && operator in .if conditions.
@ -76,5 +76,9 @@ DEF= defined
. error
.endif
all:
@:;
# The '&&' operator must be preceded by whitespace, otherwise it becomes part
# of the preceding bare word. The condition is parsed as '"1&&" != "" && 1'.
.if 1&& && 1
.else
. error
.endif

View file

@ -1,4 +1,4 @@
# $NetBSD: cond-op-or.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: cond-op-or.mk,v 1.10 2023/08/15 21:27:09 rillig Exp $
#
# Tests for the || operator in .if conditions.
@ -76,5 +76,9 @@ DEF= defined
. error
.endif
all:
@:;
# The '||' operator must be preceded by whitespace, otherwise it becomes part
# of the preceding bare word. The condition is parsed as '"1||" != "" || 0'.
.if 1|| || 0
.else
. error
.endif

View file

@ -1,4 +1,4 @@
make: "dep-op-missing.tmp" line 1: Invalid line type
make: "dep-op-missing.tmp" line 1: Invalid line 'target'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 0

View file

@ -1,4 +1,4 @@
make: "directive-dinclude-error.inc" line 1: Invalid line type
make: "directive-dinclude-error.inc" line 1: Invalid line 'syntax error'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-dinclude.mk,v 1.2 2022/01/23 21:48:59 rillig Exp $
# $NetBSD: directive-dinclude.mk,v 1.3 2023/08/19 10:52:13 rillig Exp $
#
# Tests for the .dinclude directive, which includes another file,
# silently skipping it if it cannot be opened. This is primarily used for
@ -16,7 +16,7 @@
.dinclude "${MAKEFILE}/subdir"
# Errors that are not related to opening the file are still reported.
# expect: make: "directive-dinclude-error.inc" line 1: Invalid line type
# expect: make: "directive-dinclude-error.inc" line 1: Invalid line 'syntax error'
_!= echo 'syntax error' > directive-dinclude-error.inc
.dinclude "${.CURDIR}/directive-dinclude-error.inc"
_!= rm directive-dinclude-error.inc

View file

@ -1 +1,5 @@
exit status 0
make: "directive-export-gmake.mk" line 71: Invalid line 'export VAR=${:U1}', expanded to 'export VAR=1'
make: "directive-export-gmake.mk" line 85: 16:00:00
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-export-gmake.mk,v 1.3 2020/11/17 20:16:44 rillig Exp $
# $NetBSD: directive-export-gmake.mk,v 1.7 2023/08/20 20:48:32 rillig Exp $
#
# Tests for the export directive (without leading dot), as in GNU make.
@ -60,5 +60,26 @@ export VAR=an ${UNDEF} variable
. error
.endif
all:
@:;
# The body of the .for loop expands to 'export VAR=${:U1}', and the 'export'
# directive is only recognized if the line does not contain a ':', to allow
# 'export' to be a regular target.
.for value in 1
# XXX: The ':' in this line is inside an expression and should thus not be
# interpreted as a dependency operator.
# expect+1: Invalid line 'export VAR=${:U1}'
export VAR=${value}
.endfor
# The 'export' directive expands expressions, but the expressions must not
# contain a ':', due to the overly strict parser. The indirect expressions
# may contain a ':', though.
#
# As a side effect, this test demonstrates that the 'export' directive exports
# the environment variable immediately, other than the '.export' directive,
# which defers that action if the variable value contains a '$'.
INDIRECT_TZ= ${:UAmerica/Los_Angeles}
export TZ=${INDIRECT_TZ}
# expect+1: 16:00:00
.info ${%T:L:localtime=86400}

View file

@ -1 +1,4 @@
make: "directive-export.mk" line 50: 00:00:00
make: "directive-export.mk" line 55: 00:00:00
make: "directive-export.mk" line 58: 16:00:00
exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-export.mk,v 1.8 2021/02/16 19:01:18 rillig Exp $
# $NetBSD: directive-export.mk,v 1.9 2023/08/20 20:48:32 rillig Exp $
#
# Tests for the .export directive.
#
@ -41,4 +41,21 @@ EMPTY_SHELL= ${:sh}
_!= :;: # Force the variable to be actually exported.
# If the '.export' directive exports a variable whose value contains a '$',
# the actual export action is deferred until a subprocess is started, assuming
# that only subprocesses access the environment variables. The ':localtime'
# modifier depends on the 'TZ' environment variable, without any subprocess.
export TZ=${UTC}
# expect+1: 00:00:00
.info ${%T:L:localtime=86400}
INDIRECT_TZ= ${:UAmerica/Los_Angeles}
TZ= ${INDIRECT_TZ}
.export TZ
# expect+1: 00:00:00
.info ${%T:L:localtime=86400}
_!= echo 'force exporting the environment variables'
# expect+1: 16:00:00
.info ${%T:L:localtime=86400}
all:

View file

@ -25,6 +25,22 @@ For: loop body with i = $(V:=-with-modifier):
. info ${:U$(V:=-with-modifier)}
make: "directive-for-escape.mk" line 45: value-with-modifier
For: end for 1
For: loop body with i = $:
. info ${:U\$}
make: "directive-for-escape.mk" line 60: $
For: loop body with i = ${V}:
. info ${:U${V}}
make: "directive-for-escape.mk" line 60: value
For: loop body with i = ${V:=-with-modifier}:
. info ${:U${V:=-with-modifier}}
make: "directive-for-escape.mk" line 60: value-with-modifier
For: loop body with i = $(V):
. info ${:U$(V)}
make: "directive-for-escape.mk" line 60: value
For: loop body with i = $(V:=-with-modifier):
. info ${:U$(V:=-with-modifier)}
make: "directive-for-escape.mk" line 60: value-with-modifier
For: end for 1
For: loop body with i = ${UNDEF:U\$\$:
# ${:U\${UNDEF\:U\\$\\$}
For: loop body with i = {{}}:
@ -34,24 +50,24 @@ For: loop body with i = end}:
For: end for 1
For: loop body with i = ${UNDEF:U\$\$:
. info ${:U\${UNDEF\:U\\$\\$}
make: "directive-for-escape.mk" line 99: ${UNDEF:U\backslash$
make: "directive-for-escape.mk" line 115: ${UNDEF:U\backslash$
For: loop body with i = {{}}:
. info ${:U{{\}\}}
make: "directive-for-escape.mk" line 99: {{}}
make: "directive-for-escape.mk" line 115: {{}}
For: loop body with i = end}:
. info ${:Uend\}}
make: "directive-for-escape.mk" line 99: end}
make: "directive-for-escape.mk" line 115: end}
For: end for 1
For: loop body with i = begin<${UNDEF:Ufallback:N{{{}}}}>end:
. info ${:Ubegin<${UNDEF:Ufallback:N{{{}}}}>end}
make: "directive-for-escape.mk" line 120: begin<fallback>end
make: "directive-for-escape.mk" line 136: begin<fallback>end
For: end for 1
For: loop body with i = $:
. info ${:U\$}
make: "directive-for-escape.mk" line 129: $
make: "directive-for-escape.mk" line 138: invalid character ':' in .for loop variable name
make: "directive-for-escape.mk" line 145: $
make: "directive-for-escape.mk" line 154: invalid character ':' in .for loop variable name
For: end for 1
make: "directive-for-escape.mk" line 148: invalid character '}' in .for loop variable name
make: "directive-for-escape.mk" line 164: invalid character '}' in .for loop variable name
For: end for 1
For: end for 1
For: loop body with i = inner:
@ -65,45 +81,45 @@ For: loop body with i = inner:
. info . $${i2}: ${i2}
. info . $${i,}: ${i,}
. info . adjacent: ${:Uinner}${:Uinner}${:Uinner:M*}${:Uinner}
make: "directive-for-escape.mk" line 157: . $i: inner
make: "directive-for-escape.mk" line 158: . ${i}: inner
make: "directive-for-escape.mk" line 159: . ${i:M*}: inner
make: "directive-for-escape.mk" line 160: . $(i): inner
make: "directive-for-escape.mk" line 161: . $(i:M*): inner
make: "directive-for-escape.mk" line 162: . ${i${:U}}: outer
make: "directive-for-escape.mk" line 163: . ${i\}}: inner}
make: "directive-for-escape.mk" line 164: . ${i2}: two
make: "directive-for-escape.mk" line 165: . ${i,}: comma
make: "directive-for-escape.mk" line 166: . adjacent: innerinnerinnerinner
make: "directive-for-escape.mk" line 185: invalid character '$' in .for loop variable name
make: "directive-for-escape.mk" line 173: . $i: inner
make: "directive-for-escape.mk" line 174: . ${i}: inner
make: "directive-for-escape.mk" line 175: . ${i:M*}: inner
make: "directive-for-escape.mk" line 176: . $(i): inner
make: "directive-for-escape.mk" line 177: . $(i:M*): inner
make: "directive-for-escape.mk" line 178: . ${i${:U}}: outer
make: "directive-for-escape.mk" line 179: . ${i\}}: inner}
make: "directive-for-escape.mk" line 180: . ${i2}: two
make: "directive-for-escape.mk" line 181: . ${i,}: comma
make: "directive-for-escape.mk" line 182: . adjacent: innerinnerinnerinner
make: "directive-for-escape.mk" line 201: invalid character '$' in .for loop variable name
For: end for 1
make: "directive-for-escape.mk" line 197: eight and no cents.
make: "directive-for-escape.mk" line 213: eight and no cents.
For: end for 1
make: "directive-for-escape.mk" line 210: newline in .for value
make: "directive-for-escape.mk" line 210: newline in .for value
make: "directive-for-escape.mk" line 226: newline in .for value
make: "directive-for-escape.mk" line 226: newline in .for value
For: loop body with i = "
":
. info short: ${:U" "}
. info long: ${:U" "}
make: "directive-for-escape.mk" line 211: short: " "
make: "directive-for-escape.mk" line 212: long: " "
make: "directive-for-escape.mk" line 227: short: " "
make: "directive-for-escape.mk" line 228: long: " "
For: end for 1
For: loop body with i = "
":
For: end for 1
Parse_PushInput: .for loop in directive-for-escape.mk, line 228
make: "directive-for-escape.mk" line 228: newline in .for value
in .for loop from directive-for-escape.mk:228 with i = "
Parse_PushInput: .for loop in directive-for-escape.mk, line 244
make: "directive-for-escape.mk" line 244: newline in .for value
in .for loop from directive-for-escape.mk:244 with i = "
"
For: loop body with i = "
":
: ${:U" "}
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
Parsing line 229: : ${:U" "}
Parsing line 245: : ${:U" "}
ParseDependency(: " ")
ParseEOF: returning to file directive-for-escape.mk, line 231
ParseEOF: returning to file directive-for-escape.mk, line 247
SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `directive-for-escape.mk'
Parsing line 231: .MAKEFLAGS: -d0
Parsing line 247: .MAKEFLAGS: -d0
ParseDependency(.MAKEFLAGS: -d0)
For: end for 1
For: loop body with i = #:
@ -143,6 +159,11 @@ For: loop body with i = ))):
# ${:U)))}
For: loop body with i = }}}:
# ${:U\}\}\}}
For: end for 1
For: loop body with , = 1:
# $$i $i
# VAR= $$i $i ${a:S,from${:U1}to,}
VAR= $$i $i ${a:S,from${:U1}to,}
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-for-escape.mk,v 1.20 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: directive-for-escape.mk,v 1.21 2023/06/23 06:11:06 rillig Exp $
#
# Test escaping of special characters in the iteration values of a .for loop.
# These values get expanded later using the :U variable modifier, and this
@ -44,12 +44,28 @@ VALUES= $$ $${V} $${V:=-with-modifier} $$(V) $$(V:=-with-modifier)
.for i in ${VALUES}
. info $i
.endfor
# expect-2: $
# expect-3: value
# expect-4: value-with-modifier
# expect: . info ${:U\$}
# expect-3: $
# expect: . info ${:U${V}}
# expect-5: value
# expect: . info ${:U${V:=-with-modifier}}
# expect-7: value-with-modifier
# expect: . info ${:U$(V)}
# expect-9: value
# expect: . info ${:U$(V:=-with-modifier)}
# expect-11: value-with-modifier
#
# Providing the loop items directly has the same effect.
.for i in $$ $${V} $${V:=-with-modifier} $$(V) $$(V:=-with-modifier)
. info $i
.endfor
# expect: . info ${:U\$}
# expect-3: $
# expect: . info ${:U${V}}
# expect-5: value
# expect-6: value-with-modifier
# expect-7: value
# expect-8: value-with-modifier
# Try to cover the code for nested '{}' in ExprLen, without success.
#
@ -256,6 +272,22 @@ ${closing-brace}= <closing-brace> # alternative interpretation
.for i in ((( {{{ ))) }}}
# $i
.endfor
.MAKEFLAGS: -d0
all:
# When generating the body of a .for loop, recognizing the expressions is done
# using simple heuristics. These can go wrong in ambiguous cases like this.
# The variable name ',' is unusual as it is not a pronounceable name, but the
# same principle applies for other names as well. In this case, the text '$,'
# is replaced with the expression '${:U1}', even though the text does not
# represent an expression.
.for , in 1
# $$i $i
# VAR= $$i $i ${a:S,from$,to,}
VAR= $$i $i ${a:S,from$,to,}
.endfor
# expect: # $$i $i
# expect: # VAR= $$i $i ${a:S,from${:U1}to,}
# expect: VAR= $$i $i ${a:S,from${:U1}to,}
#
# When the above variable is evaluated, make will complain about the
# unfinished modifier ':S', as it is missing a comma.

View file

@ -1,4 +1,4 @@
make: "directive-hyphen-include-error.inc" line 1: Invalid line type
make: "directive-hyphen-include-error.inc" line 1: Invalid line 'syntax error'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-hyphen-include.mk,v 1.2 2022/01/23 21:48:59 rillig Exp $
# $NetBSD: directive-hyphen-include.mk,v 1.3 2023/08/19 10:52:13 rillig Exp $
#
# Tests for the .-include directive, which includes another file,
# silently skipping it if it cannot be opened.
@ -15,7 +15,7 @@
.-include "${MAKEFILE}/subdir"
# Errors that are not related to opening the file are still reported.
# expect: make: "directive-hyphen-include-error.inc" line 1: Invalid line type
# expect: make: "directive-hyphen-include-error.inc" line 1: Invalid line 'syntax error'
_!= echo 'syntax error' > directive-hyphen-include-error.inc
.-include "${.CURDIR}/directive-hyphen-include-error.inc"
_!= rm directive-hyphen-include-error.inc

View file

@ -51,14 +51,14 @@ Parse_PushInput: file variable-undef-inside.tmp, line 1
Parse_PushInput: file variable-undef-inside.tmp, line 1
Parse_PushInput: file variable-not-defined.tmp, line 1
Parse_PushInput: file variable-not-defined.tmp, line 1
Parse_PushInput: file if-elif.tmp, line 1
Parse_PushInput: file if-elif.tmp, line 1
Parse_PushInput: file if-elif-reuse.tmp, line 1
Parse_PushInput: file if-elif-reuse.tmp, line 1
Parse_PushInput: file if-else.tmp, line 1
Parse_PushInput: file if-else.tmp, line 1
Parse_PushInput: file if-else-reuse.tmp, line 1
Parse_PushInput: file if-else-reuse.tmp, line 1
Parse_PushInput: file elif.tmp, line 1
Parse_PushInput: file elif.tmp, line 1
Parse_PushInput: file elif-reuse.tmp, line 1
Parse_PushInput: file elif-reuse.tmp, line 1
Parse_PushInput: file else.tmp, line 1
Parse_PushInput: file else.tmp, line 1
Parse_PushInput: file else-reuse.tmp, line 1
Parse_PushInput: file else-reuse.tmp, line 1
Parse_PushInput: file inner-if-elif-else.tmp, line 1
Skipping 'inner-if-elif-else.tmp' because 'INNER_IF_ELIF_ELSE' is defined
Parse_PushInput: file target.tmp, line 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-include-guard.mk,v 1.11 2023/06/21 21:21:52 sjg Exp $
# $NetBSD: directive-include-guard.mk,v 1.12 2023/08/11 04:56:31 rillig Exp $
#
# Tests for multiple-inclusion guards in makefiles.
#
@ -112,9 +112,10 @@ LINES.variable-name-mismatch= \
# The variable name '!VARNAME' cannot be used in an '.ifndef' directive, as
# the '!' would be a negation. It is syntactically valid in a '.if !defined'
# condition, but ignored there. Furthermore, when defining the variable, the
# character '!' has to be escaped, to prevent it from being interpreted as the
# '!' dependency operator.
# condition, but this case is so uncommon that the guard mechanism doesn't
# accept '!' in the guard variable name. Furthermore, when defining the
# variable, the character '!' has to be escaped, to prevent it from being
# interpreted as the '!' dependency operator.
INCS+= variable-name-exclamation
LINES.variable-name-exclamation= \
'.if !defined(!VARIABLE_NAME_EXCLAMATION)' \
@ -189,9 +190,9 @@ LINES.variable-if-indirect= \
# expect: Parse_PushInput: file variable-if-indirect.tmp, line 1
# The variable name in the guard condition must only contain alphanumeric
# characters and underscores. The guard variable is more flexible, it can be
# defined anywhere, as long as it is defined at the point where the file is
# included the next time.
# characters and underscores. The place where the guard variable is defined
# is more flexible, as long as the variable is defined at the point where the
# file is included the next time.
INCS+= variable-assign-indirect
LINES.variable-assign-indirect= \
'.ifndef VARIABLE_ASSIGN_INDIRECT' \
@ -254,9 +255,9 @@ UNDEF_BETWEEN.variable-defined-then-undefined= \
# expect: Parse_PushInput: file variable-defined-then-undefined.tmp, line 1
# The whole file content must be guarded by a single '.if' conditional, not by
# several, even if they have the same effect. This case is not expected to
# occur in practice, as the two parts would rather be split into separate
# files.
# several, as each of these conditionals would require its separate guard.
# This case is not expected to occur in practice, as the two parts would
# rather be split into separate files.
INCS+= variable-two-times
LINES.variable-two-times= \
'.ifndef VARIABLE_TWO_TIMES_1' \
@ -324,46 +325,46 @@ LINES.variable-not-defined= \
# expect: Parse_PushInput: file variable-not-defined.tmp, line 1
# The outermost '.if' must not have an '.elif' branch.
INCS+= if-elif
LINES.if-elif= \
'.ifndef IF_ELIF' \
'IF_ELIF=' \
INCS+= elif
LINES.elif= \
'.ifndef ELIF' \
'ELIF=' \
'.elif 1' \
'.endif'
# expect: Parse_PushInput: file if-elif.tmp, line 1
# expect: Parse_PushInput: file if-elif.tmp, line 1
# expect: Parse_PushInput: file elif.tmp, line 1
# expect: Parse_PushInput: file elif.tmp, line 1
# When a file with an '.if/.elif/.endif' conditional at the top level is
# included, it is never optimized, as one of its branches is taken.
INCS+= if-elif-reuse
LINES.if-elif-reuse= \
'.ifndef IF_ELIF' \
INCS+= elif-reuse
LINES.elif-reuse= \
'.ifndef ELIF' \
'syntax error' \
'.elif 1' \
'.endif'
# expect: Parse_PushInput: file if-elif-reuse.tmp, line 1
# expect: Parse_PushInput: file if-elif-reuse.tmp, line 1
# expect: Parse_PushInput: file elif-reuse.tmp, line 1
# expect: Parse_PushInput: file elif-reuse.tmp, line 1
# The outermost '.if' must not have an '.else' branch.
INCS+= if-else
LINES.if-else= \
'.ifndef IF_ELSE' \
'IF_ELSE=' \
INCS+= else
LINES.else= \
'.ifndef ELSE' \
'ELSE=' \
'.else' \
'.endif'
# expect: Parse_PushInput: file if-else.tmp, line 1
# expect: Parse_PushInput: file if-else.tmp, line 1
# expect: Parse_PushInput: file else.tmp, line 1
# expect: Parse_PushInput: file else.tmp, line 1
# When a file with an '.if/.else/.endif' conditional at the top level is
# included, it is never optimized, as one of its branches is taken.
INCS+= if-else-reuse
LINES.if-else-reuse= \
'.ifndef IF_ELSE' \
INCS+= else-reuse
LINES.else-reuse= \
'.ifndef ELSE' \
'syntax error' \
'.else' \
'.endif'
# expect: Parse_PushInput: file if-else-reuse.tmp, line 1
# expect: Parse_PushInput: file if-else-reuse.tmp, line 1
# expect: Parse_PushInput: file else-reuse.tmp, line 1
# expect: Parse_PushInput: file else-reuse.tmp, line 1
# The inner '.if' directives may have an '.elif' or '.else', and it doesn't
# matter which of their branches are taken.
@ -451,17 +452,17 @@ LINES.target-indirect-PARSEFILE2= \
# Using plain .PARSEFILE without .PARSEDIR leads to name clashes. The include
# guard is the same as in the test case 'target-indirect-PARSEFILE', as the
# guard name only contains the basename but not the directory name.
# guard name only contains the basename but not the directory name. So even
# without defining the guard variable, the file is considered guarded.
INCS+= subdir/target-indirect-PARSEFILE
LINES.subdir/target-indirect-PARSEFILE= \
'.if !target(__$${.PARSEFILE}__)' \
'__$${.PARSEFILE}__: .NOTMAIN' \
'.endif'
# expect: Parse_PushInput: file subdir/target-indirect-PARSEFILE.tmp, line 1
# expect: Skipping 'subdir/target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
# Another common form of guard target is __${.PARSEDIR}/${.PARSEFILE}__
# or __${.PARSEDIR:tA}/${.PARSEFILE}__ to be truely unique.
# or __${.PARSEDIR:tA}/${.PARSEFILE}__ to be truly unique.
INCS+= target-indirect-PARSEDIR-PARSEFILE
LINES.target-indirect-PARSEDIR-PARSEFILE= \
'.if !target(__$${.PARSEDIR}/$${.PARSEFILE}__)' \
@ -503,7 +504,7 @@ LINES.target-plus= \
# expect: Parse_PushInput: file target-plus.tmp, line 1
# If the guard target is defined before the file is included the first time,
# the file is not considered guarded.
# the file is read once and then considered guarded.
INCS+= target-already-defined
LINES.target-already-defined= \
'.if !target(target-already-defined)' \
@ -530,6 +531,7 @@ LINES.target-name-exclamation= \
# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
# expect: Parse_PushInput: file target-name-exclamation.tmp, line 1
# Now run all test cases by including each of the files twice and looking at
# the debug output. The files that properly guard against multiple inclusion
# generate a 'Skipping' line, the others repeat the 'Parse_PushInput' line.

View file

@ -7,7 +7,7 @@ make: "directive-include.mk" line 49: Could not find "
make: "directive-include.mk" line 56: Unknown modifier "Z"
make: "directive-include.mk" line 56: Could not find nonexistent.mk
make: "directive-include.mk" line 61: Cannot open /nonexistent
make: "directive-include.mk" line 66: Invalid line type
make: "directive-include.mk" line 66: Invalid line 'include'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-include.mk,v 1.12 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: directive-include.mk,v 1.13 2023/08/19 10:52:14 rillig Exp $
#
# Tests for the .include directive, which includes another file.
@ -62,7 +62,7 @@ include /nonexistent # comment
sinclude /nonexistent # comment
include ${:U/dev/null} # comment
include /dev/null /dev/null
# expect+1: Invalid line type
# expect+1: Invalid line 'include'
include
# XXX: trailing whitespace in diagnostic, missing quotes around filename

View file

@ -1,4 +1,4 @@
make: "directive-include-error.inc" line 1: Invalid line type
make: "directive-include-error.inc" line 1: Invalid line 'syntax error'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive-sinclude.mk,v 1.4 2022/01/23 21:48:59 rillig Exp $
# $NetBSD: directive-sinclude.mk,v 1.5 2023/08/19 10:52:14 rillig Exp $
#
# Tests for the .sinclude directive, which includes another file,
# silently skipping it if it cannot be opened.
@ -15,7 +15,7 @@
.sinclude "${MAKEFILE}/subdir"
# Errors that are not related to opening the file are still reported.
# expect: make: "directive-include-error.inc" line 1: Invalid line type
# expect: make: "directive-include-error.inc" line 1: Invalid line 'syntax error'
_!= echo 'syntax error' > directive-include-error.inc
.sinclude "${.CURDIR}/directive-include-error.inc"
_!= rm directive-include-error.inc

View file

@ -1,14 +1,14 @@
make: "directive.mk" line 10: Unknown directive "indented"
make: "directive.mk" line 12: Unknown directive "indented"
make: "directive.mk" line 14: Unknown directive "indented"
make: "directive.mk" line 21: Unknown directive "info"
make: "directive.mk" line 19: Unknown directive ""
Global: .info = # (empty)
Global: .info = value
make: "directive.mk" line 33: := value
make: "directive.mk" line 31: := value
Global: .MAKEFLAGS = -r -k -d v -d
Global: .MAKEFLAGS = -r -k -d v -d 0
make: "directive.mk" line 42: Invalid line type
make: "directive.mk" line 45: Invalid line type
make: "directive.mk" line 40: Invalid line 'target-without-colon'
make: "directive.mk" line 43: Invalid line 'target-without-colon another-target'
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: directive.mk,v 1.6 2022/01/23 16:09:38 rillig Exp $
# $NetBSD: directive.mk,v 1.8 2023/08/19 11:09:02 rillig Exp $
#
# Tests for the preprocessing directives, such as .if or .info.
@ -15,9 +15,7 @@
# Directives must be written directly, not indirectly via variable
# expressions.
# FIXME: The error message is misleading because it shows the expanded text of
# the line, while the parser works on the unexpanded line.
# expect+1: Unknown directive "info"
# expect+1: Unknown directive ""
.${:Uinfo} directives cannot be indirect
# There is no directive called '.target', therefore this is parsed as a
@ -38,8 +36,8 @@
# Not even the space after the '.info' can change anything about this.
.${:Uinfo} : source
# expect+1: Invalid line type
# expect+1: Invalid line 'target-without-colon'
target-without-colon
# expect+1: Invalid line type
# expect+1: Invalid line 'target-without-colon another-target'
target-without-colon another-target

View file

@ -21,6 +21,7 @@
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
.MAKE.JOBS.C = <details omitted>
.MAKE.LEVEL = <details omitted>
.MAKE.MAKEFILES = <details omitted>
.MAKE.MAKEFILE_PREFERENCE = <details omitted>

View file

@ -55,6 +55,7 @@ all : made-target error-target aborted-target
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
.MAKE.JOBS.C = <details omitted>
.MAKE.LEVEL = <details omitted>
.MAKE.MAKEFILES = <details omitted>
.MAKE.MAKEFILE_PREFERENCE = <details omitted>

View file

@ -55,6 +55,7 @@ all : made-target error-target aborted-target
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
.MAKE.JOBS.C = <details omitted>
.MAKE.LEVEL = <details omitted>
.MAKE.MAKEFILES = <details omitted>
.MAKE.MAKEFILE_PREFERENCE = <details omitted>

View file

@ -1,8 +1,54 @@
# $NetBSD: opt-jobs.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
# $NetBSD: opt-jobs.mk,v 1.5 2023/09/10 16:25:32 sjg Exp $
#
# Tests for the -j command line option.
# Tests for the -j command line option, which creates the targets in parallel.
# TODO: Implementation
all:
@:;
# The option '-j <integer>' specifies the number of targets that can be made
# in parallel.
ARGS= 0 1 2 8 08 017 0x10 -5 1000
EXPECT.0= argument '0' to option '-j' must be a positive number (exit 2)
EXPECT.1= 1
EXPECT.2= 2
EXPECT.8= 8
EXPECT.08= argument '08' to option '-j' must be a positive number (exit 2)
EXPECT.017= 15
EXPECT.0x10= 16
EXPECT.-5= argument '-5' to option '-j' must be a positive number (exit 2)
EXPECT.1000= 1000
.for arg in ${ARGS}
OUTPUT!= ${MAKE} -r -f /dev/null -j ${arg} -v .MAKE.JOBS 2>&1 || echo "(exit $$?)"
. if ${OUTPUT:[2..-1]} != ${EXPECT.${arg}}
. warning ${arg}:${.newline} have: ${OUTPUT:[2..-1]}${.newline} want: ${EXPECT.${arg}}
. endif
.endfor
# The options '-j <float>' and '-j <integer>C' multiply the given number with
# the number of available CPUs.
ARGS= 0.0 0C 0.0C .00001 .00001C 1C 1CPUs 1.2 .5e1C 07.5C 08.5C
EXPECT.0.0= argument '0.0' to option '-j' must be a positive number (exit 2)
EXPECT.0C= <integer> # rounded up to 1C
EXPECT.0.0C= argument '0.0C' to option '-j' must be a positive number (exit 2)
EXPECT..00001= argument '.00001' to option '-j' must be a positive number (exit 2)
EXPECT..00001C= argument '.00001C' to option '-j' must be a positive number (exit 2)
EXPECT.1C= <integer>
EXPECT.1CPUs= <integer>
EXPECT.1.2= <integer>
EXPECT..5e1C= <integer> # unlikely to occur in practice
EXPECT.07.5C= <integer>
EXPECT.08.5C= argument '08.5C' to option '-j' must be a positive number (exit 2)
.if ${.MAKE.JOBS.C} == "yes"
. for arg in ${ARGS}
OUTPUT!= ${MAKE} -r -f /dev/null -j ${arg} -v .MAKE.JOBS 2>&1 || echo "(exit $$?)"
. if ${OUTPUT:C,^[0-9]+$,numeric,W} == numeric
OUTPUT= <integer>
. endif
. if ${OUTPUT:[2..-1]} != ${EXPECT.${arg}}
. warning ${arg}:${.newline} have: ${OUTPUT:[2..-1]}${.newline} want: ${EXPECT.${arg}}
. endif
. endfor
.endif
all: .PHONY

View file

@ -1,6 +1,6 @@
make: "parse.mk" line 7: Makefile appears to contain unresolved CVS/RCS/??? merge conflicts
make: "parse.mk" line 14: Makefile appears to contain unresolved CVS/RCS/??? merge conflicts
make: "parse.mk" line 25: Invalid line type
make: "parse.mk" line 7: Invalid line '<<<<<< old'
make: "parse.mk" line 14: Invalid line '>>>>>> new'
make: "parse.mk" line 25: Invalid line 'one-target ${:U }', expanded to 'one-target '
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,16 +1,16 @@
# $NetBSD: parse.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: parse.mk,v 1.7 2023/08/19 11:09:02 rillig Exp $
#
# Test those parts of the parsing that do not belong in any of the other
# categories.
# expect+1: Makefile appears to contain unresolved CVS/RCS/??? merge conflicts
# expect+1: Invalid line '<<<<<< old'
<<<<<< old
# No diagnostic since the following line is parsed as a variable assignment,
# even though the variable name is empty. See also varname-empty.mk.
====== middle
# expect+1: Makefile appears to contain unresolved CVS/RCS/??? merge conflicts
# expect+1: Invalid line '>>>>>> new'
>>>>>> new
@ -21,7 +21,7 @@
# the expanded line's terminating '\0'.
#
# https://bugs.freebsd.org/265119
# expect+1: Invalid line type
# expect+1: Invalid line 'one-target ${:U }', expanded to 'one-target '
one-target ${:U }

View file

@ -86,6 +86,7 @@ ParseDependency(.MAKEFLAGS: -d0 -dg1)
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
.MAKE.JOBS.C = <details omitted>
.MAKE.LEVEL = <details omitted>
.MAKE.MAKEFILES = <details omitted>
.MAKE.MAKEFILE_PREFERENCE = <details omitted>

View file

@ -12,6 +12,7 @@
.MAKE = <details omitted>
.MAKE.DEPENDFILE = <details omitted>
.MAKE.GID = <details omitted>
.MAKE.JOBS.C = <details omitted>
.MAKE.LEVEL = <details omitted>
.MAKE.MAKEFILES = <details omitted>
.MAKE.MAKEFILE_PREFERENCE = <details omitted>

View file

@ -1,5 +1,5 @@
this will be evaluated later
make: "var-op-assign.mk" line 60: Invalid line type
make: "var-op-assign.mk" line 60: Invalid line 'VARIABLE NAME= variable value'
make: "var-op-assign.mk" line 95: Parsing still continues until here.
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests

View file

@ -1,4 +1,4 @@
# $NetBSD: var-op-assign.mk,v 1.9 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: var-op-assign.mk,v 1.10 2023/08/19 10:52:14 rillig Exp $
#
# Tests for the = variable assignment operator, which overwrites an existing
# variable or creates it.
@ -56,7 +56,7 @@ VAR= ${:! echo 'this will be evaluated later' 1>&2 !}
# In a variable assignment, the variable name must consist of a single word.
# The following line therefore generates a parse error.
# expect+1: Invalid line type
# expect+1: Invalid line 'VARIABLE NAME= variable value'
VARIABLE NAME= variable value
# But if the whitespace appears inside parentheses or braces, everything is

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-gmtime.mk,v 1.15 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: varmod-gmtime.mk,v 1.19 2023/08/19 11:53:10 rillig Exp $
#
# Tests for the :gmtime variable modifier, which formats a timestamp
# using strftime(3) in UTC.
@ -145,4 +145,33 @@
. error
.endif
# Before var.c 1.1062 from 2023-08-19, ':gmtime' but not ':localtime' reported
# wrong values for '%s', depending on the operating system and the timezone.
export TZ=UTC
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=Europe/Berlin
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=UTC
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=America/Los_Angeles
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=UTC
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
.for a b in ${TIMESTAMPS:[1]} ${TIMESTAMPS:@t@$t $t@} ${TIMESTAMPS:[-1]}
. if $a > $b
. warning timestamp $a > $b
. endif
.endfor
all:

View file

@ -16,17 +16,17 @@ CondParser_Eval: ${VAR} == value
Comparing "value" == "value"
Comparing "ok" != "ok"
make: "varmod-ifelse.mk" line 158: no.
make: "varmod-ifelse.mk" line 161: Comparison with '>=' requires both operands 'no' and '10' to be numeric
make: "varmod-ifelse.mk" line 162: Comparison with '>=' requires both operands 'no' and '10' to be numeric
make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no'
make: "varmod-ifelse.mk" line 161: .
make: "varmod-ifelse.mk" line 162: .
make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no'
make: "varmod-ifelse.mk" line 167: .
make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no'
make: "varmod-ifelse.mk" line 169: .
make: "varmod-ifelse.mk" line 177: true
make: "varmod-ifelse.mk" line 180: false
make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no'
make: "varmod-ifelse.mk" line 172: .
make: "varmod-ifelse.mk" line 180: <true>
make: "varmod-ifelse.mk" line 183: <false>
make: Bad conditional expression ' ' in ' ?true:false'
make: "varmod-ifelse.mk" line 182:
make: "varmod-ifelse.mk" line 186: <>
CondParser_Eval: 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated"
CondParser_Eval: 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1"
CondParser_Eval: 0
@ -34,6 +34,18 @@ Comparing "else1" != "else1"
CondParser_Eval: 2 && ${1:?${:Uthen2:S,}},,}:${:Uelse2:S,}},,}} != "then2"
CondParser_Eval: 1
Comparing "then2" != "then2"
CondParser_Eval: ${DELAYED} == "one"
Comparing "two" == "one"
make: "varmod-ifelse.mk" line 282: no
CondParser_Eval: ${DELAYED} == "two"
Comparing "two" == "two"
make: "varmod-ifelse.mk" line 284: yes
CondParser_Eval: ${DELAYED} == "one"
Comparing "two" == "one"
make: "varmod-ifelse.mk" line 287: no
CondParser_Eval: ${DELAYED} == "two"
Comparing "two" == "two"
make: "varmod-ifelse.mk" line 290: yes
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,4 +1,4 @@
# $NetBSD: varmod-ifelse.mk,v 1.22 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: varmod-ifelse.mk,v 1.23 2023/07/01 09:06:34 rillig Exp $
#
# Tests for the ${cond:?then:else} variable modifier, which evaluates either
# the then-expression or the else-expression, depending on the condition.
@ -97,11 +97,11 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign}
.endif
.MAKEFLAGS: -d0
# As of 2020-12-10, the variable "name" is first expanded, and the result of
# As of 2020-12-10, the variable "VAR" is first expanded, and the result of
# this expansion is then taken as the condition. To force the variable
# expression in the condition to be evaluated at exactly the right point,
# the '$' of the intended '${VAR}' escapes from the parser in form of the
# expression ${:U\$}. Because of this escaping, the variable "name" and thus
# expression ${:U\$}. Because of this escaping, the variable "VAR" and thus
# the condition ends up as "${VAR} == value", just as intended.
#
# This hack does not work for variables from .for loops since these are
@ -156,15 +156,18 @@ STRING= string
NUMBER= no # not really a number
# expect+1: no.
.info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}.
# expect+2: .
# expect+1: Comparison with '>=' requires both operands 'no' and '10' to be numeric
# expect+3: Comparison with '>=' requires both operands 'no' and '10' to be numeric
# expect: make: Bad conditional expression 'string == "literal" || no >= 10' in 'string == "literal" || no >= 10?yes:no'
# expect+1: .
.info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}.
# The following situation occasionally occurs with MKINET6 or similar
# variables.
NUMBER= # empty, not really a number either
# expect: make: Bad conditional expression 'string == "literal" && >= 10' in 'string == "literal" && >= 10?yes:no'
# expect+1: .
.info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}.
# expect: make: Bad conditional expression 'string == "literal" || >= 10' in 'string == "literal" || >= 10?yes:no'
# expect+1: .
.info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}.
@ -173,13 +176,14 @@ PLUS= +
ASTERISK= *
EMPTY= # empty
# "true" since "+" is not the empty string.
# expect+1: true
.info ${${PLUS} :?true:false}
# expect+1: <true>
.info <${${PLUS} :?true:false}>
# "false" since the variable named "*" is not defined.
# expect+1: false
.info ${${ASTERISK} :?true:false}
# expect+1: <false>
.info <${${ASTERISK} :?true:false}>
# syntax error since the condition is completely blank.
.info ${${EMPTY} :?true:false}
# expect+1: <>
.info <${${EMPTY} :?true:false}>
# Since the condition of the '?:' modifier is expanded before being parsed and
@ -256,4 +260,34 @@ PRIMES= 2 3 5 7 11
# with the 'then2' formed the result 'then2,,}}'.
. error
.endif
# Since the condition is taken from the variable name of the expression, not
# from its value, it is evaluated early. It is possible though to construct
# conditions that are evaluated lazily, at exactly the right point. There is
# no way to escape a '$' directly in the variable name, but there are
# alternative ways to bring a '$' into the condition.
#
# In an indirect condition using the ':U' modifier, each '$', ':' and
# '}' must be escaped as '\$', '\:' and '\}', respectively, but '{' must
# not be escaped.
#
# In an indirect condition using a separate variable, each '$' must be
# escaped as '$$'.
#
# These two forms allow the variables to contain arbitrary characters, as the
# condition parser does not see them.
DELAYED= two
# expect+1: no
.info ${ ${:U \${DELAYED\} == "one"}:?yes:no}
# expect+1: yes
.info ${ ${:U \${DELAYED\} == "two"}:?yes:no}
INDIRECT_COND1= $${DELAYED} == "one"
# expect+1: no
.info ${ ${INDIRECT_COND1}:?yes:no}
INDIRECT_COND2= $${DELAYED} == "two"
# expect+1: yes
.info ${ ${INDIRECT_COND2}:?yes:no}
.MAKEFLAGS: -d0

View file

@ -1 +1,8 @@
exit status 0
make: "varmod-mtime.mk" line 60: Cannot determine mtime for 'no/such/file1': <ENOENT>
make: "varmod-mtime.mk" line 60: Cannot determine mtime for 'no/such/file2': <ENOENT>
make: "varmod-mtime.mk" line 60: Malformed conditional (${no/such/file1 no/such/file2:L:mtime=error})
make: "varmod-mtime.mk" line 71: Invalid argument 'errorhandler-no' for modifier ':mtime'
make: "varmod-mtime.mk" line 71: Malformed conditional (${MAKEFILE:mtime=errorhandler-no} > 0)
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View file

@ -1,30 +1,82 @@
# $NetBSD: varmod-mtime.mk,v 1.1 2023/05/09 20:14:27 sjg Exp $
# $NetBSD: varmod-mtime.mk,v 1.5 2023/08/19 08:19:25 rillig Exp $
#
# Tests for the :mtime variable modifier, which provides mtime
# of variable value assumed to be a pathname.
# Tests for the ':mtime' variable modifier, which maps each word of the
# expression to that file's modification time.
all:
# Note: strftime() uses mktime() for %s and mktime() assumes localtime
# so this should match time()
start:= ${%s:L:localtime} # see varmod-gmtime.mk, keyword '%s'
# mtime of this makefile
mtime:= ${MAKEFILE:mtime}
# if pathname does not exist and timestamp is provided
# that is the result
.if ${no/such:L:mtime=0} != "0"
# Ensure that this makefile exists and has a modification time. If the file
# didn't exist, the ':mtime' modifier would return the current time.
.if ${MAKEFILE:mtime} >= ${start}
. error
.endif
.if ${no/such:L:mtime=42} != "42"
# For a file that doesn't exist, the ':mtime' modifier returns the current
# time, without an error or warning message. The returned timestamp differs
# from the 'now' that is used when updating the timestamps in archives or for
# touching files using the '-t' option, which is taken once when make is
# started.
not_found_mtime:= ${no/such/file:L:mtime}
.if ${not_found_mtime} < ${start}
. error
.endif
# if no timestamp is provided and stat(2) fails use current time
.if ${no/such:L:mtime} < ${mtime}
. error no/such:L:mtime ${no/such:L:mtime} < ${mtime}
# The ':mtime' modifier accepts a timestamp in seconds as an optional
# argument. This timestamp is used as a fallback in case the file's time
# cannot be determined, without any error or warning message.
.if ${no/such/file:L:mtime=0} != "0"
. error
.endif
COOKIE = ${TMPDIR}/varmod-mtime.cookie
x!= touch ${COOKIE}
.if ${COOKIE:mtime=0} < ${mtime}
. error COOKIE:mtime=0 ${COOKIE:mtime=0} < ${mtime}
# The fallback timestamp must start with a digit, and it is interpreted as a
# decimal integer.
.if ${no/such/file:L:mtime=00042} != "42"
. error
.endif
# The timestamp of a newly created file must be at least as great as the
# timestamp when parsing of this makefile started.
COOKIE= ${TMPDIR:U/tmp}/varmod-mtime.cookie
_!= touch ${COOKIE}
.if ${COOKIE:mtime=0} < ${start}
. error ${COOKIE:mtime=0} < ${start}
.endif
_!= rm -f ${COOKIE}
# If the optional argument of the ':mtime' modifier is the word 'error', the
# modifier fails with an error message, once for each affected file.
#
# expect+3: Cannot determine mtime for 'no/such/file1': <ENOENT>
# expect+2: Cannot determine mtime for 'no/such/file2': <ENOENT>
# expect+1: Malformed conditional (${no/such/file1 no/such/file2:L:mtime=error})
.if ${no/such/file1 no/such/file2:L:mtime=error}
. error
.else
. error
.endif
# Only the word 'error' is a special argument to the ':mtime' modifier, all
# other words result in a parse error.
# expect+2: Invalid argument 'errorhandler-no' for modifier ':mtime'
# expect+1: Malformed conditional (${MAKEFILE:mtime=errorhandler-no} > 0)
.if ${MAKEFILE:mtime=errorhandler-no} > 0
.else
. error
.endif
# Ensure that the fallback for a missing modification time is indeed the
# current time, and not any later time.
end:= ${%s:L:gmtime}
.if ${not_found_mtime} > ${end}
. error
.endif

View file

@ -4,5 +4,5 @@ undefined
5
--- echo ---
20
00000000000000000000000000000001
1
exit status 0

View file

@ -1,4 +1,4 @@
# $NetBSD: varname-dot-make-jobs.mk,v 1.3 2022/01/26 22:47:03 rillig Exp $
# $NetBSD: varname-dot-make-jobs.mk,v 1.5 2023/09/10 16:25:32 sjg Exp $
#
# Tests for the special .MAKE.JOBS variable, which is defined in jobs mode
# only. There it contains the number of jobs that may run in parallel.
@ -15,10 +15,29 @@ all:
@${MAKE} -r -f ${MAKEFILE} echo -j20
@${MAKE} -r -f ${MAKEFILE} echo -j00000000000000000000000000000001
.if !make(echo) && ${.MAKE.JOBS.C} == "yes"
# These results will not be static, we need NCPU
# to compute expected results.
all: jC
NCPU!= ${MAKE} -r -f /dev/null -jC -V .MAKE.JOBS
# If -j arg is floating point or ends in C;
# .MAKE.JOBS is a multiple of _SC_NPROCESSORS_ONLN
# No news is good news here.
jCvals ?= 1 1.2 2
jC:
@for j in ${jCvals}; do \
e=`echo "${NCPU} * $$j" | bc | sed 's/\.[0-9]*//'`; \
g=`${MAKE} -r -f /dev/null -V .MAKE.JOBS -j$${j}C`; \
test $$g = $$e || echo "$$g != $$e"; \
done
.endif
# expect: undefined
# expect: 1
# expect: 5
# expect: 20
# The value of .MAKE.JOBS is the exact text given in the command line, not the
# canonical number. This doesn't have practical consequences though.
# expect: 00000000000000000000000000000001
# expect: 1

View file

@ -11,7 +11,7 @@ Var_Parse: ${:UVAR\(\(\(}= try2 (eval-defined)
Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
Result of ${:UVAR\(\(\(} is "VAR\(\(\(" (eval-defined, defined)
Global: .ALLTARGETS = VAR(((=) VAR\(\(\(=
make: "varname.mk" line 38: Invalid line type
make: "varname.mk" line 38: Invalid line '${:UVAR\(\(\(}= try2', expanded to 'VAR\(\(\(= try2'
Var_Parse: ${VARNAME} (eval)
Global: VAR((( = try3
Global: .MAKEFLAGS = -r -k -d v -d

View file

@ -1,4 +1,4 @@
# $NetBSD: varname.mk,v 1.11 2023/06/01 20:56:35 rillig Exp $
# $NetBSD: varname.mk,v 1.13 2023/08/19 11:09:02 rillig Exp $
#
# Tests for special variables, such as .MAKE or .PARSEDIR.
# And for variable names in general.
@ -34,7 +34,7 @@ ${:UVAR(((}= try1
# as an escape character, therefore the parentheses still count to the nesting
# level, which at the end of the line is still 3. Therefore this is not a
# variable assignment as well.
# expect+1: Invalid line type
# expect+1: Invalid line '${:UVAR\(\(\(}= try2', expanded to 'VAR\(\(\(= try2'
${:UVAR\(\(\(}= try2
# To assign to a variable with an arbitrary name, the variable name has to
# come from an external source, not the text that is parsed in the assignment

View file

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.1059 2023/06/23 05:21:10 rillig Exp $ */
/* $NetBSD: var.c,v 1.1064 2023/08/19 19:59:17 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -147,7 +147,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: var.c,v 1.1059 2023/06/23 05:21:10 rillig Exp $");
MAKE_RCSID("$NetBSD: var.c,v 1.1064 2023/08/19 19:59:17 rillig Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@ -1894,7 +1894,20 @@ FormatTime(const char *fmt, time_t t, bool gmt)
time(&t);
if (*fmt == '\0')
fmt = "%c";
strftime(buf, sizeof buf, fmt, gmt ? gmtime(&t) : localtime(&t));
if (gmt && strchr(fmt, 's') != NULL) {
/* strftime "%s" only works with localtime, not with gmtime. */
const char *prev_tz_env = getenv("TZ");
char *prev_tz = prev_tz_env != NULL
? bmake_strdup(prev_tz_env) : NULL;
setenv("TZ", "UTC", 1);
strftime(buf, sizeof buf, fmt, localtime(&t));
if (prev_tz != NULL) {
setenv("TZ", prev_tz, 1);
free(prev_tz);
} else
unsetenv("TZ");
} else
strftime(buf, sizeof buf, fmt, (gmt ? gmtime : localtime)(&t));
buf[sizeof buf - 1] = '\0';
return bmake_strdup(buf);
@ -2844,17 +2857,17 @@ ApplyModifier_Match(const char **pp, ModChain *ch)
struct ModifyWord_MtimeArgs {
bool error;
bool fallback;
bool use_fallback;
ApplyModifierResult rc;
time_t t;
time_t fallback;
};
static void
ModifyWord_Mtime(Substring word, SepBuf *buf, void *data)
{
char tbuf[BUFSIZ];
struct stat st;
struct ModifyWord_MtimeArgs *args = data;
struct stat st;
char tbuf[21];
if (Substring_IsEmpty(word))
return;
@ -2867,8 +2880,8 @@ ModifyWord_Mtime(Substring word, SepBuf *buf, void *data)
args->rc = AMR_CLEANUP;
return;
}
if (args->fallback)
st.st_mtime = args->t;
if (args->use_fallback)
st.st_mtime = args->fallback;
else
time(&st.st_mtime);
}
@ -2887,17 +2900,21 @@ ApplyModifier_Mtime(const char **pp, ModChain *ch)
return AMR_UNKNOWN;
*pp += 5;
p = *pp;
args.error = args.fallback = false;
args.error = false;
args.use_fallback = p[0] == '=';
args.rc = AMR_OK;
if (p[0] == '=') {
if (args.use_fallback) {
p++;
args.fallback = true;
if (!TryParseTime(&p, &args.t)) {
if (strncmp(p, "error", 5) == 0) {
args.error = true;
p += 5;
} else
return AMR_BAD;
if (TryParseTime(&p, &args.fallback)) {
} else if (strncmp(p, "error", 5) == 0
&& IsDelimiter(p[5], ch)) {
p += 5;
args.error = true;
} else {
Parse_Error(PARSE_FATAL,
"Invalid argument '%.*s' for modifier ':mtime'",
(int)strcspn(p, ":{}()"), p);
return AMR_CLEANUP;
}
*pp = p;
}

View file

@ -6,7 +6,7 @@ SRCTOP?= ${.CURDIR:H:H}
# things set by configure
_MAKE_VERSION?=20230622
_MAKE_VERSION?=20230909
prefix?= /usr
srcdir= ${SRCTOP}/contrib/bmake

View file

@ -279,7 +279,7 @@
#define PACKAGE_NAME "bmake"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "bmake 20220909"
#define PACKAGE_STRING "bmake 20230723"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "bmake"
@ -288,7 +288,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "20220909"
#define PACKAGE_VERSION "20230723"
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
/* #undef STAT_MACROS_BROKEN */

View file

@ -1,9 +1,9 @@
# This is a generated file, do NOT edit!
# See contrib/bmake/bsd.after-import.mk
#
# $Id: Makefile,v 1.199 2023/06/20 17:27:20 sjg Exp $
# $Id: Makefile,v 1.207 2023/09/09 16:44:03 sjg Exp $
#
# $NetBSD: Makefile,v 1.339 2023/06/20 09:25:34 rillig Exp $
# $NetBSD: Makefile,v 1.341 2023/09/09 16:41:04 sjg Exp $
#
# Unit tests for make(1)
#
@ -472,10 +472,26 @@ BROKEN_TESTS+= opt-debug-x-trace
BROKEN_TESTS+= sh-flags
.endif
.if ${UTC_1:Uno} == ""
# this will not work if UTC_1 is set empty
BROKEN_TESTS+= varmod-localtime
.endif
.if ${.MAKE.OS:NDarwin} == ""
BROKEN_TESTS+= shell-ksh
.endif
.if ${.MAKE.OS:MIRIX*} != ""
BROKEN_TESTS+= \
cmd-interrupt \
deptgt-interrupt \
job-output-null \
opt-chdir \
opt-debug-x-trace \
sh-leading-hyphen \
.endif
.if ${.MAKE.OS} == "SCO_SV"
BROKEN_TESTS+= \
opt-debug-graph[23] \
@ -603,6 +619,7 @@ 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-mtime+= -e "s,': .*,': <ENOENT>,"
SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
SED_CMDS.varparse-errors+= ${STD_SED_CMDS.timestamp}
SED_CMDS.varname-dot-make-meta-ignore_filter+= ${SED_CMDS.meta-ignore}
@ -642,6 +659,7 @@ STD_SED_CMDS.dg1+= -e '/^\#.*\/mk/d'
STD_SED_CMDS.dg1+= -e 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.JOBS\.C *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MACHINE[_ARCH]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.SHELL *=\) .*,\1 <details omitted>,'