]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/var.c
When elftoolchain's objcopy (or strip) is rewriting a file in-place,
[FreeBSD/FreeBSD.git] / contrib / bmake / var.c
1 /*      $NetBSD: var.c,v 1.641 2020/11/01 23:17:40 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         Set the value of the variable, creating it if
84  *                      necessary.
85  *
86  *      Var_Append      Append more characters to the variable, creating it if
87  *                      necessary. A space is placed between the old value and
88  *                      the new one.
89  *
90  *      Var_Exists      See if a variable exists.
91  *
92  *      Var_Value       Return the unexpanded value of a variable, or NULL if
93  *                      the variable is undefined.
94  *
95  *      Var_Subst       Substitute all variable expressions in a string.
96  *
97  *      Var_Parse       Parse a variable expression such as ${VAR:Mpattern}.
98  *
99  *      Var_Delete      Delete a variable.
100  *
101  *      Var_ExportVars  Export some or even all variables to the environment
102  *                      of this process and its child processes.
103  *
104  *      Var_Export      Export the variable to the environment of this process
105  *                      and its child processes.
106  *
107  *      Var_UnExport    Don't export the variable anymore.
108  *
109  * Debugging:
110  *      Var_Stats       Print out hashing statistics if in -dh mode.
111  *
112  *      Var_Dump        Print out all variables defined in the given context.
113  *
114  * XXX: There's a lot of duplication in these functions.
115  */
116
117 #include <sys/stat.h>
118 #include <sys/types.h>
119 #ifndef NO_REGEX
120 #include <regex.h>
121 #endif
122
123 #include "make.h"
124
125 #include <errno.h>
126 #ifdef HAVE_INTTYPES_H
127 #include <inttypes.h>
128 #elif defined(HAVE_STDINT_H)
129 #include <stdint.h>
130 #endif
131 #ifdef HAVE_LIMITS_H
132 #include <limits.h>
133 #endif
134 #include <time.h>
135
136 #include "dir.h"
137 #include "job.h"
138 #include "metachar.h"
139
140 /*      "@(#)var.c      8.3 (Berkeley) 3/19/94" */
141 MAKE_RCSID("$NetBSD: var.c,v 1.641 2020/11/01 23:17:40 rillig Exp $");
142
143 #define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1)
144 #define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2)
145 #define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3)
146 #define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4)
147
148 ENUM_FLAGS_RTTI_3(VarEvalFlags,
149                   VARE_UNDEFERR, VARE_WANTRES, VARE_ASSIGN);
150
151 /*
152  * This lets us tell if we have replaced the original environ
153  * (which we cannot free).
154  */
155 char **savedEnv = NULL;
156
157 /* Special return value for Var_Parse, indicating a parse error.  It may be
158  * caused by an undefined variable, a syntax error in a modifier or
159  * something entirely different. */
160 char var_Error[] = "";
161
162 /* Special return value for Var_Parse, indicating an undefined variable in
163  * a case where VARE_UNDEFERR is not set.  This undefined variable is
164  * typically a dynamic variable such as ${.TARGET}, whose expansion needs to
165  * be deferred until it is defined in an actual target. */
166 static char varUndefined[] = "";
167
168 /* Special return value for Var_Parse, just to avoid allocating empty strings.
169  * In contrast to var_Error and varUndefined, this is not an error marker but
170  * just an ordinary successful return value. */
171 static char emptyString[] = "";
172
173 /*
174  * Traditionally this make consumed $$ during := like any other expansion.
175  * Other make's do not, and this make follows straight since 2016-01-09.
176  *
177  * This knob allows controlling the behavior.
178  * FALSE to consume $$ during := assignment.
179  * TRUE to preserve $$ during := assignment.
180  */
181 #define MAKE_SAVE_DOLLARS ".MAKE.SAVE_DOLLARS"
182 static Boolean save_dollars = FALSE;
183
184 /*
185  * Internally, variables are contained in four different contexts.
186  *      1) the environment. They cannot be changed. If an environment
187  *         variable is appended to, the result is placed in the global
188  *         context.
189  *      2) the global context. Variables set in the makefiles are located
190  *         here.
191  *      3) the command-line context. All variables set on the command line
192  *         are placed in this context.
193  *      4) the local context. Each target has associated with it a context
194  *         list. On this list are located the structures describing such
195  *         local variables as $(@) and $(*)
196  * The four contexts are searched in the reverse order from which they are
197  * listed (but see opts.checkEnvFirst).
198  */
199 GNode          *VAR_INTERNAL;   /* variables from make itself */
200 GNode          *VAR_GLOBAL;     /* variables from the makefile */
201 GNode          *VAR_CMDLINE;    /* variables defined on the command-line */
202
203 typedef enum VarFlags {
204
205     /* The variable's value is currently being used by Var_Parse or Var_Subst.
206      * This marker is used to avoid endless recursion. */
207     VAR_IN_USE = 0x01,
208
209     /* The variable comes from the environment.
210      * These variables are not registered in any GNode, therefore they must
211      * be freed as soon as they are not used anymore. */
212     VAR_FROM_ENV = 0x02,
213
214     /* The variable is exported to the environment, to be used by child
215      * processes. */
216     VAR_EXPORTED = 0x10,
217
218     /* At the point where this variable was exported, it contained an
219      * unresolved reference to another variable.  Before any child process is
220      * started, it needs to be exported again, in the hope that the referenced
221      * variable can then be resolved. */
222     VAR_REEXPORT = 0x20,
223
224     /* The variable came from the command line. */
225     VAR_FROM_CMD = 0x40,
226
227     /* The variable value cannot be changed anymore, and the variable cannot
228      * be deleted.  Any attempts to do so are ignored. */
229     VAR_READONLY = 0x80
230 } VarFlags;
231
232 ENUM_FLAGS_RTTI_6(VarFlags,
233                   VAR_IN_USE, VAR_FROM_ENV,
234                   VAR_EXPORTED, VAR_REEXPORT, VAR_FROM_CMD, VAR_READONLY);
235
236 /* Variables are defined using one of the VAR=value assignments.  Their
237  * value can be queried by expressions such as $V, ${VAR}, or with modifiers
238  * such as ${VAR:S,from,to,g:Q}.
239  *
240  * There are 3 kinds of variables: context variables, environment variables,
241  * undefined variables.
242  *
243  * Context variables are stored in a GNode.context.  The only way to undefine
244  * a context variable is using the .undef directive.  In particular, it must
245  * not be possible to undefine a variable during the evaluation of an
246  * expression, or Var.name might point nowhere.
247  *
248  * Environment variables are temporary.  They are returned by VarFind, and
249  * after using them, they must be freed using VarFreeEnv.
250  *
251  * Undefined variables occur during evaluation of variable expressions such
252  * as ${UNDEF:Ufallback} in Var_Parse and ApplyModifiers.
253  */
254 typedef struct Var {
255     /* The name of the variable, once set, doesn't change anymore.
256      * For context variables, it aliases the corresponding HashEntry name.
257      * For environment and undefined variables, it is allocated. */
258     const char *name;
259     void *name_freeIt;
260
261     Buffer        val;          /* its value */
262     VarFlags      flags;        /* miscellaneous status flags */
263 } Var;
264
265 /*
266  * Exporting vars is expensive so skip it if we can
267  */
268 typedef enum VarExportedMode {
269     VAR_EXPORTED_NONE,
270     VAR_EXPORTED_SOME,
271     VAR_EXPORTED_ALL
272 } VarExportedMode;
273
274 static VarExportedMode var_exportedVars = VAR_EXPORTED_NONE;
275
276 typedef enum VarExportFlags {
277     /*
278      * We pass this to Var_Export when doing the initial export
279      * or after updating an exported var.
280      */
281     VAR_EXPORT_PARENT   = 0x01,
282     /*
283      * We pass this to Var_Export1 to tell it to leave the value alone.
284      */
285     VAR_EXPORT_LITERAL  = 0x02
286 } VarExportFlags;
287
288 /* Flags for pattern matching in the :S and :C modifiers */
289 typedef enum VarPatternFlags {
290     VARP_SUB_GLOBAL     = 0x01, /* Replace as often as possible ('g') */
291     VARP_SUB_ONE        = 0x02, /* Replace only once ('1') */
292     VARP_ANCHOR_START   = 0x04, /* Match at start of word ('^') */
293     VARP_ANCHOR_END     = 0x08  /* Match at end of word ('$') */
294 } VarPatternFlags;
295
296 static Var *
297 VarNew(const char *name, void *name_freeIt, const char *value, VarFlags flags)
298 {
299     size_t value_len = strlen(value);
300     Var *var = bmake_malloc(sizeof *var);
301     var->name = name;
302     var->name_freeIt = name_freeIt;
303     Buf_Init(&var->val, value_len + 1);
304     Buf_AddBytes(&var->val, value, value_len);
305     var->flags = flags;
306     return var;
307 }
308
309 static const char *
310 CanonicalVarname(const char *name)
311 {
312     if (*name == '.' && ch_isupper(name[1])) {
313         switch (name[1]) {
314         case 'A':
315             if (strcmp(name, ".ALLSRC") == 0)
316                 name = ALLSRC;
317             if (strcmp(name, ".ARCHIVE") == 0)
318                 name = ARCHIVE;
319             break;
320         case 'I':
321             if (strcmp(name, ".IMPSRC") == 0)
322                 name = IMPSRC;
323             break;
324         case 'M':
325             if (strcmp(name, ".MEMBER") == 0)
326                 name = MEMBER;
327             break;
328         case 'O':
329             if (strcmp(name, ".OODATE") == 0)
330                 name = OODATE;
331             break;
332         case 'P':
333             if (strcmp(name, ".PREFIX") == 0)
334                 name = PREFIX;
335             break;
336         case 'S':
337             if (strcmp(name, ".SHELL") == 0) {
338                 if (!shellPath)
339                     Shell_Init();
340             }
341             break;
342         case 'T':
343             if (strcmp(name, ".TARGET") == 0)
344                 name = TARGET;
345             break;
346         }
347     }
348
349     /* GNU make has an additional alias $^ == ${.ALLSRC}. */
350
351     return name;
352 }
353
354 static Var *
355 GNode_FindVar(GNode *ctxt, const char *varname, unsigned int hash)
356 {
357     return HashTable_FindValueHash(&ctxt->context, varname, hash);
358 }
359
360 /* Find the variable in the context, and maybe in other contexts as well.
361  *
362  * Input:
363  *      name            name to find, is not expanded any further
364  *      ctxt            context in which to look first
365  *      elsewhere       TRUE to look in other contexts as well
366  *
367  * Results:
368  *      The found variable, or NULL if the variable does not exist.
369  *      If the variable is an environment variable, it must be freed using
370  *      VarFreeEnv after use.
371  */
372 static Var *
373 VarFind(const char *name, GNode *ctxt, Boolean elsewhere)
374 {
375     Var *var;
376     unsigned int nameHash;
377
378     /*
379      * If the variable name begins with a '.', it could very well be one of
380      * the local ones.  We check the name against all the local variables
381      * and substitute the short version in for 'name' if it matches one of
382      * them.
383      */
384     name = CanonicalVarname(name);
385     nameHash = Hash_Hash(name);
386
387     /* First look for the variable in the given context. */
388     var = GNode_FindVar(ctxt, name, nameHash);
389     if (!elsewhere)
390         return var;
391
392     /* The variable was not found in the given context.  Now look for it in
393      * the other contexts as well. */
394     if (var == NULL && ctxt != VAR_CMDLINE)
395         var = GNode_FindVar(VAR_CMDLINE, name, nameHash);
396
397     if (!opts.checkEnvFirst && var == NULL && ctxt != VAR_GLOBAL) {
398         var = GNode_FindVar(VAR_GLOBAL, name, nameHash);
399         if (var == NULL && ctxt != VAR_INTERNAL) {
400             /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
401             var = GNode_FindVar(VAR_INTERNAL, name, nameHash);
402         }
403     }
404
405     if (var == NULL) {
406         char *env;
407
408         if ((env = getenv(name)) != NULL) {
409             char *varname = bmake_strdup(name);
410             return VarNew(varname, varname, env, VAR_FROM_ENV);
411         }
412
413         if (opts.checkEnvFirst && ctxt != VAR_GLOBAL) {
414             var = GNode_FindVar(VAR_GLOBAL, name, nameHash);
415             if (var == NULL && ctxt != VAR_INTERNAL)
416                 var = GNode_FindVar(VAR_INTERNAL, name, nameHash);
417             return var;
418         }
419
420         return NULL;
421     }
422
423     return var;
424 }
425
426 /* If the variable is an environment variable, free it.
427  *
428  * Input:
429  *      v               the variable
430  *      freeValue       true if the variable value should be freed as well
431  *
432  * Results:
433  *      TRUE if it is an environment variable, FALSE otherwise.
434  */
435 static Boolean
436 VarFreeEnv(Var *v, Boolean freeValue)
437 {
438     if (!(v->flags & VAR_FROM_ENV))
439         return FALSE;
440
441     free(v->name_freeIt);
442     Buf_Destroy(&v->val, freeValue);
443     free(v);
444     return TRUE;
445 }
446
447 /* Add a new variable of the given name and value to the given context.
448  * The name and val arguments are duplicated so they may safely be freed. */
449 static void
450 VarAdd(const char *name, const char *val, GNode *ctxt, VarSet_Flags flags)
451 {
452     HashEntry *he = HashTable_CreateEntry(&ctxt->context, name, NULL);
453     Var *v = VarNew(he->key /* aliased */, NULL, val,
454                     flags & VAR_SET_READONLY ? VAR_READONLY : 0);
455     HashEntry_Set(he, v);
456     if (!(ctxt->flags & INTERNAL)) {
457         VAR_DEBUG3("%s:%s = %s\n", ctxt->name, name, val);
458     }
459 }
460
461 /* Remove a variable from a context, freeing all related memory as well.
462  * The variable name is expanded once. */
463 void
464 Var_Delete(const char *name, GNode *ctxt)
465 {
466     char *name_freeIt = NULL;
467     HashEntry *he;
468
469     if (strchr(name, '$') != NULL) {
470         (void)Var_Subst(name, VAR_GLOBAL, VARE_WANTRES, &name_freeIt);
471         /* TODO: handle errors */
472         name = name_freeIt;
473     }
474     he = HashTable_FindEntry(&ctxt->context, name);
475     VAR_DEBUG3("%s:delete %s%s\n",
476                ctxt->name, name, he != NULL ? "" : " (not found)");
477     free(name_freeIt);
478
479     if (he != NULL) {
480         Var *v = HashEntry_Get(he);
481         if (v->flags & VAR_EXPORTED)
482             unsetenv(v->name);
483         if (strcmp(v->name, MAKE_EXPORTED) == 0)
484             var_exportedVars = VAR_EXPORTED_NONE;
485         assert(v->name_freeIt == NULL);
486         HashTable_DeleteEntry(&ctxt->context, he);
487         Buf_Destroy(&v->val, TRUE);
488         free(v);
489     }
490 }
491
492 static Boolean
493 MayExport(const char *name)
494 {
495     if (name[0] == '.')
496         return FALSE;           /* skip internals */
497     if (name[0] == '-')
498         return FALSE;           /* skip misnamed variables */
499     if (name[1] == '\0') {
500         /*
501          * A single char.
502          * If it is one of the vars that should only appear in
503          * local context, skip it, else we can get Var_Subst
504          * into a loop.
505          */
506         switch (name[0]) {
507         case '@':
508         case '%':
509         case '*':
510         case '!':
511             return FALSE;
512         }
513     }
514     return TRUE;
515 }
516
517 /*
518  * Export a single variable.
519  * We ignore make internal variables (those which start with '.').
520  * Also we jump through some hoops to avoid calling setenv
521  * more than necessary since it can leak.
522  * We only manipulate flags of vars if 'parent' is set.
523  */
524 static Boolean
525 Var_Export1(const char *name, VarExportFlags flags)
526 {
527     VarExportFlags parent = flags & VAR_EXPORT_PARENT;
528     Var *v;
529     char *val;
530
531     if (!MayExport(name))
532         return FALSE;
533
534     v = VarFind(name, VAR_GLOBAL, 0);
535     if (v == NULL)
536         return FALSE;
537
538     if (!parent && (v->flags & VAR_EXPORTED) && !(v->flags & VAR_REEXPORT))
539         return FALSE;           /* nothing to do */
540
541     val = Buf_GetAll(&v->val, NULL);
542     if (!(flags & VAR_EXPORT_LITERAL) && strchr(val, '$') != NULL) {
543         char *expr;
544
545         if (parent) {
546             /*
547              * Flag the variable as something we need to re-export.
548              * No point actually exporting it now though,
549              * the child process can do it at the last minute.
550              */
551             v->flags |= VAR_EXPORTED | VAR_REEXPORT;
552             return TRUE;
553         }
554         if (v->flags & VAR_IN_USE) {
555             /*
556              * We recursed while exporting in a child.
557              * This isn't going to end well, just skip it.
558              */
559             return FALSE;
560         }
561
562         /* XXX: name is injected without escaping it */
563         expr = str_concat3("${", name, "}");
564         (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &val);
565         /* TODO: handle errors */
566         setenv(name, val, 1);
567         free(val);
568         free(expr);
569     } else {
570         if (parent)
571             v->flags &= ~(unsigned)VAR_REEXPORT;        /* once will do */
572         if (parent || !(v->flags & VAR_EXPORTED))
573             setenv(name, val, 1);
574     }
575
576     /*
577      * This is so Var_Set knows to call Var_Export again...
578      */
579     if (parent) {
580         v->flags |= VAR_EXPORTED;
581     }
582     return TRUE;
583 }
584
585 /*
586  * This gets called from our child processes.
587  */
588 void
589 Var_ExportVars(void)
590 {
591     char *val;
592
593     /*
594      * Several make's support this sort of mechanism for tracking
595      * recursion - but each uses a different name.
596      * We allow the makefiles to update MAKELEVEL and ensure
597      * children see a correctly incremented value.
598      */
599     char tmp[BUFSIZ];
600     snprintf(tmp, sizeof(tmp), "%d", makelevel + 1);
601     setenv(MAKE_LEVEL_ENV, tmp, 1);
602
603     if (var_exportedVars == VAR_EXPORTED_NONE)
604         return;
605
606     if (var_exportedVars == VAR_EXPORTED_ALL) {
607         HashIter hi;
608
609         /* Ouch! Exporting all variables at once is crazy... */
610         HashIter_Init(&hi, &VAR_GLOBAL->context);
611         while (HashIter_Next(&hi) != NULL) {
612             Var *var = hi.entry->value;
613             Var_Export1(var->name, 0);
614         }
615         return;
616     }
617
618     (void)Var_Subst("${" MAKE_EXPORTED ":O:u}", VAR_GLOBAL, VARE_WANTRES, &val);
619     /* TODO: handle errors */
620     if (*val) {
621         Words words = Str_Words(val, FALSE);
622         size_t i;
623
624         for (i = 0; i < words.len; i++)
625             Var_Export1(words.words[i], 0);
626         Words_Free(words);
627     }
628     free(val);
629 }
630
631 /*
632  * This is called when .export is seen or .MAKE.EXPORTED is modified.
633  *
634  * It is also called when any exported variable is modified.
635  * XXX: Is it really?
636  *
637  * str has the format "[-env|-literal] varname...".
638  */
639 void
640 Var_Export(const char *str, Boolean isExport)
641 {
642     VarExportFlags flags;
643     char *val;
644
645     if (isExport && str[0] == '\0') {
646         var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
647         return;
648     }
649
650     if (isExport && strncmp(str, "-env", 4) == 0) {
651         str += 4;
652         flags = 0;
653     } else if (isExport && strncmp(str, "-literal", 8) == 0) {
654         str += 8;
655         flags = VAR_EXPORT_LITERAL;
656     } else {
657         flags = VAR_EXPORT_PARENT;
658     }
659
660     (void)Var_Subst(str, VAR_GLOBAL, VARE_WANTRES, &val);
661     /* TODO: handle errors */
662     if (val[0] != '\0') {
663         Words words = Str_Words(val, FALSE);
664
665         size_t i;
666         for (i = 0; i < words.len; i++) {
667             const char *name = words.words[i];
668             if (Var_Export1(name, flags)) {
669                 if (var_exportedVars == VAR_EXPORTED_NONE)
670                     var_exportedVars = VAR_EXPORTED_SOME;
671                 if (isExport && (flags & VAR_EXPORT_PARENT)) {
672                     Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
673                 }
674             }
675         }
676         Words_Free(words);
677     }
678     free(val);
679 }
680
681
682 extern char **environ;
683
684 /*
685  * This is called when .unexport[-env] is seen.
686  *
687  * str must have the form "unexport[-env] varname...".
688  */
689 void
690 Var_UnExport(const char *str)
691 {
692     const char *varnames;
693     char *varnames_freeIt;
694     Boolean unexport_env;
695
696     varnames = NULL;
697     varnames_freeIt = NULL;
698
699     str += strlen("unexport");
700     unexport_env = strncmp(str, "-env", 4) == 0;
701     if (unexport_env) {
702         const char *cp;
703         char **newenv;
704
705         cp = getenv(MAKE_LEVEL_ENV);    /* we should preserve this */
706         if (environ == savedEnv) {
707             /* we have been here before! */
708             newenv = bmake_realloc(environ, 2 * sizeof(char *));
709         } else {
710             if (savedEnv) {
711                 free(savedEnv);
712                 savedEnv = NULL;
713             }
714             newenv = bmake_malloc(2 * sizeof(char *));
715         }
716
717         /* Note: we cannot safely free() the original environ. */
718         environ = savedEnv = newenv;
719         newenv[0] = NULL;
720         newenv[1] = NULL;
721         if (cp && *cp)
722             setenv(MAKE_LEVEL_ENV, cp, 1);
723     } else {
724         cpp_skip_whitespace(&str);
725         if (str[0] != '\0')
726             varnames = str;
727     }
728
729     if (varnames == NULL) {
730         /* Using .MAKE.EXPORTED */
731         (void)Var_Subst("${" MAKE_EXPORTED ":O:u}", VAR_GLOBAL, VARE_WANTRES,
732                         &varnames_freeIt);
733         /* TODO: handle errors */
734         varnames = varnames_freeIt;
735     }
736
737     {
738         Var *v;
739         size_t i;
740
741         Words words = Str_Words(varnames, FALSE);
742         for (i = 0; i < words.len; i++) {
743             const char *varname = words.words[i];
744             v = VarFind(varname, VAR_GLOBAL, 0);
745             if (v == NULL) {
746                 VAR_DEBUG1("Not unexporting \"%s\" (not found)\n", varname);
747                 continue;
748             }
749
750             VAR_DEBUG1("Unexporting \"%s\"\n", varname);
751             if (!unexport_env && (v->flags & VAR_EXPORTED) &&
752                 !(v->flags & VAR_REEXPORT))
753                 unsetenv(v->name);
754             v->flags &= ~(unsigned)(VAR_EXPORTED | VAR_REEXPORT);
755
756             /*
757              * If we are unexporting a list,
758              * remove each one from .MAKE.EXPORTED.
759              * If we are removing them all,
760              * just delete .MAKE.EXPORTED below.
761              */
762             if (varnames == str) {
763                 /* XXX: v->name is injected without escaping it */
764                 char *expr = str_concat3("${" MAKE_EXPORTED ":N", v->name, "}");
765                 char *cp;
766                 (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &cp);
767                 /* TODO: handle errors */
768                 Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL);
769                 free(cp);
770                 free(expr);
771             }
772         }
773         Words_Free(words);
774         if (varnames != str) {
775             Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
776             free(varnames_freeIt);
777         }
778     }
779 }
780
781 /* See Var_Set for documentation. */
782 void
783 Var_Set_with_flags(const char *name, const char *val, GNode *ctxt,
784                    VarSet_Flags flags)
785 {
786     const char *unexpanded_name = name;
787     char *name_freeIt = NULL;
788     Var *v;
789
790     assert(val != NULL);
791
792     if (strchr(name, '$') != NULL) {
793         (void)Var_Subst(name, ctxt, VARE_WANTRES, &name_freeIt);
794         /* TODO: handle errors */
795         name = name_freeIt;
796     }
797
798     if (name[0] == '\0') {
799         VAR_DEBUG2("Var_Set(\"%s\", \"%s\", ...) "
800                    "name expands to empty string - ignored\n",
801                    unexpanded_name, val);
802         free(name_freeIt);
803         return;
804     }
805
806     if (ctxt == VAR_GLOBAL) {
807         v = VarFind(name, VAR_CMDLINE, 0);
808         if (v != NULL) {
809             if (v->flags & VAR_FROM_CMD) {
810                 VAR_DEBUG3("%s:%s = %s ignored!\n", ctxt->name, name, val);
811                 goto out;
812             }
813             VarFreeEnv(v, TRUE);
814         }
815     }
816
817     /*
818      * We only look for a variable in the given context since anything set
819      * here will override anything in a lower context, so there's not much
820      * point in searching them all just to save a bit of memory...
821      */
822     v = VarFind(name, ctxt, 0);
823     if (v == NULL) {
824         if (ctxt == VAR_CMDLINE && !(flags & VAR_NO_EXPORT)) {
825             /*
826              * This var would normally prevent the same name being added
827              * to VAR_GLOBAL, so delete it from there if needed.
828              * Otherwise -V name may show the wrong value.
829              */
830             /* XXX: name is expanded for the second time */
831             Var_Delete(name, VAR_GLOBAL);
832         }
833         VarAdd(name, val, ctxt, flags);
834     } else {
835         if ((v->flags & VAR_READONLY) && !(flags & VAR_SET_READONLY)) {
836             VAR_DEBUG3("%s:%s = %s ignored (read-only)\n",
837                        ctxt->name, name, val);
838             goto out;
839         }
840         Buf_Empty(&v->val);
841         Buf_AddStr(&v->val, val);
842
843         VAR_DEBUG3("%s:%s = %s\n", ctxt->name, name, val);
844         if (v->flags & VAR_EXPORTED) {
845             Var_Export1(name, VAR_EXPORT_PARENT);
846         }
847     }
848     /*
849      * Any variables given on the command line are automatically exported
850      * to the environment (as per POSIX standard)
851      * Other than internals.
852      */
853     if (ctxt == VAR_CMDLINE && !(flags & VAR_NO_EXPORT) && name[0] != '.') {
854         if (v == NULL)
855             v = VarFind(name, ctxt, 0); /* we just added it */
856         v->flags |= VAR_FROM_CMD;
857
858         /*
859          * If requested, don't export these in the environment
860          * individually.  We still put them in MAKEOVERRIDES so
861          * that the command-line settings continue to override
862          * Makefile settings.
863          */
864         if (!opts.varNoExportEnv)
865             setenv(name, val, 1);
866
867         Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
868     }
869     if (name[0] == '.' && strcmp(name, MAKE_SAVE_DOLLARS) == 0)
870         save_dollars = s2Boolean(val, save_dollars);
871
872 out:
873     free(name_freeIt);
874     if (v != NULL)
875         VarFreeEnv(v, TRUE);
876 }
877
878 /*-
879  *-----------------------------------------------------------------------
880  * Var_Set --
881  *      Set the variable name to the value val in the given context.
882  *
883  *      If the variable doesn't yet exist, it is created.
884  *      Otherwise the new value overwrites and replaces the old value.
885  *
886  * Input:
887  *      name            name of the variable to set, is expanded once
888  *      val             value to give to the variable
889  *      ctxt            context in which to set it
890  *
891  * Notes:
892  *      The variable is searched for only in its context before being
893  *      created in that context. I.e. if the context is VAR_GLOBAL,
894  *      only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMDLINE,
895  *      only VAR_CMDLINE->context is searched. This is done to avoid the
896  *      literally thousands of unnecessary strcmp's that used to be done to
897  *      set, say, $(@) or $(<).
898  *      If the context is VAR_GLOBAL though, we check if the variable
899  *      was set in VAR_CMDLINE from the command line and skip it if so.
900  *-----------------------------------------------------------------------
901  */
902 void
903 Var_Set(const char *name, const char *val, GNode *ctxt)
904 {
905     Var_Set_with_flags(name, val, ctxt, 0);
906 }
907
908 /*-
909  *-----------------------------------------------------------------------
910  * Var_Append --
911  *      The variable of the given name has the given value appended to it in
912  *      the given context.
913  *
914  *      If the variable doesn't exist, it is created. Otherwise the strings
915  *      are concatenated, with a space in between.
916  *
917  * Input:
918  *      name            name of the variable to modify, is expanded once
919  *      val             string to append to it
920  *      ctxt            context in which this should occur
921  *
922  * Notes:
923  *      Only if the variable is being sought in the global context is the
924  *      environment searched.
925  *      XXX: Knows its calling circumstances in that if called with ctxt
926  *      an actual target, it will only search that context since only
927  *      a local variable could be being appended to. This is actually
928  *      a big win and must be tolerated.
929  *-----------------------------------------------------------------------
930  */
931 void
932 Var_Append(const char *name, const char *val, GNode *ctxt)
933 {
934     char *name_freeIt = NULL;
935     Var *v;
936
937     assert(val != NULL);
938
939     if (strchr(name, '$') != NULL) {
940         const char *unexpanded_name = name;
941         (void)Var_Subst(name, ctxt, VARE_WANTRES, &name_freeIt);
942         /* TODO: handle errors */
943         name = name_freeIt;
944         if (name[0] == '\0') {
945             VAR_DEBUG2("Var_Append(\"%s\", \"%s\", ...) "
946                        "name expands to empty string - ignored\n",
947                        unexpanded_name, val);
948             free(name_freeIt);
949             return;
950         }
951     }
952
953     v = VarFind(name, ctxt, ctxt == VAR_GLOBAL);
954
955     if (v == NULL) {
956         /* XXX: name is expanded for the second time */
957         Var_Set(name, val, ctxt);
958     } else if (v->flags & VAR_READONLY) {
959         VAR_DEBUG1("Ignoring append to %s since it is read-only\n", name);
960     } else if (ctxt == VAR_CMDLINE || !(v->flags & VAR_FROM_CMD)) {
961         Buf_AddByte(&v->val, ' ');
962         Buf_AddStr(&v->val, val);
963
964         VAR_DEBUG3("%s:%s = %s\n",
965                    ctxt->name, name, Buf_GetAll(&v->val, NULL));
966
967         if (v->flags & VAR_FROM_ENV) {
968             HashEntry *h;
969
970             /*
971              * If the original variable came from the environment, we
972              * have to install it in the global context (we could place
973              * it in the environment, but then we should provide a way to
974              * export other variables...)
975              */
976             v->flags &= ~(unsigned)VAR_FROM_ENV;
977             h = HashTable_CreateEntry(&ctxt->context, name, NULL);
978             HashEntry_Set(h, v);
979         }
980     }
981     free(name_freeIt);
982 }
983
984 /* See if the given variable exists, in the given context or in other
985  * fallback contexts.
986  *
987  * Input:
988  *      name            Variable to find, is expanded once
989  *      ctxt            Context in which to start search
990  */
991 Boolean
992 Var_Exists(const char *name, GNode *ctxt)
993 {
994     char *name_freeIt = NULL;
995     Var *v;
996
997     if (strchr(name, '$') != NULL) {
998         (void)Var_Subst(name, ctxt, VARE_WANTRES, &name_freeIt);
999         /* TODO: handle errors */
1000         name = name_freeIt;
1001     }
1002
1003     v = VarFind(name, ctxt, TRUE);
1004     free(name_freeIt);
1005     if (v == NULL)
1006         return FALSE;
1007
1008     (void)VarFreeEnv(v, TRUE);
1009     return TRUE;
1010 }
1011
1012 /*-
1013  *-----------------------------------------------------------------------
1014  * Var_Value --
1015  *      Return the unexpanded value of the given variable in the given
1016  *      context, or the usual contexts.
1017  *
1018  * Input:
1019  *      name            name to find, is not expanded any further
1020  *      ctxt            context in which to search for it
1021  *
1022  * Results:
1023  *      The value if the variable exists, NULL if it doesn't.
1024  *      If the returned value is not NULL, the caller must free
1025  *      out_freeIt when the returned value is no longer needed.
1026  *-----------------------------------------------------------------------
1027  */
1028 const char *
1029 Var_Value(const char *name, GNode *ctxt, void **out_freeIt)
1030 {
1031     Var *v = VarFind(name, ctxt, TRUE);
1032     char *value;
1033
1034     *out_freeIt = NULL;
1035     if (v == NULL)
1036         return NULL;
1037
1038     value = Buf_GetAll(&v->val, NULL);
1039     if (VarFreeEnv(v, FALSE))
1040         *out_freeIt = value;
1041     return value;
1042 }
1043
1044 /* Return the unexpanded variable value from this node, without trying to look
1045  * up the variable in any other context. */
1046 const char *
1047 Var_ValueDirect(const char *name, GNode *ctxt)
1048 {
1049     Var *v = VarFind(name, ctxt, FALSE);
1050     return v != NULL ? Buf_GetAll(&v->val, NULL) : NULL;
1051 }
1052
1053
1054 /* SepBuf is a string being built from words, interleaved with separators. */
1055 typedef struct SepBuf {
1056     Buffer buf;
1057     Boolean needSep;
1058     char sep;                   /* usually ' ', but see the :ts modifier */
1059 } SepBuf;
1060
1061 static void
1062 SepBuf_Init(SepBuf *buf, char sep)
1063 {
1064     Buf_Init(&buf->buf, 32 /* bytes */);
1065     buf->needSep = FALSE;
1066     buf->sep = sep;
1067 }
1068
1069 static void
1070 SepBuf_Sep(SepBuf *buf)
1071 {
1072     buf->needSep = TRUE;
1073 }
1074
1075 static void
1076 SepBuf_AddBytes(SepBuf *buf, const char *mem, size_t mem_size)
1077 {
1078     if (mem_size == 0)
1079         return;
1080     if (buf->needSep && buf->sep != '\0') {
1081         Buf_AddByte(&buf->buf, buf->sep);
1082         buf->needSep = FALSE;
1083     }
1084     Buf_AddBytes(&buf->buf, mem, mem_size);
1085 }
1086
1087 static void
1088 SepBuf_AddBytesBetween(SepBuf *buf, const char *start, const char *end)
1089 {
1090     SepBuf_AddBytes(buf, start, (size_t)(end - start));
1091 }
1092
1093 static void
1094 SepBuf_AddStr(SepBuf *buf, const char *str)
1095 {
1096     SepBuf_AddBytes(buf, str, strlen(str));
1097 }
1098
1099 static char *
1100 SepBuf_Destroy(SepBuf *buf, Boolean free_buf)
1101 {
1102     return Buf_Destroy(&buf->buf, free_buf);
1103 }
1104
1105
1106 /* This callback for ModifyWords gets a single word from a variable expression
1107  * and typically adds a modification of this word to the buffer. It may also
1108  * do nothing or add several words.
1109  *
1110  * For example, in ${:Ua b c:M*2}, the callback is called 3 times, once for
1111  * each word of "a b c". */
1112 typedef void (*ModifyWordsCallback)(const char *word, SepBuf *buf, void *data);
1113
1114
1115 /* Callback for ModifyWords to implement the :H modifier.
1116  * Add the dirname of the given word to the buffer. */
1117 static void
1118 ModifyWord_Head(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1119 {
1120     const char *slash = strrchr(word, '/');
1121     if (slash != NULL)
1122         SepBuf_AddBytesBetween(buf, word, slash);
1123     else
1124         SepBuf_AddStr(buf, ".");
1125 }
1126
1127 /* Callback for ModifyWords to implement the :T modifier.
1128  * Add the basename of the given word to the buffer. */
1129 static void
1130 ModifyWord_Tail(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1131 {
1132     const char *slash = strrchr(word, '/');
1133     const char *base = slash != NULL ? slash + 1 : word;
1134     SepBuf_AddStr(buf, base);
1135 }
1136
1137 /* Callback for ModifyWords to implement the :E modifier.
1138  * Add the filename suffix of the given word to the buffer, if it exists. */
1139 static void
1140 ModifyWord_Suffix(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1141 {
1142     const char *dot = strrchr(word, '.');
1143     if (dot != NULL)
1144         SepBuf_AddStr(buf, dot + 1);
1145 }
1146
1147 /* Callback for ModifyWords to implement the :R modifier.
1148  * Add the basename of the given word to the buffer. */
1149 static void
1150 ModifyWord_Root(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1151 {
1152     const char *dot = strrchr(word, '.');
1153     size_t len = dot != NULL ? (size_t)(dot - word) : strlen(word);
1154     SepBuf_AddBytes(buf, word, len);
1155 }
1156
1157 /* Callback for ModifyWords to implement the :M modifier.
1158  * Place the word in the buffer if it matches the given pattern. */
1159 static void
1160 ModifyWord_Match(const char *word, SepBuf *buf, void *data)
1161 {
1162     const char *pattern = data;
1163     VAR_DEBUG2("VarMatch [%s] [%s]\n", word, pattern);
1164     if (Str_Match(word, pattern))
1165         SepBuf_AddStr(buf, word);
1166 }
1167
1168 /* Callback for ModifyWords to implement the :N modifier.
1169  * Place the word in the buffer if it doesn't match the given pattern. */
1170 static void
1171 ModifyWord_NoMatch(const char *word, SepBuf *buf, void *data)
1172 {
1173     const char *pattern = data;
1174     if (!Str_Match(word, pattern))
1175         SepBuf_AddStr(buf, word);
1176 }
1177
1178 #ifdef SYSVVARSUB
1179 /* Check word against pattern for a match (% is a wildcard).
1180  *
1181  * Input:
1182  *      word            Word to examine
1183  *      pattern         Pattern to examine against
1184  *
1185  * Results:
1186  *      Returns the start of the match, or NULL.
1187  *      out_match_len returns the length of the match, if any.
1188  *      out_hasPercent returns whether the pattern contains a percent.
1189  */
1190 static const char *
1191 SysVMatch(const char *word, const char *pattern,
1192               size_t *out_match_len, Boolean *out_hasPercent)
1193 {
1194     const char *p = pattern;
1195     const char *w = word;
1196     const char *percent;
1197     size_t w_len;
1198     size_t p_len;
1199     const char *w_tail;
1200
1201     *out_hasPercent = FALSE;
1202     percent = strchr(p, '%');
1203     if (percent != NULL) {      /* ${VAR:...%...=...} */
1204         *out_hasPercent = TRUE;
1205         if (*w == '\0')
1206             return NULL;        /* empty word does not match pattern */
1207
1208         /* check that the prefix matches */
1209         for (; p != percent && *w != '\0' && *w == *p; w++, p++)
1210             continue;
1211         if (p != percent)
1212             return NULL;        /* No match */
1213
1214         p++;                    /* Skip the percent */
1215         if (*p == '\0') {
1216             /* No more pattern, return the rest of the string */
1217             *out_match_len = strlen(w);
1218             return w;
1219         }
1220     }
1221
1222     /* Test whether the tail matches */
1223     w_len = strlen(w);
1224     p_len = strlen(p);
1225     if (w_len < p_len)
1226         return NULL;
1227
1228     w_tail = w + w_len - p_len;
1229     if (memcmp(p, w_tail, p_len) != 0)
1230         return NULL;
1231
1232     *out_match_len = (size_t)(w_tail - w);
1233     return w;
1234 }
1235
1236 struct ModifyWord_SYSVSubstArgs {
1237     GNode *ctx;
1238     const char *lhs;
1239     const char *rhs;
1240 };
1241
1242 /* Callback for ModifyWords to implement the :%.from=%.to modifier. */
1243 static void
1244 ModifyWord_SYSVSubst(const char *word, SepBuf *buf, void *data)
1245 {
1246     const struct ModifyWord_SYSVSubstArgs *args = data;
1247     char *rhs_expanded;
1248     const char *rhs;
1249     const char *percent;
1250
1251     size_t match_len;
1252     Boolean lhsPercent;
1253     const char *match = SysVMatch(word, args->lhs, &match_len, &lhsPercent);
1254     if (match == NULL) {
1255         SepBuf_AddStr(buf, word);
1256         return;
1257     }
1258
1259     /* Append rhs to the buffer, substituting the first '%' with the
1260      * match, but only if the lhs had a '%' as well. */
1261
1262     (void)Var_Subst(args->rhs, args->ctx, VARE_WANTRES, &rhs_expanded);
1263     /* TODO: handle errors */
1264
1265     rhs = rhs_expanded;
1266     percent = strchr(rhs, '%');
1267
1268     if (percent != NULL && lhsPercent) {
1269         /* Copy the prefix of the replacement pattern */
1270         SepBuf_AddBytesBetween(buf, rhs, percent);
1271         rhs = percent + 1;
1272     }
1273     if (percent != NULL || !lhsPercent)
1274         SepBuf_AddBytes(buf, match, match_len);
1275
1276     /* Append the suffix of the replacement pattern */
1277     SepBuf_AddStr(buf, rhs);
1278
1279     free(rhs_expanded);
1280 }
1281 #endif
1282
1283
1284 struct ModifyWord_SubstArgs {
1285     const char  *lhs;
1286     size_t      lhsLen;
1287     const char  *rhs;
1288     size_t      rhsLen;
1289     VarPatternFlags pflags;
1290     Boolean     matched;
1291 };
1292
1293 /* Callback for ModifyWords to implement the :S,from,to, modifier.
1294  * Perform a string substitution on the given word. */
1295 static void
1296 ModifyWord_Subst(const char *word, SepBuf *buf, void *data)
1297 {
1298     size_t wordLen = strlen(word);
1299     struct ModifyWord_SubstArgs *args = data;
1300     const char *match;
1301
1302     if ((args->pflags & VARP_SUB_ONE) && args->matched)
1303         goto nosub;
1304
1305     if (args->pflags & VARP_ANCHOR_START) {
1306         if (wordLen < args->lhsLen ||
1307             memcmp(word, args->lhs, args->lhsLen) != 0)
1308             goto nosub;
1309
1310         if ((args->pflags & VARP_ANCHOR_END) && wordLen != args->lhsLen)
1311             goto nosub;
1312
1313         /* :S,^prefix,replacement, or :S,^whole$,replacement, */
1314         SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
1315         SepBuf_AddBytes(buf, word + args->lhsLen, wordLen - args->lhsLen);
1316         args->matched = TRUE;
1317         return;
1318     }
1319
1320     if (args->pflags & VARP_ANCHOR_END) {
1321         const char *start;
1322
1323         if (wordLen < args->lhsLen)
1324             goto nosub;
1325
1326         start = word + (wordLen - args->lhsLen);
1327         if (memcmp(start, args->lhs, args->lhsLen) != 0)
1328             goto nosub;
1329
1330         /* :S,suffix$,replacement, */
1331         SepBuf_AddBytesBetween(buf, word, start);
1332         SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
1333         args->matched = TRUE;
1334         return;
1335     }
1336
1337     if (args->lhs[0] == '\0')
1338         goto nosub;
1339
1340     /* unanchored case, may match more than once */
1341     while ((match = strstr(word, args->lhs)) != NULL) {
1342         SepBuf_AddBytesBetween(buf, word, match);
1343         SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
1344         args->matched = TRUE;
1345         wordLen -= (size_t)(match - word) + args->lhsLen;
1346         word += (size_t)(match - word) + args->lhsLen;
1347         if (wordLen == 0 || !(args->pflags & VARP_SUB_GLOBAL))
1348             break;
1349     }
1350 nosub:
1351     SepBuf_AddBytes(buf, word, wordLen);
1352 }
1353
1354 #ifndef NO_REGEX
1355 /* Print the error caused by a regcomp or regexec call. */
1356 static void
1357 VarREError(int reerr, regex_t *pat, const char *str)
1358 {
1359     size_t errlen = regerror(reerr, pat, 0, 0);
1360     char *errbuf = bmake_malloc(errlen);
1361     regerror(reerr, pat, errbuf, errlen);
1362     Error("%s: %s", str, errbuf);
1363     free(errbuf);
1364 }
1365
1366 struct ModifyWord_SubstRegexArgs {
1367     regex_t re;
1368     size_t nsub;
1369     char *replace;
1370     VarPatternFlags pflags;
1371     Boolean matched;
1372 };
1373
1374 /* Callback for ModifyWords to implement the :C/from/to/ modifier.
1375  * Perform a regex substitution on the given word. */
1376 static void
1377 ModifyWord_SubstRegex(const char *word, SepBuf *buf, void *data)
1378 {
1379     struct ModifyWord_SubstRegexArgs *args = data;
1380     int xrv;
1381     const char *wp = word;
1382     char *rp;
1383     int flags = 0;
1384     regmatch_t m[10];
1385
1386     if ((args->pflags & VARP_SUB_ONE) && args->matched)
1387         goto nosub;
1388
1389 tryagain:
1390     xrv = regexec(&args->re, wp, args->nsub, m, flags);
1391
1392     switch (xrv) {
1393     case 0:
1394         args->matched = TRUE;
1395         SepBuf_AddBytes(buf, wp, (size_t)m[0].rm_so);
1396
1397         for (rp = args->replace; *rp; rp++) {
1398             if (*rp == '\\' && (rp[1] == '&' || rp[1] == '\\')) {
1399                 SepBuf_AddBytes(buf, rp + 1, 1);
1400                 rp++;
1401                 continue;
1402             }
1403
1404             if (*rp == '&') {
1405                 SepBuf_AddBytesBetween(buf, wp + m[0].rm_so, wp + m[0].rm_eo);
1406                 continue;
1407             }
1408
1409             if (*rp != '\\' || !ch_isdigit(rp[1])) {
1410                 SepBuf_AddBytes(buf, rp, 1);
1411                 continue;
1412             }
1413
1414             {                   /* \0 to \9 backreference */
1415                 size_t n = (size_t)(rp[1] - '0');
1416                 rp++;
1417
1418                 if (n >= args->nsub) {
1419                     Error("No subexpression \\%zu", n);
1420                 } else if (m[n].rm_so == -1) {
1421                     Error("No match for subexpression \\%zu", n);
1422                 } else {
1423                     SepBuf_AddBytesBetween(buf, wp + m[n].rm_so,
1424                                            wp + m[n].rm_eo);
1425                 }
1426             }
1427         }
1428
1429         wp += m[0].rm_eo;
1430         if (args->pflags & VARP_SUB_GLOBAL) {
1431             flags |= REG_NOTBOL;
1432             if (m[0].rm_so == 0 && m[0].rm_eo == 0) {
1433                 SepBuf_AddBytes(buf, wp, 1);
1434                 wp++;
1435             }
1436             if (*wp)
1437                 goto tryagain;
1438         }
1439         if (*wp) {
1440             SepBuf_AddStr(buf, wp);
1441         }
1442         break;
1443     default:
1444         VarREError(xrv, &args->re, "Unexpected regex error");
1445         /* FALLTHROUGH */
1446     case REG_NOMATCH:
1447     nosub:
1448         SepBuf_AddStr(buf, wp);
1449         break;
1450     }
1451 }
1452 #endif
1453
1454
1455 struct ModifyWord_LoopArgs {
1456     GNode       *ctx;
1457     char        *tvar;          /* name of temporary variable */
1458     char        *str;           /* string to expand */
1459     VarEvalFlags eflags;
1460 };
1461
1462 /* Callback for ModifyWords to implement the :@var@...@ modifier of ODE make. */
1463 static void
1464 ModifyWord_Loop(const char *word, SepBuf *buf, void *data)
1465 {
1466     const struct ModifyWord_LoopArgs *args;
1467     char *s;
1468
1469     if (word[0] == '\0')
1470         return;
1471
1472     args = data;
1473     Var_Set_with_flags(args->tvar, word, args->ctx, VAR_NO_EXPORT);
1474     (void)Var_Subst(args->str, args->ctx, args->eflags, &s);
1475     /* TODO: handle errors */
1476
1477     VAR_DEBUG4("ModifyWord_Loop: "
1478                "in \"%s\", replace \"%s\" with \"%s\" to \"%s\"\n",
1479                word, args->tvar, args->str, s);
1480
1481     if (s[0] == '\n' || Buf_EndsWith(&buf->buf, '\n'))
1482         buf->needSep = FALSE;
1483     SepBuf_AddStr(buf, s);
1484     free(s);
1485 }
1486
1487
1488 /* The :[first..last] modifier selects words from the expression.
1489  * It can also reverse the words. */
1490 static char *
1491 VarSelectWords(char sep, Boolean oneBigWord, const char *str, int first,
1492                int last)
1493 {
1494     Words words;
1495     int len, start, end, step;
1496     int i;
1497
1498     SepBuf buf;
1499     SepBuf_Init(&buf, sep);
1500
1501     if (oneBigWord) {
1502         /* fake what Str_Words() would do if there were only one word */
1503         words.len = 1;
1504         words.words = bmake_malloc((words.len + 1) * sizeof(char *));
1505         words.freeIt = bmake_strdup(str);
1506         words.words[0] = words.freeIt;
1507         words.words[1] = NULL;
1508     } else {
1509         words = Str_Words(str, FALSE);
1510     }
1511
1512     /*
1513      * Now sanitize the given range.
1514      * If first or last are negative, convert them to the positive equivalents
1515      * (-1 gets converted to ac, -2 gets converted to (ac - 1), etc.).
1516      */
1517     len = (int)words.len;
1518     if (first < 0)
1519         first += len + 1;
1520     if (last < 0)
1521         last += len + 1;
1522
1523     /*
1524      * We avoid scanning more of the list than we need to.
1525      */
1526     if (first > last) {
1527         start = (first > len ? len : first) - 1;
1528         end = last < 1 ? 0 : last - 1;
1529         step = -1;
1530     } else {
1531         start = first < 1 ? 0 : first - 1;
1532         end = last > len ? len : last;
1533         step = 1;
1534     }
1535
1536     for (i = start; (step < 0) == (i >= end); i += step) {
1537         SepBuf_AddStr(&buf, words.words[i]);
1538         SepBuf_Sep(&buf);
1539     }
1540
1541     Words_Free(words);
1542
1543     return SepBuf_Destroy(&buf, FALSE);
1544 }
1545
1546
1547 /* Callback for ModifyWords to implement the :tA modifier.
1548  * Replace each word with the result of realpath() if successful. */
1549 static void
1550 ModifyWord_Realpath(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
1551 {
1552     struct stat st;
1553     char rbuf[MAXPATHLEN];
1554
1555     const char *rp = cached_realpath(word, rbuf);
1556     if (rp != NULL && *rp == '/' && stat(rp, &st) == 0)
1557         word = rp;
1558
1559     SepBuf_AddStr(buf, word);
1560 }
1561
1562 /* Modify each of the words of the passed string using the given function.
1563  *
1564  * Input:
1565  *      str             String whose words should be modified
1566  *      modifyWord      Function that modifies a single word
1567  *      modifyWord_args Custom arguments for modifyWord
1568  *
1569  * Results:
1570  *      A string of all the words modified appropriately.
1571  *-----------------------------------------------------------------------
1572  */
1573 static char *
1574 ModifyWords(const char *str,
1575             ModifyWordsCallback modifyWord, void *modifyWord_args,
1576             Boolean oneBigWord, char sep)
1577 {
1578     SepBuf result;
1579     Words words;
1580     size_t i;
1581
1582     if (oneBigWord) {
1583         SepBuf_Init(&result, sep);
1584         modifyWord(str, &result, modifyWord_args);
1585         return SepBuf_Destroy(&result, FALSE);
1586     }
1587
1588     SepBuf_Init(&result, sep);
1589
1590     words = Str_Words(str, FALSE);
1591
1592     VAR_DEBUG2("ModifyWords: split \"%s\" into %zu words\n", str, words.len);
1593
1594     for (i = 0; i < words.len; i++) {
1595         modifyWord(words.words[i], &result, modifyWord_args);
1596         if (Buf_Len(&result.buf) > 0)
1597             SepBuf_Sep(&result);
1598     }
1599
1600     Words_Free(words);
1601
1602     return SepBuf_Destroy(&result, FALSE);
1603 }
1604
1605
1606 static char *
1607 Words_JoinFree(Words words)
1608 {
1609     Buffer buf;
1610     size_t i;
1611
1612     Buf_Init(&buf, 0);
1613
1614     for (i = 0; i < words.len; i++) {
1615         if (i != 0)
1616             Buf_AddByte(&buf, ' ');     /* XXX: st->sep, for consistency */
1617         Buf_AddStr(&buf, words.words[i]);
1618     }
1619
1620     Words_Free(words);
1621
1622     return Buf_Destroy(&buf, FALSE);
1623 }
1624
1625 /* Remove adjacent duplicate words. */
1626 static char *
1627 VarUniq(const char *str)
1628 {
1629     Words words = Str_Words(str, FALSE);
1630
1631     if (words.len > 1) {
1632         size_t i, j;
1633         for (j = 0, i = 1; i < words.len; i++)
1634             if (strcmp(words.words[i], words.words[j]) != 0 && (++j != i))
1635                 words.words[j] = words.words[i];
1636         words.len = j + 1;
1637     }
1638
1639     return Words_JoinFree(words);
1640 }
1641
1642
1643 /* Quote shell meta-characters and space characters in the string.
1644  * If quoteDollar is set, also quote and double any '$' characters. */
1645 static char *
1646 VarQuote(const char *str, Boolean quoteDollar)
1647 {
1648     Buffer buf;
1649     Buf_Init(&buf, 0);
1650
1651     for (; *str != '\0'; str++) {
1652         if (*str == '\n') {
1653             const char *newline = Shell_GetNewline();
1654             if (newline == NULL)
1655                 newline = "\\\n";
1656             Buf_AddStr(&buf, newline);
1657             continue;
1658         }
1659         if (ch_isspace(*str) || is_shell_metachar((unsigned char)*str))
1660             Buf_AddByte(&buf, '\\');
1661         Buf_AddByte(&buf, *str);
1662         if (quoteDollar && *str == '$')
1663             Buf_AddStr(&buf, "\\$");
1664     }
1665
1666     return Buf_Destroy(&buf, FALSE);
1667 }
1668
1669 /* Compute the 32-bit hash of the given string, using the MurmurHash3
1670  * algorithm. Output is encoded as 8 hex digits, in Little Endian order. */
1671 static char *
1672 VarHash(const char *str)
1673 {
1674     static const char    hexdigits[16] = "0123456789abcdef";
1675     const unsigned char *ustr = (const unsigned char *)str;
1676
1677     uint32_t h  = 0x971e137bU;
1678     uint32_t c1 = 0x95543787U;
1679     uint32_t c2 = 0x2ad7eb25U;
1680     size_t len2 = strlen(str);
1681
1682     char *buf;
1683     size_t i;
1684
1685     size_t len;
1686     for (len = len2; len; ) {
1687         uint32_t k = 0;
1688         switch (len) {
1689         default:
1690             k = ((uint32_t)ustr[3] << 24) |
1691                 ((uint32_t)ustr[2] << 16) |
1692                 ((uint32_t)ustr[1] << 8) |
1693                 (uint32_t)ustr[0];
1694             len -= 4;
1695             ustr += 4;
1696             break;
1697         case 3:
1698             k |= (uint32_t)ustr[2] << 16;
1699             /* FALLTHROUGH */
1700         case 2:
1701             k |= (uint32_t)ustr[1] << 8;
1702             /* FALLTHROUGH */
1703         case 1:
1704             k |= (uint32_t)ustr[0];
1705             len = 0;
1706         }
1707         c1 = c1 * 5 + 0x7b7d159cU;
1708         c2 = c2 * 5 + 0x6bce6396U;
1709         k *= c1;
1710         k = (k << 11) ^ (k >> 21);
1711         k *= c2;
1712         h = (h << 13) ^ (h >> 19);
1713         h = h * 5 + 0x52dce729U;
1714         h ^= k;
1715     }
1716     h ^= (uint32_t)len2;
1717     h *= 0x85ebca6b;
1718     h ^= h >> 13;
1719     h *= 0xc2b2ae35;
1720     h ^= h >> 16;
1721
1722     buf = bmake_malloc(9);
1723     for (i = 0; i < 8; i++) {
1724         buf[i] = hexdigits[h & 0x0f];
1725         h >>= 4;
1726     }
1727     buf[8] = '\0';
1728     return buf;
1729 }
1730
1731 static char *
1732 VarStrftime(const char *fmt, Boolean zulu, time_t tim)
1733 {
1734     char buf[BUFSIZ];
1735
1736     if (!tim)
1737         time(&tim);
1738     if (!*fmt)
1739         fmt = "%c";
1740     strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&tim) : localtime(&tim));
1741
1742     buf[sizeof(buf) - 1] = '\0';
1743     return bmake_strdup(buf);
1744 }
1745
1746 /* The ApplyModifier functions all work in the same way.  They get the
1747  * current parsing position (pp) and parse the modifier from there.  The
1748  * modifier typically lasts until the next ':', or a closing '}' or ')'
1749  * (taken from st->endc), or the end of the string (parse error).
1750  *
1751  * The high-level behavior of these functions is:
1752  *
1753  * 1. parse the modifier
1754  * 2. evaluate the modifier
1755  * 3. housekeeping
1756  *
1757  * Parsing the modifier
1758  *
1759  * If parsing succeeds, the parsing position *pp is updated to point to the
1760  * first character following the modifier, which typically is either ':' or
1761  * st->endc.
1762  *
1763  * If parsing fails because of a missing delimiter (as in the :S, :C or :@
1764  * modifiers), return AMR_CLEANUP.
1765  *
1766  * If parsing fails because the modifier is unknown, return AMR_UNKNOWN to
1767  * try the SysV modifier ${VAR:from=to} as fallback.  This should only be
1768  * done as long as there have been no side effects from evaluating nested
1769  * variables, to avoid evaluating them more than once.  In this case, the
1770  * parsing position must not be updated.  (XXX: Why not? The original parsing
1771  * position is well-known in ApplyModifiers.)
1772  *
1773  * If parsing fails and the SysV modifier ${VAR:from=to} should not be used
1774  * as a fallback, either issue an error message using Error or Parse_Error
1775  * and then return AMR_CLEANUP, or return AMR_BAD for the default error
1776  * message.  Both of these return values will stop processing the variable
1777  * expression.  (XXX: As of 2020-08-23, evaluation of the whole string
1778  * continues nevertheless after skipping a few bytes, which essentially is
1779  * undefined behavior.  Not in the sense of C, but still it's impossible to
1780  * predict what happens in the parser.)
1781  *
1782  * Evaluating the modifier
1783  *
1784  * After parsing, the modifier is evaluated.  The side effects from evaluating
1785  * nested variable expressions in the modifier text often already happen
1786  * during parsing though.
1787  *
1788  * Evaluating the modifier usually takes the current value of the variable
1789  * expression from st->val, or the variable name from st->v->name and stores
1790  * the result in st->newVal.
1791  *
1792  * If evaluating fails (as of 2020-08-23), an error message is printed using
1793  * Error.  This function has no side-effects, it really just prints the error
1794  * message.  Processing the expression continues as if everything were ok.
1795  * XXX: This should be fixed by adding proper error handling to Var_Subst,
1796  * Var_Parse, ApplyModifiers and ModifyWords.
1797  *
1798  * Housekeeping
1799  *
1800  * Some modifiers such as :D and :U turn undefined expressions into defined
1801  * expressions (see VEF_UNDEF, VEF_DEF).
1802  *
1803  * Some modifiers need to free some memory.
1804  */
1805
1806 typedef enum VarExprFlags {
1807     /* The variable expression is based on an undefined variable. */
1808     VEF_UNDEF = 0x01,
1809     /* The variable expression started as an undefined expression, but one
1810      * of the modifiers (such as :D or :U) has turned the expression from
1811      * undefined to defined. */
1812     VEF_DEF = 0x02
1813 } VarExprFlags;
1814
1815 ENUM_FLAGS_RTTI_2(VarExprFlags,
1816                   VEF_UNDEF, VEF_DEF);
1817
1818
1819 typedef struct ApplyModifiersState {
1820     const char startc;          /* '\0' or '{' or '(' */
1821     const char endc;            /* '\0' or '}' or ')' */
1822     Var * const v;
1823     GNode * const ctxt;
1824     const VarEvalFlags eflags;
1825
1826     char *val;                  /* The old value of the expression,
1827                                  * before applying the modifier, never NULL */
1828     char *newVal;               /* The new value of the expression,
1829                                  * after applying the modifier, never NULL */
1830     char sep;                   /* Word separator in expansions
1831                                  * (see the :ts modifier) */
1832     Boolean oneBigWord;         /* TRUE if some modifiers that otherwise split
1833                                  * the variable value into words, like :S and
1834                                  * :C, treat the variable value as a single big
1835                                  * word, possibly containing spaces. */
1836     VarExprFlags exprFlags;
1837 } ApplyModifiersState;
1838
1839 static void
1840 ApplyModifiersState_Define(ApplyModifiersState *st)
1841 {
1842     if (st->exprFlags & VEF_UNDEF)
1843         st->exprFlags |= VEF_DEF;
1844 }
1845
1846 typedef enum ApplyModifierResult {
1847     AMR_OK,                     /* Continue parsing */
1848     AMR_UNKNOWN,                /* Not a match, try other modifiers as well */
1849     AMR_BAD,                    /* Error out with "Bad modifier" message */
1850     AMR_CLEANUP                 /* Error out without error message */
1851 } ApplyModifierResult;
1852
1853 /* Allow backslashes to escape the delimiter, $, and \, but don't touch other
1854  * backslashes. */
1855 static Boolean
1856 IsEscapedModifierPart(const char *p, char delim,
1857                       struct ModifyWord_SubstArgs *subst)
1858 {
1859     if (p[0] != '\\')
1860         return FALSE;
1861     if (p[1] == delim || p[1] == '\\' || p[1] == '$')
1862         return TRUE;
1863     return p[1] == '&' && subst != NULL;
1864 }
1865
1866 /*
1867  * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or
1868  * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and
1869  * including the next unescaped delimiter.  The delimiter, as well as the
1870  * backslash or the dollar, can be escaped with a backslash.
1871  *
1872  * Return the parsed (and possibly expanded) string, or NULL if no delimiter
1873  * was found.  On successful return, the parsing position pp points right
1874  * after the delimiter.  The delimiter is not included in the returned
1875  * value though.
1876  */
1877 static VarParseResult
1878 ParseModifierPart(
1879     const char **pp,            /* The parsing position, updated upon return */
1880     char delim,                 /* Parsing stops at this delimiter */
1881     VarEvalFlags eflags,        /* Flags for evaluating nested variables;
1882                                  * if VARE_WANTRES is not set, the text is
1883                                  * only parsed */
1884     ApplyModifiersState *st,
1885     char **out_part,
1886     size_t *out_length,         /* Optionally stores the length of the returned
1887                                  * string, just to save another strlen call. */
1888     VarPatternFlags *out_pflags,/* For the first part of the :S modifier,
1889                                  * sets the VARP_ANCHOR_END flag if the last
1890                                  * character of the pattern is a $. */
1891     struct ModifyWord_SubstArgs *subst
1892                                 /* For the second part of the :S modifier,
1893                                  * allow ampersands to be escaped and replace
1894                                  * unescaped ampersands with subst->lhs. */
1895 ) {
1896     Buffer buf;
1897     const char *p;
1898
1899     Buf_Init(&buf, 0);
1900
1901     /*
1902      * Skim through until the matching delimiter is found; pick up variable
1903      * expressions on the way.
1904      */
1905     p = *pp;
1906     while (*p != '\0' && *p != delim) {
1907         const char *varstart;
1908
1909         if (IsEscapedModifierPart(p, delim, subst)) {
1910             Buf_AddByte(&buf, p[1]);
1911             p += 2;
1912             continue;
1913         }
1914
1915         if (*p != '$') {        /* Unescaped, simple text */
1916             if (subst != NULL && *p == '&')
1917                 Buf_AddBytes(&buf, subst->lhs, subst->lhsLen);
1918             else
1919                 Buf_AddByte(&buf, *p);
1920             p++;
1921             continue;
1922         }
1923
1924         if (p[1] == delim) {    /* Unescaped $ at end of pattern */
1925             if (out_pflags != NULL)
1926                 *out_pflags |= VARP_ANCHOR_END;
1927             else
1928                 Buf_AddByte(&buf, *p);
1929             p++;
1930             continue;
1931         }
1932
1933         if (eflags & VARE_WANTRES) {    /* Nested variable, evaluated */
1934             const char *nested_p = p;
1935             const char *nested_val;
1936             void *nested_val_freeIt;
1937             VarEvalFlags nested_eflags = eflags & ~(unsigned)VARE_ASSIGN;
1938
1939             (void)Var_Parse(&nested_p, st->ctxt, nested_eflags,
1940                             &nested_val, &nested_val_freeIt);
1941             /* TODO: handle errors */
1942             Buf_AddStr(&buf, nested_val);
1943             free(nested_val_freeIt);
1944             p += nested_p - p;
1945             continue;
1946         }
1947
1948         /* XXX: This whole block is very similar to Var_Parse without
1949          * VARE_WANTRES.  There may be subtle edge cases though that are
1950          * not yet covered in the unit tests and that are parsed differently,
1951          * depending on whether they are evaluated or not.
1952          *
1953          * This subtle difference is not documented in the manual page,
1954          * neither is the difference between parsing :D and :M documented.
1955          * No code should ever depend on these details, but who knows. */
1956
1957         varstart = p;           /* Nested variable, only parsed */
1958         if (p[1] == '(' || p[1] == '{') {
1959             /*
1960              * Find the end of this variable reference
1961              * and suck it in without further ado.
1962              * It will be interpreted later.
1963              */
1964             char startc = p[1];
1965             int endc = startc == '(' ? ')' : '}';
1966             int depth = 1;
1967
1968             for (p += 2; *p != '\0' && depth > 0; p++) {
1969                 if (p[-1] != '\\') {
1970                     if (*p == startc)
1971                         depth++;
1972                     if (*p == endc)
1973                         depth--;
1974                 }
1975             }
1976             Buf_AddBytesBetween(&buf, varstart, p);
1977         } else {
1978             Buf_AddByte(&buf, *varstart);
1979             p++;
1980         }
1981     }
1982
1983     if (*p != delim) {
1984         *pp = p;
1985         Error("Unfinished modifier for %s ('%c' missing)", st->v->name, delim);
1986         *out_part = NULL;
1987         return VPR_PARSE_MSG;
1988     }
1989
1990     *pp = ++p;
1991     if (out_length != NULL)
1992         *out_length = Buf_Len(&buf);
1993
1994     *out_part = Buf_Destroy(&buf, FALSE);
1995     VAR_DEBUG1("Modifier part: \"%s\"\n", *out_part);
1996     return VPR_OK;
1997 }
1998
1999 /* Test whether mod starts with modname, followed by a delimiter. */
2000 static Boolean
2001 ModMatch(const char *mod, const char *modname, char endc)
2002 {
2003     size_t n = strlen(modname);
2004     return strncmp(mod, modname, n) == 0 &&
2005            (mod[n] == endc || mod[n] == ':');
2006 }
2007
2008 /* Test whether mod starts with modname, followed by a delimiter or '='. */
2009 static inline Boolean
2010 ModMatchEq(const char *mod, const char *modname, char endc)
2011 {
2012     size_t n = strlen(modname);
2013     return strncmp(mod, modname, n) == 0 &&
2014            (mod[n] == endc || mod[n] == ':' || mod[n] == '=');
2015 }
2016
2017 static Boolean
2018 TryParseIntBase0(const char **pp, int *out_num)
2019 {
2020     char *end;
2021     long n;
2022
2023     errno = 0;
2024     n = strtol(*pp, &end, 0);
2025     if ((n == LONG_MIN || n == LONG_MAX) && errno == ERANGE)
2026         return FALSE;
2027     if (n < INT_MIN || n > INT_MAX)
2028         return FALSE;
2029
2030     *pp = end;
2031     *out_num = (int)n;
2032     return TRUE;
2033 }
2034
2035 static Boolean
2036 TryParseSize(const char **pp, size_t *out_num)
2037 {
2038     char *end;
2039     unsigned long n;
2040
2041     if (!ch_isdigit(**pp))
2042         return FALSE;
2043
2044     errno = 0;
2045     n = strtoul(*pp, &end, 10);
2046     if (n == ULONG_MAX && errno == ERANGE)
2047         return FALSE;
2048     if (n > SIZE_MAX)
2049         return FALSE;
2050
2051     *pp = end;
2052     *out_num = (size_t)n;
2053     return TRUE;
2054 }
2055
2056 static Boolean
2057 TryParseChar(const char **pp, int base, char *out_ch)
2058 {
2059     char *end;
2060     unsigned long n;
2061
2062     if (!ch_isalnum(**pp))
2063         return FALSE;
2064
2065     errno = 0;
2066     n = strtoul(*pp, &end, base);
2067     if (n == ULONG_MAX && errno == ERANGE)
2068         return FALSE;
2069     if (n > UCHAR_MAX)
2070         return FALSE;
2071
2072     *pp = end;
2073     *out_ch = (char)n;
2074     return TRUE;
2075 }
2076
2077 /* :@var@...${var}...@ */
2078 static ApplyModifierResult
2079 ApplyModifier_Loop(const char **pp, ApplyModifiersState *st)
2080 {
2081     struct ModifyWord_LoopArgs args;
2082     char prev_sep;
2083     VarEvalFlags eflags = st->eflags & ~(unsigned)VARE_WANTRES;
2084     VarParseResult res;
2085
2086     args.ctx = st->ctxt;
2087
2088     (*pp)++;                    /* Skip the first '@' */
2089     res = ParseModifierPart(pp, '@', eflags, st,
2090                             &args.tvar, NULL, NULL, NULL);
2091     if (res != VPR_OK)
2092         return AMR_CLEANUP;
2093     if (DEBUG(LINT) && strchr(args.tvar, '$') != NULL) {
2094         Parse_Error(PARSE_FATAL,
2095                     "In the :@ modifier of \"%s\", the variable name \"%s\" "
2096                     "must not contain a dollar.",
2097                     st->v->name, args.tvar);
2098         return AMR_CLEANUP;
2099     }
2100
2101     res = ParseModifierPart(pp, '@', eflags, st,
2102                             &args.str, NULL, NULL, NULL);
2103     if (res != VPR_OK)
2104         return AMR_CLEANUP;
2105
2106     args.eflags = st->eflags & (VARE_UNDEFERR | VARE_WANTRES);
2107     prev_sep = st->sep;
2108     st->sep = ' ';              /* XXX: should be st->sep for consistency */
2109     st->newVal = ModifyWords(st->val, ModifyWord_Loop, &args,
2110                              st->oneBigWord, st->sep);
2111     st->sep = prev_sep;
2112     Var_Delete(args.tvar, st->ctxt);
2113     free(args.tvar);
2114     free(args.str);
2115     return AMR_OK;
2116 }
2117
2118 /* :Ddefined or :Uundefined */
2119 static ApplyModifierResult
2120 ApplyModifier_Defined(const char **pp, ApplyModifiersState *st)
2121 {
2122     Buffer buf;
2123     const char *p;
2124
2125     VarEvalFlags eflags = st->eflags & ~(unsigned)VARE_WANTRES;
2126     if (st->eflags & VARE_WANTRES) {
2127         if ((**pp == 'D') == !(st->exprFlags & VEF_UNDEF))
2128             eflags |= VARE_WANTRES;
2129     }
2130
2131     Buf_Init(&buf, 0);
2132     p = *pp + 1;
2133     while (*p != st->endc && *p != ':' && *p != '\0') {
2134
2135         /* Escaped delimiter or other special character */
2136         if (*p == '\\') {
2137             char c = p[1];
2138             if (c == st->endc || c == ':' || c == '$' || c == '\\') {
2139                 Buf_AddByte(&buf, c);
2140                 p += 2;
2141                 continue;
2142             }
2143         }
2144
2145         /* Nested variable expression */
2146         if (*p == '$') {
2147             const char *nested_val;
2148             void *nested_val_freeIt;
2149
2150             (void)Var_Parse(&p, st->ctxt, eflags,
2151                             &nested_val, &nested_val_freeIt);
2152             /* TODO: handle errors */
2153             Buf_AddStr(&buf, nested_val);
2154             free(nested_val_freeIt);
2155             continue;
2156         }
2157
2158         /* Ordinary text */
2159         Buf_AddByte(&buf, *p);
2160         p++;
2161     }
2162     *pp = p;
2163
2164     ApplyModifiersState_Define(st);
2165
2166     if (eflags & VARE_WANTRES) {
2167         st->newVal = Buf_Destroy(&buf, FALSE);
2168     } else {
2169         st->newVal = st->val;
2170         Buf_Destroy(&buf, TRUE);
2171     }
2172     return AMR_OK;
2173 }
2174
2175 /* :L */
2176 static ApplyModifierResult
2177 ApplyModifier_Literal(const char **pp, ApplyModifiersState *st)
2178 {
2179     ApplyModifiersState_Define(st);
2180     st->newVal = bmake_strdup(st->v->name);
2181     (*pp)++;
2182     return AMR_OK;
2183 }
2184
2185 static Boolean
2186 TryParseTime(const char **pp, time_t *out_time)
2187 {
2188     char *end;
2189     unsigned long n;
2190
2191     if (!ch_isdigit(**pp))
2192         return FALSE;
2193
2194     errno = 0;
2195     n = strtoul(*pp, &end, 10);
2196     if (n == ULONG_MAX && errno == ERANGE)
2197         return FALSE;
2198
2199     *pp = end;
2200     *out_time = (time_t)n;      /* ignore possible truncation for now */
2201     return TRUE;
2202 }
2203
2204 /* :gmtime */
2205 static ApplyModifierResult
2206 ApplyModifier_Gmtime(const char **pp, ApplyModifiersState *st)
2207 {
2208     time_t utc;
2209
2210     const char *mod = *pp;
2211     if (!ModMatchEq(mod, "gmtime", st->endc))
2212         return AMR_UNKNOWN;
2213
2214     if (mod[6] == '=') {
2215         const char *arg = mod + 7;
2216         if (!TryParseTime(&arg, &utc)) {
2217             Parse_Error(PARSE_FATAL, "Invalid time value: %s\n", mod + 7);
2218             return AMR_CLEANUP;
2219         }
2220         *pp = arg;
2221     } else {
2222         utc = 0;
2223         *pp = mod + 6;
2224     }
2225     st->newVal = VarStrftime(st->val, TRUE, utc);
2226     return AMR_OK;
2227 }
2228
2229 /* :localtime */
2230 static ApplyModifierResult
2231 ApplyModifier_Localtime(const char **pp, ApplyModifiersState *st)
2232 {
2233     time_t utc;
2234
2235     const char *mod = *pp;
2236     if (!ModMatchEq(mod, "localtime", st->endc))
2237         return AMR_UNKNOWN;
2238
2239     if (mod[9] == '=') {
2240         const char *arg = mod + 10;
2241         if (!TryParseTime(&arg, &utc)) {
2242             Parse_Error(PARSE_FATAL, "Invalid time value: %s\n", mod + 10);
2243             return AMR_CLEANUP;
2244         }
2245         *pp = arg;
2246     } else {
2247         utc = 0;
2248         *pp = mod + 9;
2249     }
2250     st->newVal = VarStrftime(st->val, FALSE, utc);
2251     return AMR_OK;
2252 }
2253
2254 /* :hash */
2255 static ApplyModifierResult
2256 ApplyModifier_Hash(const char **pp, ApplyModifiersState *st)
2257 {
2258     if (!ModMatch(*pp, "hash", st->endc))
2259         return AMR_UNKNOWN;
2260
2261     st->newVal = VarHash(st->val);
2262     *pp += 4;
2263     return AMR_OK;
2264 }
2265
2266 /* :P */
2267 static ApplyModifierResult
2268 ApplyModifier_Path(const char **pp, ApplyModifiersState *st)
2269 {
2270     GNode *gn;
2271     char *path;
2272
2273     ApplyModifiersState_Define(st);
2274
2275     gn = Targ_FindNode(st->v->name);
2276     if (gn == NULL || gn->type & OP_NOPATH) {
2277         path = NULL;
2278     } else if (gn->path != NULL) {
2279         path = bmake_strdup(gn->path);
2280     } else {
2281         SearchPath *searchPath = Suff_FindPath(gn);
2282         path = Dir_FindFile(st->v->name, searchPath);
2283     }
2284     if (path == NULL)
2285         path = bmake_strdup(st->v->name);
2286     st->newVal = path;
2287
2288     (*pp)++;
2289     return AMR_OK;
2290 }
2291
2292 /* :!cmd! */
2293 static ApplyModifierResult
2294 ApplyModifier_ShellCommand(const char **pp, ApplyModifiersState *st)
2295 {
2296     char *cmd;
2297     const char *errfmt;
2298     VarParseResult res;
2299
2300     (*pp)++;
2301     res = ParseModifierPart(pp, '!', st->eflags, st,
2302                             &cmd, NULL, NULL, NULL);
2303     if (res != VPR_OK)
2304         return AMR_CLEANUP;
2305
2306     errfmt = NULL;
2307     if (st->eflags & VARE_WANTRES)
2308         st->newVal = Cmd_Exec(cmd, &errfmt);
2309     else
2310         st->newVal = emptyString;
2311     free(cmd);
2312
2313     if (errfmt != NULL)
2314         Error(errfmt, st->val); /* XXX: why still return AMR_OK? */
2315
2316     ApplyModifiersState_Define(st);
2317     return AMR_OK;
2318 }
2319
2320 /* The :range modifier generates an integer sequence as long as the words.
2321  * The :range=7 modifier generates an integer sequence from 1 to 7. */
2322 static ApplyModifierResult
2323 ApplyModifier_Range(const char **pp, ApplyModifiersState *st)
2324 {
2325     size_t n;
2326     Buffer buf;
2327     size_t i;
2328
2329     const char *mod = *pp;
2330     if (!ModMatchEq(mod, "range", st->endc))
2331         return AMR_UNKNOWN;
2332
2333     if (mod[5] == '=') {
2334         const char *p = mod + 6;
2335         if (!TryParseSize(&p, &n)) {
2336             Parse_Error(PARSE_FATAL, "Invalid number: %s\n", mod + 6);
2337             return AMR_CLEANUP;
2338         }
2339         *pp = p;
2340     } else {
2341         n = 0;
2342         *pp = mod + 5;
2343     }
2344
2345     if (n == 0) {
2346         Words words = Str_Words(st->val, FALSE);
2347         n = words.len;
2348         Words_Free(words);
2349     }
2350
2351     Buf_Init(&buf, 0);
2352
2353     for (i = 0; i < n; i++) {
2354         if (i != 0)
2355             Buf_AddByte(&buf, ' ');     /* XXX: st->sep, for consistency */
2356         Buf_AddInt(&buf, 1 + (int)i);
2357     }
2358
2359     st->newVal = Buf_Destroy(&buf, FALSE);
2360     return AMR_OK;
2361 }
2362
2363 /* :Mpattern or :Npattern */
2364 static ApplyModifierResult
2365 ApplyModifier_Match(const char **pp, ApplyModifiersState *st)
2366 {
2367     const char *mod = *pp;
2368     Boolean copy = FALSE;       /* pattern should be, or has been, copied */
2369     Boolean needSubst = FALSE;
2370     const char *endpat;
2371     char *pattern;
2372     ModifyWordsCallback callback;
2373
2374     /*
2375      * In the loop below, ignore ':' unless we are at (or back to) the
2376      * original brace level.
2377      * XXX This will likely not work right if $() and ${} are intermixed.
2378      */
2379     int nest = 0;
2380     const char *p;
2381     for (p = mod + 1; *p != '\0' && !(*p == ':' && nest == 0); p++) {
2382         if (*p == '\\' &&
2383             (p[1] == ':' || p[1] == st->endc || p[1] == st->startc)) {
2384             if (!needSubst)
2385                 copy = TRUE;
2386             p++;
2387             continue;
2388         }
2389         if (*p == '$')
2390             needSubst = TRUE;
2391         if (*p == '(' || *p == '{')
2392             nest++;
2393         if (*p == ')' || *p == '}') {
2394             nest--;
2395             if (nest < 0)
2396                 break;
2397         }
2398     }
2399     *pp = p;
2400     endpat = p;
2401
2402     if (copy) {
2403         char *dst;
2404         const char *src;
2405
2406         /* Compress the \:'s out of the pattern. */
2407         pattern = bmake_malloc((size_t)(endpat - (mod + 1)) + 1);
2408         dst = pattern;
2409         src = mod + 1;
2410         for (; src < endpat; src++, dst++) {
2411             if (src[0] == '\\' && src + 1 < endpat &&
2412                 /* XXX: st->startc is missing here; see above */
2413                 (src[1] == ':' || src[1] == st->endc))
2414                 src++;
2415             *dst = *src;
2416         }
2417         *dst = '\0';
2418         endpat = dst;
2419     } else {
2420         pattern = bmake_strsedup(mod + 1, endpat);
2421     }
2422
2423     if (needSubst) {
2424         /* pattern contains embedded '$', so use Var_Subst to expand it. */
2425         char *old_pattern = pattern;
2426         (void)Var_Subst(pattern, st->ctxt, st->eflags, &pattern);
2427         /* TODO: handle errors */
2428         free(old_pattern);
2429     }
2430
2431     VAR_DEBUG3("Pattern[%s] for [%s] is [%s]\n", st->v->name, st->val, pattern);
2432
2433     callback = mod[0] == 'M' ? ModifyWord_Match : ModifyWord_NoMatch;
2434     st->newVal = ModifyWords(st->val, callback, pattern,
2435                              st->oneBigWord, st->sep);
2436     free(pattern);
2437     return AMR_OK;
2438 }
2439
2440 /* :S,from,to, */
2441 static ApplyModifierResult
2442 ApplyModifier_Subst(const char **pp, ApplyModifiersState *st)
2443 {
2444     struct ModifyWord_SubstArgs args;
2445     char *lhs, *rhs;
2446     Boolean oneBigWord;
2447     VarParseResult res;
2448
2449     char delim = (*pp)[1];
2450     if (delim == '\0') {
2451         Error("Missing delimiter for :S modifier");
2452         (*pp)++;
2453         return AMR_CLEANUP;
2454     }
2455
2456     *pp += 2;
2457
2458     args.pflags = 0;
2459     args.matched = FALSE;
2460
2461     /*
2462      * If pattern begins with '^', it is anchored to the
2463      * start of the word -- skip over it and flag pattern.
2464      */
2465     if (**pp == '^') {
2466         args.pflags |= VARP_ANCHOR_START;
2467         (*pp)++;
2468     }
2469
2470     res = ParseModifierPart(pp, delim, st->eflags, st,
2471                             &lhs, &args.lhsLen, &args.pflags, NULL);
2472     if (res != VPR_OK)
2473         return AMR_CLEANUP;
2474     args.lhs = lhs;
2475
2476     res = ParseModifierPart(pp, delim, st->eflags, st,
2477                             &rhs, &args.rhsLen, NULL, &args);
2478     if (res != VPR_OK)
2479         return AMR_CLEANUP;
2480     args.rhs = rhs;
2481
2482     oneBigWord = st->oneBigWord;
2483     for (;; (*pp)++) {
2484         switch (**pp) {
2485         case 'g':
2486             args.pflags |= VARP_SUB_GLOBAL;
2487             continue;
2488         case '1':
2489             args.pflags |= VARP_SUB_ONE;
2490             continue;
2491         case 'W':
2492             oneBigWord = TRUE;
2493             continue;
2494         }
2495         break;
2496     }
2497
2498     st->newVal = ModifyWords(st->val, ModifyWord_Subst, &args,
2499                              oneBigWord, st->sep);
2500
2501     free(lhs);
2502     free(rhs);
2503     return AMR_OK;
2504 }
2505
2506 #ifndef NO_REGEX
2507
2508 /* :C,from,to, */
2509 static ApplyModifierResult
2510 ApplyModifier_Regex(const char **pp, ApplyModifiersState *st)
2511 {
2512     char *re;
2513     struct ModifyWord_SubstRegexArgs args;
2514     Boolean oneBigWord;
2515     int error;
2516     VarParseResult res;
2517
2518     char delim = (*pp)[1];
2519     if (delim == '\0') {
2520         Error("Missing delimiter for :C modifier");
2521         (*pp)++;
2522         return AMR_CLEANUP;
2523     }
2524
2525     *pp += 2;
2526
2527     res = ParseModifierPart(pp, delim, st->eflags, st,
2528                             &re, NULL, NULL, NULL);
2529     if (res != VPR_OK)
2530         return AMR_CLEANUP;
2531
2532     res = ParseModifierPart(pp, delim, st->eflags, st,
2533                             &args.replace, NULL, NULL, NULL);
2534     if (args.replace == NULL) {
2535         free(re);
2536         return AMR_CLEANUP;
2537     }
2538
2539     args.pflags = 0;
2540     args.matched = FALSE;
2541     oneBigWord = st->oneBigWord;
2542     for (;; (*pp)++) {
2543         switch (**pp) {
2544         case 'g':
2545             args.pflags |= VARP_SUB_GLOBAL;
2546             continue;
2547         case '1':
2548             args.pflags |= VARP_SUB_ONE;
2549             continue;
2550         case 'W':
2551             oneBigWord = TRUE;
2552             continue;
2553         }
2554         break;
2555     }
2556
2557     error = regcomp(&args.re, re, REG_EXTENDED);
2558     free(re);
2559     if (error) {
2560         VarREError(error, &args.re, "Regex compilation error");
2561         free(args.replace);
2562         return AMR_CLEANUP;
2563     }
2564
2565     args.nsub = args.re.re_nsub + 1;
2566     if (args.nsub > 10)
2567         args.nsub = 10;
2568     st->newVal = ModifyWords(st->val, ModifyWord_SubstRegex, &args,
2569                              oneBigWord, st->sep);
2570     regfree(&args.re);
2571     free(args.replace);
2572     return AMR_OK;
2573 }
2574 #endif
2575
2576 /* :Q, :q */
2577 static ApplyModifierResult
2578 ApplyModifier_Quote(const char **pp, ApplyModifiersState *st)
2579 {
2580     if ((*pp)[1] == st->endc || (*pp)[1] == ':') {
2581         st->newVal = VarQuote(st->val, **pp == 'q');
2582         (*pp)++;
2583         return AMR_OK;
2584     } else
2585         return AMR_UNKNOWN;
2586 }
2587
2588 static void
2589 ModifyWord_Copy(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
2590 {
2591     SepBuf_AddStr(buf, word);
2592 }
2593
2594 /* :ts<separator> */
2595 static ApplyModifierResult
2596 ApplyModifier_ToSep(const char **pp, ApplyModifiersState *st)
2597 {
2598     const char *sep = *pp + 2;
2599
2600     /* ":ts<any><endc>" or ":ts<any>:" */
2601     if (sep[0] != st->endc && (sep[1] == st->endc || sep[1] == ':')) {
2602         st->sep = sep[0];
2603         *pp = sep + 1;
2604         goto ok;
2605     }
2606
2607     /* ":ts<endc>" or ":ts:" */
2608     if (sep[0] == st->endc || sep[0] == ':') {
2609         st->sep = '\0';         /* no separator */
2610         *pp = sep;
2611         goto ok;
2612     }
2613
2614     /* ":ts<unrecognised><unrecognised>". */
2615     if (sep[0] != '\\') {
2616         (*pp)++;                /* just for backwards compatibility */
2617         return AMR_BAD;
2618     }
2619
2620     /* ":ts\n" */
2621     if (sep[1] == 'n') {
2622         st->sep = '\n';
2623         *pp = sep + 2;
2624         goto ok;
2625     }
2626
2627     /* ":ts\t" */
2628     if (sep[1] == 't') {
2629         st->sep = '\t';
2630         *pp = sep + 2;
2631         goto ok;
2632     }
2633
2634     /* ":ts\x40" or ":ts\100" */
2635     {
2636         const char *p = sep + 1;
2637         int base = 8;           /* assume octal */
2638
2639         if (sep[1] == 'x') {
2640             base = 16;
2641             p++;
2642         } else if (!ch_isdigit(sep[1])) {
2643             (*pp)++;            /* just for backwards compatibility */
2644             return AMR_BAD;     /* ":ts<backslash><unrecognised>". */
2645         }
2646
2647         if (!TryParseChar(&p, base, &st->sep)) {
2648             Parse_Error(PARSE_FATAL, "Invalid character number: %s\n", p);
2649             return AMR_CLEANUP;
2650         }
2651         if (*p != ':' && *p != st->endc) {
2652             (*pp)++;            /* just for backwards compatibility */
2653             return AMR_BAD;
2654         }
2655
2656         *pp = p;
2657     }
2658
2659 ok:
2660     st->newVal = ModifyWords(st->val, ModifyWord_Copy, NULL,
2661                              st->oneBigWord, st->sep);
2662     return AMR_OK;
2663 }
2664
2665 /* :tA, :tu, :tl, :ts<separator>, etc. */
2666 static ApplyModifierResult
2667 ApplyModifier_To(const char **pp, ApplyModifiersState *st)
2668 {
2669     const char *mod = *pp;
2670     assert(mod[0] == 't');
2671
2672     if (mod[1] == st->endc || mod[1] == ':' || mod[1] == '\0') {
2673         *pp = mod + 1;
2674         return AMR_BAD;         /* Found ":t<endc>" or ":t:". */
2675     }
2676
2677     if (mod[1] == 's')
2678         return ApplyModifier_ToSep(pp, st);
2679
2680     if (mod[2] != st->endc && mod[2] != ':') {
2681         *pp = mod + 1;
2682         return AMR_BAD;         /* Found ":t<unrecognised><unrecognised>". */
2683     }
2684
2685     /* Check for two-character options: ":tu", ":tl" */
2686     if (mod[1] == 'A') {        /* absolute path */
2687         st->newVal = ModifyWords(st->val, ModifyWord_Realpath, NULL,
2688                                  st->oneBigWord, st->sep);
2689         *pp = mod + 2;
2690         return AMR_OK;
2691     }
2692
2693     if (mod[1] == 'u') {        /* :tu */
2694         size_t i;
2695         size_t len = strlen(st->val);
2696         st->newVal = bmake_malloc(len + 1);
2697         for (i = 0; i < len + 1; i++)
2698             st->newVal[i] = ch_toupper(st->val[i]);
2699         *pp = mod + 2;
2700         return AMR_OK;
2701     }
2702
2703     if (mod[1] == 'l') {        /* :tl */
2704         size_t i;
2705         size_t len = strlen(st->val);
2706         st->newVal = bmake_malloc(len + 1);
2707         for (i = 0; i < len + 1; i++)
2708             st->newVal[i] = ch_tolower(st->val[i]);
2709         *pp = mod + 2;
2710         return AMR_OK;
2711     }
2712
2713     if (mod[1] == 'W' || mod[1] == 'w') { /* :tW, :tw */
2714         st->oneBigWord = mod[1] == 'W';
2715         st->newVal = st->val;
2716         *pp = mod + 2;
2717         return AMR_OK;
2718     }
2719
2720     /* Found ":t<unrecognised>:" or ":t<unrecognised><endc>". */
2721     *pp = mod + 1;
2722     return AMR_BAD;
2723 }
2724
2725 /* :[#], :[1], :[-1..1], etc. */
2726 static ApplyModifierResult
2727 ApplyModifier_Words(const char **pp, ApplyModifiersState *st)
2728 {
2729     char *estr;
2730     int first, last;
2731     VarParseResult res;
2732     const char *p;
2733
2734     (*pp)++;                    /* skip the '[' */
2735     res = ParseModifierPart(pp, ']', st->eflags, st,
2736                             &estr, NULL, NULL, NULL);
2737     if (res != VPR_OK)
2738         return AMR_CLEANUP;
2739
2740     /* now *pp points just after the closing ']' */
2741     if (**pp != ':' && **pp != st->endc)
2742         goto bad_modifier;      /* Found junk after ']' */
2743
2744     if (estr[0] == '\0')
2745         goto bad_modifier;      /* empty square brackets in ":[]". */
2746
2747     if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */
2748         if (st->oneBigWord) {
2749             st->newVal = bmake_strdup("1");
2750         } else {
2751             Buffer buf;
2752
2753             Words words = Str_Words(st->val, FALSE);
2754             size_t ac = words.len;
2755             Words_Free(words);
2756
2757             Buf_Init(&buf, 4);  /* 3 digits + '\0' is usually enough */
2758             Buf_AddInt(&buf, (int)ac);
2759             st->newVal = Buf_Destroy(&buf, FALSE);
2760         }
2761         goto ok;
2762     }
2763
2764     if (estr[0] == '*' && estr[1] == '\0') {
2765         /* Found ":[*]" */
2766         st->oneBigWord = TRUE;
2767         st->newVal = st->val;
2768         goto ok;
2769     }
2770
2771     if (estr[0] == '@' && estr[1] == '\0') {
2772         /* Found ":[@]" */
2773         st->oneBigWord = FALSE;
2774         st->newVal = st->val;
2775         goto ok;
2776     }
2777
2778     /*
2779      * We expect estr to contain a single integer for :[N], or two integers
2780      * separated by ".." for :[start..end].
2781      */
2782     p = estr;
2783     if (!TryParseIntBase0(&p, &first))
2784         goto bad_modifier;      /* Found junk instead of a number */
2785
2786     if (p[0] == '\0') { /* Found only one integer in :[N] */
2787         last = first;
2788     } else if (p[0] == '.' && p[1] == '.' && p[2] != '\0') {
2789         /* Expecting another integer after ".." */
2790         p += 2;
2791         if (!TryParseIntBase0(&p, &last) || *p != '\0')
2792             goto bad_modifier;  /* Found junk after ".." */
2793     } else
2794         goto bad_modifier;      /* Found junk instead of ".." */
2795
2796     /*
2797      * Now first and last are properly filled in, but we still have to check
2798      * for 0 as a special case.
2799      */
2800     if (first == 0 && last == 0) {
2801         /* ":[0]" or perhaps ":[0..0]" */
2802         st->oneBigWord = TRUE;
2803         st->newVal = st->val;
2804         goto ok;
2805     }
2806
2807     /* ":[0..N]" or ":[N..0]" */
2808     if (first == 0 || last == 0)
2809         goto bad_modifier;
2810
2811     /* Normal case: select the words described by first and last. */
2812     st->newVal = VarSelectWords(st->sep, st->oneBigWord, st->val, first, last);
2813
2814 ok:
2815     free(estr);
2816     return AMR_OK;
2817
2818 bad_modifier:
2819     free(estr);
2820     return AMR_BAD;
2821 }
2822
2823 static int
2824 str_cmp_asc(const void *a, const void *b)
2825 {
2826     return strcmp(*(const char * const *)a, *(const char * const *)b);
2827 }
2828
2829 static int
2830 str_cmp_desc(const void *a, const void *b)
2831 {
2832     return strcmp(*(const char * const *)b, *(const char * const *)a);
2833 }
2834
2835 /* :O (order ascending) or :Or (order descending) or :Ox (shuffle) */
2836 static ApplyModifierResult
2837 ApplyModifier_Order(const char **pp, ApplyModifiersState *st)
2838 {
2839     const char *mod = (*pp)++;  /* skip past the 'O' in any case */
2840
2841     Words words = Str_Words(st->val, FALSE);
2842
2843     if (mod[1] == st->endc || mod[1] == ':') {
2844         /* :O sorts ascending */
2845         qsort(words.words, words.len, sizeof(char *), str_cmp_asc);
2846
2847     } else if ((mod[1] == 'r' || mod[1] == 'x') &&
2848                (mod[2] == st->endc || mod[2] == ':')) {
2849         (*pp)++;
2850
2851         if (mod[1] == 'r') {
2852             /* :Or sorts descending */
2853             qsort(words.words, words.len, sizeof(char *), str_cmp_desc);
2854
2855         } else {
2856             /* :Ox shuffles
2857              *
2858              * We will use [ac..2] range for mod factors. This will produce
2859              * random numbers in [(ac-1)..0] interval, and minimal
2860              * reasonable value for mod factor is 2 (the mod 1 will produce
2861              * 0 with probability 1).
2862              */
2863             size_t i;
2864             for (i = words.len - 1; i > 0; i--) {
2865                 size_t rndidx = (size_t)random() % (i + 1);
2866                 char *t = words.words[i];
2867                 words.words[i] = words.words[rndidx];
2868                 words.words[rndidx] = t;
2869             }
2870         }
2871     } else {
2872         Words_Free(words);
2873         return AMR_BAD;
2874     }
2875
2876     st->newVal = Words_JoinFree(words);
2877     return AMR_OK;
2878 }
2879
2880 /* :? then : else */
2881 static ApplyModifierResult
2882 ApplyModifier_IfElse(const char **pp, ApplyModifiersState *st)
2883 {
2884     char *then_expr, *else_expr;
2885     VarParseResult res;
2886
2887     Boolean value = FALSE;
2888     VarEvalFlags then_eflags = st->eflags & ~(unsigned)VARE_WANTRES;
2889     VarEvalFlags else_eflags = st->eflags & ~(unsigned)VARE_WANTRES;
2890
2891     int cond_rc = COND_PARSE;   /* anything other than COND_INVALID */
2892     if (st->eflags & VARE_WANTRES) {
2893         cond_rc = Cond_EvalCondition(st->v->name, &value);
2894         if (cond_rc != COND_INVALID && value)
2895             then_eflags |= VARE_WANTRES;
2896         if (cond_rc != COND_INVALID && !value)
2897             else_eflags |= VARE_WANTRES;
2898     }
2899
2900     (*pp)++;                    /* skip past the '?' */
2901     res = ParseModifierPart(pp, ':', then_eflags, st,
2902                             &then_expr, NULL, NULL, NULL);
2903     if (res != VPR_OK)
2904         return AMR_CLEANUP;
2905
2906     res = ParseModifierPart(pp, st->endc, else_eflags, st,
2907                             &else_expr, NULL, NULL, NULL);
2908     if (res != VPR_OK)
2909         return AMR_CLEANUP;
2910
2911     (*pp)--;
2912     if (cond_rc == COND_INVALID) {
2913         Error("Bad conditional expression `%s' in %s?%s:%s",
2914               st->v->name, st->v->name, then_expr, else_expr);
2915         return AMR_CLEANUP;
2916     }
2917
2918     if (value) {
2919         st->newVal = then_expr;
2920         free(else_expr);
2921     } else {
2922         st->newVal = else_expr;
2923         free(then_expr);
2924     }
2925     ApplyModifiersState_Define(st);
2926     return AMR_OK;
2927 }
2928
2929 /*
2930  * The ::= modifiers actually assign a value to the variable.
2931  * Their main purpose is in supporting modifiers of .for loop
2932  * iterators and other obscure uses.  They always expand to
2933  * nothing.  In a target rule that would otherwise expand to an
2934  * empty line they can be preceded with @: to keep make happy.
2935  * Eg.
2936  *
2937  * foo: .USE
2938  * .for i in ${.TARGET} ${.TARGET:R}.gz
2939  *      @: ${t::=$i}
2940  *      @echo blah ${t:T}
2941  * .endfor
2942  *
2943  *        ::=<str>      Assigns <str> as the new value of variable.
2944  *        ::?=<str>     Assigns <str> as value of variable if
2945  *                      it was not already set.
2946  *        ::+=<str>     Appends <str> to variable.
2947  *        ::!=<cmd>     Assigns output of <cmd> as the new value of
2948  *                      variable.
2949  */
2950 static ApplyModifierResult
2951 ApplyModifier_Assign(const char **pp, ApplyModifiersState *st)
2952 {
2953     GNode *v_ctxt;
2954     char delim;
2955     char *val;
2956     VarParseResult res;
2957
2958     const char *mod = *pp;
2959     const char *op = mod + 1;
2960
2961     if (op[0] == '=')
2962         goto ok;
2963     if ((op[0] == '!' || op[0] == '+' || op[0] == '?') && op[1] == '=')
2964         goto ok;
2965     return AMR_UNKNOWN;         /* "::<unrecognised>" */
2966 ok:
2967
2968     if (st->v->name[0] == '\0') {
2969         *pp = mod + 1;
2970         return AMR_BAD;
2971     }
2972
2973     v_ctxt = st->ctxt;          /* context where v belongs */
2974     if (!(st->exprFlags & VEF_UNDEF) && st->ctxt != VAR_GLOBAL) {
2975         Var *gv = VarFind(st->v->name, st->ctxt, 0);
2976         if (gv == NULL)
2977             v_ctxt = VAR_GLOBAL;
2978         else
2979             VarFreeEnv(gv, TRUE);
2980     }
2981
2982     switch (op[0]) {
2983     case '+':
2984     case '?':
2985     case '!':
2986         *pp = mod + 3;
2987         break;
2988     default:
2989         *pp = mod + 2;
2990         break;
2991     }
2992
2993     delim = st->startc == '(' ? ')' : '}';
2994     res = ParseModifierPart(pp, delim, st->eflags, st, &val, NULL, NULL, NULL);
2995     if (res != VPR_OK)
2996         return AMR_CLEANUP;
2997
2998     (*pp)--;
2999
3000     if (st->eflags & VARE_WANTRES) {
3001         switch (op[0]) {
3002         case '+':
3003             Var_Append(st->v->name, val, v_ctxt);
3004             break;
3005         case '!': {
3006             const char *errfmt;
3007             char *cmd_output = Cmd_Exec(val, &errfmt);
3008             if (errfmt)
3009                 Error(errfmt, val);
3010             else
3011                 Var_Set(st->v->name, cmd_output, v_ctxt);
3012             free(cmd_output);
3013             break;
3014         }
3015         case '?':
3016             if (!(st->exprFlags & VEF_UNDEF))
3017                 break;
3018             /* FALLTHROUGH */
3019         default:
3020             Var_Set(st->v->name, val, v_ctxt);
3021             break;
3022         }
3023     }
3024     free(val);
3025     st->newVal = emptyString;
3026     return AMR_OK;
3027 }
3028
3029 /* :_=...
3030  * remember current value */
3031 static ApplyModifierResult
3032 ApplyModifier_Remember(const char **pp, ApplyModifiersState *st)
3033 {
3034     const char *mod = *pp;
3035     if (!ModMatchEq(mod, "_", st->endc))
3036         return AMR_UNKNOWN;
3037
3038     if (mod[1] == '=') {
3039         size_t n = strcspn(mod + 2, ":)}");
3040         char *name = bmake_strldup(mod + 2, n);
3041         Var_Set(name, st->val, st->ctxt);
3042         free(name);
3043         *pp = mod + 2 + n;
3044     } else {
3045         Var_Set("_", st->val, st->ctxt);
3046         *pp = mod + 1;
3047     }
3048     st->newVal = st->val;
3049     return AMR_OK;
3050 }
3051
3052 /* Apply the given function to each word of the variable value,
3053  * for a single-letter modifier such as :H, :T. */
3054 static ApplyModifierResult
3055 ApplyModifier_WordFunc(const char **pp, ApplyModifiersState *st,
3056                        ModifyWordsCallback modifyWord)
3057 {
3058     char delim = (*pp)[1];
3059     if (delim != st->endc && delim != ':')
3060         return AMR_UNKNOWN;
3061
3062     st->newVal = ModifyWords(st->val, modifyWord, NULL,
3063                              st->oneBigWord, st->sep);
3064     (*pp)++;
3065     return AMR_OK;
3066 }
3067
3068 static ApplyModifierResult
3069 ApplyModifier_Unique(const char **pp, ApplyModifiersState *st)
3070 {
3071     if ((*pp)[1] == st->endc || (*pp)[1] == ':') {
3072         st->newVal = VarUniq(st->val);
3073         (*pp)++;
3074         return AMR_OK;
3075     } else
3076         return AMR_UNKNOWN;
3077 }
3078
3079 #ifdef SYSVVARSUB
3080 /* :from=to */
3081 static ApplyModifierResult
3082 ApplyModifier_SysV(const char **pp, ApplyModifiersState *st)
3083 {
3084     char *lhs, *rhs;
3085     VarParseResult res;
3086
3087     const char *mod = *pp;
3088     Boolean eqFound = FALSE;
3089
3090     /*
3091      * First we make a pass through the string trying to verify it is a
3092      * SysV-make-style translation. It must be: <lhs>=<rhs>
3093      */
3094     int depth = 1;
3095     const char *p = mod;
3096     while (*p != '\0' && depth > 0) {
3097         if (*p == '=') {        /* XXX: should also test depth == 1 */
3098             eqFound = TRUE;
3099             /* continue looking for st->endc */
3100         } else if (*p == st->endc)
3101             depth--;
3102         else if (*p == st->startc)
3103             depth++;
3104         if (depth > 0)
3105             p++;
3106     }
3107     if (*p != st->endc || !eqFound)
3108         return AMR_UNKNOWN;
3109
3110     *pp = mod;
3111     res = ParseModifierPart(pp, '=', st->eflags, st,
3112                             &lhs, NULL, NULL, NULL);
3113     if (res != VPR_OK)
3114         return AMR_CLEANUP;
3115
3116     /* The SysV modifier lasts until the end of the variable expression. */
3117     res = ParseModifierPart(pp, st->endc, st->eflags, st,
3118                             &rhs, NULL, NULL, NULL);
3119     if (res != VPR_OK)
3120         return AMR_CLEANUP;
3121
3122     (*pp)--;
3123     if (lhs[0] == '\0' && st->val[0] == '\0') {
3124         st->newVal = st->val;   /* special case */
3125     } else {
3126         struct ModifyWord_SYSVSubstArgs args = {st->ctxt, lhs, rhs};
3127         st->newVal = ModifyWords(st->val, ModifyWord_SYSVSubst, &args,
3128                                  st->oneBigWord, st->sep);
3129     }
3130     free(lhs);
3131     free(rhs);
3132     return AMR_OK;
3133 }
3134 #endif
3135
3136 #ifdef SUNSHCMD
3137 /* :sh */
3138 static ApplyModifierResult
3139 ApplyModifier_SunShell(const char **pp, ApplyModifiersState *st)
3140 {
3141     const char *p = *pp;
3142     if (p[1] == 'h' && (p[2] == st->endc || p[2] == ':')) {
3143         if (st->eflags & VARE_WANTRES) {
3144             const char *errfmt;
3145             st->newVal = Cmd_Exec(st->val, &errfmt);
3146             if (errfmt)
3147                 Error(errfmt, st->val);
3148         } else
3149             st->newVal = emptyString;
3150         *pp = p + 2;
3151         return AMR_OK;
3152     } else
3153         return AMR_UNKNOWN;
3154 }
3155 #endif
3156
3157 static void
3158 LogBeforeApply(const ApplyModifiersState *st, const char *mod, const char endc)
3159 {
3160     char eflags_str[VarEvalFlags_ToStringSize];
3161     char vflags_str[VarFlags_ToStringSize];
3162     char exprflags_str[VarExprFlags_ToStringSize];
3163     Boolean is_single_char = mod[0] != '\0' &&
3164                              (mod[1] == endc || mod[1] == ':');
3165
3166     /* At this point, only the first character of the modifier can
3167      * be used since the end of the modifier is not yet known. */
3168     debug_printf("Applying ${%s:%c%s} to \"%s\" (%s, %s, %s)\n",
3169                  st->v->name, mod[0], is_single_char ? "" : "...", st->val,
3170                  Enum_FlagsToString(eflags_str, sizeof eflags_str,
3171                                     st->eflags, VarEvalFlags_ToStringSpecs),
3172                  Enum_FlagsToString(vflags_str, sizeof vflags_str,
3173                                     st->v->flags, VarFlags_ToStringSpecs),
3174                  Enum_FlagsToString(exprflags_str, sizeof exprflags_str,
3175                                     st->exprFlags,
3176                                     VarExprFlags_ToStringSpecs));
3177 }
3178
3179 static void
3180 LogAfterApply(ApplyModifiersState *st, const char *p, const char *mod)
3181 {
3182     char eflags_str[VarEvalFlags_ToStringSize];
3183     char vflags_str[VarFlags_ToStringSize];
3184     char exprflags_str[VarExprFlags_ToStringSize];
3185     const char *quot = st->newVal == var_Error ? "" : "\"";
3186     const char *newVal = st->newVal == var_Error ? "error" : st->newVal;
3187
3188     debug_printf("Result of ${%s:%.*s} is %s%s%s (%s, %s, %s)\n",
3189                  st->v->name, (int)(p - mod), mod, quot, newVal, quot,
3190                  Enum_FlagsToString(eflags_str, sizeof eflags_str,
3191                                     st->eflags, VarEvalFlags_ToStringSpecs),
3192                  Enum_FlagsToString(vflags_str, sizeof vflags_str,
3193                                     st->v->flags, VarFlags_ToStringSpecs),
3194                  Enum_FlagsToString(exprflags_str, sizeof exprflags_str,
3195                                     st->exprFlags,
3196                                     VarExprFlags_ToStringSpecs));
3197 }
3198
3199 static ApplyModifierResult
3200 ApplyModifier(const char **pp, ApplyModifiersState *st)
3201 {
3202     switch (**pp) {
3203     case ':':
3204         return ApplyModifier_Assign(pp, st);
3205     case '@':
3206         return ApplyModifier_Loop(pp, st);
3207     case '_':
3208         return ApplyModifier_Remember(pp, st);
3209     case 'D':
3210     case 'U':
3211         return ApplyModifier_Defined(pp, st);
3212     case 'L':
3213         return ApplyModifier_Literal(pp, st);
3214     case 'P':
3215         return ApplyModifier_Path(pp, st);
3216     case '!':
3217         return ApplyModifier_ShellCommand(pp, st);
3218     case '[':
3219         return ApplyModifier_Words(pp, st);
3220     case 'g':
3221         return ApplyModifier_Gmtime(pp, st);
3222     case 'h':
3223         return ApplyModifier_Hash(pp, st);
3224     case 'l':
3225         return ApplyModifier_Localtime(pp, st);
3226     case 't':
3227         return ApplyModifier_To(pp, st);
3228     case 'N':
3229     case 'M':
3230         return ApplyModifier_Match(pp, st);
3231     case 'S':
3232         return ApplyModifier_Subst(pp, st);
3233     case '?':
3234         return ApplyModifier_IfElse(pp, st);
3235 #ifndef NO_REGEX
3236     case 'C':
3237         return ApplyModifier_Regex(pp, st);
3238 #endif
3239     case 'q':
3240     case 'Q':
3241         return ApplyModifier_Quote(pp, st);
3242     case 'T':
3243         return ApplyModifier_WordFunc(pp, st, ModifyWord_Tail);
3244     case 'H':
3245         return ApplyModifier_WordFunc(pp, st, ModifyWord_Head);
3246     case 'E':
3247         return ApplyModifier_WordFunc(pp, st, ModifyWord_Suffix);
3248     case 'R':
3249         return ApplyModifier_WordFunc(pp, st, ModifyWord_Root);
3250     case 'r':
3251         return ApplyModifier_Range(pp, st);
3252     case 'O':
3253         return ApplyModifier_Order(pp, st);
3254     case 'u':
3255         return ApplyModifier_Unique(pp, st);
3256 #ifdef SUNSHCMD
3257     case 's':
3258         return ApplyModifier_SunShell(pp, st);
3259 #endif
3260     default:
3261         return AMR_UNKNOWN;
3262     }
3263 }
3264
3265 static char *ApplyModifiers(const char **, char *, char, char, Var *,
3266                             VarExprFlags *, GNode *, VarEvalFlags, void **);
3267
3268 typedef enum ApplyModifiersIndirectResult {
3269     AMIR_CONTINUE,
3270     AMIR_APPLY_MODS,
3271     AMIR_OUT
3272 } ApplyModifiersIndirectResult;
3273
3274 /* While expanding a variable expression, expand and apply indirect
3275  * modifiers. */
3276 static ApplyModifiersIndirectResult
3277 ApplyModifiersIndirect(
3278         ApplyModifiersState *const st,
3279         const char **inout_p,
3280         void **const out_freeIt
3281 ) {
3282     const char *p = *inout_p;
3283     const char *nested_p = p;
3284     void *freeIt;
3285     const char *rval;
3286     char c;
3287
3288     (void)Var_Parse(&nested_p, st->ctxt, st->eflags, &rval, &freeIt);
3289     /* TODO: handle errors */
3290
3291     /*
3292      * If we have not parsed up to st->endc or ':', we are not
3293      * interested.  This means the expression ${VAR:${M_1}${M_2}}
3294      * is not accepted, but ${VAR:${M_1}:${M_2}} is.
3295      */
3296     if (rval[0] != '\0' &&
3297         (c = *nested_p) != '\0' && c != ':' && c != st->endc) {
3298         if (DEBUG(LINT))
3299             Parse_Error(PARSE_FATAL,
3300                         "Missing delimiter ':' after indirect modifier \"%.*s\"",
3301                         (int)(nested_p - p), p);
3302
3303         free(freeIt);
3304         /* XXX: apply_mods doesn't sound like "not interested". */
3305         /* XXX: Why is the indirect modifier parsed again by
3306          * apply_mods?  If any, p should be advanced to nested_p. */
3307         return AMIR_APPLY_MODS;
3308     }
3309
3310     VAR_DEBUG3("Indirect modifier \"%s\" from \"%.*s\"\n",
3311                rval, (int)(size_t)(nested_p - p), p);
3312
3313     p = nested_p;
3314
3315     if (rval[0] != '\0') {
3316         const char *rval_pp = rval;
3317         st->val = ApplyModifiers(&rval_pp, st->val, '\0', '\0', st->v,
3318                                 &st->exprFlags, st->ctxt, st->eflags, out_freeIt);
3319         if (st->val == var_Error
3320             || (st->val == varUndefined && !(st->eflags & VARE_UNDEFERR))
3321             || *rval_pp != '\0') {
3322             free(freeIt);
3323             *inout_p = p;
3324             return AMIR_OUT;    /* error already reported */
3325         }
3326     }
3327     free(freeIt);
3328
3329     if (*p == ':')
3330         p++;
3331     else if (*p == '\0' && st->endc != '\0') {
3332         Error("Unclosed variable specification after complex "
3333               "modifier (expecting '%c') for %s", st->endc, st->v->name);
3334         *inout_p = p;
3335         return AMIR_OUT;
3336     }
3337
3338     *inout_p = p;
3339     return AMIR_CONTINUE;
3340 }
3341
3342 /* Apply any modifiers (such as :Mpattern or :@var@loop@ or :Q or ::=value). */
3343 static char *
3344 ApplyModifiers(
3345     const char **pp,            /* the parsing position, updated upon return */
3346     char *const val,            /* the current value of the expression */
3347     char const startc,          /* '(' or '{', or '\0' for indirect modifiers */
3348     char const endc,            /* ')' or '}', or '\0' for indirect modifiers */
3349     Var * const v,
3350     VarExprFlags *exprFlags,
3351     GNode * const ctxt,         /* for looking up and modifying variables */
3352     VarEvalFlags const eflags,
3353     void ** const out_freeIt    /* free this after using the return value */
3354 ) {
3355     ApplyModifiersState st = {
3356         startc, endc, v, ctxt, eflags,
3357         val,                    /* .val */
3358         var_Error,              /* .newVal */
3359         ' ',                    /* .sep */
3360         FALSE,                  /* .oneBigWord */
3361         *exprFlags              /* .exprFlags */
3362     };
3363     const char *p;
3364     const char *mod;
3365     ApplyModifierResult res;
3366
3367     assert(startc == '(' || startc == '{' || startc == '\0');
3368     assert(endc == ')' || endc == '}' || endc == '\0');
3369     assert(val != NULL);
3370
3371     p = *pp;
3372     while (*p != '\0' && *p != endc) {
3373
3374         if (*p == '$') {
3375             ApplyModifiersIndirectResult amir;
3376             amir = ApplyModifiersIndirect(&st, &p, out_freeIt);
3377             if (amir == AMIR_CONTINUE)
3378                 continue;
3379             if (amir == AMIR_OUT)
3380                 goto out;
3381         }
3382         st.newVal = var_Error;  /* default value, in case of errors */
3383         mod = p;
3384
3385         if (DEBUG(VAR))
3386             LogBeforeApply(&st, mod, endc);
3387
3388         res = ApplyModifier(&p, &st);
3389
3390 #ifdef SYSVVARSUB
3391         if (res == AMR_UNKNOWN) {
3392             assert(p == mod);
3393             res = ApplyModifier_SysV(&p, &st);
3394         }
3395 #endif
3396
3397         if (res == AMR_UNKNOWN) {
3398             Error("Unknown modifier '%c'", *mod);
3399             for (p++; *p != ':' && *p != st.endc && *p != '\0'; p++)
3400                 continue;
3401             st.newVal = var_Error;
3402         }
3403         if (res == AMR_CLEANUP)
3404             goto cleanup;
3405         if (res == AMR_BAD)
3406             goto bad_modifier;
3407
3408         if (DEBUG(VAR))
3409             LogAfterApply(&st, p, mod);
3410
3411         if (st.newVal != st.val) {
3412             if (*out_freeIt) {
3413                 free(st.val);
3414                 *out_freeIt = NULL;
3415             }
3416             st.val = st.newVal;
3417             if (st.val != var_Error && st.val != varUndefined &&
3418                 st.val != emptyString) {
3419                 *out_freeIt = st.val;
3420             }
3421         }
3422         if (*p == '\0' && st.endc != '\0') {
3423             Error("Unclosed variable specification (expecting '%c') "
3424                   "for \"%s\" (value \"%s\") modifier %c",
3425                   st.endc, st.v->name, st.val, *mod);
3426         } else if (*p == ':') {
3427             p++;
3428         } else if (DEBUG(LINT) && *p != '\0' && *p != endc) {
3429             Parse_Error(PARSE_FATAL,
3430                         "Missing delimiter ':' after modifier \"%.*s\"",
3431                         (int)(p - mod), mod);
3432         }
3433     }
3434 out:
3435     *pp = p;
3436     assert(st.val != NULL);     /* Use var_Error or varUndefined instead. */
3437     *exprFlags = st.exprFlags;
3438     return st.val;
3439
3440 bad_modifier:
3441     Error("Bad modifier `:%.*s' for %s",
3442           (int)strcspn(mod, ":)}"), mod, st.v->name);
3443
3444 cleanup:
3445     *pp = p;
3446     free(*out_freeIt);
3447     *out_freeIt = NULL;
3448     *exprFlags = st.exprFlags;
3449     return var_Error;
3450 }
3451
3452 /* Only four of the local variables are treated specially as they are the
3453  * only four that will be set when dynamic sources are expanded. */
3454 static Boolean
3455 VarnameIsDynamic(const char *name, size_t len)
3456 {
3457     if (len == 1 || (len == 2 && (name[1] == 'F' || name[1] == 'D'))) {
3458         switch (name[0]) {
3459         case '@':
3460         case '%':
3461         case '*':
3462         case '!':
3463             return TRUE;
3464         }
3465         return FALSE;
3466     }
3467
3468     if ((len == 7 || len == 8) && name[0] == '.' && ch_isupper(name[1])) {
3469         return strcmp(name, ".TARGET") == 0 ||
3470                strcmp(name, ".ARCHIVE") == 0 ||
3471                strcmp(name, ".PREFIX") == 0 ||
3472                strcmp(name, ".MEMBER") == 0;
3473     }
3474
3475     return FALSE;
3476 }
3477
3478 static const char *
3479 UndefinedShortVarValue(char varname, const GNode *ctxt, VarEvalFlags eflags)
3480 {
3481     if (ctxt == VAR_CMDLINE || ctxt == VAR_GLOBAL) {
3482         /*
3483          * If substituting a local variable in a non-local context,
3484          * assume it's for dynamic source stuff. We have to handle
3485          * this specially and return the longhand for the variable
3486          * with the dollar sign escaped so it makes it back to the
3487          * caller. Only four of the local variables are treated
3488          * specially as they are the only four that will be set
3489          * when dynamic sources are expanded.
3490          */
3491         switch (varname) {
3492         case '@':
3493             return "$(.TARGET)";
3494         case '%':
3495             return "$(.MEMBER)";
3496         case '*':
3497             return "$(.PREFIX)";
3498         case '!':
3499             return "$(.ARCHIVE)";
3500         }
3501     }
3502     return eflags & VARE_UNDEFERR ? var_Error : varUndefined;
3503 }
3504
3505 /* Parse a variable name, until the end character or a colon, whichever
3506  * comes first. */
3507 static char *
3508 ParseVarname(const char **pp, char startc, char endc,
3509              GNode *ctxt, VarEvalFlags eflags,
3510              size_t *out_varname_len)
3511 {
3512     Buffer buf;
3513     const char *p = *pp;
3514     int depth = 1;
3515
3516     Buf_Init(&buf, 0);
3517
3518     while (*p != '\0') {
3519         /* Track depth so we can spot parse errors. */
3520         if (*p == startc)
3521             depth++;
3522         if (*p == endc) {
3523             if (--depth == 0)
3524                 break;
3525         }
3526         if (*p == ':' && depth == 1)
3527             break;
3528
3529         /* A variable inside a variable, expand. */
3530         if (*p == '$') {
3531             void *freeIt;
3532             const char *rval;
3533             (void)Var_Parse(&p, ctxt, eflags, &rval, &freeIt);
3534             /* TODO: handle errors */
3535             Buf_AddStr(&buf, rval);
3536             free(freeIt);
3537         } else {
3538             Buf_AddByte(&buf, *p);
3539             p++;
3540         }
3541     }
3542     *pp = p;
3543     *out_varname_len = Buf_Len(&buf);
3544     return Buf_Destroy(&buf, FALSE);
3545 }
3546
3547 static Boolean
3548 ValidShortVarname(char varname, const char *start)
3549 {
3550     switch (varname) {
3551     case '\0':
3552     case ')':
3553     case '}':
3554     case ':':
3555     case '$':
3556         break;                  /* and continue below */
3557     default:
3558         return TRUE;
3559     }
3560
3561     if (!DEBUG(LINT))
3562         return FALSE;
3563
3564     if (varname == '$')
3565         Parse_Error(PARSE_FATAL,
3566                     "To escape a dollar, use \\$, not $$, at \"%s\"", start);
3567     else if (varname == '\0')
3568         Parse_Error(PARSE_FATAL, "Dollar followed by nothing");
3569     else
3570         Parse_Error(PARSE_FATAL,
3571                     "Invalid variable name '%c', at \"%s\"", varname, start);
3572
3573     return FALSE;
3574 }
3575
3576 /* Parse a single-character variable name such as $V or $@.
3577  * Return whether to continue parsing. */
3578 static Boolean
3579 ParseVarnameShort(
3580         char startc,
3581         const char **pp,
3582         GNode *ctxt,
3583         VarEvalFlags eflags,
3584         VarParseResult *out_FALSE_res,
3585         const char **out_FALSE_val,
3586         Var **out_TRUE_var
3587 ) {
3588     char name[2];
3589     Var *v;
3590
3591     /*
3592      * If it's not bounded by braces of some sort, life is much simpler.
3593      * We just need to check for the first character and return the
3594      * value if it exists.
3595      */
3596
3597     if (!ValidShortVarname(startc, *pp)) {
3598         (*pp)++;
3599         *out_FALSE_val = var_Error;
3600         *out_FALSE_res = VPR_PARSE_MSG;
3601         return FALSE;
3602     }
3603
3604     name[0] = startc;
3605     name[1] = '\0';
3606     v = VarFind(name, ctxt, TRUE);
3607     if (v == NULL) {
3608         *pp += 2;
3609
3610         *out_FALSE_val = UndefinedShortVarValue(startc, ctxt, eflags);
3611         if (DEBUG(LINT) && *out_FALSE_val == var_Error) {
3612             Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined", name);
3613             *out_FALSE_res = VPR_UNDEF_MSG;
3614             return FALSE;
3615         }
3616         *out_FALSE_res = eflags & VARE_UNDEFERR ? VPR_UNDEF_SILENT : VPR_OK;
3617         return FALSE;
3618     }
3619
3620     *out_TRUE_var = v;
3621     return TRUE;
3622 }
3623
3624 /* Parse a long variable name enclosed in braces or parentheses such as $(VAR)
3625  * or ${VAR}, up to the closing brace or parenthesis, or in the case of
3626  * ${VAR:Modifiers}, up to the ':' that starts the modifiers.
3627  * Return whether to continue parsing. */
3628 static Boolean
3629 ParseVarnameLong(
3630         const char **pp,
3631         char startc,
3632         GNode *ctxt,
3633         VarEvalFlags eflags,
3634
3635         VarParseResult *out_FALSE_res,
3636         const char **out_FALSE_val,
3637         void **out_FALSE_freePtr,
3638
3639         char *out_TRUE_endc,
3640         const char **out_TRUE_p,
3641         Var **out_TRUE_v,
3642         Boolean *out_TRUE_haveModifier,
3643         const char **out_TRUE_extraModifiers,
3644         Boolean *out_TRUE_dynamic,
3645         VarExprFlags *out_TRUE_exprFlags
3646 ) {
3647     size_t namelen;
3648     char *varname;
3649     Var *v;
3650     Boolean haveModifier;
3651     Boolean dynamic = FALSE;
3652
3653     const char *const start = *pp;
3654     char endc = startc == '(' ? ')' : '}';
3655
3656     const char *p = start + 2;
3657     varname = ParseVarname(&p, startc, endc, ctxt, eflags, &namelen);
3658
3659     if (*p == ':') {
3660         haveModifier = TRUE;
3661     } else if (*p == endc) {
3662         haveModifier = FALSE;
3663     } else {
3664         Parse_Error(PARSE_FATAL, "Unclosed variable \"%s\"", varname);
3665         *pp = p;
3666         free(varname);
3667         *out_FALSE_val = var_Error;
3668         *out_FALSE_res = VPR_PARSE_MSG;
3669         return FALSE;
3670     }
3671
3672     v = VarFind(varname, ctxt, TRUE);
3673
3674     /* At this point, p points just after the variable name,
3675      * either at ':' or at endc. */
3676
3677     /*
3678      * Check also for bogus D and F forms of local variables since we're
3679      * in a local context and the name is the right length.
3680      */
3681     if (v == NULL && ctxt != VAR_CMDLINE && ctxt != VAR_GLOBAL &&
3682         namelen == 2 && (varname[1] == 'F' || varname[1] == 'D') &&
3683         strchr("@%?*!<>", varname[0]) != NULL)
3684     {
3685         /*
3686          * Well, it's local -- go look for it.
3687          */
3688         char name[] = { varname[0], '\0' };
3689         v = VarFind(name, ctxt, 0);
3690
3691         if (v != NULL) {
3692             if (varname[1] == 'D') {
3693                 *out_TRUE_extraModifiers = "H:";
3694             } else { /* F */
3695                 *out_TRUE_extraModifiers = "T:";
3696             }
3697         }
3698     }
3699
3700     if (v == NULL) {
3701         /* Defer expansion of dynamic variables if they appear in non-local
3702          * context since they are not defined there. */
3703         dynamic = VarnameIsDynamic(varname, namelen) &&
3704                   (ctxt == VAR_CMDLINE || ctxt == VAR_GLOBAL);
3705
3706         if (!haveModifier) {
3707             p++;                /* skip endc */
3708             *pp = p;
3709             if (dynamic) {
3710                 char *pstr = bmake_strsedup(start, p);
3711                 free(varname);
3712                 *out_FALSE_res = VPR_OK;
3713                 *out_FALSE_freePtr = pstr;
3714                 *out_FALSE_val = pstr;
3715                 return FALSE;
3716             }
3717
3718             if ((eflags & VARE_UNDEFERR) && (eflags & VARE_WANTRES) &&
3719                 DEBUG(LINT))
3720             {
3721                 Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined",
3722                             varname);
3723                 free(varname);
3724                 *out_FALSE_res = VPR_UNDEF_MSG;
3725                 *out_FALSE_val = var_Error;
3726                 return FALSE;
3727             }
3728
3729             if (eflags & VARE_UNDEFERR) {
3730                 free(varname);
3731                 *out_FALSE_res = VPR_UNDEF_SILENT;
3732                 *out_FALSE_val = var_Error;
3733                 return FALSE;
3734             }
3735
3736             free(varname);
3737             *out_FALSE_res = VPR_OK;
3738             *out_FALSE_val = varUndefined;
3739             return FALSE;
3740         }
3741
3742         /* The variable expression is based on an undefined variable.
3743          * Nevertheless it needs a Var, for modifiers that access the
3744          * variable name, such as :L or :?.
3745          *
3746          * Most modifiers leave this expression in the "undefined" state
3747          * (VEF_UNDEF), only a few modifiers like :D, :U, :L, :P turn this
3748          * undefined expression into a defined expression (VEF_DEF).
3749          *
3750          * At the end, after applying all modifiers, if the expression
3751          * is still undefined, Var_Parse will return an empty string
3752          * instead of the actually computed value. */
3753         v = VarNew(varname, varname, "", 0);
3754         *out_TRUE_exprFlags = VEF_UNDEF;
3755     } else
3756         free(varname);
3757
3758     *out_TRUE_endc = endc;
3759     *out_TRUE_p = p;
3760     *out_TRUE_v = v;
3761     *out_TRUE_haveModifier = haveModifier;
3762     *out_TRUE_dynamic = dynamic;
3763     return TRUE;
3764 }
3765
3766 /*-
3767  *-----------------------------------------------------------------------
3768  * Var_Parse --
3769  *      Given the start of a variable expression (such as $v, $(VAR),
3770  *      ${VAR:Mpattern}), extract the variable name, possibly some
3771  *      modifiers and find its value by applying the modifiers to the
3772  *      original value.
3773  *
3774  *      When parsing a condition in ParseEmptyArg, pp may also point to
3775  *      the "y" of "empty(VARNAME:Modifiers)", which is syntactically
3776  *      identical.
3777  *
3778  * Input:
3779  *      str             The string to parse
3780  *      ctxt            The context for the variable
3781  *      flags           Select the exact details of parsing
3782  *      out_val_freeIt  Must be freed by the caller after using out_val
3783  *
3784  * Results:
3785  *      Returns the value of the variable expression, never NULL.
3786  *      Returns var_Error if there was a parse error and VARE_UNDEFERR was
3787  *      set.
3788  *      Returns varUndefined if there was an undefined variable and
3789  *      VARE_UNDEFERR was not set.
3790  *
3791  *      Parsing should continue at *pp.
3792  *      TODO: Document the value of *pp on parse errors.  It might be advanced
3793  *      by 0, or +1, or the index of the parse error, or the guessed end of the
3794  *      variable expression.
3795  *
3796  *      If var_Error is returned, a diagnostic may or may not have been
3797  *      printed. XXX: This is inconsistent.
3798  *
3799  *      If varUndefined is returned, a diagnostic may or may not have been
3800  *      printed. XXX: This is inconsistent.
3801  *
3802  *      After using the returned value, *out_val_freeIt must be freed,
3803  *      preferably using bmake_free since it is NULL in most cases.
3804  *
3805  * Side Effects:
3806  *      Any effects from the modifiers, such as :!cmd! or ::=value.
3807  *-----------------------------------------------------------------------
3808  */
3809 /* coverity[+alloc : arg-*4] */
3810 VarParseResult
3811 Var_Parse(const char **pp, GNode *ctxt, VarEvalFlags eflags,
3812           const char **out_val, void **out_val_freeIt)
3813 {
3814     const char *const start = *pp;
3815     const char *p;
3816     Boolean haveModifier;       /* TRUE if have modifiers for the variable */
3817     char startc;                /* Starting character if variable in parens
3818                                  * or braces */
3819     char endc;                  /* Ending character if variable in parens
3820                                  * or braces */
3821     Boolean dynamic;            /* TRUE if the variable is local and we're
3822                                  * expanding it in a non-local context. This
3823                                  * is done to support dynamic sources. The
3824                                  * result is just the expression, unaltered */
3825     const char *extramodifiers;
3826     Var *v;
3827     char *nstr;
3828     char eflags_str[VarEvalFlags_ToStringSize];
3829     VarExprFlags exprFlags = 0;
3830
3831     VAR_DEBUG2("Var_Parse: %s with %s\n", start,
3832                Enum_FlagsToString(eflags_str, sizeof eflags_str, eflags,
3833                                   VarEvalFlags_ToStringSpecs));
3834
3835     *out_val_freeIt = NULL;
3836     extramodifiers = NULL;      /* extra modifiers to apply first */
3837     dynamic = FALSE;
3838
3839     /* Appease GCC, which thinks that the variable might not be
3840      * initialized. */
3841     endc = '\0';
3842
3843     startc = start[1];
3844     if (startc != '(' && startc != '{') {
3845         VarParseResult res;
3846         if (!ParseVarnameShort(startc, pp, ctxt, eflags, &res, out_val, &v))
3847             return res;
3848         haveModifier = FALSE;
3849         p = start + 1;
3850     } else {
3851         VarParseResult res;
3852         if (!ParseVarnameLong(pp, startc, ctxt, eflags,
3853                               &res, out_val, out_val_freeIt,
3854                               &endc, &p, &v, &haveModifier, &extramodifiers,
3855                               &dynamic, &exprFlags))
3856             return res;
3857     }
3858
3859     if (v->flags & VAR_IN_USE)
3860         Fatal("Variable %s is recursive.", v->name);
3861
3862     /*
3863      * Before doing any modification, we have to make sure the value
3864      * has been fully expanded. If it looks like recursion might be
3865      * necessary (there's a dollar sign somewhere in the variable's value)
3866      * we just call Var_Subst to do any other substitutions that are
3867      * necessary. Note that the value returned by Var_Subst will have
3868      * been dynamically-allocated, so it will need freeing when we
3869      * return.
3870      */
3871     nstr = Buf_GetAll(&v->val, NULL);
3872     if (strchr(nstr, '$') != NULL && (eflags & VARE_WANTRES)) {
3873         VarEvalFlags nested_eflags = eflags;
3874         if (DEBUG(LINT))
3875             nested_eflags &= ~(unsigned)VARE_UNDEFERR;
3876         v->flags |= VAR_IN_USE;
3877         (void)Var_Subst(nstr, ctxt, nested_eflags, &nstr);
3878         v->flags &= ~(unsigned)VAR_IN_USE;
3879         /* TODO: handle errors */
3880         *out_val_freeIt = nstr;
3881     }
3882
3883     if (haveModifier || extramodifiers != NULL) {
3884         void *extraFree;
3885
3886         extraFree = NULL;
3887         if (extramodifiers != NULL) {
3888             const char *em = extramodifiers;
3889             nstr = ApplyModifiers(&em, nstr, '(', ')',
3890                                   v, &exprFlags, ctxt, eflags, &extraFree);
3891         }
3892
3893         if (haveModifier) {
3894             /* Skip initial colon. */
3895             p++;
3896
3897             nstr = ApplyModifiers(&p, nstr, startc, endc,
3898                                   v, &exprFlags, ctxt, eflags, out_val_freeIt);
3899             free(extraFree);
3900         } else {
3901             *out_val_freeIt = extraFree;
3902         }
3903     }
3904
3905     if (*p != '\0')             /* Skip past endc if possible. */
3906         p++;
3907
3908     *pp = p;
3909
3910     if (v->flags & VAR_FROM_ENV) {
3911         /* Free the environment variable now since we own it,
3912          * but don't free the variable value if it will be returned. */
3913         Boolean keepValue = nstr == Buf_GetAll(&v->val, NULL);
3914         if (keepValue)
3915             *out_val_freeIt = nstr;
3916         (void)VarFreeEnv(v, !keepValue);
3917
3918     } else if (exprFlags & VEF_UNDEF) {
3919         if (!(exprFlags & VEF_DEF)) {
3920             if (*out_val_freeIt != NULL) {
3921                 free(*out_val_freeIt);
3922                 *out_val_freeIt = NULL;
3923             }
3924             if (dynamic) {
3925                 nstr = bmake_strsedup(start, p);
3926                 *out_val_freeIt = nstr;
3927             } else {
3928                 /* The expression is still undefined, therefore discard the
3929                  * actual value and return an error marker instead. */
3930                 nstr = (eflags & VARE_UNDEFERR) ? var_Error : varUndefined;
3931             }
3932         }
3933         if (nstr != Buf_GetAll(&v->val, NULL))
3934             Buf_Destroy(&v->val, TRUE);
3935         free(v->name_freeIt);
3936         free(v);
3937     }
3938     *out_val = nstr;
3939     return VPR_UNKNOWN;
3940 }
3941
3942 /* Substitute for all variables in the given string in the given context.
3943  *
3944  * If eflags & VARE_UNDEFERR, Parse_Error will be called when an undefined
3945  * variable is encountered.
3946  *
3947  * If eflags & VARE_WANTRES, any effects from the modifiers, such as ::=,
3948  * :sh or !cmd! take place.
3949  *
3950  * Input:
3951  *      str             the string which to substitute
3952  *      ctxt            the context wherein to find variables
3953  *      eflags          VARE_UNDEFERR   if undefineds are an error
3954  *                      VARE_WANTRES    if we actually want the result
3955  *                      VARE_ASSIGN     if we are in a := assignment
3956  *
3957  * Results:
3958  *      The resulting string.
3959  */
3960 VarParseResult
3961 Var_Subst(const char *str, GNode *ctxt, VarEvalFlags eflags, char **out_res)
3962 {
3963     const char *p = str;
3964     Buffer buf;                 /* Buffer for forming things */
3965
3966     /* Set true if an error has already been reported,
3967      * to prevent a plethora of messages when recursing */
3968     static Boolean errorReported;
3969
3970     Buf_Init(&buf, 0);
3971     errorReported = FALSE;
3972
3973     while (*p != '\0') {
3974         if (p[0] == '$' && p[1] == '$') {
3975             /* A dollar sign may be escaped with another dollar sign. */
3976             if (save_dollars && (eflags & VARE_ASSIGN))
3977                 Buf_AddByte(&buf, '$');
3978             Buf_AddByte(&buf, '$');
3979             p += 2;
3980         } else if (*p != '$') {
3981             /*
3982              * Skip as many characters as possible -- either to the end of
3983              * the string or to the next dollar sign (variable expression).
3984              */
3985             const char *plainStart = p;
3986
3987             for (p++; *p != '$' && *p != '\0'; p++)
3988                 continue;
3989             Buf_AddBytesBetween(&buf, plainStart, p);
3990         } else {
3991             const char *nested_p = p;
3992             void *freeIt;
3993             const char *val;
3994             (void)Var_Parse(&nested_p, ctxt, eflags, &val, &freeIt);
3995             /* TODO: handle errors */
3996
3997             if (val == var_Error || val == varUndefined) {
3998                 /*
3999                  * If performing old-time variable substitution, skip over
4000                  * the variable and continue with the substitution. Otherwise,
4001                  * store the dollar sign and advance str so we continue with
4002                  * the string...
4003                  */
4004                 if (oldVars) {
4005                     p = nested_p;
4006                 } else if ((eflags & VARE_UNDEFERR) || val == var_Error) {
4007                     /*
4008                      * If variable is undefined, complain and skip the
4009                      * variable. The complaint will stop us from doing anything
4010                      * when the file is parsed.
4011                      */
4012                     if (!errorReported) {
4013                         Parse_Error(PARSE_FATAL, "Undefined variable \"%.*s\"",
4014                                     (int)(size_t)(nested_p - p), p);
4015                     }
4016                     p = nested_p;
4017                     errorReported = TRUE;
4018                 } else {
4019                     /* Copy the initial '$' of the undefined expression,
4020                      * thereby deferring expansion of the expression, but
4021                      * expand nested expressions if already possible.
4022                      * See unit-tests/varparse-undef-partial.mk. */
4023                     Buf_AddByte(&buf, *p);
4024                     p++;
4025                 }
4026             } else {
4027                 p = nested_p;
4028                 Buf_AddStr(&buf, val);
4029             }
4030             free(freeIt);
4031             freeIt = NULL;
4032         }
4033     }
4034
4035     *out_res = Buf_DestroyCompact(&buf);
4036     return VPR_OK;
4037 }
4038
4039 /* Initialize the variables module. */
4040 void
4041 Var_Init(void)
4042 {
4043     VAR_INTERNAL = Targ_NewGN("Internal");
4044     VAR_GLOBAL = Targ_NewGN("Global");
4045     VAR_CMDLINE = Targ_NewGN("Command");
4046 }
4047
4048 /* Clean up the variables module. */
4049 void
4050 Var_End(void)
4051 {
4052     Var_Stats();
4053 }
4054
4055 void
4056 Var_Stats(void)
4057 {
4058     HashTable_DebugStats(&VAR_GLOBAL->context, "VAR_GLOBAL");
4059 }
4060
4061 /* Print all variables in a context, sorted by name. */
4062 void
4063 Var_Dump(GNode *ctxt)
4064 {
4065     Vector /* of const char * */ vec;
4066     HashIter hi;
4067     size_t i;
4068     const char **varnames;
4069
4070     Vector_Init(&vec, sizeof(const char *));
4071
4072     HashIter_Init(&hi, &ctxt->context);
4073     while (HashIter_Next(&hi) != NULL)
4074         *(const char **)Vector_Push(&vec) = hi.entry->key;
4075     varnames = vec.items;
4076
4077     qsort(varnames, vec.len, sizeof varnames[0], str_cmp_asc);
4078
4079     for (i = 0; i < vec.len; i++) {
4080         const char *varname = varnames[i];
4081         Var *var = HashTable_FindValue(&ctxt->context, varname);
4082         debug_printf("%-16s = %s\n", varname, Buf_GetAll(&var->val, NULL));
4083     }
4084
4085     Vector_Done(&vec);
4086 }