Module Name: src
Committed By: rillig
Date: Thu Dec 30 01:30:33 UTC 2021
Modified Files:
src/usr.bin/make: cond.c
Log Message:
make: split ParseWord into the actual ParseWord and ParseFuncArg
Combining two similar but fundamentally different parsing tasks in a
single function only increased the complexity, of the implementation as
well as the call sites.
The code makes it obvious now that a function argument is a bare word
surrounded by parentheses.
The special case of an empty word is only needed for the function
argument, it cannot occur in a bare word. The code for that has been
moved to the caller. Such an empty word not only occurs for 'defined()'
but also for 'defined(${:U})'.
No functional change.
To generate a diff of this commit:
cvs rdiff -u -r1.318 -r1.319 src/usr.bin/make/cond.c
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/cond.c
diff -u src/usr.bin/make/cond.c:1.318 src/usr.bin/make/cond.c:1.319
--- src/usr.bin/make/cond.c:1.318 Thu Dec 30 01:06:43 2021
+++ src/usr.bin/make/cond.c Thu Dec 30 01:30:33 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.318 2021/12/30 01:06:43 rillig Exp $ */
+/* $NetBSD: cond.c,v 1.319 2021/12/30 01:30:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -95,7 +95,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
-MAKE_RCSID("$NetBSD: cond.c,v 1.318 2021/12/30 01:06:43 rillig Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.319 2021/12/30 01:30:33 rillig Exp $");
/*
* The parsing of conditional expressions is based on this grammar:
@@ -208,30 +208,13 @@ CondParser_SkipWhitespace(CondParser *pa
* Parse a single word, taking into account balanced parentheses as well as
* embedded expressions. Used for the argument of a built-in function as
* well as for bare words, which are then passed to the default function.
- *
- * Arguments:
- * *pp initially points at the '(',
- * upon successful return it points right after the ')'.
- *
- * *out_arg receives the argument as string.
- *
- * func says whether the argument belongs to an actual function, or
- * NULL when parsing a bare word.
- *
- * Return NULL if there was a parse error or the argument was empty.
*/
static char *
-ParseWord(CondParser *par, const char **pp, bool doEval, const char *func)
+ParseWord(const char **pp, bool doEval)
{
const char *p = *pp;
Buffer argBuf;
int paren_depth;
- char *res;
-
- if (func != NULL)
- p++; /* Skip opening '(' - verified by caller */
-
- cpp_skip_hspace(&p);
Buf_InitSize(&argBuf, 16);
@@ -269,11 +252,25 @@ ParseWord(CondParser *par, const char **
p++;
}
- res = Buf_DoneData(&argBuf);
+ cpp_skip_hspace(&p);
+ *pp = p;
+ return Buf_DoneData(&argBuf);
+}
+
+/* Parse the function argument, including the surrounding parentheses. */
+static char *
+ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func)
+{
+ const char *p = *pp;
+ char *res;
+
+ p++; /* Skip opening '(' - verified by caller */
+ cpp_skip_hspace(&p);
+ res = ParseWord(&p, doEval);
cpp_skip_hspace(&p);
- if (func != NULL && *p++ != ')') {
+ if (*p++ != ')') {
int len = 0;
while (ch_isalpha(func[len]))
len++;
@@ -286,11 +283,6 @@ ParseWord(CondParser *par, const char **
}
*pp = p;
-
- if (res[0] == '\0') {
- free(res);
- res = NULL;
- }
return res;
}
@@ -764,8 +756,9 @@ CondParser_FuncCall(CondParser *par, boo
if (*p != '(')
return false;
- arg = ParseWord(par, &p, doEval, fn_name);
- *out_token = ToToken(doEval && arg != NULL && fn(arg));
+ arg = ParseFuncArg(par, &p, doEval, fn_name);
+ *out_token = ToToken(doEval &&
+ arg != NULL && arg[0] != '\0' && fn(arg));
free(arg);
par->p = p;
@@ -804,11 +797,12 @@ CondParser_ComparisonOrLeaf(CondParser *
* XXX: Is it possible to have a variable expression evaluated twice
* at this point?
*/
- arg = ParseWord(par, &cp, doEval, NULL);
- assert(arg != NULL);
+ arg = ParseWord(&cp, doEval);
+ assert(arg[0] != '\0');
cp1 = cp;
cpp_skip_whitespace(&cp1);
+ assert(cp1 == cp); /* TODO: remove the cpp_skip_whitespace above */
if (*cp1 == '=' || *cp1 == '!' || *cp1 == '<' || *cp1 == '>')
return CondParser_Comparison(par, doEval);
par->p = cp;