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;