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