version 1.324, 2020/07/26 18:47:02 |
version 1.325, 2020/07/26 19:11:06 |
Line 3452 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3452 Var_Parse(const char *str, GNode *ctxt, |
|
return (flags & VARE_UNDEFERR) ? var_Error : varNoError; |
return (flags & VARE_UNDEFERR) ? var_Error : varNoError; |
} else { |
} else { |
haveModifier = FALSE; |
haveModifier = FALSE; |
tstr = &str[1]; |
tstr = str + 1; |
endc = str[1]; |
endc = str[1]; |
} |
} |
} else { |
} else { |
Line 3501 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3501 Var_Parse(const char *str, GNode *ctxt, |
|
Buf_Destroy(&buf, TRUE); |
Buf_Destroy(&buf, TRUE); |
return var_Error; |
return var_Error; |
} |
} |
str = Buf_GetAll(&buf, &vlen); |
|
|
char *varname = Buf_GetAll(&buf, &vlen); |
|
|
/* |
/* |
* At this point, str points into newly allocated memory from |
* At this point, varname points into newly allocated memory from |
* buf, containing only the name of the variable. |
* buf, containing only the name of the variable. |
* |
* |
* start and tstr point into the const string that was pointed |
* start and tstr point into the const string that was pointed |
Line 3514 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3515 Var_Parse(const char *str, GNode *ctxt, |
|
* will be '\0', ':', PRCLOSE, or BRCLOSE. |
* will be '\0', ':', PRCLOSE, or BRCLOSE. |
*/ |
*/ |
|
|
v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); |
v = VarFind(varname, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); |
/* |
/* |
* Check also for bogus D and F forms of local variables since we're |
* Check also for bogus D and F forms of local variables since we're |
* in a local context and the name is the right length. |
* in a local context and the name is the right length. |
*/ |
*/ |
if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && |
if (v == NULL && ctxt != VAR_CMD && ctxt != VAR_GLOBAL && |
(vlen == 2) && (str[1] == 'F' || str[1] == 'D') && |
vlen == 2 && (varname[1] == 'F' || varname[1] == 'D') && |
strchr("@%?*!<>", str[0]) != NULL) { |
strchr("@%?*!<>", varname[0]) != NULL) { |
/* |
/* |
* Well, it's local -- go look for it. |
* Well, it's local -- go look for it. |
*/ |
*/ |
name[0] = *str; |
name[0] = varname[0]; |
name[1] = '\0'; |
name[1] = '\0'; |
v = VarFind(name, ctxt, 0); |
v = VarFind(name, ctxt, 0); |
|
|
if (v != NULL) { |
if (v != NULL) { |
if (str[1] == 'D') { |
if (varname[1] == 'D') { |
extramodifiers = "H:"; |
extramodifiers = "H:"; |
} else { /* F */ |
} else { /* F */ |
extramodifiers = "T:"; |
extramodifiers = "T:"; |
Line 3539 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3540 Var_Parse(const char *str, GNode *ctxt, |
|
} |
} |
|
|
if (v == NULL) { |
if (v == NULL) { |
if (((vlen == 1) || |
if ((vlen == 1 || |
(((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) && |
((vlen == 2 && (varname[1] == 'F' || varname[1] == 'D')))) && |
((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) |
(ctxt == VAR_CMD || ctxt == VAR_GLOBAL)) |
{ |
{ |
/* |
/* |
* If substituting a local variable in a non-local context, |
* If substituting a local variable in a non-local context, |
Line 3552 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3553 Var_Parse(const char *str, GNode *ctxt, |
|
* specially as they are the only four that will be set |
* specially as they are the only four that will be set |
* when dynamic sources are expanded. |
* when dynamic sources are expanded. |
*/ |
*/ |
switch (*str) { |
switch (varname[0]) { |
case '@': |
case '@': |
case '%': |
case '%': |
case '*': |
case '*': |
Line 3560 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3561 Var_Parse(const char *str, GNode *ctxt, |
|
dynamic = TRUE; |
dynamic = TRUE; |
break; |
break; |
} |
} |
} else if (vlen > 2 && *str == '.' && |
} else if (vlen > 2 && varname[0] == '.' && |
isupper((unsigned char) str[1]) && |
isupper((unsigned char) varname[1]) && |
(ctxt == VAR_CMD || ctxt == VAR_GLOBAL)) |
(ctxt == VAR_CMD || ctxt == VAR_GLOBAL)) |
{ |
{ |
int len = vlen - 1; |
int len = vlen - 1; |
if ((strncmp(str, ".TARGET", len) == 0) || |
if ((strncmp(varname, ".TARGET", len) == 0) || |
(strncmp(str, ".ARCHIVE", len) == 0) || |
(strncmp(varname, ".ARCHIVE", len) == 0) || |
(strncmp(str, ".PREFIX", len) == 0) || |
(strncmp(varname, ".PREFIX", len) == 0) || |
(strncmp(str, ".MEMBER", len) == 0)) |
(strncmp(varname, ".MEMBER", len) == 0)) |
{ |
{ |
dynamic = TRUE; |
dynamic = TRUE; |
} |
} |
Line 3595 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3596 Var_Parse(const char *str, GNode *ctxt, |
|
* so kludge up a Var structure for the modifications |
* so kludge up a Var structure for the modifications |
*/ |
*/ |
v = bmake_malloc(sizeof(Var)); |
v = bmake_malloc(sizeof(Var)); |
v->name = UNCONST(str); |
v->name = varname; |
Buf_Init(&v->val, 1); |
Buf_Init(&v->val, 1); |
v->flags = VAR_JUNK; |
v->flags = VAR_JUNK; |
Buf_Destroy(&buf, FALSE); |
Buf_Destroy(&buf, FALSE); |
Line 3668 Var_Parse(const char *str, GNode *ctxt, |
|
Line 3669 Var_Parse(const char *str, GNode *ctxt, |
|
/* |
/* |
* Perform any free'ing needed and set *freePtr to NULL so the caller |
* Perform any free'ing needed and set *freePtr to NULL so the caller |
* doesn't try to free a static pointer. |
* doesn't try to free a static pointer. |
* If VAR_KEEP is also set then we want to keep str as is. |
* If VAR_KEEP is also set then we want to keep str(?) as is. |
*/ |
*/ |
if (!(v->flags & VAR_KEEP)) { |
if (!(v->flags & VAR_KEEP)) { |
if (*freePtr) { |
if (*freePtr) { |