xref: /openbsd/usr.bin/make/suff.c (revision 73471bf0)
1 /*	$OpenBSD: suff.c,v 1.102 2020/01/13 15:41:53 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 
44 #include <ctype.h>
45 #include <stddef.h>
46 #include <stdint.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <ohash.h>
51 #include "config.h"
52 #include "defines.h"
53 #include "dir.h"
54 #include "engine.h"
55 #include "suff.h"
56 #include "var.h"
57 #include "targ.h"
58 #include "error.h"
59 #include "str.h"
60 #include "lst.h"
61 #include "memory.h"
62 #include "gnode.h"
63 #include "stats.h"
64 #include "dump.h"
65 #include "expandchildren.h"
66 
67 /* XXX the suffixes hash is stored using a specific hash function, suitable
68  * for looking up suffixes in reverse.
69  */
70 static struct ohash suffixes;
71 
72 /* We remember the longest suffix, so we don't need to look beyond that.  */
73 size_t maxLen = 0U;
74 static LIST srclist;
75 
76 /* Transforms (.c.o) are stored in another hash, independently from suffixes.
77  * When make sees a target, it checks whether it's currently parsable as a
78  * transform (according to the active suffixes). If yes, it's stored as a
79  * new transform.
80  *
81  * XXX
82  * But transforms DO NOT have a canonical decomposition as a set of suffixes,
83  * and will be used as necessary later, when looking up implicit rules for
84  * actual targets.
85  *
86  * For instance, a transform .a.b.c  can be parsed as .a -> .b.c if suffixes
87  * .a and .b.c are active, and then LATER, reused as .a.b -> .c if suffixes
88  * .a.b and .c are active.
89  */
90 static struct ohash transforms;
91 
92 /* conflicts between suffixes are solved by suffix declaration order. */
93 static int order = 0;
94 
95 /*
96  * Structure describing an individual suffix.
97  */
98 struct Suff_ {
99 	size_t nameLen;		/* optimisation: strlen(name) */
100 	short flags;
101 #define SUFF_ACTIVE	  0x08	/* We never destroy suffixes and rules, */
102 				/* we just deactivate them. */
103 #define SUFF_PATH	  0x10	/* False suffix: actually, the path keyword */
104 	LIST searchPath;	/* The path along which files of this suffix
105 			     	 * may be found */
106 	int order;		/* order of declaration for conflict
107 				 * resolution. */
108 	LIST parents;		/* List of Suff we have a transformation to */
109 	LIST children;		/* List of Suff we have a transformation from */
110 	char name[1];
111 };
112 
113 static struct ohash_info suff_info = {
114 	offsetof(struct Suff_, name), NULL,
115 	hash_calloc, hash_free, element_alloc
116 };
117 
118 /*
119  * Structure used in the search for implied sources.
120  */
121 typedef struct Src_ {
122 	char *file;		/* The file to look for */
123 	char *prefix;		/* Prefix from which file was formed */
124 	Suff *suff;		/* The suffix on the file */
125 	struct Src_ *parent;	/* The Src for which this is a source */
126 	GNode *node;		/* The node describing the file */
127 	int children;		/* Count of existing children (so we don't free
128 				 * this thing too early or never nuke it) */
129 #ifdef DEBUG_SRC
130 	LIST	    cp; 	/* Debug; children list */
131 #endif
132 } Src;
133 
134 /*
135  * A structure for passing more than one argument to the Lst-library-invoked
136  * function...
137  */
138 typedef struct {
139 	Lst l;
140 	Src *s;
141 } LstSrc;
142 
143 static Suff *emptySuff; /* The empty suffix required for POSIX
144 			 * single-suffix transformation rules */
145 
146 
147 #define parse_transform(s, p, q) parse_transformi(s, s + strlen(s), p, q)
148 static bool parse_transformi(const char *, const char *, Suff **, Suff **);
149 #define new_suffix(s)	new_suffixi(s, NULL)
150 static Suff *new_suffixi(const char *, const char *);
151 static void reverse_hash_add_char(uint32_t *, const char *);
152 static uint32_t reverse_hashi(const char *, const char **);
153 static unsigned int reverse_slot(struct ohash *, const char *, const char **);
154 static void record_possible_suffix(Suff *, GNode *, char *, Lst, Lst);
155 static void record_possible_suffixes(GNode *, Lst, Lst);
156 static Suff *find_suffix_as_suffix(Lst, const char *, const char *);
157 static Suff *add_suffixi(const char *, const char *);
158 
159 static void SuffInsert(Lst, Suff *);
160 static void SuffAddSrc(void *, void *);
161 static bool SuffRemoveSrc(Lst);
162 static void SuffAddLevel(Lst, Src *);
163 static Src *SuffFindThem(Lst, Lst);
164 static Src *SuffFindCmds(Src *, Lst);
165 static bool SuffApplyTransform(GNode *, GNode *, Suff *, Suff *);
166 static void SuffFindDeps(GNode *, Lst);
167 static void SuffFindArchiveDeps(GNode *, Lst);
168 static void SuffFindNormalDeps(GNode *, Lst);
169 static void SuffPrintName(void *);
170 static void SuffPrintSuff(void *);
171 static void SuffPrintTrans(GNode *);
172 
173 #define find_suff(name)	find_suffi(name, NULL)
174 static Suff *find_suffi(const char *, const char *);
175 static Suff *find_best_suffix(const char *, const char *);
176 static GNode *find_transform(const char *);
177 static GNode *find_or_create_transformi(const char *, const char *);
178 static void setup_paths(void);
179 static void build_suffixes_graph(void);
180 static void special_path_hack(void);
181 
182 #ifdef DEBUG_SRC
183 static void PrintAddr(void *);
184 #endif
185 
186 /* hash functions for the suffixes hash */
187 /* add one char to the hash */
188 static void
189 reverse_hash_add_char(uint32_t *pk, const char *s)
190 {
191 	*pk =  ((*pk << 2) | (*pk >> 30)) ^ *s;
192 }
193 
194 /* build a full hash from end to start */
195 static uint32_t
196 reverse_hashi(const char *s, const char **e)
197 {
198 	const char *p;
199 	uint32_t k;
200 
201 	if (*e == NULL)
202 		*e = s + strlen(s);
203 	p = *e;
204 	if (p == s)
205 		k = 0;
206 	else
207 		k = *--p;
208 	while (p != s) {
209 		reverse_hash_add_char(&k, --p);
210 	}
211 	return k;
212 }
213 
214 static unsigned int
215 reverse_slot(struct ohash *h, const char *s, const char **e)
216 {
217 	uint32_t hv;
218 
219 	hv = reverse_hashi(s, e);
220 	return ohash_lookup_interval(h, s, *e, hv);
221 }
222 
223 
224 static char *
225 suffix_is_suffix(Suff *s, const char *str, const char *estr)
226 {
227 	const char *p1; 	/* Pointer into suffix name */
228 	const char *p2; 	/* Pointer into string being examined */
229 
230 	if (estr - str < (ptrdiff_t) s->nameLen)
231 		return NULL;
232 	p1 = s->name + s->nameLen;
233 	p2 = estr;
234 
235 	while (p1 != s->name) {
236 		p1--;
237 		p2--;
238 		if (*p1 != *p2)
239 			return NULL;
240 	}
241 
242 	return (char *)p2;
243 }
244 
245 static Suff *
246 find_suffi(const char *name, const char *ename)
247 {
248 	unsigned int slot;
249 #ifdef STATS_SUFF
250 	STAT_SUFF_LOOKUP_NAME++;
251 #endif
252 	slot = reverse_slot(&suffixes, name, &ename);
253 	return ohash_find(&suffixes, slot);
254 }
255 
256 static GNode *
257 find_transform(const char *name)
258 {
259 	unsigned int slot;
260 
261 #ifdef STATS_SUFF
262 	STAT_TRANSFORM_LOOKUP_NAME++;
263 #endif
264 	slot = ohash_qlookup(&transforms, name);
265 
266 	return ohash_find(&transforms, slot);
267 }
268 
269 static GNode *
270 find_or_create_transformi(const char *name, const char *end)
271 {
272 	GNode *r;
273 	unsigned int slot;
274 
275 #ifdef STATS_SUFF
276 	STAT_TRANSFORM_LOOKUP_NAME++;
277 #endif
278 	slot = ohash_qlookupi(&transforms, name, &end);
279 
280 	r = ohash_find(&transforms, slot);
281 
282 	if (r == NULL) {
283 		r = Targ_NewGNi(name, end);
284 		ohash_insert(&transforms, slot, r);
285 	}
286 	return r;
287 }
288 
289 /*-
290  *-----------------------------------------------------------------------
291  * SuffInsert  --
292  *	Insert the suffix into the list keeping the list ordered by suffix
293  *	numbers.
294  *
295  * Side Effects:
296  *	The reference count of the suffix is incremented
297  *-----------------------------------------------------------------------
298  */
299 static void
300 SuffInsert(Lst l, Suff *s)
301 {
302 	LstNode ln;		/* current element in l we're examining */
303 	Suff *s2 = NULL;	/* the suffix descriptor in this element */
304 
305 	for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) {
306 		s2 = Lst_Datum(ln);
307 		if (s2->order >= s->order)
308 			break;
309 	}
310 
311 	if (DEBUG(SUFF))
312 		printf("inserting %s(%d)...", s->name, s->order);
313 	if (ln == NULL) {
314 		if (DEBUG(SUFF))
315 			printf("at end of list\n");
316 		Lst_AtEnd(l, s);
317 	} else if (s2->order != s->order) {
318 		if (DEBUG(SUFF))
319 			printf("before %s(%d)\n", s2->name, s2->order);
320 		Lst_Insert(l, ln, s);
321 	} else if (DEBUG(SUFF)) {
322 		printf("already there\n");
323 	}
324 }
325 
326 /* Suff_DisableAllSuffixes
327  *	mark all current suffixes as inactive, and reset precedence
328  *	computation.  */
329 void
330 Suff_DisableAllSuffixes(void)
331 {
332 	unsigned int i;
333 	Suff *s;
334 
335 	for (s = ohash_first(&suffixes, &i); s != NULL;
336 	    s = ohash_next(&suffixes, &i))
337 		s->flags &= ~SUFF_ACTIVE;
338 
339 	order = 0;
340 	maxLen = 0;
341 }
342 
343 
344 /* okay = parse_transform(str, &src, &targ);
345  * 	try parsing a string as a transformation rule, returns true if
346  *	successful. Fills &src, &targ with the constituent suffixes.
347  * Special hack: source suffixes must exist OR be the special SUFF_PATH
348  * pseudo suffix (.PATH)
349  */
350 static bool
351 parse_transformi(const char *str, const char *e, Suff **srcPtr, Suff **targPtr)
352 {
353 	Suff *src, *target, *best_src, *best_target;
354 	const char *p;
355 
356 	size_t len;
357 	uint32_t hv;
358 	unsigned int slot;
359 
360 	/* empty string -> no suffix */
361 	if (e == str)
362 		return false;
363 
364 	len = e - str;
365 
366 	if (len > 2 * maxLen)
367 		return false;
368 
369 	p = e;
370 	best_src = best_target = NULL;
371 
372 	hv = *--p;
373 	while (p != str) {
374 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
375 		/* no double suffix in there */
376 		if (p - str <= (ptrdiff_t)maxLen) {
377 			target = ohash_find(&suffixes, slot);
378 			if (target != NULL && (target->flags & SUFF_ACTIVE)) {
379 				src = find_suffi(str, p);
380 				if (src != NULL &&
381 				    (src->flags & (SUFF_ACTIVE | SUFF_PATH))) {
382 				/* XXX even if we find a set of suffixes, we
383 				 * have to keep going to find the best one,
384 				 * namely, the one whose src appears first in
385 				 * .SUFFIXES
386 				 */
387 					if (best_src == NULL ||
388 					    src->order < best_src->order) {
389 						best_src = src;
390 						best_target = target;
391 					}
392 				}
393 			}
394 		}
395 		/* can't be a suffix anyways */
396 		if (e - p >= (ptrdiff_t)maxLen)
397 			break;
398 		reverse_hash_add_char(&hv, --p);
399 	}
400 
401 	if (p == str && best_src == NULL) {
402 		/* no double suffix transformation, resort to single suffix if
403 		 * we find one.  */
404 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
405 		src = ohash_find(&suffixes, slot);
406 		if (src != NULL && (src->flags & (SUFF_ACTIVE | SUFF_PATH))) {
407 			best_src = src;
408 			best_target = emptySuff;
409 		}
410 	}
411 	if (best_src != NULL) {
412 		*srcPtr = best_src;
413 		*targPtr = best_target;
414 		return true;
415 	} else {
416 		return false;
417 	}
418 }
419 
420 static void
421 special_path_hack(void)
422 {
423 	Suff *path = add_suffixi(".PATH", NULL);
424 	path->flags |= SUFF_PATH;
425 }
426 
427 static Suff *
428 find_best_suffix(const char *s, const char *e)
429 {
430 	const char *p;
431 	uint32_t hv;
432 	unsigned int slot;
433 	Suff *best = NULL;
434 	Suff *suff;
435 
436 	if (e == s)
437 		return NULL;
438 	p = e;
439 	hv = *--p;
440 	while (p != s) {
441 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
442 		suff = ohash_find(&suffixes, slot);
443 		if (suff != NULL)
444 			if (best == NULL || suff->order < best->order)
445 				best = suff;
446 		if (e - p >= (ptrdiff_t)maxLen)
447 			break;
448 		reverse_hash_add_char(&hv, --p);
449 	}
450 	return best;
451 }
452 
453 Lst
454 find_best_path(const char *name)
455 {
456 	Suff *s = find_best_suffix(name, name + strlen(name));
457 	if (s != NULL) {
458 		if (DEBUG(SUFF))
459 			printf("suffix is \"%s\"...", s->name);
460 		return &s->searchPath;
461 	} else
462 		return defaultPath;
463 }
464 
465 /*-
466  *-----------------------------------------------------------------------
467  * Suff_ParseAsTransform --
468  *	Try parsing a target line as a transformation rule, depending on
469  *	existing suffixes.
470  *
471  *	Possibly create a new transform, or reset an existing one.
472  *-----------------------------------------------------------------------
473  */
474 GNode *
475 Suff_ParseAsTransform(const char *line, const char *end)
476 {
477 	GNode *gn;	/* GNode of transformation rule */
478 	Suff *s;	/* source suffix */
479 	Suff *t;	/* target suffix */
480 
481 	if (!parse_transformi(line, end, &s, &t))
482 		return NULL;
483 
484 	gn = find_or_create_transformi(line, end);
485 	/* In case the transform already exists, nuke old commands and children.
486 	 * Note we can't free them, since there might be stuff that references
487 	 * them elsewhere
488 	 */
489 	if (!Lst_IsEmpty(&gn->commands)) {
490 		Lst_Destroy(&gn->commands, NOFREE);
491 		Lst_Init(&gn->commands);
492 	}
493 	if (!Lst_IsEmpty(&gn->children)) {
494 		Lst_Destroy(&gn->children, NOFREE);
495 		Lst_Init(&gn->children);
496 	}
497 
498 	gn->type = OP_TRANSFORM;
499 	if (s->flags & SUFF_PATH) {
500 		gn->special = SPECIAL_PATH;
501 		gn->suffix = t;
502 	}
503 
504 	if (DEBUG(SUFF))
505 		printf("defining transformation from `%s' to `%s'\n",
506 		    s->name, t->name);
507 	return gn;
508 }
509 
510 static void
511 make_suffix_known(Suff *s)
512 {
513 	if ((s->flags & SUFF_ACTIVE) == 0) {
514 		s->order = order++;
515 		s->flags |= SUFF_ACTIVE;
516 		if (s->nameLen > maxLen)
517 			maxLen = s->nameLen;
518 	}
519 }
520 
521 static Suff *
522 new_suffixi(const char *str, const char *eptr)
523 {
524 	Suff *s;
525 
526 	s = ohash_create_entry(&suff_info, str, &eptr);
527 	s->nameLen = eptr - str;
528 	Lst_Init(&s->searchPath);
529 	Lst_Init(&s->children);
530 	Lst_Init(&s->parents);
531 	s->flags = 0;
532 	return s;
533 }
534 
535 /*-
536  *-----------------------------------------------------------------------
537  * Suff_AddSuffix --
538  *	Add the suffix in string to the end of the list of known suffixes.
539  *	Should we restructure the suffix graph? Make doesn't...
540  *
541  * Side Effects:
542  *	A GNode is created for the suffix and a Suff structure is created and
543  *	added to the known suffixes, unless it was already known.
544  *-----------------------------------------------------------------------
545  */
546 void
547 Suff_AddSuffixi(const char *str, const char *end)
548 {
549 	(void)add_suffixi(str, end);
550 }
551 
552 static Suff *
553 add_suffixi(const char *str, const char *end)
554 {
555 	Suff *s;	    /* new suffix descriptor */
556 
557 	unsigned int slot;
558 
559 	slot = reverse_slot(&suffixes, str, &end);
560 	s = ohash_find(&suffixes, slot);
561 	if (s == NULL) {
562 		s = new_suffixi(str, end);
563 		ohash_insert(&suffixes, slot, s);
564 	}
565 	make_suffix_known(s);
566 	return s;
567 }
568 
569 Lst
570 find_suffix_path(GNode *gn)
571 {
572 	if (gn->suffix != NULL && gn->suffix != emptySuff)
573 		return &(gn->suffix->searchPath);
574 	else
575 		return defaultPath;
576 }
577 
578 static void
579 build_suffixes_graph(void)
580 {
581 	Suff *s, *s2;
582 	GNode *gn;
583 	unsigned int i;
584 
585 	for (gn = ohash_first(&transforms, &i); gn != NULL;
586 	    gn = ohash_next(&transforms, &i)) {
587 	    	if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children))
588 			continue;
589 		if (gn->special == SPECIAL_PATH)
590 			continue;
591 	    	if (parse_transform(gn->name, &s, &s2)) {
592 			SuffInsert(&s2->children, s);
593 			SuffInsert(&s->parents, s2);
594 		}
595 	}
596 }
597 
598 /*-
599  *-----------------------------------------------------------------------
600  * setup_paths
601  *	Extend the search paths for all suffixes to include the default
602  *	search path.
603  *
604  * Side Effects:
605  *	The searchPath field of all the suffixes is extended by the
606  *	directories in defaultPath.
607  *-----------------------------------------------------------------------
608  */
609 static void
610 setup_paths(void)
611 {
612 	unsigned int i;
613 	Suff *s;
614 
615 	for (s = ohash_first(&suffixes, &i); s != NULL;
616 	    s = ohash_next(&suffixes, &i)) {
617 		if (!Lst_IsEmpty(&s->searchPath))
618 			Dir_Concat(&s->searchPath, defaultPath);
619 		else
620 			Lst_Clone(&s->searchPath, defaultPath, Dir_CopyDir);
621 	}
622 }
623 
624 void
625 process_suffixes_after_makefile_is_read(void)
626 {
627 	/* once the Makefile is finish reading, we can set up the default PATH
628 	 * stuff, and build the final suffixes graph
629 	 */
630 	setup_paths();
631 	/* and we link all transforms to active suffixes at this point. */
632 	build_suffixes_graph();
633 }
634 	  /********** Implicit Source Search Functions *********/
635 
636 /*-
637  *-----------------------------------------------------------------------
638  * SuffAddSrc  --
639  *	Add a suffix as a Src structure to the given list with its parent
640  *	being the given Src structure. If the suffix is the null suffix,
641  *	the prefix is used unaltered as the file name in the Src structure.
642  *
643  * Side Effects:
644  *	A Src structure is created and tacked onto the end of the list
645  *-----------------------------------------------------------------------
646  */
647 static void
648 SuffAddSrc(
649     void *sp,		/* suffix for which to create a Src structure */
650     void *lsp)		/* list and parent for the new Src */
651 {
652 	Suff *s = sp;
653 	LstSrc *ls = lsp;
654 	Src *s2;	/* new Src structure */
655 	Src *targ;	/* Target structure */
656 
657 	targ = ls->s;
658 
659 	s2 = emalloc(sizeof(Src));
660 	s2->file = Str_concat(targ->prefix, s->name, 0);
661 	s2->prefix = targ->prefix;
662 	s2->parent = targ;
663 	s2->node = NULL;
664 	s2->suff = s;
665 	s2->children = 0;
666 	targ->children++;
667 	Lst_AtEnd(ls->l, s2);
668 #ifdef DEBUG_SRC
669 	Lst_Init(&s2->cp);
670 	Lst_AtEnd(&targ->cp, s2);
671 	printf("2 add %x %x to %x:", targ, s2, ls->l);
672 	Lst_Every(ls->l, PrintAddr);
673 	printf("\n");
674 #endif
675 
676 }
677 
678 /*-
679  *-----------------------------------------------------------------------
680  * SuffAddLevel  --
681  *	Add all the children of targ as Src structures to the given list
682  *
683  * Side Effects:
684  *	Lots of structures are created and added to the list
685  *-----------------------------------------------------------------------
686  */
687 static void
688 SuffAddLevel(
689     Lst l,	/* list to which to add the new level */
690     Src *targ)	/* Src structure to use as the parent */
691 {
692 	LstSrc	   ls;
693 
694 	ls.s = targ;
695 	ls.l = l;
696 
697 	Lst_ForEach(&targ->suff->children, SuffAddSrc, &ls);
698 }
699 
700 /*-
701  *----------------------------------------------------------------------
702  * SuffRemoveSrc --
703  *	Free Src structure with a zero reference count in a list
704  *
705  *	returns true if a src was removed
706  *----------------------------------------------------------------------
707  */
708 static bool
709 SuffRemoveSrc(Lst l)
710 {
711 	LstNode ln;
712 	Src *s;
713 
714 #ifdef DEBUG_SRC
715 	printf("cleaning %lx: ", (unsigned long)l);
716 	Lst_Every(l, PrintAddr);
717 	printf("\n");
718 #endif
719 
720 
721 	for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) {
722 		s = Lst_Datum(ln);
723 		if (s->children == 0) {
724 			free(s->file);
725 			if (!s->parent)
726 				free(s->prefix);
727 			else {
728 #ifdef DEBUG_SRC
729 				LstNode ln2 = Lst_Member(&s->parent->cp, s);
730 				if (ln2 != NULL)
731 				    Lst_Remove(&s->parent->cp, ln2);
732 #endif
733 				--s->parent->children;
734 			}
735 #ifdef DEBUG_SRC
736 			printf("free: [l=%x] p=%x %d\n", l, s, s->children);
737 			Lst_Destroy(&s->cp, NOFREE);
738 #endif
739 			Lst_Remove(l, ln);
740 			free(s);
741 			return true;
742 		}
743 #ifdef DEBUG_SRC
744 		else {
745 			printf("keep: [l=%x] p=%x %d: ", l, s, s->children);
746 			Lst_Every(&s->cp, PrintAddr);
747 			printf("\n");
748 		}
749 #endif
750 	}
751 
752 	return false;
753 }
754 
755 /*-
756  *-----------------------------------------------------------------------
757  * SuffFindThem --
758  *	Find the first existing file/target in the list srcs
759  *
760  * Results:
761  *	The lowest structure in the chain of transformations
762  *-----------------------------------------------------------------------
763  */
764 static Src *
765 SuffFindThem(
766     Lst srcs,	/* list of Src structures to search through */
767     Lst slst)
768 {
769 	Src *s;		/* current Src */
770 	Src *rs; 	/* returned Src */
771 	char *ptr;
772 
773 	rs = NULL;
774 
775 	while ((s = Lst_DeQueue(srcs)) != NULL) {
776 		if (DEBUG(SUFF))
777 			printf("\ttrying %s...", s->file);
778 
779 		/*
780 		 * A file is considered to exist if either a node exists in the
781 		 * graph for it or the file actually exists.
782 		 */
783 		if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) {
784 #ifdef DEBUG_SRC
785 			printf("remove %x from %x\n", s, srcs);
786 #endif
787 			rs = s;
788 			break;
789 		}
790 
791 		if ((ptr = Dir_FindFile(s->file, &s->suff->searchPath))
792 		    != NULL) {
793 			rs = s;
794 #ifdef DEBUG_SRC
795 			printf("remove %x from %x\n", s, srcs);
796 #endif
797 			free(ptr);
798 			break;
799 		}
800 
801 		if (DEBUG(SUFF))
802 		    printf("not there\n");
803 
804 		SuffAddLevel(srcs, s);
805 		Lst_AtEnd(slst, s);
806 	}
807 
808 	if (DEBUG(SUFF) && rs)
809 	    printf("got it\n");
810 	return rs;
811 }
812 
813 /*-
814  *-----------------------------------------------------------------------
815  * SuffFindCmds --
816  *	See if any of the children of the target in the Src structure is
817  *	one from which the target can be transformed. If there is one,
818  *	a Src structure is put together for it and returned.
819  *-----------------------------------------------------------------------
820  */
821 static Src *
822 SuffFindCmds(Src *targ, Lst slst)
823 {
824 	LstNode ln;	/* General-purpose list node */
825 	GNode *t;	/* Target GNode */
826 	GNode *s;	/* Source GNode */
827 	int prefixLen;	/* The length of the defined prefix */
828 	Suff *suff;	/* Suffix on matching beastie */
829 	Src *ret;	/* Return value */
830 	const char *cp;
831 
832 	t = targ->node;
833 	prefixLen = strlen(targ->prefix);
834 
835 	for (ln = Lst_First(&t->children); ln != NULL; ln = Lst_Adv(ln)) {
836 		s = Lst_Datum(ln);
837 
838 		cp = strrchr(s->name, '/');
839 		if (cp == NULL)
840 			cp = s->name;
841 		else
842 			cp++;
843 		if (strncmp(cp, targ->prefix, prefixLen) != 0)
844 			continue;
845 		/* The node matches the prefix ok, see if it has a known
846 		 * suffix.	*/
847 		suff = find_suff(&cp[prefixLen]);
848 		if (suff == NULL)
849 			continue;
850 		/*
851 		 * It even has a known suffix, see if there's a transformation
852 		 * defined between the node's suffix and the target's suffix.
853 		 *
854 		 * XXX: Handle multi-stage transformations here, too.
855 		 */
856 		if (Lst_Member(&suff->parents, targ->suff) == NULL)
857 			continue;
858 		/*
859 		 * Create a new Src structure to describe this transformation
860 		 * (making sure to duplicate the source node's name so
861 		 * Suff_FindDeps can free it again (ick)), and return the new
862 		 * structure.
863 		 */
864 		ret = emalloc(sizeof(Src));
865 		ret->file = estrdup(s->name);
866 		ret->prefix = targ->prefix;
867 		ret->suff = suff;
868 		ret->parent = targ;
869 		ret->node = s;
870 		ret->children = 0;
871 		targ->children++;
872 #ifdef DEBUG_SRC
873 		Lst_Init(&ret->cp);
874 		printf("3 add %x %x\n", targ, ret);
875 		Lst_AtEnd(&targ->cp, ret);
876 #endif
877 		Lst_AtEnd(slst, ret);
878 		if (DEBUG(SUFF))
879 			printf("\tusing existing source %s\n", s->name);
880 		return ret;
881 	}
882 	return NULL;
883 }
884 
885 /*-
886  *-----------------------------------------------------------------------
887  * SuffApplyTransform --
888  *	Apply a transformation rule, given the source and target nodes
889  *	and suffixes.
890  *
891  * Results:
892  *	true if successful, false if not.
893  *
894  * Side Effects:
895  *	The source and target are linked and the commands from the
896  *	transformation are added to the target node's commands list.
897  *	All attributes but OP_DEPMASK and OP_TRANSFORM are applied
898  *	to the target. The target also inherits all the sources for
899  *	the transformation rule.
900  *-----------------------------------------------------------------------
901  */
902 static bool
903 SuffApplyTransform(
904     GNode	*tGn,	/* Target node */
905     GNode	*sGn,	/* Source node */
906     Suff	*t,	/* Target suffix */
907     Suff	*s)	/* Source suffix */
908 {
909 	LstNode	ln;	/* General node */
910 	char	*tname; /* Name of transformation rule */
911 	GNode	*gn;	/* Node for same */
912 
913 	if (Lst_AddNew(&tGn->children, sGn)) {
914 		/* Not already linked, so form the proper links between the
915 		 * target and source.  */
916 		LinkParent(sGn, tGn);
917 	}
918 
919 	if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) {
920 		/* When a :: node is used as the implied source of a node, we
921 		 * have to link all its cohorts in as sources as well. There's
922 		 * only one implied src, as that will be sufficient to get
923 		 * the .IMPSRC variable set for tGn.	*/
924 		for (ln=Lst_First(&sGn->cohorts); ln != NULL; ln=Lst_Adv(ln)) {
925 			gn = Lst_Datum(ln);
926 
927 			if (Lst_AddNew(&tGn->children, gn)) {
928 				/* Not already linked, so form the proper links
929 				 * between the target and source.  */
930 				LinkParent(gn, tGn);
931 			}
932 		}
933 	}
934 	/* Locate the transformation rule itself.  */
935 	tname = Str_concat(s->name, t->name, 0);
936 	gn = find_transform(tname);
937 	free(tname);
938 
939 	if (gn == NULL)
940 		/*
941 		 * Not really such a transformation rule (can happen when we're
942 		 * called to link an OP_MEMBER and OP_ARCHV node), so return
943 		 * false.
944 		 */
945 		return false;
946 
947 	if (DEBUG(SUFF))
948 		printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name,
949 		    tGn->name);
950 
951 	/* Record last child for expansion purposes.  */
952 	ln = Lst_Last(&tGn->children);
953 
954 	/* Pass the buck to Make_HandleUse to apply the rule.  */
955 	Make_HandleUse(gn, tGn);
956 
957 	/* Deal with wildcards and variables in any acquired sources.  */
958 	expand_children_from(tGn, Lst_Succ(ln));
959 
960 	/* Keep track of another parent to which this beast is transformed so
961 	 * the .IMPSRC variable can be set correctly for the parent.  */
962 	tGn->impliedsrc = sGn;
963 
964 	return true;
965 }
966 
967 static Suff *
968 find_suffix_as_suffix(Lst l, const char *b, const char *e)
969 {
970 	LstNode ln;
971 	Suff *s;
972 
973 	for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) {
974 		s = Lst_Datum(ln);
975 		if (suffix_is_suffix(s, b, e))
976 			return s;
977 	}
978 	return NULL;
979 }
980 
981 /*-
982  *-----------------------------------------------------------------------
983  * SuffFindArchiveDeps --
984  *	Locate dependencies for an OP_ARCHV node.
985  *
986  * Side Effects:
987  *	Same as Suff_FindDeps
988  *-----------------------------------------------------------------------
989  */
990 static void
991 SuffFindArchiveDeps(
992     GNode	*gn,    /* Node for which to locate dependencies */
993     Lst 	slst)
994 {
995 	char *eoarch;	/* End of archive portion */
996 	char *eoname;	/* End of member portion */
997 	GNode *mem;	/* Node for member */
998 	Suff *ms;	/* Suffix descriptor for member */
999 	char *name;	/* Start of member's name */
1000 
1001 	/* The node is an archive(member) pair. so we must find a suffix
1002 	 * for both of them.  */
1003 	eoarch = strchr(gn->name, '(');
1004 	if (eoarch == NULL)
1005 		return;
1006 
1007 	name = eoarch + 1;
1008 
1009 	eoname = strchr(name, ')');
1010 	if (eoname == NULL)
1011 		return;
1012 
1013 	/* To simplify things, call Suff_FindDeps recursively on the member now,
1014 	 * so we can simply compare the member's .PREFIX and .TARGET variables
1015 	 * to locate its suffix. This allows us to figure out the suffix to
1016 	 * use for the archive without having to do a quadratic search over the
1017 	 * suffix list, backtracking for each one...  */
1018 	mem = Targ_FindNodei(name, eoname, TARG_CREATE);
1019 	SuffFindDeps(mem, slst);
1020 
1021 	/* Create the link between the two nodes right off. */
1022 	if (Lst_AddNew(&gn->children, mem))
1023 		LinkParent(mem, gn);
1024 
1025 	/* Copy variables from member node to this one.  */
1026 	Var(TARGET_INDEX, gn) = Var(TARGET_INDEX, mem);
1027 	Var(PREFIX_INDEX, gn) = Var(PREFIX_INDEX, mem);
1028 
1029 	ms = mem->suffix;
1030 	if (ms == NULL) {
1031 		/* Didn't know what it was -- use .NULL suffix if not in make
1032 		 * mode.  */
1033 		if (DEBUG(SUFF))
1034 			printf("using empty suffix\n");
1035 		ms = emptySuff;
1036 	}
1037 
1038 
1039 	/* Set the other two local variables required for this target.  */
1040 	Var(MEMBER_INDEX, gn) = mem->name;
1041 	Var(ARCHIVE_INDEX, gn) = gn->name;
1042 
1043 	if (ms != NULL) {
1044 		/*
1045 		 * Member has a known suffix, so look for a transformation rule
1046 		 * from it to a possible suffix of the archive. Rather than
1047 		 * searching through the entire list, we just look at suffixes
1048 		 * to which the member's suffix may be transformed...
1049 		 */
1050 
1051 		Suff *suff;
1052 
1053 		suff = find_suffix_as_suffix(&ms->parents, gn->name, eoarch);
1054 
1055 		if (suff != NULL) {
1056 			/* Got one -- apply it.  */
1057 			if (!SuffApplyTransform(gn, mem, suff, ms) &&
1058 			    DEBUG(SUFF))
1059 				printf("\tNo transformation from %s -> %s\n",
1060 				   ms->name, suff->name);
1061 		}
1062 	}
1063 
1064 	/* Pretend gn appeared to the left of a dependency operator so
1065 	 * the user needn't provide a transformation from the member to the
1066 	 * archive.  */
1067 	if (OP_NOP(gn->type))
1068 		gn->type |= OP_DEPENDS;
1069 
1070 	/* Flag the member as such so we remember to look in the archive for
1071 	 * its modification time.  */
1072 	mem->type |= OP_MEMBER;
1073 }
1074 
1075 static void
1076 record_possible_suffix(Suff *s, GNode *gn, char *eoname, Lst srcs, Lst targs)
1077 {
1078 	int prefixLen;
1079 	Src *targ;
1080 
1081 	targ = emalloc(sizeof(Src));
1082 	targ->file = estrdup(gn->name);
1083 	targ->suff = s;
1084 	targ->node = gn;
1085 	targ->parent = NULL;
1086 	targ->children = 0;
1087 #ifdef DEBUG_SRC
1088 	Lst_Init(&targ->cp);
1089 #endif
1090 
1091 	/* Allocate room for the prefix, whose end is found by
1092 	 * subtracting the length of the suffix from the end of
1093 	 * the name.  */
1094 	prefixLen = (eoname - targ->suff->nameLen) - gn->name;
1095 	targ->prefix = emalloc(prefixLen + 1);
1096 	memcpy(targ->prefix, gn->name, prefixLen);
1097 	targ->prefix[prefixLen] = '\0';
1098 
1099 	/* Add nodes from which the target can be made.  */
1100 	SuffAddLevel(srcs, targ);
1101 
1102 	/* Record the target so we can nuke it.  */
1103 	Lst_AtEnd(targs, targ);
1104 }
1105 
1106 static void
1107 record_possible_suffixes(GNode *gn, Lst srcs, Lst targs)
1108 {
1109 	char *s = gn->name;
1110 	char *e =  s + strlen(s);
1111 	const char *p;
1112 	uint32_t hv;
1113 	unsigned int slot;
1114 	Suff *suff;
1115 
1116 	if (e == s)
1117 		return;
1118 
1119 	p = e;
1120 	hv = *--p;
1121 
1122 	while (p != s) {
1123 		slot = ohash_lookup_interval(&suffixes, p, e, hv);
1124 		suff = ohash_find(&suffixes, slot);
1125 		if (suff != NULL && (suff->flags & SUFF_ACTIVE))
1126 			record_possible_suffix(suff, gn, e, srcs, targs);
1127 		if (e - p >= (ptrdiff_t)maxLen)
1128 			break;
1129 		reverse_hash_add_char(&hv, --p);
1130 	}
1131 }
1132 
1133 /*-
1134  *-----------------------------------------------------------------------
1135  * SuffFindNormalDeps --
1136  *	Locate implicit dependencies for regular targets.
1137  *
1138  * Side Effects:
1139  *	Same as Suff_FindDeps...
1140  *-----------------------------------------------------------------------
1141  */
1142 static void
1143 SuffFindNormalDeps(
1144     GNode	*gn,	    /* Node for which to find sources */
1145     Lst 	slst)
1146 {
1147 	LIST srcs;	/* List of sources at which to look */
1148 	LIST targs;	/* List of targets to which things can be
1149 			 * transformed. They all have the same file,
1150 			 * but different suff and prefix fields */
1151 	Src *bottom;    /* Start of found transformation path */
1152 	Src *src;	/* General Src pointer */
1153 	char *prefix;	/* Prefix to use */
1154 	Src *targ;	/* General Src target pointer */
1155 
1156 
1157 	Lst_Init(&srcs);
1158 	Lst_Init(&targs);
1159 
1160 	/* We're caught in a catch-22 here. On the one hand, we want to use any
1161 	 * transformation implied by the target's sources, but we can't examine
1162 	 * the sources until we've expanded any variables/wildcards they may
1163 	 * hold, and we can't do that until we've set up the target's local
1164 	 * variables and we can't do that until we know what the proper suffix
1165 	 * for the target is (in case there are two suffixes one of which is a
1166 	 * suffix of the other) and we can't know that until we've found its
1167 	 * implied source, which we may not want to use if there's an existing
1168 	 * source that implies a different transformation.
1169 	 *
1170 	 * In an attempt to get around this, which may not work all the time,
1171 	 * but should work most of the time, we look for implied sources first,
1172 	 * checking transformations to all possible suffixes of the target, use
1173 	 * what we find to set the target's local variables, expand the
1174 	 * children, then look for any overriding transformations they imply.
1175 	 * Should we find one, we discard the one we found before.	*/
1176 
1177 
1178 	record_possible_suffixes(gn, &srcs, &targs);
1179 	/* Handle target of unknown suffix...  */
1180 	if (Lst_IsEmpty(&srcs)) {
1181 		if (DEBUG(SUFF))
1182 			printf("\tNo known suffix on %s. Using empty suffix\n",
1183 			    gn->name);
1184 
1185 		targ = emalloc(sizeof(Src));
1186 		targ->file = estrdup(gn->name);
1187 		targ->suff = emptySuff;
1188 		targ->node = gn;
1189 		targ->parent = NULL;
1190 		targ->children = 0;
1191 		targ->prefix = estrdup(gn->name);
1192 #ifdef DEBUG_SRC
1193 		Lst_Init(&targ->cp);
1194 #endif
1195 
1196 		/* Only use the default suffix rules if we don't have commands
1197 		 * or dependencies defined for this gnode.  */
1198 		if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children))
1199 			SuffAddLevel(&srcs, targ);
1200 		else {
1201 			if (DEBUG(SUFF))
1202 				printf("not ");
1203 		}
1204 
1205 		if (DEBUG(SUFF))
1206 			printf("adding suffix rules\n");
1207 
1208 		Lst_AtEnd(&targs, targ);
1209 	}
1210 
1211 	/* Using the list of possible sources built up from the target
1212 	 * suffix(es), try and find an existing file/target that matches.  */
1213 	bottom = SuffFindThem(&srcs, slst);
1214 
1215 	if (bottom == NULL) {
1216 		/* No known transformations -- use the first suffix found for
1217 		 * setting the local variables.  */
1218 		if (!Lst_IsEmpty(&targs))
1219 			targ = Lst_Datum(Lst_First(&targs));
1220 		else
1221 			targ = NULL;
1222 	} else {
1223 		/* Work up the transformation path to find the suffix of the
1224 		 * target to which the transformation was made.  */
1225 		for (targ = bottom; targ->parent != NULL; targ = targ->parent)
1226 			continue;
1227 	}
1228 
1229 	/* The .TARGET variable we always set to be the name at this point,
1230 	 * since it's only set to the path if the thing is only a source and
1231 	 * if it's only a source, it doesn't matter what we put here as far
1232 	 * as expanding sources is concerned, since it has none...	*/
1233 	Var(TARGET_INDEX, gn) = gn->name;
1234 
1235 	prefix = targ != NULL ? estrdup(targ->prefix) : gn->name;
1236 	Var(PREFIX_INDEX, gn) = prefix;
1237 
1238 	/* Now we've got the important local variables set, expand any sources
1239 	 * that still contain variables or wildcards in their names.  */
1240 	expand_all_children(gn);
1241 
1242 	if (targ == NULL) {
1243 		if (DEBUG(SUFF))
1244 			printf("\tNo valid suffix on %s\n", gn->name);
1245 
1246 sfnd_abort:
1247 		/* Deal with finding the thing on the default search path if the
1248 		 * node is only a source (not on the lhs of a dependency operator
1249 		 * or [XXX] it has neither children or commands).  */
1250 		if (OP_NOP(gn->type) ||
1251 		    (Lst_IsEmpty(&gn->children) &&
1252 		    Lst_IsEmpty(&gn->commands))) {
1253 			gn->path = Dir_FindFile(gn->name,
1254 			    (targ == NULL ? defaultPath :
1255 			    &targ->suff->searchPath));
1256 			if (gn->path != NULL) {
1257 				char *ptr;
1258 				Var(TARGET_INDEX, gn) = estrdup(gn->path);
1259 
1260 				if (targ != NULL) {
1261 					/* Suffix known for the thing -- trim
1262 					 * the suffix off the path to form the
1263 					 * proper .PREFIX variable.  */
1264 					int savep = strlen(gn->path) -
1265 					    targ->suff->nameLen;
1266 					char savec;
1267 
1268 					gn->suffix = targ->suff;
1269 
1270 					savec = gn->path[savep];
1271 					gn->path[savep] = '\0';
1272 
1273 					if ((ptr = strrchr(gn->path, '/')) !=
1274 					    NULL)
1275 						ptr++;
1276 					else
1277 						ptr = gn->path;
1278 
1279 					Var(PREFIX_INDEX, gn) = estrdup(ptr);
1280 
1281 					gn->path[savep] = savec;
1282 				} else {
1283 					/* The .PREFIX gets the full path if the
1284 					 * target has no known suffix.  */
1285 					gn->suffix = NULL;
1286 
1287 					if ((ptr = strrchr(gn->path, '/')) !=
1288 					    NULL)
1289 						ptr++;
1290 					else
1291 						ptr = gn->path;
1292 
1293 					Var(PREFIX_INDEX, gn) = estrdup(ptr);
1294 				}
1295 			}
1296 		} else {
1297 			/* Not appropriate to search for the thing -- set the
1298 			 * path to be the name so Dir_MTime won't go grovelling
1299 			 * for it.  */
1300 			gn->suffix = targ == NULL ? NULL : targ->suff;
1301 			free(gn->path);
1302 			gn->path = estrdup(gn->name);
1303 		}
1304 
1305 		goto sfnd_return;
1306 	}
1307 
1308 	/* Check for overriding transformation rule implied by sources.  */
1309 	if (!Lst_IsEmpty(&gn->children)) {
1310 		src = SuffFindCmds(targ, slst);
1311 
1312 		if (src != NULL) {
1313 			/* Free up all the Src structures in the transformation
1314 			 * path up to, but not including, the parent node.  */
1315 			while (bottom && bottom->parent != NULL) {
1316 				(void)Lst_AddNew(slst, bottom);
1317 				bottom = bottom->parent;
1318 			}
1319 			bottom = src;
1320 		}
1321 	}
1322 
1323 	if (bottom == NULL) {
1324 		/* No idea from where it can come -- return now.  */
1325 		goto sfnd_abort;
1326 	}
1327 
1328 	/* We now have a list of Src structures headed by 'bottom' and linked
1329 	 * via their 'parent' pointers. What we do next is create links between
1330 	 * source and target nodes (which may or may not have been created) and
1331 	 * set the necessary local variables in each target. The commands for
1332 	 * each target are set from the commands of the transformation rule
1333 	 * used to get from the src suffix to the targ suffix. Note that this
1334 	 * causes the commands list of the original node, gn, to be replaced by
1335 	 * the commands of the final transformation rule. Also, the children
1336 	 * to build field of gn is incremented.  Etc.  */
1337 	if (bottom->node == NULL) {
1338 		bottom->node = Targ_FindNode(bottom->file, TARG_CREATE);
1339 	}
1340 
1341 	for (src = bottom; src->parent != NULL; src = src->parent) {
1342 		targ = src->parent;
1343 
1344 		src->node->suffix = src->suff;
1345 
1346 		if (targ->node == NULL) {
1347 			targ->node = Targ_FindNode(targ->file, TARG_CREATE);
1348 		}
1349 
1350 		SuffApplyTransform(targ->node, src->node,
1351 				   targ->suff, src->suff);
1352 
1353 		if (targ->node != gn) {
1354 			/* Finish off the dependency-search process for any
1355 			 * nodes between bottom and gn (no point in questing
1356 			 * around the filesystem for their implicit source when
1357 			 * it's already known). Note that the node can't have
1358 			 * any sources that need expanding, since SuffFindThem
1359 			 * will stop on an existing node, so all we need to do
1360 			 * is set the standard and System V variables.  */
1361 			targ->node->type |= OP_DEPS_FOUND;
1362 
1363 			Var(PREFIX_INDEX, targ->node) = estrdup(targ->prefix);
1364 
1365 			Var(TARGET_INDEX, targ->node) = targ->node->name;
1366 		}
1367 	}
1368 
1369 	gn->suffix = src->suff;
1370 
1371 	/* So Dir_MTime doesn't go questing for it...  */
1372 	free(gn->path);
1373 	gn->path = estrdup(gn->name);
1374 
1375 	/* Nuke the transformation path and the Src structures left over in the
1376 	 * two lists.  */
1377 sfnd_return:
1378 	if (bottom)
1379 		(void)Lst_AddNew(slst, bottom);
1380 
1381 	while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs))
1382 		continue;
1383 
1384 	Lst_ConcatDestroy(slst, &srcs);
1385 	Lst_ConcatDestroy(slst, &targs);
1386 }
1387 
1388 
1389 /*-
1390  *-----------------------------------------------------------------------
1391  * Suff_FindDeps  --
1392  *	Find implicit sources for the target described by the graph node
1393  *	gn
1394  *
1395  * Side Effects:
1396  *	Nodes are added to the graph below the passed-in node. The nodes
1397  *	are marked to have their IMPSRC variable filled in. The
1398  *	PREFIX variable is set for the given node and all its
1399  *	implied children.
1400  *
1401  * Notes:
1402  *	The path found by this target is the shortest path in the
1403  *	transformation graph, which may pass through non-existent targets,
1404  *	to an existing target. The search continues on all paths from the
1405  *	root suffix until a file is found. I.e. if there's a path
1406  *	.o -> .c -> .l -> .l,v from the root and the .l,v file exists but
1407  *	the .c and .l files don't, the search will branch out in
1408  *	all directions from .o and again from all the nodes on the
1409  *	next level until the .l,v node is encountered.
1410  *-----------------------------------------------------------------------
1411  */
1412 
1413 void
1414 Suff_FindDeps(GNode *gn)
1415 {
1416 
1417 	SuffFindDeps(gn, &srclist);
1418 	while (SuffRemoveSrc(&srclist))
1419 		continue;
1420 }
1421 
1422 
1423 static void
1424 SuffFindDeps(GNode *gn, Lst slst)
1425 {
1426 	if (gn->type & OP_DEPS_FOUND) {
1427 		/*
1428 		 * If dependencies already found, no need to do it again...
1429 		 */
1430 		return;
1431 	} else {
1432 		gn->type |= OP_DEPS_FOUND;
1433 	}
1434 
1435 	if (DEBUG(SUFF))
1436 		printf("SuffFindDeps (%s)\n", gn->name);
1437 
1438 	current_node = gn;
1439 	if (gn->type & OP_ARCHV)
1440 		SuffFindArchiveDeps(gn, slst);
1441 	else
1442 		SuffFindNormalDeps(gn, slst);
1443 	current_node = NULL;
1444 }
1445 
1446 /*-
1447  *-----------------------------------------------------------------------
1448  * Suff_Init --
1449  *	Initialize suffixes module
1450  *
1451  * Side Effects:
1452  *	Many
1453  *-----------------------------------------------------------------------
1454  */
1455 void
1456 Suff_Init(void)
1457 {
1458 	Static_Lst_Init(&srclist);
1459 	ohash_init(&transforms, 4, &gnode_info);
1460 
1461 	/* Create null suffix for single-suffix rules (POSIX). The thing doesn't
1462 	 * actually go on the suffix list as it matches everything.  */
1463 	emptySuff = new_suffix("");
1464 	emptySuff->flags = SUFF_ACTIVE;
1465 	emptySuff->order = 0;
1466 	Dir_Concat(&emptySuff->searchPath, defaultPath);
1467 	ohash_init(&suffixes, 4, &suff_info);
1468 	special_path_hack();
1469 }
1470 
1471 
1472 /********************* DEBUGGING FUNCTIONS **********************/
1473 
1474 static void
1475 SuffPrintName(void *p)
1476 {
1477 	const Suff *s = p;
1478 	printf("%s ", s == emptySuff ? "<empty>" : s->name);
1479 }
1480 
1481 static void
1482 SuffPrintSuff(void *sp)
1483 {
1484 	Suff    *s = sp;
1485 
1486 	printf("# %-5s ", s->name);
1487 
1488 	if (!Lst_IsEmpty(&s->parents)) {
1489 		printf(" ->");
1490 		Lst_Every(&s->parents, SuffPrintName);
1491 	}
1492 	if (!Lst_IsEmpty(&s->children)) {
1493 		printf(" <-");
1494 		Lst_Every(&s->children, SuffPrintName);
1495 	}
1496 	fputc('\n', stdout);
1497 }
1498 
1499 static void
1500 SuffPrintTrans(GNode *t)
1501 {
1502 	printf("%-16s: ", t->name);
1503 	Targ_PrintType(t->type);
1504 	fputc('\n', stdout);
1505 	Lst_Every(&t->commands, Targ_PrintCmd);
1506 	fputc('\n', stdout);
1507 }
1508 
1509 static int
1510 compare_order(const void *a, const void *b)
1511 {
1512 	const Suff **pa = (const Suff **)a;
1513 	const Suff **pb = (const Suff **)b;
1514 	return (*pb)->order - (*pa)->order;
1515 }
1516 
1517 static void
1518 print_path(Suff *s)
1519 {
1520 	/* do we need to print it ? compare against defaultPath */
1521 	LstNode ln1, ln2;
1522 	bool first = true;
1523 
1524 	for (ln1 = Lst_First(&s->searchPath), ln2 = Lst_First(defaultPath);
1525 	    ln1 != NULL && ln2 != NULL;
1526 	    ln1 = Lst_Adv(ln1)) {
1527 		if (Lst_Datum(ln1) == Lst_Datum(ln2)) {
1528 			ln2 = Lst_Adv(ln2);
1529 			continue;
1530 		}
1531 		if (first) {
1532 			printf(".PATH%s:", s->name);
1533 			first = false;
1534 		}
1535 		printf(" %s", PathEntry_name(Lst_Datum(ln1)));
1536 	}
1537 	if (!first)
1538 		printf("\n\n");
1539 }
1540 
1541 void
1542 Suff_PrintAll(void)
1543 {
1544 	Suff **t;
1545 	GNode **u;
1546 	unsigned int i;
1547 	bool reprint;
1548 
1549 
1550 	printf("# Suffixes graph\n");
1551 	t = sort_ohash_by_name(&suffixes);
1552 	for (i = 0; t[i] != NULL; i++)
1553 		if (!(t[i]->flags & SUFF_PATH))
1554 			SuffPrintSuff(t[i]);
1555 
1556 	printf("\n.PATH: ");
1557 	Dir_PrintPath(defaultPath);
1558 	printf("\n\n");
1559 	for (i = 0; t[i] != NULL; i++)
1560 		if (!(t[i]->flags & SUFF_PATH))
1561 			print_path(t[i]);
1562 	free(t);
1563 
1564 	reprint = false;
1565 	t = sort_ohash(&suffixes, compare_order);
1566 	printf(".SUFFIXES:");
1567 	for (i = 0; t[i] != NULL; i++) {
1568 		if (t[i]->flags & SUFF_PATH)
1569 			continue;
1570 		printf(" %s", t[i]->name);
1571 		if (!(t[i]->flags & SUFF_ACTIVE))
1572 			reprint = true;
1573 	}
1574 	printf("\n\n");
1575 	u = sort_ohash_by_name(&transforms);
1576 	for (i = 0; u[i] != NULL; i++)
1577 	    	SuffPrintTrans(u[i]);
1578 	free(u);
1579 
1580 	if (reprint) {
1581 		printf(".SUFFIXES:");
1582 		for (i = 0; t[i] != NULL; i++)
1583 			if (t[i]->flags & SUFF_ACTIVE)
1584 				printf(" %s", t[i]->name);
1585 		printf("\n");
1586 	}
1587 	free(t);
1588 }
1589 
1590 #ifdef DEBUG_SRC
1591 static void
1592 PrintAddr(void *a)
1593 {
1594 	printf("%lx ", (unsigned long)a);
1595 }
1596 #endif
1597