summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2017-03-06 19:54:54 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2017-03-06 19:54:54 +0000
commit60a7ffecc77c5e3bf4aa5462ebf16bbd377a5af8 (patch)
treea62dcb2a25724d651b419fd45ff4dd19f6b92b77
parentb9b4b0cc41d3b0698aa59d332a8583931e6922eb (diff)
Notes
-rw-r--r--ChangeLog29
-rw-r--r--Makefile4
-rw-r--r--PSD.doc/tutorial.ms15
-rw-r--r--bmake.143
-rw-r--r--bmake.cat131
-rw-r--r--dir.c18
-rw-r--r--main.c21
-rw-r--r--make.143
-rw-r--r--meta.c12
-rw-r--r--mk/ChangeLog31
-rw-r--r--mk/dirdeps.mk10
-rw-r--r--mk/dpadd.mk6
-rw-r--r--mk/install-mk4
-rw-r--r--mk/meta.stage.mk50
-rwxr-xr-xmk/meta2deps.py31
-rw-r--r--mk/prog.mk3
-rw-r--r--mk/subdir.mk15
-rw-r--r--mk/sys.mk6
-rw-r--r--mk/sys.vars.mk11
-rwxr-xr-xos.sh11
-rw-r--r--parse.c10
-rw-r--r--unit-tests/varmisc.exp5
-rw-r--r--unit-tests/varmisc.mk24
-rw-r--r--var.c128
24 files changed, 457 insertions, 104 deletions
diff --git a/ChangeLog b/ChangeLog
index 46c563fb2efc..49ce971d4934 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2017-03-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (_MAKE_VERSION): 20170301
+ Merge with NetBSD make, pick up
+ o main.c: use -C arg as is rather than getcwd()
+ if they identify the same directory.
+ o parse.c: ensure loadfile buffer is \n terminated in non-mmap case
+
+2017-02-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (_MAKE_VERSION): 20170201
+ Merge with NetBSD make, pick up
+ o var.c: allow :_=var and avoid use of special context.
+
+2017-01-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (_MAKE_VERSION): 20170130
+ Merge with NetBSD make, pick up
+ o var.c: add :range and :_
+ o main.c: partially initialize Dir_* before MainParseArgs()
+ can be called.
+ If -V, skip Main_ExportMAKEFLAGS()
+
+2017-01-14 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (_MAKE_VERSION): 20170114
+ Merge with NetBSD make, pick up
+ o var.c: allow specifying the utc value used by :{gm,local}time
+
2016-12-12 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (_MAKE_VERSION): 20161212
diff --git a/Makefile b/Makefile
index 7f6066bc57da..34493789133f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile,v 1.77 2016/12/12 07:34:19 sjg Exp $
+# $Id: Makefile,v 1.81 2017/03/01 17:01:23 sjg Exp $
# Base version on src date
-_MAKE_VERSION= 20161212
+_MAKE_VERSION= 20170301
PROG= bmake
diff --git a/PSD.doc/tutorial.ms b/PSD.doc/tutorial.ms
index d5c8a7d54f96..814a09a62146 100644
--- a/PSD.doc/tutorial.ms
+++ b/PSD.doc/tutorial.ms
@@ -1,4 +1,4 @@
-.\" $NetBSD: tutorial.ms,v 1.12 2014/09/30 21:33:14 christos Exp $
+.\" $NetBSD: tutorial.ms,v 1.13 2017/03/01 13:05:11 kre Exp $
.\" Copyright (c) 1988, 1989, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -117,6 +117,15 @@
.de No
.br
.ne 0.5i
+.ie n \{\
+.nr g3 \w'NOTE '
+.po -\\n(g3u
+.br
+NOTE
+.br
+.po +\\n(g3u
+.\}
+.el \{\
.po -0.5i
.br
.mk
@@ -148,12 +157,14 @@
.rt
.ft \\n(g3
.ps \\n(g4
+.\}
..
.de Bp
.ie !\\n(.$ .IP \(bu 2
.el .IP "\&" 2
..
-.po +.3i
+.ie n .po +\w'NOTE 'u
+.el .po +.3i
.TL
PMake \*- A Tutorial
.AU
diff --git a/bmake.1 b/bmake.1
index 4f8f3372ca0f..3bad1e7316a0 100644
--- a/bmake.1
+++ b/bmake.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.263 2016/08/26 23:37:54 dholland Exp $
+.\" $NetBSD: make.1,v 1.266 2017/02/01 18:39:27 sjg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd August 26, 2016
+.Dd February 1, 2017
.Dt BMAKE 1
.Os
.Sh NAME
@@ -1205,18 +1205,28 @@ safely through recursive invocations of
.Nm .
.It Cm \&:R
Replaces each word in the variable with everything but its suffix.
-.It Cm \&:gmtime
+.It Cm \&:range[=count]
+The value is an integer sequence representing the words of the original
+value, or the supplied
+.Va count .
+.It Cm \&:gmtime[=utc]
The value is a format string for
.Xr strftime 3 ,
-using the current
+using
.Xr gmtime 3 .
+If a
+.Va utc
+value is not provided or is 0, the current time is used.
.It Cm \&:hash
Compute a 32-bit hash of the value and encode it as hex digits.
-.It Cm \&:localtime
+.It Cm \&:localtime[=utc]
The value is a format string for
.Xr strftime 3 ,
-using the current
+using
.Xr localtime 3 .
+If a
+.Va utc
+value is not provided or is 0, the current time is used.
.It Cm \&:tA
Attempt to convert variable to an absolute path using
.Xr realpath 3 ,
@@ -1416,6 +1426,27 @@ For example.
.Pp
However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Cm \&:_[=var]
+Save the current variable value in
+.Ql $_
+or the named
+.Va var
+for later reference.
+Example usage:
+.Bd -literal -offset indent
+M_cmpv.units = 1 1000 1000000
+M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \&\\
+\\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+
+.Dv .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}}
+
+.Ed
+Here
+.Ql $_
+is used to save the result of the
+.Ql :S
+modifier which is later referenced using the index values from
+.Ql :range .
.It Cm \&:U Ns Ar newval
If the variable is undefined
.Ar newval
diff --git a/bmake.cat1 b/bmake.cat1
index 2aec542ac785..bd98e5b3b245 100644
--- a/bmake.cat1
+++ b/bmake.cat1
@@ -789,16 +789,20 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
::RR Replaces each word in the variable with everything but its suffix.
- ::ggmmttiimmee
- The value is a format string for strftime(3), using the current
- gmtime(3).
+ ::rraannggee[[==ccoouunntt]]
+ The value is an integer sequence representing the words of the orig-
+ inal value, or the supplied _c_o_u_n_t.
+
+ ::ggmmttiimmee[[==uuttcc]]
+ The value is a format string for strftime(3), using gmtime(3). If a
+ _u_t_c value is not provided or is 0, the current time is used.
::hhaasshh
Compute a 32-bit hash of the value and encode it as hex digits.
- ::llooccaallttiimmee
- The value is a format string for strftime(3), using the current
- localtime(3).
+ ::llooccaallttiimmee[[==uuttcc]]
+ The value is a format string for strftime(3), using localtime(3).
+ If a _u_t_c value is not provided or is 0, the current time is used.
::ttAA Attempt to convert variable to an absolute path using realpath(3),
if that fails, the value is unchanged.
@@ -899,6 +903,19 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
However a single character variable is often more readable:
${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+ ::__[[==vvaarr]]
+ Save the current variable value in `$_' or the named _v_a_r for later
+ reference. Example usage:
+
+ M_cmpv.units = 1 1000 1000000
+ M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \
+ \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+
+ .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}}
+
+ Here `$_' is used to save the result of the `:S' modifier which is
+ later referenced using the index values from `:range'.
+
::UU_n_e_w_v_a_l
If the variable is undefined _n_e_w_v_a_l is the value. If the variable
is defined, the existing value is returned. This is another ODE
@@ -1506,4 +1523,4 @@ BBUUGGSS
There is no way of escaping a space character in a filename.
-NetBSD 5.1 August 26, 2016 NetBSD 5.1
+NetBSD 7.1_RC1 February 1, 2017 NetBSD 7.1_RC1
diff --git a/dir.c b/dir.c
index 4667e3cdb677..2494da513ee2 100644
--- a/dir.c
+++ b/dir.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $ */
+/* $NetBSD: dir.c,v 1.69 2017/01/31 06:54:23 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.69 2017/01/31 06:54:23 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $");
+__RCSID("$NetBSD: dir.c,v 1.69 2017/01/31 06:54:23 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -346,11 +346,13 @@ cached_lstat(const char *pathname, void *st)
void
Dir_Init(const char *cdname)
{
- dirSearchPath = Lst_Init(FALSE);
- openDirectories = Lst_Init(FALSE);
- Hash_InitTable(&mtimes, 0);
- Hash_InitTable(&lmtimes, 0);
-
+ if (!cdname) {
+ dirSearchPath = Lst_Init(FALSE);
+ openDirectories = Lst_Init(FALSE);
+ Hash_InitTable(&mtimes, 0);
+ Hash_InitTable(&lmtimes, 0);
+ return;
+ }
Dir_InitCur(cdname);
dotLast = bmake_malloc(sizeof(Path));
diff --git a/main.c b/main.c
index 087438927355..870eefd6e591 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.254 2016/12/10 23:12:39 christos Exp $ */
+/* $NetBSD: main.c,v 1.257 2017/02/08 17:47:36 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.254 2016/12/10 23:12:39 christos Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.257 2017/02/08 17:47:36 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.254 2016/12/10 23:12:39 christos Exp $");
+__RCSID("$NetBSD: main.c,v 1.257 2017/02/08 17:47:36 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -389,6 +389,7 @@ MainParseArgs(int argc, char **argv)
int arginc;
char *argvalue;
const char *getopt_def;
+ struct stat sa, sb;
char *optscan;
Boolean inOption, dashDash = FALSE;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
@@ -457,6 +458,11 @@ rearg:
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
exit(2);
}
+ if (stat(argvalue, &sa) != -1 &&
+ stat(curdir, &sb) != -1 &&
+ sa.st_ino == sb.st_ino &&
+ sa.st_dev == sb.st_dev)
+ strncpy(curdir, argvalue, MAXPATHLEN);
ignorePWD = TRUE;
break;
case 'D':
@@ -1073,6 +1079,8 @@ main(int argc, char **argv)
#ifdef USE_META
meta_init();
#endif
+ Dir_Init(NULL); /* Dir_* safe to call from MainParseArgs */
+
/*
* First snag any flags out of the MAKE environment variable.
* (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
@@ -1314,8 +1322,9 @@ main(int argc, char **argv)
fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
- Main_ExportMAKEFLAGS(TRUE); /* initial export */
-
+ if (!printVars)
+ Main_ExportMAKEFLAGS(TRUE); /* initial export */
+
/*
* For compatibility, look at the directories in the VPATH variable
* and add them to the search path, if the variable is defined. The
@@ -1933,7 +1942,7 @@ PrintAddr(void *a, void *b)
static int
-addErrorCMD(void *cmdp, void *gnp)
+addErrorCMD(void *cmdp, void *gnp MAKE_ATTR_UNUSED)
{
if (cmdp == NULL)
return 1; /* stop */
diff --git a/make.1 b/make.1
index c74988716f23..a461909e87ee 100644
--- a/make.1
+++ b/make.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.263 2016/08/26 23:37:54 dholland Exp $
+.\" $NetBSD: make.1,v 1.266 2017/02/01 18:39:27 sjg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd August 26, 2016
+.Dd February 1, 2017
.Dt MAKE 1
.Os
.Sh NAME
@@ -1205,18 +1205,28 @@ safely through recursive invocations of
.Nm .
.It Cm \&:R
Replaces each word in the variable with everything but its suffix.
-.It Cm \&:gmtime
+.It Cm \&:range[=count]
+The value is an integer sequence representing the words of the original
+value, or the supplied
+.Va count .
+.It Cm \&:gmtime[=utc]
The value is a format string for
.Xr strftime 3 ,
-using the current
+using
.Xr gmtime 3 .
+If a
+.Va utc
+value is not provided or is 0, the current time is used.
.It Cm \&:hash
Compute a 32-bit hash of the value and encode it as hex digits.
-.It Cm \&:localtime
+.It Cm \&:localtime[=utc]
The value is a format string for
.Xr strftime 3 ,
-using the current
+using
.Xr localtime 3 .
+If a
+.Va utc
+value is not provided or is 0, the current time is used.
.It Cm \&:tA
Attempt to convert variable to an absolute path using
.Xr realpath 3 ,
@@ -1416,6 +1426,27 @@ For example.
.Pp
However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Cm \&:_[=var]
+Save the current variable value in
+.Ql $_
+or the named
+.Va var
+for later reference.
+Example usage:
+.Bd -literal -offset indent
+M_cmpv.units = 1 1000 1000000
+M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \&\\
+\\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+
+.Dv .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}}
+
+.Ed
+Here
+.Ql $_
+is used to save the result of the
+.Ql :S
+modifier which is later referenced using the index values from
+.Ql :range .
.It Cm \&:U Ns Ar newval
If the variable is undefined
.Ar newval
diff --git a/meta.c b/meta.c
index 0ea41f643f3a..33c2dd8d5e3d 100644
--- a/meta.c
+++ b/meta.c
@@ -241,7 +241,7 @@ eat_dots(char *buf, size_t bufsz, int dots)
}
static char *
-meta_name(struct GNode *gn, char *mname, size_t mnamelen,
+meta_name(char *mname, size_t mnamelen,
const char *dname,
const char *tname,
const char *cwd)
@@ -396,7 +396,7 @@ printCMD(void *cmdp, void *mfpp)
* Do we need/want a .meta file ?
*/
static Boolean
-meta_needed(GNode *gn, const char *dname, const char *tname,
+meta_needed(GNode *gn, const char *dname,
char *objdir, int verbose)
{
struct stat fs;
@@ -476,7 +476,7 @@ meta_create(BuildMon *pbm, GNode *gn)
tname = Var_Value(TARGET, gn, &p[i++]);
/* if this succeeds objdir is realpath of dname */
- if (!meta_needed(gn, dname, tname, objdir, TRUE))
+ if (!meta_needed(gn, dname, objdir, TRUE))
goto out;
dname = objdir;
@@ -502,7 +502,7 @@ meta_create(BuildMon *pbm, GNode *gn)
/* Don't create meta data. */
goto out;
- fname = meta_name(gn, pbm->meta_fname, sizeof(pbm->meta_fname),
+ fname = meta_name(pbm->meta_fname, sizeof(pbm->meta_fname),
dname, tname, objdir);
#ifdef DEBUG_META_MODE
@@ -1049,7 +1049,7 @@ meta_oodate(GNode *gn, Boolean oodate)
tname = Var_Value(TARGET, gn, &pa[i++]);
/* if this succeeds fname3 is realpath of dname */
- if (!meta_needed(gn, dname, tname, fname3, FALSE))
+ if (!meta_needed(gn, dname, fname3, FALSE))
goto oodate_out;
dname = fname3;
@@ -1063,7 +1063,7 @@ meta_oodate(GNode *gn, Boolean oodate)
*/
Make_DoAllVar(gn);
- meta_name(gn, fname, sizeof(fname), dname, tname, dname);
+ meta_name(fname, sizeof(fname), dname, tname, dname);
#ifdef DEBUG_META_MODE
if (DEBUG(META))
diff --git a/mk/ChangeLog b/mk/ChangeLog
index 4df06cd22897..ef0bd3793fba 100644
--- a/mk/ChangeLog
+++ b/mk/ChangeLog
@@ -1,3 +1,34 @@
+2017-03-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * install-mk (MK_VERSION): 20170301
+
+ * dirdeps.mk (_build_all_dirs): update this outside test for empty
+ DIRDEPS.
+
+ * meta.stage.mk: allow multiple inclusion to the extent it makes
+ sense.
+
+2017-02-14 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * prog.mk (install_links): depends on realinstall
+
+2017-02-12 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * install-mk (MK_VERSION): 20170212
+
+ * dpadd.mk: avoid applying :T:R twice to DPLIBS entries
+
+2017-01-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * install-mk (MK_VERSION): 20170130
+
+ * dirdeps.mk: use :range if we can.
+
+ * sys.vars.mk: provide M_cmpv if MAKE_VERSION >= 20170130
+
+ * meta2deps.py: clean paths without using realpath() where possible.
+ fix sort_unique.
+
2016-12-12 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): 20161212
diff --git a/mk/dirdeps.mk b/mk/dirdeps.mk
index 179122e96f79..6b2952057d72 100644
--- a/mk/dirdeps.mk
+++ b/mk/dirdeps.mk
@@ -1,4 +1,4 @@
-# $Id: dirdeps.mk,v 1.84 2016/11/27 02:44:34 sjg Exp $
+# $Id: dirdeps.mk,v 1.86 2017/03/01 20:26:51 sjg Exp $
# Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
@@ -197,7 +197,9 @@ DEP_$v ?= ${$v}
# we compute below are fully qualified wrt DEP_TARGET_SPEC.
# The makefiles may only partially specify (eg. MACHINE only),
# so we need to construct a set of modifiers to fill in the gaps.
-.if ${TARGET_SPEC_VARS:[#]} > 10
+.if ${MAKE_VERSION} >= 20170130
+_tspec_x := ${TARGET_SPEC_VARS:range}
+.elif ${TARGET_SPEC_VARS:[#]} > 10
# seriously? better have jot(1) or equivalent to produce suitable sequence
_tspec_x := ${${JOT:Ujot} ${TARGET_SPEC_VARS:[#]}:L:sh}
.else
@@ -612,11 +614,11 @@ _build_dirs += \
# qualify everything now
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
+.endif # empty DIRDEPS
+
_build_all_dirs += ${_build_dirs}
_build_all_dirs := ${_build_all_dirs:O:u}
-.endif # empty DIRDEPS
-
# Normally if doing make -V something,
# we do not want to waste time chasing DIRDEPS
# but if we want to count the number of Makefile.depend* read, we do.
diff --git a/mk/dpadd.mk b/mk/dpadd.mk
index c789acfb9904..650d61bf9a80 100644
--- a/mk/dpadd.mk
+++ b/mk/dpadd.mk
@@ -1,4 +1,4 @@
-# $Id: dpadd.mk,v 1.22 2016/05/31 23:30:59 sjg Exp $
+# $Id: dpadd.mk,v 1.23 2017/02/13 16:46:01 sjg Exp $
#
# @(#) Copyright (c) 2004, Simon J. Gerraty
#
@@ -49,11 +49,11 @@ CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
# DPLIBS helps us ensure we keep DPADD and LDADD in sync
DPLIBS+= ${DPLIBS_LAST}
DPADD+= ${DPLIBS:N-*}
-.for __lib in ${DPLIBS:T:R}
+.for __lib in ${DPLIBS}
.if "${_lib:M-*}" != ""
LDADD += ${__lib}
.else
-LDADD += ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
+LDADD += ${LDADD_${__lib:T:R}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
.endif
.endfor
diff --git a/mk/install-mk b/mk/install-mk
index 8d09f8462bc0..158f74cf6d06 100644
--- a/mk/install-mk
+++ b/mk/install-mk
@@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: install-mk,v 1.135 2016/12/12 19:07:42 sjg Exp $
+# $Id: install-mk,v 1.138 2017/03/01 20:26:51 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@@ -70,7 +70,7 @@
# sjg@crufty.net
#
-MK_VERSION=20161212
+MK_VERSION=20170301
OWNER=
GROUP=
MODE=444
diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk
index a0f30e31885c..223421a51ece 100644
--- a/mk/meta.stage.mk
+++ b/mk/meta.stage.mk
@@ -1,6 +1,6 @@
-# $Id: meta.stage.mk,v 1.47 2016/12/07 23:07:49 sjg Exp $
+# $Id: meta.stage.mk,v 1.48 2017/03/01 22:48:07 sjg Exp $
#
-# @(#) Copyright (c) 2011, Simon J. Gerraty
+# @(#) Copyright (c) 2011-2017, Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
@@ -14,7 +14,7 @@
#
.if !target(__${.PARSEFILE}__)
-__${.PARSEFILE}__:
+# the guard target is defined later
.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != ""
# this is generally safer anyway
@@ -127,26 +127,17 @@ STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \
done; :; }
# this is simple, a list of the "staged" files depends on this,
-_STAGE_BASENAME_USE: .USE ${.TARGET:T}
+_STAGE_BASENAME_USE: .USE .dirdep ${.TARGET:T}
@${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T}
-_STAGE_AS_BASENAME_USE: .USE ${.TARGET:T}
+_STAGE_AS_BASENAME_USE: .USE .dirdep ${.TARGET:T}
@${STAGE_AS_SCRIPT}; StageAs ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} ${STAGE_AS_${.TARGET:T}:U${.TARGET:T}}
-.if !empty(STAGE_INCSDIR)
-STAGE_TARGETS += stage_incs
-STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*}
stage_includes: stage_incs
stage_incs: .dirdep
@${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR:${STAGE_DIR_FILTER}} ${STAGE_INCS}
@touch $@
-.endif
-
-.if !empty(STAGE_LIBDIR)
-STAGE_TARGETS += stage_libs
-
-STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*}
stage_libs: .dirdep
@${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS}
@@ -159,6 +150,18 @@ stage_libs: .dirdep
.endif
.endif
@touch $@
+
+.endif # first time
+
+
+.if !empty(STAGE_INCSDIR)
+STAGE_TARGETS += stage_incs
+STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*}
+.endif
+
+.if !empty(STAGE_LIBDIR)
+STAGE_TARGETS += stage_libs
+STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*}
.endif
.if !empty(STAGE_DIR)
@@ -184,6 +187,8 @@ STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP}
STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP}
STAGE_TARGETS += stage_files
+.if !target(.stage_files.$s)
+.stage_files.$s:
.if $s != "_default"
stage_files: stage_files.$s
stage_files.$s: .dirdep
@@ -192,8 +197,11 @@ stage_files: .dirdep
.endif
@${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s}
@touch $@
+.endif
STAGE_TARGETS += stage_links
+.if !target(.stage_links.$s)
+.stage_links.$s:
.if $s != "_default"
stage_links: stage_links.$s
stage_links.$s: .dirdep
@@ -202,8 +210,11 @@ stage_links: .dirdep
.endif
@${STAGE_LINKS_SCRIPT}; StageLinks ${STAGE_LINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_LINKS.$s}
@touch $@
+.endif
STAGE_TARGETS += stage_symlinks
+.if !target(.stage_symlinks.$s)
+.stage_symlinks.$s:
.if $s != "_default"
stage_symlinks: stage_symlinks.$s
stage_symlinks.$s: .dirdep
@@ -212,6 +223,7 @@ stage_symlinks: .dirdep
.endif
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_SYMLINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_SYMLINKS.$s}
@touch $@
+.endif
.endfor
.endif
@@ -231,22 +243,32 @@ STAGE_TARGETS += stage_as stage_as_and_symlink
STAGE_AS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
STAGE_AS_AND_SYMLINK.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
+.if !target(.stage_as.$s)
+.stage_as.$s:
stage_as: stage_as.$s
stage_as.$s: .dirdep
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
@touch $@
+.endif
+.if !target(.stage_as_and_symlink.$s)
+.stage_as_and_symlink.$s:
stage_as_and_symlink: stage_as_and_symlink.$s
stage_as_and_symlink.$s: .dirdep
@${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
@${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS_AND_SYMLINK.$s:@f@${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}} $f@}
@touch $@
+.endif
.endfor
.endif
CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes
+# this lot also only makes sense the first time...
+.if !target(__${.PARSEFILE}__)
+__${.PARSEFILE}__:
+
# stage_*links usually needs to follow any others.
# for non-jobs mode the order here matters
staging: ${STAGE_TARGETS:N*_links} ${STAGE_TARGETS:M*_links}
diff --git a/mk/meta2deps.py b/mk/meta2deps.py
index 8d0b044a185c..8688213d75d3 100755
--- a/mk/meta2deps.py
+++ b/mk/meta2deps.py
@@ -37,7 +37,7 @@ We only pay attention to a subset of the information in the
"""
RCSid:
- $Id: meta2deps.py,v 1.22 2016/12/12 19:07:42 sjg Exp $
+ $Id: meta2deps.py,v 1.24 2017/02/08 22:17:10 sjg Exp $
Copyright (c) 2011-2013, Juniper Networks, Inc.
All rights reserved.
@@ -103,20 +103,36 @@ def resolve(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
return p
return None
+def cleanpath(path):
+ """cleanup path without using realpath(3)"""
+ if path.startswith('/'):
+ r = '/'
+ else:
+ r = ''
+ p = []
+ w = path.split('/')
+ for d in w:
+ if not d or d == '.':
+ continue
+ if d == '..':
+ p.pop()
+ continue
+ p.append(d)
+
+ return r + '/'.join(p)
+
def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
"""
Return an absolute path, resolving via cwd or last_dir if needed.
- this gets called a lot, so we try to avoid calling realpath
- until we know we have something.
+ this gets called a lot, so we try to avoid calling realpath.
"""
rpath = resolve(path, cwd, last_dir, debug, debug_out)
if rpath:
path = rpath
if (path.find('/') < 0 or
path.find('./') > 0 or
- path.endswith('/..') or
- os.path.islink(path)):
- return os.path.realpath(path)
+ path.endswith('/..')):
+ path = cleanpath(path)
return path
def sort_unique(list, cmp=None, key=None, reverse=False):
@@ -126,6 +142,7 @@ def sort_unique(list, cmp=None, key=None, reverse=False):
for e in list:
if e == le:
continue
+ le = e
nl.append(e)
return nl
@@ -504,6 +521,8 @@ class MetaFile:
dir = abspath(dir, cwd, self.last_dir, self.debug, self.debug_out)
if rdir == dir or rdir.find('./') > 0:
rdir = None
+ if os.path.islink(dir):
+ rdir = os.path.realpath(dir)
# now put path back together
path = '/'.join([dir,base])
if self.debug > 1:
diff --git a/mk/prog.mk b/mk/prog.mk
index 2a4160af1422..ba87a974bc8c 100644
--- a/mk/prog.mk
+++ b/mk/prog.mk
@@ -1,4 +1,4 @@
-# $Id: prog.mk,v 1.27 2016/08/02 20:52:17 sjg Exp $
+# $Id: prog.mk,v 1.28 2017/02/14 21:26:13 sjg Exp $
.if !target(__${.PARSEFILE}__)
__${.PARSEFILE}__:
@@ -191,6 +191,7 @@ install_links:
maninstall: afterinstall
afterinstall: realinstall
+install_links: realinstall
proginstall: beforeinstall
realinstall: beforeinstall
.endif
diff --git a/mk/subdir.mk b/mk/subdir.mk
index 2511d1037503..1d5001acd2a2 100644
--- a/mk/subdir.mk
+++ b/mk/subdir.mk
@@ -1,4 +1,4 @@
-# $Id: subdir.mk,v 1.15 2016/04/05 15:58:37 sjg Exp $
+# $Id: subdir.mk,v 1.16 2017/02/08 22:16:59 sjg Exp $
# skip missing directories...
# $NetBSD: bsd.subdir.mk,v 1.11 1996/04/04 02:05:06 jtc Exp $
@@ -45,13 +45,18 @@ _SUBDIRUSE: .USE
done
${SUBDIR}::
- @set -e; if test -d ${.CURDIR}/${.TARGET}.${MACHINE}; then \
- _newdir_=${.TARGET}.${MACHINE}; \
+ @set -e; _r=${.CURDIR}/; \
+ if test -z "${.TARGET:M/*}"; then \
+ if test -d ${.CURDIR}/${.TARGET}.${MACHINE}; then \
+ _newdir_=${.TARGET}.${MACHINE}; \
+ else \
+ _newdir_=${.TARGET}; \
+ fi; \
else \
- _newdir_=${.TARGET}; \
+ _r= _newdir_=${.TARGET}; \
fi; \
${ECHO_DIR} "===> $${_newdir_}"; \
- cd ${.CURDIR}/$${_newdir_}; \
+ cd $${_r}$${_newdir_}; \
${.MAKE} _THISDIR_="$${_newdir_}" all
.endif
diff --git a/mk/sys.mk b/mk/sys.mk
index 832dfc81f8c9..55f615d1d8ef 100644
--- a/mk/sys.mk
+++ b/mk/sys.mk
@@ -1,4 +1,4 @@
-# $Id: sys.mk,v 1.44 2016/10/01 19:11:55 sjg Exp $
+# $Id: sys.mk,v 1.45 2017/02/05 01:26:13 sjg Exp $
#
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
#
@@ -71,11 +71,11 @@ SYS_OS_MK := ${_sys_mk}
# some options we need to know early
OPTIONS_DEFAULT_NO += \
DIRDEPS_BUILD \
- DIRDEPS_CACHE \
- META_MODE
+ DIRDEPS_CACHE
OPTIONS_DEFAULT_DEPENDENT += \
AUTO_OBJ/DIRDEPS_BUILD \
+ META_MODE/DIRDEPS_BUILD \
STAGING/DIRDEPS_BUILD \
.-include <options.mk>
diff --git a/mk/sys.vars.mk b/mk/sys.vars.mk
index 2438499581c6..f2cb00e90bc2 100644
--- a/mk/sys.vars.mk
+++ b/mk/sys.vars.mk
@@ -1,4 +1,4 @@
-# $Id: sys.vars.mk,v 1.1 2016/10/01 19:11:55 sjg Exp $
+# $Id: sys.vars.mk,v 1.2 2017/01/31 07:44:45 sjg Exp $
#
# @(#) Copyright (c) 2003-2009, Simon J. Gerraty
#
@@ -67,5 +67,14 @@ M_tA = tA
M_tA = C,.*,('cd' & \&\& 'pwd') 2> /dev/null || echo &,:sh
.endif
+.if ${MAKE_VERSION:U0} >= 20170130
+# M_cmpv allows comparing dotted versions like 3.1.2
+# ${3.1.2:L:${M_cmpv}} -> 3001002
+# we use big jumps to handle 3 digits per dot:
+# ${123.456.789:L:${M_cmpv}} -> 123456789
+M_cmpv.units = 1 1000 1000000
+M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+.endif
+
# absoulte path to what we are reading.
_PARSEDIR = ${.PARSEDIR:${M_tA}}
diff --git a/os.sh b/os.sh
index aba9bbdd8a80..8468ba1b3e7d 100755
--- a/os.sh
+++ b/os.sh
@@ -17,7 +17,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: os.sh,v 1.52 2016/06/17 05:15:14 sjg Exp $
+# $Id: os.sh,v 1.53 2017/01/11 20:01:09 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@@ -206,7 +206,13 @@ esac
TMP_DIRS=${TMP_DIRS:-"/tmp /var/tmp"}
MACHINE_ARCH=${MACHINE_ARCH:-$MACHINE}
+case "$MACHINE_ARCH" in
+x86*64|amd64) MACHINE32_ARCH=i386;;
+*64) MACHINE32_ARCH=`echo $MACHINE_ARCH | sed 's,64,32,'`;;
+*) MACHINE32_ARCH=$MACHINE_ARCH;;
+esac
HOST_ARCH=${HOST_ARCH:-$MACHINE_ARCH}
+HOST_ARCH32=${HOST_ARCH32:-$MACHINE32_ARCH}
# we mount server:/share/arch/$SHARE_ARCH as /usr/local
SHARE_ARCH_DEFAULT=$OS/$OSMAJOR.X/$HOST_ARCH
SHARE_ARCH=${SHARE_ARCH:-$SHARE_ARCH_DEFAULT}
@@ -215,7 +221,8 @@ TR=${TR:-tr}
# Some people like have /share/$HOST_TARGET/bin etc.
HOST_TARGET=`echo ${OS}${OSMAJOR}-$HOST_ARCH | tr -d / | toLower`
-export HOST_TARGET
+HOST_TARGET32=`echo ${OS}${OSMAJOR}-$HOST_ARCH32 | tr -d / | toLower`
+export HOST_TARGET HOST_TARGET32
case `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac
diff --git a/parse.c b/parse.c
index bbc43bd1a529..e84cae17ffe6 100644
--- a/parse.c
+++ b/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.217 2016/12/09 22:56:21 sjg Exp $ */
+/* $NetBSD: parse.c,v 1.218 2017/03/01 16:39:49 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.217 2016/12/09 22:56:21 sjg Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.218 2017/03/01 16:39:49 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: parse.c,v 1.217 2016/12/09 22:56:21 sjg Exp $");
+__RCSID("$NetBSD: parse.c,v 1.218 2017/03/01 16:39:49 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -578,7 +578,11 @@ loadfile(const char *path, int fd)
/* truncate malloc region to actual length (maybe not useful) */
if (lf->len > 0) {
+ /* as for mmap case, ensure trailing \n */
+ if (lf->buf[lf->len - 1] != '\n')
+ lf->len++;
lf->buf = bmake_realloc(lf->buf, lf->len);
+ lf->buf[lf->len - 1] = '\n';
}
#ifdef HAVE_MMAP
diff --git a/unit-tests/varmisc.exp b/unit-tests/varmisc.exp
index e2af496afabe..ffe8f8b867c8 100644
--- a/unit-tests/varmisc.exp
+++ b/unit-tests/varmisc.exp
@@ -17,4 +17,9 @@ false
FALSE
do not evaluate or expand :? if discarding
is set
+year=2016 month=04 day=01
+date=20160401
+Version=123.456.789 == 123456789
+Literal=3.4.5 == 3004005
+We have target specific vars
exit status 0
diff --git a/unit-tests/varmisc.mk b/unit-tests/varmisc.mk
index 14b52d22c3e6..a0b8f2dc84f4 100644
--- a/unit-tests/varmisc.mk
+++ b/unit-tests/varmisc.mk
@@ -1,8 +1,9 @@
-# $Id: varmisc.mk,v 1.5 2015/10/12 17:10:48 sjg Exp $
+# $Id: varmisc.mk,v 1.9 2017/02/01 18:44:54 sjg Exp $
#
# Miscellaneous variable tests.
-all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none
+all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \
+ strftime cmpv
unmatched_var_paren:
@echo ${foo::=foo-text}
@@ -40,3 +41,22 @@ Q_rhs:
NQ_none:
@echo do not evaluate or expand :? if discarding
@echo ${VSET:U${1:L:?${True}:${False}}}
+
+April1= 1459494000
+
+# slightly contorted syntax to use utc via variable
+strftime:
+ @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000}
+ @echo date=${%Y%m%d:L:${gmtime=${April1}:L}}
+
+# big jumps to handle 3 digits per step
+M_cmpv.units = 1 1000 1000000
+M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+
+Version = 123.456.789
+cmpv.only = target specific vars
+
+cmpv:
+ @echo Version=${Version} == ${Version:${M_cmpv}}
+ @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}}
+ @echo We have ${${.TARGET:T}.only}
diff --git a/var.c b/var.c
index 81e9daff7060..91c11a8e2981 100644
--- a/var.c
+++ b/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $ */
+/* $NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -2139,6 +2139,51 @@ VarUniq(const char *str)
return Buf_Destroy(&buf, FALSE);
}
+/*-
+ *-----------------------------------------------------------------------
+ * VarRange --
+ * Return an integer sequence
+ *
+ * Input:
+ * str String whose words provide default range
+ * ac range length, if 0 use str words
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarRange(const char *str, int ac)
+{
+ Buffer buf; /* Buffer for new string */
+ char tmp[32]; /* each element */
+ char **av; /* List of words to affect */
+ char *as; /* Word list memory */
+ int i, n;
+
+ Buf_Init(&buf, 0);
+ if (ac > 0) {
+ as = NULL;
+ av = NULL;
+ } else {
+ av = brk_string(str, &ac, FALSE, &as);
+ }
+ for (i = 0; i < ac; i++) {
+ n = snprintf(tmp, sizeof(tmp), "%d", 1 + i);
+ if (n >= (int)sizeof(tmp))
+ break;
+ Buf_AddBytes(&buf, n, tmp);
+ if (i != ac - 1)
+ Buf_AddByte(&buf, ' ');
+ }
+
+ free(as);
+ free(av);
+
+ return Buf_Destroy(&buf, FALSE);
+}
+
/*-
*-----------------------------------------------------------------------
@@ -2380,12 +2425,12 @@ VarHash(char *str)
}
static char *
-VarStrftime(const char *fmt, int zulu)
+VarStrftime(const char *fmt, int zulu, time_t utc)
{
char buf[BUFSIZ];
- time_t utc;
- time(&utc);
+ if (!utc)
+ time(&utc);
if (!*fmt)
fmt = "%c";
strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc));
@@ -2482,6 +2527,9 @@ VarStrftime(const char *fmt, int zulu)
/* we now have some modifiers with long names */
#define STRMOD_MATCH(s, want, n) \
(strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':'))
+#define STRMOD_MATCHX(s, want, n) \
+ (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':' || s[n] == '='))
+#define CHARMOD_MATCH(c) (c == endc || c == ':')
static char *
ApplyModifiers(char *nstr, const char *tstr,
@@ -2493,12 +2541,14 @@ ApplyModifiers(char *nstr, const char *tstr,
const char *cp; /* Secondary pointer into str (place marker
* for tstr) */
char *newStr; /* New value to return */
+ char *ep;
char termc; /* Character which terminated scan */
int cnt; /* Used to count brace pairs when variable in
* in parens or braces */
char delim;
int modifier; /* that we are processing */
Var_Parse_State parsestate; /* Flags passed to helper functions */
+ time_t utc; /* for VarStrftime */
delim = '\0';
parsestate.oneBigWord = FALSE;
@@ -2690,6 +2740,28 @@ ApplyModifiers(char *nstr, const char *tstr,
free(loop.str);
break;
}
+ case '_': /* remember current value */
+ cp = tstr + 1; /* make sure it is set */
+ if (STRMOD_MATCHX(tstr, "_", 1)) {
+ if (tstr[1] == '=') {
+ char *np;
+ int n;
+
+ cp++;
+ n = strcspn(cp, ":)}");
+ np = bmake_strndup(cp, n+1);
+ np[n] = '\0';
+ cp = tstr + 2 + n;
+ Var_Set(np, nstr, ctxt, 0);
+ free(np);
+ } else {
+ Var_Set("_", nstr, ctxt, 0);
+ }
+ newStr = nstr;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
case 'D':
case 'U':
{
@@ -2895,8 +2967,6 @@ ApplyModifiers(char *nstr, const char *tstr,
* integer for :[N], or two integers
* separated by ".." for :[start..end].
*/
- char *ep;
-
VarSelectWords_t seldata = { 0, 0 };
seldata.start = strtol(estr, &ep, 0);
@@ -2955,9 +3025,15 @@ ApplyModifiers(char *nstr, const char *tstr,
}
case 'g':
cp = tstr + 1; /* make sure it is set */
- if (STRMOD_MATCH(tstr, "gmtime", 6)) {
- newStr = VarStrftime(nstr, 1);
- cp = tstr + 6;
+ if (STRMOD_MATCHX(tstr, "gmtime", 6)) {
+ if (tstr[6] == '=') {
+ utc = strtoul(&tstr[7], &ep, 10);
+ cp = ep;
+ } else {
+ utc = 0;
+ cp = tstr + 6;
+ }
+ newStr = VarStrftime(nstr, 1, utc);
termc = *cp;
} else {
goto default_case;
@@ -2975,9 +3051,15 @@ ApplyModifiers(char *nstr, const char *tstr,
break;
case 'l':
cp = tstr + 1; /* make sure it is set */
- if (STRMOD_MATCH(tstr, "localtime", 9)) {
- newStr = VarStrftime(nstr, 0);
- cp = tstr + 9;
+ if (STRMOD_MATCHX(tstr, "localtime", 9)) {
+ if (tstr[9] == '=') {
+ utc = strtoul(&tstr[10], &ep, 10);
+ cp = ep;
+ } else {
+ utc = 0;
+ cp = tstr + 9;
+ }
+ newStr = VarStrftime(nstr, 0, utc);
termc = *cp;
} else {
goto default_case;
@@ -3026,7 +3108,6 @@ ApplyModifiers(char *nstr, const char *tstr,
goto get_numeric;
default:
if (isdigit((unsigned char)tstr[3])) {
- char *ep;
get_numeric:
parsestate.varSpace =
@@ -3447,6 +3528,23 @@ ApplyModifiers(char *nstr, const char *tstr,
break;
}
goto default_case;
+ case 'r':
+ cp = tstr + 1; /* make sure it is set */
+ if (STRMOD_MATCHX(tstr, "range", 5)) {
+ int n;
+
+ if (tstr[5] == '=') {
+ n = strtoul(&tstr[6], &ep, 10);
+ cp = ep;
+ } else {
+ n = 0;
+ cp = tstr + 5;
+ }
+ newStr = VarRange(nstr, n);
+ termc = *cp;
+ break;
+ }
+ goto default_case;
case 'O':
{
char otype;