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