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