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