| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: cond.c,v 1.331 2022/03/03 19:36:35 rillig Exp $ */ | | 1 | /* $NetBSD: cond.c,v 1.332 2022/03/03 19:40:54 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -85,27 +85,27 @@ | | | @@ -85,27 +85,27 @@ |
85 | * Cond_restore_depth | | 85 | * Cond_restore_depth |
86 | * Save and restore the nesting of the conditions, at | | 86 | * Save and restore the nesting of the conditions, at |
87 | * the start and end of including another makefile, to | | 87 | * the start and end of including another makefile, to |
88 | * ensure that in each makefile the conditional | | 88 | * ensure that in each makefile the conditional |
89 | * directives are well-balanced. | | 89 | * directives are well-balanced. |
90 | */ | | 90 | */ |
91 | | | 91 | |
92 | #include <errno.h> | | 92 | #include <errno.h> |
93 | | | 93 | |
94 | #include "make.h" | | 94 | #include "make.h" |
95 | #include "dir.h" | | 95 | #include "dir.h" |
96 | | | 96 | |
97 | /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ | | 97 | /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ |
98 | MAKE_RCSID("$NetBSD: cond.c,v 1.331 2022/03/03 19:36:35 rillig Exp $"); | | 98 | MAKE_RCSID("$NetBSD: cond.c,v 1.332 2022/03/03 19:40:54 rillig Exp $"); |
99 | | | 99 | |
100 | /* | | 100 | /* |
101 | * Conditional expressions conform to this grammar: | | 101 | * Conditional expressions conform to this grammar: |
102 | * Or -> And ('||' And)* | | 102 | * Or -> And ('||' And)* |
103 | * And -> Term ('&&' Term)* | | 103 | * And -> Term ('&&' Term)* |
104 | * Term -> Function '(' Argument ')' | | 104 | * Term -> Function '(' Argument ')' |
105 | * Term -> Leaf Operator Leaf | | 105 | * Term -> Leaf Operator Leaf |
106 | * Term -> Leaf | | 106 | * Term -> Leaf |
107 | * Term -> '(' Or ')' | | 107 | * Term -> '(' Or ')' |
108 | * Term -> '!' Term | | 108 | * Term -> '!' Term |
109 | * Leaf -> "string" | | 109 | * Leaf -> "string" |
110 | * Leaf -> Number | | 110 | * Leaf -> Number |
111 | * Leaf -> VariableExpression | | 111 | * Leaf -> VariableExpression |
| @@ -203,69 +203,69 @@ CondParser_SkipWhitespace(CondParser *pa | | | @@ -203,69 +203,69 @@ CondParser_SkipWhitespace(CondParser *pa |
203 | { | | 203 | { |
204 | cpp_skip_whitespace(&par->p); | | 204 | cpp_skip_whitespace(&par->p); |
205 | } | | 205 | } |
206 | | | 206 | |
207 | /* | | 207 | /* |
208 | * Parse a single word, taking into account balanced parentheses as well as | | 208 | * Parse a single word, taking into account balanced parentheses as well as |
209 | * embedded expressions. Used for the argument of a built-in function as | | 209 | * embedded expressions. Used for the argument of a built-in function as |
210 | * well as for bare words, which are then passed to the default function. | | 210 | * well as for bare words, which are then passed to the default function. |
211 | */ | | 211 | */ |
212 | static char * | | 212 | static char * |
213 | ParseWord(const char **pp, bool doEval) | | 213 | ParseWord(const char **pp, bool doEval) |
214 | { | | 214 | { |
215 | const char *p = *pp; | | 215 | const char *p = *pp; |
216 | Buffer argBuf; | | 216 | Buffer word; |
217 | int paren_depth; | | 217 | int paren_depth; |
218 | | | 218 | |
219 | Buf_InitSize(&argBuf, 16); | | 219 | Buf_InitSize(&word, 16); |
220 | | | 220 | |
221 | paren_depth = 0; | | 221 | paren_depth = 0; |
222 | for (;;) { | | 222 | for (;;) { |
223 | char ch = *p; | | 223 | char ch = *p; |
224 | if (ch == '\0' || ch == ' ' || ch == '\t') | | 224 | if (ch == '\0' || ch == ' ' || ch == '\t') |
225 | break; | | 225 | break; |
226 | if ((ch == '&' || ch == '|') && paren_depth == 0) | | 226 | if ((ch == '&' || ch == '|') && paren_depth == 0) |
227 | break; | | 227 | break; |
228 | if (ch == '$') { | | 228 | if (ch == '$') { |
229 | /* | | 229 | /* |
230 | * Parse the variable expression and install it as | | 230 | * Parse the variable expression and install it as |
231 | * part of the argument if it's valid. We tell | | 231 | * part of the argument if it's valid. We tell |
232 | * Var_Parse to complain on an undefined variable, | | 232 | * Var_Parse to complain on an undefined variable, |
233 | * (XXX: but Var_Parse ignores that request) | | 233 | * (XXX: but Var_Parse ignores that request) |
234 | * so we don't need to do it. Nor do we return an | | 234 | * so we don't need to do it. Nor do we return an |
235 | * error, though perhaps we should. | | 235 | * error, though perhaps we should. |
236 | */ | | 236 | */ |
237 | VarEvalMode emode = doEval | | 237 | VarEvalMode emode = doEval |
238 | ? VARE_UNDEFERR | | 238 | ? VARE_UNDEFERR |
239 | : VARE_PARSE_ONLY; | | 239 | : VARE_PARSE_ONLY; |
240 | FStr nestedVal; | | 240 | FStr nestedVal; |
241 | (void)Var_Parse(&p, SCOPE_CMDLINE, emode, &nestedVal); | | 241 | (void)Var_Parse(&p, SCOPE_CMDLINE, emode, &nestedVal); |
242 | /* TODO: handle errors */ | | 242 | /* TODO: handle errors */ |
243 | Buf_AddStr(&argBuf, nestedVal.str); | | 243 | Buf_AddStr(&word, nestedVal.str); |
244 | FStr_Done(&nestedVal); | | 244 | FStr_Done(&nestedVal); |
245 | continue; | | 245 | continue; |
246 | } | | 246 | } |
247 | if (ch == '(') | | 247 | if (ch == '(') |
248 | paren_depth++; | | 248 | paren_depth++; |
249 | else if (ch == ')' && --paren_depth < 0) | | 249 | else if (ch == ')' && --paren_depth < 0) |
250 | break; | | 250 | break; |
251 | Buf_AddByte(&argBuf, ch); | | 251 | Buf_AddByte(&word, ch); |
252 | p++; | | 252 | p++; |
253 | } | | 253 | } |
254 | | | 254 | |
255 | cpp_skip_hspace(&p); | | 255 | cpp_skip_hspace(&p); |
256 | *pp = p; | | 256 | *pp = p; |
257 | | | 257 | |
258 | return Buf_DoneData(&argBuf); | | 258 | return Buf_DoneData(&word); |
259 | } | | 259 | } |
260 | | | 260 | |
261 | /* Parse the function argument, including the surrounding parentheses. */ | | 261 | /* Parse the function argument, including the surrounding parentheses. */ |
262 | static char * | | 262 | static char * |
263 | ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func) | | 263 | ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func) |
264 | { | | 264 | { |
265 | const char *p = *pp; | | 265 | const char *p = *pp; |
266 | char *res; | | 266 | char *res; |
267 | | | 267 | |
268 | p++; /* Skip opening '(' - verified by caller */ | | 268 | p++; /* Skip opening '(' - verified by caller */ |
269 | cpp_skip_hspace(&p); | | 269 | cpp_skip_hspace(&p); |
270 | res = ParseWord(&p, doEval); | | 270 | res = ParseWord(&p, doEval); |
271 | cpp_skip_hspace(&p); | | 271 | cpp_skip_hspace(&p); |