summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/make/var.c282
1 files changed, 143 insertions, 139 deletions
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 3f2a9f7..5686aa3 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -1499,21 +1499,14 @@ VarParseLong(char foo[], GNode *ctxt, Boolean err, size_t *lengthPtr,
{
const char *input = foo;
char *rw_str = foo;
-
- Var *v; /* Variable in invocation */
- const char *vname;
- size_t vlen; /* length of variable name, after embedded variable
- * expansion */
- Boolean haveModifier; /* TRUE if have modifiers for the variable */
- char endc; /* Ending character when variable in parens
+ char *ptr;
+ char endc; /* Ending character when variable in parens
* or braces */
- char startc; /* Starting character when variable in parens
+ char startc; /* Starting character when variable in parens
* or braces */
- char *tstr; /* Pointer into str */
- Boolean dynamic; /* TRUE if the variable is local and we're
- * expanding it in a non-local context. This
- * is done to support dynamic sources. The
- * result is just the invocation, unaltered */
+ const char *vname;
+ size_t vlen; /* length of variable name, after embedded
+ * variable expansion */
/* build up expanded variable name in this buffer */
Buffer *buf = Buf_Init(MAKE_BSIZE);
@@ -1524,10 +1517,10 @@ VarParseLong(char foo[], GNode *ctxt, Boolean err, size_t *lengthPtr,
*/
startc = input[1];
endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE;
- tstr = rw_str + 2;
+ ptr = rw_str + 2;
- while (*tstr != endc && *tstr != ':') {
- if (*tstr == '\0') {
+ while (*ptr != endc && *ptr != ':') {
+ if (*ptr == '\0') {
/*
* If we did not find the end character,
* return var_Error right now, setting the
@@ -1535,177 +1528,188 @@ VarParseLong(char foo[], GNode *ctxt, Boolean err, size_t *lengthPtr,
* the string, since that's what make does.
*/
*freePtr = FALSE;
- *lengthPtr = tstr - input;
+ *lengthPtr = ptr - input;
Buf_Destroy(buf, TRUE);
return (var_Error);
- } else if (*tstr == '$') {
+ } else if (*ptr == '$') {
size_t rlen;
Boolean rfree;
char *rval;
rlen = 0;
- rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
+ rval = Var_Parse(ptr, ctxt, err, &rlen, &rfree);
if (rval == var_Error) {
Fatal("Error expanding embedded variable.");
}
Buf_Append(buf, rval);
if (rfree)
free(rval);
- tstr += rlen - 1;
+ ptr += rlen - 1;
} else {
- Buf_AddByte(buf, (Byte)*tstr);
+ Buf_AddByte(buf, (Byte)*ptr);
}
- tstr++;
+ ptr++;
}
- haveModifier = (*tstr == ':');
-
vname = Buf_GetAll(buf, (size_t *)NULL); /* REPLACE str */
vlen = strlen(vname);
+ {
+ char *const tstr = ptr;
+ size_t consumed = tstr - input + 1;
+
+ Var *v; /* Variable in invocation */
+ Boolean haveModifier; /* TRUE if have modifiers for the variable */
+ Boolean dynamic; /* TRUE if the variable is local and we're
+ * expanding it in a non-local context. This
+ * is done to support dynamic sources. The
+ * result is just the invocation, unaltered */
+
+ haveModifier = (*tstr == ':');
+ dynamic = FALSE;
+
v = VarFind(vname, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
+ if (v != NULL) {
+ Buf_Destroy(buf, TRUE);
- if ((v == NULL) &&
- (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
- (vlen == 2) && (vname[1] == 'F' || vname[1] == 'D'))
- {
- /*
- * Check for bogus D and F forms of local variables since we're
- * in a local context and the name is the right length.
- */
- if (strchr("!%*<>@", vname[0]) != NULL) {
- char name[2];
- char *val;
+ if (haveModifier) {
+ return (ParseModifier(input, tstr,
+ startc, endc, dynamic, v,
+ ctxt, err, lengthPtr, freePtr));
+ } else {
+ char *result;
- /*
- * Well, it's local -- go look for it.
- */
- name[0] = vname[0];
- name[1] = '\0';
+ result = VarExpand(v, ctxt, err);
- v = VarFind(name, ctxt, 0);
- if (v != NULL && !haveModifier) {
- /*
- * No need for nested expansion or anything, as we're
- * the only one who sets these things and we sure don't
- * put nested invocations in them...
- */
- val = (char *)Buf_GetAll(v->val, (size_t *)NULL);
+ if (v->flags & VAR_FROM_ENV) {
+ VarDestroy(v, TRUE);
+ }
- if (vname[1] == 'D') {
- val = VarModify(val, VarHead, (void *)NULL);
- } else {
- val = VarModify(val, VarTail, (void *)NULL);
- }
- /*
- * Resulting string is dynamically allocated, so
- * tell caller to free it.
- */
- *freePtr = TRUE;
- *lengthPtr = tstr - input + 1;
- Buf_Destroy(buf, TRUE);
- return (val);
+ *freePtr = TRUE;
+ *lengthPtr = consumed;
+ return (result);
}
- }
}
- dynamic = FALSE;
-
- if (v == NULL) {
- if (((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) &&
- ((vlen == 1) ||
- ((vlen == 2) && (vname[1] == 'F' || vname[1] == 'D'))))
- {
+ if ((ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL)) {
/*
- * If substituting a local variable in a non-local context,
- * assume it's for dynamic source stuff. We have to handle
- * this specially and return the longhand for the variable
- * with the dollar sign escaped so it makes it back to the
- * caller. Only four of the local variables are treated
- * specially as they are the only four that will be set
- * when dynamic sources are expanded.
+ * Check for D and F forms of local variables since we're in
+ * a local context and the name is the right length.
*/
- if (strchr("!%*@", vname[0]) != NULL) {
- dynamic = TRUE;
- } else {
- dynamic = FALSE;
+ if ((vlen == 2) &&
+ (vname[1] == 'F' || vname[1] == 'D') &&
+ (strchr("!%*<>@", vname[0]) != NULL)) {
+ char name[2];
+ char *val;
+
+ /*
+ * Well, it's local -- go look for it.
+ */
+ name[0] = vname[0];
+ name[1] = '\0';
+
+ v = VarFind(name, ctxt, 0);
+ if (v != NULL) {
+ if (haveModifier) {
+ Buf_Destroy(buf, TRUE);
+ return (ParseModifier(input, tstr,
+ startc, endc, dynamic, v,
+ ctxt, err, lengthPtr, freePtr));
+ } else {
+ /*
+ * No need for nested expansion or
+ * anything, as we're the only one
+ * who sets these things and we sure
+ * don't put nested invocations in
+ * them...
+ */
+ val = (char *)Buf_GetAll(v->val, (size_t *) NULL);
+
+ if (vname[1] == 'D') {
+ val = VarModify(val, VarHead, (void *)NULL);
+ } else {
+ val = VarModify(val, VarTail, (void *)NULL);
+ }
+ /*
+ * Resulting string is dynamically
+ * allocated, so tell caller to free
+ * it.
+ */
+ *freePtr = TRUE;
+ *lengthPtr = consumed;
+ Buf_Destroy(buf, TRUE);
+ return (val);
+ }
+ }
}
- } else if (((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) &&
- (vlen > 2) &&
- (vname[0] == '.') &&
- isupper((unsigned char)vname[1]))
- {
- int len;
-
- len = vlen - 1;
- if ((strncmp(vname, ".TARGET", len) == 0) ||
- (strncmp(vname, ".ARCHIVE", len) == 0) ||
- (strncmp(vname, ".PREFIX", len) == 0) ||
- (strncmp(vname, ".MEMBER", len) == 0))
- {
- dynamic = TRUE;
- } else {
- dynamic = FALSE;
+ } else {
+ if (((vlen == 1)) ||
+ ((vlen == 2) && (vname[1] == 'F' || vname[1] == 'D'))) {
+ /*
+ * If substituting a local variable in a non-local
+ * context, assume it's for dynamic source stuff. We
+ * have to handle this specially and return the
+ * longhand for the variable with the dollar sign
+ * escaped so it makes it back to the caller. Only
+ * four of the local variables are treated specially
+ * as they are the only four that will be set when
+ * dynamic sources are expanded.
+ */
+ if (strchr("!%*@", vname[0]) != NULL) {
+ dynamic = TRUE;
+ }
}
- } else {
- dynamic = FALSE;
- }
+ if ((vlen > 2) &&
+ (vname[0] == '.') &&
+ isupper((unsigned char)vname[1])) {
+ if ((strncmp(vname, ".TARGET", vlen - 1) == 0) ||
+ (strncmp(vname, ".ARCHIVE", vlen - 1) == 0) ||
+ (strncmp(vname, ".PREFIX", vlen - 1) == 0) ||
+ (strncmp(vname, ".MEMBER", vlen - 1) == 0)) {
+ dynamic = TRUE;
+ }
+ }
+ }
- if (haveModifier) {
+ if (haveModifier) {
/*
- * Still need to get to the end of the variable specification,
- * so kludge up a Var structure for the modifications
+ * Still need to get to the end of the variable
+ * specification, so kludge up a Var structure for
+ * the modifications
*/
v = VarCreate(vname, NULL, VAR_JUNK);
- } else {
+ Buf_Destroy(buf, TRUE);
+ return (ParseModifier(input, tstr,
+ startc, endc, dynamic, v,
+ ctxt, err, lengthPtr, freePtr));
+ } else {
/*
- * No modifiers -- have specification length so we can return
- * now.
+ * No modifiers -- have specification length so we
+ * can return now.
*/
- size_t rlen = tstr - input + 1;
if (dynamic) {
- char *result;
+ char *result;
- result = emalloc(rlen + 1);
- strncpy(result, input, rlen);
- result[rlen] = '\0';
+ result = emalloc(consumed + 1);
+ strncpy(result, input, consumed);
+ result[consumed] = '\0';
- *freePtr = TRUE;
- *lengthPtr = rlen;
+ *freePtr = TRUE;
+ *lengthPtr = consumed;
- Buf_Destroy(buf, TRUE);
- return (result);
+ Buf_Destroy(buf, TRUE);
+ return (result);
} else {
- *freePtr = FALSE;
- *lengthPtr = rlen;
-
- Buf_Destroy(buf, TRUE);
- return (err ? var_Error : varNoError);
- }
- }
- }
-
- Buf_Destroy(buf, TRUE);
-
- if (haveModifier) {
- return (ParseModifier(input, tstr,
- startc, endc, dynamic, v,
- ctxt, err, lengthPtr, freePtr));
- } else {
- char *result;
-
- result = VarExpand(v, ctxt, err);
+ *freePtr = FALSE;
+ *lengthPtr = consumed;
- if (v->flags & VAR_FROM_ENV) {
- VarDestroy(v, TRUE);
+ Buf_Destroy(buf, TRUE);
+ return (err ? var_Error : varNoError);
}
-
- *freePtr = TRUE;
- *lengthPtr = tstr - input + 1;
- return (result);
}
+ }
}
/**
OpenPOWER on IntegriCloud