]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/suff.c
Update to bmake-20201101
[FreeBSD/FreeBSD.git] / contrib / bmake / suff.c
1 /*      $NetBSD: suff.c,v 1.230 2020/10/31 11:54:33 rillig Exp $        */
2
3 /*
4  * Copyright (c) 1988, 1989, 1990, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 /*
36  * Copyright (c) 1989 by Berkeley Softworks
37  * All rights reserved.
38  *
39  * This code is derived from software contributed to Berkeley by
40  * Adam de Boor.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  * 3. All advertising materials mentioning features or use of this software
51  *    must display the following acknowledgement:
52  *      This product includes software developed by the University of
53  *      California, Berkeley and its contributors.
54  * 4. Neither the name of the University nor the names of its contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  */
70
71 /*-
72  * suff.c --
73  *      Functions to maintain suffix lists and find implicit dependents
74  *      using suffix transformation rules
75  *
76  * Interface:
77  *      Suff_Init       Initialize all things to do with suffixes.
78  *
79  *      Suff_End        Clean up the module
80  *
81  *      Suff_DoPaths    This function is used to make life easier
82  *                      when searching for a file according to its
83  *                      suffix. It takes the global search path,
84  *                      as defined using the .PATH: target, and appends
85  *                      its directories to the path of each of the
86  *                      defined suffixes, as specified using
87  *                      .PATH<suffix>: targets. In addition, all
88  *                      directories given for suffixes labeled as
89  *                      include files or libraries, using the .INCLUDES
90  *                      or .LIBS targets, are played with using
91  *                      Dir_MakeFlags to create the .INCLUDES and
92  *                      .LIBS global variables.
93  *
94  *      Suff_ClearSuffixes
95  *                      Clear out all the suffixes and defined
96  *                      transformations.
97  *
98  *      Suff_IsTransform
99  *                      Return TRUE if the passed string is the lhs
100  *                      of a transformation rule.
101  *
102  *      Suff_AddSuffix  Add the passed string as another known suffix.
103  *
104  *      Suff_GetPath    Return the search path for the given suffix.
105  *
106  *      Suff_AddInclude
107  *                      Mark the given suffix as denoting an include file.
108  *
109  *      Suff_AddLib     Mark the given suffix as denoting a library.
110  *
111  *      Suff_AddTransform
112  *                      Add another transformation to the suffix
113  *                      graph. Returns  GNode suitable for framing, I
114  *                      mean, tacking commands, attributes, etc. on.
115  *
116  *      Suff_SetNull    Define the suffix to consider the suffix of
117  *                      any file that doesn't have a known one.
118  *
119  *      Suff_FindDeps   Find implicit sources for and the location of
120  *                      a target based on its suffix. Returns the
121  *                      bottom-most node added to the graph or NULL
122  *                      if the target had no implicit sources.
123  *
124  *      Suff_FindPath   Return the appropriate path to search in order to
125  *                      find the node.
126  */
127
128 #include "make.h"
129 #include "dir.h"
130
131 /*      "@(#)suff.c     8.4 (Berkeley) 3/21/94" */
132 MAKE_RCSID("$NetBSD: suff.c,v 1.230 2020/10/31 11:54:33 rillig Exp $");
133
134 #define SUFF_DEBUG0(text) DEBUG0(SUFF, text)
135 #define SUFF_DEBUG1(fmt, arg1) DEBUG1(SUFF, fmt, arg1)
136 #define SUFF_DEBUG2(fmt, arg1, arg2) DEBUG2(SUFF, fmt, arg1, arg2)
137 #define SUFF_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(SUFF, fmt, arg1, arg2, arg3)
138 #define SUFF_DEBUG4(fmt, arg1, arg2, arg3, arg4) \
139         DEBUG4(SUFF, fmt, arg1, arg2, arg3, arg4)
140
141 typedef List SuffList;
142 typedef ListNode SuffListNode;
143
144 typedef List SrcList;
145 typedef ListNode SrcListNode;
146
147 static SuffList *sufflist;      /* List of suffixes */
148 #ifdef CLEANUP
149 static SuffList *suffClean;     /* List of suffixes to be cleaned */
150 #endif
151 static SrcList *srclist;        /* List of sources */
152 static GNodeList *transforms;   /* List of transformation rules */
153
154 static int        sNum = 0;     /* Counter for assigning suffix numbers */
155
156 typedef enum SuffFlags {
157     SUFF_INCLUDE        = 0x01, /* One which is #include'd */
158     SUFF_LIBRARY        = 0x02, /* One which contains a library */
159     SUFF_NULL           = 0x04  /* The empty suffix */
160     /* XXX: Why is SUFF_NULL needed? Wouldn't nameLen == 0 mean the same? */
161 } SuffFlags;
162
163 ENUM_FLAGS_RTTI_3(SuffFlags,
164                   SUFF_INCLUDE, SUFF_LIBRARY, SUFF_NULL);
165
166 typedef List SuffListList;
167
168 /*
169  * Structure describing an individual suffix.
170  */
171 typedef struct Suff {
172     char         *name;         /* The suffix itself, such as ".c" */
173     size_t       nameLen;       /* Length of the name, to avoid strlen calls */
174     SuffFlags    flags;         /* Type of suffix */
175     SearchPath   *searchPath;   /* The path along which files of this suffix
176                                  * may be found */
177     int          sNum;          /* The suffix number */
178     int          refCount;      /* Reference count of list membership
179                                  * and several other places */
180     SuffList     *parents;      /* Suffixes we have a transformation to */
181     SuffList     *children;     /* Suffixes we have a transformation from */
182     SuffListList *ref;          /* Lists in which this suffix is referenced */
183 } Suff;
184
185 /*
186  * Structure used in the search for implied sources.
187  */
188 typedef struct Src {
189     char *file;                 /* The file to look for */
190     char *pref;                 /* Prefix from which file was formed */
191     Suff *suff;                 /* The suffix on the file */
192     struct Src *parent;         /* The Src for which this is a source */
193     GNode *node;                /* The node describing the file */
194     int children;               /* Count of existing children (so we don't free
195                                  * this thing too early or never nuke it) */
196 #ifdef DEBUG_SRC
197     SrcList *childrenList;
198 #endif
199 } Src;
200
201 static Suff *suffNull;          /* The NULL suffix for this run */
202 static Suff *emptySuff;         /* The empty suffix required for POSIX
203                                  * single-suffix transformation rules */
204
205
206 static void SuffFindDeps(GNode *, SrcList *);
207 static void SuffExpandWildcards(GNodeListNode *, GNode *);
208
209         /*************** Lst Predicates ****************/
210 /*-
211  *-----------------------------------------------------------------------
212  * SuffStrIsPrefix  --
213  *      See if pref is a prefix of str.
214  *
215  * Input:
216  *      pref            possible prefix
217  *      str             string to check
218  *
219  * Results:
220  *      NULL if it ain't, pointer to character in str after prefix if so
221  *
222  * Side Effects:
223  *      None
224  *-----------------------------------------------------------------------
225  */
226 static const char *
227 SuffStrIsPrefix(const char *pref, const char *str)
228 {
229     while (*str && *pref == *str) {
230         pref++;
231         str++;
232     }
233
234     return *pref ? NULL : str;
235 }
236
237 /* See if suff is a suffix of str.
238  *
239  * Input:
240  *      s               possible suffix
241  *      nameLen         length of the string to examine
242  *      nameEnd         end of the string to examine
243  *
244  * Results:
245  *      NULL if it ain't, pointer to the start of suffix in str if it is.
246  */
247 static const char *
248 SuffSuffGetSuffix(const Suff *s, size_t nameLen, const char *nameEnd)
249 {
250     const char *p1;             /* Pointer into suffix name */
251     const char *p2;             /* Pointer into string being examined */
252
253     if (nameLen < s->nameLen)
254         return NULL;            /* this string is shorter than the suffix */
255
256     p1 = s->name + s->nameLen;
257     p2 = nameEnd;
258
259     while (p1 >= s->name && *p1 == *p2) {
260         p1--;
261         p2--;
262     }
263
264     /* XXX: s->name - 1 invokes undefined behavior */
265     return p1 == s->name - 1 ? p2 + 1 : NULL;
266 }
267
268 static Boolean
269 SuffSuffIsSuffix(const Suff *suff, size_t nameLen, const char *nameEnd)
270 {
271     return SuffSuffGetSuffix(suff, nameLen, nameEnd) != NULL;
272 }
273
274 static Suff *
275 FindSuffByNameLen(const char *name, size_t nameLen)
276 {
277     SuffListNode *ln;
278
279     for (ln = sufflist->first; ln != NULL; ln = ln->next) {
280         Suff *suff = ln->datum;
281         if (suff->nameLen == nameLen && memcmp(suff->name, name, nameLen) == 0)
282             return suff;
283     }
284     return NULL;
285 }
286
287 static Suff *
288 FindSuffByName(const char *name)
289 {
290     return FindSuffByNameLen(name, strlen(name));
291 }
292
293 static GNode *
294 FindTransformByName(const char *name)
295 {
296     GNodeListNode *ln;
297     for (ln = transforms->first; ln != NULL; ln = ln->next) {
298         GNode *gn = ln->datum;
299         if (strcmp(gn->name, name) == 0)
300             return gn;
301     }
302     return NULL;
303 }
304
305             /*********** Maintenance Functions ************/
306
307 static void
308 SuffUnRef(SuffList *list, Suff *suff)
309 {
310     SuffListNode *ln = Lst_FindDatum(list, suff);
311     if (ln != NULL) {
312         Lst_Remove(list, ln);
313         suff->refCount--;
314     }
315 }
316
317 /* Free up all memory associated with the given suffix structure. */
318 static void
319 SuffFree(void *sp)
320 {
321     Suff *s = sp;
322
323     if (s == suffNull)
324         suffNull = NULL;
325
326     if (s == emptySuff)
327         emptySuff = NULL;
328
329 #if 0
330     /* We don't delete suffixes in order, so we cannot use this */
331     if (s->refCount)
332         Punt("Internal error deleting suffix `%s' with refcount = %d", s->name,
333             s->refCount);
334 #endif
335
336     Lst_Free(s->ref);
337     Lst_Free(s->children);
338     Lst_Free(s->parents);
339     Lst_Destroy(s->searchPath, Dir_Destroy);
340
341     free(s->name);
342     free(s);
343 }
344
345 /* Remove the suffix from the list, and free if it is otherwise unused. */
346 static void
347 SuffRemove(SuffList *list, Suff *suff)
348 {
349     SuffUnRef(list, suff);
350     if (suff->refCount == 0) {
351         SuffUnRef(sufflist, suff);
352         SuffFree(suff);
353     }
354 }
355
356 /* Insert the suffix into the list, keeping the list ordered by suffix
357  * numbers. */
358 static void
359 SuffInsert(SuffList *list, Suff *suff)
360 {
361     SuffListNode *ln;
362     Suff *listSuff = NULL;
363
364     for (ln = list->first; ln != NULL; ln = ln->next) {
365         listSuff = ln->datum;
366         if (listSuff->sNum >= suff->sNum)
367             break;
368     }
369
370     if (ln == NULL) {
371         SUFF_DEBUG2("inserting \"%s\" (%d) at end of list\n",
372                     suff->name, suff->sNum);
373         Lst_Append(list, suff);
374         suff->refCount++;
375         Lst_Append(suff->ref, list);
376     } else if (listSuff->sNum != suff->sNum) {
377         SUFF_DEBUG4("inserting \"%s\" (%d) before \"%s\" (%d)\n",
378                     suff->name, suff->sNum, listSuff->name, listSuff->sNum);
379         Lst_InsertBefore(list, ln, suff);
380         suff->refCount++;
381         Lst_Append(suff->ref, list);
382     } else {
383         SUFF_DEBUG2("\"%s\" (%d) is already there\n", suff->name, suff->sNum);
384     }
385 }
386
387 static Suff *
388 SuffNew(const char *name)
389 {
390     Suff *s = bmake_malloc(sizeof(Suff));
391
392     s->name = bmake_strdup(name);
393     s->nameLen = strlen(s->name);
394     s->searchPath = Lst_New();
395     s->children = Lst_New();
396     s->parents = Lst_New();
397     s->ref = Lst_New();
398     s->sNum = sNum++;
399     s->flags = 0;
400     s->refCount = 1;
401
402     return s;
403 }
404
405 /* This is gross. Nuke the list of suffixes but keep all transformation
406  * rules around. The transformation graph is destroyed in this process, but
407  * we leave the list of rules so when a new graph is formed the rules will
408  * remain. This function is called from the parse module when a .SUFFIXES:\n
409  * line is encountered. */
410 void
411 Suff_ClearSuffixes(void)
412 {
413 #ifdef CLEANUP
414     Lst_MoveAll(suffClean, sufflist);
415 #endif
416     sufflist = Lst_New();
417     sNum = 0;
418     if (suffNull)
419         SuffFree(suffNull);
420     emptySuff = suffNull = SuffNew("");
421
422     Dir_Concat(suffNull->searchPath, dirSearchPath);
423     suffNull->flags = SUFF_NULL;
424 }
425
426 /* Parse a transformation string such as ".c.o" to find its two component
427  * suffixes (the source ".c" and the target ".o").  If there are no such
428  * suffixes, try a single-suffix transformation as well.
429  *
430  * Return TRUE if the string is a valid transformation.
431  */
432 static Boolean
433 SuffParseTransform(const char *str, Suff **out_src, Suff **out_targ)
434 {
435     SuffListNode *ln;
436     Suff *singleSrc = NULL;
437
438     /*
439      * Loop looking first for a suffix that matches the start of the
440      * string and then for one that exactly matches the rest of it. If
441      * we can find two that meet these criteria, we've successfully
442      * parsed the string.
443      */
444     for (ln = sufflist->first; ln != NULL; ln = ln->next) {
445         Suff *src = ln->datum;
446
447         if (SuffStrIsPrefix(src->name, str) == NULL)
448             continue;
449
450         if (str[src->nameLen] == '\0') {
451             singleSrc = src;
452         } else {
453             Suff *targ = FindSuffByName(str + src->nameLen);
454             if (targ != NULL) {
455                 *out_src = src;
456                 *out_targ = targ;
457                 return TRUE;
458             }
459         }
460     }
461
462     if (singleSrc != NULL) {
463         /*
464          * Not so fast Mr. Smith! There was a suffix that encompassed
465          * the entire string, so we assume it was a transformation
466          * to the null suffix (thank you POSIX). We still prefer to
467          * find a double rule over a singleton, hence we leave this
468          * check until the end.
469          *
470          * XXX: Use emptySuff over suffNull?
471          */
472         *out_src = singleSrc;
473         *out_targ = suffNull;
474         return TRUE;
475     }
476     return FALSE;
477 }
478
479 /* Return TRUE if the given string is a transformation rule, that is, a
480  * concatenation of two known suffixes. */
481 Boolean
482 Suff_IsTransform(const char *str)
483 {
484     Suff *src, *targ;
485
486     return SuffParseTransform(str, &src, &targ);
487 }
488
489 /* Add the transformation rule to the list of rules and place the
490  * transformation itself in the graph.
491  *
492  * The transformation is linked to the two suffixes mentioned in the name.
493  *
494  * Input:
495  *      name            must have the form ".from.to" or just ".from"
496  *
497  * Results:
498  *      The created or existing transformation node in the transforms list
499  */
500 GNode *
501 Suff_AddTransform(const char *name)
502 {
503     GNode         *gn;          /* GNode of transformation rule */
504     Suff          *s,           /* source suffix */
505                   *t;           /* target suffix */
506     Boolean ok;
507
508     gn = FindTransformByName(name);
509     if (gn == NULL) {
510         /*
511          * Make a new graph node for the transformation. It will be filled in
512          * by the Parse module.
513          */
514         gn = Targ_NewGN(name);
515         Lst_Append(transforms, gn);
516     } else {
517         /*
518          * New specification for transformation rule. Just nuke the old list
519          * of commands so they can be filled in again... We don't actually
520          * free the commands themselves, because a given command can be
521          * attached to several different transformations.
522          */
523         Lst_Free(gn->commands);
524         Lst_Free(gn->children);
525         gn->commands = Lst_New();
526         gn->children = Lst_New();
527     }
528
529     gn->type = OP_TRANSFORM;
530
531     ok = SuffParseTransform(name, &s, &t);
532     assert(ok);
533     (void)ok;
534
535     /*
536      * link the two together in the proper relationship and order
537      */
538     SUFF_DEBUG2("defining transformation from `%s' to `%s'\n",
539                 s->name, t->name);
540     SuffInsert(t->children, s);
541     SuffInsert(s->parents, t);
542
543     return gn;
544 }
545
546 /* Handle the finish of a transformation definition, removing the
547  * transformation from the graph if it has neither commands nor sources.
548  *
549  * If the node has no commands or children, the children and parents lists
550  * of the affected suffixes are altered.
551  *
552  * Input:
553  *      gn              Node for transformation
554  */
555 void
556 Suff_EndTransform(GNode *gn)
557 {
558     if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(gn->cohorts))
559         gn = gn->cohorts->last->datum;
560     if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) &&
561         Lst_IsEmpty(gn->children))
562     {
563         Suff    *s, *t;
564
565         /*
566          * SuffParseTransform() may fail for special rules which are not
567          * actual transformation rules. (e.g. .DEFAULT)
568          */
569         if (SuffParseTransform(gn->name, &s, &t)) {
570             SuffList *p;
571
572             SUFF_DEBUG2("deleting transformation from `%s' to `%s'\n",
573                         s->name, t->name);
574
575             /*
576              * Store s->parents because s could be deleted in SuffRemove
577              */
578             p = s->parents;
579
580             /*
581              * Remove the source from the target's children list. We check for a
582              * nil return to handle a beanhead saying something like
583              *  .c.o .c.o:
584              *
585              * We'll be called twice when the next target is seen, but .c and .o
586              * are only linked once...
587              */
588             SuffRemove(t->children, s);
589
590             /*
591              * Remove the target from the source's parents list
592              */
593             SuffRemove(p, t);
594         }
595     } else if (gn->type & OP_TRANSFORM) {
596         SUFF_DEBUG1("transformation %s complete\n", gn->name);
597     }
598 }
599
600 /* Called from Suff_AddSuffix to search through the list of
601  * existing transformation rules and rebuild the transformation graph when
602  * it has been destroyed by Suff_ClearSuffixes. If the given rule is a
603  * transformation involving this suffix and another, existing suffix, the
604  * proper relationship is established between the two.
605  *
606  * The appropriate links will be made between this suffix and others if
607  * transformation rules exist for it.
608  *
609  * Input:
610  *      transform       Transformation to test
611  *      suff            Suffix to rebuild
612  */
613 static void
614 SuffRebuildGraph(GNode *transform, Suff *suff)
615 {
616     const char *name = transform->name;
617     size_t nameLen = strlen(name);
618     const char *toName;
619
620     /*
621      * First see if it is a transformation from this suffix.
622      */
623     toName = SuffStrIsPrefix(suff->name, name);
624     if (toName != NULL) {
625         Suff *to = FindSuffByName(toName);
626         if (to != NULL) {
627             /* Link in and return, since it can't be anything else. */
628             SuffInsert(to->children, suff);
629             SuffInsert(suff->parents, to);
630             return;
631         }
632     }
633
634     /*
635      * Not from, maybe to?
636      */
637     toName = SuffSuffGetSuffix(suff, nameLen, name + nameLen);
638     if (toName != NULL) {
639         Suff *from = FindSuffByNameLen(name, (size_t)(toName - name));
640
641         if (from != NULL) {
642             /* establish the proper relationship */
643             SuffInsert(suff->children, from);
644             SuffInsert(from->parents, suff);
645         }
646     }
647 }
648
649 /* During Suff_AddSuffix, search through the list of existing targets and find
650  * if any of the existing targets can be turned into a transformation rule.
651  *
652  * If such a target is found and the target is the current main target, the
653  * main target is set to NULL and the next target examined (if that exists)
654  * becomes the main target.
655  *
656  * Results:
657  *      TRUE iff a new main target has been selected.
658  */
659 static Boolean
660 SuffScanTargets(GNode *target, GNode **inout_main, Suff *gs_s, Boolean *gs_r)
661 {
662     Suff *s, *t;
663     char *ptr;
664
665     if (*inout_main == NULL && *gs_r && !(target->type & OP_NOTARGET)) {
666         *inout_main = target;
667         Targ_SetMain(target);
668         return TRUE;
669     }
670
671     if (target->type == OP_TRANSFORM)
672         return FALSE;
673
674     if ((ptr = strstr(target->name, gs_s->name)) == NULL ||
675         ptr == target->name)
676         return FALSE;
677
678     if (SuffParseTransform(target->name, &s, &t)) {
679         if (*inout_main == target) {
680             *gs_r = TRUE;
681             *inout_main = NULL;
682             Targ_SetMain(NULL);
683         }
684         Lst_Free(target->children);
685         target->children = Lst_New();
686         target->type = OP_TRANSFORM;
687         /*
688          * link the two together in the proper relationship and order
689          */
690         SUFF_DEBUG2("defining transformation from `%s' to `%s'\n",
691                     s->name, t->name);
692         SuffInsert(t->children, s);
693         SuffInsert(s->parents, t);
694     }
695     return FALSE;
696 }
697
698 /* Look at all existing targets to see if adding this suffix will make one
699  * of the current targets mutate into a suffix rule.
700  *
701  * This is ugly, but other makes treat all targets that start with a '.' as
702  * suffix rules. */
703 static void
704 UpdateTargets(GNode **inout_main, Suff *s)
705 {
706     Boolean r = FALSE;
707     GNodeListNode *ln;
708     for (ln = Targ_List()->first; ln != NULL; ln = ln->next) {
709         GNode *gn = ln->datum;
710         if (SuffScanTargets(gn, inout_main, s, &r))
711             break;
712     }
713 }
714
715 /* Add the suffix to the end of the list of known suffixes.
716  * Should we restructure the suffix graph? Make doesn't...
717  *
718  * A GNode is created for the suffix and a Suff structure is created and
719  * added to the suffixes list unless the suffix was already known.
720  * The mainNode passed can be modified if a target mutated into a
721  * transform and that target happened to be the main target.
722  *
723  * Input:
724  *      name            the name of the suffix to add
725  */
726 void
727 Suff_AddSuffix(const char *name, GNode **inout_main)
728 {
729     GNodeListNode *ln;
730
731     Suff *s = FindSuffByName(name);
732     if (s != NULL)
733         return;
734
735     s = SuffNew(name);
736     Lst_Append(sufflist, s);
737
738     UpdateTargets(inout_main, s);
739
740     /*
741      * Look for any existing transformations from or to this suffix.
742      * XXX: Only do this after a Suff_ClearSuffixes?
743      */
744     for (ln = transforms->first; ln != NULL; ln = ln->next)
745         SuffRebuildGraph(ln->datum, s);
746 }
747
748 /* Return the search path for the given suffix, or NULL. */
749 SearchPath *
750 Suff_GetPath(const char *sname)
751 {
752     Suff *s = FindSuffByName(sname);
753     return s != NULL ? s->searchPath : NULL;
754 }
755
756 /* Extend the search paths for all suffixes to include the default search
757  * path.
758  *
759  * The searchPath field of all the suffixes is extended by the directories
760  * in dirSearchPath. If paths were specified for the ".h" suffix, the
761  * directories are stuffed into a global variable called ".INCLUDES" with
762  * each directory preceded by a -I. The same is done for the ".a" suffix,
763  * except the variable is called ".LIBS" and the flag is -L.
764  */
765 void
766 Suff_DoPaths(void)
767 {
768     SuffListNode *ln;
769     char *ptr;
770     SearchPath *inIncludes; /* Cumulative .INCLUDES path */
771     SearchPath *inLibs;     /* Cumulative .LIBS path */
772
773     inIncludes = Lst_New();
774     inLibs = Lst_New();
775
776     for (ln = sufflist->first; ln != NULL; ln = ln->next) {
777         Suff *s = ln->datum;
778         if (!Lst_IsEmpty(s->searchPath)) {
779 #ifdef INCLUDES
780             if (s->flags & SUFF_INCLUDE) {
781                 Dir_Concat(inIncludes, s->searchPath);
782             }
783 #endif
784 #ifdef LIBRARIES
785             if (s->flags & SUFF_LIBRARY) {
786                 Dir_Concat(inLibs, s->searchPath);
787             }
788 #endif
789             Dir_Concat(s->searchPath, dirSearchPath);
790         } else {
791             Lst_Destroy(s->searchPath, Dir_Destroy);
792             s->searchPath = Dir_CopyDirSearchPath();
793         }
794     }
795
796     Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL);
797     free(ptr);
798     Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL);
799     free(ptr);
800
801     Lst_Destroy(inIncludes, Dir_Destroy);
802     Lst_Destroy(inLibs, Dir_Destroy);
803 }
804
805 /* Add the given suffix as a type of file which gets included.
806  * Called from the parse module when a .INCLUDES line is parsed.
807  * The suffix must have already been defined.
808  * The SUFF_INCLUDE bit is set in the suffix's flags field.
809  *
810  * Input:
811  *      sname           Name of the suffix to mark
812  */
813 void
814 Suff_AddInclude(const char *sname)
815 {
816     Suff *suff = FindSuffByName(sname);
817     if (suff != NULL)
818         suff->flags |= SUFF_INCLUDE;
819 }
820
821 /* Add the given suffix as a type of file which is a library.
822  * Called from the parse module when parsing a .LIBS line.
823  * The suffix must have been defined via .SUFFIXES before this is called.
824  * The SUFF_LIBRARY bit is set in the suffix's flags field.
825  *
826  * Input:
827  *      sname           Name of the suffix to mark
828  */
829 void
830 Suff_AddLib(const char *sname)
831 {
832     Suff *suff = FindSuffByName(sname);
833     if (suff != NULL)
834         suff->flags |= SUFF_LIBRARY;
835 }
836
837           /********** Implicit Source Search Functions *********/
838
839 #ifdef DEBUG_SRC
840 static void
841 SrcList_PrintAddrs(SrcList *srcList)
842 {
843     SrcListNode *ln;
844     for (ln = srcList->first; ln != NULL; ln = ln->next)
845         debug_printf(" %p", ln->datum);
846     debug_printf("\n");
847 }
848 #endif
849
850 static Src *
851 SrcNew(char *name, char *pref, Suff *suff, Src *parent, GNode *gn)
852 {
853     Src *src = bmake_malloc(sizeof *src);
854
855     src->file = name;
856     src->pref = pref;
857     src->suff = suff;
858     src->parent = parent;
859     src->node = gn;
860     src->children = 0;
861 #ifdef DEBUG_SRC
862     src->childrenList = Lst_New();
863 #endif
864
865     return src;
866 }
867
868 static void
869 SuffAddSrc(Suff *suff, SrcList *srcList, Src *targ, char *srcName,
870            const char *debug_tag)
871 {
872     Src *s2 = SrcNew(srcName, targ->pref, suff, targ, NULL);
873     suff->refCount++;
874     targ->children++;
875     Lst_Append(srcList, s2);
876 #ifdef DEBUG_SRC
877     Lst_Append(targ->childrenList, s2);
878     debug_printf("%s add suff %p src %p to list %p:",
879                  debug_tag, targ, s2, srcList);
880     SrcList_PrintAddrs(srcList);
881 #endif
882 }
883
884 /* Add a suffix as a Src structure to the given list with its parent
885  * being the given Src structure. If the suffix is the null suffix,
886  * the prefix is used unaltered as the file name in the Src structure.
887  *
888  * Input:
889  *      suff            suffix for which to create a Src structure
890  *      srcList         list for the new Src
891  *      targ            parent for the new Src
892  */
893 static void
894 SuffAddSources(Suff *suff, SrcList *srcList, Src *targ)
895 {
896     if ((suff->flags & SUFF_NULL) && suff->name[0] != '\0') {
897         /*
898          * If the suffix has been marked as the NULL suffix, also create a Src
899          * structure for a file with no suffix attached. Two birds, and all
900          * that...
901          */
902         SuffAddSrc(suff, srcList, targ, bmake_strdup(targ->pref), "1");
903     }
904     SuffAddSrc(suff, srcList, targ, str_concat2(targ->pref, suff->name), "2");
905 }
906
907 /* Add all the children of targ as Src structures to the given list.
908  *
909  * Input:
910  *      l               list to which to add the new level
911  *      targ            Src structure to use as the parent
912  */
913 static void
914 SuffAddLevel(SrcList *l, Src *targ)
915 {
916     SrcListNode *ln;
917     for (ln = targ->suff->children->first; ln != NULL; ln = ln->next) {
918         Suff *childSuff = ln->datum;
919         SuffAddSources(childSuff, l, targ);
920     }
921 }
922
923 /* Free the first Src in the list that is not referenced anymore.
924  * Return whether a Src was removed. */
925 static Boolean
926 SuffRemoveSrc(SrcList *l)
927 {
928     SrcListNode *ln;
929
930 #ifdef DEBUG_SRC
931     debug_printf("cleaning list %p:", l);
932     SrcList_PrintAddrs(l);
933 #endif
934
935     for (ln = l->first; ln != NULL; ln = ln->next) {
936         Src *s = ln->datum;
937
938         if (s->children == 0) {
939             free(s->file);
940             if (s->parent == NULL)
941                 free(s->pref);
942             else {
943 #ifdef DEBUG_SRC
944                 SrcListNode *ln2 = Lst_FindDatum(s->parent->childrenList, s);
945                 if (ln2 != NULL)
946                     Lst_Remove(s->parent->childrenList, ln2);
947 #endif
948                 s->parent->children--;
949             }
950 #ifdef DEBUG_SRC
951             debug_printf("free: list %p src %p children %d\n",
952                          l, s, s->children);
953             Lst_Free(s->childrenList);
954 #endif
955             Lst_Remove(l, ln);
956             free(s);
957             return TRUE;
958         }
959 #ifdef DEBUG_SRC
960         else {
961             debug_printf("keep: list %p src %p children %d:",
962                          l, s, s->children);
963             SrcList_PrintAddrs(s->childrenList);
964         }
965 #endif
966     }
967
968     return FALSE;
969 }
970
971 /* Find the first existing file/target in the list srcs.
972  *
973  * Input:
974  *      srcs            list of Src structures to search through
975  *
976  * Results:
977  *      The lowest structure in the chain of transformations, or NULL.
978  */
979 static Src *
980 SuffFindThem(SrcList *srcs, SrcList *slst)
981 {
982     Src *retsrc = NULL;
983
984     while (!Lst_IsEmpty(srcs)) {
985         Src *src = Lst_Dequeue(srcs);
986
987         SUFF_DEBUG1("\ttrying %s...", src->file);
988
989         /*
990          * A file is considered to exist if either a node exists in the
991          * graph for it or the file actually exists.
992          */
993         if (Targ_FindNode(src->file) != NULL) {
994 #ifdef DEBUG_SRC
995             debug_printf("remove from list %p src %p\n", srcs, src);
996 #endif
997             retsrc = src;
998             break;
999         }
1000
1001         {
1002             char *file = Dir_FindFile(src->file, src->suff->searchPath);
1003             if (file != NULL) {
1004                 retsrc = src;
1005 #ifdef DEBUG_SRC
1006                 debug_printf("remove from list %p src %p\n", srcs, src);
1007 #endif
1008                 free(file);
1009                 break;
1010             }
1011         }
1012
1013         SUFF_DEBUG0("not there\n");
1014
1015         SuffAddLevel(srcs, src);
1016         Lst_Append(slst, src);
1017     }
1018
1019     if (retsrc) {
1020         SUFF_DEBUG0("got it\n");
1021     }
1022     return retsrc;
1023 }
1024
1025 /* See if any of the children of the target in the Src structure is one from
1026  * which the target can be transformed. If there is one, a Src structure is
1027  * put together for it and returned.
1028  *
1029  * Input:
1030  *      targ            Src to play with
1031  *
1032  * Results:
1033  *      The Src of the "winning" child, or NULL.
1034  */
1035 static Src *
1036 SuffFindCmds(Src *targ, SrcList *slst)
1037 {
1038     GNodeListNode *gln;
1039     GNode *tgn;                 /* Target GNode */
1040     GNode *sgn;                 /* Source GNode */
1041     size_t prefLen;             /* The length of the defined prefix */
1042     Suff *suff;                 /* Suffix on matching beastie */
1043     Src *ret;                   /* Return value */
1044     char *cp;
1045
1046     tgn = targ->node;
1047     prefLen = strlen(targ->pref);
1048
1049     for (gln = tgn->children->first; gln != NULL; gln = gln->next) {
1050         sgn = gln->datum;
1051
1052         if (sgn->type & OP_OPTIONAL && Lst_IsEmpty(tgn->commands)) {
1053             /*
1054              * We haven't looked to see if .OPTIONAL files exist yet, so
1055              * don't use one as the implicit source.
1056              * This allows us to use .OPTIONAL in .depend files so make won't
1057              * complain "don't know how to make xxx.h' when a dependent file
1058              * has been moved/deleted.
1059              */
1060             continue;
1061         }
1062
1063         cp = strrchr(sgn->name, '/');
1064         if (cp == NULL) {
1065             cp = sgn->name;
1066         } else {
1067             cp++;
1068         }
1069         if (strncmp(cp, targ->pref, prefLen) != 0)
1070             continue;
1071         /*
1072          * The node matches the prefix ok, see if it has a known
1073          * suffix.
1074          */
1075         suff = FindSuffByName(cp + prefLen);
1076         if (suff == NULL)
1077             continue;
1078
1079         /*
1080          * It even has a known suffix, see if there's a transformation
1081          * defined between the node's suffix and the target's suffix.
1082          *
1083          * XXX: Handle multi-stage transformations here, too.
1084          */
1085
1086         /* XXX: Can targ->suff be NULL here? */
1087         if (targ->suff != NULL &&
1088             Lst_FindDatum(suff->parents, targ->suff) != NULL)
1089             break;
1090     }
1091
1092     if (gln == NULL)
1093         return NULL;
1094
1095     /*
1096      * Hot Damn! Create a new Src structure to describe
1097      * this transformation (making sure to duplicate the
1098      * source node's name so Suff_FindDeps can free it
1099      * again (ick)), and return the new structure.
1100      */
1101     ret = SrcNew(bmake_strdup(sgn->name), targ->pref, suff, targ, sgn);
1102     suff->refCount++;
1103     targ->children++;
1104 #ifdef DEBUG_SRC
1105     debug_printf("3 add targ %p ret %p\n", targ, ret);
1106     Lst_Append(targ->childrenList, ret);
1107 #endif
1108     Lst_Append(slst, ret);
1109     SUFF_DEBUG1("\tusing existing source %s\n", sgn->name);
1110     return ret;
1111 }
1112
1113 /* Expand the names of any children of a given node that contain variable
1114  * expressions or file wildcards into actual targets.
1115  *
1116  * The expanded node is removed from the parent's list of children, and the
1117  * parent's unmade counter is decremented, but other nodes may be added.
1118  *
1119  * Input:
1120  *      cln             Child to examine
1121  *      pgn             Parent node being processed
1122  */
1123 static void
1124 SuffExpandChildren(GNodeListNode *cln, GNode *pgn)
1125 {
1126     GNode *cgn = cln->datum;
1127     GNode *gn;                  /* New source 8) */
1128     char *cp;                   /* Expanded value */
1129
1130     if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ))
1131         /* It is all too hard to process the result of .ORDER */
1132         return;
1133
1134     if (cgn->type & OP_WAIT)
1135         /* Ignore these (& OP_PHONY ?) */
1136         return;
1137
1138     /*
1139      * First do variable expansion -- this takes precedence over
1140      * wildcard expansion. If the result contains wildcards, they'll be gotten
1141      * to later since the resulting words are tacked on to the end of
1142      * the children list.
1143      */
1144     if (strchr(cgn->name, '$') == NULL) {
1145         SuffExpandWildcards(cln, pgn);
1146         return;
1147     }
1148
1149     SUFF_DEBUG1("Expanding \"%s\"...", cgn->name);
1150     (void)Var_Subst(cgn->name, pgn, VARE_UNDEFERR|VARE_WANTRES, &cp);
1151     /* TODO: handle errors */
1152
1153     {
1154         GNodeList *members = Lst_New();
1155
1156         if (cgn->type & OP_ARCHV) {
1157             /*
1158              * Node was an archive(member) target, so we want to call
1159              * on the Arch module to find the nodes for us, expanding
1160              * variables in the parent's context.
1161              */
1162             char        *sacrifice = cp;
1163
1164             (void)Arch_ParseArchive(&sacrifice, members, pgn);
1165         } else {
1166             /*
1167              * Break the result into a vector of strings whose nodes
1168              * we can find, then add those nodes to the members list.
1169              * Unfortunately, we can't use brk_string b/c it
1170              * doesn't understand about variable specifications with
1171              * spaces in them...
1172              */
1173             char            *start;
1174             char            *initcp = cp;   /* For freeing... */
1175
1176             for (start = cp; *start == ' ' || *start == '\t'; start++)
1177                 continue;
1178             cp = start;
1179             while (*cp != '\0') {
1180                 if (*cp == ' ' || *cp == '\t') {
1181                     /*
1182                      * White-space -- terminate element, find the node,
1183                      * add it, skip any further spaces.
1184                      */
1185                     *cp++ = '\0';
1186                     gn = Targ_GetNode(start);
1187                     Lst_Append(members, gn);
1188                     while (*cp == ' ' || *cp == '\t') {
1189                         cp++;
1190                     }
1191                     start = cp;         /* Continue at the next non-space. */
1192                 } else if (*cp == '$') {
1193                     /*
1194                      * Start of a variable spec -- contact variable module
1195                      * to find the end so we can skip over it.
1196                      */
1197                     const char *nested_p = cp;
1198                     const char  *junk;
1199                     void        *freeIt;
1200
1201                     /* XXX: Why VARE_WANTRES when the result is not used? */
1202                     (void)Var_Parse(&nested_p, pgn,
1203                                     VARE_UNDEFERR|VARE_WANTRES,
1204                                     &junk, &freeIt);
1205                     /* TODO: handle errors */
1206                     if (junk == var_Error) {
1207                         Parse_Error(PARSE_FATAL,
1208                                     "Malformed variable expression at \"%s\"",
1209                                     cp);
1210                         cp++;
1211                     } else {
1212                         cp += nested_p - cp;
1213                     }
1214
1215                     free(freeIt);
1216                 } else if (*cp == '\\' && cp[1] != '\0') {
1217                     /*
1218                      * Escaped something -- skip over it
1219                      */
1220                     /* XXX: In other places, escaping at this syntactical
1221                      * position is done by a '$', not a '\'.  The '\' is only
1222                      * used in variable modifiers. */
1223                     cp += 2;
1224                 } else {
1225                     cp++;
1226                 }
1227             }
1228
1229             if (cp != start) {
1230                 /*
1231                  * Stuff left over -- add it to the list too
1232                  */
1233                 gn = Targ_GetNode(start);
1234                 Lst_Append(members, gn);
1235             }
1236             /*
1237              * Point cp back at the beginning again so the variable value
1238              * can be freed.
1239              */
1240             cp = initcp;
1241         }
1242
1243         /*
1244          * Add all elements of the members list to the parent node.
1245          */
1246         while(!Lst_IsEmpty(members)) {
1247             gn = Lst_Dequeue(members);
1248
1249             SUFF_DEBUG1("%s...", gn->name);
1250             /* Add gn to the parents child list before the original child */
1251             Lst_InsertBefore(pgn->children, cln, gn);
1252             Lst_Append(gn->parents, pgn);
1253             pgn->unmade++;
1254             /* Expand wildcards on new node */
1255             SuffExpandWildcards(cln->prev, pgn);
1256         }
1257         Lst_Free(members);
1258
1259         /*
1260          * Free the result
1261          */
1262         free(cp);
1263     }
1264
1265     SUFF_DEBUG0("\n");
1266
1267     /*
1268      * Now the source is expanded, remove it from the list of children to
1269      * keep it from being processed.
1270      */
1271     pgn->unmade--;
1272     Lst_Remove(pgn->children, cln);
1273     Lst_Remove(cgn->parents, Lst_FindDatum(cgn->parents, pgn));
1274 }
1275
1276 static void
1277 SuffExpandWildcards(GNodeListNode *cln, GNode *pgn)
1278 {
1279     GNode *cgn = cln->datum;
1280     StringList *explist;
1281
1282     if (!Dir_HasWildcards(cgn->name))
1283         return;
1284
1285     /*
1286      * Expand the word along the chosen path
1287      */
1288     explist = Lst_New();
1289     Dir_Expand(cgn->name, Suff_FindPath(cgn), explist);
1290
1291     while (!Lst_IsEmpty(explist)) {
1292         GNode   *gn;
1293         /*
1294          * Fetch next expansion off the list and find its GNode
1295          */
1296         char *cp = Lst_Dequeue(explist);
1297
1298         SUFF_DEBUG1("%s...", cp);
1299         gn = Targ_GetNode(cp);
1300
1301         /* Add gn to the parents child list before the original child */
1302         Lst_InsertBefore(pgn->children, cln, gn);
1303         Lst_Append(gn->parents, pgn);
1304         pgn->unmade++;
1305     }
1306
1307     Lst_Free(explist);
1308
1309     SUFF_DEBUG0("\n");
1310
1311     /*
1312      * Now the source is expanded, remove it from the list of children to
1313      * keep it from being processed.
1314      */
1315     pgn->unmade--;
1316     Lst_Remove(pgn->children, cln);
1317     Lst_Remove(cgn->parents, Lst_FindDatum(cgn->parents, pgn));
1318 }
1319
1320 /* Find a path along which to expand the node.
1321  *
1322  * If the word has a known suffix, use that path.
1323  * If it has no known suffix, use the default system search path.
1324  *
1325  * Input:
1326  *      gn              Node being examined
1327  *
1328  * Results:
1329  *      The appropriate path to search for the GNode.
1330  */
1331 SearchPath *
1332 Suff_FindPath(GNode* gn)
1333 {
1334     Suff *suff = gn->suffix;
1335
1336     if (suff == NULL) {
1337         char *name = gn->name;
1338         size_t nameLen = strlen(gn->name);
1339         SuffListNode *ln;
1340         for (ln = sufflist->first; ln != NULL; ln = ln->next)
1341             if (SuffSuffIsSuffix(ln->datum, nameLen, name + nameLen))
1342                 break;
1343
1344         SUFF_DEBUG1("Wildcard expanding \"%s\"...", gn->name);
1345         if (ln != NULL)
1346             suff = ln->datum;
1347         /* XXX: Here we can save the suffix so we don't have to do this again */
1348     }
1349
1350     if (suff != NULL) {
1351         SUFF_DEBUG1("suffix is \"%s\"...\n", suff->name);
1352         return suff->searchPath;
1353     } else {
1354         SUFF_DEBUG0("\n");
1355         return dirSearchPath;   /* Use default search path */
1356     }
1357 }
1358
1359 /* Apply a transformation rule, given the source and target nodes and
1360  * suffixes.
1361  *
1362  * Input:
1363  *      tGn             Target node
1364  *      sGn             Source node
1365  *      t               Target suffix
1366  *      s               Source suffix
1367  *
1368  * Results:
1369  *      TRUE if successful, FALSE if not.
1370  *
1371  * Side Effects:
1372  *      The source and target are linked and the commands from the
1373  *      transformation are added to the target node's commands list.
1374  *      All attributes but OP_DEPMASK and OP_TRANSFORM are applied
1375  *      to the target. The target also inherits all the sources for
1376  *      the transformation rule.
1377  */
1378 static Boolean
1379 SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s)
1380 {
1381     GNodeListNode *ln, *nln;    /* General node */
1382     char *tname;                /* Name of transformation rule */
1383     GNode *gn;                  /* Node for same */
1384
1385     /*
1386      * Form the proper links between the target and source.
1387      */
1388     Lst_Append(tGn->children, sGn);
1389     Lst_Append(sGn->parents, tGn);
1390     tGn->unmade++;
1391
1392     /*
1393      * Locate the transformation rule itself
1394      */
1395     tname = str_concat2(s->name, t->name);
1396     gn = FindTransformByName(tname);
1397     free(tname);
1398
1399     if (gn == NULL) {
1400         /*
1401          * Not really such a transformation rule (can happen when we're
1402          * called to link an OP_MEMBER and OP_ARCHV node), so return
1403          * FALSE.
1404          */
1405         return FALSE;
1406     }
1407
1408     SUFF_DEBUG3("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name);
1409
1410     /*
1411      * Record last child for expansion purposes
1412      */
1413     ln = tGn->children->last;
1414
1415     /*
1416      * Pass the buck to Make_HandleUse to apply the rule
1417      */
1418     (void)Make_HandleUse(gn, tGn);
1419
1420     /*
1421      * Deal with wildcards and variables in any acquired sources
1422      */
1423     for (ln = ln != NULL ? ln->next : NULL; ln != NULL; ln = nln) {
1424         nln = ln->next;
1425         SuffExpandChildren(ln, tGn);
1426     }
1427
1428     /*
1429      * Keep track of another parent to which this beast is transformed so
1430      * the .IMPSRC variable can be set correctly for the parent.
1431      */
1432     Lst_Append(sGn->implicitParents, tGn);
1433
1434     return TRUE;
1435 }
1436
1437
1438 /* Locate dependencies for an OP_ARCHV node.
1439  *
1440  * Input:
1441  *      gn              Node for which to locate dependencies
1442  *
1443  * Side Effects:
1444  *      Same as Suff_FindDeps
1445  */
1446 static void
1447 SuffFindArchiveDeps(GNode *gn, SrcList *slst)
1448 {
1449     char *eoarch;               /* End of archive portion */
1450     char *eoname;               /* End of member portion */
1451     GNode *mem;                 /* Node for member */
1452     SuffListNode *ln, *nln;     /* Next suffix node to check */
1453     Suff *ms;                   /* Suffix descriptor for member */
1454     char *name;                 /* Start of member's name */
1455
1456     /*
1457      * The node is an archive(member) pair. so we must find a
1458      * suffix for both of them.
1459      */
1460     eoarch = strchr(gn->name, '(');
1461     eoname = strchr(eoarch, ')');
1462
1463     /*
1464      * Caller guarantees the format `libname(member)', via
1465      * Arch_ParseArchive.
1466      */
1467     assert(eoarch != NULL);
1468     assert(eoname != NULL);
1469
1470     *eoname = '\0';       /* Nuke parentheses during suffix search */
1471     *eoarch = '\0';       /* So a suffix can be found */
1472
1473     name = eoarch + 1;
1474
1475     /*
1476      * To simplify things, call Suff_FindDeps recursively on the member now,
1477      * so we can simply compare the member's .PREFIX and .TARGET variables
1478      * to locate its suffix. This allows us to figure out the suffix to
1479      * use for the archive without having to do a quadratic search over the
1480      * suffix list, backtracking for each one...
1481      */
1482     mem = Targ_GetNode(name);
1483     SuffFindDeps(mem, slst);
1484
1485     /*
1486      * Create the link between the two nodes right off
1487      */
1488     Lst_Append(gn->children, mem);
1489     Lst_Append(mem->parents, gn);
1490     gn->unmade++;
1491
1492     /*
1493      * Copy in the variables from the member node to this one.
1494      */
1495     Var_Set(PREFIX, GNode_VarPrefix(mem), gn);
1496     Var_Set(TARGET, GNode_VarTarget(mem), gn);
1497
1498     ms = mem->suffix;
1499     if (ms == NULL) {
1500         /*
1501          * Didn't know what it was -- use .NULL suffix if not in make mode
1502          */
1503         SUFF_DEBUG0("using null suffix\n");
1504         ms = suffNull;
1505     }
1506
1507
1508     /*
1509      * Set the other two local variables required for this target.
1510      */
1511     Var_Set(MEMBER, name, gn);
1512     Var_Set(ARCHIVE, gn->name, gn);
1513
1514     /*
1515      * Set $@ for compatibility with other makes
1516      */
1517     Var_Set(TARGET, gn->name, gn);
1518
1519     /*
1520      * Now we've got the important local variables set, expand any sources
1521      * that still contain variables or wildcards in their names.
1522      */
1523     for (ln = gn->children->first; ln != NULL; ln = nln) {
1524         nln = ln->next;
1525         SuffExpandChildren(ln, gn);
1526     }
1527
1528     if (ms != NULL) {
1529         /*
1530          * Member has a known suffix, so look for a transformation rule from
1531          * it to a possible suffix of the archive. Rather than searching
1532          * through the entire list, we just look at suffixes to which the
1533          * member's suffix may be transformed...
1534          */
1535         size_t nameLen = (size_t)(eoarch - gn->name);
1536
1537         /* Use first matching suffix... */
1538         for (ln = ms->parents->first; ln != NULL; ln = ln->next)
1539             if (SuffSuffIsSuffix(ln->datum, nameLen, eoarch))
1540                 break;
1541
1542         if (ln != NULL) {
1543             /*
1544              * Got one -- apply it
1545              */
1546             Suff *suff = ln->datum;
1547             if (!SuffApplyTransform(gn, mem, suff, ms)) {
1548                 SUFF_DEBUG2("\tNo transformation from %s -> %s\n",
1549                             ms->name, suff->name);
1550             }
1551         }
1552     }
1553
1554     /*
1555      * Replace the opening and closing parens now we've no need of the separate
1556      * pieces.
1557      */
1558     *eoarch = '('; *eoname = ')';
1559
1560     /*
1561      * Pretend gn appeared to the left of a dependency operator so
1562      * the user needn't provide a transformation from the member to the
1563      * archive.
1564      */
1565     if (!GNode_IsTarget(gn)) {
1566         gn->type |= OP_DEPENDS;
1567     }
1568
1569     /*
1570      * Flag the member as such so we remember to look in the archive for
1571      * its modification time. The OP_JOIN | OP_MADE is needed because this
1572      * target should never get made.
1573      */
1574     mem->type |= OP_MEMBER | OP_JOIN | OP_MADE;
1575 }
1576
1577 static void
1578 SuffFindNormalDepsKnown(const char *name, size_t nameLen, GNode *gn,
1579                         SrcList *srcs, SrcList *targs)
1580 {
1581     SuffListNode *ln;
1582     Src *targ;
1583     char *pref;
1584
1585     for (ln = sufflist->first; ln != NULL; ln = ln->next) {
1586         Suff *suff = ln->datum;
1587         if (!SuffSuffIsSuffix(suff, nameLen, name + nameLen))
1588             continue;
1589
1590         pref = bmake_strldup(name, (size_t)(nameLen - suff->nameLen));
1591         targ = SrcNew(bmake_strdup(gn->name), pref, suff, NULL, gn);
1592         suff->refCount++;
1593
1594         /*
1595          * Add nodes from which the target can be made
1596          */
1597         SuffAddLevel(srcs, targ);
1598
1599         /*
1600          * Record the target so we can nuke it
1601          */
1602         Lst_Append(targs, targ);
1603     }
1604 }
1605
1606 static void
1607 SuffFindNormalDepsUnknown(GNode *gn, const char *sopref,
1608                           SrcList *srcs, SrcList *targs)
1609 {
1610     Src *targ;
1611
1612     if (!Lst_IsEmpty(targs) || suffNull == NULL)
1613         return;
1614
1615     SUFF_DEBUG1("\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
1616
1617     targ = SrcNew(bmake_strdup(gn->name), bmake_strdup(sopref),
1618                   suffNull, NULL, gn);
1619     targ->suff->refCount++;
1620
1621     /*
1622      * Only use the default suffix rules if we don't have commands
1623      * defined for this gnode; traditional make programs used to
1624      * not define suffix rules if the gnode had children but we
1625      * don't do this anymore.
1626      */
1627     if (Lst_IsEmpty(gn->commands))
1628         SuffAddLevel(srcs, targ);
1629     else {
1630         SUFF_DEBUG0("not ");
1631     }
1632
1633     SUFF_DEBUG0("adding suffix rules\n");
1634
1635     Lst_Append(targs, targ);
1636 }
1637
1638 /*
1639  * Deal with finding the thing on the default search path. We
1640  * always do that, not only if the node is only a source (not
1641  * on the lhs of a dependency operator or [XXX] it has neither
1642  * children or commands) as the old pmake did.
1643  */
1644 static void
1645 SuffFindNormalDepsPath(GNode *gn, Src *targ)
1646 {
1647     if (gn->type & (OP_PHONY | OP_NOPATH))
1648         return;
1649
1650     free(gn->path);
1651     gn->path = Dir_FindFile(gn->name,
1652                             (targ == NULL ? dirSearchPath :
1653                              targ->suff->searchPath));
1654     if (gn->path == NULL)
1655         return;
1656
1657     Var_Set(TARGET, gn->path, gn);
1658
1659     if (targ != NULL) {
1660         /*
1661          * Suffix known for the thing -- trim the suffix off
1662          * the path to form the proper .PREFIX variable.
1663          */
1664         size_t savep = strlen(gn->path) - targ->suff->nameLen;
1665         char savec;
1666         char *ptr;
1667
1668         if (gn->suffix)
1669             gn->suffix->refCount--;
1670         gn->suffix = targ->suff;
1671         gn->suffix->refCount++;
1672
1673         savec = gn->path[savep];
1674         gn->path[savep] = '\0';
1675
1676         if ((ptr = strrchr(gn->path, '/')) != NULL)
1677             ptr++;
1678         else
1679             ptr = gn->path;
1680
1681         Var_Set(PREFIX, ptr, gn);
1682
1683         gn->path[savep] = savec;
1684     } else {
1685         char *ptr;
1686
1687         /* The .PREFIX gets the full path if the target has no known suffix. */
1688         if (gn->suffix)
1689             gn->suffix->refCount--;
1690         gn->suffix = NULL;
1691
1692         if ((ptr = strrchr(gn->path, '/')) != NULL)
1693             ptr++;
1694         else
1695             ptr = gn->path;
1696
1697         Var_Set(PREFIX, ptr, gn);
1698     }
1699 }
1700
1701 /* Locate implicit dependencies for regular targets.
1702  *
1703  * Input:
1704  *      gn              Node for which to find sources
1705  *
1706  * Side Effects:
1707  *      Same as Suff_FindDeps
1708  */
1709 static void
1710 SuffFindNormalDeps(GNode *gn, SrcList *slst)
1711 {
1712     SrcList *srcs;              /* List of sources at which to look */
1713     SrcList *targs;             /* List of targets to which things can be
1714                                  * transformed. They all have the same file,
1715                                  * but different suff and pref fields */
1716     Src *bottom;                /* Start of found transformation path */
1717     Src *src;                   /* General Src pointer */
1718     char *pref;                 /* Prefix to use */
1719     Src *targ;                  /* General Src target pointer */
1720
1721     const char *name = gn->name;
1722     size_t nameLen = strlen(name);
1723
1724     /*
1725      * Begin at the beginning...
1726      */
1727     srcs = Lst_New();
1728     targs = Lst_New();
1729
1730     /*
1731      * We're caught in a catch-22 here. On the one hand, we want to use any
1732      * transformation implied by the target's sources, but we can't examine
1733      * the sources until we've expanded any variables/wildcards they may hold,
1734      * and we can't do that until we've set up the target's local variables
1735      * and we can't do that until we know what the proper suffix for the
1736      * target is (in case there are two suffixes one of which is a suffix of
1737      * the other) and we can't know that until we've found its implied
1738      * source, which we may not want to use if there's an existing source
1739      * that implies a different transformation.
1740      *
1741      * In an attempt to get around this, which may not work all the time,
1742      * but should work most of the time, we look for implied sources first,
1743      * checking transformations to all possible suffixes of the target,
1744      * use what we find to set the target's local variables, expand the
1745      * children, then look for any overriding transformations they imply.
1746      * Should we find one, we discard the one we found before.
1747      */
1748     bottom = NULL;
1749     targ = NULL;
1750
1751     if (!(gn->type & OP_PHONY)) {
1752
1753         SuffFindNormalDepsKnown(name, nameLen, gn, srcs, targs);
1754
1755         /* Handle target of unknown suffix... */
1756         SuffFindNormalDepsUnknown(gn, name, srcs, targs);
1757
1758         /*
1759          * Using the list of possible sources built up from the target
1760          * suffix(es), try and find an existing file/target that matches.
1761          */
1762         bottom = SuffFindThem(srcs, slst);
1763
1764         if (bottom == NULL) {
1765             /*
1766              * No known transformations -- use the first suffix found
1767              * for setting the local variables.
1768              */
1769             if (!Lst_IsEmpty(targs)) {
1770                 targ = targs->first->datum;
1771             } else {
1772                 targ = NULL;
1773             }
1774         } else {
1775             /*
1776              * Work up the transformation path to find the suffix of the
1777              * target to which the transformation was made.
1778              */
1779             for (targ = bottom; targ->parent != NULL; targ = targ->parent)
1780                 continue;
1781         }
1782     }
1783
1784     Var_Set(TARGET, GNode_Path(gn), gn);
1785
1786     pref = (targ != NULL) ? targ->pref : gn->name;
1787     Var_Set(PREFIX, pref, gn);
1788
1789     /*
1790      * Now we've got the important local variables set, expand any sources
1791      * that still contain variables or wildcards in their names.
1792      */
1793     {
1794         SuffListNode *ln, *nln;
1795         for (ln = gn->children->first; ln != NULL; ln = nln) {
1796             nln = ln->next;
1797             SuffExpandChildren(ln, gn);
1798         }
1799     }
1800
1801     if (targ == NULL) {
1802         SUFF_DEBUG1("\tNo valid suffix on %s\n", gn->name);
1803
1804 sfnd_abort:
1805         SuffFindNormalDepsPath(gn, targ);
1806         goto sfnd_return;
1807     }
1808
1809     /*
1810      * If the suffix indicates that the target is a library, mark that in
1811      * the node's type field.
1812      */
1813     if (targ->suff->flags & SUFF_LIBRARY) {
1814         gn->type |= OP_LIB;
1815     }
1816
1817     /*
1818      * Check for overriding transformation rule implied by sources
1819      */
1820     if (!Lst_IsEmpty(gn->children)) {
1821         src = SuffFindCmds(targ, slst);
1822
1823         if (src != NULL) {
1824             /*
1825              * Free up all the Src structures in the transformation path
1826              * up to, but not including, the parent node.
1827              */
1828             while (bottom && bottom->parent != NULL) {
1829                 if (Lst_FindDatum(slst, bottom) == NULL) {
1830                     Lst_Append(slst, bottom);
1831                 }
1832                 bottom = bottom->parent;
1833             }
1834             bottom = src;
1835         }
1836     }
1837
1838     if (bottom == NULL) {
1839         /*
1840          * No idea from where it can come -- return now.
1841          */
1842         goto sfnd_abort;
1843     }
1844
1845     /*
1846      * We now have a list of Src structures headed by 'bottom' and linked via
1847      * their 'parent' pointers. What we do next is create links between
1848      * source and target nodes (which may or may not have been created)
1849      * and set the necessary local variables in each target. The
1850      * commands for each target are set from the commands of the
1851      * transformation rule used to get from the src suffix to the targ
1852      * suffix. Note that this causes the commands list of the original
1853      * node, gn, to be replaced by the commands of the final
1854      * transformation rule. Also, the unmade field of gn is incremented.
1855      * Etc.
1856      */
1857     if (bottom->node == NULL) {
1858         bottom->node = Targ_GetNode(bottom->file);
1859     }
1860
1861     for (src = bottom; src->parent != NULL; src = src->parent) {
1862         targ = src->parent;
1863
1864         if (src->node->suffix)
1865             src->node->suffix->refCount--;
1866         src->node->suffix = src->suff;
1867         src->node->suffix->refCount++;
1868
1869         if (targ->node == NULL) {
1870             targ->node = Targ_GetNode(targ->file);
1871         }
1872
1873         SuffApplyTransform(targ->node, src->node,
1874                            targ->suff, src->suff);
1875
1876         if (targ->node != gn) {
1877             /*
1878              * Finish off the dependency-search process for any nodes
1879              * between bottom and gn (no point in questing around the
1880              * filesystem for their implicit source when it's already
1881              * known). Note that the node can't have any sources that
1882              * need expanding, since SuffFindThem will stop on an existing
1883              * node, so all we need to do is set the standard and System V
1884              * variables.
1885              */
1886             targ->node->type |= OP_DEPS_FOUND;
1887
1888             Var_Set(PREFIX, targ->pref, targ->node);
1889
1890             Var_Set(TARGET, targ->node->name, targ->node);
1891         }
1892     }
1893
1894     if (gn->suffix)
1895         gn->suffix->refCount--;
1896     gn->suffix = src->suff;
1897     gn->suffix->refCount++;
1898
1899     /*
1900      * Nuke the transformation path and the Src structures left over in the
1901      * two lists.
1902      */
1903 sfnd_return:
1904     if (bottom)
1905         if (Lst_FindDatum(slst, bottom) == NULL)
1906             Lst_Append(slst, bottom);
1907
1908     while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs))
1909         continue;
1910
1911     Lst_MoveAll(slst, srcs);
1912     Lst_MoveAll(slst, targs);
1913 }
1914
1915
1916 /* Find implicit sources for the target described by the graph node.
1917  *
1918  * Nodes are added to the graph below the passed-in node. The nodes are
1919  * marked to have their IMPSRC variable filled in. The PREFIX variable is set
1920  * for the given node and all its implied children.
1921  *
1922  * The path found by this target is the shortest path in the transformation
1923  * graph, which may pass through non-existent targets, to an existing target.
1924  * The search continues on all paths from the root suffix until a file is
1925  * found. I.e. if there's a path .o -> .c -> .l -> .l,v from the root and the
1926  * .l,v file exists but the .c and .l files don't, the search will branch out
1927  * in all directions from .o and again from all the nodes on the next level
1928  * until the .l,v node is encountered.
1929  */
1930 void
1931 Suff_FindDeps(GNode *gn)
1932 {
1933
1934     SuffFindDeps(gn, srclist);
1935     while (SuffRemoveSrc(srclist))
1936         continue;
1937 }
1938
1939 static void
1940 SuffFindDeps(GNode *gn, SrcList *slst)
1941 {
1942     if (gn->type & OP_DEPS_FOUND)
1943         return;
1944     gn->type |= OP_DEPS_FOUND;
1945
1946     /*
1947      * Make sure we have these set, may get revised below.
1948      */
1949     Var_Set(TARGET, GNode_Path(gn), gn);
1950     Var_Set(PREFIX, gn->name, gn);
1951
1952     SUFF_DEBUG1("SuffFindDeps (%s)\n", gn->name);
1953
1954     if (gn->type & OP_ARCHV) {
1955         SuffFindArchiveDeps(gn, slst);
1956     } else if (gn->type & OP_LIB) {
1957         /*
1958          * If the node is a library, it is the arch module's job to find it
1959          * and set the TARGET variable accordingly. We merely provide the
1960          * search path, assuming all libraries end in ".a" (if the suffix
1961          * hasn't been defined, there's nothing we can do for it, so we just
1962          * set the TARGET variable to the node's name in order to give it a
1963          * value).
1964          */
1965         Suff *s = FindSuffByName(LIBSUFF);
1966         if (gn->suffix)
1967             gn->suffix->refCount--;
1968         if (s != NULL) {
1969             gn->suffix = s;
1970             gn->suffix->refCount++;
1971             Arch_FindLib(gn, s->searchPath);
1972         } else {
1973             gn->suffix = NULL;
1974             Var_Set(TARGET, gn->name, gn);
1975         }
1976         /*
1977          * Because a library (-lfoo) target doesn't follow the standard
1978          * filesystem conventions, we don't set the regular variables for
1979          * the thing. .PREFIX is simply made empty...
1980          */
1981         Var_Set(PREFIX, "", gn);
1982     } else {
1983         SuffFindNormalDeps(gn, slst);
1984     }
1985 }
1986
1987 /* Define which suffix is the null suffix.
1988  *
1989  * Need to handle the changing of the null suffix gracefully so the old
1990  * transformation rules don't just go away.
1991  *
1992  * Input:
1993  *      name            Name of null suffix
1994  */
1995 void
1996 Suff_SetNull(const char *name)
1997 {
1998     Suff *s = FindSuffByName(name);
1999     if (s == NULL) {
2000         Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.",
2001                     name);
2002         return;
2003     }
2004
2005     if (suffNull != NULL) {
2006         suffNull->flags &= ~(unsigned)SUFF_NULL;
2007     }
2008     s->flags |= SUFF_NULL;
2009     /*
2010      * XXX: Here's where the transformation mangling would take place
2011      */
2012     suffNull = s;
2013 }
2014
2015 /* Initialize the suffixes module. */
2016 void
2017 Suff_Init(void)
2018 {
2019 #ifdef CLEANUP
2020     suffClean = Lst_New();
2021     sufflist = Lst_New();
2022 #endif
2023     srclist = Lst_New();
2024     transforms = Lst_New();
2025
2026     /*
2027      * Create null suffix for single-suffix rules (POSIX). The thing doesn't
2028      * actually go on the suffix list or everyone will think that's its
2029      * suffix.
2030      */
2031     Suff_ClearSuffixes();
2032 }
2033
2034
2035 /* Clean up the suffixes module. */
2036 void
2037 Suff_End(void)
2038 {
2039 #ifdef CLEANUP
2040     Lst_Destroy(sufflist, SuffFree);
2041     Lst_Destroy(suffClean, SuffFree);
2042     if (suffNull)
2043         SuffFree(suffNull);
2044     Lst_Free(srclist);
2045     Lst_Free(transforms);
2046 #endif
2047 }
2048
2049
2050 /********************* DEBUGGING FUNCTIONS **********************/
2051
2052 static void
2053 PrintSuffNames(const char *prefix, SuffList *suffs)
2054 {
2055     SuffListNode *ln;
2056
2057     debug_printf("#\t%s: ", prefix);
2058     for (ln = suffs->first; ln != NULL; ln = ln->next) {
2059         Suff *suff = ln->datum;
2060         debug_printf("%s ", suff->name);
2061     }
2062     debug_printf("\n");
2063 }
2064
2065 static void
2066 PrintSuff(Suff *s)
2067 {
2068     debug_printf("# \"%s\" (num %d, ref %d)", s->name, s->sNum, s->refCount);
2069     if (s->flags != 0) {
2070         char flags_buf[SuffFlags_ToStringSize];
2071
2072         debug_printf(" (%s)",
2073                      Enum_FlagsToString(flags_buf, sizeof flags_buf,
2074                                         s->flags, SuffFlags_ToStringSpecs));
2075     }
2076     debug_printf("\n");
2077
2078     PrintSuffNames("To", s->parents);
2079     PrintSuffNames("From", s->children);
2080
2081     debug_printf("#\tSearch Path: ");
2082     Dir_PrintPath(s->searchPath);
2083     debug_printf("\n");
2084 }
2085
2086 static void
2087 PrintTransformation(GNode *t)
2088 {
2089     debug_printf("%-16s:", t->name);
2090     Targ_PrintType(t->type);
2091     debug_printf("\n");
2092     Targ_PrintCmds(t);
2093     debug_printf("\n");
2094 }
2095
2096 void
2097 Suff_PrintAll(void)
2098 {
2099     debug_printf("#*** Suffixes:\n");
2100     {
2101         SuffListNode *ln;
2102         for (ln = sufflist->first; ln != NULL; ln = ln->next)
2103             PrintSuff(ln->datum);
2104     }
2105
2106     debug_printf("#*** Transformations:\n");
2107     {
2108         GNodeListNode *ln;
2109         for (ln = transforms->first; ln != NULL; ln = ln->next)
2110             PrintTransformation(ln->datum);
2111     }
2112 }