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