Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Add :range and :_



details:   https://anonhg.NetBSD.org/src/rev/1d27c7d0d4d4
branches:  trunk
changeset: 821249:1d27c7d0d4d4
user:      sjg <sjg%NetBSD.org@localhost>
date:      Mon Jan 30 02:46:20 2017 +0000

description:
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:

 usr.bin/make/make.1                 |  31 +++++++++++++-
 usr.bin/make/unit-tests/varmisc.exp |   2 +
 usr.bin/make/unit-tests/varmisc.mk  |  14 +++++-
 usr.bin/make/var.c                  |  78 +++++++++++++++++++++++++++++++++++-
 4 files changed, 118 insertions(+), 7 deletions(-)

diffs (224 lines):

diff -r 4e5a0a5a28b9 -r 1d27c7d0d4d4 usr.bin/make/make.1
--- a/usr.bin/make/make.1       Mon Jan 30 02:41:12 2017 +0000
+++ b/usr.bin/make/make.1       Mon Jan 30 02:46:20 2017 +0000
@@ -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 @@
 .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 @@
 .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 -r 4e5a0a5a28b9 -r 1d27c7d0d4d4 usr.bin/make/unit-tests/varmisc.exp
--- a/usr.bin/make/unit-tests/varmisc.exp       Mon Jan 30 02:41:12 2017 +0000
+++ b/usr.bin/make/unit-tests/varmisc.exp       Mon Jan 30 02:46:20 2017 +0000
@@ -19,4 +19,6 @@
 is set
 year=2016 month=04 day=01
 date=20160401
+Version=1.2.3 == 10203
+Literal=3.4.5 == 30405
 exit status 0
diff -r 4e5a0a5a28b9 -r 1d27c7d0d4d4 usr.bin/make/unit-tests/varmisc.mk
--- a/usr.bin/make/unit-tests/varmisc.mk        Mon Jan 30 02:41:12 2017 +0000
+++ b/usr.bin/make/unit-tests/varmisc.mk        Mon Jan 30 02:46:20 2017 +0000
@@ -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 @@
        @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 -r 4e5a0a5a28b9 -r 1d27c7d0d4d4 usr.bin/make/var.c
--- a/usr.bin/make/var.c        Mon Jan 30 02:41:12 2017 +0000
+++ b/usr.bin/make/var.c        Mon Jan 30 02:46:20 2017 +0000
@@ -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 @@
     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 @@
     (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 @@
                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 @@
                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;



Home | Main Index | Thread Index | Old Index