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

Reply via email to