var.c revision 1.1132 1 /* $NetBSD: var.c,v 1.1132 2024/07/05 19:47:22 rillig Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 /*
36 * Copyright (c) 1989 by Berkeley Softworks
37 * All rights reserved.
38 *
39 * This code is derived from software contributed to Berkeley by
40 * Adam de Boor.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement:
52 * This product includes software developed by the University of
53 * California, Berkeley and its contributors.
54 * 4. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 */
70
71 /*
72 * Handling of variables and the expressions formed from them.
73 *
74 * Variables are set using lines of the form VAR=value. Both the variable
75 * name and the value can contain references to other variables, by using
76 * expressions like ${VAR}, ${VAR:Modifiers}, ${${VARNAME}} or ${VAR:${MODS}}.
77 *
78 * Interface:
79 * Var_Init Initialize this module.
80 *
81 * Var_End Clean up the module.
82 *
83 * Var_Set
84 * Var_SetExpand Set the value of the variable, creating it if
85 * necessary.
86 *
87 * Var_Append
88 * Var_AppendExpand
89 * Append more characters to the variable, creating it if
90 * necessary. A space is placed between the old value and
91 * the new one.
92 *
93 * Var_Exists
94 * Var_ExistsExpand
95 * See if a variable exists.
96 *
97 * Var_Value Return the unexpanded value of a variable, or NULL if
98 * the variable is undefined.
99 *
100 * Var_Subst Substitute all expressions in a string.
101 *
102 * Var_Parse Parse an expression such as ${VAR:Mpattern}.
103 *
104 * Var_Delete Delete a variable.
105 *
106 * Var_ReexportVars
107 * Export some or even all variables to the environment
108 * of this process and its child processes.
109 *
110 * Var_Export Export the variable to the environment of this process
111 * and its child processes.
112 *
113 * Var_UnExport Don't export the variable anymore.
114 *
115 * Debugging:
116 * Var_Stats Print out hashing statistics if in -dh mode.
117 *
118 * Var_Dump Print out all variables defined in the given scope.
119 */
120
121 #include <sys/stat.h>
122 #include <sys/types.h>
123 #include <regex.h>
124 #include <errno.h>
125 #include <inttypes.h>
126 #include <limits.h>
127 #include <time.h>
128
129 #include "make.h"
130 #include "dir.h"
131 #include "job.h"
132 #include "metachar.h"
133
134 /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
135 MAKE_RCSID("$NetBSD: var.c,v 1.1132 2024/07/05 19:47:22 rillig Exp $");
136
137 /*
138 * Variables are defined using one of the VAR=value assignments. Their
139 * value can be queried by expressions such as $V, ${VAR}, or with modifiers
140 * such as ${VAR:S,from,to,g:Q}.
141 *
142 * There are 3 kinds of variables: scope variables, environment variables,
143 * undefined variables.
144 *
145 * Scope variables are stored in GNode.vars. The only way to undefine
146 * a scope variable is using the .undef directive. In particular, it must
147 * not be possible to undefine a variable during the evaluation of an
148 * expression, or Var.name might point nowhere. (There is another,
149 * unintended way to undefine a scope variable, see varmod-loop-delete.mk.)
150 *
151 * Environment variables are short-lived. They are returned by VarFind, and
152 * after using them, they must be freed using VarFreeShortLived.
153 *
154 * Undefined variables occur during evaluation of expressions such
155 * as ${UNDEF:Ufallback} in Var_Parse and ApplyModifiers.
156 */
157 typedef struct Var {
158 /*
159 * The name of the variable, once set, doesn't change anymore.
160 * For scope variables, it aliases the corresponding HashEntry name.
161 * For environment and undefined variables, it is allocated.
162 */
163 FStr name;
164
165 /* The unexpanded value of the variable. */
166 Buffer val;
167
168 /* The variable came from the command line. */
169 bool fromCmd:1;
170
171 /*
172 * The variable is short-lived.
173 * These variables are not registered in any GNode, therefore they
174 * must be freed after use.
175 */
176 bool shortLived:1;
177
178 /*
179 * The variable comes from the environment.
180 * Appending to its value depends on the scope, see var-op-append.mk.
181 */
182 bool fromEnvironment:1;
183
184 /*
185 * The variable value cannot be changed anymore, and the variable
186 * cannot be deleted. Any attempts to do so are silently ignored,
187 * they are logged with -dv though.
188 * Use .[NO]READONLY: to adjust.
189 *
190 * See VAR_SET_READONLY.
191 */
192 bool readOnly:1;
193
194 /*
195 * The variable is read-only and immune to the .NOREADONLY special
196 * target. Any attempt to modify it results in an error.
197 */
198 bool readOnlyLoud:1;
199
200 /*
201 * The variable is currently being accessed by Var_Parse or Var_Subst.
202 * This temporary marker is used to avoid endless recursion.
203 */
204 bool inUse:1;
205
206 /*
207 * The variable is exported to the environment, to be used by child
208 * processes.
209 */
210 bool exported:1;
211
212 /*
213 * At the point where this variable was exported, it contained an
214 * unresolved reference to another variable. Before any child
215 * process is started, it needs to be actually exported, resolving
216 * the referenced variable just in time.
217 */
218 bool reexport:1;
219 } Var;
220
221 /*
222 * Exporting variables is expensive and may leak memory, so skip it if we
223 * can.
224 */
225 typedef enum VarExportedMode {
226 VAR_EXPORTED_NONE,
227 VAR_EXPORTED_SOME,
228 VAR_EXPORTED_ALL
229 } VarExportedMode;
230
231 typedef enum UnexportWhat {
232 /* Unexport the variables given by name. */
233 UNEXPORT_NAMED,
234 /*
235 * Unexport all globals previously exported, but keep the environment
236 * inherited from the parent.
237 */
238 UNEXPORT_ALL,
239 /*
240 * Unexport all globals previously exported and clear the environment
241 * inherited from the parent.
242 */
243 UNEXPORT_ENV
244 } UnexportWhat;
245
246 /* Flags for pattern matching in the :S and :C modifiers */
247 typedef struct PatternFlags {
248 bool subGlobal:1; /* 'g': replace as often as possible */
249 bool subOnce:1; /* '1': replace only once */
250 bool anchorStart:1; /* '^': match only at start of word */
251 bool anchorEnd:1; /* '$': match only at end of word */
252 } PatternFlags;
253
254 /* SepBuf builds a string from words interleaved with separators. */
255 typedef struct SepBuf {
256 Buffer buf;
257 bool needSep;
258 /* Usually ' ', but see the ':ts' modifier. */
259 char sep;
260 } SepBuf;
261
262 typedef enum {
263 VSK_TARGET,
264 VSK_VARNAME,
265 VSK_COND,
266 VSK_COND_THEN,
267 VSK_COND_ELSE,
268 VSK_EXPR
269 } EvalStackElementKind;
270
271 typedef struct {
272 EvalStackElementKind kind;
273 const char *str;
274 const FStr *value;
275 } EvalStackElement;
276
277 typedef struct {
278 EvalStackElement *elems;
279 size_t len;
280 size_t cap;
281 Buffer details;
282 } EvalStack;
283
284 /* Whether we have replaced the original environ (which we cannot free). */
285 char **savedEnv = NULL;
286
287 /*
288 * Special return value for Var_Parse, indicating a parse error. It may be
289 * caused by an undefined variable, a syntax error in a modifier or
290 * something entirely different.
291 */
292 char var_Error[] = "";
293
294 /*
295 * Special return value for Var_Parse, indicating an undefined variable in
296 * a case where VARE_EVAL_DEFINED is not set. This undefined variable is
297 * typically a dynamic variable such as ${.TARGET}, whose expansion needs to
298 * be deferred until it is defined in an actual target.
299 *
300 * See VARE_EVAL_KEEP_UNDEFINED.
301 */
302 static char varUndefined[] = "";
303
304 /*
305 * Traditionally this make consumed $$ during := like any other expansion.
306 * Other make's do not, and this make follows straight since 2016-01-09.
307 *
308 * This knob allows controlling the behavior:
309 * false to consume $$ during := assignment.
310 * true to preserve $$ during := assignment.
311 */
312 #define MAKE_SAVE_DOLLARS ".MAKE.SAVE_DOLLARS"
313 static bool save_dollars = true;
314
315 /*
316 * A scope collects variable names and their values.
317 *
318 * The main scope is SCOPE_GLOBAL, which contains the variables that are set
319 * in the makefiles. SCOPE_INTERNAL acts as a fallback for SCOPE_GLOBAL and
320 * contains some internal make variables. These internal variables can thus
321 * be overridden, they can also be restored by undefining the overriding
322 * variable.
323 *
324 * SCOPE_CMDLINE contains variables from the command line arguments. These
325 * override variables from SCOPE_GLOBAL.
326 *
327 * There is no scope for environment variables, these are generated on-the-fly
328 * whenever they are referenced.
329 *
330 * Each target has its own scope, containing the 7 target-local variables
331 * .TARGET, .ALLSRC, etc. Variables set on dependency lines also go in
332 * this scope.
333 */
334
335 GNode *SCOPE_CMDLINE;
336 GNode *SCOPE_GLOBAL;
337 GNode *SCOPE_INTERNAL;
338
339 static VarExportedMode var_exportedVars = VAR_EXPORTED_NONE;
340
341 static const char VarEvalMode_Name[][32] = {
342 "parse",
343 "parse-balanced",
344 "eval",
345 "eval-defined",
346 "eval-keep-undefined",
347 "eval-keep-dollar-and-undefined",
348 };
349
350 static EvalStack evalStack;
351
352
353 static void
354 EvalStack_Push(EvalStackElementKind kind, const char *str, const FStr *value)
355 {
356 if (evalStack.len >= evalStack.cap) {
357 evalStack.cap = 16 + 2 * evalStack.cap;
358 evalStack.elems = bmake_realloc(evalStack.elems,
359 evalStack.cap * sizeof(*evalStack.elems));
360 }
361 evalStack.elems[evalStack.len].kind = kind;
362 evalStack.elems[evalStack.len].str = str;
363 evalStack.elems[evalStack.len].value = value;
364 evalStack.len++;
365 }
366
367 static void
368 EvalStack_Pop(void)
369 {
370 assert(evalStack.len > 0);
371 evalStack.len--;
372 }
373
374 const char *
375 EvalStack_Details(void)
376 {
377 size_t i;
378 Buffer *buf = &evalStack.details;
379
380
381 buf->len = 0;
382 for (i = 0; i < evalStack.len; i++) {
383 static const char descr[][42] = {
384 "in target",
385 "while evaluating variable",
386 "while evaluating condition",
387 "while evaluating then-branch of condition",
388 "while evaluating else-branch of condition",
389 "while evaluating",
390 };
391 EvalStackElement *elem = evalStack.elems + i;
392 EvalStackElementKind kind = elem->kind;
393 Buf_AddStr(buf, descr[kind]);
394 Buf_AddStr(buf, " \"");
395 Buf_AddStr(buf, elem->str);
396 if (elem->value != NULL
397 && (kind == VSK_VARNAME || kind == VSK_EXPR)) {
398 Buf_AddStr(buf, "\" with value \"");
399 Buf_AddStr(buf, elem->value->str);
400 }
401 Buf_AddStr(buf, "\": ");
402 }
403 return buf->len > 0 ? buf->data : "";
404 }
405
406 static Var *
407 VarNew(FStr name, const char *value,
408 bool shortLived, bool fromEnvironment, bool readOnly)
409 {
410 size_t value_len = strlen(value);
411 Var *var = bmake_malloc(sizeof *var);
412 var->name = name;
413 Buf_InitSize(&var->val, value_len + 1);
414 Buf_AddBytes(&var->val, value, value_len);
415 var->fromCmd = false;
416 var->shortLived = shortLived;
417 var->fromEnvironment = fromEnvironment;
418 var->readOnly = readOnly;
419 var->readOnlyLoud = false;
420 var->inUse = false;
421 var->exported = false;
422 var->reexport = false;
423 return var;
424 }
425
426 static Substring
427 CanonicalVarname(Substring name)
428 {
429
430 if (!(Substring_Length(name) > 0 && name.start[0] == '.'))
431 return name;
432
433 if (Substring_Equals(name, ".ALLSRC"))
434 return Substring_InitStr(ALLSRC);
435 if (Substring_Equals(name, ".ARCHIVE"))
436 return Substring_InitStr(ARCHIVE);
437 if (Substring_Equals(name, ".IMPSRC"))
438 return Substring_InitStr(IMPSRC);
439 if (Substring_Equals(name, ".MEMBER"))
440 return Substring_InitStr(MEMBER);
441 if (Substring_Equals(name, ".OODATE"))
442 return Substring_InitStr(OODATE);
443 if (Substring_Equals(name, ".PREFIX"))
444 return Substring_InitStr(PREFIX);
445 if (Substring_Equals(name, ".TARGET"))
446 return Substring_InitStr(TARGET);
447
448 /* GNU make has an additional alias $^ == ${.ALLSRC}. */
449
450 if (Substring_Equals(name, ".SHELL") && shellPath == NULL)
451 Shell_Init();
452
453 return name;
454 }
455
456 static Var *
457 GNode_FindVar(GNode *scope, Substring varname, unsigned int hash)
458 {
459 return HashTable_FindValueBySubstringHash(&scope->vars, varname, hash);
460 }
461
462 /*
463 * Find the variable in the scope, and maybe in other scopes as well.
464 *
465 * Input:
466 * name name to find, is not expanded any further
467 * scope scope in which to look first
468 * elsewhere true to look in other scopes as well
469 *
470 * Results:
471 * The found variable, or NULL if the variable does not exist.
472 * If the variable is short-lived (such as environment variables), it
473 * must be freed using VarFreeShortLived after use.
474 */
475 static Var *
476 VarFindSubstring(Substring name, GNode *scope, bool elsewhere)
477 {
478 Var *var;
479 unsigned int nameHash;
480
481 /* Replace '.TARGET' with '@', likewise for other local variables. */
482 name = CanonicalVarname(name);
483 nameHash = Hash_Substring(name);
484
485 var = GNode_FindVar(scope, name, nameHash);
486 if (!elsewhere)
487 return var;
488
489 if (var == NULL && scope != SCOPE_CMDLINE)
490 var = GNode_FindVar(SCOPE_CMDLINE, name, nameHash);
491
492 if (!opts.checkEnvFirst && var == NULL && scope != SCOPE_GLOBAL) {
493 var = GNode_FindVar(SCOPE_GLOBAL, name, nameHash);
494 if (var == NULL && scope != SCOPE_INTERNAL) {
495 /* SCOPE_INTERNAL is subordinate to SCOPE_GLOBAL */
496 var = GNode_FindVar(SCOPE_INTERNAL, name, nameHash);
497 }
498 }
499
500 if (var == NULL) {
501 FStr envName = Substring_Str(name);
502 const char *envValue = getenv(envName.str);
503 if (envValue != NULL)
504 return VarNew(envName, envValue, true, true, false);
505 FStr_Done(&envName);
506
507 if (opts.checkEnvFirst && scope != SCOPE_GLOBAL) {
508 var = GNode_FindVar(SCOPE_GLOBAL, name, nameHash);
509 if (var == NULL && scope != SCOPE_INTERNAL)
510 var = GNode_FindVar(SCOPE_INTERNAL, name,
511 nameHash);
512 return var;
513 }
514
515 return NULL;
516 }
517
518 return var;
519 }
520
521 static Var *
522 VarFind(const char *name, GNode *scope, bool elsewhere)
523 {
524 return VarFindSubstring(Substring_InitStr(name), scope, elsewhere);
525 }
526
527 /* If the variable is short-lived, free it, including its value. */
528 static void
529 VarFreeShortLived(Var *v)
530 {
531 if (!v->shortLived)
532 return;
533
534 FStr_Done(&v->name);
535 Buf_Done(&v->val);
536 free(v);
537 }
538
539 static const char *
540 ValueDescription(const char *value)
541 {
542 if (value[0] == '\0')
543 return "# (empty)";
544 if (ch_isspace(value[strlen(value) - 1]))
545 return "# (ends with space)";
546 return "";
547 }
548
549 /* Add a new variable of the given name and value to the given scope. */
550 static Var *
551 VarAdd(const char *name, const char *value, GNode *scope, VarSetFlags flags)
552 {
553 HashEntry *he = HashTable_CreateEntry(&scope->vars, name, NULL);
554 Var *v = VarNew(FStr_InitRefer(/* aliased to */ he->key), value,
555 false, false, (flags & VAR_SET_READONLY) != 0);
556 HashEntry_Set(he, v);
557 DEBUG4(VAR, "%s: %s = %s%s\n",
558 scope->name, name, value, ValueDescription(value));
559 return v;
560 }
561
562 /*
563 * Remove a variable from a scope, freeing all related memory as well.
564 * The variable name is kept as-is, it is not expanded.
565 */
566 void
567 Var_Delete(GNode *scope, const char *varname)
568 {
569 HashEntry *he = HashTable_FindEntry(&scope->vars, varname);
570 Var *v;
571
572 if (he == NULL) {
573 DEBUG2(VAR, "%s: ignoring delete '%s' as it is not found\n",
574 scope->name, varname);
575 return;
576 }
577
578 v = he->value;
579 if (v->readOnlyLoud) {
580 Parse_Error(PARSE_FATAL,
581 "Cannot delete \"%s\" as it is read-only",
582 v->name.str);
583 return;
584 }
585 if (v->readOnly) {
586 DEBUG2(VAR, "%s: ignoring delete '%s' as it is read-only\n",
587 scope->name, varname);
588 return;
589 }
590 if (v->inUse) {
591 Parse_Error(PARSE_FATAL,
592 "Cannot delete variable \"%s\" while it is used",
593 v->name.str);
594 return;
595 }
596
597 DEBUG2(VAR, "%s: delete %s\n", scope->name, varname);
598 if (v->exported)
599 unsetenv(v->name.str);
600 if (strcmp(v->name.str, ".MAKE.EXPORTED") == 0)
601 var_exportedVars = VAR_EXPORTED_NONE;
602
603 assert(v->name.freeIt == NULL);
604 HashTable_DeleteEntry(&scope->vars, he);
605 Buf_Done(&v->val);
606 free(v);
607 }
608
609 #ifdef CLEANUP
610 void
611 Var_DeleteAll(GNode *scope)
612 {
613 HashIter hi;
614 HashIter_Init(&hi, &scope->vars);
615 while (HashIter_Next(&hi)) {
616 Var *v = hi.entry->value;
617 Buf_Done(&v->val);
618 free(v);
619 }
620 }
621 #endif
622
623 /*
624 * Undefine one or more variables from the global scope.
625 * The argument is expanded exactly once and then split into words.
626 */
627 void
628 Var_Undef(const char *arg)
629 {
630 char *expanded;
631 Words varnames;
632 size_t i;
633
634 if (arg[0] == '\0') {
635 Parse_Error(PARSE_FATAL,
636 "The .undef directive requires an argument");
637 return;
638 }
639
640 expanded = Var_Subst(arg, SCOPE_GLOBAL, VARE_EVAL);
641 if (expanded == var_Error) {
642 /* TODO: Make this part of the code reachable. */
643 Parse_Error(PARSE_FATAL,
644 "Error in variable names to be undefined");
645 return;
646 }
647
648 varnames = Str_Words(expanded, false);
649 if (varnames.len == 1 && varnames.words[0][0] == '\0')
650 varnames.len = 0;
651
652 for (i = 0; i < varnames.len; i++) {
653 const char *varname = varnames.words[i];
654 Global_Delete(varname);
655 }
656
657 Words_Free(varnames);
658 free(expanded);
659 }
660
661 static bool
662 MayExport(const char *name)
663 {
664 if (name[0] == '.')
665 return false; /* skip internals */
666 if (name[0] == '-')
667 return false; /* skip misnamed variables */
668 if (name[1] == '\0') {
669 /*
670 * A single char.
671 * If it is one of the variables that should only appear in
672 * local scope, skip it, else we can get Var_Subst
673 * into a loop.
674 */
675 switch (name[0]) {
676 case '@':
677 case '%':
678 case '*':
679 case '!':
680 return false;
681 }
682 }
683 return true;
684 }
685
686 static bool
687 ExportVarEnv(Var *v, GNode *scope)
688 {
689 const char *name = v->name.str;
690 char *val = v->val.data;
691 char *expr;
692
693 if (v->exported && !v->reexport)
694 return false; /* nothing to do */
695
696 if (strchr(val, '$') == NULL) {
697 if (!v->exported)
698 setenv(name, val, 1);
699 return true;
700 }
701
702 if (v->inUse)
703 return false; /* see EMPTY_SHELL in directive-export.mk */
704
705 /* XXX: name is injected without escaping it */
706 expr = str_concat3("${", name, "}");
707 val = Var_Subst(expr, scope, VARE_EVAL);
708 if (scope != SCOPE_GLOBAL) {
709 /* we will need to re-export the global version */
710 v = VarFind(name, SCOPE_GLOBAL, false);
711 if (v != NULL)
712 v->exported = false;
713 }
714 /* TODO: handle errors */
715 setenv(name, val, 1);
716 free(val);
717 free(expr);
718 return true;
719 }
720
721 static bool
722 ExportVarPlain(Var *v)
723 {
724 if (strchr(v->val.data, '$') == NULL) {
725 setenv(v->name.str, v->val.data, 1);
726 v->exported = true;
727 v->reexport = false;
728 return true;
729 }
730
731 /*
732 * Flag the variable as something we need to re-export.
733 * No point actually exporting it now though,
734 * the child process can do it at the last minute.
735 * Avoid calling setenv more often than necessary since it can leak.
736 */
737 v->exported = true;
738 v->reexport = true;
739 return true;
740 }
741
742 static bool
743 ExportVarLiteral(Var *v)
744 {
745 if (v->exported && !v->reexport)
746 return false;
747
748 if (!v->exported)
749 setenv(v->name.str, v->val.data, 1);
750
751 return true;
752 }
753
754 /*
755 * Mark a single variable to be exported later for subprocesses.
756 *
757 * Internal variables are not exported.
758 */
759 static bool
760 ExportVar(const char *name, GNode *scope, VarExportMode mode)
761 {
762 Var *v;
763
764 if (!MayExport(name))
765 return false;
766
767 v = VarFind(name, scope, false);
768 if (v == NULL && scope != SCOPE_GLOBAL)
769 v = VarFind(name, SCOPE_GLOBAL, false);
770 if (v == NULL)
771 return false;
772
773 if (mode == VEM_ENV)
774 return ExportVarEnv(v, scope);
775 else if (mode == VEM_PLAIN)
776 return ExportVarPlain(v);
777 else
778 return ExportVarLiteral(v);
779 }
780
781 /*
782 * Actually export the variables that have been marked as needing to be
783 * re-exported.
784 */
785 void
786 Var_ReexportVars(GNode *scope)
787 {
788 char *xvarnames;
789
790 /*
791 * Several make implementations support this sort of mechanism for
792 * tracking recursion - but each uses a different name.
793 * We allow the makefiles to update MAKELEVEL and ensure
794 * children see a correctly incremented value.
795 */
796 char level_buf[21];
797 snprintf(level_buf, sizeof level_buf, "%d", makelevel + 1);
798 setenv(MAKE_LEVEL_ENV, level_buf, 1);
799
800 if (var_exportedVars == VAR_EXPORTED_NONE)
801 return;
802
803 if (var_exportedVars == VAR_EXPORTED_ALL) {
804 HashIter hi;
805
806 /* Ouch! Exporting all variables at once is crazy. */
807 HashIter_Init(&hi, &SCOPE_GLOBAL->vars);
808 while (HashIter_Next(&hi)) {
809 Var *var = hi.entry->value;
810 ExportVar(var->name.str, scope, VEM_ENV);
811 }
812 return;
813 }
814
815 xvarnames = Var_Subst("${.MAKE.EXPORTED:O:u}", SCOPE_GLOBAL,
816 VARE_EVAL);
817 /* TODO: handle errors */
818 if (xvarnames[0] != '\0') {
819 Words varnames = Str_Words(xvarnames, false);
820 size_t i;
821
822 for (i = 0; i < varnames.len; i++)
823 ExportVar(varnames.words[i], scope, VEM_ENV);
824 Words_Free(varnames);
825 }
826 free(xvarnames);
827 }
828
829 static void
830 ExportVars(const char *varnames, bool isExport, VarExportMode mode)
831 /* TODO: try to combine the parameters 'isExport' and 'mode'. */
832 {
833 Words words = Str_Words(varnames, false);
834 size_t i;
835
836 if (words.len == 1 && words.words[0][0] == '\0')
837 words.len = 0;
838
839 for (i = 0; i < words.len; i++) {
840 const char *varname = words.words[i];
841 if (!ExportVar(varname, SCOPE_GLOBAL, mode))
842 continue;
843
844 if (var_exportedVars == VAR_EXPORTED_NONE)
845 var_exportedVars = VAR_EXPORTED_SOME;
846
847 if (isExport && mode == VEM_PLAIN)
848 Global_Append(".MAKE.EXPORTED", varname);
849 }
850 Words_Free(words);
851 }
852
853 static void
854 ExportVarsExpand(const char *uvarnames, bool isExport, VarExportMode mode)
855 {
856 char *xvarnames = Var_Subst(uvarnames, SCOPE_GLOBAL, VARE_EVAL);
857 /* TODO: handle errors */
858 ExportVars(xvarnames, isExport, mode);
859 free(xvarnames);
860 }
861
862 /* Export the named variables, or all variables. */
863 void
864 Var_Export(VarExportMode mode, const char *varnames)
865 {
866 if (mode == VEM_ALL) {
867 var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
868 return;
869 } else if (mode == VEM_PLAIN && varnames[0] == '\0') {
870 Parse_Error(PARSE_WARNING, ".export requires an argument.");
871 return;
872 }
873
874 ExportVarsExpand(varnames, true, mode);
875 }
876
877 void
878 Var_ExportVars(const char *varnames)
879 {
880 ExportVarsExpand(varnames, false, VEM_PLAIN);
881 }
882
883
884 static void
885 ClearEnv(void)
886 {
887 const char *level;
888 char **newenv;
889
890 level = getenv(MAKE_LEVEL_ENV); /* we should preserve this */
891 if (environ == savedEnv) {
892 /* we have been here before! */
893 newenv = bmake_realloc(environ, 2 * sizeof(char *));
894 } else {
895 if (savedEnv != NULL) {
896 free(savedEnv);
897 savedEnv = NULL;
898 }
899 newenv = bmake_malloc(2 * sizeof(char *));
900 }
901
902 /* Note: we cannot safely free() the original environ. */
903 environ = savedEnv = newenv;
904 newenv[0] = NULL;
905 newenv[1] = NULL;
906 if (level != NULL && *level != '\0')
907 setenv(MAKE_LEVEL_ENV, level, 1);
908 }
909
910 static void
911 GetVarnamesToUnexport(bool isEnv, const char *arg,
912 FStr *out_varnames, UnexportWhat *out_what)
913 {
914 UnexportWhat what;
915 FStr varnames = FStr_InitRefer("");
916
917 if (isEnv) {
918 if (arg[0] != '\0') {
919 Parse_Error(PARSE_FATAL,
920 "The directive .unexport-env does not take "
921 "arguments");
922 /* continue anyway */
923 }
924 what = UNEXPORT_ENV;
925
926 } else {
927 what = arg[0] != '\0' ? UNEXPORT_NAMED : UNEXPORT_ALL;
928 if (what == UNEXPORT_NAMED)
929 varnames = FStr_InitRefer(arg);
930 }
931
932 if (what != UNEXPORT_NAMED) {
933 char *expanded = Var_Subst("${.MAKE.EXPORTED:O:u}",
934 SCOPE_GLOBAL, VARE_EVAL);
935 /* TODO: handle errors */
936 varnames = FStr_InitOwn(expanded);
937 }
938
939 *out_varnames = varnames;
940 *out_what = what;
941 }
942
943 static void
944 UnexportVar(Substring varname, UnexportWhat what)
945 {
946 Var *v = VarFindSubstring(varname, SCOPE_GLOBAL, false);
947 if (v == NULL) {
948 DEBUG2(VAR, "Not unexporting \"%.*s\" (not found)\n",
949 (int)Substring_Length(varname), varname.start);
950 return;
951 }
952
953 DEBUG2(VAR, "Unexporting \"%.*s\"\n",
954 (int)Substring_Length(varname), varname.start);
955 if (what != UNEXPORT_ENV && v->exported && !v->reexport)
956 unsetenv(v->name.str);
957 v->exported = false;
958 v->reexport = false;
959
960 if (what == UNEXPORT_NAMED) {
961 /* Remove the variable names from .MAKE.EXPORTED. */
962 /* XXX: v->name is injected without escaping it */
963 char *expr = str_concat3(
964 "${.MAKE.EXPORTED:N", v->name.str, "}");
965 char *filtered = Var_Subst(expr, SCOPE_GLOBAL, VARE_EVAL);
966 /* TODO: handle errors */
967 Global_Set(".MAKE.EXPORTED", filtered);
968 free(filtered);
969 free(expr);
970 }
971 }
972
973 static void
974 UnexportVars(FStr *varnames, UnexportWhat what)
975 {
976 size_t i;
977 SubstringWords words;
978
979 if (what == UNEXPORT_ENV)
980 ClearEnv();
981
982 words = Substring_Words(varnames->str, false);
983 for (i = 0; i < words.len; i++)
984 UnexportVar(words.words[i], what);
985 SubstringWords_Free(words);
986
987 if (what != UNEXPORT_NAMED)
988 Global_Delete(".MAKE.EXPORTED");
989 }
990
991 /* Handle the .unexport and .unexport-env directives. */
992 void
993 Var_UnExport(bool isEnv, const char *arg)
994 {
995 UnexportWhat what;
996 FStr varnames;
997
998 GetVarnamesToUnexport(isEnv, arg, &varnames, &what);
999 UnexportVars(&varnames, what);
1000 FStr_Done(&varnames);
1001 }
1002
1003 /* Set the variable to the value; the name is not expanded. */
1004 void
1005 Var_SetWithFlags(GNode *scope, const char *name, const char *val,
1006 VarSetFlags flags)
1007 {
1008 Var *v;
1009
1010 assert(val != NULL);
1011 if (name[0] == '\0') {
1012 DEBUG3(VAR,
1013 "%s: ignoring '%s = %s' as the variable name is empty\n",
1014 scope->name, name, val);
1015 return;
1016 }
1017
1018 if (scope == SCOPE_GLOBAL
1019 && VarFind(name, SCOPE_CMDLINE, false) != NULL) {
1020 /*
1021 * The global variable would not be visible anywhere.
1022 * Therefore, there is no point in setting it at all.
1023 */
1024 DEBUG3(VAR,
1025 "%s: ignoring '%s = %s' "
1026 "due to a command line variable of the same name\n",
1027 scope->name, name, val);
1028 return;
1029 }
1030
1031 /*
1032 * Only look for a variable in the given scope since anything set
1033 * here will override anything in a lower scope, so there's not much
1034 * point in searching them all.
1035 */
1036 v = VarFind(name, scope, false);
1037 if (v == NULL) {
1038 if (scope == SCOPE_CMDLINE && !(flags & VAR_SET_NO_EXPORT)) {
1039 /*
1040 * This variable would normally prevent the same name
1041 * being added to SCOPE_GLOBAL, so delete it from
1042 * there if needed. Otherwise -V name may show the
1043 * wrong value.
1044 *
1045 * See ExistsInCmdline.
1046 */
1047 Var_Delete(SCOPE_GLOBAL, name);
1048 }
1049 if (strcmp(name, ".SUFFIXES") == 0) {
1050 /* special: treat as read-only */
1051 DEBUG3(VAR,
1052 "%s: ignoring '%s = %s' as it is read-only\n",
1053 scope->name, name, val);
1054 return;
1055 }
1056 v = VarAdd(name, val, scope, flags);
1057 } else {
1058 if (v->readOnlyLoud) {
1059 Parse_Error(PARSE_FATAL,
1060 "Cannot overwrite \"%s\" as it is read-only",
1061 name);
1062 return;
1063 }
1064 if (v->readOnly && !(flags & VAR_SET_READONLY)) {
1065 DEBUG3(VAR,
1066 "%s: ignoring '%s = %s' as it is read-only\n",
1067 scope->name, name, val);
1068 return;
1069 }
1070 Buf_Clear(&v->val);
1071 Buf_AddStr(&v->val, val);
1072
1073 DEBUG4(VAR, "%s: %s = %s%s\n",
1074 scope->name, name, val, ValueDescription(val));
1075 if (v->exported)
1076 ExportVar(name, scope, VEM_PLAIN);
1077 }
1078
1079 if (scope == SCOPE_CMDLINE) {
1080 v->fromCmd = true;
1081
1082 /*
1083 * Any variables given on the command line are automatically
1084 * exported to the environment (as per POSIX standard), except
1085 * for internals.
1086 */
1087 if (!(flags & VAR_SET_NO_EXPORT)) {
1088
1089 /*
1090 * If requested, don't export these in the
1091 * environment individually. We still put
1092 * them in .MAKEOVERRIDES so that the
1093 * command-line settings continue to override
1094 * Makefile settings.
1095 */
1096 if (!opts.varNoExportEnv && name[0] != '.')
1097 setenv(name, val, 1);
1098
1099 if (!(flags & VAR_SET_INTERNAL))
1100 Global_Append(".MAKEOVERRIDES", name);
1101 }
1102 }
1103
1104 if (name[0] == '.' && strcmp(name, MAKE_SAVE_DOLLARS) == 0)
1105 save_dollars = ParseBoolean(val, save_dollars);
1106
1107 if (v != NULL)
1108 VarFreeShortLived(v);
1109 }
1110
1111 void
1112 Var_Set(GNode *scope, const char *name, const char *val)
1113 {
1114 Var_SetWithFlags(scope, name, val, VAR_SET_NONE);
1115 }
1116
1117 /*
1118 * In the scope, expand the variable name once, then create the variable or
1119 * replace its value.
1120 */
1121 void
1122 Var_SetExpand(GNode *scope, const char *name, const char *val)
1123 {
1124 FStr varname = FStr_InitRefer(name);
1125
1126 assert(val != NULL);
1127
1128 Var_Expand(&varname, scope, VARE_EVAL);
1129
1130 if (varname.str[0] == '\0') {
1131 DEBUG4(VAR,
1132 "%s: ignoring '%s = %s' "
1133 "as the variable name '%s' expands to empty\n",
1134 scope->name, varname.str, val, name);
1135 } else
1136 Var_SetWithFlags(scope, varname.str, val, VAR_SET_NONE);
1137
1138 FStr_Done(&varname);
1139 }
1140
1141 void
1142 Global_Set(const char *name, const char *value)
1143 {
1144 Var_Set(SCOPE_GLOBAL, name, value);
1145 }
1146
1147 void
1148 Global_Delete(const char *name)
1149 {
1150 Var_Delete(SCOPE_GLOBAL, name);
1151 }
1152
1153 void
1154 Global_Set_ReadOnly(const char *name, const char *value)
1155 {
1156 Var_SetWithFlags(SCOPE_GLOBAL, name, value, VAR_SET_NONE);
1157 VarFind(name, SCOPE_GLOBAL, false)->readOnlyLoud = true;
1158 }
1159
1160 /*
1161 * Append the value to the named variable.
1162 *
1163 * If the variable doesn't exist, it is created. Otherwise a single space
1164 * and the given value are appended.
1165 */
1166 void
1167 Var_Append(GNode *scope, const char *name, const char *val)
1168 {
1169 Var *v;
1170
1171 v = VarFind(name, scope, scope == SCOPE_GLOBAL);
1172
1173 if (v == NULL) {
1174 Var_SetWithFlags(scope, name, val, VAR_SET_NONE);
1175 } else if (v->readOnlyLoud) {
1176 Parse_Error(PARSE_FATAL,
1177 "Cannot append to \"%s\" as it is read-only", name);
1178 return;
1179 } else if (v->readOnly) {
1180 DEBUG3(VAR, "%s: ignoring '%s += %s' as it is read-only\n",
1181 scope->name, name, val);
1182 } else if (scope == SCOPE_CMDLINE || !v->fromCmd) {
1183 Buf_AddByte(&v->val, ' ');
1184 Buf_AddStr(&v->val, val);
1185
1186 DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, v->val.data);
1187
1188 if (v->fromEnvironment) {
1189 /* See VarAdd. */
1190 HashEntry *he =
1191 HashTable_CreateEntry(&scope->vars, name, NULL);
1192 HashEntry_Set(he, v);
1193 FStr_Done(&v->name);
1194 v->name = FStr_InitRefer(/* aliased to */ he->key);
1195 v->shortLived = false;
1196 v->fromEnvironment = false;
1197 }
1198 }
1199 }
1200
1201 /*
1202 * In the scope, expand the variable name once. If the variable exists in the
1203 * scope, add a space and the value, otherwise set the variable to the value.
1204 *
1205 * Appending to an environment variable only works in the global scope, that
1206 * is, for variable assignments in makefiles, but not inside conditions or the
1207 * commands of a target.
1208 */
1209 void
1210 Var_AppendExpand(GNode *scope, const char *name, const char *val)
1211 {
1212 FStr xname = FStr_InitRefer(name);
1213
1214 assert(val != NULL);
1215
1216 Var_Expand(&xname, scope, VARE_EVAL);
1217 if (xname.str != name && xname.str[0] == '\0')
1218 DEBUG4(VAR,
1219 "%s: ignoring '%s += %s' "
1220 "as the variable name '%s' expands to empty\n",
1221 scope->name, xname.str, val, name);
1222 else
1223 Var_Append(scope, xname.str, val);
1224
1225 FStr_Done(&xname);
1226 }
1227
1228 void
1229 Global_Append(const char *name, const char *value)
1230 {
1231 Var_Append(SCOPE_GLOBAL, name, value);
1232 }
1233
1234 bool
1235 Var_Exists(GNode *scope, const char *name)
1236 {
1237 Var *v = VarFind(name, scope, true);
1238 if (v == NULL)
1239 return false;
1240
1241 VarFreeShortLived(v);
1242 return true;
1243 }
1244
1245 /*
1246 * See if the given variable exists, in the given scope or in other
1247 * fallback scopes.
1248 *
1249 * Input:
1250 * scope scope in which to start search
1251 * name name of the variable to find, is expanded once
1252 */
1253 bool
1254 Var_ExistsExpand(GNode *scope, const char *name)
1255 {
1256 FStr varname = FStr_InitRefer(name);
1257 bool exists;
1258
1259 Var_Expand(&varname, scope, VARE_EVAL);
1260 exists = Var_Exists(scope, varname.str);
1261 FStr_Done(&varname);
1262 return exists;
1263 }
1264
1265 /*
1266 * Return the unexpanded value of the given variable in the given scope,
1267 * falling back to the command, global and environment scopes, in this order,
1268 * but see the -e option.
1269 *
1270 * Input:
1271 * name the name to find, is not expanded any further
1272 *
1273 * Results:
1274 * The value if the variable exists, NULL if it doesn't.
1275 * The value is valid until the next modification to any variable.
1276 */
1277 FStr
1278 Var_Value(GNode *scope, const char *name)
1279 {
1280 Var *v = VarFind(name, scope, true);
1281 char *value;
1282
1283 if (v == NULL)
1284 return FStr_InitRefer(NULL);
1285
1286 if (!v->shortLived)
1287 return FStr_InitRefer(v->val.data);
1288
1289 value = v->val.data;
1290 v->val.data = NULL;
1291 VarFreeShortLived(v);
1292
1293 return FStr_InitOwn(value);
1294 }
1295
1296 /* Set or clear the read-only attribute of the variable if it exists. */
1297 void
1298 Var_ReadOnly(const char *name, bool bf)
1299 {
1300 Var *v;
1301
1302 v = VarFind(name, SCOPE_GLOBAL, false);
1303 if (v == NULL) {
1304 DEBUG1(VAR, "Var_ReadOnly: %s not found\n", name);
1305 return;
1306 }
1307 v->readOnly = bf;
1308 DEBUG2(VAR, "Var_ReadOnly: %s %s\n", name, bf ? "true" : "false");
1309 }
1310
1311 /*
1312 * Return the unexpanded variable value from this node, without trying to look
1313 * up the variable in any other scope.
1314 */
1315 const char *
1316 GNode_ValueDirect(GNode *gn, const char *name)
1317 {
1318 Var *v = VarFind(name, gn, false);
1319 return v != NULL ? v->val.data : NULL;
1320 }
1321
1322 static VarEvalMode
1323 VarEvalMode_WithoutKeepDollar(VarEvalMode emode)
1324 {
1325 return emode == VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED
1326 ? VARE_EVAL_KEEP_UNDEFINED : emode;
1327 }
1328
1329 static VarEvalMode
1330 VarEvalMode_UndefOk(VarEvalMode emode)
1331 {
1332 return emode == VARE_EVAL_DEFINED ? VARE_EVAL : emode;
1333 }
1334
1335 static bool
1336 VarEvalMode_ShouldEval(VarEvalMode emode)
1337 {
1338 return emode != VARE_PARSE;
1339 }
1340
1341 static bool
1342 VarEvalMode_ShouldKeepUndef(VarEvalMode emode)
1343 {
1344 return emode == VARE_EVAL_KEEP_UNDEFINED ||
1345 emode == VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED;
1346 }
1347
1348 static bool
1349 VarEvalMode_ShouldKeepDollar(VarEvalMode emode)
1350 {
1351 return emode == VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED;
1352 }
1353
1354
1355 static void
1356 SepBuf_Init(SepBuf *buf, char sep)
1357 {
1358 Buf_InitSize(&buf->buf, 32);
1359 buf->needSep = false;
1360 buf->sep = sep;
1361 }
1362
1363 static void
1364 SepBuf_Sep(SepBuf *buf)
1365 {
1366 buf->needSep = true;
1367 }
1368
1369 static void
1370 SepBuf_AddBytes(SepBuf *buf, const char *mem, size_t mem_size)
1371 {
1372 if (mem_size == 0)
1373 return;
1374 if (buf->needSep && buf->sep != '\0') {
1375 Buf_AddByte(&buf->buf, buf->sep);
1376 buf->needSep = false;
1377 }
1378 Buf_AddBytes(&buf->buf, mem, mem_size);
1379 }
1380
1381 static void
1382 SepBuf_AddRange(SepBuf *buf, const char *start, const char *end)
1383 {
1384 SepBuf_AddBytes(buf, start, (size_t)(end - start));
1385 }
1386
1387 static void
1388 SepBuf_AddStr(SepBuf *buf, const char *str)
1389 {
1390 SepBuf_AddBytes(buf, str, strlen(str));
1391 }
1392
1393 static void
1394 SepBuf_AddSubstring(SepBuf *buf, Substring sub)
1395 {
1396 SepBuf_AddRange(buf, sub.start, sub.end);
1397 }
1398
1399 static char *
1400 SepBuf_DoneData(SepBuf *buf)
1401 {
1402 return Buf_DoneData(&buf->buf);
1403 }
1404
1405
1406 /*
1407 * This callback for ModifyWords gets a single word from an expression
1408 * and typically adds a modification of this word to the buffer. It may also
1409 * do nothing or add several words.
1410 *
1411 * For example, when evaluating the modifier ':M*b' in ${:Ua b c:M*b}, the
1412 * callback is called 3 times, once for "a", "b" and "c".
1413 *
1414 * Some ModifyWord functions assume that they are always passed a
1415 * null-terminated substring, which is currently guaranteed but may change in
1416 * the future.
1417 */
1418 typedef void (*ModifyWordProc)(Substring word, SepBuf *buf, void *data);
1419
1420
1421 static void
1422 ModifyWord_Head(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1423 {
1424 SepBuf_AddSubstring(buf, Substring_Dirname(word));
1425 }
1426
1427 static void
1428 ModifyWord_Tail(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1429 {
1430 SepBuf_AddSubstring(buf, Substring_Basename(word));
1431 }
1432
1433 static void
1434 ModifyWord_Suffix(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1435 {
1436 const char *lastDot = Substring_FindLast(word, '.');
1437 if (lastDot != NULL)
1438 SepBuf_AddRange(buf, lastDot + 1, word.end);
1439 }
1440
1441 static void
1442 ModifyWord_Root(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1443 {
1444 const char *lastDot, *end;
1445
1446 lastDot = Substring_FindLast(word, '.');
1447 end = lastDot != NULL ? lastDot : word.end;
1448 SepBuf_AddRange(buf, word.start, end);
1449 }
1450
1451 struct ModifyWord_SysVSubstArgs {
1452 GNode *scope;
1453 Substring lhsPrefix;
1454 bool lhsPercent;
1455 Substring lhsSuffix;
1456 const char *rhs;
1457 };
1458
1459 static void
1460 ModifyWord_SysVSubst(Substring word, SepBuf *buf, void *data)
1461 {
1462 const struct ModifyWord_SysVSubstArgs *args = data;
1463 FStr rhs;
1464 const char *percent;
1465
1466 if (Substring_IsEmpty(word))
1467 return;
1468
1469 if (!Substring_HasPrefix(word, args->lhsPrefix) ||
1470 !Substring_HasSuffix(word, args->lhsSuffix)) {
1471 SepBuf_AddSubstring(buf, word);
1472 return;
1473 }
1474
1475 rhs = FStr_InitRefer(args->rhs);
1476 Var_Expand(&rhs, args->scope, VARE_EVAL);
1477
1478 percent = args->lhsPercent ? strchr(rhs.str, '%') : NULL;
1479
1480 if (percent != NULL)
1481 SepBuf_AddRange(buf, rhs.str, percent);
1482 if (percent != NULL || !args->lhsPercent)
1483 SepBuf_AddRange(buf,
1484 word.start + Substring_Length(args->lhsPrefix),
1485 word.end - Substring_Length(args->lhsSuffix));
1486 SepBuf_AddStr(buf, percent != NULL ? percent + 1 : rhs.str);
1487
1488 FStr_Done(&rhs);
1489 }
1490
1491 static const char *
1492 Substring_Find(Substring haystack, Substring needle)
1493 {
1494 size_t len, needleLen, i;
1495
1496 len = Substring_Length(haystack);
1497 needleLen = Substring_Length(needle);
1498 for (i = 0; i + needleLen <= len; i++)
1499 if (memcmp(haystack.start + i, needle.start, needleLen) == 0)
1500 return haystack.start + i;
1501 return NULL;
1502 }
1503
1504 struct ModifyWord_SubstArgs {
1505 Substring lhs;
1506 Substring rhs;
1507 PatternFlags pflags;
1508 bool matched;
1509 };
1510
1511 static void
1512 ModifyWord_Subst(Substring word, SepBuf *buf, void *data)
1513 {
1514 struct ModifyWord_SubstArgs *args = data;
1515 size_t wordLen, lhsLen;
1516 const char *match;
1517
1518 wordLen = Substring_Length(word);
1519 if (args->pflags.subOnce && args->matched)
1520 goto nosub;
1521
1522 lhsLen = Substring_Length(args->lhs);
1523 if (args->pflags.anchorStart) {
1524 if (wordLen < lhsLen ||
1525 memcmp(word.start, args->lhs.start, lhsLen) != 0)
1526 goto nosub;
1527
1528 if (args->pflags.anchorEnd && wordLen != lhsLen)
1529 goto nosub;
1530
1531 /* :S,^prefix,replacement, or :S,^whole$,replacement, */
1532 SepBuf_AddSubstring(buf, args->rhs);
1533 SepBuf_AddRange(buf, word.start + lhsLen, word.end);
1534 args->matched = true;
1535 return;
1536 }
1537
1538 if (args->pflags.anchorEnd) {
1539 if (wordLen < lhsLen)
1540 goto nosub;
1541 if (memcmp(word.end - lhsLen, args->lhs.start, lhsLen) != 0)
1542 goto nosub;
1543
1544 /* :S,suffix$,replacement, */
1545 SepBuf_AddRange(buf, word.start, word.end - lhsLen);
1546 SepBuf_AddSubstring(buf, args->rhs);
1547 args->matched = true;
1548 return;
1549 }
1550
1551 if (Substring_IsEmpty(args->lhs))
1552 goto nosub;
1553
1554 /* unanchored case, may match more than once */
1555 while ((match = Substring_Find(word, args->lhs)) != NULL) {
1556 SepBuf_AddRange(buf, word.start, match);
1557 SepBuf_AddSubstring(buf, args->rhs);
1558 args->matched = true;
1559 word.start = match + lhsLen;
1560 if (Substring_IsEmpty(word) || !args->pflags.subGlobal)
1561 break;
1562 }
1563 nosub:
1564 SepBuf_AddSubstring(buf, word);
1565 }
1566
1567 /* Print the error caused by a regcomp or regexec call. */
1568 static void
1569 RegexError(int reerr, const regex_t *pat, const char *str)
1570 {
1571 size_t errlen = regerror(reerr, pat, NULL, 0);
1572 char *errbuf = bmake_malloc(errlen);
1573 regerror(reerr, pat, errbuf, errlen);
1574 Parse_Error(PARSE_FATAL, "%s: %s", str, errbuf);
1575 free(errbuf);
1576 }
1577
1578 /* In the modifier ':C', replace a backreference from \0 to \9. */
1579 static void
1580 RegexReplaceBackref(char ref, SepBuf *buf, const char *wp,
1581 const regmatch_t *m, size_t nsub)
1582 {
1583 unsigned int n = (unsigned)ref - '0';
1584
1585 if (n >= nsub)
1586 Parse_Error(PARSE_FATAL, "No subexpression \\%u", n);
1587 else if (m[n].rm_so == -1) {
1588 if (opts.strict)
1589 Error("No match for subexpression \\%u", n);
1590 } else {
1591 SepBuf_AddRange(buf,
1592 wp + (size_t)m[n].rm_so,
1593 wp + (size_t)m[n].rm_eo);
1594 }
1595 }
1596
1597 /*
1598 * The regular expression matches the word; now add the replacement to the
1599 * buffer, taking back-references from 'wp'.
1600 */
1601 static void
1602 RegexReplace(Substring replace, SepBuf *buf, const char *wp,
1603 const regmatch_t *m, size_t nsub)
1604 {
1605 const char *rp;
1606
1607 for (rp = replace.start; rp != replace.end; rp++) {
1608 if (*rp == '\\' && rp + 1 != replace.end &&
1609 (rp[1] == '&' || rp[1] == '\\'))
1610 SepBuf_AddBytes(buf, ++rp, 1);
1611 else if (*rp == '\\' && rp + 1 != replace.end &&
1612 ch_isdigit(rp[1]))
1613 RegexReplaceBackref(*++rp, buf, wp, m, nsub);
1614 else if (*rp == '&') {
1615 SepBuf_AddRange(buf,
1616 wp + (size_t)m[0].rm_so,
1617 wp + (size_t)m[0].rm_eo);
1618 } else
1619 SepBuf_AddBytes(buf, rp, 1);
1620 }
1621 }
1622
1623 struct ModifyWord_SubstRegexArgs {
1624 regex_t re;
1625 size_t nsub;
1626 Substring replace;
1627 PatternFlags pflags;
1628 bool matched;
1629 };
1630
1631 static void
1632 ModifyWord_SubstRegex(Substring word, SepBuf *buf, void *data)
1633 {
1634 struct ModifyWord_SubstRegexArgs *args = data;
1635 int xrv;
1636 const char *wp;
1637 int flags = 0;
1638 regmatch_t m[10];
1639
1640 assert(word.end[0] == '\0'); /* assume null-terminated word */
1641 wp = word.start;
1642 if (args->pflags.subOnce && args->matched)
1643 goto no_match;
1644
1645 again:
1646 xrv = regexec(&args->re, wp, args->nsub, m, flags);
1647 if (xrv == 0)
1648 goto ok;
1649 if (xrv != REG_NOMATCH)
1650 RegexError(xrv, &args->re, "Unexpected regex error");
1651 no_match:
1652 SepBuf_AddRange(buf, wp, word.end);
1653 return;
1654
1655 ok:
1656 args->matched = true;
1657 SepBuf_AddBytes(buf, wp, (size_t)m[0].rm_so);
1658
1659 RegexReplace(args->replace, buf, wp, m, args->nsub);
1660
1661 wp += (size_t)m[0].rm_eo;
1662 if (args->pflags.subGlobal) {
1663 flags |= REG_NOTBOL;
1664 if (m[0].rm_so == 0 && m[0].rm_eo == 0 && *wp != '\0') {
1665 SepBuf_AddBytes(buf, wp, 1);
1666 wp++;
1667 }
1668 if (*wp != '\0')
1669 goto again;
1670 }
1671 if (*wp != '\0')
1672 SepBuf_AddStr(buf, wp);
1673 }
1674
1675
1676 struct ModifyWord_LoopArgs {
1677 GNode *scope;
1678 const char *var; /* name of the temporary variable */
1679 const char *body; /* string to expand */
1680 VarEvalMode emode;
1681 };
1682
1683 static void
1684 ModifyWord_Loop(Substring word, SepBuf *buf, void *data)
1685 {
1686 const struct ModifyWord_LoopArgs *args;
1687 char *s;
1688
1689 if (Substring_IsEmpty(word))
1690 return;
1691
1692 args = data;
1693 assert(word.end[0] == '\0'); /* assume null-terminated word */
1694 Var_SetWithFlags(args->scope, args->var, word.start,
1695 VAR_SET_NO_EXPORT);
1696 s = Var_Subst(args->body, args->scope, args->emode);
1697 /* TODO: handle errors */
1698
1699 DEBUG2(VAR, "ModifyWord_Loop: expand \"%s\" to \"%s\"\n",
1700 args->body, s);
1701
1702 if (s[0] == '\n' || Buf_EndsWith(&buf->buf, '\n'))
1703 buf->needSep = false;
1704 SepBuf_AddStr(buf, s);
1705 free(s);
1706 }
1707
1708
1709 /*
1710 * The :[first..last] modifier selects words from the expression.
1711 * It can also reverse the words.
1712 */
1713 static char *
1714 VarSelectWords(const char *str, int first, int last,
1715 char sep, bool oneBigWord)
1716 {
1717 SubstringWords words;
1718 int len, start, end, step;
1719 int i;
1720
1721 SepBuf buf;
1722 SepBuf_Init(&buf, sep);
1723
1724 if (oneBigWord) {
1725 /* fake what Substring_Words() would do */
1726 words.len = 1;
1727 words.words = bmake_malloc(sizeof(words.words[0]));
1728 words.freeIt = NULL;
1729 words.words[0] = Substring_InitStr(str); /* no need to copy */
1730 } else {
1731 words = Substring_Words(str, false);
1732 }
1733
1734 /* Convert -1 to len, -2 to (len - 1), etc. */
1735 len = (int)words.len;
1736 if (first < 0)
1737 first += len + 1;
1738 if (last < 0)
1739 last += len + 1;
1740
1741 if (first > last) {
1742 start = (first > len ? len : first) - 1;
1743 end = last < 1 ? 0 : last - 1;
1744 step = -1;
1745 } else {
1746 start = first < 1 ? 0 : first - 1;
1747 end = last > len ? len : last;
1748 step = 1;
1749 }
1750
1751 for (i = start; (step < 0) == (i >= end); i += step) {
1752 SepBuf_AddSubstring(&buf, words.words[i]);
1753 SepBuf_Sep(&buf);
1754 }
1755
1756 SubstringWords_Free(words);
1757
1758 return SepBuf_DoneData(&buf);
1759 }
1760
1761
1762 static void
1763 ModifyWord_Realpath(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
1764 {
1765 struct stat st;
1766 char rbuf[MAXPATHLEN];
1767 const char *rp;
1768
1769 assert(word.end[0] == '\0'); /* assume null-terminated word */
1770 rp = cached_realpath(word.start, rbuf);
1771 if (rp != NULL && *rp == '/' && stat(rp, &st) == 0)
1772 SepBuf_AddStr(buf, rp);
1773 else
1774 SepBuf_AddSubstring(buf, word);
1775 }
1776
1777
1778 static char *
1779 SubstringWords_JoinFree(SubstringWords words)
1780 {
1781 Buffer buf;
1782 size_t i;
1783
1784 Buf_Init(&buf);
1785
1786 for (i = 0; i < words.len; i++) {
1787 if (i != 0) {
1788 /*
1789 * XXX: Use ch->sep instead of ' ', for consistency.
1790 */
1791 Buf_AddByte(&buf, ' ');
1792 }
1793 Buf_AddRange(&buf, words.words[i].start, words.words[i].end);
1794 }
1795
1796 SubstringWords_Free(words);
1797
1798 return Buf_DoneData(&buf);
1799 }
1800
1801
1802 /*
1803 * Quote shell meta-characters and space characters in the string.
1804 * If quoteDollar is set, also quote and double any '$' characters.
1805 */
1806 static void
1807 QuoteShell(const char *str, bool quoteDollar, LazyBuf *buf)
1808 {
1809 const char *p;
1810
1811 LazyBuf_Init(buf, str);
1812 for (p = str; *p != '\0'; p++) {
1813 if (*p == '\n') {
1814 const char *newline = Shell_GetNewline();
1815 if (newline == NULL)
1816 newline = "\\\n";
1817 LazyBuf_AddStr(buf, newline);
1818 continue;
1819 }
1820 if (ch_isspace(*p) || ch_is_shell_meta(*p))
1821 LazyBuf_Add(buf, '\\');
1822 LazyBuf_Add(buf, *p);
1823 if (quoteDollar && *p == '$')
1824 LazyBuf_AddStr(buf, "\\$");
1825 }
1826 }
1827
1828 /*
1829 * Compute the 32-bit hash of the given string, using the MurmurHash3
1830 * algorithm. Output is encoded as 8 hex digits, in Little Endian order.
1831 */
1832 static char *
1833 Hash(const char *str)
1834 {
1835 static const char hexdigits[16] = "0123456789abcdef";
1836 const unsigned char *ustr = (const unsigned char *)str;
1837
1838 uint32_t h = 0x971e137bU;
1839 uint32_t c1 = 0x95543787U;
1840 uint32_t c2 = 0x2ad7eb25U;
1841 size_t len2 = strlen(str);
1842
1843 char *buf;
1844 size_t i;
1845
1846 size_t len;
1847 for (len = len2; len != 0;) {
1848 uint32_t k = 0;
1849 switch (len) {
1850 default:
1851 k = ((uint32_t)ustr[3] << 24) |
1852 ((uint32_t)ustr[2] << 16) |
1853 ((uint32_t)ustr[1] << 8) |
1854 (uint32_t)ustr[0];
1855 len -= 4;
1856 ustr += 4;
1857 break;
1858 case 3:
1859 k |= (uint32_t)ustr[2] << 16;
1860 /* FALLTHROUGH */
1861 case 2:
1862 k |= (uint32_t)ustr[1] << 8;
1863 /* FALLTHROUGH */
1864 case 1:
1865 k |= (uint32_t)ustr[0];
1866 len = 0;
1867 }
1868 c1 = c1 * 5 + 0x7b7d159cU;
1869 c2 = c2 * 5 + 0x6bce6396U;
1870 k *= c1;
1871 k = (k << 11) ^ (k >> 21);
1872 k *= c2;
1873 h = (h << 13) ^ (h >> 19);
1874 h = h * 5 + 0x52dce729U;
1875 h ^= k;
1876 }
1877 h ^= (uint32_t)len2;
1878 h *= 0x85ebca6b;
1879 h ^= h >> 13;
1880 h *= 0xc2b2ae35;
1881 h ^= h >> 16;
1882
1883 buf = bmake_malloc(9);
1884 for (i = 0; i < 8; i++) {
1885 buf[i] = hexdigits[h & 0x0f];
1886 h >>= 4;
1887 }
1888 buf[8] = '\0';
1889 return buf;
1890 }
1891
1892 static char *
1893 FormatTime(const char *fmt, time_t t, bool gmt)
1894 {
1895 char buf[BUFSIZ];
1896
1897 if (t == 0)
1898 time(&t);
1899 if (*fmt == '\0')
1900 fmt = "%c";
1901 if (gmt && strchr(fmt, 's') != NULL) {
1902 /* strftime "%s" only works with localtime, not with gmtime. */
1903 const char *prev_tz_env = getenv("TZ");
1904 char *prev_tz = prev_tz_env != NULL
1905 ? bmake_strdup(prev_tz_env) : NULL;
1906 setenv("TZ", "UTC", 1);
1907 strftime(buf, sizeof buf, fmt, localtime(&t));
1908 if (prev_tz != NULL) {
1909 setenv("TZ", prev_tz, 1);
1910 free(prev_tz);
1911 } else
1912 unsetenv("TZ");
1913 } else
1914 strftime(buf, sizeof buf, fmt, (gmt ? gmtime : localtime)(&t));
1915
1916 buf[sizeof buf - 1] = '\0';
1917 return bmake_strdup(buf);
1918 }
1919
1920 /*
1921 * The ApplyModifier functions take an expression that is being evaluated.
1922 * Their task is to apply a single modifier to the expression. This involves
1923 * parsing the modifier, evaluating it and finally updating the value of the
1924 * expression.
1925 *
1926 * Parsing the modifier
1927 *
1928 * If parsing succeeds, the parsing position *pp is updated to point to the
1929 * first character following the modifier, which typically is either ':' or
1930 * ch->endc. The modifier doesn't have to check for this delimiter character,
1931 * this is done by ApplyModifiers.
1932 *
1933 * XXX: As of 2020-11-15, some modifiers such as :S, :C, :P, :L do not
1934 * need to be followed by a ':' or endc; this was an unintended mistake.
1935 *
1936 * If parsing fails because of a missing delimiter after a modifier part (as
1937 * in the :S, :C or :@ modifiers), return AMR_CLEANUP.
1938 *
1939 * If parsing fails because the modifier is unknown, return AMR_UNKNOWN to
1940 * try the SysV modifier ':from=to' as fallback. This should only be
1941 * done as long as there have been no side effects from evaluating nested
1942 * variables, to avoid evaluating them more than once. In this case, the
1943 * parsing position may or may not be updated. (XXX: Why not? The original
1944 * parsing position is well-known in ApplyModifiers.)
1945 *
1946 * If parsing fails and the SysV modifier ${VAR:from=to} should not be used
1947 * as a fallback, issue an error message using Parse_Error (preferred over
1948 * Error) and then return AMR_CLEANUP, which stops processing the expression.
1949 * (XXX: As of 2020-08-23, evaluation of the string continues nevertheless
1950 * after skipping a few bytes, which results in garbage.)
1951 *
1952 * Evaluating the modifier
1953 *
1954 * After parsing, the modifier is evaluated. The side effects from evaluating
1955 * nested expressions in the modifier text often already happen
1956 * during parsing though. For most modifiers this doesn't matter since their
1957 * only noticeable effect is that they update the value of the expression.
1958 * Some modifiers such as ':sh' or '::=' have noticeable side effects though.
1959 *
1960 * Evaluating the modifier usually takes the current value of the
1961 * expression from ch->expr->value, or the variable name from ch->var->name,
1962 * and stores the result back in ch->expr->value via Expr_SetValueOwn or
1963 * Expr_SetValueRefer.
1964 *
1965 * If evaluating fails, the fallback error message "Bad modifier" is printed.
1966 * TODO: Add proper error handling to Var_Subst, Var_Parse, ApplyModifiers and
1967 * ModifyWords.
1968 *
1969 * Some modifiers such as :D and :U turn undefined expressions into defined
1970 * expressions using Expr_Define.
1971 */
1972
1973 typedef enum ExprDefined {
1974 /* The expression is based on a regular, defined variable. */
1975 DEF_REGULAR,
1976 /* The expression is based on an undefined variable. */
1977 DEF_UNDEF,
1978 /*
1979 * The expression started as an undefined expression, but one
1980 * of the modifiers (such as ':D' or ':U') has turned the expression
1981 * from undefined to defined.
1982 */
1983 DEF_DEFINED
1984 } ExprDefined;
1985
1986 static const char ExprDefined_Name[][10] = {
1987 "regular",
1988 "undefined",
1989 "defined"
1990 };
1991
1992 #if __STDC_VERSION__ >= 199901L
1993 #define const_member const
1994 #else
1995 #define const_member /* no const possible */
1996 #endif
1997
1998 /* An expression based on a variable, such as $@ or ${VAR:Mpattern:Q}. */
1999 typedef struct Expr {
2000 const char *name;
2001 FStr value;
2002 VarEvalMode const_member emode;
2003 GNode *const_member scope;
2004 ExprDefined defined;
2005 } Expr;
2006
2007 /*
2008 * The status of applying a chain of modifiers to an expression.
2009 *
2010 * The modifiers of an expression are broken into chains of modifiers,
2011 * starting a new nested chain whenever an indirect modifier starts. There
2012 * are at most 2 nesting levels: the outer one for the direct modifiers, and
2013 * the inner one for the indirect modifiers.
2014 *
2015 * For example, the expression ${VAR:M*:${IND1}:${IND2}:O:u} has 3 chains of
2016 * modifiers:
2017 *
2018 * Chain 1 starts with the single modifier ':M*'.
2019 * Chain 2 starts with all modifiers from ${IND1}.
2020 * Chain 2 ends at the ':' between ${IND1} and ${IND2}.
2021 * Chain 3 starts with all modifiers from ${IND2}.
2022 * Chain 3 ends at the ':' after ${IND2}.
2023 * Chain 1 continues with the 2 modifiers ':O' and ':u'.
2024 * Chain 1 ends at the final '}' of the expression.
2025 *
2026 * After such a chain ends, its properties no longer have any effect.
2027 *
2028 * See varmod-indirect.mk.
2029 */
2030 typedef struct ModChain {
2031 Expr *expr;
2032 /* '\0' or '{' or '(' */
2033 char const_member startc;
2034 /* '\0' or '}' or ')' */
2035 char const_member endc;
2036 /* Separator when joining words (see the :ts modifier). */
2037 char sep;
2038 /*
2039 * Whether some modifiers that otherwise split the variable value
2040 * into words, like :S and :C, treat the variable value as a single
2041 * big word, possibly containing spaces.
2042 */
2043 bool oneBigWord;
2044 } ModChain;
2045
2046 static void
2047 Expr_Define(Expr *expr)
2048 {
2049 if (expr->defined == DEF_UNDEF)
2050 expr->defined = DEF_DEFINED;
2051 }
2052
2053 static const char *
2054 Expr_Str(const Expr *expr)
2055 {
2056 return expr->value.str;
2057 }
2058
2059 static SubstringWords
2060 Expr_Words(const Expr *expr)
2061 {
2062 return Substring_Words(Expr_Str(expr), false);
2063 }
2064
2065 static void
2066 Expr_SetValue(Expr *expr, FStr value)
2067 {
2068 FStr_Done(&expr->value);
2069 expr->value = value;
2070 }
2071
2072 static void
2073 Expr_SetValueOwn(Expr *expr, char *value)
2074 {
2075 Expr_SetValue(expr, FStr_InitOwn(value));
2076 }
2077
2078 static void
2079 Expr_SetValueRefer(Expr *expr, const char *value)
2080 {
2081 Expr_SetValue(expr, FStr_InitRefer(value));
2082 }
2083
2084 static bool
2085 Expr_ShouldEval(const Expr *expr)
2086 {
2087 return VarEvalMode_ShouldEval(expr->emode);
2088 }
2089
2090 static bool
2091 ModChain_ShouldEval(const ModChain *ch)
2092 {
2093 return Expr_ShouldEval(ch->expr);
2094 }
2095
2096
2097 typedef enum ApplyModifierResult {
2098 /* Continue parsing */
2099 AMR_OK,
2100 /* Not a match, try the ':from=to' modifier as well. */
2101 AMR_UNKNOWN,
2102 /* Error out with "Bad modifier" message. */
2103 AMR_BAD,
2104 /* Error out without the standard error message. */
2105 AMR_CLEANUP
2106 } ApplyModifierResult;
2107
2108 /*
2109 * Allow backslashes to escape the delimiter, $, and \, but don't touch other
2110 * backslashes.
2111 */
2112 static bool
2113 IsEscapedModifierPart(const char *p, char delim,
2114 struct ModifyWord_SubstArgs *subst)
2115 {
2116 if (p[0] != '\\' || p[1] == '\0')
2117 return false;
2118 if (p[1] == delim || p[1] == '\\' || p[1] == '$')
2119 return true;
2120 return p[1] == '&' && subst != NULL;
2121 }
2122
2123 /*
2124 * In a part of a modifier, parse a subexpression and evaluate it.
2125 */
2126 static void
2127 ParseModifierPartExpr(const char **pp, LazyBuf *part, const ModChain *ch,
2128 VarEvalMode emode)
2129 {
2130 const char *p = *pp;
2131 FStr nested_val = Var_Parse(&p, ch->expr->scope,
2132 VarEvalMode_WithoutKeepDollar(emode));
2133 /* TODO: handle errors */
2134 if (VarEvalMode_ShouldEval(emode))
2135 LazyBuf_AddStr(part, nested_val.str);
2136 else
2137 LazyBuf_AddSubstring(part, Substring_Init(*pp, p));
2138 FStr_Done(&nested_val);
2139 *pp = p;
2140 }
2141
2142 /*
2143 * In a part of a modifier, parse some text that looks like a subexpression.
2144 * If the text starts with '$(', any '(' and ')' must be balanced.
2145 * If the text starts with '${', any '{' and '}' must be balanced.
2146 * If the text starts with '$', that '$' is copied verbatim, it is not parsed
2147 * as a short-name expression.
2148 */
2149 static void
2150 ParseModifierPartBalanced(const char **pp, LazyBuf *part)
2151 {
2152 const char *p = *pp;
2153
2154 if (p[1] == '(' || p[1] == '{') {
2155 char startc = p[1];
2156 int endc = startc == '(' ? ')' : '}';
2157 int depth = 1;
2158
2159 for (p += 2; *p != '\0' && depth > 0; p++) {
2160 if (p[-1] != '\\') {
2161 if (*p == startc)
2162 depth++;
2163 if (*p == endc)
2164 depth--;
2165 }
2166 }
2167 LazyBuf_AddSubstring(part, Substring_Init(*pp, p));
2168 *pp = p;
2169 } else {
2170 LazyBuf_Add(part, *p);
2171 *pp = p + 1;
2172 }
2173 }
2174
2175 /*
2176 * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or
2177 * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and
2178 * including the next unescaped delimiter. The delimiter, as well as the
2179 * backslash or the dollar, can be escaped with a backslash.
2180 *
2181 * Return true if parsing succeeded, together with the parsed (and possibly
2182 * expanded) part. In that case, pp points right after the delimiter. The
2183 * delimiter is not included in the part though.
2184 */
2185 static bool
2186 ParseModifierPart(
2187 /* The parsing position, updated upon return */
2188 const char **pp,
2189 char end1,
2190 char end2,
2191 /* Mode for evaluating nested expressions. */
2192 VarEvalMode emode,
2193 ModChain *ch,
2194 LazyBuf *part,
2195 /*
2196 * For the first part of the ':S' modifier, set anchorEnd if the last
2197 * character of the pattern is a $.
2198 */
2199 PatternFlags *out_pflags,
2200 /*
2201 * For the second part of the ':S' modifier, allow ampersands to be
2202 * escaped and replace unescaped ampersands with subst->lhs.
2203 */
2204 struct ModifyWord_SubstArgs *subst
2205 )
2206 {
2207 const char *p = *pp;
2208
2209 LazyBuf_Init(part, p);
2210 while (*p != '\0' && *p != end1 && *p != end2) {
2211 if (IsEscapedModifierPart(p, end2, subst)) {
2212 LazyBuf_Add(part, p[1]);
2213 p += 2;
2214 } else if (*p != '$') { /* Unescaped, simple text */
2215 if (subst != NULL && *p == '&')
2216 LazyBuf_AddSubstring(part, subst->lhs);
2217 else
2218 LazyBuf_Add(part, *p);
2219 p++;
2220 } else if (p[1] == end2) { /* Unescaped '$' at end */
2221 if (out_pflags != NULL)
2222 out_pflags->anchorEnd = true;
2223 else
2224 LazyBuf_Add(part, *p);
2225 p++;
2226 } else if (emode == VARE_PARSE_BALANCED)
2227 ParseModifierPartBalanced(&p, part);
2228 else
2229 ParseModifierPartExpr(&p, part, ch, emode);
2230 }
2231
2232 *pp = p;
2233 if (*p != end1 && *p != end2) {
2234 Parse_Error(PARSE_FATAL,
2235 "Unfinished modifier ('%c' missing)", end2);
2236 LazyBuf_Done(part);
2237 return false;
2238 }
2239 if (end1 == end2)
2240 (*pp)++;
2241
2242 {
2243 Substring sub = LazyBuf_Get(part);
2244 DEBUG2(VAR, "Modifier part: \"%.*s\"\n",
2245 (int)Substring_Length(sub), sub.start);
2246 }
2247
2248 return true;
2249 }
2250
2251 MAKE_INLINE bool
2252 IsDelimiter(char c, const ModChain *ch)
2253 {
2254 return c == ':' || c == ch->endc || c == '\0';
2255 }
2256
2257 /* Test whether mod starts with modname, followed by a delimiter. */
2258 MAKE_INLINE bool
2259 ModMatch(const char *mod, const char *modname, const ModChain *ch)
2260 {
2261 size_t n = strlen(modname);
2262 return strncmp(mod, modname, n) == 0 && IsDelimiter(mod[n], ch);
2263 }
2264
2265 /* Test whether mod starts with modname, followed by a delimiter or '='. */
2266 MAKE_INLINE bool
2267 ModMatchEq(const char *mod, const char *modname, const ModChain *ch)
2268 {
2269 size_t n = strlen(modname);
2270 return strncmp(mod, modname, n) == 0 &&
2271 (IsDelimiter(mod[n], ch) || mod[n] == '=');
2272 }
2273
2274 static bool
2275 TryParseIntBase0(const char **pp, int *out_num)
2276 {
2277 char *end;
2278 long n;
2279
2280 errno = 0;
2281 n = strtol(*pp, &end, 0);
2282
2283 if (end == *pp)
2284 return false;
2285 if ((n == LONG_MIN || n == LONG_MAX) && errno == ERANGE)
2286 return false;
2287 if (n < INT_MIN || n > INT_MAX)
2288 return false;
2289
2290 *pp = end;
2291 *out_num = (int)n;
2292 return true;
2293 }
2294
2295 static bool
2296 TryParseSize(const char **pp, size_t *out_num)
2297 {
2298 char *end;
2299 unsigned long n;
2300
2301 if (!ch_isdigit(**pp))
2302 return false;
2303
2304 errno = 0;
2305 n = strtoul(*pp, &end, 10);
2306 if (n == ULONG_MAX && errno == ERANGE)
2307 return false;
2308 if (n > SIZE_MAX)
2309 return false;
2310
2311 *pp = end;
2312 *out_num = (size_t)n;
2313 return true;
2314 }
2315
2316 static bool
2317 TryParseChar(const char **pp, int base, char *out_ch)
2318 {
2319 char *end;
2320 unsigned long n;
2321
2322 if (!ch_isalnum(**pp))
2323 return false;
2324
2325 errno = 0;
2326 n = strtoul(*pp, &end, base);
2327 if (n == ULONG_MAX && errno == ERANGE)
2328 return false;
2329 if (n > UCHAR_MAX)
2330 return false;
2331
2332 *pp = end;
2333 *out_ch = (char)n;
2334 return true;
2335 }
2336
2337 /*
2338 * Modify each word of the expression using the given function and place the
2339 * result back in the expression.
2340 */
2341 static void
2342 ModifyWords(ModChain *ch,
2343 ModifyWordProc modifyWord, void *modifyWord_args,
2344 bool oneBigWord)
2345 {
2346 Expr *expr = ch->expr;
2347 const char *val = Expr_Str(expr);
2348 SepBuf result;
2349 SubstringWords words;
2350 size_t i;
2351 Substring word;
2352
2353 if (!ModChain_ShouldEval(ch))
2354 return;
2355
2356 if (oneBigWord) {
2357 SepBuf_Init(&result, ch->sep);
2358 /* XXX: performance: Substring_InitStr calls strlen */
2359 word = Substring_InitStr(val);
2360 modifyWord(word, &result, modifyWord_args);
2361 goto done;
2362 }
2363
2364 words = Substring_Words(val, false);
2365
2366 DEBUG3(VAR, "ModifyWords: split \"%s\" into %u %s\n",
2367 val, (unsigned)words.len, words.len != 1 ? "words" : "word");
2368
2369 SepBuf_Init(&result, ch->sep);
2370 for (i = 0; i < words.len; i++) {
2371 modifyWord(words.words[i], &result, modifyWord_args);
2372 if (result.buf.len > 0)
2373 SepBuf_Sep(&result);
2374 }
2375
2376 SubstringWords_Free(words);
2377
2378 done:
2379 Expr_SetValueOwn(expr, SepBuf_DoneData(&result));
2380 }
2381
2382 /* :@var (at) ...${var}...@ */
2383 static ApplyModifierResult
2384 ApplyModifier_Loop(const char **pp, ModChain *ch)
2385 {
2386 Expr *expr = ch->expr;
2387 struct ModifyWord_LoopArgs args;
2388 char prev_sep;
2389 LazyBuf tvarBuf, strBuf;
2390 FStr tvar, str;
2391
2392 args.scope = expr->scope;
2393
2394 (*pp)++; /* Skip the first '@' */
2395 if (!ParseModifierPart(pp, '@', '@', VARE_PARSE,
2396 ch, &tvarBuf, NULL, NULL))
2397 return AMR_CLEANUP;
2398 tvar = LazyBuf_DoneGet(&tvarBuf);
2399 args.var = tvar.str;
2400 if (strchr(args.var, '$') != NULL) {
2401 Parse_Error(PARSE_FATAL,
2402 "In the :@ modifier, the variable name \"%s\" "
2403 "must not contain a dollar",
2404 args.var);
2405 goto cleanup_tvar;
2406 }
2407
2408 if (!ParseModifierPart(pp, '@', '@', VARE_PARSE_BALANCED,
2409 ch, &strBuf, NULL, NULL))
2410 goto cleanup_tvar;
2411 str = LazyBuf_DoneGet(&strBuf);
2412 args.body = str.str;
2413
2414 if (!Expr_ShouldEval(expr))
2415 goto done;
2416
2417 args.emode = VarEvalMode_WithoutKeepDollar(expr->emode);
2418 prev_sep = ch->sep;
2419 ch->sep = ' '; /* XXX: should be ch->sep for consistency */
2420 ModifyWords(ch, ModifyWord_Loop, &args, ch->oneBigWord);
2421 ch->sep = prev_sep;
2422 /* XXX: Consider restoring the previous value instead of deleting. */
2423 Var_Delete(expr->scope, args.var);
2424
2425 done:
2426 FStr_Done(&tvar);
2427 FStr_Done(&str);
2428 return AMR_OK;
2429
2430 cleanup_tvar:
2431 FStr_Done(&tvar);
2432 return AMR_CLEANUP;
2433 }
2434
2435 static void
2436 ParseModifier_Defined(const char **pp, ModChain *ch, bool shouldEval,
2437 LazyBuf *buf)
2438 {
2439 const char *p;
2440
2441 p = *pp + 1;
2442 LazyBuf_Init(buf, p);
2443 while (!IsDelimiter(*p, ch)) {
2444
2445 /*
2446 * XXX: This code is similar to the one in Var_Parse. See if
2447 * the code can be merged. See also ParseModifier_Match and
2448 * ParseModifierPart.
2449 */
2450
2451 /* See Buf_AddEscaped in for.c for the counterpart. */
2452 if (*p == '\\') {
2453 char c = p[1];
2454 if ((IsDelimiter(c, ch) && c != '\0') ||
2455 c == '$' || c == '\\') {
2456 if (shouldEval)
2457 LazyBuf_Add(buf, c);
2458 p += 2;
2459 continue;
2460 }
2461 }
2462
2463 if (*p == '$') {
2464 FStr val = Var_Parse(&p, ch->expr->scope,
2465 shouldEval ? ch->expr->emode : VARE_PARSE);
2466 /* TODO: handle errors */
2467 if (shouldEval)
2468 LazyBuf_AddStr(buf, val.str);
2469 FStr_Done(&val);
2470 continue;
2471 }
2472
2473 if (shouldEval)
2474 LazyBuf_Add(buf, *p);
2475 p++;
2476 }
2477 *pp = p;
2478 }
2479
2480 /* :Ddefined or :Uundefined */
2481 static ApplyModifierResult
2482 ApplyModifier_Defined(const char **pp, ModChain *ch)
2483 {
2484 Expr *expr = ch->expr;
2485 LazyBuf buf;
2486 bool shouldEval =
2487 Expr_ShouldEval(expr) &&
2488 (**pp == 'D') == (expr->defined == DEF_REGULAR);
2489
2490 ParseModifier_Defined(pp, ch, shouldEval, &buf);
2491
2492 Expr_Define(expr);
2493 if (shouldEval)
2494 Expr_SetValue(expr, Substring_Str(LazyBuf_Get(&buf)));
2495 LazyBuf_Done(&buf);
2496
2497 return AMR_OK;
2498 }
2499
2500 /* :L */
2501 static ApplyModifierResult
2502 ApplyModifier_Literal(const char **pp, ModChain *ch)
2503 {
2504 Expr *expr = ch->expr;
2505
2506 (*pp)++;
2507
2508 if (Expr_ShouldEval(expr)) {
2509 Expr_Define(expr);
2510 Expr_SetValueOwn(expr, bmake_strdup(expr->name));
2511 }
2512
2513 return AMR_OK;
2514 }
2515
2516 static bool
2517 TryParseTime(const char **pp, time_t *out_time)
2518 {
2519 char *end;
2520 unsigned long n;
2521
2522 if (!ch_isdigit(**pp))
2523 return false;
2524
2525 errno = 0;
2526 n = strtoul(*pp, &end, 10);
2527 if (n == ULONG_MAX && errno == ERANGE)
2528 return false;
2529
2530 *pp = end;
2531 *out_time = (time_t)n; /* ignore possible truncation for now */
2532 return true;
2533 }
2534
2535 /* :gmtime and :localtime */
2536 static ApplyModifierResult
2537 ApplyModifier_Time(const char **pp, ModChain *ch)
2538 {
2539 Expr *expr;
2540 time_t t;
2541 const char *args;
2542 const char *mod = *pp;
2543 bool gmt = mod[0] == 'g';
2544
2545 if (!ModMatchEq(mod, gmt ? "gmtime" : "localtime", ch))
2546 return AMR_UNKNOWN;
2547 args = mod + (gmt ? 6 : 9);
2548
2549 if (args[0] == '=') {
2550 const char *p = args + 1;
2551 LazyBuf buf;
2552 FStr arg;
2553 if (!ParseModifierPart(&p, ':', ch->endc, ch->expr->emode,
2554 ch, &buf, NULL, NULL))
2555 return AMR_CLEANUP;
2556 arg = LazyBuf_DoneGet(&buf);
2557 if (ModChain_ShouldEval(ch)) {
2558 const char *arg_p = arg.str;
2559 if (!TryParseTime(&arg_p, &t) || *arg_p != '\0') {
2560 Parse_Error(PARSE_FATAL,
2561 "Invalid time value \"%s\"", arg.str);
2562 FStr_Done(&arg);
2563 return AMR_CLEANUP;
2564 }
2565 } else
2566 t = 0;
2567 FStr_Done(&arg);
2568 *pp = p;
2569 } else {
2570 t = 0;
2571 *pp = args;
2572 }
2573
2574 expr = ch->expr;
2575 if (Expr_ShouldEval(expr))
2576 Expr_SetValueOwn(expr, FormatTime(Expr_Str(expr), t, gmt));
2577
2578 return AMR_OK;
2579 }
2580
2581 /* :hash */
2582 static ApplyModifierResult
2583 ApplyModifier_Hash(const char **pp, ModChain *ch)
2584 {
2585 if (!ModMatch(*pp, "hash", ch))
2586 return AMR_UNKNOWN;
2587 *pp += 4;
2588
2589 if (ModChain_ShouldEval(ch))
2590 Expr_SetValueOwn(ch->expr, Hash(Expr_Str(ch->expr)));
2591
2592 return AMR_OK;
2593 }
2594
2595 /* :P */
2596 static ApplyModifierResult
2597 ApplyModifier_Path(const char **pp, ModChain *ch)
2598 {
2599 Expr *expr = ch->expr;
2600 GNode *gn;
2601 char *path;
2602
2603 (*pp)++;
2604
2605 if (!Expr_ShouldEval(expr))
2606 return AMR_OK;
2607
2608 Expr_Define(expr);
2609
2610 gn = Targ_FindNode(expr->name);
2611 if (gn == NULL || gn->type & OP_NOPATH)
2612 path = NULL;
2613 else if (gn->path != NULL)
2614 path = bmake_strdup(gn->path);
2615 else {
2616 SearchPath *searchPath = Suff_FindPath(gn);
2617 path = Dir_FindFile(expr->name, searchPath);
2618 }
2619 if (path == NULL)
2620 path = bmake_strdup(expr->name);
2621 Expr_SetValueOwn(expr, path);
2622
2623 return AMR_OK;
2624 }
2625
2626 /* :!cmd! */
2627 static ApplyModifierResult
2628 ApplyModifier_ShellCommand(const char **pp, ModChain *ch)
2629 {
2630 Expr *expr = ch->expr;
2631 LazyBuf cmdBuf;
2632 FStr cmd;
2633
2634 (*pp)++;
2635 if (!ParseModifierPart(pp, '!', '!', expr->emode,
2636 ch, &cmdBuf, NULL, NULL))
2637 return AMR_CLEANUP;
2638 cmd = LazyBuf_DoneGet(&cmdBuf);
2639
2640 if (Expr_ShouldEval(expr)) {
2641 char *output, *error;
2642 output = Cmd_Exec(cmd.str, &error);
2643 Expr_SetValueOwn(expr, output);
2644 if (error != NULL) {
2645 Parse_Error(PARSE_WARNING, "%s", error);
2646 free(error);
2647 }
2648 } else
2649 Expr_SetValueRefer(expr, "");
2650
2651 FStr_Done(&cmd);
2652 Expr_Define(expr);
2653
2654 return AMR_OK;
2655 }
2656
2657 /*
2658 * The :range modifier generates an integer sequence as long as the words.
2659 * The :range=7 modifier generates an integer sequence from 1 to 7.
2660 */
2661 static ApplyModifierResult
2662 ApplyModifier_Range(const char **pp, ModChain *ch)
2663 {
2664 size_t n;
2665 Buffer buf;
2666 size_t i;
2667
2668 const char *mod = *pp;
2669 if (!ModMatchEq(mod, "range", ch))
2670 return AMR_UNKNOWN;
2671
2672 if (mod[5] == '=') {
2673 const char *p = mod + 6;
2674 if (!TryParseSize(&p, &n)) {
2675 Parse_Error(PARSE_FATAL,
2676 "Invalid number \"%s\" for ':range' modifier",
2677 mod + 6);
2678 return AMR_CLEANUP;
2679 }
2680 *pp = p;
2681 } else {
2682 n = 0;
2683 *pp = mod + 5;
2684 }
2685
2686 if (!ModChain_ShouldEval(ch))
2687 return AMR_OK;
2688
2689 if (n == 0) {
2690 SubstringWords words = Expr_Words(ch->expr);
2691 n = words.len;
2692 SubstringWords_Free(words);
2693 }
2694
2695 Buf_Init(&buf);
2696
2697 for (i = 0; i < n; i++) {
2698 if (i != 0) {
2699 /*
2700 * XXX: Use ch->sep instead of ' ', for consistency.
2701 */
2702 Buf_AddByte(&buf, ' ');
2703 }
2704 Buf_AddInt(&buf, 1 + (int)i);
2705 }
2706
2707 Expr_SetValueOwn(ch->expr, Buf_DoneData(&buf));
2708 return AMR_OK;
2709 }
2710
2711 /* Parse a ':M' or ':N' modifier. */
2712 static char *
2713 ParseModifier_Match(const char **pp, const ModChain *ch)
2714 {
2715 const char *mod = *pp;
2716 Expr *expr = ch->expr;
2717 bool copy = false; /* pattern should be, or has been, copied */
2718 bool needSubst = false;
2719 const char *endpat;
2720 char *pattern;
2721
2722 /*
2723 * In the loop below, ignore ':' unless we are at (or back to) the
2724 * original brace level.
2725 * XXX: This will likely not work right if $() and ${} are intermixed.
2726 */
2727 /*
2728 * XXX: This code is similar to the one in Var_Parse.
2729 * See if the code can be merged.
2730 * See also ApplyModifier_Defined.
2731 */
2732 int depth = 0;
2733 const char *p;
2734 for (p = mod + 1; *p != '\0' && !(*p == ':' && depth == 0); p++) {
2735 if (*p == '\\' && p[1] != '\0' &&
2736 (IsDelimiter(p[1], ch) || p[1] == ch->startc)) {
2737 if (!needSubst)
2738 copy = true;
2739 p++;
2740 continue;
2741 }
2742 if (*p == '$')
2743 needSubst = true;
2744 if (*p == '(' || *p == '{')
2745 depth++;
2746 if (*p == ')' || *p == '}') {
2747 depth--;
2748 if (depth < 0)
2749 break;
2750 }
2751 }
2752 *pp = p;
2753 endpat = p;
2754
2755 if (copy) {
2756 char *dst;
2757 const char *src;
2758
2759 /* Compress the \:'s out of the pattern. */
2760 pattern = bmake_malloc((size_t)(endpat - (mod + 1)) + 1);
2761 dst = pattern;
2762 src = mod + 1;
2763 for (; src < endpat; src++, dst++) {
2764 if (src[0] == '\\' && src + 1 < endpat &&
2765 /* XXX: ch->startc is missing here; see above */
2766 IsDelimiter(src[1], ch))
2767 src++;
2768 *dst = *src;
2769 }
2770 *dst = '\0';
2771 } else {
2772 pattern = bmake_strsedup(mod + 1, endpat);
2773 }
2774
2775 if (needSubst) {
2776 char *old_pattern = pattern;
2777 /*
2778 * XXX: Contrary to ParseModifierPart, a dollar in a ':M' or
2779 * ':N' modifier must be escaped as '$$', not as '\$'.
2780 */
2781 pattern = Var_Subst(pattern, expr->scope, expr->emode);
2782 /* TODO: handle errors */
2783 free(old_pattern);
2784 }
2785
2786 DEBUG2(VAR, "Pattern for ':%c' is \"%s\"\n", mod[0], pattern);
2787
2788 return pattern;
2789 }
2790
2791 struct ModifyWord_MatchArgs {
2792 const char *pattern;
2793 bool neg;
2794 bool error_reported;
2795 };
2796
2797 static void
2798 ModifyWord_Match(Substring word, SepBuf *buf, void *data)
2799 {
2800 struct ModifyWord_MatchArgs *args = data;
2801 StrMatchResult res;
2802 assert(word.end[0] == '\0'); /* assume null-terminated word */
2803 res = Str_Match(word.start, args->pattern);
2804 if (res.error != NULL && !args->error_reported) {
2805 args->error_reported = true;
2806 Parse_Error(PARSE_WARNING,
2807 "%s in pattern '%s' of modifier '%s'",
2808 res.error, args->pattern, args->neg ? ":N" : ":M");
2809 }
2810 if (res.matched != args->neg)
2811 SepBuf_AddSubstring(buf, word);
2812 }
2813
2814 /* :Mpattern or :Npattern */
2815 static ApplyModifierResult
2816 ApplyModifier_Match(const char **pp, ModChain *ch)
2817 {
2818 char mod = **pp;
2819 char *pattern;
2820
2821 pattern = ParseModifier_Match(pp, ch);
2822
2823 if (ModChain_ShouldEval(ch)) {
2824 struct ModifyWord_MatchArgs args;
2825 args.pattern = pattern;
2826 args.neg = mod == 'N';
2827 args.error_reported = false;
2828 ModifyWords(ch, ModifyWord_Match, &args, ch->oneBigWord);
2829 }
2830
2831 free(pattern);
2832 return AMR_OK;
2833 }
2834
2835 struct ModifyWord_MtimeArgs {
2836 bool error;
2837 bool use_fallback;
2838 ApplyModifierResult rc;
2839 time_t fallback;
2840 };
2841
2842 static void
2843 ModifyWord_Mtime(Substring word, SepBuf *buf, void *data)
2844 {
2845 struct ModifyWord_MtimeArgs *args = data;
2846 struct stat st;
2847 char tbuf[21];
2848
2849 if (Substring_IsEmpty(word))
2850 return;
2851 assert(word.end[0] == '\0'); /* assume null-terminated word */
2852 if (stat(word.start, &st) < 0) {
2853 if (args->error) {
2854 Parse_Error(PARSE_FATAL,
2855 "Cannot determine mtime for '%s': %s",
2856 word.start, strerror(errno));
2857 args->rc = AMR_CLEANUP;
2858 return;
2859 }
2860 if (args->use_fallback)
2861 st.st_mtime = args->fallback;
2862 else
2863 time(&st.st_mtime);
2864 }
2865 snprintf(tbuf, sizeof(tbuf), "%u", (unsigned)st.st_mtime);
2866 SepBuf_AddStr(buf, tbuf);
2867 }
2868
2869 /* :mtime */
2870 static ApplyModifierResult
2871 ApplyModifier_Mtime(const char **pp, ModChain *ch)
2872 {
2873 const char *p, *mod = *pp;
2874 struct ModifyWord_MtimeArgs args;
2875
2876 if (!ModMatchEq(mod, "mtime", ch))
2877 return AMR_UNKNOWN;
2878 *pp += 5;
2879 p = *pp;
2880 args.error = false;
2881 args.use_fallback = p[0] == '=';
2882 args.rc = AMR_OK;
2883 if (args.use_fallback) {
2884 p++;
2885 if (TryParseTime(&p, &args.fallback)) {
2886 } else if (strncmp(p, "error", 5) == 0) {
2887 p += 5;
2888 args.error = true;
2889 } else
2890 goto invalid_argument;
2891 if (!IsDelimiter(*p, ch))
2892 goto invalid_argument;
2893 *pp = p;
2894 }
2895 ModifyWords(ch, ModifyWord_Mtime, &args, ch->oneBigWord);
2896 return args.rc;
2897
2898 invalid_argument:
2899 Parse_Error(PARSE_FATAL,
2900 "Invalid argument '%.*s' for modifier ':mtime'",
2901 (int)strcspn(*pp + 1, ":{}()"), *pp + 1);
2902 return AMR_CLEANUP;
2903 }
2904
2905 static void
2906 ParsePatternFlags(const char **pp, PatternFlags *pflags, bool *oneBigWord)
2907 {
2908 for (;; (*pp)++) {
2909 if (**pp == 'g')
2910 pflags->subGlobal = true;
2911 else if (**pp == '1')
2912 pflags->subOnce = true;
2913 else if (**pp == 'W')
2914 *oneBigWord = true;
2915 else
2916 break;
2917 }
2918 }
2919
2920 MAKE_INLINE PatternFlags
2921 PatternFlags_None(void)
2922 {
2923 PatternFlags pflags = { false, false, false, false };
2924 return pflags;
2925 }
2926
2927 /* :S,from,to, */
2928 static ApplyModifierResult
2929 ApplyModifier_Subst(const char **pp, ModChain *ch)
2930 {
2931 struct ModifyWord_SubstArgs args;
2932 bool oneBigWord;
2933 LazyBuf lhsBuf, rhsBuf;
2934
2935 char delim = (*pp)[1];
2936 if (delim == '\0') {
2937 Parse_Error(PARSE_FATAL,
2938 "Missing delimiter for modifier ':S'");
2939 (*pp)++;
2940 return AMR_CLEANUP;
2941 }
2942
2943 *pp += 2;
2944
2945 args.pflags = PatternFlags_None();
2946 args.matched = false;
2947
2948 if (**pp == '^') {
2949 args.pflags.anchorStart = true;
2950 (*pp)++;
2951 }
2952
2953 if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
2954 ch, &lhsBuf, &args.pflags, NULL))
2955 return AMR_CLEANUP;
2956 args.lhs = LazyBuf_Get(&lhsBuf);
2957
2958 if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
2959 ch, &rhsBuf, NULL, &args)) {
2960 LazyBuf_Done(&lhsBuf);
2961 return AMR_CLEANUP;
2962 }
2963 args.rhs = LazyBuf_Get(&rhsBuf);
2964
2965 oneBigWord = ch->oneBigWord;
2966 ParsePatternFlags(pp, &args.pflags, &oneBigWord);
2967
2968 ModifyWords(ch, ModifyWord_Subst, &args, oneBigWord);
2969
2970 LazyBuf_Done(&lhsBuf);
2971 LazyBuf_Done(&rhsBuf);
2972 return AMR_OK;
2973 }
2974
2975 /* :C,from,to, */
2976 static ApplyModifierResult
2977 ApplyModifier_Regex(const char **pp, ModChain *ch)
2978 {
2979 struct ModifyWord_SubstRegexArgs args;
2980 bool oneBigWord;
2981 int error;
2982 LazyBuf reBuf, replaceBuf;
2983 FStr re;
2984
2985 char delim = (*pp)[1];
2986 if (delim == '\0') {
2987 Parse_Error(PARSE_FATAL,
2988 "Missing delimiter for modifier ':C'");
2989 (*pp)++;
2990 return AMR_CLEANUP;
2991 }
2992
2993 *pp += 2;
2994
2995 if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
2996 ch, &reBuf, NULL, NULL))
2997 return AMR_CLEANUP;
2998 re = LazyBuf_DoneGet(&reBuf);
2999
3000 if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
3001 ch, &replaceBuf, NULL, NULL)) {
3002 FStr_Done(&re);
3003 return AMR_CLEANUP;
3004 }
3005 args.replace = LazyBuf_Get(&replaceBuf);
3006
3007 args.pflags = PatternFlags_None();
3008 args.matched = false;
3009 oneBigWord = ch->oneBigWord;
3010 ParsePatternFlags(pp, &args.pflags, &oneBigWord);
3011
3012 if (!ModChain_ShouldEval(ch))
3013 goto done;
3014
3015 error = regcomp(&args.re, re.str, REG_EXTENDED);
3016 if (error != 0) {
3017 RegexError(error, &args.re, "Regex compilation error");
3018 LazyBuf_Done(&replaceBuf);
3019 FStr_Done(&re);
3020 return AMR_CLEANUP;
3021 }
3022
3023 args.nsub = args.re.re_nsub + 1;
3024 if (args.nsub > 10)
3025 args.nsub = 10;
3026
3027 ModifyWords(ch, ModifyWord_SubstRegex, &args, oneBigWord);
3028
3029 regfree(&args.re);
3030 done:
3031 LazyBuf_Done(&replaceBuf);
3032 FStr_Done(&re);
3033 return AMR_OK;
3034 }
3035
3036 /* :Q, :q */
3037 static ApplyModifierResult
3038 ApplyModifier_Quote(const char **pp, ModChain *ch)
3039 {
3040 LazyBuf buf;
3041 bool quoteDollar;
3042
3043 quoteDollar = **pp == 'q';
3044 if (!IsDelimiter((*pp)[1], ch))
3045 return AMR_UNKNOWN;
3046 (*pp)++;
3047
3048 if (!ModChain_ShouldEval(ch))
3049 return AMR_OK;
3050
3051 QuoteShell(Expr_Str(ch->expr), quoteDollar, &buf);
3052 if (buf.data != NULL)
3053 Expr_SetValue(ch->expr, LazyBuf_DoneGet(&buf));
3054 else
3055 LazyBuf_Done(&buf);
3056
3057 return AMR_OK;
3058 }
3059
3060 static void
3061 ModifyWord_Copy(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
3062 {
3063 SepBuf_AddSubstring(buf, word);
3064 }
3065
3066 /* :ts<separator> */
3067 static ApplyModifierResult
3068 ApplyModifier_ToSep(const char **pp, ModChain *ch)
3069 {
3070 const char *sep = *pp + 2;
3071
3072 /*
3073 * Even in parse-only mode, apply the side effects, since the side
3074 * effects are neither observable nor is there a performance penalty.
3075 * Checking for VARE_EVAL for every single piece of code in here
3076 * would make the code in this function too hard to read.
3077 */
3078
3079 /* ":ts<any><endc>" or ":ts<any>:" */
3080 if (sep[0] != ch->endc && IsDelimiter(sep[1], ch)) {
3081 *pp = sep + 1;
3082 ch->sep = sep[0];
3083 goto ok;
3084 }
3085
3086 /* ":ts<endc>" or ":ts:" */
3087 if (IsDelimiter(sep[0], ch)) {
3088 *pp = sep;
3089 ch->sep = '\0'; /* no separator */
3090 goto ok;
3091 }
3092
3093 /* ":ts<unrecognized><unrecognized>". */
3094 if (sep[0] != '\\') {
3095 (*pp)++; /* just for backwards compatibility */
3096 return AMR_BAD;
3097 }
3098
3099 /* ":ts\n" */
3100 if (sep[1] == 'n') {
3101 *pp = sep + 2;
3102 ch->sep = '\n';
3103 goto ok;
3104 }
3105
3106 /* ":ts\t" */
3107 if (sep[1] == 't') {
3108 *pp = sep + 2;
3109 ch->sep = '\t';
3110 goto ok;
3111 }
3112
3113 /* ":ts\x40" or ":ts\100" */
3114 {
3115 const char *p = sep + 1;
3116 int base = 8; /* assume octal */
3117
3118 if (sep[1] == 'x') {
3119 base = 16;
3120 p++;
3121 } else if (!ch_isdigit(sep[1])) {
3122 (*pp)++; /* just for backwards compatibility */
3123 return AMR_BAD; /* ":ts<backslash><unrecognized>". */
3124 }
3125
3126 if (!TryParseChar(&p, base, &ch->sep)) {
3127 Parse_Error(PARSE_FATAL,
3128 "Invalid character number at \"%s\"", p);
3129 return AMR_CLEANUP;
3130 }
3131 if (!IsDelimiter(*p, ch)) {
3132 (*pp)++; /* just for backwards compatibility */
3133 return AMR_BAD;
3134 }
3135
3136 *pp = p;
3137 }
3138
3139 ok:
3140 ModifyWords(ch, ModifyWord_Copy, NULL, ch->oneBigWord);
3141 return AMR_OK;
3142 }
3143
3144 static char *
3145 str_totitle(const char *str)
3146 {
3147 size_t i, n = strlen(str) + 1;
3148 char *res = bmake_malloc(n);
3149 for (i = 0; i < n; i++) {
3150 if (i == 0 || ch_isspace(res[i - 1]))
3151 res[i] = ch_toupper(str[i]);
3152 else
3153 res[i] = ch_tolower(str[i]);
3154 }
3155 return res;
3156 }
3157
3158
3159 static char *
3160 str_toupper(const char *str)
3161 {
3162 size_t i, n = strlen(str) + 1;
3163 char *res = bmake_malloc(n);
3164 for (i = 0; i < n; i++)
3165 res[i] = ch_toupper(str[i]);
3166 return res;
3167 }
3168
3169 static char *
3170 str_tolower(const char *str)
3171 {
3172 size_t i, n = strlen(str) + 1;
3173 char *res = bmake_malloc(n);
3174 for (i = 0; i < n; i++)
3175 res[i] = ch_tolower(str[i]);
3176 return res;
3177 }
3178
3179 /* :tA, :tu, :tl, :ts<separator>, etc. */
3180 static ApplyModifierResult
3181 ApplyModifier_To(const char **pp, ModChain *ch)
3182 {
3183 Expr *expr = ch->expr;
3184 const char *mod = *pp;
3185 assert(mod[0] == 't');
3186
3187 if (IsDelimiter(mod[1], ch)) {
3188 *pp = mod + 1;
3189 return AMR_BAD; /* Found ":t<endc>" or ":t:". */
3190 }
3191
3192 if (mod[1] == 's')
3193 return ApplyModifier_ToSep(pp, ch);
3194
3195 if (!IsDelimiter(mod[2], ch)) { /* :t<any><any> */
3196 *pp = mod + 1;
3197 return AMR_BAD;
3198 }
3199
3200 if (mod[1] == 'A') { /* :tA */
3201 *pp = mod + 2;
3202 ModifyWords(ch, ModifyWord_Realpath, NULL, ch->oneBigWord);
3203 return AMR_OK;
3204 }
3205
3206 if (mod[1] == 't') { /* :tt */
3207 *pp = mod + 2;
3208 if (Expr_ShouldEval(expr))
3209 Expr_SetValueOwn(expr, str_totitle(Expr_Str(expr)));
3210 return AMR_OK;
3211 }
3212
3213 if (mod[1] == 'u') { /* :tu */
3214 *pp = mod + 2;
3215 if (Expr_ShouldEval(expr))
3216 Expr_SetValueOwn(expr, str_toupper(Expr_Str(expr)));
3217 return AMR_OK;
3218 }
3219
3220 if (mod[1] == 'l') { /* :tl */
3221 *pp = mod + 2;
3222 if (Expr_ShouldEval(expr))
3223 Expr_SetValueOwn(expr, str_tolower(Expr_Str(expr)));
3224 return AMR_OK;
3225 }
3226
3227 if (mod[1] == 'W' || mod[1] == 'w') { /* :tW, :tw */
3228 *pp = mod + 2;
3229 ch->oneBigWord = mod[1] == 'W';
3230 return AMR_OK;
3231 }
3232
3233 /* Found ":t<unrecognized>:" or ":t<unrecognized><endc>". */
3234 *pp = mod + 1; /* XXX: unnecessary but observable */
3235 return AMR_BAD;
3236 }
3237
3238 /* :[#], :[1], :[-1..1], etc. */
3239 static ApplyModifierResult
3240 ApplyModifier_Words(const char **pp, ModChain *ch)
3241 {
3242 Expr *expr = ch->expr;
3243 int first, last;
3244 const char *p;
3245 LazyBuf argBuf;
3246 FStr arg;
3247
3248 (*pp)++; /* skip the '[' */
3249 if (!ParseModifierPart(pp, ']', ']', expr->emode,
3250 ch, &argBuf, NULL, NULL))
3251 return AMR_CLEANUP;
3252 arg = LazyBuf_DoneGet(&argBuf);
3253 p = arg.str;
3254
3255 if (!IsDelimiter(**pp, ch))
3256 goto bad_modifier; /* Found junk after ']' */
3257
3258 if (!ModChain_ShouldEval(ch))
3259 goto ok;
3260
3261 if (p[0] == '\0')
3262 goto bad_modifier; /* Found ":[]". */
3263
3264 if (strcmp(p, "#") == 0) { /* Found ":[#]" */
3265 if (ch->oneBigWord)
3266 Expr_SetValueRefer(expr, "1");
3267 else {
3268 Buffer buf;
3269
3270 SubstringWords words = Expr_Words(expr);
3271 size_t ac = words.len;
3272 SubstringWords_Free(words);
3273
3274 Buf_Init(&buf);
3275 Buf_AddInt(&buf, (int)ac);
3276 Expr_SetValueOwn(expr, Buf_DoneData(&buf));
3277 }
3278 goto ok;
3279 }
3280
3281 if (strcmp(p, "*") == 0) { /* ":[*]" */
3282 ch->oneBigWord = true;
3283 goto ok;
3284 }
3285
3286 if (strcmp(p, "@") == 0) { /* ":[@]" */
3287 ch->oneBigWord = false;
3288 goto ok;
3289 }
3290
3291 /* Expect ":[N]" or ":[start..end]" */
3292 if (!TryParseIntBase0(&p, &first))
3293 goto bad_modifier;
3294
3295 if (p[0] == '\0') /* ":[N]" */
3296 last = first;
3297 else if (strncmp(p, "..", 2) == 0) {
3298 p += 2;
3299 if (!TryParseIntBase0(&p, &last) || *p != '\0')
3300 goto bad_modifier;
3301 } else
3302 goto bad_modifier;
3303
3304 if (first == 0 && last == 0) { /* ":[0]" or ":[0..0]" */
3305 ch->oneBigWord = true;
3306 goto ok;
3307 }
3308
3309 if (first == 0 || last == 0) /* ":[0..N]" or ":[N..0]" */
3310 goto bad_modifier;
3311
3312 Expr_SetValueOwn(expr,
3313 VarSelectWords(Expr_Str(expr), first, last,
3314 ch->sep, ch->oneBigWord));
3315
3316 ok:
3317 FStr_Done(&arg);
3318 return AMR_OK;
3319
3320 bad_modifier:
3321 FStr_Done(&arg);
3322 return AMR_BAD;
3323 }
3324
3325 #if __STDC_VERSION__ >= 199901L
3326 # define NUM_TYPE long long
3327 # define PARSE_NUM_TYPE strtoll
3328 #else
3329 # define NUM_TYPE long
3330 # define PARSE_NUM_TYPE strtol
3331 #endif
3332
3333 static NUM_TYPE
3334 num_val(Substring s)
3335 {
3336 NUM_TYPE val;
3337 char *ep;
3338
3339 val = PARSE_NUM_TYPE(s.start, &ep, 0);
3340 if (ep != s.start) {
3341 switch (*ep) {
3342 case 'K':
3343 case 'k':
3344 val <<= 10;
3345 break;
3346 case 'M':
3347 case 'm':
3348 val <<= 20;
3349 break;
3350 case 'G':
3351 case 'g':
3352 val <<= 30;
3353 break;
3354 }
3355 }
3356 return val;
3357 }
3358
3359 static int
3360 SubNumAsc(const void *sa, const void *sb)
3361 {
3362 NUM_TYPE a, b;
3363
3364 a = num_val(*((const Substring *)sa));
3365 b = num_val(*((const Substring *)sb));
3366 return a > b ? 1 : b > a ? -1 : 0;
3367 }
3368
3369 static int
3370 SubNumDesc(const void *sa, const void *sb)
3371 {
3372 return SubNumAsc(sb, sa);
3373 }
3374
3375 static int
3376 Substring_Cmp(Substring a, Substring b)
3377 {
3378 for (; a.start < a.end && b.start < b.end; a.start++, b.start++)
3379 if (a.start[0] != b.start[0])
3380 return (unsigned char)a.start[0]
3381 - (unsigned char)b.start[0];
3382 return (int)((a.end - a.start) - (b.end - b.start));
3383 }
3384
3385 static int
3386 SubStrAsc(const void *sa, const void *sb)
3387 {
3388 return Substring_Cmp(*(const Substring *)sa, *(const Substring *)sb);
3389 }
3390
3391 static int
3392 SubStrDesc(const void *sa, const void *sb)
3393 {
3394 return SubStrAsc(sb, sa);
3395 }
3396
3397 static void
3398 ShuffleSubstrings(Substring *strs, size_t n)
3399 {
3400 size_t i;
3401
3402 for (i = n - 1; i > 0; i--) {
3403 size_t rndidx = (size_t)random() % (i + 1);
3404 Substring t = strs[i];
3405 strs[i] = strs[rndidx];
3406 strs[rndidx] = t;
3407 }
3408 }
3409
3410 /*
3411 * :O order ascending
3412 * :Or order descending
3413 * :Ox shuffle
3414 * :On numeric ascending
3415 * :Onr, :Orn numeric descending
3416 */
3417 static ApplyModifierResult
3418 ApplyModifier_Order(const char **pp, ModChain *ch)
3419 {
3420 const char *mod = *pp;
3421 SubstringWords words;
3422 int (*cmp)(const void *, const void *);
3423
3424 if (IsDelimiter(mod[1], ch)) {
3425 cmp = SubStrAsc;
3426 (*pp)++;
3427 } else if (IsDelimiter(mod[2], ch)) {
3428 if (mod[1] == 'n')
3429 cmp = SubNumAsc;
3430 else if (mod[1] == 'r')
3431 cmp = SubStrDesc;
3432 else if (mod[1] == 'x')
3433 cmp = NULL;
3434 else
3435 goto bad;
3436 *pp += 2;
3437 } else if (IsDelimiter(mod[3], ch)) {
3438 if ((mod[1] == 'n' && mod[2] == 'r') ||
3439 (mod[1] == 'r' && mod[2] == 'n'))
3440 cmp = SubNumDesc;
3441 else
3442 goto bad;
3443 *pp += 3;
3444 } else
3445 goto bad;
3446
3447 if (!ModChain_ShouldEval(ch))
3448 return AMR_OK;
3449
3450 words = Expr_Words(ch->expr);
3451 if (cmp == NULL)
3452 ShuffleSubstrings(words.words, words.len);
3453 else {
3454 assert(words.words[0].end[0] == '\0');
3455 qsort(words.words, words.len, sizeof(words.words[0]), cmp);
3456 }
3457 Expr_SetValueOwn(ch->expr, SubstringWords_JoinFree(words));
3458
3459 return AMR_OK;
3460
3461 bad:
3462 (*pp)++;
3463 return AMR_BAD;
3464 }
3465
3466 /* :? then : else */
3467 static ApplyModifierResult
3468 ApplyModifier_IfElse(const char **pp, ModChain *ch)
3469 {
3470 Expr *expr = ch->expr;
3471 LazyBuf thenBuf;
3472 LazyBuf elseBuf;
3473
3474 VarEvalMode then_emode = VARE_PARSE;
3475 VarEvalMode else_emode = VARE_PARSE;
3476
3477 CondResult cond_rc = CR_TRUE; /* just not CR_ERROR */
3478 if (Expr_ShouldEval(expr)) {
3479 evalStack.elems[evalStack.len - 1].kind = VSK_COND;
3480 cond_rc = Cond_EvalCondition(expr->name);
3481 if (cond_rc == CR_TRUE)
3482 then_emode = expr->emode;
3483 if (cond_rc == CR_FALSE)
3484 else_emode = expr->emode;
3485 }
3486
3487 evalStack.elems[evalStack.len - 1].kind = VSK_COND_THEN;
3488 (*pp)++; /* skip past the '?' */
3489 if (!ParseModifierPart(pp, ':', ':', then_emode,
3490 ch, &thenBuf, NULL, NULL))
3491 return AMR_CLEANUP;
3492
3493 evalStack.elems[evalStack.len - 1].kind = VSK_COND_ELSE;
3494 if (!ParseModifierPart(pp, ch->endc, ch->endc, else_emode,
3495 ch, &elseBuf, NULL, NULL)) {
3496 LazyBuf_Done(&thenBuf);
3497 return AMR_CLEANUP;
3498 }
3499
3500 (*pp)--; /* Go back to the ch->endc. */
3501
3502 if (cond_rc == CR_ERROR) {
3503 evalStack.elems[evalStack.len - 1].kind = VSK_COND;
3504 Parse_Error(PARSE_FATAL, "Bad condition");
3505 LazyBuf_Done(&thenBuf);
3506 LazyBuf_Done(&elseBuf);
3507 return AMR_CLEANUP;
3508 }
3509
3510 if (!Expr_ShouldEval(expr)) {
3511 LazyBuf_Done(&thenBuf);
3512 LazyBuf_Done(&elseBuf);
3513 } else if (cond_rc == CR_TRUE) {
3514 Expr_SetValue(expr, LazyBuf_DoneGet(&thenBuf));
3515 LazyBuf_Done(&elseBuf);
3516 } else {
3517 LazyBuf_Done(&thenBuf);
3518 Expr_SetValue(expr, LazyBuf_DoneGet(&elseBuf));
3519 }
3520 Expr_Define(expr);
3521 return AMR_OK;
3522 }
3523
3524 /*
3525 * The ::= modifiers are special in that they do not read the variable value
3526 * but instead assign to that variable. They always expand to an empty
3527 * string.
3528 *
3529 * Their main purpose is in supporting .for loops that generate shell commands
3530 * since an ordinary variable assignment at that point would terminate the
3531 * dependency group for these targets. For example:
3532 *
3533 * list-targets: .USE
3534 * .for i in ${.TARGET} ${.TARGET:R}.gz
3535 * @${t::=$i}
3536 * @echo 'The target is ${t:T}.'
3537 * .endfor
3538 *
3539 * ::=<str> Assigns <str> as the new value of variable.
3540 * ::?=<str> Assigns <str> as value of variable if
3541 * it was not already set.
3542 * ::+=<str> Appends <str> to variable.
3543 * ::!=<cmd> Assigns output of <cmd> as the new value of
3544 * variable.
3545 */
3546 static ApplyModifierResult
3547 ApplyModifier_Assign(const char **pp, ModChain *ch)
3548 {
3549 Expr *expr = ch->expr;
3550 GNode *scope;
3551 FStr val;
3552 LazyBuf buf;
3553
3554 const char *mod = *pp;
3555 const char *op = mod + 1;
3556
3557 if (op[0] == '=')
3558 goto found_op;
3559 if ((op[0] == '+' || op[0] == '?' || op[0] == '!') && op[1] == '=')
3560 goto found_op;
3561 return AMR_UNKNOWN; /* "::<unrecognized>" */
3562
3563 found_op:
3564 if (expr->name[0] == '\0') {
3565 *pp = mod + 1;
3566 return AMR_BAD;
3567 }
3568
3569 *pp = mod + (op[0] != '=' ? 3 : 2);
3570
3571 if (!ParseModifierPart(pp, ch->endc, ch->endc, expr->emode,
3572 ch, &buf, NULL, NULL))
3573 return AMR_CLEANUP;
3574 val = LazyBuf_DoneGet(&buf);
3575
3576 (*pp)--; /* Go back to the ch->endc. */
3577
3578 if (!Expr_ShouldEval(expr))
3579 goto done;
3580
3581 scope = expr->scope; /* scope where v belongs */
3582 if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL
3583 && VarFind(expr->name, expr->scope, false) == NULL)
3584 scope = SCOPE_GLOBAL;
3585
3586 if (op[0] == '+')
3587 Var_Append(scope, expr->name, val.str);
3588 else if (op[0] == '!') {
3589 char *output, *error;
3590 output = Cmd_Exec(val.str, &error);
3591 if (error != NULL) {
3592 Parse_Error(PARSE_WARNING, "%s", error);
3593 free(error);
3594 } else
3595 Var_Set(scope, expr->name, output);
3596 free(output);
3597 } else if (op[0] == '?' && expr->defined == DEF_REGULAR) {
3598 /* Do nothing. */
3599 } else
3600 Var_Set(scope, expr->name, val.str);
3601
3602 Expr_SetValueRefer(expr, "");
3603
3604 done:
3605 FStr_Done(&val);
3606 return AMR_OK;
3607 }
3608
3609 /*
3610 * :_=...
3611 * remember current value
3612 */
3613 static ApplyModifierResult
3614 ApplyModifier_Remember(const char **pp, ModChain *ch)
3615 {
3616 Expr *expr = ch->expr;
3617 const char *mod = *pp;
3618 FStr name;
3619
3620 if (!ModMatchEq(mod, "_", ch))
3621 return AMR_UNKNOWN;
3622
3623 name = FStr_InitRefer("_");
3624 if (mod[1] == '=') {
3625 /*
3626 * XXX: This ad-hoc call to strcspn deviates from the usual
3627 * behavior defined in ParseModifierPart. This creates an
3628 * unnecessary and undocumented inconsistency in make.
3629 */
3630 const char *arg = mod + 2;
3631 size_t argLen = strcspn(arg, ":)}");
3632 *pp = arg + argLen;
3633 name = FStr_InitOwn(bmake_strldup(arg, argLen));
3634 } else
3635 *pp = mod + 1;
3636
3637 if (Expr_ShouldEval(expr))
3638 Var_Set(SCOPE_GLOBAL, name.str, Expr_Str(expr));
3639 FStr_Done(&name);
3640
3641 return AMR_OK;
3642 }
3643
3644 /*
3645 * Apply the given function to each word of the variable value,
3646 * for a single-letter modifier such as :H, :T.
3647 */
3648 static ApplyModifierResult
3649 ApplyModifier_WordFunc(const char **pp, ModChain *ch,
3650 ModifyWordProc modifyWord)
3651 {
3652 if (!IsDelimiter((*pp)[1], ch))
3653 return AMR_UNKNOWN;
3654 (*pp)++;
3655
3656 ModifyWords(ch, modifyWord, NULL, ch->oneBigWord);
3657
3658 return AMR_OK;
3659 }
3660
3661 /* Remove adjacent duplicate words. */
3662 static ApplyModifierResult
3663 ApplyModifier_Unique(const char **pp, ModChain *ch)
3664 {
3665 SubstringWords words;
3666
3667 if (!IsDelimiter((*pp)[1], ch))
3668 return AMR_UNKNOWN;
3669 (*pp)++;
3670
3671 if (!ModChain_ShouldEval(ch))
3672 return AMR_OK;
3673
3674 words = Expr_Words(ch->expr);
3675
3676 if (words.len > 1) {
3677 size_t di, si;
3678
3679 di = 0;
3680 for (si = 1; si < words.len; si++) {
3681 if (!Substring_Eq(words.words[si], words.words[di])) {
3682 di++;
3683 if (di != si)
3684 words.words[di] = words.words[si];
3685 }
3686 }
3687 words.len = di + 1;
3688 }
3689
3690 Expr_SetValueOwn(ch->expr, SubstringWords_JoinFree(words));
3691
3692 return AMR_OK;
3693 }
3694
3695 /* Test whether the modifier has the form '<lhs>=<rhs>'. */
3696 static bool
3697 IsSysVModifier(const char *p, char startc, char endc)
3698 {
3699 bool eqFound = false;
3700
3701 int depth = 1;
3702 while (*p != '\0' && depth > 0) {
3703 if (*p == '=') /* XXX: should also test depth == 1 */
3704 eqFound = true;
3705 else if (*p == endc)
3706 depth--;
3707 else if (*p == startc)
3708 depth++;
3709 if (depth > 0)
3710 p++;
3711 }
3712 return *p == endc && eqFound;
3713 }
3714
3715 /* :from=to */
3716 static ApplyModifierResult
3717 ApplyModifier_SysV(const char **pp, ModChain *ch)
3718 {
3719 Expr *expr = ch->expr;
3720 LazyBuf lhsBuf, rhsBuf;
3721 FStr rhs;
3722 struct ModifyWord_SysVSubstArgs args;
3723 Substring lhs;
3724 const char *lhsSuffix;
3725
3726 const char *mod = *pp;
3727
3728 if (!IsSysVModifier(mod, ch->startc, ch->endc))
3729 return AMR_UNKNOWN;
3730
3731 if (!ParseModifierPart(pp, '=', '=', expr->emode,
3732 ch, &lhsBuf, NULL, NULL))
3733 return AMR_CLEANUP;
3734
3735 if (!ParseModifierPart(pp, ch->endc, ch->endc, expr->emode,
3736 ch, &rhsBuf, NULL, NULL)) {
3737 LazyBuf_Done(&lhsBuf);
3738 return AMR_CLEANUP;
3739 }
3740 rhs = LazyBuf_DoneGet(&rhsBuf);
3741
3742 (*pp)--; /* Go back to the ch->endc. */
3743
3744 /* Do not turn an empty expression into non-empty. */
3745 if (lhsBuf.len == 0 && Expr_Str(expr)[0] == '\0')
3746 goto done;
3747
3748 lhs = LazyBuf_Get(&lhsBuf);
3749 lhsSuffix = Substring_SkipFirst(lhs, '%');
3750
3751 args.scope = expr->scope;
3752 args.lhsPrefix = Substring_Init(lhs.start,
3753 lhsSuffix != lhs.start ? lhsSuffix - 1 : lhs.start);
3754 args.lhsPercent = lhsSuffix != lhs.start;
3755 args.lhsSuffix = Substring_Init(lhsSuffix, lhs.end);
3756 args.rhs = rhs.str;
3757
3758 ModifyWords(ch, ModifyWord_SysVSubst, &args, ch->oneBigWord);
3759
3760 done:
3761 LazyBuf_Done(&lhsBuf);
3762 FStr_Done(&rhs);
3763 return AMR_OK;
3764 }
3765
3766 /* :sh */
3767 static ApplyModifierResult
3768 ApplyModifier_SunShell(const char **pp, ModChain *ch)
3769 {
3770 Expr *expr = ch->expr;
3771 const char *p = *pp;
3772 if (!(p[1] == 'h' && IsDelimiter(p[2], ch)))
3773 return AMR_UNKNOWN;
3774 *pp = p + 2;
3775
3776 if (Expr_ShouldEval(expr)) {
3777 char *output, *error;
3778 output = Cmd_Exec(Expr_Str(expr), &error);
3779 if (error != NULL) {
3780 Parse_Error(PARSE_WARNING, "%s", error);
3781 free(error);
3782 }
3783 Expr_SetValueOwn(expr, output);
3784 }
3785
3786 return AMR_OK;
3787 }
3788
3789 /*
3790 * In cases where the evaluation mode and the definedness are the "standard"
3791 * ones, don't log them, to keep the logs readable.
3792 */
3793 static bool
3794 ShouldLogInSimpleFormat(const Expr *expr)
3795 {
3796 return (expr->emode == VARE_EVAL || expr->emode == VARE_EVAL_DEFINED)
3797 && expr->defined == DEF_REGULAR;
3798 }
3799
3800 static void
3801 LogBeforeApply(const ModChain *ch, const char *mod)
3802 {
3803 const Expr *expr = ch->expr;
3804 bool is_single_char = mod[0] != '\0' && IsDelimiter(mod[1], ch);
3805
3806 /*
3807 * At this point, only the first character of the modifier can
3808 * be used since the end of the modifier is not yet known.
3809 */
3810
3811 if (!Expr_ShouldEval(expr)) {
3812 debug_printf("Parsing modifier ${%s:%c%s}\n",
3813 expr->name, mod[0], is_single_char ? "" : "...");
3814 return;
3815 }
3816
3817 if (ShouldLogInSimpleFormat(expr)) {
3818 debug_printf(
3819 "Evaluating modifier ${%s:%c%s} on value \"%s\"\n",
3820 expr->name, mod[0], is_single_char ? "" : "...",
3821 Expr_Str(expr));
3822 return;
3823 }
3824
3825 debug_printf(
3826 "Evaluating modifier ${%s:%c%s} on value \"%s\" (%s, %s)\n",
3827 expr->name, mod[0], is_single_char ? "" : "...", Expr_Str(expr),
3828 VarEvalMode_Name[expr->emode], ExprDefined_Name[expr->defined]);
3829 }
3830
3831 static void
3832 LogAfterApply(const ModChain *ch, const char *p, const char *mod)
3833 {
3834 const Expr *expr = ch->expr;
3835 const char *value = Expr_Str(expr);
3836 const char *quot = value == var_Error ? "" : "\"";
3837
3838 if (ShouldLogInSimpleFormat(expr)) {
3839 debug_printf("Result of ${%s:%.*s} is %s%s%s\n",
3840 expr->name, (int)(p - mod), mod,
3841 quot, value == var_Error ? "error" : value, quot);
3842 return;
3843 }
3844
3845 debug_printf("Result of ${%s:%.*s} is %s%s%s (%s, %s)\n",
3846 expr->name, (int)(p - mod), mod,
3847 quot, value == var_Error ? "error" : value, quot,
3848 VarEvalMode_Name[expr->emode],
3849 ExprDefined_Name[expr->defined]);
3850 }
3851
3852 static ApplyModifierResult
3853 ApplyModifier(const char **pp, ModChain *ch)
3854 {
3855 switch (**pp) {
3856 case '!':
3857 return ApplyModifier_ShellCommand(pp, ch);
3858 case ':':
3859 return ApplyModifier_Assign(pp, ch);
3860 case '?':
3861 return ApplyModifier_IfElse(pp, ch);
3862 case '@':
3863 return ApplyModifier_Loop(pp, ch);
3864 case '[':
3865 return ApplyModifier_Words(pp, ch);
3866 case '_':
3867 return ApplyModifier_Remember(pp, ch);
3868 case 'C':
3869 return ApplyModifier_Regex(pp, ch);
3870 case 'D':
3871 case 'U':
3872 return ApplyModifier_Defined(pp, ch);
3873 case 'E':
3874 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Suffix);
3875 case 'g':
3876 case 'l':
3877 return ApplyModifier_Time(pp, ch);
3878 case 'H':
3879 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Head);
3880 case 'h':
3881 return ApplyModifier_Hash(pp, ch);
3882 case 'L':
3883 return ApplyModifier_Literal(pp, ch);
3884 case 'M':
3885 case 'N':
3886 return ApplyModifier_Match(pp, ch);
3887 case 'm':
3888 return ApplyModifier_Mtime(pp, ch);
3889 case 'O':
3890 return ApplyModifier_Order(pp, ch);
3891 case 'P':
3892 return ApplyModifier_Path(pp, ch);
3893 case 'Q':
3894 case 'q':
3895 return ApplyModifier_Quote(pp, ch);
3896 case 'R':
3897 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Root);
3898 case 'r':
3899 return ApplyModifier_Range(pp, ch);
3900 case 'S':
3901 return ApplyModifier_Subst(pp, ch);
3902 case 's':
3903 return ApplyModifier_SunShell(pp, ch);
3904 case 'T':
3905 return ApplyModifier_WordFunc(pp, ch, ModifyWord_Tail);
3906 case 't':
3907 return ApplyModifier_To(pp, ch);
3908 case 'u':
3909 return ApplyModifier_Unique(pp, ch);
3910 default:
3911 return AMR_UNKNOWN;
3912 }
3913 }
3914
3915 static void ApplyModifiers(Expr *, const char **, char, char);
3916
3917 typedef enum ApplyModifiersIndirectResult {
3918 /* The indirect modifiers have been applied successfully. */
3919 AMIR_CONTINUE,
3920 /* Fall back to the SysV modifier. */
3921 AMIR_SYSV,
3922 /* Error out. */
3923 AMIR_OUT
3924 } ApplyModifiersIndirectResult;
3925
3926 /*
3927 * While expanding an expression, expand and apply indirect modifiers,
3928 * such as in ${VAR:${M_indirect}}.
3929 *
3930 * All indirect modifiers of a group must come from a single
3931 * expression. ${VAR:${M1}} is valid but ${VAR:${M1}${M2}} is not.
3932 *
3933 * Multiple groups of indirect modifiers can be chained by separating them
3934 * with colons. ${VAR:${M1}:${M2}} contains 2 indirect modifiers.
3935 *
3936 * If the expression is not followed by ch->endc or ':', fall
3937 * back to trying the SysV modifier, such as in ${VAR:${FROM}=${TO}}.
3938 */
3939 static ApplyModifiersIndirectResult
3940 ApplyModifiersIndirect(ModChain *ch, const char **pp)
3941 {
3942 Expr *expr = ch->expr;
3943 const char *p = *pp;
3944 FStr mods = Var_Parse(&p, expr->scope, expr->emode);
3945 /* TODO: handle errors */
3946
3947 if (mods.str[0] != '\0' && !IsDelimiter(*p, ch)) {
3948 FStr_Done(&mods);
3949 return AMIR_SYSV;
3950 }
3951
3952 DEBUG3(VAR, "Indirect modifier \"%s\" from \"%.*s\"\n",
3953 mods.str, (int)(p - *pp), *pp);
3954
3955 if (ModChain_ShouldEval(ch) && mods.str[0] != '\0') {
3956 const char *modsp = mods.str;
3957 ApplyModifiers(expr, &modsp, '\0', '\0');
3958 if (Expr_Str(expr) == var_Error || *modsp != '\0') {
3959 FStr_Done(&mods);
3960 *pp = p;
3961 return AMIR_OUT; /* error already reported */
3962 }
3963 }
3964 FStr_Done(&mods);
3965
3966 if (*p == ':')
3967 p++;
3968 else if (*p == '\0' && ch->endc != '\0') {
3969 Parse_Error(PARSE_FATAL,
3970 "Unclosed expression after indirect modifier, "
3971 "expecting '%c'",
3972 ch->endc);
3973 *pp = p;
3974 return AMIR_OUT;
3975 }
3976
3977 *pp = p;
3978 return AMIR_CONTINUE;
3979 }
3980
3981 static ApplyModifierResult
3982 ApplySingleModifier(const char **pp, ModChain *ch)
3983 {
3984 ApplyModifierResult res;
3985 const char *mod = *pp;
3986 const char *p = *pp;
3987
3988 if (DEBUG(VAR))
3989 LogBeforeApply(ch, mod);
3990
3991 res = ApplyModifier(&p, ch);
3992
3993 if (res == AMR_UNKNOWN) {
3994 assert(p == mod);
3995 res = ApplyModifier_SysV(&p, ch);
3996 }
3997
3998 if (res == AMR_UNKNOWN) {
3999 /*
4000 * Guess the end of the current modifier.
4001 * XXX: Skipping the rest of the modifier hides
4002 * errors and leads to wrong results.
4003 * Parsing should rather stop here.
4004 */
4005 for (p++; !IsDelimiter(*p, ch); p++)
4006 continue;
4007 Parse_Error(PARSE_FATAL, "Unknown modifier \"%.*s\"",
4008 (int)(p - mod), mod);
4009 Expr_SetValueRefer(ch->expr, var_Error);
4010 }
4011 if (res == AMR_CLEANUP || res == AMR_BAD) {
4012 *pp = p;
4013 return res;
4014 }
4015
4016 if (DEBUG(VAR))
4017 LogAfterApply(ch, p, mod);
4018
4019 if (*p == '\0' && ch->endc != '\0') {
4020 Parse_Error(PARSE_FATAL,
4021 "Unclosed expression, expecting '%c' for "
4022 "modifier \"%.*s\"",
4023 ch->endc, (int)(p - mod), mod);
4024 } else if (*p == ':') {
4025 p++;
4026 } else if (opts.strict && *p != '\0' && *p != ch->endc) {
4027 Parse_Error(PARSE_FATAL,
4028 "Missing delimiter ':' after modifier \"%.*s\"",
4029 (int)(p - mod), mod);
4030 /*
4031 * TODO: propagate parse error to the enclosing
4032 * expression
4033 */
4034 }
4035 *pp = p;
4036 return AMR_OK;
4037 }
4038
4039 #if __STDC_VERSION__ >= 199901L
4040 #define ModChain_Init(expr, startc, endc, sep, oneBigWord) \
4041 (ModChain) { expr, startc, endc, sep, oneBigWord }
4042 #else
4043 MAKE_INLINE ModChain
4044 ModChain_Init(Expr *expr, char startc, char endc, char sep, bool oneBigWord)
4045 {
4046 ModChain ch;
4047 ch.expr = expr;
4048 ch.startc = startc;
4049 ch.endc = endc;
4050 ch.sep = sep;
4051 ch.oneBigWord = oneBigWord;
4052 return ch;
4053 }
4054 #endif
4055
4056 /* Apply any modifiers (such as :Mpattern or :@var@loop@ or :Q or ::=value). */
4057 static void
4058 ApplyModifiers(
4059 Expr *expr,
4060 const char **pp, /* the parsing position, updated upon return */
4061 char startc, /* '(' or '{'; or '\0' for indirect modifiers */
4062 char endc /* ')' or '}'; or '\0' for indirect modifiers */
4063 )
4064 {
4065 ModChain ch = ModChain_Init(expr, startc, endc, ' ', false);
4066 const char *p;
4067 const char *mod;
4068
4069 assert(startc == '(' || startc == '{' || startc == '\0');
4070 assert(endc == ')' || endc == '}' || endc == '\0');
4071 assert(Expr_Str(expr) != NULL);
4072
4073 p = *pp;
4074
4075 if (*p == '\0' && endc != '\0') {
4076 Parse_Error(PARSE_FATAL,
4077 "Unclosed expression, expecting '%c'", ch.endc);
4078 goto cleanup;
4079 }
4080
4081 while (*p != '\0' && *p != endc) {
4082 ApplyModifierResult res;
4083
4084 if (*p == '$') {
4085 /*
4086 * TODO: Only evaluate the expression once, no matter
4087 * whether it's an indirect modifier or the initial
4088 * part of a SysV modifier.
4089 */
4090 ApplyModifiersIndirectResult amir =
4091 ApplyModifiersIndirect(&ch, &p);
4092 if (amir == AMIR_CONTINUE)
4093 continue;
4094 if (amir == AMIR_OUT)
4095 break;
4096 }
4097
4098 mod = p;
4099
4100 res = ApplySingleModifier(&p, &ch);
4101 if (res == AMR_CLEANUP)
4102 goto cleanup;
4103 if (res == AMR_BAD)
4104 goto bad_modifier;
4105 }
4106
4107 *pp = p;
4108 assert(Expr_Str(expr) != NULL); /* Use var_Error or varUndefined. */
4109 return;
4110
4111 bad_modifier:
4112 /* Take a guess at where the modifier ends. */
4113 Parse_Error(PARSE_FATAL, "Bad modifier \":%.*s\"",
4114 (int)strcspn(mod, ":)}"), mod);
4115
4116 cleanup:
4117 /*
4118 * TODO: Use p + strlen(p) instead, to stop parsing immediately.
4119 *
4120 * In the unit tests, this generates a few shell commands with
4121 * unbalanced quotes. Instead of producing these incomplete strings,
4122 * commands with evaluation errors should not be run at all.
4123 *
4124 * To make that happen, Var_Subst must report the actual errors
4125 * instead of returning the resulting string unconditionally.
4126 */
4127 *pp = p;
4128 Expr_SetValueRefer(expr, var_Error);
4129 }
4130
4131 /*
4132 * Only 4 of the 7 built-in local variables are treated specially as they are
4133 * the only ones that will be set when dynamic sources are expanded.
4134 */
4135 static bool
4136 VarnameIsDynamic(Substring varname)
4137 {
4138 const char *name;
4139 size_t len;
4140
4141 name = varname.start;
4142 len = Substring_Length(varname);
4143 if (len == 1 || (len == 2 && (name[1] == 'F' || name[1] == 'D'))) {
4144 switch (name[0]) {
4145 case '@':
4146 case '%':
4147 case '*':
4148 case '!':
4149 return true;
4150 }
4151 return false;
4152 }
4153
4154 if ((len == 7 || len == 8) && name[0] == '.' && ch_isupper(name[1])) {
4155 return Substring_Equals(varname, ".TARGET") ||
4156 Substring_Equals(varname, ".ARCHIVE") ||
4157 Substring_Equals(varname, ".PREFIX") ||
4158 Substring_Equals(varname, ".MEMBER");
4159 }
4160
4161 return false;
4162 }
4163
4164 static const char *
4165 UndefinedShortVarValue(char varname, const GNode *scope)
4166 {
4167 if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL) {
4168 /*
4169 * If substituting a local variable in a non-local scope,
4170 * assume it's for dynamic source stuff. We have to handle
4171 * this specially and return the longhand for the variable
4172 * with the dollar sign escaped so it makes it back to the
4173 * caller. Only four of the local variables are treated
4174 * specially as they are the only four that will be set
4175 * when dynamic sources are expanded.
4176 */
4177 switch (varname) {
4178 case '@':
4179 return "$(.TARGET)";
4180 case '%':
4181 return "$(.MEMBER)";
4182 case '*':
4183 return "$(.PREFIX)";
4184 case '!':
4185 return "$(.ARCHIVE)";
4186 }
4187 }
4188 return NULL;
4189 }
4190
4191 /*
4192 * Parse a variable name, until the end character or a colon, whichever
4193 * comes first.
4194 */
4195 static void
4196 ParseVarname(const char **pp, char startc, char endc,
4197 GNode *scope, VarEvalMode emode,
4198 LazyBuf *buf)
4199 {
4200 const char *p = *pp;
4201 int depth = 0;
4202
4203 LazyBuf_Init(buf, p);
4204
4205 while (*p != '\0') {
4206 if ((*p == endc || *p == ':') && depth == 0)
4207 break;
4208 if (*p == startc)
4209 depth++;
4210 if (*p == endc)
4211 depth--;
4212
4213 if (*p == '$') {
4214 FStr nested_val = Var_Parse(&p, scope, emode);
4215 /* TODO: handle errors */
4216 LazyBuf_AddStr(buf, nested_val.str);
4217 FStr_Done(&nested_val);
4218 } else {
4219 LazyBuf_Add(buf, *p);
4220 p++;
4221 }
4222 }
4223 *pp = p;
4224 }
4225
4226 static bool
4227 IsShortVarnameValid(char varname, const char *start)
4228 {
4229 if (varname != '$' && varname != ':' && varname != '}' &&
4230 varname != ')' && varname != '\0')
4231 return true;
4232
4233 if (!opts.strict)
4234 return false; /* XXX: Missing error message */
4235
4236 if (varname == '$' && save_dollars)
4237 Parse_Error(PARSE_FATAL,
4238 "To escape a dollar, use \\$, not $$, at \"%s\"", start);
4239 else if (varname == '\0')
4240 Parse_Error(PARSE_FATAL, "Dollar followed by nothing");
4241 else if (save_dollars)
4242 Parse_Error(PARSE_FATAL,
4243 "Invalid variable name '%c', at \"%s\"", varname, start);
4244
4245 return false;
4246 }
4247
4248 /*
4249 * Parse a single-character variable name such as in $V or $@.
4250 * Return whether to continue parsing.
4251 */
4252 static bool
4253 ParseVarnameShort(char varname, const char **pp, GNode *scope,
4254 VarEvalMode emode,
4255 const char **out_false_val,
4256 Var **out_true_var)
4257 {
4258 char name[2];
4259 Var *v;
4260 const char *val;
4261
4262 if (!IsShortVarnameValid(varname, *pp)) {
4263 (*pp)++; /* only skip the '$' */
4264 *out_false_val = var_Error;
4265 return false;
4266 }
4267
4268 name[0] = varname;
4269 name[1] = '\0';
4270 v = VarFind(name, scope, true);
4271 if (v != NULL) {
4272 /* No need to advance *pp, the calling code handles this. */
4273 *out_true_var = v;
4274 return true;
4275 }
4276
4277 *pp += 2;
4278
4279 val = UndefinedShortVarValue(varname, scope);
4280 if (val == NULL)
4281 val = emode == VARE_EVAL_DEFINED ? var_Error : varUndefined;
4282
4283 if (opts.strict && val == var_Error) {
4284 Parse_Error(PARSE_FATAL,
4285 "Variable \"%s\" is undefined", name);
4286 }
4287
4288 *out_false_val = val;
4289 return false;
4290 }
4291
4292 /* Find variables like @F or <D. */
4293 static Var *
4294 FindLocalLegacyVar(Substring varname, GNode *scope,
4295 const char **out_extraModifiers)
4296 {
4297 Var *v;
4298
4299 /* Only resolve these variables if scope is a "real" target. */
4300 if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL)
4301 return NULL;
4302
4303 if (Substring_Length(varname) != 2)
4304 return NULL;
4305 if (varname.start[1] != 'F' && varname.start[1] != 'D')
4306 return NULL;
4307 if (strchr("@%?*!<>", varname.start[0]) == NULL)
4308 return NULL;
4309
4310 v = VarFindSubstring(Substring_Init(varname.start, varname.start + 1),
4311 scope, false);
4312 if (v == NULL)
4313 return NULL;
4314
4315 *out_extraModifiers = varname.start[1] == 'D' ? "H:" : "T:";
4316 return v;
4317 }
4318
4319 static FStr
4320 EvalUndefined(bool dynamic, const char *start, const char *p,
4321 Substring varname, VarEvalMode emode)
4322 {
4323 if (dynamic)
4324 return FStr_InitOwn(bmake_strsedup(start, p));
4325
4326 if (emode == VARE_EVAL_DEFINED && opts.strict) {
4327 Parse_Error(PARSE_FATAL,
4328 "Variable \"%.*s\" is undefined",
4329 (int)Substring_Length(varname), varname.start);
4330 return FStr_InitRefer(var_Error);
4331 }
4332
4333 return FStr_InitRefer(
4334 emode == VARE_EVAL_DEFINED ? var_Error : varUndefined);
4335 }
4336
4337 /*
4338 * Parse a long variable name enclosed in braces or parentheses such as $(VAR)
4339 * or ${VAR}, up to the closing brace or parenthesis, or in the case of
4340 * ${VAR:Modifiers}, up to the ':' that starts the modifiers.
4341 * Return whether to continue parsing.
4342 */
4343 static bool
4344 ParseVarnameLong(
4345 const char **pp,
4346 char startc,
4347 GNode *scope,
4348 VarEvalMode emode,
4349
4350 const char **out_false_pp,
4351 FStr *out_false_val,
4352
4353 char *out_true_endc,
4354 Var **out_true_v,
4355 bool *out_true_haveModifier,
4356 const char **out_true_extraModifiers,
4357 bool *out_true_dynamic,
4358 ExprDefined *out_true_exprDefined
4359 )
4360 {
4361 LazyBuf varname;
4362 Substring name;
4363 Var *v;
4364 bool haveModifier;
4365 bool dynamic = false;
4366
4367 const char *p = *pp;
4368 const char *start = p;
4369 char endc = startc == '(' ? ')' : '}';
4370
4371 p += 2; /* skip "${" or "$(" or "y(" */
4372 ParseVarname(&p, startc, endc, scope, emode, &varname);
4373 name = LazyBuf_Get(&varname);
4374
4375 if (*p == ':')
4376 haveModifier = true;
4377 else if (*p == endc)
4378 haveModifier = false;
4379 else {
4380 Parse_Error(PARSE_FATAL, "Unclosed variable \"%.*s\"",
4381 (int)Substring_Length(name), name.start);
4382 LazyBuf_Done(&varname);
4383 *out_false_pp = p;
4384 *out_false_val = FStr_InitRefer(var_Error);
4385 return false;
4386 }
4387
4388 v = VarFindSubstring(name, scope, true);
4389
4390 /*
4391 * At this point, p points just after the variable name, either at
4392 * ':' or at endc.
4393 */
4394
4395 if (v == NULL && Substring_Equals(name, ".SUFFIXES")) {
4396 char *suffixes = Suff_NamesStr();
4397 v = VarNew(FStr_InitRefer(".SUFFIXES"), suffixes,
4398 true, false, true);
4399 free(suffixes);
4400 } else if (v == NULL)
4401 v = FindLocalLegacyVar(name, scope, out_true_extraModifiers);
4402
4403 if (v == NULL) {
4404 /*
4405 * Defer expansion of dynamic variables if they appear in
4406 * non-local scope since they are not defined there.
4407 */
4408 dynamic = VarnameIsDynamic(name) &&
4409 (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL);
4410
4411 if (!haveModifier) {
4412 p++; /* skip endc */
4413 *out_false_pp = p;
4414 *out_false_val = EvalUndefined(dynamic, start, p,
4415 name, emode);
4416 LazyBuf_Done(&varname);
4417 return false;
4418 }
4419
4420 /*
4421 * The expression is based on an undefined variable.
4422 * Nevertheless it needs a Var, for modifiers that access the
4423 * variable name, such as :L or :?.
4424 *
4425 * Most modifiers leave this expression in the "undefined"
4426 * state (DEF_UNDEF), only a few modifiers like :D, :U, :L,
4427 * :P turn this undefined expression into a defined
4428 * expression (DEF_DEFINED).
4429 *
4430 * In the end, after applying all modifiers, if the expression
4431 * is still undefined, Var_Parse will return an empty string
4432 * instead of the actually computed value.
4433 */
4434 v = VarNew(LazyBuf_DoneGet(&varname), "",
4435 true, false, false);
4436 *out_true_exprDefined = DEF_UNDEF;
4437 } else
4438 LazyBuf_Done(&varname);
4439
4440 *pp = p;
4441 *out_true_endc = endc;
4442 *out_true_v = v;
4443 *out_true_haveModifier = haveModifier;
4444 *out_true_dynamic = dynamic;
4445 return true;
4446 }
4447
4448 #if __STDC_VERSION__ >= 199901L
4449 #define Expr_Init(name, value, emode, scope, defined) \
4450 (Expr) { name, value, emode, scope, defined }
4451 #else
4452 MAKE_INLINE Expr
4453 Expr_Init(const char *name, FStr value,
4454 VarEvalMode emode, GNode *scope, ExprDefined defined)
4455 {
4456 Expr expr;
4457
4458 expr.name = name;
4459 expr.value = value;
4460 expr.emode = emode;
4461 expr.scope = scope;
4462 expr.defined = defined;
4463 return expr;
4464 }
4465 #endif
4466
4467 /*
4468 * Expressions of the form ${:U...} with a trivial value are often generated
4469 * by .for loops and are boring, so evaluate them without debug logging.
4470 */
4471 static bool
4472 Var_Parse_U(const char **pp, VarEvalMode emode, FStr *out_value)
4473 {
4474 const char *p;
4475
4476 p = *pp;
4477 if (!(p[0] == '$' && p[1] == '{' && p[2] == ':' && p[3] == 'U'))
4478 return false;
4479
4480 p += 4;
4481 while (*p != '$' && *p != '{' && *p != ':' && *p != '\\' &&
4482 *p != '}' && *p != '\0')
4483 p++;
4484 if (*p != '}')
4485 return false;
4486
4487 *out_value = emode == VARE_PARSE
4488 ? FStr_InitRefer("")
4489 : FStr_InitOwn(bmake_strsedup(*pp + 4, p));
4490 *pp = p + 1;
4491 return true;
4492 }
4493
4494 /*
4495 * Given the start of an expression (such as $v, $(VAR), ${VAR:Mpattern}),
4496 * extract the variable name and the modifiers, if any. While parsing, apply
4497 * the modifiers to the value of the expression.
4498 *
4499 * Input:
4500 * *pp The string to parse.
4501 * When called from CondParser_FuncCallEmpty, it can
4502 * also point to the "y" of "empty(VARNAME:Modifiers)".
4503 * scope The scope for finding variables.
4504 * emode Controls the exact details of parsing and evaluation.
4505 *
4506 * Output:
4507 * *pp The position where to continue parsing.
4508 * TODO: After a parse error, the value of *pp is
4509 * unspecified. It may not have been updated at all,
4510 * point to some random character in the string, to the
4511 * location of the parse error, or at the end of the
4512 * string.
4513 * return The value of the expression, never NULL.
4514 * return var_Error if there was a parse error.
4515 * return var_Error if the base variable of the expression was
4516 * undefined, emode is VARE_EVAL_DEFINED, and none of
4517 * the modifiers turned the undefined expression into a
4518 * defined expression.
4519 * XXX: It is not guaranteed that an error message has
4520 * been printed.
4521 * return varUndefined if the base variable of the expression
4522 * was undefined, emode was not VARE_EVAL_DEFINED,
4523 * and none of the modifiers turned the undefined
4524 * expression into a defined expression.
4525 * XXX: It is not guaranteed that an error message has
4526 * been printed.
4527 */
4528 FStr
4529 Var_Parse(const char **pp, GNode *scope, VarEvalMode emode)
4530 {
4531 const char *start, *p;
4532 bool haveModifier; /* true for ${VAR:...}, false for ${VAR} */
4533 char startc; /* the actual '{' or '(' or '\0' */
4534 char endc; /* the expected '}' or ')' or '\0' */
4535 /*
4536 * true if the expression is based on one of the 7 predefined
4537 * variables that are local to a target, and the expression is
4538 * expanded in a non-local scope. The result is the text of the
4539 * expression, unaltered. This is needed to support dynamic sources.
4540 */
4541 bool dynamic;
4542 const char *extramodifiers;
4543 Var *v;
4544 Expr expr = Expr_Init(NULL, FStr_InitRefer(NULL), emode,
4545 scope, DEF_REGULAR);
4546 FStr val;
4547
4548 if (Var_Parse_U(pp, emode, &val))
4549 return val;
4550
4551 p = *pp;
4552 start = p;
4553 DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]);
4554
4555 val = FStr_InitRefer(NULL);
4556 extramodifiers = NULL; /* extra modifiers to apply first */
4557 dynamic = false;
4558
4559 endc = '\0'; /* Appease GCC. */
4560
4561 startc = p[1];
4562 if (startc != '(' && startc != '{') {
4563 if (!ParseVarnameShort(startc, pp, scope, emode, &val.str, &v))
4564 return val;
4565 haveModifier = false;
4566 p++;
4567 } else {
4568 if (!ParseVarnameLong(&p, startc, scope, emode,
4569 pp, &val,
4570 &endc, &v, &haveModifier, &extramodifiers,
4571 &dynamic, &expr.defined))
4572 return val;
4573 }
4574
4575 expr.name = v->name.str;
4576 if (v->inUse && VarEvalMode_ShouldEval(emode)) {
4577 if (scope->fname != NULL) {
4578 fprintf(stderr, "In a command near ");
4579 PrintLocation(stderr, false, scope);
4580 }
4581 Fatal("Variable %s is recursive.", v->name.str);
4582 }
4583
4584 /*
4585 * FIXME: This assignment creates an alias to the current value of the
4586 * variable. This means that as long as the value of the expression
4587 * stays the same, the value of the variable must not change, and the
4588 * variable must not be deleted. Using the ':@' modifier, it is
4589 * possible (since var.c 1.212 from 2017-02-01) to delete the variable
4590 * while its value is still being used:
4591 *
4592 * VAR= value
4593 * _:= ${VAR:${:U:@VAR@@}:S,^,prefix,}
4594 *
4595 * The same effect might be achievable using the '::=' or the ':_'
4596 * modifiers.
4597 *
4598 * At the bottom of this function, the resulting value is compared to
4599 * the then-current value of the variable. This might also invoke
4600 * undefined behavior.
4601 */
4602 expr.value = FStr_InitRefer(v->val.data);
4603
4604 if (expr.name[0] != '\0')
4605 EvalStack_Push(VSK_VARNAME, expr.name, &expr.value);
4606 else
4607 EvalStack_Push(VSK_EXPR, start, &expr.value);
4608
4609 /*
4610 * Before applying any modifiers, expand any nested expressions from
4611 * the variable value.
4612 */
4613 if (VarEvalMode_ShouldEval(emode) &&
4614 strchr(Expr_Str(&expr), '$') != NULL) {
4615 char *expanded;
4616 VarEvalMode nested_emode = emode;
4617 if (opts.strict)
4618 nested_emode = VarEvalMode_UndefOk(nested_emode);
4619 v->inUse = true;
4620 expanded = Var_Subst(Expr_Str(&expr), scope, nested_emode);
4621 v->inUse = false;
4622 /* TODO: handle errors */
4623 Expr_SetValueOwn(&expr, expanded);
4624 }
4625
4626 if (extramodifiers != NULL) {
4627 const char *em = extramodifiers;
4628 ApplyModifiers(&expr, &em, '\0', '\0');
4629 }
4630
4631 if (haveModifier) {
4632 p++; /* Skip initial colon. */
4633 ApplyModifiers(&expr, &p, startc, endc);
4634 }
4635
4636 if (*p != '\0') /* Skip past endc if possible. */
4637 p++;
4638
4639 *pp = p;
4640
4641 if (expr.defined == DEF_UNDEF) {
4642 if (dynamic)
4643 Expr_SetValueOwn(&expr, bmake_strsedup(start, p));
4644 else {
4645 /*
4646 * The expression is still undefined, therefore
4647 * discard the actual value and return an error marker
4648 * instead.
4649 */
4650 Expr_SetValueRefer(&expr,
4651 emode == VARE_EVAL_DEFINED
4652 ? var_Error : varUndefined);
4653 }
4654 }
4655
4656 if (v->shortLived) {
4657 if (expr.value.str == v->val.data) {
4658 /* move ownership */
4659 expr.value.freeIt = v->val.data;
4660 v->val.data = NULL;
4661 }
4662 VarFreeShortLived(v);
4663 }
4664
4665 EvalStack_Pop();
4666 return expr.value;
4667 }
4668
4669 static void
4670 VarSubstDollarDollar(const char **pp, Buffer *res, VarEvalMode emode)
4671 {
4672 /* A dollar sign may be escaped with another dollar sign. */
4673 if (save_dollars && VarEvalMode_ShouldKeepDollar(emode))
4674 Buf_AddByte(res, '$');
4675 Buf_AddByte(res, '$');
4676 *pp += 2;
4677 }
4678
4679 static void
4680 VarSubstExpr(const char **pp, Buffer *buf, GNode *scope,
4681 VarEvalMode emode, bool *inout_errorReported)
4682 {
4683 const char *p = *pp;
4684 const char *nested_p = p;
4685 FStr val = Var_Parse(&nested_p, scope, emode);
4686 /* TODO: handle errors */
4687
4688 if (val.str == var_Error || val.str == varUndefined) {
4689 if (!VarEvalMode_ShouldKeepUndef(emode)) {
4690 p = nested_p;
4691 } else if (val.str == var_Error) {
4692
4693 /*
4694 * FIXME: The condition 'val.str == var_Error' doesn't
4695 * mean there was an undefined variable. It could
4696 * equally well be a parse error; see
4697 * unit-tests/varmod-order.mk.
4698 */
4699
4700 /*
4701 * If variable is undefined, complain and skip the
4702 * variable. The complaint will stop us from doing
4703 * anything when the file is parsed.
4704 */
4705 if (!*inout_errorReported) {
4706 Parse_Error(PARSE_FATAL,
4707 "Undefined variable \"%.*s\"",
4708 (int)(nested_p - p), p);
4709 *inout_errorReported = true;
4710 }
4711 p = nested_p;
4712 } else {
4713 /*
4714 * Copy the initial '$' of the undefined expression,
4715 * thereby deferring expansion of the expression, but
4716 * expand nested expressions if already possible. See
4717 * unit-tests/varparse-undef-partial.mk.
4718 */
4719 Buf_AddByte(buf, *p);
4720 p++;
4721 }
4722 } else {
4723 p = nested_p;
4724 Buf_AddStr(buf, val.str);
4725 }
4726
4727 FStr_Done(&val);
4728
4729 *pp = p;
4730 }
4731
4732 /*
4733 * Skip as many characters as possible -- either to the end of the string,
4734 * or to the next dollar sign, which may start an expression.
4735 */
4736 static void
4737 VarSubstPlain(const char **pp, Buffer *res)
4738 {
4739 const char *p = *pp;
4740 const char *start = p;
4741
4742 for (p++; *p != '$' && *p != '\0'; p++)
4743 continue;
4744 Buf_AddRange(res, start, p);
4745 *pp = p;
4746 }
4747
4748 /*
4749 * Expand all expressions like $V, ${VAR}, $(VAR:Modifiers) in the
4750 * given string.
4751 *
4752 * Input:
4753 * str The string in which the expressions are expanded.
4754 * scope The scope in which to start searching for variables.
4755 * The other scopes are searched as well.
4756 * emode The mode for parsing or evaluating subexpressions.
4757 */
4758 char *
4759 Var_Subst(const char *str, GNode *scope, VarEvalMode emode)
4760 {
4761 const char *p = str;
4762 Buffer res;
4763
4764 /*
4765 * Set true if an error has already been reported, to prevent a
4766 * plethora of messages when recursing
4767 */
4768 static bool errorReported;
4769
4770 Buf_Init(&res);
4771 errorReported = false;
4772
4773 while (*p != '\0') {
4774 if (p[0] == '$' && p[1] == '$')
4775 VarSubstDollarDollar(&p, &res, emode);
4776 else if (p[0] == '$')
4777 VarSubstExpr(&p, &res, scope, emode, &errorReported);
4778 else
4779 VarSubstPlain(&p, &res);
4780 }
4781
4782 return Buf_DoneData(&res);
4783 }
4784
4785 char *
4786 Var_SubstInTarget(const char *str, GNode *scope)
4787 {
4788 char *res;
4789 EvalStack_Push(VSK_TARGET, scope->name, NULL);
4790 res = Var_Subst(str, scope, VARE_EVAL);
4791 EvalStack_Pop();
4792 return res;
4793 }
4794
4795 void
4796 Var_Expand(FStr *str, GNode *scope, VarEvalMode emode)
4797 {
4798 char *expanded;
4799
4800 if (strchr(str->str, '$') == NULL)
4801 return;
4802 expanded = Var_Subst(str->str, scope, emode);
4803 /* TODO: handle errors */
4804 FStr_Done(str);
4805 *str = FStr_InitOwn(expanded);
4806 }
4807
4808 /* Initialize the variables module. */
4809 void
4810 Var_Init(void)
4811 {
4812 SCOPE_INTERNAL = GNode_New("Internal");
4813 SCOPE_GLOBAL = GNode_New("Global");
4814 SCOPE_CMDLINE = GNode_New("Command");
4815 }
4816
4817 /* Clean up the variables module. */
4818 void
4819 Var_End(void)
4820 {
4821 Var_Stats();
4822 }
4823
4824 void
4825 Var_Stats(void)
4826 {
4827 HashTable_DebugStats(&SCOPE_GLOBAL->vars, "Global variables");
4828 }
4829
4830 static int
4831 StrAsc(const void *sa, const void *sb)
4832 {
4833 return strcmp(
4834 *((const char *const *)sa), *((const char *const *)sb));
4835 }
4836
4837
4838 /* Print all variables in a scope, sorted by name. */
4839 void
4840 Var_Dump(GNode *scope)
4841 {
4842 Vector /* of const char * */ vec;
4843 HashIter hi;
4844 size_t i;
4845 const char **varnames;
4846
4847 Vector_Init(&vec, sizeof(const char *));
4848
4849 HashIter_Init(&hi, &scope->vars);
4850 while (HashIter_Next(&hi))
4851 *(const char **)Vector_Push(&vec) = hi.entry->key;
4852 varnames = vec.items;
4853
4854 qsort(varnames, vec.len, sizeof varnames[0], StrAsc);
4855
4856 for (i = 0; i < vec.len; i++) {
4857 const char *varname = varnames[i];
4858 const Var *var = HashTable_FindValue(&scope->vars, varname);
4859 debug_printf("%-16s = %s%s\n", varname,
4860 var->val.data, ValueDescription(var->val.data));
4861 }
4862
4863 Vector_Done(&vec);
4864 }
4865