tech-toolchain archive

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

Re: make: :range



Simon J Gerraty <sjg%juniper.net@localhost> wrote:
> Another example is converting a version like 3.0.5 into something that
> can be compared using > < etc:
> 

> Actually I'd like to be able to encode something like that
> in an inline modifier sequence, but that would require being able to
> refer back to the variable being modified... something like:
> 
> M_cmpv = S,., ,g:range:@i@+ ${_:[-$i]} \* ${units:[$i]}@:S,^,expr 0,:sh
> 
> ie $_ refering to the original variable name.
> One could then do things like:

> .if ${SWIG_VERSION:${M_cmpv}} < ${3.0.11:L:${M_cmpv}}
> # compensate for lack of ....

Actually the patch for this isn't too hideous (other that forcing use of
VAR_INTERNAL during modifier application to avoid clobbering any '_' set
in makefile):

Eg.

--------------------8<--------------------
units = 1 100 10000 100000
version = 3.0.5

v = 0
vc := ${version:S,., ,g}
.for i in ${vc:range}
v += + ${vc:[-$i]} \* ${units:[$i]}
.endfor

n := ${expr $v:L:sh}

# this should produce the same result
M_cmpv = S,., ,g:range:@i@+ $${$_:S,., ,g:[-$$i]} \* $${units:[$$i]}@:S,^,expr 0 ,1:sh

# pollute GLOBAL scope
_=underscore

all:
	@echo 'version=${version} -> $n == ${version:${M_cmpv}} _=$_'

--------------------8<--------------------
	
produces:

version=3.0.5 -> 30005 == 30005 _=underscore

diff -r 44c8e0b96534 bmake/arch.c
--- a/bmake/arch.c	Sat Jan 14 15:21:31 2017 -0800
+++ b/bmake/arch.c	Mon Jan 23 13:58:06 2017 -0800
@@ -308,7 +308,7 @@
 	    char	*result;
 
 	    result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
-			       &length, &freeIt);
+			       &length, &freeIt, NULL);
 	    free(freeIt);
 
 	    if (result == var_Error) {
@@ -350,7 +350,7 @@
 		char	*result;
 
 		result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
-				   &length, &freeIt);
+				   &length, &freeIt, NULL);
 		free(freeIt);
 
 		if (result == var_Error) {
diff -r 44c8e0b96534 bmake/cond.c
--- a/bmake/cond.c	Sat Jan 14 15:21:31 2017 -0800
+++ b/bmake/cond.c	Mon Jan 23 13:58:06 2017 -0800
@@ -290,7 +290,7 @@
 	    void	*freeIt;
 
 	    cp2 = Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES,
-			    &len, &freeIt);
+			    &len, &freeIt, NULL);
 	    Buf_AddBytes(&buf, strlen(cp2), cp2);
 	    free(freeIt);
 	    cp += len;
@@ -576,7 +576,7 @@
 	    /* if we are in quotes, then an undefined variable is ok */
 	    str = Var_Parse(condExpr, VAR_CMD,
 			    ((!qt && doEval) ? VARF_UNDEFERR : 0) |
-			    VARF_WANTRES, &len, freeIt);
+			    VARF_WANTRES, &len, freeIt, NULL);
 	    if (str == var_Error) {
 		if (*freeIt) {
 		    free(*freeIt);
@@ -826,7 +826,7 @@
     /* We do all the work here and return the result as the length */
     *argPtr = NULL;
 
-    val = Var_Parse(cp - 1, VAR_CMD, VARF_WANTRES, &length, &freeIt);
+    val = Var_Parse(cp - 1, VAR_CMD, VARF_WANTRES, &length, &freeIt, NULL);
     /*
      * Advance *linePtr to beyond the closing ). Note that
      * we subtract one because 'length' is calculated from 'cp - 1'.
diff -r 44c8e0b96534 bmake/nonints.h
--- a/bmake/nonints.h	Sat Jan 14 15:21:31 2017 -0800
+++ b/bmake/nonints.h	Mon Jan 23 13:58:06 2017 -0800
@@ -185,7 +185,7 @@
 void Var_Append(const char *, const char *, GNode *);
 Boolean Var_Exists(const char *, GNode *);
 char *Var_Value(const char *, GNode *, char **);
-char *Var_Parse(const char *, GNode *, int, int *, void **);
+char *Var_Parse(const char *, GNode *, int, int *, void **, void *);
 char *Var_Subst(const char *, const char *, GNode *, int);
 char *Var_GetTail(const char *);
 char *Var_GetHead(const char *);
diff -r 44c8e0b96534 bmake/parse.c
--- a/bmake/parse.c	Sat Jan 14 15:21:31 2017 -0800
+++ b/bmake/parse.c	Mon Jan 23 13:58:06 2017 -0800
@@ -1236,7 +1236,7 @@
 		void    *freeIt;
 
 		(void)Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES,
-				&length, &freeIt);
+				&length, &freeIt, NULL);
 		free(freeIt);
 		cp += length-1;
 	    }
diff -r 44c8e0b96534 bmake/suff.c
--- a/bmake/suff.c	Sat Jan 14 15:21:31 2017 -0800
+++ b/bmake/suff.c	Mon Jan 23 13:58:06 2017 -0800
@@ -1612,7 +1612,7 @@
 		    void	*freeIt;
 
 		    junk = Var_Parse(cp, pgn, VARF_UNDEFERR|VARF_WANTRES,
-			&len, &freeIt);
+				     &len, &freeIt, NULL);
 		    if (junk != var_Error) {
 			cp += len - 1;
 		    }
diff -r 44c8e0b96534 bmake/var.c
--- a/bmake/var.c	Sat Jan 14 15:21:31 2017 -0800
+++ b/bmake/var.c	Mon Jan 23 13:58:06 2017 -0800
@@ -2138,6 +2138,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 >= sizeof(tmp))
+	    break;
+	Buf_AddBytes(&buf, n, tmp);
+	if (i != ac - 1)
+	    Buf_AddByte(&buf, ' ');
+    }
+
+    free(as);
+    free(av);
+
+    return Buf_Destroy(&buf, FALSE);
+}
+
 
 /*-
  *-----------------------------------------------------------------------
@@ -2212,7 +2257,7 @@
 		     * substitution and recurse.
 		     */
 		    cp2 = Var_Parse(cp, ctxt, errnum | VARF_WANTRES, &len,
-			&freeIt);
+				    &freeIt, NULL);
 		    Buf_AddBytes(&buf, strlen(cp2), cp2);
 		    free(freeIt);
 		    cp += len - 1;
@@ -2520,7 +2565,7 @@
 	    int rlen;
 	    int c;
 
-	    rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
+	    rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt, v);
 
 	    /*
 	     * If we have not parsed up to endc or ':',
@@ -2738,7 +2783,7 @@
 			    int	    len;
 			    void    *freeIt;
 
-			    cp2 = Var_Parse(cp, ctxt, nflags, &len, &freeIt);
+			    cp2 = Var_Parse(cp, ctxt, nflags, &len, &freeIt, v);
 			    Buf_AddBytes(&buf, strlen(cp2), cp2);
 			    free(freeIt);
 			    cp += len - 1;
@@ -3459,6 +3504,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;
@@ -3653,7 +3715,7 @@
 /* coverity[+alloc : arg-*4] */
 char *
 Var_Parse(const char *str, GNode *ctxt, int flags,
-	  int *lengthPtr, void **freePtr)
+	  int *lengthPtr, void **freePtr, void *varp)
 {
     const char	   *tstr;    	/* Pointer into str */
     Var		   *v;		/* Variable in invocation */
@@ -3677,6 +3739,11 @@
     dynamic = FALSE;
     start = str;
 
+    if (varp) {
+	v = varp;
+	Var_Set("_", v->name, VAR_INTERNAL, 0);
+	ctxt = VAR_INTERNAL;
+    }
     startc = str[1];
     if (startc != PROPEN && startc != BROPEN) {
 	/*
@@ -3758,7 +3825,7 @@
 	    if (*tstr == '$') {
 		int rlen;
 		void *freeIt;
-		char *rval = Var_Parse(tstr, ctxt, flags,  &rlen, &freeIt);
+		char *rval = Var_Parse(tstr, ctxt, flags,  &rlen, &freeIt, NULL);
 		if (rval != NULL) {
 		    Buf_AddBytes(&buf, strlen(rval), rval);
 		}
@@ -4101,7 +4168,7 @@
 		    continue;
 	    }
 
-	    val = Var_Parse(str, ctxt, flags, &length, &freeIt);
+	    val = Var_Parse(str, ctxt, flags, &length, &freeIt, NULL);
 
 	    /*
 	     * When we come down here, val should either point to the


Home | Main Index | Thread Index | Old Index