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