Split Var_Subst() into two functions: Var_SubstOnly() which substitutes

only one variable and Var_Subst() which substitutes all. Split out the
test whether a variable should not be expanded into match_var().
Make access to the input string consistently using str[]. Remove two
unused functions: Var_GetTail() and Var_GetHead().

Patches:	7.184-7.189
Submitted by:	Max Okumoto <okumoto@ucsd.edu>
This commit is contained in:
Hartmut Brandt 2005-05-09 14:06:04 +00:00
parent 18d92cd86c
commit 02c3270da1
9 changed files with 174 additions and 163 deletions

View File

@ -249,7 +249,7 @@ Arch_ParseArchive(char **linePtr, Lst *nodeLst, GNode *ctxt)
*cp++ = '\0';
if (subLibName) {
libName = Buf_Peel(Var_Subst(NULL, libName, ctxt, TRUE));
libName = Buf_Peel(Var_Subst(libName, ctxt, TRUE));
}
for (;;) {
@ -346,7 +346,7 @@ Arch_ParseArchive(char **linePtr, Lst *nodeLst, GNode *ctxt)
* The results are just placed at the end of the
* nodeLst we're returning.
*/
buf1 = Var_Subst(NULL, memName, ctxt, TRUE);
buf1 = Var_Subst(memName, ctxt, TRUE);
memName = Buf_Data(buf1);
sz = strlen(memName) + strlen(libName) + 3;

View File

@ -252,7 +252,7 @@ Compat_RunCommand(char *cmd, GNode *gn)
doit = FALSE;
cmdNode = Lst_Member(&gn->commands, cmd);
cmdStart = Buf_Peel(Var_Subst(NULL, cmd, gn, FALSE));
cmdStart = Buf_Peel(Var_Subst(cmd, gn, FALSE));
/*
* brk_string will return an argv with a NULL in av[0], thus causing

View File

@ -150,7 +150,7 @@ For_For(char *line)
* Make a list with the remaining words
* XXX should use brk_string here.
*/
sub = Buf_Peel(Var_Subst(NULL, ptr, VAR_CMD, FALSE));
sub = Buf_Peel(Var_Subst(ptr, VAR_CMD, FALSE));
for (ptr = sub; *ptr != '\0' && isspace((u_char)*ptr); ptr++)
;
@ -271,7 +271,7 @@ For_Run(int lineno)
Var_Set(var, val, VAR_GLOBAL);
DEBUGF(FOR, ("--- %s = %s\n", var, val));
str = Buf_Peel(Var_Subst(var, Buf_Data(buf),
str = Buf_Peel(Var_SubstOnly(var, Buf_Data(buf),
VAR_GLOBAL, FALSE));
Parse_FromString(str, lineno);

View File

@ -609,7 +609,7 @@ JobPrintCommand(char *cmd, Job *job)
*/
cmdNode = Lst_Member(&job->node->commands, cmd);
cmd = Buf_Peel(Var_Subst(NULL, cmd, job->node, FALSE));
cmd = Buf_Peel(Var_Subst(cmd, job->node, FALSE));
cmdStart = cmd;
Lst_Replace(cmdNode, cmdStart);
@ -972,8 +972,8 @@ JobFinish(Job *job, int *status)
*/
for (ln = job->tailCmds; ln != NULL; ln = LST_NEXT(ln)) {
Lst_AtEnd(&postCommands->commands,
Buf_Peel(Var_Subst(NULL, Lst_Datum(ln),
job->node, FALSE)));
Buf_Peel(
Var_Subst(Lst_Datum(ln), job->node, FALSE)));
}
job->node->made = MADE;
@ -1655,8 +1655,8 @@ JobStart(GNode *gn, int flags, Job *previous)
for (ln = job->tailCmds; ln != NULL;
ln = LST_NEXT(ln)) {
Lst_AtEnd(&postCommands->commands,
Buf_Peel(Var_Subst(NULL,
Lst_Datum(ln), job->node, FALSE)));
Buf_Peel(Var_Subst(Lst_Datum(ln),
job->node, FALSE)));
}
job->node->made = MADE;
Make_Update(job->node);

View File

@ -901,7 +901,7 @@ main(int argc, char **argv)
char *ptr;
char savec;
buf = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
buf = Var_Subst(VPATH, VAR_CMD, FALSE);
vpath = Buf_Data(buf);
do {
@ -992,7 +992,7 @@ main(int argc, char **argv)
v = emalloc(strlen(name) + 1 + 3);
sprintf(v, "${%s}", name);
value = Buf_Peel(Var_Subst(NULL, v,
value = Buf_Peel(Var_Subst(v,
VAR_GLOBAL, FALSE));
printf("%s\n", value);

View File

@ -1493,7 +1493,7 @@ Parse_DoVar(char *line, GNode *ctxt)
if (!Var_Exists(line, ctxt))
Var_Set(line, "", ctxt);
cp = Buf_Peel(Var_Subst(NULL, cp, ctxt, FALSE));
cp = Buf_Peel(Var_Subst(cp, ctxt, FALSE));
oldVars = oldOldVars;
@ -1516,7 +1516,7 @@ Parse_DoVar(char *line, GNode *ctxt)
* resulting string will need freeing when we're done,
* so set freeCmd to TRUE.
*/
cp = Buf_Peel(Var_Subst(NULL, cp, VAR_CMD, TRUE));
cp = Buf_Peel(Var_Subst(cp, VAR_CMD, TRUE));
freeCmd = TRUE;
}
@ -1655,7 +1655,7 @@ ParseTraditionalInclude(char *file)
* Substitute for any variables in the file name before trying to
* find the thing.
*/
file = Buf_Peel(Var_Subst(NULL, file, VAR_CMD, FALSE));
file = Buf_Peel(Var_Subst(file, VAR_CMD, FALSE));
/*
* Now we know the file's name, we attempt to find the durn thing.
@ -2127,7 +2127,7 @@ parse_include(char *file, int code __unused, int lineno __unused)
* Substitute for any variables in the file name before trying to
* find the thing.
*/
file = Buf_Peel(Var_Subst(NULL, file, VAR_CMD, FALSE));
file = Buf_Peel(Var_Subst(file, VAR_CMD, FALSE));
/*
* Now we know the file's name and its search path, we attempt to
@ -2227,7 +2227,7 @@ parse_message(char *line, int iserror, int lineno __unused)
while (isspace((u_char)*line))
line++;
line = Buf_Peel(Var_Subst(NULL, line, VAR_GLOBAL, FALSE));
line = Buf_Peel(Var_Subst(line, VAR_GLOBAL, FALSE));
Parse_Error(iserror ? PARSE_FATAL : PARSE_WARNING, "%s", line);
free(line);
@ -2254,7 +2254,7 @@ parse_undef(char *line, int code __unused, int lineno __unused)
}
*cp = '\0';
cp = Buf_Peel(Var_Subst(NULL, line, VAR_CMD, FALSE));
cp = Buf_Peel(Var_Subst(line, VAR_CMD, FALSE));
Var_Delete(cp, VAR_GLOBAL);
free(cp);
}
@ -2468,7 +2468,7 @@ Parse_File(const char *name, FILE *stream)
ParseFinishLine();
cp = Buf_Peel(Var_Subst(NULL, line, VAR_CMD, TRUE));
cp = Buf_Peel(Var_Subst(line, VAR_CMD, TRUE));
free(line);
line = cp;

View File

@ -1155,7 +1155,7 @@ SuffExpandVariables(GNode *parent, GNode *child, Lst *members)
Lst_Init(members);
DEBUGF(SUFF, ("Expanding \"%s\"...", child->name));
buf = Var_Subst(NULL, child->name, parent, TRUE);
buf = Var_Subst(child->name, parent, TRUE);
cp = Buf_Data(buf);
if (child->type & OP_ARCHV) {

View File

@ -222,7 +222,7 @@ VarPossiblyExpand(const char *name, GNode *ctxt)
Buffer *buf;
if (strchr(name, '$') != NULL) {
buf = Var_Subst(NULL, name, ctxt, 0);
buf = Var_Subst(name, ctxt, 0);
return (Buf_Peel(buf));
} else {
return estrdup(name);
@ -882,7 +882,7 @@ VarExpand(Var *v, VarParser *vp)
} else {
Buffer *buf;
buf = Var_Subst(NULL, value, vp->ctxt, vp->err);
buf = Var_Subst(value, vp->ctxt, vp->err);
result = Buf_Peel(buf);
}
@ -1715,9 +1715,9 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err,
*-----------------------------------------------------------------------
*/
Buffer *
Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
Var_Subst(const char *str, GNode *ctxt, Boolean err)
{
Boolean errorReported;
Boolean errorReported;
Buffer *buf; /* Buffer for forming things */
/*
@ -1728,89 +1728,21 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
errorReported = FALSE;
buf = Buf_Init(0);
while (*str) {
if (var == NULL && (str[0] == '$') && (str[1] == '$')) {
while (str[0] != '\0') {
if ((str[0] == '$') && (str[1] == '$')) {
/*
* A dollar sign may be escaped either with another
* dollar sign. In such a case, we skip over the
* escape character and store the dollar sign into
* the buffer directly.
* A dollar sign may be escaped with another dollar
* sign. In such a case, we skip over the escape
* character and store the dollar sign into the
* buffer directly.
*/
str++;
Buf_AddByte(buf, (Byte)str[0]);
str += 2;
str++;
} else if (str[0] == '$') {
/*
* Variable invocation.
*/
if (var != NULL) {
int expand;
for (;;) {
if (str[1] == OPEN_PAREN || str[1] == OPEN_BRACE) {
size_t ln;
const char *p = str + 2;
/*
* Scan up to the end of the
* variable name.
*/
while (*p != '\0' &&
*p != ':' &&
*p != CLOSE_PAREN &&
*p != CLOSE_BRACE &&
*p != '$') {
++p;
}
/*
* A variable inside the
* variable. We cannot expand
* the external variable yet,
* so we try again with the
* nested one
*/
if (*p == '$') {
Buf_AppendRange(buf, str, p);
str = p;
continue;
}
ln = p - (str + 2);
if (var[ln] == '\0' && strncmp(var, str + 2, ln) == 0) {
expand = TRUE;
} else {
/*
* Not the variable
* we want to expand,
* scan until the
* next variable
*/
while (*p != '$' && *p != '\0')
p++;
Buf_AppendRange(buf, str, p);
str = p;
expand = FALSE;
}
} else {
/*
* Single letter variable
* name
*/
if (var[1] == '\0' && var[0] == str[1]) {
expand = TRUE;
} else {
Buf_AddBytes(buf, 2, (const Byte *) str);
str += 2;
expand = FALSE;
}
}
break;
}
if (!expand)
continue;
}
{
VarParser subvp = {
/* Variable invocation. */
VarParser subvp = {
str,
str,
ctxt,
@ -1849,20 +1781,13 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
Parse_Error(PARSE_FATAL,
"Undefined variable \"%.*s\"", subvp.ptr - subvp.input, str);
}
str = subvp.ptr;
errorReported = TRUE;
str = subvp.ptr;
} else {
Buf_AddByte(buf, (Byte)*str);
str += 1;
Buf_AddByte(buf, (Byte)str[0]);
str++;
}
} else {
/*
* We've now got a variable structure to
* store in. But first, advance the string
* pointer.
*/
str = subvp.ptr;
/*
* Copy all the characters from the variable
* value straight into the new string.
@ -1871,68 +1796,155 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
if (rfree) {
free(rval);
}
str = subvp.ptr;
}
}
} else {
/*
* Skip as many characters as possible -- either to
* the end of the string or to the next dollar sign
* (variable invocation).
*/
const char *cp = str;
do {
str++;
} while (str[0] != '$' && str[0] != '\0');
Buf_AppendRange(buf, cp, str);
Buf_AddByte(buf, (Byte)str[0]);
str++;
}
}
return (buf);
}
/*-
*-----------------------------------------------------------------------
* Var_GetTail --
* Return the tail from each of a list of words. Used to set the
* System V local variables.
*
* Results:
* The resulting string.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
char *
Var_GetTail(char *file)
static int
match_var(const char str[], const char var[])
{
const char *start = str;
size_t len;
return (VarModify(file, VarTail, (void *)NULL));
str++; /* consume '$' */
if (str[0] == OPEN_PAREN || str[0] == OPEN_BRACE) {
str++; /* consume opening paren or brace */
while (str[0] != '\0') {
if (str[0] == '$') {
/*
* A variable inside the variable. We cannot
* expand the external variable yet.
*/
return (str - start);
} else if (str[0] == ':' ||
str[0] == CLOSE_PAREN ||
str[0] == CLOSE_BRACE) {
len = str - (start + 2);
if (var[len] == '\0' && strncmp(var, start + 2, len) == 0) {
return (0); /* match */
} else {
/*
* Not the variable we want to
* expand.
*/
return (str - start);
}
} else {
++str;
}
}
return (str - start);
} else {
/* Single letter variable name */
if (var[1] == '\0' && var[0] == str[0]) {
return (0); /* match */
} else {
str++; /* consume variable name */
return (str - start);
}
}
}
/*-
*-----------------------------------------------------------------------
* Var_GetHead --
* Find the leading components of a (list of) filename(s).
* XXX: VarHead does not replace foo by ., as (sun) System V make
* does.
*
* Results:
* The leading components.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
char *
Var_GetHead(char *file)
Buffer *
Var_SubstOnly(const char *var, const char *str, GNode *ctxt, Boolean err)
{
Boolean errorReported;
Buffer *buf; /* Buffer for forming things */
return (VarModify(file, VarHead, (void *)NULL));
/*
* Set TRUE if an error has already been reported to prevent a
* plethora of messages when recursing. XXXHB this comment sounds
* wrong.
*/
errorReported = FALSE;
buf = Buf_Init(0);
while (str[0] != '\0') {
if (str[0] == '$') {
int skip;
skip = match_var(str, var);
if (skip > 0) {
Buf_AddBytes(buf, skip, str);
str += skip;
} else {
/* Variable invocation. */
VarParser subvp = {
str,
str,
ctxt,
err
};
char *rval;
Boolean rfree;
rval = VarParse(&subvp, &rfree);
/*
* When we get down here, rval should either
* point to the value of this variable, or be
* NULL.
*/
if (rval == var_Error || rval == varNoError) {
/*
* If performing old-time variable
* substitution, skip over the
* variable and continue with the
* substitution. Otherwise, store the
* dollar sign and advance str so we
* continue with the string...
*/
if (oldVars) {
str = subvp.ptr;
} else if (err) {
/*
* If variable is undefined,
* complain and skip the
* variable. The complaint
* will stop us from doing
* anything when the file is
* parsed.
*/
if (!errorReported) {
Parse_Error(PARSE_FATAL,
"Undefined variable \"%.*s\"", subvp.ptr - subvp.input, str);
}
errorReported = TRUE;
str = subvp.ptr;
} else {
Buf_AddByte(buf, (Byte)str[0]);
str++;
}
} else {
/*
* Copy all the characters from the
* variable value straight into the
* new string.
*/
Buf_Append(buf, rval);
if (rfree) {
free(rval);
}
str = subvp.ptr;
}
}
} else {
Buf_AddByte(buf, (Byte)str[0]);
str++;
}
}
return (buf);
}
/*-

View File

@ -93,14 +93,13 @@ void Var_Append(const char *, const char *, struct GNode *);
void Var_Delete(const char *, struct GNode *);
void Var_Dump(const struct GNode *);
Boolean Var_Exists(const char *, struct GNode *);
char *Var_GetHead(char *);
char *Var_GetTail(char *);
void Var_Init(char **);
char *Var_Parse(const char *, struct GNode *, Boolean, size_t *, Boolean *);
char *Var_Quote(const char *);
void Var_Set(const char *, const char *, struct GNode *);
void Var_SetEnv(const char *, struct GNode *);
struct Buffer *Var_Subst(const char *, const char *, struct GNode *, Boolean);
struct Buffer *Var_Subst(const char *, struct GNode *, Boolean);
struct Buffer *Var_SubstOnly(const char *, const char *, struct GNode *, Boolean);
char *Var_Value(const char *, struct GNode *, char **);
/*