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}}