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