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