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