Module Name: src
Committed By: sjg
Date: Mon Jan 30 02:46:20 UTC 2017
Modified Files:
src/usr.bin/make: make.1 var.c
src/usr.bin/make/unit-tests: varmisc.exp varmisc.mk
Log Message:
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
To generate a diff of this commit:
cvs rdiff -u -r1.264 -r1.265 src/usr.bin/make/make.1
cvs rdiff -u -r1.209 -r1.210 src/usr.bin/make/var.c
cvs rdiff -u -r1.5 -r1.6 src/usr.bin/make/unit-tests/varmisc.exp
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/varmisc.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/make.1
diff -u src/usr.bin/make/make.1:1.264 src/usr.bin/make/make.1:1.265
--- src/usr.bin/make/make.1:1.264 Sat Jan 14 22:58:04 2017
+++ src/usr.bin/make/make.1 Mon Jan 30 02:46:20 2017
@@ -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
Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.209 src/usr.bin/make/var.c:1.210
--- src/usr.bin/make/var.c:1.209 Sat Jan 14 22:58:04 2017
+++ src/usr.bin/make/var.c Mon Jan 30 02:46:20 2017
@@ -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, t
(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 *t
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 *t
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;
Index: src/usr.bin/make/unit-tests/varmisc.exp
diff -u src/usr.bin/make/unit-tests/varmisc.exp:1.5 src/usr.bin/make/unit-tests/varmisc.exp:1.6
--- src/usr.bin/make/unit-tests/varmisc.exp:1.5 Sat Jan 14 22:58:04 2017
+++ src/usr.bin/make/unit-tests/varmisc.exp Mon Jan 30 02:46:20 2017
@@ -19,4 +19,6 @@ do not evaluate or expand :? if discardi
is set
year=2016 month=04 day=01
date=20160401
+Version=1.2.3 == 10203
+Literal=3.4.5 == 30405
exit status 0
Index: src/usr.bin/make/unit-tests/varmisc.mk
diff -u src/usr.bin/make/unit-tests/varmisc.mk:1.6 src/usr.bin/make/unit-tests/varmisc.mk:1.7
--- src/usr.bin/make/unit-tests/varmisc.mk:1.6 Sat Jan 14 22:58:04 2017
+++ src/usr.bin/make/unit-tests/varmisc.mk Mon Jan 30 02:46:20 2017
@@ -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}}