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