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