Fix handling of the silly $(@D) $(@F) etc. vars so modifiers on them

work. This is issue #1 in PR 49085 from Jarmo Jaakkola, but I've used
a different and cleaner patch this time.
This commit is contained in:
dholland 2014-09-14 02:32:51 +00:00
parent 58de96de3f
commit d2a37b0d8b

View File

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.190 2014/09/13 23:21:01 dholland Exp $ */
/* $NetBSD: var.c,v 1.191 2014/09/14 02:32:51 dholland Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: var.c,v 1.190 2014/09/13 23:21:01 dholland Exp $";
static char rcsid[] = "$NetBSD: var.c,v 1.191 2014/09/14 02:32:51 dholland 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.190 2014/09/13 23:21:01 dholland Exp $");
__RCSID("$NetBSD: var.c,v 1.191 2014/09/14 02:32:51 dholland Exp $");
#endif
#endif /* not lint */
#endif
@ -3599,14 +3599,13 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
* expanding it in a non-local context. This
* is done to support dynamic sources. The
* result is just the invocation, unaltered */
Var_Parse_State parsestate; /* Flags passed to helper functions */
const char *extramodifiers; /* extra modifiers to apply first */
char name[2];
*freePtr = NULL;
extramodifiers = NULL;
dynamic = FALSE;
start = str;
parsestate.oneBigWord = FALSE;
parsestate.varSpace = ' '; /* word separator */
startc = str[1];
if (startc != PROPEN && startc != BROPEN) {
@ -3743,29 +3742,12 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
v = VarFind(name, ctxt, 0);
if (v != NULL) {
/*
* 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...
*/
nstr = Buf_GetAll(&v->val, NULL);
if (str[1] == 'D') {
nstr = VarModify(ctxt, &parsestate, nstr, VarHead,
NULL);
} else {
nstr = VarModify(ctxt, &parsestate, nstr, VarTail,
NULL);
extramodifiers = "H:";
}
else { /* F */
extramodifiers = "T:";
}
/*
* Resulting string is dynamically allocated, so
* tell caller to free it.
*/
*freePtr = nstr;
*lengthPtr = tstr-start+1;
Buf_Destroy(&buf, TRUE);
VarFreeEnv(v, TRUE);
return nstr;
}
}
@ -3860,16 +3842,29 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
v->flags &= ~VAR_IN_USE;
if ((nstr != NULL) && haveModifier) {
if ((nstr != NULL) && (haveModifier || extramodifiers != NULL)) {
void *extraFree;
int used;
/*
* Skip initial colon.
*/
tstr++;
nstr = ApplyModifiers(nstr, tstr, startc, endc,
v, ctxt, errnum, &used, freePtr);
tstr += used;
extraFree = NULL;
if (extramodifiers != NULL) {
nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
v, ctxt, errnum, &used, &extraFree);
}
if (haveModifier) {
/* Skip initial colon. */
tstr++;
nstr = ApplyModifiers(nstr, tstr, startc, endc,
v, ctxt, errnum, &used, freePtr);
tstr += used;
if (extraFree) {
free(extraFree);
}
} else {
*freePtr = extraFree;
}
}
if (*tstr) {
*lengthPtr = tstr - start + 1;