diff options
| author | sjg <sjg@NetBSD.org> | 2017-01-30 02:46:20 +0000 |
|---|---|---|
| committer | sjg <sjg@NetBSD.org> | 2017-01-30 02:46:20 +0000 |
| commit | 4e63770db0aa9deb37dd7a7ffde5886a413a8cc0 (patch) | |
| tree | 1cd70e2e5d11a68541c039292e5f22e88ebf4c6d /usr.bin/make | |
| parent | 44a97d0210b25fc07d55c10591df4ee477b9da14 (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.1 | 31 | ||||
| -rw-r--r-- | usr.bin/make/unit-tests/varmisc.exp | 2 | ||||
| -rw-r--r-- | usr.bin/make/unit-tests/varmisc.mk | 14 | ||||
| -rw-r--r-- | usr.bin/make/var.c | 78 |
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; |
