summaryrefslogtreecommitdiff
path: root/usr.bin/make
diff options
context:
space:
mode:
authorsjg <sjg@NetBSD.org>2017-01-30 02:46:20 +0000
committersjg <sjg@NetBSD.org>2017-01-30 02:46:20 +0000
commit4e63770db0aa9deb37dd7a7ffde5886a413a8cc0 (patch)
tree1cd70e2e5d11a68541c039292e5f22e88ebf4c6d /usr.bin/make
parent44a97d0210b25fc07d55c10591df4ee477b9da14 (diff)
Add :range and :_
:range replaces var value with an integer sequence one per word in the current var value. :_ stores the current var value in $_ so that it can be referred to later in the modifier series. Reviewed by: christos
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/make.131
-rw-r--r--usr.bin/make/unit-tests/varmisc.exp2
-rw-r--r--usr.bin/make/unit-tests/varmisc.mk14
-rw-r--r--usr.bin/make/var.c78
4 files changed, 118 insertions, 7 deletions
diff --git a/usr.bin/make/make.1 b/usr.bin/make/make.1
index 7d0a01c2545..8d6bf431977 100644
--- a/usr.bin/make/make.1
+++ b/usr.bin/make/make.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.264 2017/01/14 22:58:04 sjg Exp $
+.\" $NetBSD: make.1,v 1.265 2017/01/30 02:46:20 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 January 14, 2017
+.Dd January 29, 2017
.Dt MAKE 1
.Os
.Sh NAME
@@ -1204,6 +1204,10 @@ safely through recursive invocations of
.Nm .
.It Cm \&:R
Replaces each word in the variable with everything but its suffix.
+.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 ,
@@ -1421,6 +1425,29 @@ For example.
.Pp
However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Cm \&:_
+Save the current variable value in
+.Ql $_
+for later reference.
+This
+.Ql $_
+is internal to the variable modifier processing and
+will not conflict with any set in a makefile.
+Example usage:
+.Bd -literal -offset indent
+M_cmpv.units = 1 100 10000
+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 the
+.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/usr.bin/make/unit-tests/varmisc.exp b/usr.bin/make/unit-tests/varmisc.exp
index 555534f2f51..e6ce3545f1d 100644
--- a/usr.bin/make/unit-tests/varmisc.exp
+++ b/usr.bin/make/unit-tests/varmisc.exp
@@ -19,4 +19,6 @@ do not evaluate or expand :? if discarding
is set
year=2016 month=04 day=01
date=20160401
+Version=1.2.3 == 10203
+Literal=3.4.5 == 30405
exit status 0
diff --git a/usr.bin/make/unit-tests/varmisc.mk b/usr.bin/make/unit-tests/varmisc.mk
index 4b856c43d3d..5de314700a1 100644
--- a/usr.bin/make/unit-tests/varmisc.mk
+++ b/usr.bin/make/unit-tests/varmisc.mk
@@ -1,9 +1,9 @@
-# $Id: varmisc.mk,v 1.6 2017/01/14 22:58:04 sjg Exp $
+# $Id: varmisc.mk,v 1.7 2017/01/30 02:46:20 sjg Exp $
#
# Miscellaneous variable tests.
all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \
- strftime
+ strftime cmpv
unmatched_var_paren:
@echo ${foo::=foo-text}
@@ -49,3 +49,13 @@ 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 100 10000 1000000
+# this will produce the same result as the .for loop below
+M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+
+Version = 1.2.3
+
+cmpv:
+ @echo Version=${Version} == ${Version:${M_cmpv}}
+ @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}}
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 7e648009b7a..aefd5de679d 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.209 2017/01/14 22:58:04 sjg Exp $ */
+/* $NetBSD: var.c,v 1.210 2017/01/30 02:46:20 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.209 2017/01/14 22:58:04 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.210 2017/01/30 02:46:20 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.209 2017/01/14 22:58:04 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.210 2017/01/30 02:46:20 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -2140,6 +2140,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);
+}
+
/*-
*-----------------------------------------------------------------------
@@ -2485,6 +2530,7 @@ VarStrftime(const char *fmt, int zulu, time_t utc)
(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,
@@ -2695,6 +2741,15 @@ ApplyModifiers(char *nstr, const char *tstr,
free(loop.str);
break;
}
+ case '_': /* remember current value */
+ if CHARMOD_MATCH(tstr[1]) {
+ Var_Set("_", nstr, VAR_INTERNAL, 0);
+ newStr = nstr;
+ cp = ++tstr;
+ termc = *tstr;
+ break;
+ }
+ goto default_case;
case 'D':
case 'U':
{
@@ -3461,6 +3516,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;