Module Name: src
Committed By: rillig
Date: Mon Mar 15 20:00:51 UTC 2021
Modified Files:
src/usr.bin/make: var.c
src/usr.bin/make/unit-tests: varmod-indirect.mk
Log Message:
make: rename ApplyModifiersState to ModChain
The new name accurately describes the structural element that holds such
properties as the separator character and whether the expression value
is considered a single word. The old name ApplyModifiersState was too
long and was meant as a placeholder anyway, when I introduced it in
var.c 1.236 from 2020-07-03.
To generate a diff of this commit:
cvs rdiff -u -r1.890 -r1.891 src/usr.bin/make/var.c
cvs rdiff -u -r1.8 -r1.9 src/usr.bin/make/unit-tests/varmod-indirect.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.890 src/usr.bin/make/var.c:1.891
--- src/usr.bin/make/var.c:1.890 Mon Mar 15 19:15:04 2021
+++ src/usr.bin/make/var.c Mon Mar 15 20:00:50 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.890 2021/03/15 19:15:04 rillig Exp $ */
+/* $NetBSD: var.c,v 1.891 2021/03/15 20:00:50 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.890 2021/03/15 19:15:04 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.891 2021/03/15 20:00:50 rillig Exp $");
typedef enum VarFlags {
VFL_NONE = 0,
@@ -1831,7 +1831,7 @@ Words_JoinFree(Words words)
for (i = 0; i < words.len; i++) {
if (i != 0) {
- /* XXX: Use st->sep instead of ' ', for consistency. */
+ /* XXX: Use ch->sep instead of ' ', for consistency. */
Buf_AddByte(&buf, ' ');
}
Buf_AddStr(&buf, words.words[i]);
@@ -1978,7 +1978,7 @@ VarStrftime(const char *fmt, Boolean zul
*
* If parsing succeeds, the parsing position *pp is updated to point to the
* first character following the modifier, which typically is either ':' or
- * st->endc. The modifier doesn't have to check for this delimiter character,
+ * ch->endc. The modifier doesn't have to check for this delimiter character,
* this is done by ApplyModifiers.
*
* XXX: As of 2020-11-15, some modifiers such as :S, :C, :P, :L do not
@@ -2012,7 +2012,7 @@ VarStrftime(const char *fmt, Boolean zul
* Some modifiers such as ':sh' or '::=' have noticeable side effects though.
*
* Evaluating the modifier usually takes the current value of the variable
- * expression from st->expr->value, or the variable name from st->var->name
+ * expression from ch->expr->value, or the variable name from ch->var->name
* and stores the result back in expr->value via Expr_SetValueOwn or
* Expr_SetValueRefer.
*
@@ -2079,7 +2079,7 @@ typedef struct Expr {
*
* See varmod-indirect.mk.
*/
-typedef struct ApplyModifiersState {
+typedef struct ModChain {
Expr *expr;
/* '\0' or '{' or '(' */
const char startc;
@@ -2093,7 +2093,7 @@ typedef struct ApplyModifiersState {
* big word, possibly containing spaces.
*/
Boolean oneBigWord;
-} ApplyModifiersState;
+} ModChain;
static void
Expr_Define(Expr *expr)
@@ -2148,7 +2148,7 @@ ParseModifierPartSubst(
const char **pp,
char delim,
VarEvalFlags eflags,
- ApplyModifiersState *st,
+ ModChain *ch,
char **out_part,
/* Optionally stores the length of the returned string, just to save
* another strlen call. */
@@ -2204,7 +2204,7 @@ ParseModifierPartSubst(
VarEvalFlags nested_eflags = eflags;
nested_eflags.keepDollar = FALSE;
- (void)Var_Parse(&nested_p, st->expr->scope,
+ (void)Var_Parse(&nested_p, ch->expr->scope,
nested_eflags, &nested_val);
/* TODO: handle errors */
Buf_AddStr(&buf, nested_val.str);
@@ -2255,7 +2255,7 @@ ParseModifierPartSubst(
if (*p != delim) {
*pp = p;
Error("Unfinished modifier for \"%s\" ('%c' missing)",
- st->expr->var->name.str, delim);
+ ch->expr->var->name.str, delim);
*out_part = NULL;
return VPR_ERR;
}
@@ -2288,35 +2288,35 @@ ParseModifierPart(
char delim,
/* Flags for evaluating nested variables. */
VarEvalFlags eflags,
- ApplyModifiersState *st,
+ ModChain *ch,
char **out_part
)
{
- return ParseModifierPartSubst(pp, delim, eflags, st, out_part,
+ return ParseModifierPartSubst(pp, delim, eflags, ch, out_part,
NULL, NULL, NULL);
}
MAKE_INLINE Boolean
-IsDelimiter(char ch, const ApplyModifiersState *st)
+IsDelimiter(char c, const ModChain *ch)
{
- return ch == ':' || ch == st->endc;
+ return c == ':' || c == ch->endc;
}
/* Test whether mod starts with modname, followed by a delimiter. */
MAKE_INLINE Boolean
-ModMatch(const char *mod, const char *modname, const ApplyModifiersState *st)
+ModMatch(const char *mod, const char *modname, const ModChain *ch)
{
size_t n = strlen(modname);
- return strncmp(mod, modname, n) == 0 && IsDelimiter(mod[n], st);
+ return strncmp(mod, modname, n) == 0 && IsDelimiter(mod[n], ch);
}
/* Test whether mod starts with modname, followed by a delimiter or '='. */
MAKE_INLINE Boolean
-ModMatchEq(const char *mod, const char *modname, const ApplyModifiersState *st)
+ModMatchEq(const char *mod, const char *modname, const ModChain *ch)
{
size_t n = strlen(modname);
return strncmp(mod, modname, n) == 0 &&
- (IsDelimiter(mod[n], st) || mod[n] == '=');
+ (IsDelimiter(mod[n], ch) || mod[n] == '=');
}
static Boolean
@@ -2387,18 +2387,18 @@ TryParseChar(const char **pp, int base,
* result back in the expression.
*/
static void
-ModifyWords(ApplyModifiersState *st,
+ModifyWords(ModChain *ch,
ModifyWordProc modifyWord, void *modifyWord_args,
Boolean oneBigWord)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
const char *val = expr->value.str;
SepBuf result;
Words words;
size_t i;
if (oneBigWord) {
- SepBuf_Init(&result, st->sep);
+ SepBuf_Init(&result, ch->sep);
modifyWord(val, &result, modifyWord_args);
goto done;
}
@@ -2408,7 +2408,7 @@ ModifyWords(ApplyModifiersState *st,
DEBUG2(VAR, "ModifyWords: split \"%s\" into %u words\n",
val, (unsigned)words.len);
- SepBuf_Init(&result, st->sep);
+ SepBuf_Init(&result, ch->sep);
for (i = 0; i < words.len; i++) {
modifyWord(words.words[i], &result, modifyWord_args);
if (result.buf.len > 0)
@@ -2423,9 +2423,9 @@ done:
/* :@var@...${var}...@ */
static ApplyModifierResult
-ApplyModifier_Loop(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Loop(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
struct ModifyWord_LoopArgs args;
char prev_sep;
VarParseResult res;
@@ -2433,7 +2433,7 @@ ApplyModifier_Loop(const char **pp, Appl
args.scope = expr->scope;
(*pp)++; /* Skip the first '@' */
- res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, st, &args.tvar);
+ res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &args.tvar);
if (res != VPR_OK)
return AMR_CLEANUP;
if (opts.strict && strchr(args.tvar, '$') != NULL) {
@@ -2444,7 +2444,7 @@ ApplyModifier_Loop(const char **pp, Appl
return AMR_CLEANUP;
}
- res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, st, &args.str);
+ res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &args.str);
if (res != VPR_OK)
return AMR_CLEANUP;
@@ -2453,10 +2453,10 @@ ApplyModifier_Loop(const char **pp, Appl
args.eflags = expr->eflags;
args.eflags.keepDollar = FALSE;
- prev_sep = st->sep;
- st->sep = ' '; /* XXX: should be st->sep for consistency */
- ModifyWords(st, ModifyWord_Loop, &args, st->oneBigWord);
- st->sep = prev_sep;
+ prev_sep = ch->sep;
+ ch->sep = ' '; /* XXX: should be ch->sep for consistency */
+ ModifyWords(ch, ModifyWord_Loop, &args, ch->oneBigWord);
+ ch->sep = prev_sep;
/* XXX: Consider restoring the previous variable instead of deleting. */
/*
* XXX: The variable name should not be expanded here, see
@@ -2472,9 +2472,9 @@ done:
/* :Ddefined or :Uundefined */
static ApplyModifierResult
-ApplyModifier_Defined(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Defined(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
Buffer buf;
const char *p;
@@ -2485,7 +2485,7 @@ ApplyModifier_Defined(const char **pp, A
Buf_Init(&buf);
p = *pp + 1;
- while (!IsDelimiter(*p, st) && *p != '\0') {
+ while (!IsDelimiter(*p, ch) && *p != '\0') {
/* XXX: This code is similar to the one in Var_Parse.
* See if the code can be merged.
@@ -2495,7 +2495,7 @@ ApplyModifier_Defined(const char **pp, A
/* See Buf_AddEscaped in for.c. */
if (*p == '\\') {
char c = p[1];
- if (IsDelimiter(c, st) || c == '$' || c == '\\') {
+ if (IsDelimiter(c, ch) || c == '$' || c == '\\') {
Buf_AddByte(&buf, c);
p += 2;
continue;
@@ -2532,9 +2532,9 @@ ApplyModifier_Defined(const char **pp, A
/* :L */
static ApplyModifierResult
-ApplyModifier_Literal(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Literal(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
(*pp)++;
@@ -2567,12 +2567,12 @@ TryParseTime(const char **pp, time_t *ou
/* :gmtime */
static ApplyModifierResult
-ApplyModifier_Gmtime(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Gmtime(const char **pp, ModChain *ch)
{
time_t utc;
const char *mod = *pp;
- if (!ModMatchEq(mod, "gmtime", st))
+ if (!ModMatchEq(mod, "gmtime", ch))
return AMR_UNKNOWN;
if (mod[6] == '=') {
@@ -2588,21 +2588,21 @@ ApplyModifier_Gmtime(const char **pp, Ap
*pp = mod + 6;
}
- if (st->expr->eflags.wantRes)
- Expr_SetValueOwn(st->expr,
- VarStrftime(st->expr->value.str, TRUE, utc));
+ if (ch->expr->eflags.wantRes)
+ Expr_SetValueOwn(ch->expr,
+ VarStrftime(ch->expr->value.str, TRUE, utc));
return AMR_OK;
}
/* :localtime */
static ApplyModifierResult
-ApplyModifier_Localtime(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Localtime(const char **pp, ModChain *ch)
{
time_t utc;
const char *mod = *pp;
- if (!ModMatchEq(mod, "localtime", st))
+ if (!ModMatchEq(mod, "localtime", ch))
return AMR_UNKNOWN;
if (mod[9] == '=') {
@@ -2618,38 +2618,38 @@ ApplyModifier_Localtime(const char **pp,
*pp = mod + 9;
}
- if (st->expr->eflags.wantRes)
- Expr_SetValueOwn(st->expr,
- VarStrftime(st->expr->value.str, FALSE, utc));
+ if (ch->expr->eflags.wantRes)
+ Expr_SetValueOwn(ch->expr,
+ VarStrftime(ch->expr->value.str, FALSE, utc));
return AMR_OK;
}
/* :hash */
static ApplyModifierResult
-ApplyModifier_Hash(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Hash(const char **pp, ModChain *ch)
{
- if (!ModMatch(*pp, "hash", st))
+ if (!ModMatch(*pp, "hash", ch))
return AMR_UNKNOWN;
*pp += 4;
- if (st->expr->eflags.wantRes)
- Expr_SetValueOwn(st->expr, VarHash(st->expr->value.str));
+ if (ch->expr->eflags.wantRes)
+ Expr_SetValueOwn(ch->expr, VarHash(ch->expr->value.str));
return AMR_OK;
}
/* :P */
static ApplyModifierResult
-ApplyModifier_Path(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Path(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
GNode *gn;
char *path;
(*pp)++;
- if (!st->expr->eflags.wantRes)
+ if (!ch->expr->eflags.wantRes)
return AMR_OK;
Expr_Define(expr);
@@ -2672,15 +2672,15 @@ ApplyModifier_Path(const char **pp, Appl
/* :!cmd! */
static ApplyModifierResult
-ApplyModifier_ShellCommand(const char **pp, ApplyModifiersState *st)
+ApplyModifier_ShellCommand(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
char *cmd;
const char *errfmt;
VarParseResult res;
(*pp)++;
- res = ParseModifierPart(pp, '!', expr->eflags, st, &cmd);
+ res = ParseModifierPart(pp, '!', expr->eflags, ch, &cmd);
if (res != VPR_OK)
return AMR_CLEANUP;
@@ -2702,14 +2702,14 @@ ApplyModifier_ShellCommand(const char **
* The :range=7 modifier generates an integer sequence from 1 to 7.
*/
static ApplyModifierResult
-ApplyModifier_Range(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Range(const char **pp, ModChain *ch)
{
size_t n;
Buffer buf;
size_t i;
const char *mod = *pp;
- if (!ModMatchEq(mod, "range", st))
+ if (!ModMatchEq(mod, "range", ch))
return AMR_UNKNOWN;
if (mod[5] == '=') {
@@ -2726,11 +2726,11 @@ ApplyModifier_Range(const char **pp, App
*pp = mod + 5;
}
- if (!st->expr->eflags.wantRes)
+ if (!ch->expr->eflags.wantRes)
return AMR_OK;
if (n == 0) {
- Words words = Str_Words(st->expr->value.str, FALSE);
+ Words words = Str_Words(ch->expr->value.str, FALSE);
n = words.len;
Words_Free(words);
}
@@ -2739,23 +2739,23 @@ ApplyModifier_Range(const char **pp, App
for (i = 0; i < n; i++) {
if (i != 0) {
- /* XXX: Use st->sep instead of ' ', for consistency. */
+ /* XXX: Use ch->sep instead of ' ', for consistency. */
Buf_AddByte(&buf, ' ');
}
Buf_AddInt(&buf, 1 + (int)i);
}
- Expr_SetValueOwn(st->expr, Buf_DoneData(&buf));
+ Expr_SetValueOwn(ch->expr, Buf_DoneData(&buf));
return AMR_OK;
}
/* Parse a ':M' or ':N' modifier. */
static void
-ParseModifier_Match(const char **pp, const ApplyModifiersState *st,
+ParseModifier_Match(const char **pp, const ModChain *ch,
char **out_pattern)
{
const char *mod = *pp;
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
Boolean copy = FALSE; /* pattern should be, or has been, copied */
Boolean needSubst = FALSE;
const char *endpat;
@@ -2775,7 +2775,7 @@ ParseModifier_Match(const char **pp, con
const char *p;
for (p = mod + 1; *p != '\0' && !(*p == ':' && nest == 0); p++) {
if (*p == '\\' &&
- (IsDelimiter(p[1], st) || p[1] == st->startc)) {
+ (IsDelimiter(p[1], ch) || p[1] == ch->startc)) {
if (!needSubst)
copy = TRUE;
p++;
@@ -2804,8 +2804,8 @@ ParseModifier_Match(const char **pp, con
src = mod + 1;
for (; src < endpat; src++, dst++) {
if (src[0] == '\\' && src + 1 < endpat &&
- /* XXX: st->startc is missing here; see above */
- IsDelimiter(src[1], st))
+ /* XXX: ch->startc is missing here; see above */
+ IsDelimiter(src[1], ch))
src++;
*dst = *src;
}
@@ -2829,17 +2829,17 @@ ParseModifier_Match(const char **pp, con
/* :Mpattern or :Npattern */
static ApplyModifierResult
-ApplyModifier_Match(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Match(const char **pp, ModChain *ch)
{
const char mod = **pp;
char *pattern;
- ParseModifier_Match(pp, st, &pattern);
+ ParseModifier_Match(pp, ch, &pattern);
- if (st->expr->eflags.wantRes) {
+ if (ch->expr->eflags.wantRes) {
ModifyWordProc modifyWord =
mod == 'M' ? ModifyWord_Match : ModifyWord_NoMatch;
- ModifyWords(st, modifyWord, pattern, st->oneBigWord);
+ ModifyWords(ch, modifyWord, pattern, ch->oneBigWord);
}
free(pattern);
@@ -2863,7 +2863,7 @@ ParsePatternFlags(const char **pp, VarPa
/* :S,from,to, */
static ApplyModifierResult
-ApplyModifier_Subst(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Subst(const char **pp, ModChain *ch)
{
struct ModifyWord_SubstArgs args;
char *lhs, *rhs;
@@ -2887,22 +2887,22 @@ ApplyModifier_Subst(const char **pp, App
(*pp)++;
}
- res = ParseModifierPartSubst(pp, delim, st->expr->eflags, st, &lhs,
+ res = ParseModifierPartSubst(pp, delim, ch->expr->eflags, ch, &lhs,
&args.lhsLen, &args.pflags, NULL);
if (res != VPR_OK)
return AMR_CLEANUP;
args.lhs = lhs;
- res = ParseModifierPartSubst(pp, delim, st->expr->eflags, st, &rhs,
+ res = ParseModifierPartSubst(pp, delim, ch->expr->eflags, ch, &rhs,
&args.rhsLen, NULL, &args);
if (res != VPR_OK)
return AMR_CLEANUP;
args.rhs = rhs;
- oneBigWord = st->oneBigWord;
+ oneBigWord = ch->oneBigWord;
ParsePatternFlags(pp, &args.pflags, &oneBigWord);
- ModifyWords(st, ModifyWord_Subst, &args, oneBigWord);
+ ModifyWords(ch, ModifyWord_Subst, &args, oneBigWord);
free(lhs);
free(rhs);
@@ -2913,7 +2913,7 @@ ApplyModifier_Subst(const char **pp, App
/* :C,from,to, */
static ApplyModifierResult
-ApplyModifier_Regex(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Regex(const char **pp, ModChain *ch)
{
char *re;
struct ModifyWord_SubstRegexArgs args;
@@ -2930,11 +2930,11 @@ ApplyModifier_Regex(const char **pp, App
*pp += 2;
- res = ParseModifierPart(pp, delim, st->expr->eflags, st, &re);
+ res = ParseModifierPart(pp, delim, ch->expr->eflags, ch, &re);
if (res != VPR_OK)
return AMR_CLEANUP;
- res = ParseModifierPart(pp, delim, st->expr->eflags, st, &args.replace);
+ res = ParseModifierPart(pp, delim, ch->expr->eflags, ch, &args.replace);
if (args.replace == NULL) {
free(re);
return AMR_CLEANUP;
@@ -2942,10 +2942,10 @@ ApplyModifier_Regex(const char **pp, App
args.pflags = (VarPatternFlags){ FALSE, FALSE, FALSE, FALSE };
args.matched = FALSE;
- oneBigWord = st->oneBigWord;
+ oneBigWord = ch->oneBigWord;
ParsePatternFlags(pp, &args.pflags, &oneBigWord);
- if (!(st->expr->eflags.wantRes)) {
+ if (!(ch->expr->eflags.wantRes)) {
free(args.replace);
free(re);
return AMR_OK;
@@ -2963,7 +2963,7 @@ ApplyModifier_Regex(const char **pp, App
if (args.nsub > 10)
args.nsub = 10;
- ModifyWords(st, ModifyWord_SubstRegex, &args, oneBigWord);
+ ModifyWords(ch, ModifyWord_SubstRegex, &args, oneBigWord);
regfree(&args.re);
free(args.replace);
@@ -2974,16 +2974,16 @@ ApplyModifier_Regex(const char **pp, App
/* :Q, :q */
static ApplyModifierResult
-ApplyModifier_Quote(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Quote(const char **pp, ModChain *ch)
{
Boolean quoteDollar = **pp == 'q';
- if (!IsDelimiter((*pp)[1], st))
+ if (!IsDelimiter((*pp)[1], ch))
return AMR_UNKNOWN;
(*pp)++;
- if (st->expr->eflags.wantRes)
- Expr_SetValueOwn(st->expr,
- VarQuote(st->expr->value.str, quoteDollar));
+ if (ch->expr->eflags.wantRes)
+ Expr_SetValueOwn(ch->expr,
+ VarQuote(ch->expr->value.str, quoteDollar));
return AMR_OK;
}
@@ -2997,7 +2997,7 @@ ModifyWord_Copy(const char *word, SepBuf
/* :ts<separator> */
static ApplyModifierResult
-ApplyModifier_ToSep(const char **pp, ApplyModifiersState *st)
+ApplyModifier_ToSep(const char **pp, ModChain *ch)
{
const char *sep = *pp + 2;
@@ -3009,16 +3009,16 @@ ApplyModifier_ToSep(const char **pp, App
*/
/* ":ts<any><endc>" or ":ts<any>:" */
- if (sep[0] != st->endc && IsDelimiter(sep[1], st)) {
+ if (sep[0] != ch->endc && IsDelimiter(sep[1], ch)) {
*pp = sep + 1;
- st->sep = sep[0];
+ ch->sep = sep[0];
goto ok;
}
/* ":ts<endc>" or ":ts:" */
- if (IsDelimiter(sep[0], st)) {
+ if (IsDelimiter(sep[0], ch)) {
*pp = sep;
- st->sep = '\0'; /* no separator */
+ ch->sep = '\0'; /* no separator */
goto ok;
}
@@ -3031,14 +3031,14 @@ ApplyModifier_ToSep(const char **pp, App
/* ":ts\n" */
if (sep[1] == 'n') {
*pp = sep + 2;
- st->sep = '\n';
+ ch->sep = '\n';
goto ok;
}
/* ":ts\t" */
if (sep[1] == 't') {
*pp = sep + 2;
- st->sep = '\t';
+ ch->sep = '\t';
goto ok;
}
@@ -3055,12 +3055,12 @@ ApplyModifier_ToSep(const char **pp, App
return AMR_BAD; /* ":ts<backslash><unrecognised>". */
}
- if (!TryParseChar(&p, base, &st->sep)) {
+ if (!TryParseChar(&p, base, &ch->sep)) {
Parse_Error(PARSE_FATAL,
"Invalid character number: %s", p);
return AMR_CLEANUP;
}
- if (!IsDelimiter(*p, st)) {
+ if (!IsDelimiter(*p, ch)) {
(*pp)++; /* just for backwards compatibility */
return AMR_BAD;
}
@@ -3069,7 +3069,7 @@ ApplyModifier_ToSep(const char **pp, App
}
ok:
- ModifyWords(st, ModifyWord_Copy, NULL, st->oneBigWord);
+ ModifyWords(ch, ModifyWord_Copy, NULL, ch->oneBigWord);
return AMR_OK;
}
@@ -3103,48 +3103,48 @@ str_tolower(const char *str)
/* :tA, :tu, :tl, :ts<separator>, etc. */
static ApplyModifierResult
-ApplyModifier_To(const char **pp, ApplyModifiersState *st)
+ApplyModifier_To(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
const char *mod = *pp;
assert(mod[0] == 't');
- if (IsDelimiter(mod[1], st) || mod[1] == '\0') {
+ if (IsDelimiter(mod[1], ch) || mod[1] == '\0') {
*pp = mod + 1;
return AMR_BAD; /* Found ":t<endc>" or ":t:". */
}
if (mod[1] == 's')
- return ApplyModifier_ToSep(pp, st);
+ return ApplyModifier_ToSep(pp, ch);
- if (!IsDelimiter(mod[2], st)) { /* :t<unrecognized> */
+ if (!IsDelimiter(mod[2], ch)) { /* :t<unrecognized> */
*pp = mod + 1;
return AMR_BAD;
}
if (mod[1] == 'A') { /* :tA */
*pp = mod + 2;
- ModifyWords(st, ModifyWord_Realpath, NULL, st->oneBigWord);
+ ModifyWords(ch, ModifyWord_Realpath, NULL, ch->oneBigWord);
return AMR_OK;
}
if (mod[1] == 'u') { /* :tu */
*pp = mod + 2;
- if (st->expr->eflags.wantRes)
+ if (ch->expr->eflags.wantRes)
Expr_SetValueOwn(expr, str_toupper(expr->value.str));
return AMR_OK;
}
if (mod[1] == 'l') { /* :tl */
*pp = mod + 2;
- if (st->expr->eflags.wantRes)
+ if (ch->expr->eflags.wantRes)
Expr_SetValueOwn(expr, str_tolower(expr->value.str));
return AMR_OK;
}
if (mod[1] == 'W' || mod[1] == 'w') { /* :tW, :tw */
*pp = mod + 2;
- st->oneBigWord = mod[1] == 'W';
+ ch->oneBigWord = mod[1] == 'W';
return AMR_OK;
}
@@ -3155,20 +3155,20 @@ ApplyModifier_To(const char **pp, ApplyM
/* :[#], :[1], :[-1..1], etc. */
static ApplyModifierResult
-ApplyModifier_Words(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Words(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
char *estr;
int first, last;
VarParseResult res;
const char *p;
(*pp)++; /* skip the '[' */
- res = ParseModifierPart(pp, ']', expr->eflags, st, &estr);
+ res = ParseModifierPart(pp, ']', expr->eflags, ch, &estr);
if (res != VPR_OK)
return AMR_CLEANUP;
- if (!IsDelimiter(**pp, st))
+ if (!IsDelimiter(**pp, ch))
goto bad_modifier; /* Found junk after ']' */
if (!(expr->eflags.wantRes))
@@ -3178,7 +3178,7 @@ ApplyModifier_Words(const char **pp, App
goto bad_modifier; /* Found ":[]". */
if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */
- if (st->oneBigWord) {
+ if (ch->oneBigWord) {
Expr_SetValueRefer(expr, "1");
} else {
Buffer buf;
@@ -3196,12 +3196,12 @@ ApplyModifier_Words(const char **pp, App
}
if (estr[0] == '*' && estr[1] == '\0') { /* Found ":[*]" */
- st->oneBigWord = TRUE;
+ ch->oneBigWord = TRUE;
goto ok;
}
if (estr[0] == '@' && estr[1] == '\0') { /* Found ":[@]" */
- st->oneBigWord = FALSE;
+ ch->oneBigWord = FALSE;
goto ok;
}
@@ -3229,7 +3229,7 @@ ApplyModifier_Words(const char **pp, App
*/
if (first == 0 && last == 0) {
/* ":[0]" or perhaps ":[0..0]" */
- st->oneBigWord = TRUE;
+ ch->oneBigWord = TRUE;
goto ok;
}
@@ -3240,7 +3240,7 @@ ApplyModifier_Words(const char **pp, App
/* Normal case: select the words described by first and last. */
Expr_SetValueOwn(expr,
VarSelectWords(expr->value.str, first, last,
- st->sep, st->oneBigWord));
+ ch->sep, ch->oneBigWord));
ok:
free(estr);
@@ -3278,7 +3278,7 @@ ShuffleStrings(char **strs, size_t n)
/* :O (order ascending) or :Or (order descending) or :Ox (shuffle) */
static ApplyModifierResult
-ApplyModifier_Order(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Order(const char **pp, ModChain *ch)
{
const char *mod = (*pp)++; /* skip past the 'O' in any case */
Words words;
@@ -3286,34 +3286,34 @@ ApplyModifier_Order(const char **pp, App
ASC, DESC, SHUFFLE
} mode;
- if (IsDelimiter(mod[1], st)) {
+ if (IsDelimiter(mod[1], ch)) {
mode = ASC;
} else if ((mod[1] == 'r' || mod[1] == 'x') &&
- IsDelimiter(mod[2], st)) {
+ IsDelimiter(mod[2], ch)) {
(*pp)++;
mode = mod[1] == 'r' ? DESC : SHUFFLE;
} else
return AMR_BAD;
- if (!st->expr->eflags.wantRes)
+ if (!ch->expr->eflags.wantRes)
return AMR_OK;
- words = Str_Words(st->expr->value.str, FALSE);
+ words = Str_Words(ch->expr->value.str, FALSE);
if (mode == SHUFFLE)
ShuffleStrings(words.words, words.len);
else
qsort(words.words, words.len, sizeof words.words[0],
mode == ASC ? str_cmp_asc : str_cmp_desc);
- Expr_SetValueOwn(st->expr, Words_JoinFree(words));
+ Expr_SetValueOwn(ch->expr, Words_JoinFree(words));
return AMR_OK;
}
/* :? then : else */
static ApplyModifierResult
-ApplyModifier_IfElse(const char **pp, ApplyModifiersState *st)
+ApplyModifier_IfElse(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
char *then_expr, *else_expr;
VarParseResult res;
@@ -3331,15 +3331,15 @@ ApplyModifier_IfElse(const char **pp, Ap
}
(*pp)++; /* skip past the '?' */
- res = ParseModifierPart(pp, ':', then_eflags, st, &then_expr);
+ res = ParseModifierPart(pp, ':', then_eflags, ch, &then_expr);
if (res != VPR_OK)
return AMR_CLEANUP;
- res = ParseModifierPart(pp, st->endc, else_eflags, st, &else_expr);
+ res = ParseModifierPart(pp, ch->endc, else_eflags, ch, &else_expr);
if (res != VPR_OK)
return AMR_CLEANUP;
- (*pp)--; /* Go back to the st->endc. */
+ (*pp)--; /* Go back to the ch->endc. */
if (cond_rc == COND_INVALID) {
Error("Bad conditional expression `%s' in %s?%s:%s",
@@ -3385,9 +3385,9 @@ ApplyModifier_IfElse(const char **pp, Ap
* variable.
*/
static ApplyModifierResult
-ApplyModifier_Assign(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Assign(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
GNode *scope;
char *val;
VarParseResult res;
@@ -3418,11 +3418,11 @@ ok:
break;
}
- res = ParseModifierPart(pp, st->endc, expr->eflags, st, &val);
+ res = ParseModifierPart(pp, ch->endc, expr->eflags, ch, &val);
if (res != VPR_OK)
return AMR_CLEANUP;
- (*pp)--; /* Go back to the st->endc. */
+ (*pp)--; /* Go back to the ch->endc. */
if (!expr->eflags.wantRes)
goto done;
@@ -3470,13 +3470,13 @@ done:
* remember current value
*/
static ApplyModifierResult
-ApplyModifier_Remember(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Remember(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
const char *mod = *pp;
FStr name;
- if (!ModMatchEq(mod, "_", st))
+ if (!ModMatchEq(mod, "_", ch))
return AMR_UNKNOWN;
name = FStr_InitRefer("_");
@@ -3505,28 +3505,28 @@ ApplyModifier_Remember(const char **pp,
* for a single-letter modifier such as :H, :T.
*/
static ApplyModifierResult
-ApplyModifier_WordFunc(const char **pp, ApplyModifiersState *st,
+ApplyModifier_WordFunc(const char **pp, ModChain *ch,
ModifyWordProc modifyWord)
{
- if (!IsDelimiter((*pp)[1], st))
+ if (!IsDelimiter((*pp)[1], ch))
return AMR_UNKNOWN;
(*pp)++;
- if (st->expr->eflags.wantRes)
- ModifyWords(st, modifyWord, NULL, st->oneBigWord);
+ if (ch->expr->eflags.wantRes)
+ ModifyWords(ch, modifyWord, NULL, ch->oneBigWord);
return AMR_OK;
}
static ApplyModifierResult
-ApplyModifier_Unique(const char **pp, ApplyModifiersState *st)
+ApplyModifier_Unique(const char **pp, ModChain *ch)
{
- if (!IsDelimiter((*pp)[1], st))
+ if (!IsDelimiter((*pp)[1], ch))
return AMR_UNKNOWN;
(*pp)++;
- if (st->expr->eflags.wantRes)
- Expr_SetValueOwn(st->expr, VarUniq(st->expr->value.str));
+ if (ch->expr->eflags.wantRes)
+ Expr_SetValueOwn(ch->expr, VarUniq(ch->expr->value.str));
return AMR_OK;
}
@@ -3534,9 +3534,9 @@ ApplyModifier_Unique(const char **pp, Ap
#ifdef SYSVVARSUB
/* :from=to */
static ApplyModifierResult
-ApplyModifier_SysV(const char **pp, ApplyModifiersState *st)
+ApplyModifier_SysV(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
char *lhs, *rhs;
VarParseResult res;
@@ -3552,27 +3552,27 @@ ApplyModifier_SysV(const char **pp, Appl
while (*p != '\0' && depth > 0) {
if (*p == '=') { /* XXX: should also test depth == 1 */
eqFound = TRUE;
- /* continue looking for st->endc */
- } else if (*p == st->endc)
+ /* continue looking for ch->endc */
+ } else if (*p == ch->endc)
depth--;
- else if (*p == st->startc)
+ else if (*p == ch->startc)
depth++;
if (depth > 0)
p++;
}
- if (*p != st->endc || !eqFound)
+ if (*p != ch->endc || !eqFound)
return AMR_UNKNOWN;
- res = ParseModifierPart(pp, '=', expr->eflags, st, &lhs);
+ res = ParseModifierPart(pp, '=', expr->eflags, ch, &lhs);
if (res != VPR_OK)
return AMR_CLEANUP;
/* The SysV modifier lasts until the end of the variable expression. */
- res = ParseModifierPart(pp, st->endc, expr->eflags, st, &rhs);
+ res = ParseModifierPart(pp, ch->endc, expr->eflags, ch, &rhs);
if (res != VPR_OK)
return AMR_CLEANUP;
- (*pp)--; /* Go back to the st->endc. */
+ (*pp)--; /* Go back to the ch->endc. */
if (lhs[0] == '\0' && expr->value.str[0] == '\0') {
/* Do not turn an empty expression into non-empty. */
@@ -3580,7 +3580,7 @@ ApplyModifier_SysV(const char **pp, Appl
struct ModifyWord_SYSVSubstArgs args = {
expr->scope, lhs, rhs
};
- ModifyWords(st, ModifyWord_SYSVSubst, &args, st->oneBigWord);
+ ModifyWords(ch, ModifyWord_SYSVSubst, &args, ch->oneBigWord);
}
free(lhs);
free(rhs);
@@ -3591,11 +3591,11 @@ ApplyModifier_SysV(const char **pp, Appl
#ifdef SUNSHCMD
/* :sh */
static ApplyModifierResult
-ApplyModifier_SunShell(const char **pp, ApplyModifiersState *st)
+ApplyModifier_SunShell(const char **pp, ModChain *ch)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
const char *p = *pp;
- if (!(p[1] == 'h' && IsDelimiter(p[2], st)))
+ if (!(p[1] == 'h' && IsDelimiter(p[2], ch)))
return AMR_UNKNOWN;
*pp = p + 2;
@@ -3612,11 +3612,11 @@ ApplyModifier_SunShell(const char **pp,
#endif
static void
-LogBeforeApply(const ApplyModifiersState *st, const char *mod)
+LogBeforeApply(const ModChain *ch, const char *mod)
{
- const Expr *expr = st->expr;
+ const Expr *expr = ch->expr;
char vflags_str[VarFlags_ToStringSize];
- Boolean is_single_char = mod[0] != '\0' && IsDelimiter(mod[1], st);
+ Boolean is_single_char = mod[0] != '\0' && IsDelimiter(mod[1], ch);
/* At this point, only the first character of the modifier can
* be used since the end of the modifier is not yet known. */
@@ -3629,9 +3629,9 @@ LogBeforeApply(const ApplyModifiersState
}
static void
-LogAfterApply(const ApplyModifiersState *st, const char *p, const char *mod)
+LogAfterApply(const ModChain *ch, const char *p, const char *mod)
{
- const Expr *expr = st->expr;
+ const Expr *expr = ch->expr;
const char *value = expr->value.str;
char vflags_str[VarFlags_ToStringSize];
const char *quot = value == var_Error ? "" : "\"";
@@ -3645,67 +3645,67 @@ LogAfterApply(const ApplyModifiersState
}
static ApplyModifierResult
-ApplyModifier(const char **pp, ApplyModifiersState *st)
+ApplyModifier(const char **pp, ModChain *ch)
{
switch (**pp) {
case '!':
- return ApplyModifier_ShellCommand(pp, st);
+ return ApplyModifier_ShellCommand(pp, ch);
case ':':
- return ApplyModifier_Assign(pp, st);
+ return ApplyModifier_Assign(pp, ch);
case '?':
- return ApplyModifier_IfElse(pp, st);
+ return ApplyModifier_IfElse(pp, ch);
case '@':
- return ApplyModifier_Loop(pp, st);
+ return ApplyModifier_Loop(pp, ch);
case '[':
- return ApplyModifier_Words(pp, st);
+ return ApplyModifier_Words(pp, ch);
case '_':
- return ApplyModifier_Remember(pp, st);
+ return ApplyModifier_Remember(pp, ch);
#ifndef NO_REGEX
case 'C':
- return ApplyModifier_Regex(pp, st);
+ return ApplyModifier_Regex(pp, ch);
#endif
case 'D':
- return ApplyModifier_Defined(pp, st);
+ return ApplyModifier_Defined(pp, ch);
case 'E':
- return ApplyModifier_WordFunc(pp, st, ModifyWord_Suffix);
+ return ApplyModifier_WordFunc(pp, ch, ModifyWord_Suffix);
case 'g':
- return ApplyModifier_Gmtime(pp, st);
+ return ApplyModifier_Gmtime(pp, ch);
case 'H':
- return ApplyModifier_WordFunc(pp, st, ModifyWord_Head);
+ return ApplyModifier_WordFunc(pp, ch, ModifyWord_Head);
case 'h':
- return ApplyModifier_Hash(pp, st);
+ return ApplyModifier_Hash(pp, ch);
case 'L':
- return ApplyModifier_Literal(pp, st);
+ return ApplyModifier_Literal(pp, ch);
case 'l':
- return ApplyModifier_Localtime(pp, st);
+ return ApplyModifier_Localtime(pp, ch);
case 'M':
case 'N':
- return ApplyModifier_Match(pp, st);
+ return ApplyModifier_Match(pp, ch);
case 'O':
- return ApplyModifier_Order(pp, st);
+ return ApplyModifier_Order(pp, ch);
case 'P':
- return ApplyModifier_Path(pp, st);
+ return ApplyModifier_Path(pp, ch);
case 'Q':
case 'q':
- return ApplyModifier_Quote(pp, st);
+ return ApplyModifier_Quote(pp, ch);
case 'R':
- return ApplyModifier_WordFunc(pp, st, ModifyWord_Root);
+ return ApplyModifier_WordFunc(pp, ch, ModifyWord_Root);
case 'r':
- return ApplyModifier_Range(pp, st);
+ return ApplyModifier_Range(pp, ch);
case 'S':
- return ApplyModifier_Subst(pp, st);
+ return ApplyModifier_Subst(pp, ch);
#ifdef SUNSHCMD
case 's':
- return ApplyModifier_SunShell(pp, st);
+ return ApplyModifier_SunShell(pp, ch);
#endif
case 'T':
- return ApplyModifier_WordFunc(pp, st, ModifyWord_Tail);
+ return ApplyModifier_WordFunc(pp, ch, ModifyWord_Tail);
case 't':
- return ApplyModifier_To(pp, st);
+ return ApplyModifier_To(pp, ch);
case 'U':
- return ApplyModifier_Defined(pp, st);
+ return ApplyModifier_Defined(pp, ch);
case 'u':
- return ApplyModifier_Unique(pp, st);
+ return ApplyModifier_Unique(pp, ch);
default:
return AMR_UNKNOWN;
}
@@ -3732,20 +3732,20 @@ typedef enum ApplyModifiersIndirectResul
* Multiple groups of indirect modifiers can be chained by separating them
* with colons. ${VAR:${M1}:${M2}} contains 2 indirect modifiers.
*
- * If the variable expression is not followed by st->endc or ':', fall
+ * If the variable expression is not followed by ch->endc or ':', fall
* back to trying the SysV modifier, such as in ${VAR:${FROM}=${TO}}.
*/
static ApplyModifiersIndirectResult
-ApplyModifiersIndirect(ApplyModifiersState *st, const char **pp)
+ApplyModifiersIndirect(ModChain *ch, const char **pp)
{
- Expr *expr = st->expr;
+ Expr *expr = ch->expr;
const char *p = *pp;
FStr mods;
(void)Var_Parse(&p, expr->scope, expr->eflags, &mods);
/* TODO: handle errors */
- if (mods.str[0] != '\0' && *p != '\0' && !IsDelimiter(*p, st)) {
+ if (mods.str[0] != '\0' && *p != '\0' && !IsDelimiter(*p, ch)) {
FStr_Done(&mods);
return AMIR_SYSV;
}
@@ -3766,10 +3766,10 @@ ApplyModifiersIndirect(ApplyModifiersSta
if (*p == ':')
p++;
- else if (*p == '\0' && st->endc != '\0') {
+ else if (*p == '\0' && ch->endc != '\0') {
Error("Unclosed variable expression after indirect "
"modifier, expecting '%c' for variable \"%s\"",
- st->endc, expr->var->name.str);
+ ch->endc, expr->var->name.str);
*pp = p;
return AMIR_OUT;
}
@@ -3779,21 +3779,21 @@ ApplyModifiersIndirect(ApplyModifiersSta
}
static ApplyModifierResult
-ApplySingleModifier(const char **pp, ApplyModifiersState *st)
+ApplySingleModifier(const char **pp, ModChain *ch)
{
ApplyModifierResult res;
const char *mod = *pp;
const char *p = *pp;
if (DEBUG(VAR))
- LogBeforeApply(st, mod);
+ LogBeforeApply(ch, mod);
- res = ApplyModifier(&p, st);
+ res = ApplyModifier(&p, ch);
#ifdef SYSVVARSUB
if (res == AMR_UNKNOWN) {
assert(p == mod);
- res = ApplyModifier_SysV(&p, st);
+ res = ApplyModifier_SysV(&p, ch);
}
#endif
@@ -3804,11 +3804,11 @@ ApplySingleModifier(const char **pp, App
* errors and leads to wrong results.
* Parsing should rather stop here.
*/
- for (p++; !IsDelimiter(*p, st) && *p != '\0'; p++)
+ for (p++; !IsDelimiter(*p, ch) && *p != '\0'; p++)
continue;
Parse_Error(PARSE_FATAL, "Unknown modifier \"%.*s\"",
(int)(p - mod), mod);
- Expr_SetValueRefer(st->expr, var_Error);
+ Expr_SetValueRefer(ch->expr, var_Error);
}
if (res == AMR_CLEANUP || res == AMR_BAD) {
*pp = p;
@@ -3816,18 +3816,18 @@ ApplySingleModifier(const char **pp, App
}
if (DEBUG(VAR))
- LogAfterApply(st, p, mod);
+ LogAfterApply(ch, p, mod);
- if (*p == '\0' && st->endc != '\0') {
+ if (*p == '\0' && ch->endc != '\0') {
Error(
"Unclosed variable expression, expecting '%c' for "
"modifier \"%.*s\" of variable \"%s\" with value \"%s\"",
- st->endc,
+ ch->endc,
(int)(p - mod), mod,
- st->expr->var->name.str, st->expr->value.str);
+ ch->expr->var->name.str, ch->expr->value.str);
} else if (*p == ':') {
p++;
- } else if (opts.strict && *p != '\0' && *p != st->endc) {
+ } else if (opts.strict && *p != '\0' && *p != ch->endc) {
Parse_Error(PARSE_FATAL,
"Missing delimiter ':' after modifier \"%.*s\"",
(int)(p - mod), mod);
@@ -3849,7 +3849,7 @@ ApplyModifiers(
char endc /* ')' or '}'; or '\0' for indirect modifiers */
)
{
- ApplyModifiersState st = {
+ ModChain ch = {
expr,
startc,
endc,
@@ -3868,7 +3868,7 @@ ApplyModifiers(
if (*p == '\0' && endc != '\0') {
Error(
"Unclosed variable expression (expecting '%c') for \"%s\"",
- st.endc, expr->var->name.str);
+ ch.endc, expr->var->name.str);
goto cleanup;
}
@@ -3877,7 +3877,7 @@ ApplyModifiers(
if (*p == '$') {
ApplyModifiersIndirectResult amir =
- ApplyModifiersIndirect(&st, &p);
+ ApplyModifiersIndirect(&ch, &p);
if (amir == AMIR_CONTINUE)
continue;
if (amir == AMIR_OUT)
@@ -3891,7 +3891,7 @@ ApplyModifiers(
mod = p;
- res = ApplySingleModifier(&p, &st);
+ res = ApplySingleModifier(&p, &ch);
if (res == AMR_CLEANUP)
goto cleanup;
if (res == AMR_BAD)
Index: src/usr.bin/make/unit-tests/varmod-indirect.mk
diff -u src/usr.bin/make/unit-tests/varmod-indirect.mk:1.8 src/usr.bin/make/unit-tests/varmod-indirect.mk:1.9
--- src/usr.bin/make/unit-tests/varmod-indirect.mk:1.8 Sun Feb 14 17:47:33 2021
+++ src/usr.bin/make/unit-tests/varmod-indirect.mk Mon Mar 15 20:00:50 2021
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-indirect.mk,v 1.8 2021/02/14 17:47:33 rillig Exp $
+# $NetBSD: varmod-indirect.mk,v 1.9 2021/03/15 20:00:50 rillig Exp $
#
# Tests for indirect variable modifiers, such as in ${VAR:${M_modifiers}}.
# These can be used for very basic purposes like converting a string to either
@@ -221,7 +221,7 @@ _:= before ${UNDEF:${:UZ}} after
# the ':M' since that is not part of the text from the indirect modifier.
#
# Implementation detail: when ApplyModifiersIndirect calls ApplyModifiers
-# (which creates a new ApplyModifiersState containing a fresh separator),
+# (which creates a new ModChain containing a fresh separator),
# the outer separator character is not passed by reference to the inner
# evaluation, therefore the scope of the inner separator ends after applying
# the modifier ':ts*'.