- Constify Var_Delete()
[dragonfly.git] / usr.bin / make / var.c
1 /*-
2  * Copyright (c) 1988, 1989, 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1989 by Berkeley Softworks
5  * 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. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * @(#)var.c    8.3 (Berkeley) 3/19/94
39  * $FreeBSD: src/usr.bin/make/var.c,v 1.16.2.3 2002/02/27 14:18:57 cjc Exp $
40  * $DragonFly: src/usr.bin/make/var.c,v 1.58 2005/02/04 22:06:01 okumoto Exp $
41  */
42
43 /*-
44  * var.c --
45  *      Variable-handling functions
46  *
47  * Interface:
48  *      Var_Set             Set the value of a variable in the given
49  *                          context. The variable is created if it doesn't
50  *                          yet exist. The value and variable name need not
51  *                          be preserved.
52  *
53  *      Var_Append          Append more characters to an existing variable
54  *                          in the given context. The variable needn't
55  *                          exist already -- it will be created if it doesn't.
56  *                          A space is placed between the old value and the
57  *                          new one.
58  *
59  *      Var_Exists          See if a variable exists.
60  *
61  *      Var_Value           Return the value of a variable in a context or
62  *                          NULL if the variable is undefined.
63  *
64  *      Var_Subst           Substitute named variable, or all variables if
65  *                          NULL in a string using
66  *                          the given context as the top-most one. If the
67  *                          third argument is non-zero, Parse_Error is
68  *                          called if any variables are undefined.
69  *
70  *      Var_Parse           Parse a variable expansion from a string and
71  *                          return the result and the number of characters
72  *                          consumed.
73  *
74  *      Var_Delete          Delete a variable in a context.
75  *
76  *      Var_Init            Initialize this module.
77  *
78  * Debugging:
79  *      Var_Dump            Print out all variables defined in the given
80  *                          context.
81  *
82  * XXX: There's a lot of duplication in these functions.
83  */
84
85 #include <ctype.h>
86 #include <stdlib.h>
87 #include <string.h>
88
89 #include "buf.h"
90 #include "config.h"
91 #include "globals.h"
92 #include "GNode.h"
93 #include "make.h"
94 #include "nonints.h"
95 #include "parse.h"
96 #include "str.h"
97 #include "targ.h"
98 #include "util.h"
99 #include "var.h"
100
101 /*
102  * This is a harmless return value for Var_Parse that can be used by Var_Subst
103  * to determine if there was an error in parsing -- easier than returning
104  * a flag, as things outside this module don't give a hoot.
105  */
106 char    var_Error[] = "";
107
108 /*
109  * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
110  * set false. Why not just use a constant? Well, gcc likes to condense
111  * identical string instances...
112  */
113 static char     varNoError[] = "";
114
115 /*
116  * Internally, variables are contained in four different contexts.
117  *      1) the environment. They may not be changed. If an environment
118  *          variable is appended-to, the result is placed in the global
119  *          context.
120  *      2) the global context. Variables set in the Makefile are located in
121  *          the global context. It is the penultimate context searched when
122  *          substituting.
123  *      3) the command-line context. All variables set on the command line
124  *         are placed in this context. They are UNALTERABLE once placed here.
125  *      4) the local context. Each target has associated with it a context
126  *         list. On this list are located the structures describing such
127  *         local variables as $(@) and $(*)
128  * The four contexts are searched in the reverse order from which they are
129  * listed.
130  */
131 GNode          *VAR_GLOBAL;   /* variables from the makefile */
132 GNode          *VAR_CMD;      /* variables defined on the command-line */
133
134 #define FIND_CMD        0x1   /* look in VAR_CMD when searching */
135 #define FIND_GLOBAL     0x2   /* look in VAR_GLOBAL as well */
136 #define FIND_ENV        0x4   /* look in the environment also */
137
138 #define OPEN_PAREN              '('
139 #define CLOSE_PAREN             ')'
140 #define OPEN_BRACKET            '{'
141 #define CLOSE_BRACKET           '}'
142
143 static Var *VarCreate(const char [], const char [], int);
144 static void VarDestroy(Var *, Boolean);
145 static char *VarGetPattern(GNode *, int, char **, int, int *, size_t *,
146                            VarPattern *);
147 static char *VarModify(char *,
148                        Boolean (*)(const char *, Boolean, Buffer *, void *),
149                        void *);
150 static int VarPrintVar(void *, void *);
151
152 /*-
153  *-----------------------------------------------------------------------
154  * VarCmp  --
155  *      See if the given variable matches the named one. Called from
156  *      Lst_Find when searching for a variable of a given name.
157  *
158  * Results:
159  *      0 if they match. non-zero otherwise.
160  *
161  * Side Effects:
162  *      none
163  *-----------------------------------------------------------------------
164  */
165 static int
166 VarCmp(const void *v, const void *name)
167 {
168
169     return (strcmp(name, ((const Var *)v)->name));
170 }
171
172 /*-
173  *-----------------------------------------------------------------------
174  * VarPossiblyExpand --
175  *      Expand a variable name's embedded variables in the given context.
176  *
177  * Results:
178  *      The contents of name, possibly expanded.
179  *-----------------------------------------------------------------------
180  */
181 static char *
182 VarPossiblyExpand(const char *name, GNode *ctxt)
183 {
184     if (strchr(name, '$') != NULL) {
185         Buffer  *buf;
186         char    *str;
187
188         buf = Var_Subst(NULL, name, ctxt, 0);
189         str = Buf_GetAll(buf, NULL);
190         Buf_Destroy(buf, FALSE);
191
192         return(str);
193     } else {
194         return(estrdup(name));
195     }
196 }
197
198 /*-
199  *-----------------------------------------------------------------------
200  * VarFind --
201  *      Find the given variable in the given context and any other contexts
202  *      indicated.
203  *
204  *      Flags:
205  *              FIND_GLOBAL     set means look in the VAR_GLOBAL context too
206  *              FIND_CMD        set means to look in the VAR_CMD context too
207  *              FIND_ENV        set means to look in the environment
208  *
209  * Results:
210  *      A pointer to the structure describing the desired variable or
211  *      NULL if the variable does not exist.
212  *
213  * Side Effects:
214  *      None
215  *-----------------------------------------------------------------------
216  */
217 static Var *
218 VarFind(const char *name, GNode *ctxt, int flags)
219 {
220     Boolean             localCheckEnvFirst;
221     LstNode             *var;
222     Var                 *v;
223
224     /*
225      * If the variable name begins with a '.', it could very well be one of
226      * the local ones.  We check the name against all the local variables
227      * and substitute the short version in for 'name' if it matches one of
228      * them.
229      */
230     if (name[0] == '.' && isupper((unsigned char)name[1]))
231         switch (name[1]) {
232         case 'A':
233                 if (!strcmp(name, ".ALLSRC"))
234                         name = ALLSRC;
235                 if (!strcmp(name, ".ARCHIVE"))
236                         name = ARCHIVE;
237                 break;
238         case 'I':
239                 if (!strcmp(name, ".IMPSRC"))
240                         name = IMPSRC;
241                 break;
242         case 'M':
243                 if (!strcmp(name, ".MEMBER"))
244                         name = MEMBER;
245                 break;
246         case 'O':
247                 if (!strcmp(name, ".OODATE"))
248                         name = OODATE;
249                 break;
250         case 'P':
251                 if (!strcmp(name, ".PREFIX"))
252                         name = PREFIX;
253                 break;
254         case 'T':
255                 if (!strcmp(name, ".TARGET"))
256                         name = TARGET;
257                 break;
258         }
259
260     /*
261      * Note whether this is one of the specific variables we were told through
262      * the -E flag to use environment-variable-override for.
263      */
264     if (Lst_Find(&envFirstVars, name, (CompareProc *)strcmp) != NULL) {
265         localCheckEnvFirst = TRUE;
266     } else {
267         localCheckEnvFirst = FALSE;
268     }
269
270     /*
271      * First look for the variable in the given context. If it's not there,
272      * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
273      * depending on the FIND_* flags in 'flags'
274      */
275     var = Lst_Find(&ctxt->context, name, VarCmp);
276
277     if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
278         var = Lst_Find(&VAR_CMD->context, name, VarCmp);
279     }
280     if ((var == NULL) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
281         !checkEnvFirst && !localCheckEnvFirst)
282     {
283         var = Lst_Find(&VAR_GLOBAL->context, name, VarCmp);
284     }
285     if ((var == NULL) && (flags & FIND_ENV)) {
286         char *env;
287
288         if ((env = getenv(name)) != NULL) {
289             v = VarCreate(name, env, VAR_FROM_ENV);
290
291             return (v);
292         } else if ((checkEnvFirst || localCheckEnvFirst) &&
293                    (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
294         {
295             var = Lst_Find(&VAR_GLOBAL->context, name, VarCmp);
296             if (var == NULL) {
297                 return (NULL);
298             } else {
299                 return (Lst_Datum(var));
300             }
301         } else {
302             return (NULL);
303         }
304     } else if (var == NULL) {
305         return (NULL);
306     } else {
307         return (Lst_Datum(var));
308     }
309 }
310
311 /*-
312  *-----------------------------------------------------------------------
313  * VarAdd  --
314  *      Add a new variable of name name and value val to the given context.
315  *
316  * Results:
317  *      None
318  *
319  * Side Effects:
320  *      The new variable is placed at the front of the given context
321  *      The name and val arguments are duplicated so they may
322  *      safely be freed.
323  *-----------------------------------------------------------------------
324  */
325 static void
326 VarAdd(const char *name, const char *val, GNode *ctxt)
327 {
328     Lst_AtFront(&ctxt->context, VarCreate(name, val, 0));
329
330     DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
331 }
332
333 /*
334  * Create a Var object.
335  *
336  * @param name          Name of variable.
337  * @param value         Value of variable.
338  * @param flags         Flags set on variable.
339  */
340 static Var *
341 VarCreate(const char name[], const char value[], int flags)
342 {
343     Var *v;
344
345     v = emalloc(sizeof(Var));
346     v->name     = estrdup(name);
347     v->val      = Buf_Init(0);
348     v->flags    = flags;
349
350     if (value != NULL) {
351         Buf_Append(v->val, value);
352     }
353     return (v);
354 }
355
356 /*
357  * Destroy a Var object.
358  *
359  * @param v     Object to destroy.
360  * @param f     true if internal buffer in Buffer object is to be
361  *              removed.
362  */
363 static void
364 VarDestroy(Var *v, Boolean f)
365 {
366     Buf_Destroy(v->val, f);
367     free(v->name);
368     free(v);
369 }
370
371 /*-
372  *-----------------------------------------------------------------------
373  * Var_Delete --
374  *      Remove a variable from a context.
375  *
376  * Results:
377  *      None.
378  *
379  * Side Effects:
380  *      The Var structure is removed and freed.
381  *
382  *-----------------------------------------------------------------------
383  */
384 void
385 Var_Delete(const char *name, GNode *ctxt)
386 {
387     LstNode *ln;
388
389     DEBUGF(VAR, ("%s:delete %s\n", ctxt->name, name));
390     ln = Lst_Find(&ctxt->context, name, VarCmp);
391     if (ln != NULL) {
392         VarDestroy(Lst_Datum(ln), TRUE);
393         Lst_Remove(&ctxt->context, ln);
394     }
395 }
396
397 /*-
398  *-----------------------------------------------------------------------
399  * Var_Set --
400  *      Set the variable name to the value val in the given context.
401  *
402  * Results:
403  *      None.
404  *
405  * Side Effects:
406  *      If the variable doesn't yet exist, a new record is created for it.
407  *      Else the old value is freed and the new one stuck in its place
408  *
409  * Notes:
410  *      The variable is searched for only in its context before being
411  *      created in that context. I.e. if the context is VAR_GLOBAL,
412  *      only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
413  *      VAR_CMD->context is searched. This is done to avoid the literally
414  *      thousands of unnecessary strcmp's that used to be done to
415  *      set, say, $(@) or $(<).
416  *-----------------------------------------------------------------------
417  */
418 void
419 Var_Set(const char *name, const char *val, GNode *ctxt)
420 {
421     Var         *v;
422     char        *n;
423
424     /*
425      * We only look for a variable in the given context since anything set
426      * here will override anything in a lower context, so there's not much
427      * point in searching them all just to save a bit of memory...
428      */
429     n = VarPossiblyExpand(name, ctxt);
430     v = VarFind(n, ctxt, 0);
431     if (v == NULL) {
432         VarAdd(n, val, ctxt);
433     } else {
434         Buf_Clear(v->val);
435         Buf_Append(v->val, val);
436
437         DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, val));
438     }
439     /*
440      * Any variables given on the command line are automatically exported
441      * to the environment (as per POSIX standard)
442      */
443     if (ctxt == VAR_CMD || (v != (Var *)NULL && (v->flags & VAR_TO_ENV))) {
444         setenv(n, val, 1);
445     }
446     free(n);
447 }
448
449 /*
450  * Var_SetEnv --
451  *      Set the VAR_TO_ENV flag on a variable
452  */
453 void
454 Var_SetEnv(const char *name, GNode *ctxt)
455 {
456     Var *v;
457
458     v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
459     if (v) {
460         if ((v->flags & VAR_TO_ENV) == 0) {
461             v->flags |= VAR_TO_ENV;
462             setenv(v->name, Buf_GetAll(v->val, NULL), 1);
463         }
464     } else {
465         Error("Cannot set environment flag on non-existant variable %s", name);
466     }
467 }
468
469 /*-
470  *-----------------------------------------------------------------------
471  * Var_Append --
472  *      The variable of the given name has the given value appended to it in
473  *      the given context.
474  *
475  * Results:
476  *      None
477  *
478  * Side Effects:
479  *      If the variable doesn't exist, it is created. Else the strings
480  *      are concatenated (with a space in between).
481  *
482  * Notes:
483  *      Only if the variable is being sought in the global context is the
484  *      environment searched.
485  *      XXX: Knows its calling circumstances in that if called with ctxt
486  *      an actual target, it will only search that context since only
487  *      a local variable could be being appended to. This is actually
488  *      a big win and must be tolerated.
489  *-----------------------------------------------------------------------
490  */
491 void
492 Var_Append(const char *name, const char *val, GNode *ctxt)
493 {
494     Var         *v;
495     char        *n;
496
497     n = VarPossiblyExpand(name, ctxt);
498     v = VarFind(n, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
499
500     if (v == NULL) {
501         VarAdd(n, val, ctxt);
502     } else {
503         Buf_AddByte(v->val, (Byte)' ');
504         Buf_Append(v->val, val);
505
506         DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n,
507                (char *)Buf_GetAll(v->val, (size_t *)NULL)));
508
509         if (v->flags & VAR_FROM_ENV) {
510             /*
511              * If the original variable came from the environment, we
512              * have to install it in the global context (we could place
513              * it in the environment, but then we should provide a way to
514              * export other variables...)
515              */
516             v->flags &= ~VAR_FROM_ENV;
517             Lst_AtFront(&ctxt->context, v);
518         }
519     }
520     free(n);
521 }
522
523 /*-
524  *-----------------------------------------------------------------------
525  * Var_Exists --
526  *      See if the given variable exists.
527  *
528  * Results:
529  *      TRUE if it does, FALSE if it doesn't
530  *
531  * Side Effects:
532  *      None.
533  *
534  *-----------------------------------------------------------------------
535  */
536 Boolean
537 Var_Exists(const char *name, GNode *ctxt)
538 {
539     Var         *v;
540     char        *n;
541
542     n = VarPossiblyExpand(name, ctxt);
543     v = VarFind(n, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
544     free(n);
545
546     if (v == NULL) {
547         return (FALSE);
548     } else if (v->flags & VAR_FROM_ENV) {
549         VarDestroy(v, TRUE);
550     }
551     return (TRUE);
552 }
553
554 /*-
555  *-----------------------------------------------------------------------
556  * Var_Value --
557  *      Return the value of the named variable in the given context
558  *
559  * Results:
560  *      The value if the variable exists, NULL if it doesn't
561  *
562  * Side Effects:
563  *      None
564  *-----------------------------------------------------------------------
565  */
566 char *
567 Var_Value(const char *name, GNode *ctxt, char **frp)
568 {
569     Var         *v;
570     char        *n;
571
572     n = VarPossiblyExpand(name, ctxt);
573     v = VarFind(n, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
574     free(n);
575     *frp = NULL;
576     if (v != NULL) {
577         char *p = (char *)Buf_GetAll(v->val, (size_t *)NULL);
578
579         if (v->flags & VAR_FROM_ENV) {
580             VarDestroy(v, FALSE);
581             *frp = p;
582         }
583         return (p);
584     } else {
585         return (NULL);
586     }
587 }
588
589 /*-
590  *-----------------------------------------------------------------------
591  * VarModify --
592  *      Modify each of the words of the passed string using the given
593  *      function. Used to implement all modifiers.
594  *
595  * Results:
596  *      A string of all the words modified appropriately.
597  *
598  * Side Effects:
599  *      None.
600  *
601  *-----------------------------------------------------------------------
602  */
603 static char *
604 VarModify(char *str, Boolean (*modProc)(const char *, Boolean, Buffer *, void *),
605     void *datum)
606 {
607     Buffer        *buf;             /* Buffer for the new string */
608     Boolean       addSpace;         /* TRUE if need to add a space to the
609                                      * buffer before adding the trimmed
610                                      * word */
611     char **av;                      /* word list [first word does not count] */
612     int ac, i;
613
614     buf = Buf_Init(0);
615     addSpace = FALSE;
616
617     av = brk_string(str, &ac, FALSE);
618
619     for (i = 1; i < ac; i++)
620         addSpace = (*modProc)(av[i], addSpace, buf, datum);
621
622     Buf_AddByte(buf, '\0');
623     str = (char *)Buf_GetAll(buf, (size_t *)NULL);
624     Buf_Destroy(buf, FALSE);
625     return (str);
626 }
627
628 /*-
629  *-----------------------------------------------------------------------
630  * VarSortWords --
631  *      Sort the words in the string.
632  *
633  * Input:
634  *      str             String whose words should be sorted
635  *      cmp             A comparison function to control the ordering
636  *
637  * Results:
638  *      A string containing the words sorted
639  *
640  * Side Effects:
641  *      None.
642  *
643  *-----------------------------------------------------------------------
644  */
645 static char *
646 VarSortWords(char *str, int (*cmp)(const void *, const void *))
647 {
648         Buffer *buf;
649         char **av;
650         int ac, i;
651
652         buf = Buf_Init(0);
653         av = brk_string(str, &ac, FALSE);
654         qsort(av + 1, ac - 1, sizeof(char *), cmp);
655         for (i = 1; i < ac; i++) {
656                 Buf_Append(buf, av[i]);
657                 Buf_AddByte(buf, (Byte)((i < ac - 1) ? ' ' : '\0'));
658         }
659         str = (char *)Buf_GetAll(buf, (size_t *)NULL);
660         Buf_Destroy(buf, FALSE);
661         return (str);
662 }
663
664 static int
665 SortIncreasing(const void *l, const void *r)
666 {
667
668         return (strcmp(*(const char* const*)l, *(const char* const*)r));
669 }
670
671 /*-
672  *-----------------------------------------------------------------------
673  * VarGetPattern --
674  *      Pass through the tstr looking for 1) escaped delimiters,
675  *      '$'s and backslashes (place the escaped character in
676  *      uninterpreted) and 2) unescaped $'s that aren't before
677  *      the delimiter (expand the variable substitution unless flags
678  *      has VAR_NOSUBST set).
679  *      Return the expanded string or NULL if the delimiter was missing
680  *      If pattern is specified, handle escaped ampersands, and replace
681  *      unescaped ampersands with the lhs of the pattern.
682  *
683  * Results:
684  *      A string of all the words modified appropriately.
685  *      If length is specified, return the string length of the buffer
686  *      If flags is specified and the last character of the pattern is a
687  *      $ set the VAR_MATCH_END bit of flags.
688  *
689  * Side Effects:
690  *      None.
691  *-----------------------------------------------------------------------
692  */
693 static char *
694 VarGetPattern(GNode *ctxt, int err, char **tstr, int delim, int *flags,
695     size_t *length, VarPattern *pattern)
696 {
697     char *cp;
698     Buffer *buf = Buf_Init(0);
699     size_t junk;
700
701     if (length == NULL)
702         length = &junk;
703
704 #define IS_A_MATCH(cp, delim) \
705     ((cp[0] == '\\') && ((cp[1] == delim) ||  \
706      (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
707
708     /*
709      * Skim through until the matching delimiter is found;
710      * pick up variable substitutions on the way. Also allow
711      * backslashes to quote the delimiter, $, and \, but don't
712      * touch other backslashes.
713      */
714     for (cp = *tstr; *cp && (*cp != delim); cp++) {
715         if (IS_A_MATCH(cp, delim)) {
716             Buf_AddByte(buf, (Byte)cp[1]);
717             cp++;
718         } else if (*cp == '$') {
719             if (cp[1] == delim) {
720                 if (flags == NULL)
721                     Buf_AddByte(buf, (Byte)*cp);
722                 else
723                     /*
724                      * Unescaped $ at end of pattern => anchor
725                      * pattern at end.
726                      */
727                     *flags |= VAR_MATCH_END;
728             } else {
729                 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
730                     char   *cp2;
731                     size_t len;
732                     Boolean freeIt;
733
734                     /*
735                      * If unescaped dollar sign not before the
736                      * delimiter, assume it's a variable
737                      * substitution and recurse.
738                      */
739                     cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
740                     Buf_Append(buf, cp2);
741                     if (freeIt)
742                         free(cp2);
743                     cp += len - 1;
744                 } else {
745                     char *cp2 = &cp[1];
746
747                     if (*cp2 == OPEN_PAREN || *cp2 == OPEN_BRACKET) {
748                         /*
749                          * Find the end of this variable reference
750                          * and suck it in without further ado.
751                          * It will be interperated later.
752                          */
753                         int have = *cp2;
754                         int want = (*cp2 == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACKET;
755                         int depth = 1;
756
757                         for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
758                             if (cp2[-1] != '\\') {
759                                 if (*cp2 == have)
760                                     ++depth;
761                                 if (*cp2 == want)
762                                     --depth;
763                             }
764                         }
765                         Buf_AppendRange(buf, cp, cp2);
766                         cp = --cp2;
767                     } else
768                         Buf_AddByte(buf, (Byte)*cp);
769                 }
770             }
771         }
772         else if (pattern && *cp == '&')
773             Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
774         else
775             Buf_AddByte(buf, (Byte)*cp);
776     }
777
778     Buf_AddByte(buf, (Byte)'\0');
779
780     if (*cp != delim) {
781         *tstr = cp;
782         *length = 0;
783         return (NULL);
784     } else {
785         *tstr = ++cp;
786         cp = (char *)Buf_GetAll(buf, length);
787         *length -= 1;   /* Don't count the NULL */
788         Buf_Destroy(buf, FALSE);
789         return (cp);
790     }
791 }
792
793 /*-
794  *-----------------------------------------------------------------------
795  * Var_Quote --
796  *      Quote shell meta-characters in the string
797  *
798  * Results:
799  *      The quoted string
800  *
801  * Side Effects:
802  *      None.
803  *
804  *-----------------------------------------------------------------------
805  */
806 char *
807 Var_Quote(const char *str)
808 {
809     Buffer       *buf;
810     /* This should cover most shells :-( */
811     static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
812     char          *ret;
813
814     buf = Buf_Init(MAKE_BSIZE);
815     for (; *str; str++) {
816         if (strchr(meta, *str) != NULL)
817             Buf_AddByte(buf, (Byte)'\\');
818         Buf_AddByte(buf, (Byte)*str);
819     }
820     Buf_AddByte(buf, (Byte)'\0');
821     ret = Buf_GetAll(buf, NULL);
822     Buf_Destroy(buf, FALSE);
823     return (ret);
824 }
825
826 /*-
827  *-----------------------------------------------------------------------
828  * VarREError --
829  *      Print the error caused by a regcomp or regexec call.
830  *
831  * Results:
832  *      None.
833  *
834  * Side Effects:
835  *      An error gets printed.
836  *
837  *-----------------------------------------------------------------------
838  */
839 void
840 VarREError(int err, regex_t *pat, const char *str)
841 {
842     char *errbuf;
843     int errlen;
844
845     errlen = regerror(err, pat, 0, 0);
846     errbuf = emalloc(errlen);
847     regerror(err, pat, errbuf, errlen);
848     Error("%s: %s", str, errbuf);
849     free(errbuf);
850 }
851
852 /*-
853  *-----------------------------------------------------------------------
854  * Var_Parse --
855  *      Given the start of a variable invocation, extract the variable
856  *      name and find its value, then modify it according to the
857  *      specification.
858  *
859  * Results:
860  *      The (possibly-modified) value of the variable or var_Error if the
861  *      specification is invalid. The length of the specification is
862  *      placed in *lengthPtr (for invalid specifications, this is just
863  *      2 to skip the '$' and the following letter, or 1 if '$' was the
864  *      last character in the string).
865  *      A Boolean in *freePtr telling whether the returned string should
866  *      be freed by the caller.
867  *
868  * Side Effects:
869  *      None.
870  *
871  *-----------------------------------------------------------------------
872  */
873 char *
874 Var_Parse(char *str, GNode *ctxt, Boolean err, size_t *lengthPtr,
875     Boolean *freePtr)
876 {
877     char            *tstr;      /* Pointer into str */
878     Var             *v;         /* Variable in invocation */
879     char            *cp;        /* Secondary pointer into str (place marker
880                                  * for tstr) */
881     Boolean         haveModifier;/* TRUE if have modifiers for the variable */
882     char            endc;       /* Ending character when variable in parens
883                                  * or braces */
884     char            startc=0;   /* Starting character when variable in parens
885                                  * or braces */
886     int             cnt;        /* Used to count brace pairs when variable in
887                                  * in parens or braces */
888     char            *start;
889     char             delim;
890     Boolean         dynamic;    /* TRUE if the variable is local and we're
891                                  * expanding it in a non-local context. This
892                                  * is done to support dynamic sources. The
893                                  * result is just the invocation, unaltered */
894     int         vlen;           /* length of variable name, after embedded variable
895                                  * expansion */
896
897     *freePtr = FALSE;
898     dynamic = FALSE;
899     start = str;
900
901     /*
902      * It is assumed that Var_Parse() is called with str[0] == '$'
903      */
904
905     if (str[1] != OPEN_PAREN && str[1] != OPEN_BRACKET) {
906         /*
907          * If it's not bounded by braces of some sort, life is much simpler.
908          * We just need to check for the first character and return the
909          * value if it exists.
910          */
911         char      name[2];
912
913         name[0] = str[1];
914         name[1] = '\0';
915
916         v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
917         if (v == (Var *)NULL) {
918             if (str[1] != '\0')
919                 *lengthPtr = 2;
920             else
921                 *lengthPtr = 1;
922
923             if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
924                 /*
925                  * If substituting a local variable in a non-local context,
926                  * assume it's for dynamic source stuff. We have to handle
927                  * this specially and return the longhand for the variable
928                  * with the dollar sign escaped so it makes it back to the
929                  * caller. Only four of the local variables are treated
930                  * specially as they are the only four that will be set
931                  * when dynamic sources are expanded.
932                  */
933                 /* XXX: It looks like $% and $! are reversed here */
934                 switch (str[1]) {
935                     case '@':
936                         return ("$(.TARGET)");
937                     case '%':
938                         return ("$(.ARCHIVE)");
939                     case '*':
940                         return ("$(.PREFIX)");
941                     case '!':
942                         return ("$(.MEMBER)");
943                     default:
944                         break;
945                 }
946             }
947             /*
948              * Error
949              */
950             return (err ? var_Error : varNoError);
951         } else {
952             haveModifier = FALSE;
953             tstr = &str[1];
954             endc = str[1];
955         }
956     } else {
957         /* build up expanded variable name in this buffer */
958         Buffer  *buf = Buf_Init(MAKE_BSIZE);
959
960         /*
961          * Skip to the end character or a colon, whichever comes first,
962          * replacing embedded variables as we go.
963          */
964         startc = str[1];
965         endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACKET;
966
967         tstr = str + 2;;
968         while (*tstr != '\0' && *tstr != endc && *tstr != ':') {
969             if (*tstr == '$') {
970                 size_t  rlen;
971                 Boolean rfree;
972                 char    *rval;
973
974                 rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
975                 if (rval == var_Error) {
976                         Fatal("Error expanding embedded variable.");
977                 } else if (rval != NULL) {
978                         Buf_Append(buf, rval);
979                         if (rfree)
980                                 free(rval);
981                 }
982                 tstr += rlen - 1;
983             } else {
984                 Buf_AddByte(buf, (Byte)*tstr);
985             }
986             tstr++;
987         }
988
989         if (*tstr == '\0') {
990             /*
991              * If we never did find the end character, return NULL
992              * right now, setting the length to be the distance to
993              * the end of the string, since that's what make does.
994              */
995             *lengthPtr = tstr - str;
996             return (var_Error);
997         }
998
999         haveModifier = (*tstr == ':');
1000         *tstr = '\0';                   /* modify input string */
1001
1002         Buf_AddByte(buf, (Byte)'\0');
1003         str = Buf_GetAll(buf, (size_t *)NULL);
1004         vlen = strlen(str);
1005
1006         v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1007         if ((v == (Var *)NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
1008             (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
1009         {
1010             /*
1011              * Check for bogus D and F forms of local variables since we're
1012              * in a local context and the name is the right length.
1013              */
1014             switch (str[0]) {
1015                 case '@':
1016                 case '%':
1017                 case '*':
1018                 case '!':
1019                 case '>':
1020                 case '<':
1021                 {
1022                     char    vname[2];
1023                     char    *val;
1024
1025                     /*
1026                      * Well, it's local -- go look for it.
1027                      */
1028                     vname[0] = str[0];
1029                     vname[1] = '\0';
1030                     v = VarFind(vname, ctxt, 0);
1031
1032                     if (v != NULL && !haveModifier) {
1033                         /*
1034                          * No need for nested expansion or anything, as we're
1035                          * the only one who sets these things and we sure don't
1036                          * put nested invocations in them...
1037                          */
1038                         val = (char *)Buf_GetAll(v->val, (size_t *)NULL);
1039
1040                         if (str[1] == 'D') {
1041                             val = VarModify(val, VarHead, (void *)NULL);
1042                         } else {
1043                             val = VarModify(val, VarTail, (void *)NULL);
1044                         }
1045                         /*
1046                          * Resulting string is dynamically allocated, so
1047                          * tell caller to free it.
1048                          */
1049                         *freePtr = TRUE;
1050                         *lengthPtr = tstr-start+1;
1051                         *tstr = endc;
1052                         Buf_Destroy(buf, TRUE);
1053                         return (val);
1054                     }
1055                     break;
1056                 default:
1057                     break;
1058                 }
1059             }
1060         }
1061
1062         if (v == (Var *)NULL) {
1063             if (((vlen == 1) ||
1064                  (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
1065                 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1066             {
1067                 /*
1068                  * If substituting a local variable in a non-local context,
1069                  * assume it's for dynamic source stuff. We have to handle
1070                  * this specially and return the longhand for the variable
1071                  * with the dollar sign escaped so it makes it back to the
1072                  * caller. Only four of the local variables are treated
1073                  * specially as they are the only four that will be set
1074                  * when dynamic sources are expanded.
1075                  */
1076                 switch (str[0]) {
1077                     case '@':
1078                     case '%':
1079                     case '*':
1080                     case '!':
1081                         dynamic = TRUE;
1082                         break;
1083                     default:
1084                         break;
1085                 }
1086             } else if ((vlen > 2) && (str[0] == '.') &&
1087                        isupper((unsigned char)str[1]) &&
1088                        ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1089             {
1090                 int     len;
1091
1092                 len = vlen - 1;
1093                 if ((strncmp(str, ".TARGET", len) == 0) ||
1094                     (strncmp(str, ".ARCHIVE", len) == 0) ||
1095                     (strncmp(str, ".PREFIX", len) == 0) ||
1096                     (strncmp(str, ".MEMBER", len) == 0))
1097                 {
1098                     dynamic = TRUE;
1099                 }
1100             }
1101
1102             if (!haveModifier) {
1103                 /*
1104                  * No modifiers -- have specification length so we can return
1105                  * now.
1106                  */
1107                 *lengthPtr = tstr - start + 1;
1108                 *tstr = endc;
1109                 if (dynamic) {
1110                     str = emalloc(*lengthPtr + 1);
1111                     strncpy(str, start, *lengthPtr);
1112                     str[*lengthPtr] = '\0';
1113                     *freePtr = TRUE;
1114                     Buf_Destroy(buf, TRUE);
1115                     return (str);
1116                 } else {
1117                     Buf_Destroy(buf, TRUE);
1118                     return (err ? var_Error : varNoError);
1119                 }
1120             } else {
1121                 /*
1122                  * Still need to get to the end of the variable specification,
1123                  * so kludge up a Var structure for the modifications
1124                  */
1125                 v = VarCreate(str, NULL, VAR_JUNK);
1126             }
1127         }
1128         Buf_Destroy(buf, TRUE);
1129     }
1130
1131     if (v->flags & VAR_IN_USE) {
1132         Fatal("Variable %s is recursive.", v->name);
1133         /*NOTREACHED*/
1134     } else {
1135         v->flags |= VAR_IN_USE;
1136     }
1137
1138     /*
1139      * Before doing any modification, we have to make sure the value
1140      * has been fully expanded. If it looks like recursion might be
1141      * necessary (there's a dollar sign somewhere in the variable's value)
1142      * we just call Var_Subst to do any other substitutions that are
1143      * necessary. Note that the value returned by Var_Subst will have
1144      * been dynamically-allocated, so it will need freeing when we
1145      * return.
1146      */
1147     str = (char *)Buf_GetAll(v->val, (size_t *)NULL);
1148     if (strchr(str, '$') != NULL) {
1149         Buffer  *buf;
1150
1151         buf = Var_Subst(NULL, str, ctxt, err);
1152         str = Buf_GetAll(buf, NULL);
1153         Buf_Destroy(buf, FALSE);
1154
1155         *freePtr = TRUE;
1156     }
1157
1158     v->flags &= ~VAR_IN_USE;
1159
1160     /*
1161      * Now we need to apply any modifiers the user wants applied.
1162      * These are:
1163      *            :M<pattern>   words which match the given <pattern>.
1164      *                          <pattern> is of the standard file
1165      *                          wildcarding form.
1166      *            :S<d><pat1><d><pat2><d>[g]
1167      *                          Substitute <pat2> for <pat1> in the value
1168      *            :C<d><pat1><d><pat2><d>[g]
1169      *                          Substitute <pat2> for regex <pat1> in the value
1170      *            :H            Substitute the head of each word
1171      *            :T            Substitute the tail of each word
1172      *            :E            Substitute the extension (minus '.') of
1173      *                          each word
1174      *            :R            Substitute the root of each word
1175      *                          (pathname minus the suffix).
1176      *            :lhs=rhs      Like :S, but the rhs goes to the end of
1177      *                          the invocation.
1178      *            :U            Converts variable to upper-case.
1179      *            :L            Converts variable to lower-case.
1180      */
1181     if ((str != NULL) && haveModifier) {
1182         /*
1183          * Skip initial colon while putting it back.
1184          */
1185         *tstr++ = ':';
1186         while (*tstr != endc) {
1187             char        *newStr;    /* New value to return */
1188             char        termc;      /* Character which terminated scan */
1189
1190             DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, str));
1191             switch (*tstr) {
1192                 case 'N':
1193                 case 'M':
1194                 {
1195                     char    *pattern;
1196                     char    *cp2;
1197                     Boolean copy;
1198
1199                     copy = FALSE;
1200                     for (cp = tstr + 1;
1201                          *cp != '\0' && *cp != ':' && *cp != endc;
1202                          cp++)
1203                     {
1204                         if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)) {
1205                             copy = TRUE;
1206                             cp++;
1207                         }
1208                     }
1209                     termc = *cp;
1210                     *cp = '\0';
1211                     if (copy) {
1212                         /*
1213                          * Need to compress the \:'s out of the pattern, so
1214                          * allocate enough room to hold the uncompressed
1215                          * pattern (note that cp started at tstr+1, so
1216                          * cp - tstr takes the null byte into account) and
1217                          * compress the pattern into the space.
1218                          */
1219                         pattern = emalloc(cp - tstr);
1220                         for (cp2 = pattern, cp = tstr + 1;
1221                              *cp != '\0';
1222                              cp++, cp2++)
1223                         {
1224                             if ((*cp == '\\') &&
1225                                 (cp[1] == ':' || cp[1] == endc)) {
1226                                     cp++;
1227                             }
1228                             *cp2 = *cp;
1229                         }
1230                         *cp2 = '\0';
1231                     } else {
1232                         pattern = &tstr[1];
1233                     }
1234                     if (*tstr == 'M' || *tstr == 'm') {
1235                         newStr = VarModify(str, VarMatch, pattern);
1236                     } else {
1237                         newStr = VarModify(str, VarNoMatch, pattern);
1238                     }
1239                     if (copy) {
1240                         free(pattern);
1241                     }
1242                     break;
1243                 }
1244                 case 'S':
1245                 {
1246                     VarPattern      pattern;
1247                     char            del;
1248                     Buffer          *buf;       /* Buffer for patterns */
1249
1250                     pattern.flags = 0;
1251                     del = tstr[1];
1252                     tstr += 2;
1253
1254                     /*
1255                      * If pattern begins with '^', it is anchored to the
1256                      * start of the word -- skip over it and flag pattern.
1257                      */
1258                     if (*tstr == '^') {
1259                         pattern.flags |= VAR_MATCH_START;
1260                         tstr += 1;
1261                     }
1262
1263                     buf = Buf_Init(0);
1264
1265                     /*
1266                      * Pass through the lhs looking for 1) escaped delimiters,
1267                      * '$'s and backslashes (place the escaped character in
1268                      * uninterpreted) and 2) unescaped $'s that aren't before
1269                      * the delimiter (expand the variable substitution).
1270                      * The result is left in the Buffer buf.
1271                      */
1272                     for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
1273                         if ((*cp == '\\') &&
1274                             ((cp[1] == del) ||
1275                              (cp[1] == '$') ||
1276                              (cp[1] == '\\')))
1277                         {
1278                             Buf_AddByte(buf, (Byte)cp[1]);
1279                             cp++;
1280                         } else if (*cp == '$') {
1281                             if (cp[1] != del) {
1282                                 /*
1283                                  * If unescaped dollar sign not before the
1284                                  * delimiter, assume it's a variable
1285                                  * substitution and recurse.
1286                                  */
1287                                 char        *cp2;
1288                                 size_t len;
1289                                 Boolean     freeIt;
1290
1291                                 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1292                                 Buf_Append(buf, cp2);
1293                                 if (freeIt) {
1294                                     free(cp2);
1295                                 }
1296                                 cp += len - 1;
1297                             } else {
1298                                 /*
1299                                  * Unescaped $ at end of pattern => anchor
1300                                  * pattern at end.
1301                                  */
1302                                 pattern.flags |= VAR_MATCH_END;
1303                             }
1304                         } else {
1305                             Buf_AddByte(buf, (Byte)*cp);
1306                         }
1307                     }
1308
1309                     Buf_AddByte(buf, (Byte)'\0');
1310
1311                     /*
1312                      * If lhs didn't end with the delimiter, complain and
1313                      * exit.
1314                      */
1315                     if (*cp != del) {
1316                         Fatal("Unclosed substitution for %s (%c missing)",
1317                               v->name, del);
1318                     }
1319
1320                     /*
1321                      * Fetch pattern and destroy buffer, but preserve the data
1322                      * in it, since that's our lhs. Note that Buf_GetAll
1323                      * will return the actual number of bytes, which includes
1324                      * the null byte, so we have to decrement the length by
1325                      * one.
1326                      */
1327                     pattern.lhs = (char *)Buf_GetAll(buf, &pattern.leftLen);
1328                     pattern.leftLen--;
1329                     Buf_Destroy(buf, FALSE);
1330
1331                     /*
1332                      * Now comes the replacement string. Three things need to
1333                      * be done here: 1) need to compress escaped delimiters and
1334                      * ampersands and 2) need to replace unescaped ampersands
1335                      * with the l.h.s. (since this isn't regexp, we can do
1336                      * it right here) and 3) expand any variable substitutions.
1337                      */
1338                     buf = Buf_Init(0);
1339
1340                     tstr = cp + 1;
1341                     for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
1342                         if ((*cp == '\\') &&
1343                             ((cp[1] == del) ||
1344                              (cp[1] == '&') ||
1345                              (cp[1] == '\\') ||
1346                              (cp[1] == '$')))
1347                         {
1348                             Buf_AddByte(buf, (Byte)cp[1]);
1349                             cp++;
1350                         } else if ((*cp == '$') && (cp[1] != del)) {
1351                             char    *cp2;
1352                             size_t len;
1353                             Boolean freeIt;
1354
1355                             cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1356                             Buf_Append(buf, cp2);
1357                             cp += len - 1;
1358                             if (freeIt) {
1359                                 free(cp2);
1360                             }
1361                         } else if (*cp == '&') {
1362                             Buf_AddBytes(buf, pattern.leftLen,
1363                                          (Byte *)pattern.lhs);
1364                         } else {
1365                             Buf_AddByte(buf, (Byte)*cp);
1366                         }
1367                     }
1368
1369                     Buf_AddByte(buf, (Byte)'\0');
1370
1371                     /*
1372                      * If didn't end in delimiter character, complain
1373                      */
1374                     if (*cp != del) {
1375                         Fatal("Unclosed substitution for %s (%c missing)",
1376                               v->name, del);
1377                     }
1378
1379                     pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen);
1380                     pattern.rightLen--;
1381                     Buf_Destroy(buf, FALSE);
1382
1383                     /*
1384                      * Check for global substitution. If 'g' after the final
1385                      * delimiter, substitution is global and is marked that
1386                      * way.
1387                      */
1388                     cp++;
1389                     if (*cp == 'g') {
1390                         pattern.flags |= VAR_SUB_GLOBAL;
1391                         cp++;
1392                     }
1393
1394                     /*
1395                      * Global substitution of the empty string causes an
1396                      * infinite number of matches, unless anchored by '^'
1397                      * (start of string) or '$' (end of string). Catch the
1398                      * infinite substitution here.
1399                      * Note that flags can only contain the 3 bits we're
1400                      * interested in so we don't have to mask unrelated
1401                      * bits. We can test for equality.
1402                      */
1403                     if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL)
1404                         Fatal("Global substitution of the empty string");
1405
1406                     termc = *cp;
1407                     newStr = VarModify(str, VarSubstitute, &pattern);
1408                     /*
1409                      * Free the two strings.
1410                      */
1411                     free(pattern.lhs);
1412                     free(pattern.rhs);
1413                     break;
1414                 }
1415                 case 'C':
1416                 {
1417                     VarREPattern    pattern;
1418                     char           *re;
1419                     int             error;
1420
1421                     pattern.flags = 0;
1422                     delim = tstr[1];
1423                     tstr += 2;
1424
1425                     cp = tstr;
1426
1427                     if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL,
1428                         NULL, NULL)) == NULL) {
1429                         /* was: goto cleanup */
1430                         *lengthPtr = cp - start + 1;
1431                         if (*freePtr)
1432                             free(str);
1433                         if (delim != '\0')
1434                             Fatal("Unclosed substitution for %s (%c missing)",
1435                                   v->name, delim);
1436                         return (var_Error);
1437                     }
1438
1439                     if ((pattern.replace = VarGetPattern(ctxt, err, &cp,
1440                         delim, NULL, NULL, NULL)) == NULL){
1441                         free(re);
1442
1443                         /* was: goto cleanup */
1444                         *lengthPtr = cp - start + 1;
1445                         if (*freePtr)
1446                             free(str);
1447                         if (delim != '\0')
1448                             Fatal("Unclosed substitution for %s (%c missing)",
1449                                   v->name, delim);
1450                         return (var_Error);
1451                     }
1452
1453                     for (;; cp++) {
1454                         switch (*cp) {
1455                         case 'g':
1456                             pattern.flags |= VAR_SUB_GLOBAL;
1457                             continue;
1458                         case '1':
1459                             pattern.flags |= VAR_SUB_ONE;
1460                             continue;
1461                         default:
1462                             break;
1463                         }
1464                         break;
1465                     }
1466
1467                     termc = *cp;
1468
1469                     error = regcomp(&pattern.re, re, REG_EXTENDED);
1470                     free(re);
1471                     if (error)  {
1472                         *lengthPtr = cp - start + 1;
1473                         VarREError(error, &pattern.re, "RE substitution error");
1474                         free(pattern.replace);
1475                         return (var_Error);
1476                     }
1477
1478                     pattern.nsub = pattern.re.re_nsub + 1;
1479                     if (pattern.nsub < 1)
1480                         pattern.nsub = 1;
1481                     if (pattern.nsub > 10)
1482                         pattern.nsub = 10;
1483                     pattern.matches = emalloc(pattern.nsub *
1484                                               sizeof(regmatch_t));
1485                     newStr = VarModify(str, VarRESubstitute, &pattern);
1486                     regfree(&pattern.re);
1487                     free(pattern.replace);
1488                     free(pattern.matches);
1489                     break;
1490                 }
1491                 case 'L':
1492                     if (tstr[1] == endc || tstr[1] == ':') {
1493                         Buffer *buf;
1494                         buf = Buf_Init(MAKE_BSIZE);
1495                         for (cp = str; *cp ; cp++)
1496                             Buf_AddByte(buf, (Byte)tolower(*cp));
1497
1498                         Buf_AddByte(buf, (Byte)'\0');
1499                         newStr = (char *)Buf_GetAll(buf, (size_t *)NULL);
1500                         Buf_Destroy(buf, FALSE);
1501
1502                         cp = tstr + 1;
1503                         termc = *cp;
1504                         break;
1505                     }
1506                     /* FALLTHROUGH */
1507                 case 'O':
1508                     if (tstr[1] == endc || tstr[1] == ':') {
1509                         newStr = VarSortWords(str, SortIncreasing);
1510                         cp = tstr + 1;
1511                         termc = *cp;
1512                         break;
1513                     }
1514                     /* FALLTHROUGH */
1515                 case 'Q':
1516                     if (tstr[1] == endc || tstr[1] == ':') {
1517                         newStr = Var_Quote(str);
1518                         cp = tstr + 1;
1519                         termc = *cp;
1520                         break;
1521                     }
1522                     /*FALLTHRU*/
1523                 case 'T':
1524                     if (tstr[1] == endc || tstr[1] == ':') {
1525                         newStr = VarModify(str, VarTail, (void *)NULL);
1526                         cp = tstr + 1;
1527                         termc = *cp;
1528                         break;
1529                     }
1530                     /*FALLTHRU*/
1531                 case 'U':
1532                     if (tstr[1] == endc || tstr[1] == ':') {
1533                         Buffer *buf;
1534                         buf = Buf_Init(MAKE_BSIZE);
1535                         for (cp = str; *cp ; cp++)
1536                             Buf_AddByte(buf, (Byte)toupper(*cp));
1537
1538                         Buf_AddByte(buf, (Byte)'\0');
1539                         newStr = (char *)Buf_GetAll(buf, (size_t *)NULL);
1540                         Buf_Destroy(buf, FALSE);
1541
1542                         cp = tstr + 1;
1543                         termc = *cp;
1544                         break;
1545                     }
1546                     /* FALLTHROUGH */
1547                 case 'H':
1548                     if (tstr[1] == endc || tstr[1] == ':') {
1549                         newStr = VarModify(str, VarHead, (void *)NULL);
1550                         cp = tstr + 1;
1551                         termc = *cp;
1552                         break;
1553                     }
1554                     /*FALLTHRU*/
1555                 case 'E':
1556                     if (tstr[1] == endc || tstr[1] == ':') {
1557                         newStr = VarModify(str, VarSuffix, (void *)NULL);
1558                         cp = tstr + 1;
1559                         termc = *cp;
1560                         break;
1561                     }
1562                     /*FALLTHRU*/
1563                 case 'R':
1564                     if (tstr[1] == endc || tstr[1] == ':') {
1565                         newStr = VarModify(str, VarRoot, (void *)NULL);
1566                         cp = tstr + 1;
1567                         termc = *cp;
1568                         break;
1569                     }
1570                     /*FALLTHRU*/
1571 #ifdef SUNSHCMD
1572                 case 's':
1573                     if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
1574                         const char *error;
1575                         {
1576                             Buffer *buf = Cmd_Exec(str, &error);
1577                             newStr = Buf_GetAll(buf, NULL);
1578                             Buf_Destroy(buf, FALSE);
1579                         }
1580                         if (error)
1581                             Error(error, str);
1582                         cp = tstr + 2;
1583                         termc = *cp;
1584                         break;
1585                     }
1586                     /*FALLTHRU*/
1587 #endif
1588                 default:
1589                 {
1590 #ifdef SYSVVARSUB
1591                     /*
1592                      * This can either be a bogus modifier or a System-V
1593                      * substitution command.
1594                      */
1595                     VarPattern      pattern;
1596                     Boolean         eqFound;
1597
1598                     pattern.flags = 0;
1599                     eqFound = FALSE;
1600                     /*
1601                      * First we make a pass through the string trying
1602                      * to verify it is a SYSV-make-style translation:
1603                      * it must be: <string1>=<string2>)
1604                      */
1605                     cp = tstr;
1606                     cnt = 1;
1607                     while (*cp != '\0' && cnt) {
1608                         if (*cp == '=') {
1609                             eqFound = TRUE;
1610                             /* continue looking for endc */
1611                         }
1612                         else if (*cp == endc)
1613                             cnt--;
1614                         else if (*cp == startc)
1615                             cnt++;
1616                         if (cnt)
1617                             cp++;
1618                     }
1619                     if (*cp == endc && eqFound) {
1620
1621                         /*
1622                          * Now we break this sucker into the lhs and
1623                          * rhs. We must null terminate them of course.
1624                          */
1625                         cp = tstr;
1626
1627                         delim = '=';
1628                         if ((pattern.lhs = VarGetPattern(ctxt,
1629                             err, &cp, delim, &pattern.flags, &pattern.leftLen,
1630                             NULL)) == NULL) {
1631                                 /* was: goto cleanup */
1632                                 *lengthPtr = cp - start + 1;
1633                                 if (*freePtr)
1634                                     free(str);
1635                                 if (delim != '\0')
1636                                     Fatal("Unclosed substitution for %s (%c missing)",
1637                                           v->name, delim);
1638                                 return (var_Error);
1639                         }
1640
1641                         delim = endc;
1642                         if ((pattern.rhs = VarGetPattern(ctxt,
1643                             err, &cp, delim, NULL, &pattern.rightLen,
1644                             &pattern)) == NULL) {
1645                                 /* was: goto cleanup */
1646                                 *lengthPtr = cp - start + 1;
1647                                 if (*freePtr)
1648                                     free(str);
1649                                 if (delim != '\0')
1650                                     Fatal("Unclosed substitution for %s (%c missing)",
1651                                           v->name, delim);
1652                                 return (var_Error);
1653                         }
1654
1655                         /*
1656                          * SYSV modifications happen through the whole
1657                          * string. Note the pattern is anchored at the end.
1658                          */
1659                         termc = *--cp;
1660                         delim = '\0';
1661                         newStr = VarModify(str, VarSYSVMatch, &pattern);
1662
1663                         free(pattern.lhs);
1664                         free(pattern.rhs);
1665
1666                         termc = endc;
1667                     } else
1668 #endif
1669                     {
1670                         Error("Unknown modifier '%c'\n", *tstr);
1671                         for (cp = tstr+1;
1672                              *cp != ':' && *cp != endc && *cp != '\0';
1673                              cp++)
1674                                  continue;
1675                         termc = *cp;
1676                         newStr = var_Error;
1677                     }
1678                 }
1679             }
1680             DEBUGF(VAR, ("Result is \"%s\"\n", newStr));
1681
1682             if (*freePtr) {
1683                 free(str);
1684             }
1685             str = newStr;
1686             if (str != var_Error) {
1687                 *freePtr = TRUE;
1688             } else {
1689                 *freePtr = FALSE;
1690             }
1691             if (termc == '\0') {
1692                 Error("Unclosed variable specification for %s", v->name);
1693             } else if (termc == ':') {
1694                 *cp++ = termc;
1695             } else {
1696                 *cp = termc;
1697             }
1698             tstr = cp;
1699         }
1700         *lengthPtr = tstr - start + 1;
1701     } else {
1702         *lengthPtr = tstr - start + 1;
1703         *tstr = endc;
1704     }
1705
1706     if (v->flags & VAR_FROM_ENV) {
1707         Boolean   destroy = FALSE;
1708
1709         if (str != (char *)Buf_GetAll(v->val, (size_t *)NULL)) {
1710             destroy = TRUE;
1711         } else {
1712             /*
1713              * Returning the value unmodified, so tell the caller to free
1714              * the thing.
1715              */
1716             *freePtr = TRUE;
1717         }
1718         VarDestroy(v, destroy);
1719     } else if (v->flags & VAR_JUNK) {
1720         /*
1721          * Perform any free'ing needed and set *freePtr to FALSE so the caller
1722          * doesn't try to free a static pointer.
1723          */
1724         if (*freePtr) {
1725             free(str);
1726         }
1727         *freePtr = FALSE;
1728         VarDestroy(v, TRUE);
1729         if (dynamic) {
1730             str = emalloc(*lengthPtr + 1);
1731             strncpy(str, start, *lengthPtr);
1732             str[*lengthPtr] = '\0';
1733             *freePtr = TRUE;
1734         } else {
1735             str = err ? var_Error : varNoError;
1736         }
1737     }
1738     return (str);
1739 }
1740
1741 /*-
1742  *-----------------------------------------------------------------------
1743  * Var_Subst  --
1744  *      Substitute for all variables in the given string in the given context
1745  *      If undefErr is TRUE, Parse_Error will be called when an undefined
1746  *      variable is encountered.
1747  *
1748  * Results:
1749  *      The resulting string.
1750  *
1751  * Side Effects:
1752  *      None. The old string must be freed by the caller
1753  *-----------------------------------------------------------------------
1754  */
1755 Buffer *
1756 Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
1757 {
1758     Boolean     errorReported;
1759     Buffer      *buf;           /* Buffer for forming things */
1760
1761     /*
1762      * Set TRUE if an error has already been reported to prevent a
1763      * plethora of messages when recursing.
1764      */
1765     errorReported = FALSE;
1766
1767     buf = Buf_Init(0);
1768     while (*str) {
1769         if (var == NULL && (str[0] == '$') && (str[1] == '$')) {
1770             /*
1771              * A dollar sign may be escaped either with another dollar sign.
1772              * In such a case, we skip over the escape character and store the
1773              * dollar sign into the buffer directly.
1774              */
1775             Buf_AddByte(buf, (Byte)str[0]);
1776             str += 2;
1777
1778         } else if (str[0] == '$') {
1779             char        *val;   /* Value to substitute for a variable */
1780             size_t      length; /* Length of the variable invocation */
1781             Boolean     doFree; /* Set true if val should be freed */
1782             /*
1783              * Variable invocation.
1784              */
1785             if (var != NULL) {
1786                 int expand;
1787                 for (;;) {
1788                     if (str[1] == OPEN_PAREN || str[1] == OPEN_BRACKET) {
1789                         const char *p = str + 2;
1790
1791                         /*
1792                          * Scan up to the end of the variable name.
1793                          */
1794                         while (*p != '\0' &&
1795                                *p != ':' &&
1796                                *p != CLOSE_PAREN &&
1797                                *p != CLOSE_BRACKET &&
1798                                *p != '$') {
1799                             ++p;
1800                         }
1801
1802                         /*
1803                          * A variable inside the variable. We cannot expand
1804                          * the external variable yet, so we try again with
1805                          * the nested one
1806                          */
1807                         if (*p == '$') {
1808                             Buf_AppendRange(buf, str, p);
1809                             str = p;
1810                             continue;
1811                         }
1812
1813                         if (var[p - (str + 2)] == '\0' && strncmp(var, str + 2, p - (str + 2)) == 0) {
1814                             expand = TRUE;
1815                         } else {
1816                             /*
1817                              * Not the variable we want to expand, scan
1818                              * until the next variable
1819                              */
1820                             while (*p != '$' && *p != '\0')
1821                                 ++p;
1822
1823                             Buf_AppendRange(buf, str, p);
1824                             str = p;
1825                             expand = FALSE;
1826                         }
1827
1828                     } else {
1829                         /*
1830                          * Single letter variable name.
1831                          */
1832                         if (var[1] == '\0' && str[1] == var[0]) {
1833                             expand = TRUE;
1834                         } else {
1835                             Buf_AddBytes(buf, 2, (const Byte *)str);
1836                             str += 2;
1837                             expand = FALSE;
1838                         }
1839                     }
1840                     break;
1841                 }
1842                 if (!expand)
1843                     continue;
1844             }
1845
1846             val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
1847
1848             /*
1849              * When we come down here, val should either point to the
1850              * value of this variable, suitably modified, or be NULL.
1851              * Length should be the total length of the potential
1852              * variable invocation (from $ to end character...)
1853              */
1854             if (val == var_Error || val == varNoError) {
1855                 /*
1856                  * If performing old-time variable substitution, skip over
1857                  * the variable and continue with the substitution. Otherwise,
1858                  * store the dollar sign and advance str so we continue with
1859                  * the string...
1860                  */
1861                 if (oldVars) {
1862                     str += length;
1863                 } else if (undefErr) {
1864                     /*
1865                      * If variable is undefined, complain and skip the
1866                      * variable. The complaint will stop us from doing anything
1867                      * when the file is parsed.
1868                      */
1869                     if (!errorReported) {
1870                         Parse_Error(PARSE_FATAL,
1871                                      "Undefined variable \"%.*s\"",length,str);
1872                     }
1873                     str += length;
1874                     errorReported = TRUE;
1875                 } else {
1876                     Buf_AddByte(buf, (Byte)*str);
1877                     str += 1;
1878                 }
1879             } else {
1880                 /*
1881                  * We've now got a variable structure to store in. But first,
1882                  * advance the string pointer.
1883                  */
1884                 str += length;
1885
1886                 /*
1887                  * Copy all the characters from the variable value straight
1888                  * into the new string.
1889                  */
1890                 Buf_Append(buf, val);
1891                 if (doFree) {
1892                     free(val);
1893                 }
1894             }
1895
1896         } else {
1897             /*
1898              * Skip as many characters as possible -- either to the end of
1899              * the string or to the next dollar sign (variable invocation).
1900              */
1901             const char  *cp = str;
1902
1903             do {
1904                 str++;
1905             } while (str[0] != '$' && str[0] != '\0');
1906
1907             Buf_AppendRange(buf, cp, str);
1908         }
1909     }
1910
1911     return (buf);
1912 }
1913
1914 /*-
1915  *-----------------------------------------------------------------------
1916  * Var_GetTail --
1917  *      Return the tail from each of a list of words. Used to set the
1918  *      System V local variables.
1919  *
1920  * Results:
1921  *      The resulting string.
1922  *
1923  * Side Effects:
1924  *      None.
1925  *
1926  *-----------------------------------------------------------------------
1927  */
1928 char *
1929 Var_GetTail(char *file)
1930 {
1931
1932     return (VarModify(file, VarTail, (void *)NULL));
1933 }
1934
1935 /*-
1936  *-----------------------------------------------------------------------
1937  * Var_GetHead --
1938  *      Find the leading components of a (list of) filename(s).
1939  *      XXX: VarHead does not replace foo by ., as (sun) System V make
1940  *      does.
1941  *
1942  * Results:
1943  *      The leading components.
1944  *
1945  * Side Effects:
1946  *      None.
1947  *
1948  *-----------------------------------------------------------------------
1949  */
1950 char *
1951 Var_GetHead(char *file)
1952 {
1953
1954     return (VarModify(file, VarHead, (void *)NULL));
1955 }
1956
1957 /*-
1958  *-----------------------------------------------------------------------
1959  * Var_Init --
1960  *      Initialize the module
1961  *
1962  * Results:
1963  *      None
1964  *
1965  * Side Effects:
1966  *      The VAR_CMD and VAR_GLOBAL contexts are created
1967  *-----------------------------------------------------------------------
1968  */
1969 void
1970 Var_Init(void)
1971 {
1972
1973     VAR_GLOBAL = Targ_NewGN("Global");
1974     VAR_CMD = Targ_NewGN("Command");
1975 }
1976
1977 /****************** PRINT DEBUGGING INFO *****************/
1978 static int
1979 VarPrintVar(void *vp, void *dummy __unused)
1980 {
1981     Var    *v = (Var *) vp;
1982
1983     printf("%-16s = %s\n", v->name, (char *)Buf_GetAll(v->val, (size_t *)NULL));
1984     return (0);
1985 }
1986
1987 /*-
1988  *-----------------------------------------------------------------------
1989  * Var_Dump --
1990  *      print all variables in a context
1991  *-----------------------------------------------------------------------
1992  */
1993 void
1994 Var_Dump(GNode *ctxt)
1995 {
1996
1997     Lst_ForEach(&ctxt->context, VarPrintVar, (void *)NULL);
1998 }