make(1): return FStr from Var_Parse

This reduces the number of variable declarations at the call sites.
This commit is contained in:
rillig 2020-12-20 13:38:43 +00:00
parent 49eb293fd6
commit 7b3d8cbe3a
6 changed files with 90 additions and 119 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: arch.c,v 1.189 2020/12/18 15:47:34 rillig Exp $ */
/* $NetBSD: arch.c,v 1.190 2020/12/20 13:38:43 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -125,7 +125,7 @@
#include "config.h"
/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: arch.c,v 1.189 2020/12/18 15:47:34 rillig Exp $");
MAKE_RCSID("$NetBSD: arch.c,v 1.190 2020/12/20 13:38:43 rillig Exp $");
typedef struct List ArchList;
typedef struct ListNode ArchListNode;
@ -202,17 +202,15 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
/* Expand nested variable expressions. */
/* XXX: This code can probably be shortened. */
const char *nested_p = cp;
void *result_freeIt;
const char *result;
FStr result;
Boolean isError;
/* XXX: is expanded twice: once here and once below */
(void)Var_Parse(&nested_p, ctxt,
VARE_WANTRES | VARE_UNDEFERR,
&result, &result_freeIt);
VARE_WANTRES | VARE_UNDEFERR, &result);
/* TODO: handle errors */
isError = result == var_Error;
free(result_freeIt);
isError = result.str == var_Error;
FStr_Done(&result);
if (isError)
return FALSE;
@ -246,17 +244,16 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *ctxt)
if (*cp == '$') {
/* Expand nested variable expressions. */
/* XXX: This code can probably be shortened. */
void *freeIt;
const char *result;
FStr result;
Boolean isError;
const char *nested_p = cp;
(void)Var_Parse(&nested_p, ctxt,
VARE_WANTRES | VARE_UNDEFERR,
&result, &freeIt);
&result);
/* TODO: handle errors */
isError = result == var_Error;
free(freeIt);
isError = result.str == var_Error;
FStr_Done(&result);
if (isError)
return FALSE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.228 2020/12/20 13:03:48 rillig Exp $ */
/* $NetBSD: cond.c,v 1.229 2020/12/20 13:38:43 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -94,7 +94,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
MAKE_RCSID("$NetBSD: cond.c,v 1.228 2020/12/20 13:03:48 rillig Exp $");
MAKE_RCSID("$NetBSD: cond.c,v 1.229 2020/12/20 13:38:43 rillig Exp $");
/*
* The parsing of conditional expressions is based on this grammar:
@ -247,16 +247,14 @@ ParseFuncArg(const char **pp, Boolean doEval, const char *func,
* so we don't need to do it. Nor do we return an
* error, though perhaps we should.
*/
void *nestedVal_freeIt;
VarEvalFlags eflags = doEval
? VARE_WANTRES | VARE_UNDEFERR
: VARE_NONE;
const char *nestedVal;
(void)Var_Parse(&p, VAR_CMDLINE, eflags,
&nestedVal, &nestedVal_freeIt);
FStr nestedVal;
(void)Var_Parse(&p, VAR_CMDLINE, eflags, &nestedVal);
/* TODO: handle errors */
Buf_AddStr(&argBuf, nestedVal);
free(nestedVal_freeIt);
Buf_AddStr(&argBuf, nestedVal.str);
FStr_Done(&nestedVal);
continue;
}
if (ch == '(')
@ -451,7 +449,7 @@ CondParser_String(CondParser *par, Boolean doEval, Boolean strictLHS,
nested_p = par->p;
atStart = nested_p == start;
parseResult = Var_Parse(&nested_p, VAR_CMDLINE, eflags,
&str.str, &str.freeIt);
&str);
/* TODO: handle errors */
if (str.str == var_Error) {
if (parseResult & VPR_ANY_MSG)
@ -693,8 +691,7 @@ static size_t
ParseEmptyArg(const char **pp, Boolean doEval,
const char *func MAKE_ATTR_UNUSED, char **out_arg)
{
void *val_freeIt;
const char *val;
FStr val;
size_t magic_res;
/* We do all the work here and return the result as the length */
@ -702,12 +699,12 @@ ParseEmptyArg(const char **pp, Boolean doEval,
(*pp)--; /* Make (*pp)[1] point to the '('. */
(void)Var_Parse(pp, VAR_CMDLINE, doEval ? VARE_WANTRES : VARE_NONE,
&val, &val_freeIt);
&val);
/* TODO: handle errors */
/* If successful, *pp points beyond the closing ')' now. */
if (val == var_Error) {
free(val_freeIt);
if (val.str == var_Error) {
FStr_Done(&val);
return (size_t)-1;
}
@ -715,14 +712,14 @@ ParseEmptyArg(const char **pp, Boolean doEval,
* A variable is empty when it just contains spaces...
* 4/15/92, christos
*/
cpp_skip_whitespace(&val);
cpp_skip_whitespace(&val.str);
/*
* For consistency with the other functions we can't generate the
* true/false here.
*/
magic_res = *val != '\0' ? 2 : 1;
free(val_freeIt);
magic_res = val.str[0] != '\0' ? 2 : 1;
FStr_Done(&val);
return magic_res;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nonints.h,v 1.176 2020/12/20 12:53:34 rillig Exp $ */
/* $NetBSD: nonints.h,v 1.177 2020/12/20 13:38:43 rillig Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@ -404,8 +404,7 @@ void Var_Append(const char *, const char *, GNode *);
Boolean Var_Exists(const char *, GNode *);
const char *Var_Value(const char *, GNode *, void **);
const char *Var_ValueDirect(const char *, GNode *);
VarParseResult Var_Parse(const char **, GNode *, VarEvalFlags,
const char **, void **);
VarParseResult Var_Parse(const char **, GNode *, VarEvalFlags, FStr *);
VarParseResult Var_Subst(const char *, GNode *, VarEvalFlags, char **);
void Var_Stats(void);
void Var_Dump(GNode *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.503 2020/12/19 22:33:11 rillig Exp $ */
/* $NetBSD: parse.c,v 1.504 2020/12/20 13:38:43 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -117,7 +117,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: parse.c,v 1.503 2020/12/19 22:33:11 rillig Exp $");
MAKE_RCSID("$NetBSD: parse.c,v 1.504 2020/12/20 13:38:43 rillig Exp $");
/* types and constants */
@ -1080,14 +1080,13 @@ ParseDependencyTargetWord(const char **pp, const char *lstart)
* we wouldn't be here.
*/
const char *nested_p = cp;
const char *nested_val;
void *freeIt;
FStr nested_val;
/* XXX: Why VARE_WANTRES? */
(void)Var_Parse(&nested_p, VAR_CMDLINE,
VARE_WANTRES | VARE_UNDEFERR, &nested_val, &freeIt);
VARE_WANTRES | VARE_UNDEFERR, &nested_val);
/* TODO: handle errors */
free(freeIt);
FStr_Done(&nested_val);
cp += nested_p - cp;
} else
cp++;

View File

@ -1,4 +1,4 @@
/* $NetBSD: suff.c,v 1.331 2020/12/18 15:47:34 rillig Exp $ */
/* $NetBSD: suff.c,v 1.332 2020/12/20 13:38:43 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -114,7 +114,7 @@
#include "dir.h"
/* "@(#)suff.c 8.4 (Berkeley) 3/21/94" */
MAKE_RCSID("$NetBSD: suff.c,v 1.331 2020/12/18 15:47:34 rillig Exp $");
MAKE_RCSID("$NetBSD: suff.c,v 1.332 2020/12/20 13:38:43 rillig Exp $");
typedef List SuffixList;
typedef ListNode SuffixListNode;
@ -1300,13 +1300,11 @@ ExpandChildrenRegular(char *cp, GNode *pgn, GNodeList *members)
} else if (*cp == '$') {
/* Skip over the variable expression. */
const char *nested_p = cp;
const char *junk;
void *freeIt;
FStr junk;
(void)Var_Parse(&nested_p, pgn,
VARE_NONE, &junk, &freeIt);
(void)Var_Parse(&nested_p, pgn, VARE_NONE, &junk);
/* TODO: handle errors */
if (junk == var_Error) {
if (junk.str == var_Error) {
Parse_Error(PARSE_FATAL,
"Malformed variable expression at \"%s\"",
cp);
@ -1315,7 +1313,7 @@ ExpandChildrenRegular(char *cp, GNode *pgn, GNodeList *members)
cp += nested_p - cp;
}
free(freeIt);
FStr_Done(&junk);
} else if (cp[0] == '\\' && cp[1] != '\0') {
/* Escaped something -- skip over it. */
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.742 2020/12/20 12:53:34 rillig Exp $ */
/* $NetBSD: var.c,v 1.743 2020/12/20 13:38:43 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -131,7 +131,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
MAKE_RCSID("$NetBSD: var.c,v 1.742 2020/12/20 12:53:34 rillig Exp $");
MAKE_RCSID("$NetBSD: var.c,v 1.743 2020/12/20 13:38:43 rillig Exp $");
typedef enum VarFlags {
VAR_NONE = 0,
@ -2044,16 +2044,15 @@ ParseModifierPart(
if (eflags & VARE_WANTRES) { /* Nested variable, evaluated */
const char *nested_p = p;
const char *nested_val;
void *nested_val_freeIt;
FStr nested_val;
VarEvalFlags nested_eflags =
eflags & ~(unsigned)VARE_KEEP_DOLLAR;
(void)Var_Parse(&nested_p, st->ctxt, nested_eflags,
&nested_val, &nested_val_freeIt);
&nested_val);
/* TODO: handle errors */
Buf_AddStr(&buf, nested_val);
free(nested_val_freeIt);
Buf_AddStr(&buf, nested_val.str);
FStr_Done(&nested_val);
p += nested_p - p;
continue;
}
@ -2266,14 +2265,12 @@ ApplyModifier_Defined(const char **pp, ApplyModifiersState *st)
/* Nested variable expression */
if (*p == '$') {
const char *nested_val;
void *nested_val_freeIt;
FStr nested_val;
(void)Var_Parse(&p, st->ctxt, eflags,
&nested_val, &nested_val_freeIt);
(void)Var_Parse(&p, st->ctxt, eflags, &nested_val);
/* TODO: handle errors */
Buf_AddStr(&buf, nested_val);
free(nested_val_freeIt);
Buf_AddStr(&buf, nested_val.str);
FStr_Done(&nested_val);
continue;
}
@ -3430,10 +3427,9 @@ ApplyModifiersIndirect(ApplyModifiersState *st, const char **pp,
void **inout_freeIt)
{
const char *p = *pp;
const char *mods;
void *mods_freeIt;
FStr mods;
(void)Var_Parse(&p, st->ctxt, st->eflags, &mods, &mods_freeIt);
(void)Var_Parse(&p, st->ctxt, st->eflags, &mods);
/* TODO: handle errors */
/*
@ -3441,14 +3437,14 @@ ApplyModifiersIndirect(ApplyModifiersState *st, const char **pp,
* interested. This means the expression ${VAR:${M1}${M2}}
* is not accepted, but ${VAR:${M1}:${M2}} is.
*/
if (mods[0] != '\0' && *p != '\0' && *p != ':' && *p != st->endc) {
if (mods.str[0] != '\0' && *p != '\0' && *p != ':' && *p != st->endc) {
if (opts.lint)
Parse_Error(PARSE_FATAL,
"Missing delimiter ':' "
"after indirect modifier \"%.*s\"",
(int)(p - *pp), *pp);
free(mods_freeIt);
FStr_Done(&mods);
/* XXX: apply_mods doesn't sound like "not interested". */
/* XXX: Why is the indirect modifier parsed once more by
* apply_mods? Try *pp = p here. */
@ -3456,20 +3452,21 @@ ApplyModifiersIndirect(ApplyModifiersState *st, const char **pp,
}
DEBUG3(VAR, "Indirect modifier \"%s\" from \"%.*s\"\n",
mods, (int)(p - *pp), *pp);
mods.str, (int)(p - *pp), *pp);
if (mods[0] != '\0') {
st->val = ApplyModifiers(&mods, st->val, '\0', '\0',
if (mods.str[0] != '\0') {
const char *modsp = mods.str;
st->val = ApplyModifiers(&modsp, st->val, '\0', '\0',
st->var, &st->exprFlags, st->ctxt, st->eflags,
inout_freeIt);
if (st->val == var_Error || st->val == varUndefined ||
*mods != '\0') {
free(mods_freeIt);
*modsp != '\0') {
FStr_Done(&mods);
*pp = p;
return AMIR_OUT; /* error already reported */
}
}
free(mods_freeIt);
FStr_Done(&mods);
if (*p == ':')
p++;
@ -3694,13 +3691,11 @@ ParseVarname(const char **pp, char startc, char endc,
/* A variable inside a variable, expand. */
if (*p == '$') {
const char *nested_val;
void *nested_val_freeIt;
(void)Var_Parse(&p, ctxt, eflags, &nested_val,
&nested_val_freeIt);
FStr nested_val;
(void)Var_Parse(&p, ctxt, eflags, &nested_val);
/* TODO: handle errors */
Buf_AddStr(&buf, nested_val);
free(nested_val_freeIt);
Buf_AddStr(&buf, nested_val.str);
FStr_Done(&nested_val);
} else {
Buf_AddByte(&buf, *p);
p++;
@ -4005,8 +4000,7 @@ FreeEnvVar(void **out_val_freeIt, Var *v, const char *value)
*/
/* coverity[+alloc : arg-*4] */
VarParseResult
Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
const char **out_val, void **out_val_freeIt)
Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags, FStr *out_val)
{
const char *p = *pp;
const char *const start = p;
@ -4024,7 +4018,7 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
Boolean dynamic;
const char *extramodifiers;
Var *v;
char *value;
MFStr value;
char eflags_str[VarEvalFlags_ToStringSize];
VarExprFlags exprFlags = VEF_NONE;
@ -4032,7 +4026,7 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
Enum_FlagsToString(eflags_str, sizeof eflags_str, eflags,
VarEvalFlags_ToStringSpecs));
*out_val_freeIt = NULL;
*out_val = FStr_InitRefer(NULL);
extramodifiers = NULL; /* extra modifiers to apply first */
dynamic = FALSE;
@ -4046,21 +4040,17 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
if (startc != '(' && startc != '{') {
VarParseResult res;
if (!ParseVarnameShort(startc, pp, ctxt, eflags, &res,
out_val, &v))
&out_val->str, &v))
return res;
haveModifier = FALSE;
p++;
} else {
VarParseResult res;
FStr fval;
if (!ParseVarnameLong(p, startc, ctxt, eflags,
pp, &res, &fval,
pp, &res, out_val,
&endc, &p, &v, &haveModifier, &extramodifiers,
&dynamic, &exprFlags)) {
*out_val = fval.str;
*out_val_freeIt = fval.freeIt;
&dynamic, &exprFlags))
return res;
}
}
if (v->flags & VAR_IN_USE)
@ -4075,21 +4065,22 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
* the then-current value of the variable. This might also invoke
* undefined behavior.
*/
value = Buf_GetAll(&v->val, NULL);
value = MFStr_InitRefer(Buf_GetAll(&v->val, NULL));
/*
* Before applying any modifiers, expand any nested expressions from
* the variable value.
*/
if (strchr(value, '$') != NULL && (eflags & VARE_WANTRES)) {
if (strchr(value.str, '$') != NULL && (eflags & VARE_WANTRES)) {
char *expanded;
VarEvalFlags nested_eflags = eflags;
if (opts.lint)
nested_eflags &= ~(unsigned)VARE_UNDEFERR;
v->flags |= VAR_IN_USE;
(void)Var_Subst(value, ctxt, nested_eflags, &value);
(void)Var_Subst(value.str, ctxt, nested_eflags, &expanded);
v->flags &= ~(unsigned)VAR_IN_USE;
/* TODO: handle errors */
*out_val_freeIt = value;
value = MFStr_InitOwn(expanded);
}
if (haveModifier || extramodifiers != NULL) {
@ -4098,7 +4089,7 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
extraFree = NULL;
if (extramodifiers != NULL) {
const char *em = extramodifiers;
value = ApplyModifiers(&em, value, '\0', '\0',
value.str = ApplyModifiers(&em, value.str, '\0', '\0',
v, &exprFlags, ctxt, eflags, &extraFree);
}
@ -4106,11 +4097,11 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
/* Skip initial colon. */
p++;
value = ApplyModifiers(&p, value, startc, endc,
v, &exprFlags, ctxt, eflags, out_val_freeIt);
value.str = ApplyModifiers(&p, value.str, startc, endc,
v, &exprFlags, ctxt, eflags, &value.freeIt);
free(extraFree);
} else {
*out_val_freeIt = extraFree;
value.freeIt = extraFree;
}
}
@ -4120,38 +4111,29 @@ Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
*pp = p;
if (v->flags & VAR_FROM_ENV) {
FreeEnvVar(out_val_freeIt, v, value);
FreeEnvVar(&value.freeIt, v, value.str);
} else if (exprFlags & VEF_UNDEF) {
if (!(exprFlags & VEF_DEF)) {
/*
* TODO: Use a local variable instead of
* out_val_freeIt. Variables named out_* must only
* be written to.
*/
if (*out_val_freeIt != NULL) {
free(*out_val_freeIt);
*out_val_freeIt = NULL;
}
MFStr_Done(&value);
if (dynamic) {
value = bmake_strsedup(start, p);
*out_val_freeIt = value;
value = MFStr_InitOwn(bmake_strsedup(start, p));
} else {
/*
* The expression is still undefined,
* therefore discard the actual value and
* return an error marker instead.
*/
value = eflags & VARE_UNDEFERR
? var_Error : varUndefined;
value = MFStr_InitRefer(eflags & VARE_UNDEFERR
? var_Error : varUndefined);
}
}
if (value != Buf_GetAll(&v->val, NULL))
if (value.str != Buf_GetAll(&v->val, NULL))
Buf_Destroy(&v->val, TRUE);
FStr_Done(&v->name);
free(v);
}
*out_val = value;
*out_val = (FStr){ value.str, value.freeIt };
return VPR_UNKNOWN;
}
@ -4161,16 +4143,15 @@ VarSubstNested(const char **pp, Buffer *buf, GNode *ctxt,
{
const char *p = *pp;
const char *nested_p = p;
const char *val;
void *val_freeIt;
FStr val;
(void)Var_Parse(&nested_p, ctxt, eflags, &val, &val_freeIt);
(void)Var_Parse(&nested_p, ctxt, eflags, &val);
/* TODO: handle errors */
if (val == var_Error || val == varUndefined) {
if (val.str == var_Error || val.str == varUndefined) {
if (!preserveUndefined) {
p = nested_p;
} else if ((eflags & VARE_UNDEFERR) || val == var_Error) {
} else if ((eflags & VARE_UNDEFERR) || val.str == var_Error) {
/*
* XXX: This condition is wrong. If val == var_Error,
@ -4201,10 +4182,10 @@ VarSubstNested(const char **pp, Buffer *buf, GNode *ctxt,
}
} else {
p = nested_p;
Buf_AddStr(buf, val);
Buf_AddStr(buf, val.str);
}
free(val_freeIt);
FStr_Done(&val);
*pp = p;
}