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