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