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