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