xref: /openbsd-src/usr.bin/make/suff.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: suff.c,v 1.79 2010/07/19 19:46:44 espie Exp $ */
2 /*	$NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $	*/
3 
4 /*
5  * Copyright (c) 1988, 1989, 1990, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  * Copyright (c) 1989 by Berkeley Softworks
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * Adam de Boor.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 /*-
39  * suff.c --
40  *	Functions to maintain suffix lists and find implicit dependents
41  *	using suffix transformation rules
42  *
43  * Interface:
44  *	Suff_Init		Initialize all things to do with suffixes.
45  *
46  *	Suff_End		Cleanup the module
47  *
48  *	Suff_ClearSuffixes	Clear out all the suffixes and defined
49  *				transformations.
50  *
51  *	Suff_AddSuffix		Add the passed string as another known suffix.
52  *
53  *	Suff_GetPath		Return the search path for the given suffix.
54  *
55  *	Suff_AddInclude 	Mark the given suffix as denoting an include
56  *				file.
57  *
58  *	Suff_AddLib		Mark the given suffix as denoting a library.
59  *
60  *	Suff_ParseAsTransform	Line might be a suffix line, check it.
61  *				If it's not, return NULL. Otherwise, add
62  *				another transformation to the suffix graph.
63  *				Returns	GNode suitable for framing, I mean,
64  *				tacking commands, attributes, etc. on.
65  *
66  *	Suff_SetNull		Define the suffix to consider the suffix of
67  *				any file that doesn't have a known one.
68  *
69  *	Suff_FindDeps		Find implicit sources for and the location of
70  *				a target based on its suffix. Returns the
71  *				bottom-most node added to the graph or NULL
72  *				if the target had no implicit sources.
73  */
74 
75 #include <ctype.h>
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <stdint.h>
79 #include <stddef.h>
80 #include <string.h>
81 #include <signal.h>
82 #include <ohash.h>
83 #include "config.h"
84 #include "defines.h"
85 #include "dir.h"
86 #include "direxpand.h"
87 #include "engine.h"
88 #include "arch.h"
89 #include "suff.h"
90 #include "var.h"
91 #include "targ.h"
92 #include "error.h"
93 #include "str.h"
94 #include "lst.h"
95 #include "memory.h"
96 #include "gnode.h"
97 #include "make.h"
98 #include "stats.h"
99 
100 /* XXX the suffixes hash is stored using a specific hash function, suitable
101  * for looking up suffixes in reverse.
102  */
103 static struct ohash suffixes;
104 
105 /* We remember the longest suffix, so we don't need to look beyond that.  */
106 size_t maxLen;
107 static LIST srclist;
108 
109 /* Transforms (.c.o) are stored in another hash, independently from suffixes.
110  * When make sees a target, it checks whether it's currently parsable as a
111  * transform (according to the active suffixes). If yes, it's stored as a
112  * new transform.
113  *
114  * XXX
115  * But transforms DO NOT have a canonical decomposition as a set of suffixes,
116  * and will be used as necessary later, when looking up implicit rules for
117  * actual targets.
118  *
119  * For instance, a transform .a.b.c  can be parsed as .a -> .b.c if suffixes
120  * .a and .b.c are active, and then LATER, reused as .a.b -> .c if suffixes
121  * .a.b and .c are active.
122  */
123 static struct ohash transforms;
124 
125 /* conflicts between suffixes are solved by suffix declaration order. */
126 static int order = 0;
127 
128 /*
129  * Structure describing an individual suffix.
130  */
131 typedef struct Suff_ {
132 	size_t nameLen;		/* optimisation: strlen(name) */
133 	short flags;
134 #define SUFF_INCLUDE	  0x01	/* suffix marked with .INCLUDES keyword */
135 #define SUFF_LIBRARY	  0x02	/* suffix marked with .LIBS keyword */
136 #define SUFF_NULL	  0x04	/* The empty suffix (normally '', */
137 				/* but see .EMPTY keyword) */
138 #define SUFF_ACTIVE	  0x08	/* We never destroy suffixes and rules, */
139 				/* we just deactivate them. */
140 #define SUFF_PATH	  0x10	/* False suffix: actually, the path keyword */
141 	LIST searchPath;	/* The path along which files of this suffix
142 			     	 * may be found */
143 	int order;		/* order of declaration for conflict
144 				 * resolution. */
145 	LIST parents;		/* List of Suff we have a transformation to */
146 	LIST children;		/* List of Suff we have a transformation from */
147 	char name[1];
148 } Suff;
149 
150 static struct ohash_info suff_info = {
151 	offsetof(struct Suff_, name), NULL,
152 	hash_alloc, hash_free, element_alloc
153 };
154 
155 /*
156  * Structure used in the search for implied sources.
157  */
158 typedef struct Src_ {
159 	char *file;		/* The file to look for */
160 	char *pref;		/* Prefix from which file was formed */
161 	Suff *suff;		/* The suffix on the file */
162 	struct Src_ *parent;	/* The Src for which this is a source */
163 	GNode *node;		/* The node describing the file */
164 	int children;		/* Count of existing children (so we don't free
165 				 * this thing too early or never nuke it) */
166 #ifdef DEBUG_SRC
167 	LIST	    cp; 	/* Debug; children list */
168 #endif
169 } Src;
170 
171 /*
172  * A structure for passing more than one argument to the Lst-library-invoked
173  * function...
174  */
175 typedef struct {
176 	Lst l;
177 	Src *s;
178 } LstSrc;
179 
180 static Suff *suffNull;	/* The NULL suffix for this run */
181 static Suff *emptySuff; /* The empty suffix required for POSIX
182 			 * single-suffix transformation rules */
183 
184 
185 static void build_path_variable(struct ohash *, int, const char *, const char *);
186 static void add_property(const char *, const char *, int);
187 #define parse_transform(s, p, q) parse_transformi(s, s + strlen(s), p, q)
188 static bool parse_transformi(const char *, const char *, Suff **, Suff **);
189 #define new_suffix(s)	new_suffixi(s, NULL)
190 static Suff *new_suffixi(const char *, const char *);
191 static void reverse_hash_add_char(uint32_t *, const char *);
192 static uint32_t reverse_hashi(const char *, const char **);
193 static unsigned int reverse_slot(struct ohash *, const char *, const char **);
194 static void clear_suffixes(void);
195 static void record_possible_suffix(Suff *, GNode *, char *, Lst, Lst);
196 static void record_possible_suffixes(GNode *, Lst, Lst);
197 static Suff *find_suffix_as_suffix(Lst, const char *, const char *);
198 static Suff *add_suffixi(const char *, const char *);
199 
200 #ifdef CLEANUP
201 static void SuffFree(void *);
202 #endif
203 static void SuffInsert(Lst, Suff *);
204 static void SuffAddSrc(void *, void *);
205 static int SuffRemoveSrc(Lst);
206 static void SuffAddLevel(Lst, Src *);
207 static Src *SuffFindThem(Lst, Lst);
208 static Src *SuffFindCmds(Src *, Lst);
209 static void SuffExpandChildren(LstNode, GNode *);
210 static void SuffExpandVarChildren(LstNode, GNode *, GNode *);
211 static void SuffExpandWildChildren(LstNode, GNode *, GNode *);
212 static bool SuffApplyTransform(GNode *, GNode *, Suff *, Suff *);
213 static void SuffFindDeps(GNode *, Lst);
214 static void SuffFindArchiveDeps(GNode *, Lst);
215 static void SuffFindNormalDeps(GNode *, Lst);
216 static void SuffPrintName(void *);
217 static void SuffPrintSuff(void *);
218 static void SuffPrintTrans(GNode *);
219 
220 #define find_suff(name)	find_suffi(name, NULL)
221 static Suff *find_suffi(const char *, const char *);
222 static Suff *find_best_suffix(const char *, const char *);
223 static GNode *find_transform(const char *);
224 static GNode *find_or_create_transformi(const char *, const char *);
225 static void setup_paths(void);
226 static void build_suffixes_graph(void);
227 static void special_path_hack(void);
228 
229 #ifdef DEBUG_SRC
230 static void PrintAddr(void *);
231 #endif
232 
233 /* hash functions for the suffixes hash */
234 /* add one char to the hash */
235 static void
236 reverse_hash_add_char(uint32_t *pk, const char *s)
237 {
238 	*pk =  ((*pk << 2) | (*pk >> 30)) ^ *s;
239 }
240 
241 /* build a full hash from end to start */
242 static uint32_t
243 reverse_hashi(const char *s, const char **e)
244 {
245 	const char *p;
246 	uint32_t k;
247 
248 	if (*e == NULL)
249 		*e = s + strlen(s);
250 	p = *e;
251 	if (p == s)
252 		k = 0;
253 	else
254 		k = *--p;
255 	while (p != s) {
256 		reverse_hash_add_char(&k, --p);
257 	}
258 	return k;
259 }
260 
261 static unsigned int
262 reverse_slot(struct ohash *h, const char *s, const char **e)
263 {
264 	uint32_t hv;
265 
266 	hv = reverse_hashi(s, e);
267 	return ohash_lookup_interval(h, s, *e, hv);
268 }
269 
270 
271 static char *
272 suffix_is_suffix(Suff *s, const char *str, const char *estr)
273 {
274 	const char *p1; 	/* Pointer into suffix name */
275 	const char *p2; 	/* Pointer into string being examined */
276 
277 	if (estr - str < (ptrdiff_t) s->nameLen)
278 		return NULL;
279 	p1 = s->name + s->nameLen;
280 	p2 = estr;
281 
282 	while (p1 != s->name) {
283 		p1--;
284 		p2--;
285 		if (*p1 != *p2)
286 			return NULL;
287 	}
288 
289 	return (char *)p2;
290 }
291 
292 static Suff *
293 find_suffi(const char *name, const char *ename)
294 {
295 	unsigned int slot;
296 #ifdef STATS_SUFF
297 	STAT_SUFF_LOOKUP_NAME++;
298 #endif
299 	slot = reverse_slot(&suffixes, name, &ename);
300 	return ohash_find(&suffixes, slot);
301 }
302 
303 static GNode *
304 find_transform(const char *name)
305 {
306 	unsigned int slot;
307 
308 #ifdef STATS_SUFF
309 	STAT_TRANSFORM_LOOKUP_NAME++;
310 #endif
311 	slot = ohash_qlookup(&transforms, name);
312 
313 	return ohash_find(&transforms, slot);
314 }
315 
316 static GNode *
317 find_or_create_transformi(const char *name, const char *end)
318 {
319 	GNode *r;
320 	unsigned int slot;
321 
322 #ifdef STATS_SUFF
323 	STAT_TRANSFORM_LOOKUP_NAME++;
324 #endif
325 	slot = ohash_qlookupi(&transforms, name, &end);
326 
327 	r = ohash_find(&transforms, slot);
328 
329 	if (r == NULL) {
330 		r = Targ_NewGNi(name, end);
331 		ohash_insert(&transforms, slot, r);
332 	}
333 	return r;
334 }
335 
336 #ifdef CLEANUP
337 /*-
338  *-----------------------------------------------------------------------
339  * SuffFree  --
340  *	Free up all memory associated with the given suffix structure.
341  *
342  * Side Effects:
343  *	the suffix entry is detroyed
344  *-----------------------------------------------------------------------
345  */
346 static void
347 SuffFree(void *sp)
348 {
349 	Suff *s = (Suff *)sp;
350 
351 	if (s == emptySuff)
352 		emptySuff = NULL;
353 
354 	Lst_Destroy(&s->children, NOFREE);
355 	Lst_Destroy(&s->parents, NOFREE);
356 	Lst_Destroy(&s->searchPath, Dir_Destroy);
357 
358 	free(s->name);
359 	free(s);
360 }
361 #endif
362 
363 
364 /*-
365  *-----------------------------------------------------------------------
366  * SuffInsert  --
367  *	Insert the suffix into the list keeping the list ordered by suffix
368  *	numbers.
369  *
370  * Side Effects:
371  *	The reference count of the suffix is incremented
372  *-----------------------------------------------------------------------
373  */
374 static void
375 SuffInsert(Lst l, Suff *s)
376 {
377 	LstNode ln;		/* current element in l we're examining */
378 	Suff *s2 = NULL;	/* the suffix descriptor in this element */
379 
380 	for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) {
381 		s2 = (Suff *)Lst_Datum(ln);
382 		if (s2->order >= s->order)
383 			break;
384 	}
385 
386 	if (DEBUG(SUFF))
387 		printf("inserting %s(%d)...", s->name, s->order);
388 	if (ln == NULL) {
389 		if (DEBUG(SUFF))
390 			printf("at end of list\n");
391 		Lst_AtEnd(l, s);
392 	} else if (s2->order != s->order) {
393 		if (DEBUG(SUFF))
394 			printf("before %s(%d)\n", s2->name, s2->order);
395 		Lst_Insert(l, ln, s);
396 	} else if (DEBUG(SUFF)) {
397 		printf("already there\n");
398 	}
399 }
400 
401 /*-
402  *-----------------------------------------------------------------------
403  * Suff_ClearSuffixes --
404  *	Nuke the list of suffixes but keep all transformation
405  *	rules around.
406  *
407  * Side Effects:
408  *	Current suffixes are reset
409  *-----------------------------------------------------------------------
410  */
411 static void
412 clear_suffixes(void)
413 {
414 	unsigned int i;
415 	Suff *s;
416 
417 	for (s = ohash_first(&suffixes, &i); s != NULL;
418 	    s = ohash_next(&suffixes, &i))
419 		s->flags &= ~SUFF_ACTIVE;
420 
421 	order = 0;
422 	maxLen = 0;
423 	suffNull = emptySuff;
424 }
425 
426 void
427 Suff_ClearSuffixes(void)
428 {
429 	clear_suffixes();
430 }
431 
432 
433 /* okay = parse_transform(str, &src, &targ);
434  * 	try parsing a string as a transformation rule, returns true if
435  *	successful. Fills &src, &targ with the constituent suffixes.
436  * Special hack: source suffixes must exist OR be the special SUFF_PATH
437  * pseudo suffix (.PATH)
438  */
439 static bool
440 parse_transformi(const char *str, const char *e, Suff **srcPtr, Suff **targPtr)
441 {
442 	Suff *src, *target, *best_src, *best_target;
443 	const char *p;
444 
445 	size_t len;
446 	uint32_t hv;
447 	unsigned int slot;
448 
449 	/* empty string -> no suffix */
450 	if (e == str)
451 		return false;
452 
453 	len = e - str;
454 
455 	if (len > 2 * maxLen)
456 		return false;
457 
458 	p = e;
459 	best_src = best_target = NULL;
460 
461 	hv = *--p;
462 	while (p != str) {
463 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
464 		/* no double suffix in there */
465 		if (p - str <= (ptrdiff_t)maxLen) {
466 			target = ohash_find(&suffixes, slot);
467 			if (target != NULL && (target->flags & SUFF_ACTIVE)) {
468 				src = find_suffi(str, p);
469 				if (src != NULL &&
470 				    (src->flags & (SUFF_ACTIVE | SUFF_PATH))) {
471 				/* XXX even if we find a set of suffixes, we
472 				 * have to keep going to find the best one,
473 				 * namely, the one whose src appears first in
474 				 * .SUFFIXES
475 				 */
476 					if (best_src == NULL ||
477 					    src->order < best_src->order) {
478 						best_src = src;
479 						best_target = target;
480 					}
481 				}
482 			}
483 		}
484 		/* can't be a suffix anyways */
485 		if (e - p >= (ptrdiff_t)maxLen)
486 			break;
487 		reverse_hash_add_char(&hv, --p);
488 	}
489 
490 	if (p == str && best_src == NULL) {
491 		/* no double suffix transformation, resort to single suffix if
492 		 * we find one.  */
493 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
494 		src = ohash_find(&suffixes, slot);
495 		if (src != NULL && (src->flags & (SUFF_ACTIVE | SUFF_PATH))) {
496 			best_src = src;
497 			best_target = suffNull;
498 		}
499 	}
500 	if (best_src != NULL) {
501 		*srcPtr = best_src;
502 		*targPtr = best_target;
503 		return true;
504 	} else {
505 		return false;
506 	}
507 }
508 
509 static void
510 special_path_hack(void)
511 {
512 	Suff *path = add_suffixi(".PATH", NULL);
513 	path->flags |= SUFF_PATH;
514 }
515 
516 static Suff *
517 find_best_suffix(const char *s, const char *e)
518 {
519 	const char *p;
520 	uint32_t hv;
521 	unsigned int slot;
522 	Suff *best = NULL;
523 	Suff *suff;
524 
525 	if (e == s)
526 		return NULL;
527 	p = e;
528 	hv = *--p;
529 	while (p != s) {
530 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
531 		suff = ohash_find(&suffixes, slot);
532 		if (suff != NULL)
533 			if (best == NULL || suff->order < best->order)
534 				best = suff;
535 		if (e - p >= (ptrdiff_t)maxLen)
536 			break;
537 		reverse_hash_add_char(&hv, --p);
538 	}
539 	return best;
540 }
541 
542 /*-
543  *-----------------------------------------------------------------------
544  * Suff_ParseAsTransform --
545  *	Try parsing a target line as a transformation rule, depending on
546  *	existing suffixes.
547  *
548  *	Possibly create anew transform, or reset an existing one.
549  *-----------------------------------------------------------------------
550  */
551 GNode *
552 Suff_ParseAsTransform(const char *line, const char *end)
553 {
554 	GNode *gn;	/* GNode of transformation rule */
555 	Suff *s;	/* source suffix */
556 	Suff *t;	/* target suffix */
557 
558 	if (!parse_transformi(line, end, &s, &t))
559 		return NULL;
560 
561 	gn = find_or_create_transformi(line, end);
562 	/* In case the transform already exists, nuke old commands and children.
563 	 * Note we can't free them, since there might be stuff that references
564 	 * them elsewhere
565 	 */
566 	if (!Lst_IsEmpty(&gn->commands)) {
567 		Lst_Destroy(&gn->commands, NOFREE);
568 		Lst_Init(&gn->commands);
569 	}
570 	if (!Lst_IsEmpty(&gn->children)) {
571 		Lst_Destroy(&gn->children, NOFREE);
572 		Lst_Init(&gn->children);
573 	}
574 
575 	gn->type = OP_TRANSFORM;
576 	if (s->flags & SUFF_PATH) {
577 		gn->special = SPECIAL_PATH | SPECIAL_TARGET;
578 		gn->suffix = t;
579 	}
580 
581 	if (DEBUG(SUFF))
582 		printf("defining transformation from `%s' to `%s'\n",
583 		    s->name, t->name);
584 	return gn;
585 }
586 
587 static void
588 make_suffix_known(Suff *s)
589 {
590 	if ((s->flags & SUFF_ACTIVE) == 0) {
591 		s->order = order++;
592 		s->flags |= SUFF_ACTIVE;
593 		if (s->nameLen > maxLen)
594 			maxLen = s->nameLen;
595 	}
596 }
597 
598 static Suff *
599 new_suffixi(const char *str, const char *eptr)
600 {
601 	Suff *s;
602 
603 	s = ohash_create_entry(&suff_info, str, &eptr);
604 	s->nameLen = eptr - str;
605 	Lst_Init(&s->searchPath);
606 	Lst_Init(&s->children);
607 	Lst_Init(&s->parents);
608 	s->flags = 0;
609 	return s;
610 }
611 
612 /*-
613  *-----------------------------------------------------------------------
614  * Suff_AddSuffix --
615  *	Add the suffix in string to the end of the list of known suffixes.
616  *	Should we restructure the suffix graph? Make doesn't...
617  *
618  * Side Effects:
619  *	A GNode is created for the suffix and a Suff structure is created and
620  *	added to the known suffixes, unless it was already known.
621  *-----------------------------------------------------------------------
622  */
623 void
624 Suff_AddSuffixi(const char *str, const char *end)
625 {
626 	(void)add_suffixi(str, end);
627 }
628 
629 static Suff *
630 add_suffixi(const char *str, const char *end)
631 {
632 	Suff *s;	    /* new suffix descriptor */
633 
634 	unsigned int slot;
635 
636 	slot = reverse_slot(&suffixes, str, &end);
637 	s = ohash_find(&suffixes, slot);
638 	if (s == NULL) {
639 		s = new_suffixi(str, end);
640 		ohash_insert(&suffixes, slot, s);
641 	}
642 	make_suffix_known(s);
643 	return s;
644 }
645 
646 Lst
647 find_suffix_path(GNode *gn)
648 {
649 	if (gn->suffix != NULL && gn->suffix != emptySuff)
650 		return &(gn->suffix->searchPath);
651 	else
652 		return defaultPath;
653 }
654 
655 /* find out the tagged suffixes, build a temporary path, and construct
656  * a variable based on that.
657  */
658 static void
659 build_path_variable(struct ohash *h, int opt, const char *name,
660     const char *flag)
661 {
662 	char *value;
663 	LIST path;
664 	Suff *s;
665 	unsigned int i;
666 
667 	Lst_Init(&path);
668 	for (s = ohash_first(h, &i); s != NULL; s = ohash_next(h, &i)) {
669 		if (Lst_IsEmpty(&s->searchPath))
670 			continue;
671 		if (s->flags & opt)
672 			Dir_Concat(&path, &s->searchPath);
673 	}
674 
675 	value = Dir_MakeFlags(flag, &path);
676 	Var_Set(name, value);
677 	free(value);
678 	Lst_Destroy(&path, Dir_Destroy);
679 }
680 
681 static void
682 add_property(const char *sname, const char *end, int opt)
683 {
684 	Suff *s;
685 
686 	s = find_suffi(sname, end);
687 	if (s != NULL) {
688 		s->flags |= opt;
689 	}
690 }
691 
692 void
693 Suff_AddIncludei(const char *sname, const char *end)
694 {
695 	add_property(sname, end, SUFF_INCLUDE);
696 }
697 
698 void
699 Suff_AddLibi(const char *sname, const char *end)
700 {
701 	add_property(sname, end, SUFF_LIBRARY);
702 }
703 
704 static void
705 build_suffixes_graph(void)
706 {
707 	Suff *s, *s2;
708 	GNode *gn;
709 	unsigned int i;
710 
711 	for (gn = ohash_first(&transforms, &i); gn != NULL;
712 	    gn = ohash_next(&transforms, &i)) {
713 	    	if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children))
714 			continue;
715 		if ((gn->special & SPECIAL_MASK) == SPECIAL_PATH)
716 			continue;
717 	    	if (parse_transform(gn->name, &s, &s2)) {
718 			SuffInsert(&s2->children, s);
719 			SuffInsert(&s->parents, s2);
720 		}
721 	}
722 }
723 
724 /*-
725  *-----------------------------------------------------------------------
726  * setup_paths
727  *	Extend the search paths for all suffixes to include the default
728  *	search path.
729  *
730  * Side Effects:
731  *	The searchPath field of all the suffixes is extended by the
732  *	directories in defaultPath. If paths were specified for the
733  *	".h" suffix, the directories are stuffed into a global variable
734  *	called ".INCLUDES" with each directory preceded by a -I. The same
735  *	is done for the ".a" suffix, except the variable is called
736  *	".LIBS" and the flag is -L.
737  *-----------------------------------------------------------------------
738  */
739 static void
740 setup_paths(void)
741 {
742 	unsigned int i;
743 	Suff *s;
744 
745 	for (s = ohash_first(&suffixes, &i); s != NULL;
746 	    s = ohash_next(&suffixes, &i)) {
747 		if (!Lst_IsEmpty(&s->searchPath))
748 			Dir_Concat(&s->searchPath, defaultPath);
749 		else
750 			Lst_Clone(&s->searchPath, defaultPath, Dir_CopyDir);
751 	}
752 
753 	build_path_variable(&suffixes, SUFF_INCLUDE, ".INCLUDES", "-I");
754 	build_path_variable(&suffixes, SUFF_LIBRARY, ".LIBS", "-L");
755 }
756 
757 void
758 process_suffixes_after_makefile_is_read(void)
759 {
760 	/* once the Makefile is finish reading, we can set up the default PATH
761 	 * stuff, and build the final suffixes graph
762 	 */
763 	setup_paths();
764 	/* and we link all transforms to active suffixes at this point. */
765 	build_suffixes_graph();
766 }
767 	  /********** Implicit Source Search Functions *********/
768 
769 /*-
770  *-----------------------------------------------------------------------
771  * SuffAddSrc  --
772  *	Add a suffix as a Src structure to the given list with its parent
773  *	being the given Src structure. If the suffix is the null suffix,
774  *	the prefix is used unaltered as the file name in the Src structure.
775  *
776  * Side Effects:
777  *	A Src structure is created and tacked onto the end of the list
778  *-----------------------------------------------------------------------
779  */
780 static void
781 SuffAddSrc(
782     void *sp,		/* suffix for which to create a Src structure */
783     void *lsp)		/* list and parent for the new Src */
784 {
785 	Suff *s = (Suff *)sp;
786 	LstSrc *ls = (LstSrc *)lsp;
787 	Src *s2;	/* new Src structure */
788 	Src *targ;	/* Target structure */
789 
790 	targ = ls->s;
791 
792 	if ((s->flags & SUFF_NULL) && *s->name != '\0') {
793 		/*
794 		 * If the suffix has been marked as the NULL suffix, also
795 		 * create a Src structure for a file with no suffix attached.
796 		 * Two birds, and all that...
797 		 */
798 		s2 = emalloc(sizeof(Src));
799 		s2->file = estrdup(targ->pref);
800 		s2->pref = targ->pref;
801 		s2->parent = targ;
802 		s2->node = NULL;
803 		s2->suff = s;
804 		s2->children = 0;
805 		targ->children++;
806 		Lst_AtEnd(ls->l, s2);
807 #ifdef DEBUG_SRC
808 		Lst_Init(&s2->cp);
809 		Lst_AtEnd(&targ->cp, s2);
810 		printf("1 add %x %x to %x:", targ, s2, ls->l);
811 		Lst_Every(ls->l, PrintAddr);
812 		printf("\n");
813 #endif
814 	}
815 	s2 = emalloc(sizeof(Src));
816 	s2->file = Str_concat(targ->pref, s->name, 0);
817 	s2->pref = targ->pref;
818 	s2->parent = targ;
819 	s2->node = NULL;
820 	s2->suff = s;
821 	s2->children = 0;
822 	targ->children++;
823 	Lst_AtEnd(ls->l, s2);
824 #ifdef DEBUG_SRC
825 	Lst_Init(&s2->cp);
826 	Lst_AtEnd(&targ->cp, s2);
827 	printf("2 add %x %x to %x:", targ, s2, ls->l);
828 	Lst_Every(ls->l, PrintAddr);
829 	printf("\n");
830 #endif
831 
832 }
833 
834 /*-
835  *-----------------------------------------------------------------------
836  * SuffAddLevel  --
837  *	Add all the children of targ as Src structures to the given list
838  *
839  * Side Effects:
840  *	Lots of structures are created and added to the list
841  *-----------------------------------------------------------------------
842  */
843 static void
844 SuffAddLevel(
845     Lst l,	/* list to which to add the new level */
846     Src *targ)	/* Src structure to use as the parent */
847 {
848 	LstSrc	   ls;
849 
850 	ls.s = targ;
851 	ls.l = l;
852 
853 	Lst_ForEach(&targ->suff->children, SuffAddSrc, &ls);
854 }
855 
856 /*-
857  *----------------------------------------------------------------------
858  * SuffRemoveSrc --
859  *	Free all src structures in list that don't have a reference count
860  *
861  * Results:
862  *	Ture if an src was removed
863  *
864  * Side Effects:
865  *	The memory is free'd.
866  *----------------------------------------------------------------------
867  */
868 static int
869 SuffRemoveSrc(Lst l)
870 {
871 	LstNode ln;
872 	Src *s;
873 	int t = 0;
874 
875 #ifdef DEBUG_SRC
876 	printf("cleaning %lx: ", (unsigned long)l);
877 	Lst_Every(l, PrintAddr);
878 	printf("\n");
879 #endif
880 
881 
882 	for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) {
883 		s = (Src *)Lst_Datum(ln);
884 		if (s->children == 0) {
885 			free(s->file);
886 			if (!s->parent)
887 				free(s->pref);
888 			else {
889 #ifdef DEBUG_SRC
890 				LstNode ln2 = Lst_Member(&s->parent->cp, s);
891 				if (ln2 != NULL)
892 				    Lst_Remove(&s->parent->cp, ln2);
893 #endif
894 				--s->parent->children;
895 			}
896 #ifdef DEBUG_SRC
897 			printf("free: [l=%x] p=%x %d\n", l, s, s->children);
898 			Lst_Destroy(&s->cp, NOFREE);
899 #endif
900 			Lst_Remove(l, ln);
901 			free(s);
902 			t |= 1;
903 			return true;
904 		}
905 #ifdef DEBUG_SRC
906 		else {
907 			printf("keep: [l=%x] p=%x %d: ", l, s, s->children);
908 			Lst_Every(&s->cp, PrintAddr);
909 			printf("\n");
910 		}
911 #endif
912 	}
913 
914 	return t;
915 }
916 
917 /*-
918  *-----------------------------------------------------------------------
919  * SuffFindThem --
920  *	Find the first existing file/target in the list srcs
921  *
922  * Results:
923  *	The lowest structure in the chain of transformations
924  *-----------------------------------------------------------------------
925  */
926 static Src *
927 SuffFindThem(
928     Lst srcs,	/* list of Src structures to search through */
929     Lst slst)
930 {
931 	Src *s;		/* current Src */
932 	Src *rs; 	/* returned Src */
933 	char *ptr;
934 
935 	rs = NULL;
936 
937 	while ((s = (Src *)Lst_DeQueue(srcs)) != NULL) {
938 		if (DEBUG(SUFF))
939 			printf("\ttrying %s...", s->file);
940 
941 		/*
942 		 * A file is considered to exist if either a node exists in the
943 		 * graph for it or the file actually exists.
944 		 */
945 		if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) {
946 #ifdef DEBUG_SRC
947 			printf("remove %x from %x\n", s, srcs);
948 #endif
949 			rs = s;
950 			break;
951 		}
952 
953 		if ((ptr = Dir_FindFile(s->file, &s->suff->searchPath))
954 		    != NULL) {
955 			rs = s;
956 #ifdef DEBUG_SRC
957 			printf("remove %x from %x\n", s, srcs);
958 #endif
959 			free(ptr);
960 			break;
961 		}
962 
963 		if (DEBUG(SUFF))
964 		    printf("not there\n");
965 
966 		SuffAddLevel(srcs, s);
967 		Lst_AtEnd(slst, s);
968 	}
969 
970 	if (DEBUG(SUFF) && rs)
971 	    printf("got it\n");
972 	return rs;
973 }
974 
975 /*-
976  *-----------------------------------------------------------------------
977  * SuffFindCmds --
978  *	See if any of the children of the target in the Src structure is
979  *	one from which the target can be transformed. If there is one,
980  *	a Src structure is put together for it and returned.
981  *
982  * Results:
983  *	The Src structure of the "winning" child, or NULL if no such beast.
984  *
985  * Side Effects:
986  *	A Src structure may be allocated.
987  *-----------------------------------------------------------------------
988  */
989 static Src *
990 SuffFindCmds(
991     Src 	*targ,	/* Src structure to play with */
992     Lst 	slst)
993 {
994 	LstNode ln;	/* General-purpose list node */
995 	GNode *t;	/* Target GNode */
996 	GNode *s;	/* Source GNode */
997 	int prefLen;	/* The length of the defined prefix */
998 	Suff *suff;	/* Suffix on matching beastie */
999 	Src *ret;	/* Return value */
1000 	const char *cp;
1001 
1002 	t = targ->node;
1003 	prefLen = strlen(targ->pref);
1004 
1005 	for (ln = Lst_First(&t->children); ln != NULL; ln = Lst_Adv(ln)) {
1006 		s = (GNode *)Lst_Datum(ln);
1007 
1008 		cp = strrchr(s->name, '/');
1009 		if (cp == NULL) {
1010 			cp = s->name;
1011 		} else {
1012 			cp++;
1013 		}
1014 		if (strncmp(cp, targ->pref, prefLen) == 0) {
1015 			/* The node matches the prefix ok, see if it has a known
1016 			 * suffix.	*/
1017 			suff = find_suff(&cp[prefLen]);
1018 			if (suff != NULL) {
1019 				/*
1020 				 * It even has a known suffix, see if there's a
1021 				 * transformation defined between the node's
1022 				 * suffix and the target's suffix.
1023 				 *
1024 				 * XXX: Handle multi-stage transformations
1025 				 * here, too.
1026 				 */
1027 				if (Lst_Member(&suff->parents, targ->suff)
1028 				    != NULL) {
1029 					/*
1030 					 * Hot Damn! Create a new Src structure
1031 					 * to describe this transformation
1032 					 * (making sure to duplicate the source
1033 					 * node's name so Suff_FindDeps can
1034 					 * free it again (ick)), and return the
1035 					 * new structure.
1036 					 */
1037 					ret = emalloc(sizeof(Src));
1038 					ret->file = estrdup(s->name);
1039 					ret->pref = targ->pref;
1040 					ret->suff = suff;
1041 					ret->parent = targ;
1042 					ret->node = s;
1043 					ret->children = 0;
1044 					targ->children++;
1045 #ifdef DEBUG_SRC
1046 					Lst_Init(&ret->cp);
1047 					printf("3 add %x %x\n", targ, ret);
1048 					Lst_AtEnd(&targ->cp, ret);
1049 #endif
1050 					Lst_AtEnd(slst, ret);
1051 					if (DEBUG(SUFF))
1052 					    printf(
1053 						"\tusing existing source %s\n",
1054 						    s->name);
1055 					return ret;
1056 				}
1057 			}
1058 		}
1059 	}
1060 	return NULL;
1061 }
1062 
1063 static void
1064 SuffExpandVarChildren(LstNode after, GNode *cgn, GNode *pgn)
1065 {
1066 	GNode *gn;		/* New source 8) */
1067 	char *cp;		/* Expanded value */
1068 	LIST members;
1069 
1070 
1071 	if (DEBUG(SUFF))
1072 		printf("Expanding \"%s\"...", cgn->name);
1073 
1074 	cp = Var_Subst(cgn->name, &pgn->context, true);
1075 	if (cp == NULL) {
1076 		printf("Problem substituting in %s", cgn->name);
1077 		printf("\n");
1078 		return;
1079 	}
1080 
1081 	Lst_Init(&members);
1082 
1083 	if (cgn->type & OP_ARCHV) {
1084 		/*
1085 		 * Node was an archive(member) target, so we want to call
1086 		 * on the Arch module to find the nodes for us, expanding
1087 		 * variables in the parent's context.
1088 		 */
1089 		const char *sacrifice = (const char *)cp;
1090 
1091 		(void)Arch_ParseArchive(&sacrifice, &members, &pgn->context);
1092 	} else {
1093 		/* Break the result into a vector of strings whose nodes
1094 		 * we can find, then add those nodes to the members list.
1095 		 * Unfortunately, we can't use brk_string because it
1096 		 * doesn't understand about variable specifications with
1097 		 * spaces in them...  */
1098 		const char *start, *cp2;
1099 
1100 		for (start = cp; *start == ' ' || *start == '\t'; start++)
1101 			continue;
1102 		for (cp2 = start; *cp2 != '\0';) {
1103 			if (isspace(*cp2)) {
1104 				/* White-space -- terminate element, find the
1105 				 * node, add it, skip any further spaces.  */
1106 				gn = Targ_FindNodei(start, cp2, TARG_CREATE);
1107 				cp2++;
1108 				Lst_AtEnd(&members, gn);
1109 				while (isspace(*cp2))
1110 					cp2++;
1111 				/* Adjust cp2 for increment at start of loop,
1112 				 * but set start to first non-space.  */
1113 				start = cp2;
1114 			} else if (*cp2 == '$')
1115 				/* Start of a variable spec -- contact variable
1116 				 * module to find the end so we can skip over
1117 				 * it.  */
1118 				Var_ParseSkip(&cp2, &pgn->context);
1119 			else if (*cp2 == '\\' && cp2[1] != '\0')
1120 				/* Escaped something -- skip over it.  */
1121 				cp2+=2;
1122 			else
1123 				cp2++;
1124 	    }
1125 
1126 	    if (cp2 != start) {
1127 		    /* Stuff left over -- add it to the list too.  */
1128 		    gn = Targ_FindNodei(start, cp2, TARG_CREATE);
1129 		    Lst_AtEnd(&members, gn);
1130 	    }
1131 	}
1132 	/* Add all elements of the members list to the parent node.  */
1133 	while ((gn = (GNode *)Lst_DeQueue(&members)) != NULL) {
1134 		if (DEBUG(SUFF))
1135 			printf("%s...", gn->name);
1136 		if (Lst_Member(&pgn->children, gn) == NULL) {
1137 			Lst_Append(&pgn->children, after, gn);
1138 			after = Lst_Adv(after);
1139 			Lst_AtEnd(&gn->parents, pgn);
1140 			if (!has_been_built(gn))
1141 				pgn->unmade++;
1142 		}
1143 	}
1144 	/* Free the result.  */
1145 	free(cp);
1146 	if (DEBUG(SUFF))
1147 		printf("\n");
1148 }
1149 
1150 static void
1151 SuffExpandWildChildren(LstNode after, GNode *cgn, GNode *pgn)
1152 {
1153 	Suff *s;
1154 	char *cp;	/* Expanded value */
1155 
1156 	LIST exp;	/* List of expansions */
1157 	Lst path;	/* Search path along which to expand */
1158 
1159 	if (DEBUG(SUFF))
1160 		printf("Wildcard expanding \"%s\"...", cgn->name);
1161 
1162 	/* Find a path along which to expand the word.
1163 	 *
1164 	 * If the word has a known suffix, use that path.
1165 	 * If it has no known suffix and we're allowed to use the null
1166 	 *	 suffix, use its path.
1167 	 * Else use the default system search path.  */
1168 	s = find_best_suffix(cgn->name, cgn->name + strlen(cgn->name));
1169 
1170 	if (s != NULL) {
1171 		if (DEBUG(SUFF))
1172 			printf("suffix is \"%s\"...", s->name);
1173 		path = &s->searchPath;
1174 	} else
1175 		/* Use default search path.  */
1176 		path = defaultPath;
1177 
1178 	/* Expand the word along the chosen path. */
1179 	Lst_Init(&exp);
1180 	Dir_Expand(cgn->name, path, &exp);
1181 
1182 	/* Fetch next expansion off the list and find its GNode.  */
1183 	while ((cp = (char *)Lst_DeQueue(&exp)) != NULL) {
1184 		GNode *gn;		/* New source 8) */
1185 		if (DEBUG(SUFF))
1186 			printf("%s...", cp);
1187 		gn = Targ_FindNode(cp, TARG_CREATE);
1188 
1189 		/* If gn isn't already a child of the parent, make it so and
1190 		 * up the parent's count of unmade children.  */
1191 		if (Lst_Member(&pgn->children, gn) == NULL) {
1192 			Lst_Append(&pgn->children, after, gn);
1193 			after = Lst_Adv(after);
1194 			Lst_AtEnd(&gn->parents, pgn);
1195 			if (!has_been_built(gn))
1196 				pgn->unmade++;
1197 		}
1198 	}
1199 
1200 	if (DEBUG(SUFF))
1201 		printf("\n");
1202 }
1203 
1204 /*-
1205  *-----------------------------------------------------------------------
1206  * SuffExpandChildren --
1207  *	Expand the names of any children of a given node that contain
1208  *	variable invocations or file wildcards into actual targets.
1209  *
1210  * Side Effects:
1211  *	The expanded node is removed from the parent's list of children,
1212  *	and the parent's unmade counter is decremented, but other nodes
1213  *	may be added.
1214  *-----------------------------------------------------------------------
1215  */
1216 static void
1217 SuffExpandChildren(LstNode ln, /* LstNode of child, so we can replace it */
1218     GNode *pgn)
1219 {
1220 	GNode	*cgn = (GNode *)Lst_Datum(ln);
1221 
1222 	/* First do variable expansion -- this takes precedence over wildcard
1223 	 * expansion. If the result contains wildcards, they'll be gotten to
1224 	 * later since the resulting words are tacked on to the end of the
1225 	 * children list.  */
1226 	if (strchr(cgn->name, '$') != NULL)
1227 		SuffExpandVarChildren(ln, cgn, pgn);
1228 	else if (Dir_HasWildcards(cgn->name))
1229 		SuffExpandWildChildren(ln, cgn, pgn);
1230 	else
1231 	    /* Third case: nothing to expand.  */
1232 		return;
1233 
1234 	/* Since the source was expanded, remove it from the list of children to
1235 	 * keep it from being processed.  */
1236 	pgn->unmade--;
1237 	Lst_Remove(&pgn->children, ln);
1238 }
1239 
1240 void
1241 expand_children_from(GNode *parent, LstNode from)
1242 {
1243 	LstNode np, ln;
1244 
1245 	for (ln = from; ln != NULL; ln = np) {
1246 		np = Lst_Adv(ln);
1247 		SuffExpandChildren(ln, parent);
1248 	}
1249 }
1250 
1251 /*-
1252  *-----------------------------------------------------------------------
1253  * SuffApplyTransform --
1254  *	Apply a transformation rule, given the source and target nodes
1255  *	and suffixes.
1256  *
1257  * Results:
1258  *	true if successful, false if not.
1259  *
1260  * Side Effects:
1261  *	The source and target are linked and the commands from the
1262  *	transformation are added to the target node's commands list.
1263  *	All attributes but OP_DEPMASK and OP_TRANSFORM are applied
1264  *	to the target. The target also inherits all the sources for
1265  *	the transformation rule.
1266  *-----------------------------------------------------------------------
1267  */
1268 static bool
1269 SuffApplyTransform(
1270     GNode	*tGn,	/* Target node */
1271     GNode	*sGn,	/* Source node */
1272     Suff	*t,	/* Target suffix */
1273     Suff	*s)	/* Source suffix */
1274 {
1275 	LstNode	ln;	/* General node */
1276 	char	*tname; /* Name of transformation rule */
1277 	GNode	*gn;	/* Node for same */
1278 
1279 	if (Lst_AddNew(&tGn->children, sGn)) {
1280 		/* Not already linked, so form the proper links between the
1281 		 * target and source.  */
1282 		Lst_AtEnd(&sGn->parents, tGn);
1283 		if (!has_been_built(sGn))
1284 			tGn->unmade++;
1285 	}
1286 
1287 	if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) {
1288 		/* When a :: node is used as the implied source of a node, we
1289 		 * have to link all its cohorts in as sources as well. There's
1290 		 * only one implied src, as that will be sufficient to get
1291 		 * the .IMPSRC variable set for tGn.	*/
1292 		for (ln=Lst_First(&sGn->cohorts); ln != NULL; ln=Lst_Adv(ln)) {
1293 			gn = (GNode *)Lst_Datum(ln);
1294 
1295 			if (Lst_AddNew(&tGn->children, gn)) {
1296 				/* Not already linked, so form the proper links
1297 				 * between the target and source.  */
1298 				Lst_AtEnd(&gn->parents, tGn);
1299 				if (!has_been_built(gn))
1300 					tGn->unmade++;
1301 			}
1302 		}
1303 	}
1304 	/* Locate the transformation rule itself.  */
1305 	tname = Str_concat(s->name, t->name, 0);
1306 	gn = find_transform(tname);
1307 	free(tname);
1308 
1309 	if (gn == NULL)
1310 		/*
1311 		 * Not really such a transformation rule (can happen when we're
1312 		 * called to link an OP_MEMBER and OP_ARCHV node), so return
1313 		 * false.
1314 		 */
1315 		return false;
1316 
1317 	if (DEBUG(SUFF))
1318 		printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name,
1319 		    tGn->name);
1320 
1321 	/* Record last child for expansion purposes.  */
1322 	ln = Lst_Last(&tGn->children);
1323 
1324 	/* Pass the buck to Make_HandleUse to apply the rule.  */
1325 	Make_HandleUse(gn, tGn);
1326 
1327 	/* Deal with wildcards and variables in any acquired sources.  */
1328 	expand_children_from(tGn, Lst_Succ(ln));
1329 
1330 	/* Keep track of another parent to which this beast is transformed so
1331 	 * the .IMPSRC variable can be set correctly for the parent.  */
1332 	tGn->impliedsrc = sGn;
1333 
1334 	return true;
1335 }
1336 
1337 static Suff *
1338 find_suffix_as_suffix(Lst l, const char *b, const char *e)
1339 {
1340 	LstNode ln;
1341 	Suff *s;
1342 
1343 	for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) {
1344 		s = (Suff *)Lst_Datum(ln);
1345 		if (suffix_is_suffix(s, b, e))
1346 			return s;
1347 	}
1348 	return NULL;
1349 }
1350 
1351 /*-
1352  *-----------------------------------------------------------------------
1353  * SuffFindArchiveDeps --
1354  *	Locate dependencies for an OP_ARCHV node.
1355  *
1356  * Side Effects:
1357  *	Same as Suff_FindDeps
1358  *-----------------------------------------------------------------------
1359  */
1360 static void
1361 SuffFindArchiveDeps(
1362     GNode	*gn,    /* Node for which to locate dependencies */
1363     Lst 	slst)
1364 {
1365 	char *eoarch;	/* End of archive portion */
1366 	char *eoname;	/* End of member portion */
1367 	GNode *mem;	/* Node for member */
1368 	Suff *ms;	/* Suffix descriptor for member */
1369 	char *name;	/* Start of member's name */
1370 
1371 	/* The node is an archive(member) pair. so we must find a suffix
1372 	 * for both of them.  */
1373 	eoarch = strchr(gn->name, '(');
1374 	if (eoarch == NULL)
1375 		return;
1376 
1377 	name = eoarch + 1;
1378 
1379 	eoname = strchr(name, ')');
1380 	if (eoname == NULL)
1381 		return;
1382 
1383 	/* To simplify things, call Suff_FindDeps recursively on the member now,
1384 	 * so we can simply compare the member's .PREFIX and .TARGET variables
1385 	 * to locate its suffix. This allows us to figure out the suffix to
1386 	 * use for the archive without having to do a quadratic search over the
1387 	 * suffix list, backtracking for each one...  */
1388 	mem = Targ_FindNodei(name, eoname, TARG_CREATE);
1389 	SuffFindDeps(mem, slst);
1390 
1391 	/* Create the link between the two nodes right off. */
1392 	if (Lst_AddNew(&gn->children, mem)) {
1393 		Lst_AtEnd(&mem->parents, gn);
1394 		if (!has_been_built(mem))
1395 			gn->unmade++;
1396 	}
1397 
1398 	/* Copy variables from member node to this one.  */
1399 	Var(TARGET_INDEX, gn) = Var(TARGET_INDEX, mem);
1400 	Var(PREFIX_INDEX, gn) = Var(PREFIX_INDEX, mem);
1401 
1402 	ms = mem->suffix;
1403 	if (ms == NULL) {
1404 		/* Didn't know what it was -- use .NULL suffix if not in make
1405 		 * mode.  */
1406 		if (DEBUG(SUFF))
1407 			printf("using null suffix\n");
1408 		ms = suffNull;
1409 	}
1410 
1411 
1412 	/* Set the other two local variables required for this target.  */
1413 	Var(MEMBER_INDEX, gn) = mem->name;
1414 	Var(ARCHIVE_INDEX, gn) = gn->name;
1415 
1416 	if (ms != NULL) {
1417 		/*
1418 		 * Member has a known suffix, so look for a transformation rule
1419 		 * from it to a possible suffix of the archive. Rather than
1420 		 * searching through the entire list, we just look at suffixes
1421 		 * to which the member's suffix may be transformed...
1422 		 */
1423 
1424 		Suff *suff;
1425 
1426 		suff = find_suffix_as_suffix(&ms->parents, gn->name, eoarch);
1427 
1428 		if (suff != NULL) {
1429 			/* Got one -- apply it.  */
1430 			if (!SuffApplyTransform(gn, mem, suff, ms) &&
1431 			    DEBUG(SUFF))
1432 				printf("\tNo transformation from %s -> %s\n",
1433 				   ms->name, suff->name);
1434 		}
1435 	}
1436 
1437 	/* Pretend gn appeared to the left of a dependency operator so
1438 	 * the user needn't provide a transformation from the member to the
1439 	 * archive.  */
1440 	if (OP_NOP(gn->type))
1441 		gn->type |= OP_DEPENDS;
1442 
1443 	/* Flag the member as such so we remember to look in the archive for
1444 	 * its modification time.  */
1445 	mem->type |= OP_MEMBER;
1446 }
1447 
1448 static void
1449 record_possible_suffix(Suff *s, GNode *gn, char *eoname, Lst srcs, Lst targs)
1450 {
1451 	int prefLen;
1452 	Src *targ;
1453 	char *sopref = gn->name;
1454 
1455 	targ = emalloc(sizeof(Src));
1456 	targ->file = estrdup(gn->name);
1457 	targ->suff = s;
1458 	targ->node = gn;
1459 	targ->parent = NULL;
1460 	targ->children = 0;
1461 #ifdef DEBUG_SRC
1462 	Lst_Init(&targ->cp);
1463 #endif
1464 
1465 	/* Allocate room for the prefix, whose end is found by
1466 	 * subtracting the length of the suffix from the end of
1467 	 * the name.  */
1468 	prefLen = (eoname - targ->suff->nameLen) - sopref;
1469 	targ->pref = emalloc(prefLen + 1);
1470 	memcpy(targ->pref, sopref, prefLen);
1471 	targ->pref[prefLen] = '\0';
1472 
1473 	/* Add nodes from which the target can be made.  */
1474 	SuffAddLevel(srcs, targ);
1475 
1476 	/* Record the target so we can nuke it.  */
1477 	Lst_AtEnd(targs, targ);
1478 }
1479 
1480 static void
1481 record_possible_suffixes(GNode *gn, Lst srcs, Lst targs)
1482 {
1483 	char *s = gn->name;
1484 	char *e =  s + strlen(s);
1485 	const char *p;
1486 	uint32_t hv;
1487 	unsigned int slot;
1488 	Suff *suff;
1489 
1490 	if (e == s)
1491 		return;
1492 
1493 	p = e;
1494 	hv = *--p;
1495 
1496 	while (p != s) {
1497 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
1498 		suff = ohash_find(&suffixes, slot);
1499 		if (suff != NULL && (suff->flags & SUFF_ACTIVE))
1500 			record_possible_suffix(suff, gn, e, srcs, targs);
1501 		if (e - p >= (ptrdiff_t)maxLen)
1502 			break;
1503 		reverse_hash_add_char(&hv, --p);
1504 	}
1505 }
1506 
1507 /*-
1508  *-----------------------------------------------------------------------
1509  * SuffFindNormalDeps --
1510  *	Locate implicit dependencies for regular targets.
1511  *
1512  * Side Effects:
1513  *	Same as Suff_FindDeps...
1514  *-----------------------------------------------------------------------
1515  */
1516 static void
1517 SuffFindNormalDeps(
1518     GNode	*gn,	    /* Node for which to find sources */
1519     Lst 	slst)
1520 {
1521 	LIST srcs;	/* List of sources at which to look */
1522 	LIST targs;	/* List of targets to which things can be
1523 			 * transformed. They all have the same file,
1524 			 * but different suff and pref fields */
1525 	Src *bottom;    /* Start of found transformation path */
1526 	Src *src;	/* General Src pointer */
1527 	char *pref;	/* Prefix to use */
1528 	Src *targ;	/* General Src target pointer */
1529 
1530 
1531 	Lst_Init(&srcs);
1532 	Lst_Init(&targs);
1533 
1534 	/* We're caught in a catch-22 here. On the one hand, we want to use any
1535 	 * transformation implied by the target's sources, but we can't examine
1536 	 * the sources until we've expanded any variables/wildcards they may
1537 	 * hold, and we can't do that until we've set up the target's local
1538 	 * variables and we can't do that until we know what the proper suffix
1539 	 * for the target is (in case there are two suffixes one of which is a
1540 	 * suffix of the other) and we can't know that until we've found its
1541 	 * implied source, which we may not want to use if there's an existing
1542 	 * source that implies a different transformation.
1543 	 *
1544 	 * In an attempt to get around this, which may not work all the time,
1545 	 * but should work most of the time, we look for implied sources first,
1546 	 * checking transformations to all possible suffixes of the target, use
1547 	 * what we find to set the target's local variables, expand the
1548 	 * children, then look for any overriding transformations they imply.
1549 	 * Should we find one, we discard the one we found before.	*/
1550 
1551 
1552 	record_possible_suffixes(gn, &srcs, &targs);
1553 	/* Handle target of unknown suffix...  */
1554 	if (Lst_IsEmpty(&srcs)) {
1555 		if (DEBUG(SUFF))
1556 			printf("\tNo known suffix on %s. Using .NULL suffix\n",
1557 			    gn->name);
1558 
1559 		targ = emalloc(sizeof(Src));
1560 		targ->file = estrdup(gn->name);
1561 		targ->suff = suffNull;
1562 		targ->node = gn;
1563 		targ->parent = NULL;
1564 		targ->children = 0;
1565 		targ->pref = estrdup(gn->name);
1566 #ifdef DEBUG_SRC
1567 		Lst_Init(&targ->cp);
1568 #endif
1569 
1570 		/* Only use the default suffix rules if we don't have commands
1571 		 * or dependencies defined for this gnode.  */
1572 		if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children))
1573 			SuffAddLevel(&srcs, targ);
1574 		else {
1575 			if (DEBUG(SUFF))
1576 				printf("not ");
1577 		}
1578 
1579 		if (DEBUG(SUFF))
1580 			printf("adding suffix rules\n");
1581 
1582 		Lst_AtEnd(&targs, targ);
1583 	}
1584 
1585 	/* Using the list of possible sources built up from the target
1586 	 * suffix(es), try and find an existing file/target that matches.  */
1587 	bottom = SuffFindThem(&srcs, slst);
1588 
1589 	if (bottom == NULL) {
1590 		/* No known transformations -- use the first suffix found for
1591 		 * setting the local variables.  */
1592 		if (!Lst_IsEmpty(&targs))
1593 			targ = (Src *)Lst_Datum(Lst_First(&targs));
1594 		else
1595 			targ = NULL;
1596 	} else {
1597 		/* Work up the transformation path to find the suffix of the
1598 		 * target to which the transformation was made.  */
1599 		for (targ = bottom; targ->parent != NULL; targ = targ->parent)
1600 			continue;
1601 	}
1602 
1603 	/* The .TARGET variable we always set to be the name at this point,
1604 	 * since it's only set to the path if the thing is only a source and
1605 	 * if it's only a source, it doesn't matter what we put here as far
1606 	 * as expanding sources is concerned, since it has none...	*/
1607 	Var(TARGET_INDEX, gn) = gn->name;
1608 
1609 	pref = targ != NULL ? estrdup(targ->pref) : gn->name;
1610 	Var(PREFIX_INDEX, gn) = pref;
1611 
1612 	/* Now we've got the important local variables set, expand any sources
1613 	 * that still contain variables or wildcards in their names.  */
1614 	expand_all_children(gn);
1615 
1616 	if (targ == NULL) {
1617 		if (DEBUG(SUFF))
1618 			printf("\tNo valid suffix on %s\n", gn->name);
1619 
1620 sfnd_abort:
1621 		/* Deal with finding the thing on the default search path if the
1622 		 * node is only a source (not on the lhs of a dependency operator
1623 		 * or [XXX] it has neither children or commands).  */
1624 		if (OP_NOP(gn->type) ||
1625 		    (Lst_IsEmpty(&gn->children) &&
1626 		    Lst_IsEmpty(&gn->commands))) {
1627 			gn->path = Dir_FindFile(gn->name,
1628 			    (targ == NULL ? defaultPath :
1629 			    &targ->suff->searchPath));
1630 			if (gn->path != NULL) {
1631 				char *ptr;
1632 				Var(TARGET_INDEX, gn) = estrdup(gn->path);
1633 
1634 				if (targ != NULL) {
1635 					/* Suffix known for the thing -- trim
1636 					 * the suffix off the path to form the
1637 					 * proper .PREFIX variable.  */
1638 					int savep = strlen(gn->path) -
1639 					    targ->suff->nameLen;
1640 					char savec;
1641 
1642 					gn->suffix = targ->suff;
1643 
1644 					savec = gn->path[savep];
1645 					gn->path[savep] = '\0';
1646 
1647 					if ((ptr = strrchr(gn->path, '/')) !=
1648 					    NULL)
1649 						ptr++;
1650 					else
1651 						ptr = gn->path;
1652 
1653 					Var(PREFIX_INDEX, gn) = estrdup(ptr);
1654 
1655 					gn->path[savep] = savec;
1656 				} else {
1657 					/* The .PREFIX gets the full path if the
1658 					 * target has no known suffix.  */
1659 					gn->suffix = NULL;
1660 
1661 					if ((ptr = strrchr(gn->path, '/')) !=
1662 					    NULL)
1663 						ptr++;
1664 					else
1665 						ptr = gn->path;
1666 
1667 					Var(PREFIX_INDEX, gn) = estrdup(ptr);
1668 				}
1669 			}
1670 		} else {
1671 			/* Not appropriate to search for the thing -- set the
1672 			 * path to be the name so Dir_MTime won't go grovelling
1673 			 * for it.  */
1674 			gn->suffix = targ == NULL ? NULL : targ->suff;
1675 			efree(gn->path);
1676 			gn->path = estrdup(gn->name);
1677 		}
1678 
1679 		goto sfnd_return;
1680 	}
1681 
1682 	/* If the suffix indicates that the target is a library, mark that in
1683 	 * the node's type field.  */
1684 	if (targ->suff->flags & SUFF_LIBRARY) {
1685 		gn->type |= OP_LIB;
1686 	}
1687 
1688 	/* Check for overriding transformation rule implied by sources.  */
1689 	if (!Lst_IsEmpty(&gn->children)) {
1690 		src = SuffFindCmds(targ, slst);
1691 
1692 		if (src != NULL) {
1693 			/* Free up all the Src structures in the transformation
1694 			 * path up to, but not including, the parent node.  */
1695 			while (bottom && bottom->parent != NULL) {
1696 				(void)Lst_AddNew(slst, bottom);
1697 				bottom = bottom->parent;
1698 			}
1699 			bottom = src;
1700 		}
1701 	}
1702 
1703 	if (bottom == NULL) {
1704 		/* No idea from where it can come -- return now.  */
1705 		goto sfnd_abort;
1706 	}
1707 
1708 	/* We now have a list of Src structures headed by 'bottom' and linked
1709 	 * via their 'parent' pointers. What we do next is create links between
1710 	 * source and target nodes (which may or may not have been created) and
1711 	 * set the necessary local variables in each target. The commands for
1712 	 * each target are set from the commands of the transformation rule
1713 	 * used to get from the src suffix to the targ suffix. Note that this
1714 	 * causes the commands list of the original node, gn, to be replaced by
1715 	 * the commands of the final transformation rule. Also, the unmade
1716 	 * field of gn is incremented.  Etc.  */
1717 	if (bottom->node == NULL) {
1718 		bottom->node = Targ_FindNode(bottom->file, TARG_CREATE);
1719 	}
1720 
1721 	for (src = bottom; src->parent != NULL; src = src->parent) {
1722 		targ = src->parent;
1723 
1724 		src->node->suffix = src->suff;
1725 
1726 		if (targ->node == NULL) {
1727 			targ->node = Targ_FindNode(targ->file, TARG_CREATE);
1728 		}
1729 
1730 		SuffApplyTransform(targ->node, src->node,
1731 				   targ->suff, src->suff);
1732 
1733 		if (targ->node != gn) {
1734 			/* Finish off the dependency-search process for any
1735 			 * nodes between bottom and gn (no point in questing
1736 			 * around the filesystem for their implicit source when
1737 			 * it's already known). Note that the node can't have
1738 			 * any sources that need expanding, since SuffFindThem
1739 			 * will stop on an existing node, so all we need to do
1740 			 * is set the standard and System V variables.  */
1741 			targ->node->type |= OP_DEPS_FOUND;
1742 
1743 			Var(PREFIX_INDEX, targ->node) = estrdup(targ->pref);
1744 
1745 			Var(TARGET_INDEX, targ->node) = targ->node->name;
1746 		}
1747 	}
1748 
1749 	gn->suffix = src->suff;
1750 
1751 	/* So Dir_MTime doesn't go questing for it...  */
1752 	efree(gn->path);
1753 	gn->path = estrdup(gn->name);
1754 
1755 	/* Nuke the transformation path and the Src structures left over in the
1756 	 * two lists.  */
1757 sfnd_return:
1758 	if (bottom)
1759 		(void)Lst_AddNew(slst, bottom);
1760 
1761 	while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs))
1762 		continue;
1763 
1764 	Lst_ConcatDestroy(slst, &srcs);
1765 	Lst_ConcatDestroy(slst, &targs);
1766 }
1767 
1768 
1769 /*-
1770  *-----------------------------------------------------------------------
1771  * Suff_FindDeps  --
1772  *	Find implicit sources for the target described by the graph node
1773  *	gn
1774  *
1775  * Side Effects:
1776  *	Nodes are added to the graph below the passed-in node. The nodes
1777  *	are marked to have their IMPSRC variable filled in. The
1778  *	PREFIX variable is set for the given node and all its
1779  *	implied children.
1780  *
1781  * Notes:
1782  *	The path found by this target is the shortest path in the
1783  *	transformation graph, which may pass through non-existent targets,
1784  *	to an existing target. The search continues on all paths from the
1785  *	root suffix until a file is found. I.e. if there's a path
1786  *	.o -> .c -> .l -> .l,v from the root and the .l,v file exists but
1787  *	the .c and .l files don't, the search will branch out in
1788  *	all directions from .o and again from all the nodes on the
1789  *	next level until the .l,v node is encountered.
1790  *-----------------------------------------------------------------------
1791  */
1792 
1793 void
1794 Suff_FindDeps(GNode *gn)
1795 {
1796 
1797 	SuffFindDeps(gn, &srclist);
1798 	while (SuffRemoveSrc(&srclist))
1799 		continue;
1800 }
1801 
1802 
1803 static void
1804 SuffFindDeps(GNode *gn, Lst slst)
1805 {
1806 	if (gn->type & OP_DEPS_FOUND) {
1807 		/*
1808 		 * If dependencies already found, no need to do it again...
1809 		 */
1810 		return;
1811 	} else {
1812 		gn->type |= OP_DEPS_FOUND;
1813 	}
1814 
1815 	if (DEBUG(SUFF))
1816 		printf("SuffFindDeps (%s)\n", gn->name);
1817 
1818 	if (gn->type & OP_ARCHV) {
1819 		SuffFindArchiveDeps(gn, slst);
1820 	} else if (gn->type & OP_LIB) {
1821 		/*
1822 		 * If the node is a library, it is the arch module's job to
1823 		 * find it and set the TARGET variable accordingly. We merely
1824 		 * provide the search path, assuming all libraries end in ".a"
1825 		 * (if the suffix hasn't been defined, there's nothing we can
1826 		 * do for it, so we just set the TARGET variable to the node's
1827 		 * name in order to give it a value).
1828 		 */
1829 		Suff	*s;
1830 
1831 		s = find_suff(LIBSUFF);
1832 		if (s != NULL) {
1833 			gn->suffix = s;
1834 			Arch_FindLib(gn, &s->searchPath);
1835 		} else {
1836 			gn->suffix = NULL;
1837 			Var(TARGET_INDEX, gn) = gn->name;
1838 		}
1839 		/*
1840 		 * Because a library (-lfoo) target doesn't follow the standard
1841 		 * filesystem conventions, we don't set the regular variables
1842 		 * for the thing. .PREFIX is simply made empty...
1843 		 */
1844 		Var(PREFIX_INDEX, gn) = "";
1845 	} else
1846 		SuffFindNormalDeps(gn, slst);
1847 }
1848 
1849 /*-
1850  * Notes:
1851  */
1852 void
1853 Suff_SetNulli(const char *name, const char *end)
1854 {
1855 	Suff    *s;
1856 
1857 	s= find_suffi(name, end);
1858 	if (s != NULL) {
1859 		/* pass the pumpkin */
1860 		suffNull->flags &= ~SUFF_NULL;
1861 		s->flags |= SUFF_NULL;
1862 		/*
1863 		 * XXX: Here's where the transformation mangling would take
1864 		 * place
1865 		 * we would need to handle the changing of the null suffix
1866 		 * gracefully so the old transformation rules don't just go
1867 		 * away.
1868 		 */
1869 		suffNull = s;
1870 	} else {
1871 		Parse_Error(PARSE_WARNING,
1872 		    "Desired null suffix %s not defined.", name);
1873 	}
1874 }
1875 
1876 /*-
1877  *-----------------------------------------------------------------------
1878  * Suff_Init --
1879  *	Initialize suffixes module
1880  *
1881  * Side Effects:
1882  *	Many
1883  *-----------------------------------------------------------------------
1884  */
1885 void
1886 Suff_Init(void)
1887 {
1888 	Static_Lst_Init(&srclist);
1889 	ohash_init(&transforms, 4, &gnode_info);
1890 
1891 	/*
1892 	 * Create null suffix for single-suffix rules (POSIX). The thing doesn't
1893 	 * actually go on the suffix list or everyone will think that's its
1894 	 * suffix.
1895 	 */
1896 	emptySuff = new_suffix("");
1897 	emptySuff->flags |= SUFF_NULL;
1898 	make_suffix_known(emptySuff);
1899 	Dir_Concat(&emptySuff->searchPath, defaultPath);
1900 	ohash_init(&suffixes, 4, &suff_info);
1901 	order = 0;
1902 	clear_suffixes();
1903 	special_path_hack();
1904 
1905 }
1906 
1907 
1908 /*-
1909  *----------------------------------------------------------------------
1910  * Suff_End --
1911  *	Cleanup the this module
1912  *
1913  * Side Effects:
1914  *	The memory is free'd.
1915  *----------------------------------------------------------------------
1916  */
1917 
1918 #ifdef CLEANUP
1919 void
1920 Suff_End(void)
1921 {
1922 	free_hash(&suffixes);
1923 	if (emptySuff)
1924 		SuffFree(emptySuff);
1925 	Lst_Destroy(&srclist, NOFREE);
1926 	ohash_delete(&transforms);
1927 }
1928 #endif
1929 
1930 
1931 /********************* DEBUGGING FUNCTIONS **********************/
1932 
1933 static void
1934 SuffPrintName(void *s)
1935 {
1936 	printf("%s ", ((Suff *)s)->name);
1937 }
1938 
1939 static void
1940 SuffPrintSuff(void *sp)
1941 {
1942 	Suff    *s = (Suff *)sp;
1943 	int     flags;
1944 	int     flag;
1945 
1946 	printf("# `%s' ", s->name);
1947 
1948 	flags = s->flags;
1949 	if (flags) {
1950 		fputs(" (", stdout);
1951 		while (flags) {
1952 			flag = 1 << (ffs(flags) - 1);
1953 			flags &= ~flag;
1954 			switch (flag) {
1955 			case SUFF_NULL:
1956 				printf("NULL");
1957 				break;
1958 			case SUFF_INCLUDE:
1959 				printf("INCLUDE");
1960 				break;
1961 			case SUFF_LIBRARY:
1962 				printf("LIBRARY");
1963 				break;
1964 			}
1965 			fputc(flags ? '|' : ')', stdout);
1966 		}
1967 	}
1968 	fputc('\n', stdout);
1969 	printf("#\tTo: ");
1970 	Lst_Every(&s->parents, SuffPrintName);
1971 	fputc('\n', stdout);
1972 	printf("#\tFrom: ");
1973 	Lst_Every(&s->children, SuffPrintName);
1974 	fputc('\n', stdout);
1975 	printf("#\tSearch Path: ");
1976 	Dir_PrintPath(&s->searchPath);
1977 	fputc('\n', stdout);
1978 }
1979 
1980 static void
1981 SuffPrintTrans(GNode *t)
1982 {
1983 	printf("%-16s: ", t->name);
1984 	Targ_PrintType(t->type);
1985 	fputc('\n', stdout);
1986 	Lst_Every(&t->commands, Targ_PrintCmd);
1987 	fputc('\n', stdout);
1988 }
1989 
1990 void
1991 Suff_PrintAll(void)
1992 {
1993 	Suff *s;
1994 	GNode *gn;
1995 	unsigned int i;
1996 
1997 	printf("#*** Suffixes:\n");
1998 
1999 	for (s = ohash_first(&suffixes, &i); s != NULL;
2000 	    s = ohash_next(&suffixes, &i))
2001 		SuffPrintSuff(s);
2002 
2003 	printf("#*** Transformations:\n");
2004 	for (gn = ohash_first(&transforms, &i); gn != NULL;
2005 	    gn = ohash_next(&transforms, &i))
2006 	    	SuffPrintTrans(gn);
2007 }
2008 
2009 #ifdef DEBUG_SRC
2010 static void
2011 PrintAddr(void *a)
2012 {
2013 	printf("%lx ", (unsigned long)a);
2014 }
2015 #endif
2016