suff.c revision 1.302 1 /* $NetBSD: suff.c,v 1.302 2020/11/22 22:27:19 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 /*
72 * Maintain suffix lists and find implicit dependents using suffix
73 * transformation rules such as ".c.o".
74 *
75 * Interface:
76 * Suff_Init Initialize the module.
77 *
78 * Suff_End Clean up the module.
79 *
80 * Suff_DoPaths Extend the search path of each suffix to include the
81 * default search path.
82 *
83 * Suff_ClearSuffixes
84 * Clear out all the suffixes and transformations.
85 *
86 * Suff_IsTransform
87 * See if the passed string is a transformation rule.
88 *
89 * Suff_AddSuffix Add the passed string as another known suffix.
90 *
91 * Suff_GetPath Return the search path for the given suffix.
92 *
93 * Suff_AddInclude
94 * Mark the given suffix as denoting an include file.
95 *
96 * Suff_AddLib Mark the given suffix as denoting a library.
97 *
98 * Suff_AddTransform
99 * Add another transformation to the suffix graph.
100 *
101 * Suff_SetNull Define the suffix to consider the suffix of
102 * any file that doesn't have a known one.
103 *
104 * Suff_FindDeps Find implicit sources for and the location of
105 * a target based on its suffix. Returns the
106 * bottom-most node added to the graph or NULL
107 * if the target had no implicit sources.
108 *
109 * Suff_FindPath Return the appropriate path to search in order to
110 * find the node.
111 */
112
113 #include "make.h"
114 #include "dir.h"
115
116 /* "@(#)suff.c 8.4 (Berkeley) 3/21/94" */
117 MAKE_RCSID("$NetBSD: suff.c,v 1.302 2020/11/22 22:27:19 rillig Exp $");
118
119 #define SUFF_DEBUG0(text) DEBUG0(SUFF, text)
120 #define SUFF_DEBUG1(fmt, arg1) DEBUG1(SUFF, fmt, arg1)
121 #define SUFF_DEBUG2(fmt, arg1, arg2) DEBUG2(SUFF, fmt, arg1, arg2)
122
123 typedef List SuffixList;
124 typedef ListNode SuffixListNode;
125
126 typedef List CandidateList;
127 typedef ListNode CandidateListNode;
128
129 static SuffixList *sufflist; /* List of suffixes */
130 #ifdef CLEANUP
131 static SuffixList *suffClean; /* List of suffixes to be cleaned */
132 #endif
133
134 /* List of transformation rules, such as ".c.o" */
135 static GNodeList *transforms;
136
137 static int sNum = 0; /* Counter for assigning suffix numbers */
138
139 typedef enum SuffixFlags {
140 SUFF_INCLUDE = 0x01, /* One which is #include'd */
141 SUFF_LIBRARY = 0x02, /* One which contains a library */
142 SUFF_NULL = 0x04 /* The empty suffix */
143 /* XXX: Why is SUFF_NULL needed? Wouldn't nameLen == 0 mean the same? */
144 } SuffixFlags;
145
146 ENUM_FLAGS_RTTI_3(SuffixFlags,
147 SUFF_INCLUDE, SUFF_LIBRARY, SUFF_NULL);
148
149 typedef List SuffixListList;
150
151 /*
152 * A suffix such as ".c" or ".o" that is used in suffix transformation rules
153 * such as ".c.o:".
154 */
155 typedef struct Suffix {
156 /* The suffix itself, such as ".c" */
157 char *name;
158 /* Length of the name, to avoid strlen calls */
159 size_t nameLen;
160 /* Type of suffix */
161 SuffixFlags flags;
162 /* The path along which files of this suffix may be found */
163 SearchPath *searchPath;
164 /* The suffix number; TODO: document the purpose of this number */
165 int sNum;
166 /* Reference count of list membership and several other places */
167 int refCount;
168 /* Suffixes we have a transformation to */
169 SuffixList *parents;
170 /* Suffixes we have a transformation from */
171 SuffixList *children;
172
173 /* Lists in which this suffix is referenced.
174 * XXX: These lists are used nowhere, they are just appended to, for no
175 * apparent reason. They do have the side effect of increasing refCount
176 * though. */
177 SuffixListList *ref;
178 } Suffix;
179
180 /*
181 * A candidate when searching for implied sources.
182 *
183 * For example, when "src.o" is to be made, a typical candidate is "src.c"
184 * via the transformation rule ".c.o". If that doesn't exist, maybe there is
185 * another transformation rule ".pas.c" that would make "src.pas" an indirect
186 * candidate as well. The first such chain that leads to an existing file or
187 * node is finally chosen to be made.
188 */
189 typedef struct Candidate {
190 /* The file or node to look for. */
191 char *file;
192 /* The prefix from which file was formed.
193 * Its memory is shared among all candidates. */
194 char *prefix;
195 /* The suffix on the file. */
196 Suffix *suff;
197
198 /* The candidate that can be made from this,
199 * or NULL for the top-level candidate. */
200 struct Candidate *parent;
201 /* The node describing the file. */
202 GNode *node;
203
204 /* Count of existing children, only used for memory management, so we
205 * don't free this candidate too early or too late. */
206 int numChildren;
207 #ifdef DEBUG_SRC
208 CandidateList *childrenList;
209 #endif
210 } Candidate;
211
212 typedef struct CandidateSearcher {
213
214 CandidateList *list;
215
216 /*
217 * TODO: Add HashSet for seen entries, to avoid endless loops such as
218 * in suff-transform-endless.mk.
219 */
220
221 } CandidateSearcher;
222
223
224 /* TODO: Document the difference between nullSuff and emptySuff. */
225 /* The NULL suffix for this run */
226 static Suffix *nullSuff;
227 /* The empty suffix required for POSIX single-suffix transformation rules */
228 static Suffix *emptySuff;
229
230
231 static Suffix *
232 Suffix_Ref(Suffix *suff)
233 {
234 suff->refCount++;
235 return suff;
236 }
237
238 /* Change the value of a Suffix variable, adjusting the reference counts. */
239 static void
240 Suffix_Reassign(Suffix **var, Suffix *suff)
241 {
242 if (*var != NULL)
243 (*var)->refCount--;
244 *var = suff;
245 suff->refCount++;
246 }
247
248 /* Set a Suffix variable to NULL, adjusting the reference count. */
249 static void
250 Suffix_Unassign(Suffix **var)
251 {
252 if (*var != NULL)
253 (*var)->refCount--;
254 *var = NULL;
255 }
256
257 /*
258 * See if pref is a prefix of str.
259 * Return NULL if it ain't, pointer to character in str after prefix if so.
260 */
261 static const char *
262 StrTrimPrefix(const char *pref, const char *str)
263 {
264 while (*str && *pref == *str) {
265 pref++;
266 str++;
267 }
268
269 return *pref != '\0' ? NULL : str;
270 }
271
272 /*
273 * See if suff is a suffix of str, and if so, return the pointer to the suffix
274 * in str, which at the same time marks the end of the prefix.
275 */
276 static const char *
277 StrTrimSuffix(const char *str, size_t strLen, const char *suff, size_t suffLen)
278 {
279 const char *suffInStr;
280 size_t i;
281
282 if (strLen < suffLen)
283 return NULL;
284
285 suffInStr = str + strLen - suffLen;
286 for (i = 0; i < suffLen; i++)
287 if (suff[i] != suffInStr[i])
288 return NULL;
289
290 return suffInStr;
291 }
292
293 /*
294 * See if suff is a suffix of name, and if so, return the end of the prefix
295 * in name.
296 */
297 static const char *
298 Suffix_TrimSuffix(const Suffix *suff, size_t nameLen, const char *nameEnd)
299 {
300 return StrTrimSuffix(nameEnd - nameLen, nameLen, suff->name, suff->nameLen);
301 }
302
303 static Boolean
304 Suffix_IsSuffix(const Suffix *suff, size_t nameLen, const char *nameEnd)
305 {
306 return Suffix_TrimSuffix(suff, nameLen, nameEnd) != NULL;
307 }
308
309 static Suffix *
310 FindSuffixByNameLen(const char *name, size_t nameLen)
311 {
312 SuffixListNode *ln;
313
314 for (ln = sufflist->first; ln != NULL; ln = ln->next) {
315 Suffix *suff = ln->datum;
316 if (suff->nameLen == nameLen && memcmp(suff->name, name, nameLen) == 0)
317 return suff;
318 }
319 return NULL;
320 }
321
322 static Suffix *
323 FindSuffixByName(const char *name)
324 {
325 return FindSuffixByNameLen(name, strlen(name));
326 }
327
328 static GNode *
329 FindTransformByName(const char *name)
330 {
331 GNodeListNode *ln;
332 for (ln = transforms->first; ln != NULL; ln = ln->next) {
333 GNode *gn = ln->datum;
334 if (strcmp(gn->name, name) == 0)
335 return gn;
336 }
337 return NULL;
338 }
339
340 static void
341 SuffixList_Unref(SuffixList *list, Suffix *suff)
342 {
343 SuffixListNode *ln = Lst_FindDatum(list, suff);
344 if (ln != NULL) {
345 Lst_Remove(list, ln);
346 suff->refCount--;
347 }
348 }
349
350 /* Free up all memory associated with the given suffix structure. */
351 static void
352 Suffix_Free(Suffix *suff)
353 {
354
355 if (suff == nullSuff)
356 nullSuff = NULL;
357
358 if (suff == emptySuff)
359 emptySuff = NULL;
360
361 #if 0
362 /* We don't delete suffixes in order, so we cannot use this */
363 if (suff->refCount != 0)
364 Punt("Internal error deleting suffix `%s' with refcount = %d",
365 suff->name, suff->refCount);
366 #endif
367
368 Lst_Free(suff->ref);
369 Lst_Free(suff->children);
370 Lst_Free(suff->parents);
371 Lst_Destroy(suff->searchPath, Dir_Destroy);
372
373 free(suff->name);
374 free(suff);
375 }
376
377 static void
378 SuffFree(void *p)
379 {
380 Suffix_Free(p);
381 }
382
383 /* Remove the suffix from the list, and free if it is otherwise unused. */
384 static void
385 SuffixList_Remove(SuffixList *list, Suffix *suff)
386 {
387 SuffixList_Unref(list, suff);
388 if (suff->refCount == 0) {
389 /* XXX: can lead to suff->refCount == -1 */
390 SuffixList_Unref(sufflist, suff);
391 DEBUG1(SUFF, "Removing suffix \"%s\"\n", suff->name);
392 SuffFree(suff);
393 }
394 }
395
396 /* Insert the suffix into the list, keeping the list ordered by suffix
397 * number. */
398 static void
399 SuffixList_Insert(SuffixList *list, Suffix *suff)
400 {
401 SuffixListNode *ln;
402 Suffix *listSuff = NULL;
403
404 for (ln = list->first; ln != NULL; ln = ln->next) {
405 listSuff = ln->datum;
406 if (listSuff->sNum >= suff->sNum)
407 break;
408 }
409
410 if (ln == NULL) {
411 SUFF_DEBUG2("inserting \"%s\" (%d) at end of list\n",
412 suff->name, suff->sNum);
413 Lst_Append(list, Suffix_Ref(suff));
414 Lst_Append(suff->ref, list);
415 } else if (listSuff->sNum != suff->sNum) {
416 DEBUG4(SUFF, "inserting \"%s\" (%d) before \"%s\" (%d)\n",
417 suff->name, suff->sNum, listSuff->name, listSuff->sNum);
418 Lst_InsertBefore(list, ln, Suffix_Ref(suff));
419 Lst_Append(suff->ref, list);
420 } else {
421 SUFF_DEBUG2("\"%s\" (%d) is already there\n", suff->name, suff->sNum);
422 }
423 }
424
425 static void
426 Relate(Suffix *srcSuff, Suffix *targSuff)
427 {
428 SuffixList_Insert(targSuff->children, srcSuff);
429 SuffixList_Insert(srcSuff->parents, targSuff);
430 }
431
432 static Suffix *
433 Suffix_New(const char *name)
434 {
435 Suffix *suff = bmake_malloc(sizeof *suff);
436
437 suff->name = bmake_strdup(name);
438 suff->nameLen = strlen(suff->name);
439 suff->searchPath = Lst_New();
440 suff->children = Lst_New();
441 suff->parents = Lst_New();
442 suff->ref = Lst_New();
443 suff->sNum = sNum++;
444 suff->flags = 0;
445 suff->refCount = 1; /* XXX: why 1? It's not assigned anywhere yet. */
446
447 return suff;
448 }
449
450 /*
451 * Nuke the list of suffixes but keep all transformation rules around. The
452 * transformation graph is destroyed in this process, but we leave the list
453 * of rules so when a new graph is formed, the rules will remain. This
454 * function is called when a line '.SUFFIXES:' with an empty suffixes list is
455 * encountered in a makefile.
456 */
457 void
458 Suff_ClearSuffixes(void)
459 {
460 #ifdef CLEANUP
461 Lst_MoveAll(suffClean, sufflist);
462 #endif
463 DEBUG0(SUFF, "Clearing all suffixes\n");
464 sufflist = Lst_New();
465 sNum = 0;
466 if (nullSuff != NULL)
467 SuffFree(nullSuff);
468 emptySuff = nullSuff = Suffix_New("");
469
470 Dir_Concat(nullSuff->searchPath, dirSearchPath);
471 nullSuff->flags = SUFF_NULL;
472 }
473
474 /* Parse a transformation string such as ".c.o" to find its two component
475 * suffixes (the source ".c" and the target ".o"). If there are no such
476 * suffixes, try a single-suffix transformation as well.
477 *
478 * Return TRUE if the string is a valid transformation.
479 */
480 static Boolean
481 ParseTransform(const char *str, Suffix **out_src, Suffix **out_targ)
482 {
483 SuffixListNode *ln;
484 Suffix *single = NULL;
485
486 /*
487 * Loop looking first for a suffix that matches the start of the
488 * string and then for one that exactly matches the rest of it. If
489 * we can find two that meet these criteria, we've successfully
490 * parsed the string.
491 */
492 for (ln = sufflist->first; ln != NULL; ln = ln->next) {
493 Suffix *src = ln->datum;
494
495 if (StrTrimPrefix(src->name, str) == NULL)
496 continue;
497
498 if (str[src->nameLen] == '\0') {
499 single = src;
500 } else {
501 Suffix *targ = FindSuffixByName(str + src->nameLen);
502 if (targ != NULL) {
503 *out_src = src;
504 *out_targ = targ;
505 return TRUE;
506 }
507 }
508 }
509
510 if (single != NULL) {
511 /*
512 * There was a suffix that encompassed the entire string, so we
513 * assume it was a transformation to the null suffix (thank you
514 * POSIX; search for "single suffix" or "single-suffix").
515 *
516 * We still prefer to find a double rule over a singleton,
517 * hence we leave this check until the end.
518 *
519 * XXX: Use emptySuff over nullSuff?
520 */
521 *out_src = single;
522 *out_targ = nullSuff;
523 return TRUE;
524 }
525 return FALSE;
526 }
527
528 /* Return TRUE if the given string is a transformation rule, that is, a
529 * concatenation of two known suffixes such as ".c.o" or a single suffix
530 * such as ".o". */
531 Boolean
532 Suff_IsTransform(const char *str)
533 {
534 Suffix *src, *targ;
535
536 return ParseTransform(str, &src, &targ);
537 }
538
539 /* Add the transformation rule to the list of rules and place the
540 * transformation itself in the graph.
541 *
542 * The transformation is linked to the two suffixes mentioned in the name.
543 *
544 * Input:
545 * name must have the form ".from.to" or just ".from"
546 *
547 * Results:
548 * The created or existing transformation node in the transforms list
549 */
550 GNode *
551 Suff_AddTransform(const char *name)
552 {
553 Suffix *srcSuff;
554 Suffix *targSuff;
555
556 GNode *gn = FindTransformByName(name);
557 if (gn == NULL) {
558 /*
559 * Make a new graph node for the transformation. It will be filled in
560 * by the Parse module.
561 */
562 gn = GNode_New(name);
563 Lst_Append(transforms, gn);
564 } else {
565 /*
566 * New specification for transformation rule. Just nuke the old list
567 * of commands so they can be filled in again... We don't actually
568 * free the commands themselves, because a given command can be
569 * attached to several different transformations.
570 */
571 Lst_Free(gn->commands);
572 Lst_Free(gn->children);
573 gn->commands = Lst_New();
574 gn->children = Lst_New();
575 }
576
577 gn->type = OP_TRANSFORM;
578
579 {
580 Boolean ok = ParseTransform(name, &srcSuff, &targSuff);
581 assert(ok);
582 (void)ok;
583 }
584
585 /*
586 * link the two together in the proper relationship and order
587 */
588 SUFF_DEBUG2("defining transformation from `%s' to `%s'\n",
589 srcSuff->name, targSuff->name);
590 Relate(srcSuff, targSuff);
591
592 return gn;
593 }
594
595 /* Handle the finish of a transformation definition, removing the
596 * transformation from the graph if it has neither commands nor sources.
597 *
598 * If the node has no commands or children, the children and parents lists
599 * of the affected suffixes are altered.
600 *
601 * Input:
602 * gn Node for transformation
603 */
604 void
605 Suff_EndTransform(GNode *gn)
606 {
607 Suffix *srcSuff, *targSuff;
608 SuffixList *srcSuffParents;
609
610 if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(gn->cohorts))
611 gn = gn->cohorts->last->datum;
612
613 if (!(gn->type & OP_TRANSFORM))
614 return;
615
616 if (!Lst_IsEmpty(gn->commands) || !Lst_IsEmpty(gn->children)) {
617 SUFF_DEBUG1("transformation %s complete\n", gn->name);
618 return;
619 }
620
621 /*
622 * SuffParseTransform() may fail for special rules which are not
623 * actual transformation rules. (e.g. .DEFAULT)
624 */
625 if (!ParseTransform(gn->name, &srcSuff, &targSuff))
626 return;
627
628 SUFF_DEBUG2("deleting incomplete transformation from `%s' to `%s'\n",
629 srcSuff->name, targSuff->name);
630
631 /* Remember parents since srcSuff could be deleted in SuffixList_Remove. */
632 srcSuffParents = srcSuff->parents;
633 SuffixList_Remove(targSuff->children, srcSuff);
634 SuffixList_Remove(srcSuffParents, targSuff);
635 }
636
637 /* Called from Suff_AddSuffix to search through the list of
638 * existing transformation rules and rebuild the transformation graph when
639 * it has been destroyed by Suff_ClearSuffixes. If the given rule is a
640 * transformation involving this suffix and another, existing suffix, the
641 * proper relationship is established between the two.
642 *
643 * The appropriate links will be made between this suffix and others if
644 * transformation rules exist for it.
645 *
646 * Input:
647 * transform Transformation to test
648 * suff Suffix to rebuild
649 */
650 static void
651 RebuildGraph(GNode *transform, Suffix *suff)
652 {
653 const char *name = transform->name;
654 size_t nameLen = strlen(name);
655 const char *toName;
656
657 /*
658 * First see if it is a transformation from this suffix.
659 */
660 toName = StrTrimPrefix(suff->name, name);
661 if (toName != NULL) {
662 Suffix *to = FindSuffixByName(toName);
663 if (to != NULL) {
664 /* Link in and return, since it can't be anything else. */
665 Relate(suff, to);
666 return;
667 }
668 }
669
670 /*
671 * Not from, maybe to?
672 */
673 toName = Suffix_TrimSuffix(suff, nameLen, name + nameLen);
674 if (toName != NULL) {
675 Suffix *from = FindSuffixByNameLen(name, (size_t)(toName - name));
676 if (from != NULL)
677 Relate(from, suff);
678 }
679 }
680
681 /* During Suff_AddSuffix, search through the list of existing targets and find
682 * if any of the existing targets can be turned into a transformation rule.
683 *
684 * If such a target is found and the target is the current main target, the
685 * main target is set to NULL and the next target examined (if that exists)
686 * becomes the main target.
687 *
688 * Results:
689 * TRUE iff a new main target has been selected.
690 */
691 static Boolean
692 UpdateTarget(GNode *target, GNode **inout_main, Suffix *suff,
693 Boolean *inout_removedMain)
694 {
695 Suffix *srcSuff, *targSuff;
696 char *ptr;
697
698 if (*inout_main == NULL && *inout_removedMain &&
699 !(target->type & OP_NOTARGET)) {
700 DEBUG1(MAKE, "Setting main node to \"%s\"\n", target->name);
701 *inout_main = target;
702 Targ_SetMain(target);
703 /*
704 * XXX: Why could it be a good idea to return TRUE here?
705 * The main task of this function is to turn ordinary nodes into
706 * transformations, no matter whether or not a new .MAIN node
707 * has been found.
708 */
709 /*
710 * XXX: Even when changing this to FALSE, none of the existing unit
711 * tests fails.
712 */
713 return TRUE;
714 }
715
716 if (target->type == OP_TRANSFORM)
717 return FALSE;
718
719 /*
720 * XXX: What about a transformation ".cpp.c"? If ".c" is added as a new
721 * suffix, it seems wrong that this transformation would be skipped just
722 * because ".c" happens to be a prefix of ".cpp".
723 */
724 ptr = strstr(target->name, suff->name);
725 if (ptr == NULL)
726 return FALSE;
727
728 /*
729 * XXX: In suff-rebuild.mk, in the line '.SUFFIXES: .c .b .a', this
730 * condition prevents the rule '.b.c' from being added again during
731 * Suff_AddSuffix(".b").
732 *
733 * XXX: Removing this paragraph makes suff-add-later.mk use massive
734 * amounts of memory.
735 */
736 if (ptr == target->name)
737 return FALSE;
738
739 if (ParseTransform(target->name, &srcSuff, &targSuff)) {
740 if (*inout_main == target) {
741 DEBUG1(MAKE, "Setting main node from \"%s\" back to null\n",
742 target->name);
743 *inout_removedMain = TRUE;
744 *inout_main = NULL;
745 Targ_SetMain(NULL);
746 }
747 Lst_Free(target->children);
748 target->children = Lst_New();
749 target->type = OP_TRANSFORM;
750 /*
751 * link the two together in the proper relationship and order
752 */
753 SUFF_DEBUG2("defining transformation from `%s' to `%s'\n",
754 srcSuff->name, targSuff->name);
755 Relate(srcSuff, targSuff);
756 }
757 return FALSE;
758 }
759
760 /* Look at all existing targets to see if adding this suffix will make one
761 * of the current targets mutate into a suffix rule.
762 *
763 * This is ugly, but other makes treat all targets that start with a '.' as
764 * suffix rules. */
765 static void
766 UpdateTargets(GNode **inout_main, Suffix *suff)
767 {
768 Boolean removedMain = FALSE;
769 GNodeListNode *ln;
770
771 for (ln = Targ_List()->first; ln != NULL; ln = ln->next) {
772 GNode *gn = ln->datum;
773 if (UpdateTarget(gn, inout_main, suff, &removedMain))
774 break;
775 }
776 }
777
778 /* Add the suffix to the end of the list of known suffixes.
779 * Should we restructure the suffix graph? Make doesn't...
780 *
781 * A GNode is created for the suffix and a Suffix structure is created and
782 * added to the suffixes list unless the suffix was already known.
783 * The mainNode passed can be modified if a target mutated into a
784 * transform and that target happened to be the main target.
785 *
786 * Input:
787 * name the name of the suffix to add
788 */
789 void
790 Suff_AddSuffix(const char *name, GNode **inout_main)
791 {
792 GNodeListNode *ln;
793
794 Suffix *suff = FindSuffixByName(name);
795 if (suff != NULL)
796 return;
797
798 suff = Suffix_New(name);
799 Lst_Append(sufflist, suff);
800 DEBUG1(SUFF, "Adding suffix \"%s\"\n", suff->name);
801
802 UpdateTargets(inout_main, suff);
803
804 /*
805 * Look for any existing transformations from or to this suffix.
806 * XXX: Only do this after a Suff_ClearSuffixes?
807 */
808 for (ln = transforms->first; ln != NULL; ln = ln->next)
809 RebuildGraph(ln->datum, suff);
810 }
811
812 /* Return the search path for the given suffix, or NULL. */
813 SearchPath *
814 Suff_GetPath(const char *sname)
815 {
816 Suffix *suff = FindSuffixByName(sname);
817 return suff != NULL ? suff->searchPath : NULL;
818 }
819
820 /*
821 * Extend the search paths for all suffixes to include the default search
822 * path (dirSearchPath).
823 *
824 * The default search path can be defined using the special target '.PATH'.
825 * The search path of each suffix can be defined using the special target
826 * '.PATH<suffix>'.
827 *
828 * If paths were specified for the ".h" suffix, the directories are stuffed
829 * into a global variable called ".INCLUDES" with each directory preceded by
830 * '-I'. The same is done for the ".a" suffix, except the variable is called
831 * ".LIBS" and the flag is '-L'.
832 */
833 void
834 Suff_DoPaths(void)
835 {
836 SuffixListNode *ln;
837 char *ptr;
838 SearchPath *inIncludes; /* Cumulative .INCLUDES path */
839 SearchPath *inLibs; /* Cumulative .LIBS path */
840
841 inIncludes = Lst_New();
842 inLibs = Lst_New();
843
844 for (ln = sufflist->first; ln != NULL; ln = ln->next) {
845 Suffix *suff = ln->datum;
846 if (!Lst_IsEmpty(suff->searchPath)) {
847 #ifdef INCLUDES
848 if (suff->flags & SUFF_INCLUDE)
849 Dir_Concat(inIncludes, suff->searchPath);
850 #endif
851 #ifdef LIBRARIES
852 if (suff->flags & SUFF_LIBRARY)
853 Dir_Concat(inLibs, suff->searchPath);
854 #endif
855 Dir_Concat(suff->searchPath, dirSearchPath);
856 } else {
857 Lst_Destroy(suff->searchPath, Dir_Destroy);
858 suff->searchPath = Dir_CopyDirSearchPath();
859 }
860 }
861
862 Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL);
863 free(ptr);
864 Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL);
865 free(ptr);
866
867 Lst_Destroy(inIncludes, Dir_Destroy);
868 Lst_Destroy(inLibs, Dir_Destroy);
869 }
870
871 /*
872 * Add the given suffix as a type of file which gets included.
873 * Called when a '.INCLUDES: .h' line is parsed.
874 * To have an effect, the suffix must already exist.
875 * This affects the magic variable '.INCLUDES'.
876 */
877 void
878 Suff_AddInclude(const char *suffName)
879 {
880 Suffix *suff = FindSuffixByName(suffName);
881 if (suff != NULL)
882 suff->flags |= SUFF_INCLUDE;
883 }
884
885 /*
886 * Add the given suffix as a type of file which is a library.
887 * Called when a '.LIBS: .a' line is parsed.
888 * To have an effect, the suffix must already exist.
889 * This affects the magic variable '.LIBS'.
890 */
891 void
892 Suff_AddLib(const char *suffName)
893 {
894 Suffix *suff = FindSuffixByName(suffName);
895 if (suff != NULL)
896 suff->flags |= SUFF_LIBRARY;
897 }
898
899 /********** Implicit Source Search Functions *********/
900
901 #ifdef DEBUG_SRC
902 static void
903 CandidateList_PrintAddrs(CandidateList *list)
904 {
905 CandidateListNode *ln;
906
907 for (ln = list->first; ln != NULL; ln = ln->next) {
908 Candidate *cand = ln->datum;
909 debug_printf(" %p:%s", cand, cand->file);
910 }
911 debug_printf("\n");
912 }
913 #endif
914
915 static Candidate *
916 Candidate_New(char *name, char *prefix, Suffix *suff, Candidate *parent,
917 GNode *gn)
918 {
919 Candidate *cand = bmake_malloc(sizeof *cand);
920
921 cand->file = name;
922 cand->prefix = prefix;
923 cand->suff = Suffix_Ref(suff);
924 cand->parent = parent;
925 cand->node = gn;
926 cand->numChildren = 0;
927 #ifdef DEBUG_SRC
928 cand->childrenList = Lst_New();
929 #endif
930
931 return cand;
932 }
933
934 /* Add a new candidate to the list. */
935 static void
936 CandidateList_Add(CandidateList *list, char *srcName, Candidate *targ,
937 Suffix *suff, const char *debug_tag)
938 {
939 Candidate *cand = Candidate_New(srcName, targ->prefix, suff, targ, NULL);
940 targ->numChildren++;
941 Lst_Append(list, cand);
942
943 #ifdef DEBUG_SRC
944 Lst_Append(targ->childrenList, cand);
945 debug_printf("%s add suff %p:%s candidate %p:%s to list %p:",
946 debug_tag, targ, targ->file, cand, cand->file, list);
947 CandidateList_PrintAddrs(list);
948 #endif
949 }
950
951 /* Add all candidates to the list that can be formed by applying a suffix to
952 * the candidate. */
953 static void
954 CandidateList_AddCandidatesFor(CandidateList *list, Candidate *cand)
955 {
956 SuffixListNode *ln;
957 for (ln = cand->suff->children->first; ln != NULL; ln = ln->next) {
958 Suffix *suff = ln->datum;
959
960 if ((suff->flags & SUFF_NULL) && suff->name[0] != '\0') {
961 /*
962 * If the suffix has been marked as the NULL suffix, also
963 * create a candidate for a file with no suffix attached.
964 */
965 CandidateList_Add(list, bmake_strdup(cand->prefix),
966 cand, suff, "1");
967 }
968
969 CandidateList_Add(list, str_concat2(cand->prefix, suff->name),
970 cand, suff, "2");
971 }
972 }
973
974 /* Free the first candidate in the list that is not referenced anymore.
975 * Return whether a candidate was removed. */
976 static Boolean
977 RemoveCandidate(CandidateList *srcs)
978 {
979 CandidateListNode *ln;
980
981 #ifdef DEBUG_SRC
982 debug_printf("cleaning list %p:", srcs);
983 CandidateList_PrintAddrs(srcs);
984 #endif
985
986 for (ln = srcs->first; ln != NULL; ln = ln->next) {
987 Candidate *src = ln->datum;
988
989 if (src->numChildren == 0) {
990 free(src->file);
991 if (src->parent == NULL)
992 free(src->prefix);
993 else {
994 #ifdef DEBUG_SRC
995 /* XXX: Lst_RemoveDatum */
996 CandidateListNode *ln2;
997 ln2 = Lst_FindDatum(src->parent->childrenList, src);
998 if (ln2 != NULL)
999 Lst_Remove(src->parent->childrenList, ln2);
1000 #endif
1001 src->parent->numChildren--;
1002 }
1003 #ifdef DEBUG_SRC
1004 debug_printf("free: list %p src %p:%s children %d\n",
1005 srcs, src, src->file, src->numChildren);
1006 Lst_Free(src->childrenList);
1007 #endif
1008 Lst_Remove(srcs, ln);
1009 free(src);
1010 return TRUE;
1011 }
1012 #ifdef DEBUG_SRC
1013 else {
1014 debug_printf("keep: list %p src %p:%s children %d:",
1015 srcs, src, src->file, src->numChildren);
1016 CandidateList_PrintAddrs(src->childrenList);
1017 }
1018 #endif
1019 }
1020
1021 return FALSE;
1022 }
1023
1024 /* Find the first existing file/target in srcs. */
1025 static Candidate *
1026 FindThem(CandidateList *srcs, CandidateSearcher *cs)
1027 {
1028 Candidate *retsrc = NULL;
1029
1030 while (!Lst_IsEmpty(srcs)) {
1031 Candidate *src = Lst_Dequeue(srcs);
1032
1033 SUFF_DEBUG1("\ttrying %s...", src->file);
1034
1035 /*
1036 * A file is considered to exist if either a node exists in the
1037 * graph for it or the file actually exists.
1038 */
1039 if (Targ_FindNode(src->file) != NULL) {
1040 #ifdef DEBUG_SRC
1041 debug_printf("remove from list %p src %p:%s\n",
1042 srcs, src, src->file);
1043 #endif
1044 retsrc = src;
1045 break;
1046 }
1047
1048 {
1049 char *file = Dir_FindFile(src->file, src->suff->searchPath);
1050 if (file != NULL) {
1051 retsrc = src;
1052 #ifdef DEBUG_SRC
1053 debug_printf("remove from list %p src %p:%s\n",
1054 srcs, src, src->file);
1055 #endif
1056 free(file);
1057 break;
1058 }
1059 }
1060
1061 SUFF_DEBUG0("not there\n");
1062
1063 CandidateList_AddCandidatesFor(srcs, src);
1064 Lst_Append(cs->list, src);
1065 }
1066
1067 if (retsrc) {
1068 SUFF_DEBUG0("got it\n");
1069 }
1070 return retsrc;
1071 }
1072
1073 /*
1074 * See if any of the children of the candidate's GNode is one from which the
1075 * target can be transformed. If there is one, a candidate is put together
1076 * for it and returned.
1077 */
1078 static Candidate *
1079 FindCmds(Candidate *targ, CandidateSearcher *cs)
1080 {
1081 GNodeListNode *gln;
1082 GNode *tgn; /* Target GNode */
1083 GNode *sgn; /* Source GNode */
1084 size_t prefLen; /* The length of the defined prefix */
1085 Suffix *suff; /* Suffix on matching beastie */
1086 Candidate *ret; /* Return value */
1087 char *cp;
1088
1089 tgn = targ->node;
1090 prefLen = strlen(targ->prefix);
1091
1092 for (gln = tgn->children->first; gln != NULL; gln = gln->next) {
1093 sgn = gln->datum;
1094
1095 if (sgn->type & OP_OPTIONAL && Lst_IsEmpty(tgn->commands)) {
1096 /*
1097 * We haven't looked to see if .OPTIONAL files exist yet, so
1098 * don't use one as the implicit source.
1099 * This allows us to use .OPTIONAL in .depend files so make won't
1100 * complain "don't know how to make xxx.h' when a dependent file
1101 * has been moved/deleted.
1102 */
1103 continue;
1104 }
1105
1106 cp = strrchr(sgn->name, '/');
1107 if (cp == NULL) {
1108 cp = sgn->name;
1109 } else {
1110 cp++;
1111 }
1112 if (strncmp(cp, targ->prefix, prefLen) != 0)
1113 continue;
1114 /* The node matches the prefix ok, see if it has a known suffix. */
1115 suff = FindSuffixByName(cp + prefLen);
1116 if (suff == NULL)
1117 continue;
1118
1119 /*
1120 * It even has a known suffix, see if there's a transformation
1121 * defined between the node's suffix and the target's suffix.
1122 *
1123 * XXX: Handle multi-stage transformations here, too.
1124 */
1125
1126 if (Lst_FindDatum(suff->parents, targ->suff) != NULL)
1127 break;
1128 }
1129
1130 if (gln == NULL)
1131 return NULL;
1132
1133 ret = Candidate_New(bmake_strdup(sgn->name), targ->prefix, suff, targ, sgn);
1134 targ->numChildren++;
1135 #ifdef DEBUG_SRC
1136 debug_printf("3 add targ %p:%s ret %p:%s\n",
1137 targ, targ->file, ret, ret->file);
1138 Lst_Append(targ->childrenList, ret);
1139 #endif
1140 Lst_Append(cs->list, ret);
1141 SUFF_DEBUG1("\tusing existing source %s\n", sgn->name);
1142 return ret;
1143 }
1144
1145 static void
1146 ExpandWildcards(GNodeListNode *cln, GNode *pgn)
1147 {
1148 GNode *cgn = cln->datum;
1149 StringList *expansions;
1150
1151 if (!Dir_HasWildcards(cgn->name))
1152 return;
1153
1154 /*
1155 * Expand the word along the chosen path
1156 */
1157 expansions = Lst_New();
1158 Dir_Expand(cgn->name, Suff_FindPath(cgn), expansions);
1159
1160 while (!Lst_IsEmpty(expansions)) {
1161 GNode *gn;
1162 /*
1163 * Fetch next expansion off the list and find its GNode
1164 */
1165 char *cp = Lst_Dequeue(expansions);
1166
1167 SUFF_DEBUG1("%s...", cp);
1168 gn = Targ_GetNode(cp);
1169
1170 /* Add gn to the parents child list before the original child */
1171 Lst_InsertBefore(pgn->children, cln, gn);
1172 Lst_Append(gn->parents, pgn);
1173 pgn->unmade++;
1174 }
1175
1176 Lst_Free(expansions);
1177
1178 SUFF_DEBUG0("\n");
1179
1180 /*
1181 * Now the source is expanded, remove it from the list of children to
1182 * keep it from being processed.
1183 */
1184 pgn->unmade--;
1185 Lst_Remove(pgn->children, cln);
1186 Lst_Remove(cgn->parents, Lst_FindDatum(cgn->parents, pgn));
1187 }
1188
1189 /* Expand the names of any children of a given node that contain variable
1190 * expressions or file wildcards into actual targets.
1191 *
1192 * The expanded node is removed from the parent's list of children, and the
1193 * parent's unmade counter is decremented, but other nodes may be added.
1194 *
1195 * Input:
1196 * cln Child to examine
1197 * pgn Parent node being processed
1198 */
1199 static void
1200 ExpandChildren(GNodeListNode *cln, GNode *pgn)
1201 {
1202 GNode *cgn = cln->datum;
1203 GNode *gn; /* New source 8) */
1204 char *cp; /* Expanded value */
1205
1206 if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ))
1207 /* It is all too hard to process the result of .ORDER */
1208 return;
1209
1210 if (cgn->type & OP_WAIT)
1211 /* Ignore these (& OP_PHONY ?) */
1212 return;
1213
1214 /*
1215 * First do variable expansion -- this takes precedence over
1216 * wildcard expansion. If the result contains wildcards, they'll be gotten
1217 * to later since the resulting words are tacked on to the end of
1218 * the children list.
1219 */
1220 if (strchr(cgn->name, '$') == NULL) {
1221 ExpandWildcards(cln, pgn);
1222 return;
1223 }
1224
1225 SUFF_DEBUG1("Expanding \"%s\"...", cgn->name);
1226 (void)Var_Subst(cgn->name, pgn, VARE_WANTRES | VARE_UNDEFERR, &cp);
1227 /* TODO: handle errors */
1228
1229 {
1230 GNodeList *members = Lst_New();
1231
1232 if (cgn->type & OP_ARCHV) {
1233 /*
1234 * Node was an archive(member) target, so we want to call
1235 * on the Arch module to find the nodes for us, expanding
1236 * variables in the parent's context.
1237 */
1238 char *sacrifice = cp;
1239
1240 (void)Arch_ParseArchive(&sacrifice, members, pgn);
1241 } else {
1242 /*
1243 * Break the result into a vector of strings whose nodes
1244 * we can find, then add those nodes to the members list.
1245 * Unfortunately, we can't use Str_Words because it
1246 * doesn't understand about variable specifications with
1247 * spaces in them...
1248 */
1249 char *start;
1250 char *initcp = cp; /* For freeing... */
1251
1252 start = cp;
1253 pp_skip_hspace(&start);
1254 cp = start;
1255 while (*cp != '\0') {
1256 if (*cp == ' ' || *cp == '\t') {
1257 /*
1258 * White-space -- terminate element, find the node,
1259 * add it, skip any further spaces.
1260 */
1261 *cp++ = '\0';
1262 gn = Targ_GetNode(start);
1263 Lst_Append(members, gn);
1264 pp_skip_hspace(&cp);
1265 start = cp; /* Continue at the next non-space. */
1266 } else if (*cp == '$') {
1267 /* Skip over the variable expression. */
1268 const char *nested_p = cp;
1269 const char *junk;
1270 void *freeIt;
1271
1272 (void)Var_Parse(&nested_p, pgn, VARE_NONE, &junk, &freeIt);
1273 /* TODO: handle errors */
1274 if (junk == var_Error) {
1275 Parse_Error(PARSE_FATAL,
1276 "Malformed variable expression at \"%s\"",
1277 cp);
1278 cp++;
1279 } else {
1280 cp += nested_p - cp;
1281 }
1282
1283 free(freeIt);
1284 } else if (cp[0] == '\\' && cp[1] != '\0') {
1285 /*
1286 * Escaped something -- skip over it
1287 */
1288 /* XXX: In other places, escaping at this syntactical
1289 * position is done by a '$', not a '\'. The '\' is only
1290 * used in variable modifiers. */
1291 cp += 2;
1292 } else {
1293 cp++;
1294 }
1295 }
1296
1297 if (cp != start) {
1298 /*
1299 * Stuff left over -- add it to the list too
1300 */
1301 gn = Targ_GetNode(start);
1302 Lst_Append(members, gn);
1303 }
1304 /*
1305 * Point cp back at the beginning again so the variable value
1306 * can be freed.
1307 */
1308 cp = initcp;
1309 }
1310
1311 /*
1312 * Add all elements of the members list to the parent node.
1313 */
1314 while(!Lst_IsEmpty(members)) {
1315 gn = Lst_Dequeue(members);
1316
1317 SUFF_DEBUG1("%s...", gn->name);
1318 /* Add gn to the parents child list before the original child */
1319 Lst_InsertBefore(pgn->children, cln, gn);
1320 Lst_Append(gn->parents, pgn);
1321 pgn->unmade++;
1322 /* Expand wildcards on new node */
1323 ExpandWildcards(cln->prev, pgn);
1324 }
1325 Lst_Free(members);
1326
1327 /*
1328 * Free the result
1329 */
1330 free(cp);
1331 }
1332
1333 SUFF_DEBUG0("\n");
1334
1335 /*
1336 * Now the source is expanded, remove it from the list of children to
1337 * keep it from being processed.
1338 */
1339 pgn->unmade--;
1340 Lst_Remove(pgn->children, cln);
1341 Lst_Remove(cgn->parents, Lst_FindDatum(cgn->parents, pgn));
1342 }
1343
1344 static void
1345 ExpandAllChildren(GNode *gn)
1346 {
1347 GNodeListNode *ln, *nln;
1348
1349 for (ln = gn->children->first; ln != NULL; ln = nln) {
1350 nln = ln->next;
1351 ExpandChildren(ln, gn);
1352 }
1353 }
1354
1355 /* Find a path along which to expand the node.
1356 *
1357 * If the node has a known suffix, use that path.
1358 * If it has no known suffix, use the default system search path.
1359 *
1360 * Input:
1361 * gn Node being examined
1362 *
1363 * Results:
1364 * The appropriate path to search for the GNode.
1365 */
1366 SearchPath *
1367 Suff_FindPath(GNode* gn)
1368 {
1369 Suffix *suff = gn->suffix;
1370
1371 if (suff == NULL) {
1372 char *name = gn->name;
1373 size_t nameLen = strlen(gn->name);
1374 SuffixListNode *ln;
1375 for (ln = sufflist->first; ln != NULL; ln = ln->next)
1376 if (Suffix_IsSuffix(ln->datum, nameLen, name + nameLen))
1377 break;
1378
1379 SUFF_DEBUG1("Wildcard expanding \"%s\"...", gn->name);
1380 if (ln != NULL)
1381 suff = ln->datum;
1382 /* XXX: Here we can save the suffix so we don't have to do this again */
1383 }
1384
1385 if (suff != NULL) {
1386 SUFF_DEBUG1("suffix is \"%s\"...\n", suff->name);
1387 return suff->searchPath;
1388 } else {
1389 SUFF_DEBUG0("\n");
1390 return dirSearchPath; /* Use default search path */
1391 }
1392 }
1393
1394 /* Apply a transformation rule, given the source and target nodes and
1395 * suffixes.
1396 *
1397 * The source and target are linked and the commands from the transformation
1398 * are added to the target node's commands list. The target also inherits all
1399 * the sources for the transformation rule.
1400 *
1401 * Results:
1402 * TRUE if successful, FALSE if not.
1403 */
1404 static Boolean
1405 ApplyTransform(GNode *tgn, GNode *sgn, Suffix *tsuff, Suffix *ssuff)
1406 {
1407 GNodeListNode *ln;
1408 char *tname; /* Name of transformation rule */
1409 GNode *gn; /* Node for same */
1410
1411 /*
1412 * Form the proper links between the target and source.
1413 */
1414 Lst_Append(tgn->children, sgn);
1415 Lst_Append(sgn->parents, tgn);
1416 tgn->unmade++;
1417
1418 /*
1419 * Locate the transformation rule itself
1420 */
1421 tname = str_concat2(ssuff->name, tsuff->name);
1422 gn = FindTransformByName(tname);
1423 free(tname);
1424
1425 if (gn == NULL) {
1426 /* This can happen when linking an OP_MEMBER and OP_ARCHV node. */
1427 return FALSE;
1428 }
1429
1430 DEBUG3(SUFF,"\tapplying %s -> %s to \"%s\"\n",
1431 ssuff->name, tsuff->name, tgn->name);
1432
1433 /* Record last child; Make_HandleUse may add child nodes. */
1434 ln = tgn->children->last;
1435
1436 /* Apply the rule. */
1437 Make_HandleUse(gn, tgn);
1438
1439 /* Deal with wildcards and variables in any acquired sources. */
1440 ln = ln != NULL ? ln->next : NULL;
1441 while (ln != NULL) {
1442 GNodeListNode *nln = ln->next;
1443 ExpandChildren(ln, tgn);
1444 ln = nln;
1445 }
1446
1447 /*
1448 * Keep track of another parent to which this node is transformed so
1449 * the .IMPSRC variable can be set correctly for the parent.
1450 */
1451 Lst_Append(sgn->implicitParents, tgn);
1452
1453 return TRUE;
1454 }
1455
1456 /*
1457 * Member has a known suffix, so look for a transformation rule from
1458 * it to a possible suffix of the archive.
1459 *
1460 * Rather than searching through the entire list, we just look at
1461 * suffixes to which the member's suffix may be transformed.
1462 */
1463 static void
1464 ExpandMember(GNode *gn, const char *eoarch, GNode *mem, Suffix *memSuff)
1465 {
1466 GNodeListNode *ln;
1467 size_t nameLen = (size_t)(eoarch - gn->name);
1468
1469 /* Use first matching suffix... */
1470 for (ln = memSuff->parents->first; ln != NULL; ln = ln->next)
1471 if (Suffix_IsSuffix(ln->datum, nameLen, eoarch))
1472 break;
1473
1474 if (ln != NULL) {
1475 /* Got one -- apply it */
1476 Suffix *suff = ln->datum;
1477 if (!ApplyTransform(gn, mem, suff, memSuff)) {
1478 SUFF_DEBUG2("\tNo transformation from %s -> %s\n",
1479 memSuff->name, suff->name);
1480 }
1481 }
1482 }
1483
1484 static void FindDeps(GNode *, CandidateSearcher *);
1485
1486 /* Locate dependencies for an OP_ARCHV node.
1487 *
1488 * Input:
1489 * gn Node for which to locate dependencies
1490 *
1491 * Side Effects:
1492 * Same as Suff_FindDeps
1493 */
1494 static void
1495 FindDepsArchive(GNode *gn, CandidateSearcher *cs)
1496 {
1497 char *eoarch; /* End of archive portion */
1498 char *eoname; /* End of member portion */
1499 GNode *mem; /* Node for member */
1500 Suffix *memSuff;
1501 const char *name; /* Start of member's name */
1502
1503 /*
1504 * The node is an archive(member) pair. so we must find a
1505 * suffix for both of them.
1506 */
1507 eoarch = strchr(gn->name, '(');
1508 eoname = strchr(eoarch, ')');
1509
1510 /*
1511 * Caller guarantees the format `libname(member)', via
1512 * Arch_ParseArchive.
1513 */
1514 assert(eoarch != NULL);
1515 assert(eoname != NULL);
1516
1517 *eoname = '\0'; /* Nuke parentheses during suffix search */
1518 *eoarch = '\0'; /* So a suffix can be found */
1519
1520 name = eoarch + 1;
1521
1522 /*
1523 * To simplify things, call Suff_FindDeps recursively on the member now,
1524 * so we can simply compare the member's .PREFIX and .TARGET variables
1525 * to locate its suffix. This allows us to figure out the suffix to
1526 * use for the archive without having to do a quadratic search over the
1527 * suffix list, backtracking for each one...
1528 */
1529 mem = Targ_GetNode(name);
1530 FindDeps(mem, cs);
1531
1532 /*
1533 * Create the link between the two nodes right off
1534 */
1535 Lst_Append(gn->children, mem);
1536 Lst_Append(mem->parents, gn);
1537 gn->unmade++;
1538
1539 /*
1540 * Copy in the variables from the member node to this one.
1541 */
1542 Var_Set(PREFIX, GNode_VarPrefix(mem), gn);
1543 Var_Set(TARGET, GNode_VarTarget(mem), gn);
1544
1545 memSuff = mem->suffix;
1546 if (memSuff == NULL) { /* Didn't know what it was. */
1547 SUFF_DEBUG0("using null suffix\n");
1548 memSuff = nullSuff;
1549 }
1550
1551
1552 /*
1553 * Set the other two local variables required for this target.
1554 */
1555 Var_Set(MEMBER, name, gn);
1556 Var_Set(ARCHIVE, gn->name, gn);
1557
1558 /*
1559 * Set $@ for compatibility with other makes
1560 */
1561 Var_Set(TARGET, gn->name, gn);
1562
1563 /*
1564 * Now we've got the important local variables set, expand any sources
1565 * that still contain variables or wildcards in their names.
1566 */
1567 ExpandAllChildren(gn);
1568
1569 if (memSuff != NULL)
1570 ExpandMember(gn, eoarch, mem, memSuff);
1571
1572 /*
1573 * Replace the opening and closing parens now we've no need of the separate
1574 * pieces.
1575 */
1576 *eoarch = '(';
1577 *eoname = ')';
1578
1579 /*
1580 * Pretend gn appeared to the left of a dependency operator so
1581 * the user needn't provide a transformation from the member to the
1582 * archive.
1583 */
1584 if (!GNode_IsTarget(gn))
1585 gn->type |= OP_DEPENDS;
1586
1587 /*
1588 * Flag the member as such so we remember to look in the archive for
1589 * its modification time. The OP_JOIN | OP_MADE is needed because this
1590 * target should never get made.
1591 */
1592 mem->type |= OP_MEMBER | OP_JOIN | OP_MADE;
1593 }
1594
1595 /*
1596 * If the node is a library, it is the arch module's job to find it
1597 * and set the TARGET variable accordingly. We merely provide the
1598 * search path, assuming all libraries end in ".a" (if the suffix
1599 * hasn't been defined, there's nothing we can do for it, so we just
1600 * set the TARGET variable to the node's name in order to give it a
1601 * value).
1602 */
1603 static void
1604 FindDepsLib(GNode *gn)
1605 {
1606 Suffix *suff = FindSuffixByName(LIBSUFF);
1607 if (suff != NULL) {
1608 Suffix_Reassign(&gn->suffix, suff);
1609 Arch_FindLib(gn, suff->searchPath);
1610 } else {
1611 Suffix_Unassign(&gn->suffix);
1612 Var_Set(TARGET, gn->name, gn);
1613 }
1614
1615 /*
1616 * Because a library (-lfoo) target doesn't follow the standard
1617 * filesystem conventions, we don't set the regular variables for
1618 * the thing. .PREFIX is simply made empty.
1619 */
1620 Var_Set(PREFIX, "", gn);
1621 }
1622
1623 static void
1624 FindDepsRegularKnown(const char *name, size_t nameLen, GNode *gn,
1625 CandidateList *srcs, CandidateList *targs)
1626 {
1627 SuffixListNode *ln;
1628 Candidate *targ;
1629 char *pref;
1630
1631 for (ln = sufflist->first; ln != NULL; ln = ln->next) {
1632 Suffix *suff = ln->datum;
1633 if (!Suffix_IsSuffix(suff, nameLen, name + nameLen))
1634 continue;
1635
1636 pref = bmake_strldup(name, (size_t)(nameLen - suff->nameLen));
1637 targ = Candidate_New(bmake_strdup(gn->name), pref, suff, NULL, gn);
1638
1639 CandidateList_AddCandidatesFor(srcs, targ);
1640
1641 /*
1642 * Record the target so we can nuke it
1643 */
1644 Lst_Append(targs, targ);
1645 }
1646 }
1647
1648 static void
1649 FindDepsRegularUnknown(GNode *gn, const char *sopref,
1650 CandidateList *srcs, CandidateList *targs)
1651 {
1652 Candidate *targ;
1653
1654 if (!Lst_IsEmpty(targs) || nullSuff == NULL)
1655 return;
1656
1657 SUFF_DEBUG1("\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
1658
1659 targ = Candidate_New(bmake_strdup(gn->name), bmake_strdup(sopref),
1660 nullSuff, NULL, gn);
1661
1662 /*
1663 * Only use the default suffix rules if we don't have commands
1664 * defined for this gnode; traditional make programs used to
1665 * not define suffix rules if the gnode had children but we
1666 * don't do this anymore.
1667 */
1668 if (Lst_IsEmpty(gn->commands))
1669 CandidateList_AddCandidatesFor(srcs, targ);
1670 else {
1671 SUFF_DEBUG0("not ");
1672 }
1673
1674 SUFF_DEBUG0("adding suffix rules\n");
1675
1676 Lst_Append(targs, targ);
1677 }
1678
1679 /*
1680 * Deal with finding the thing on the default search path. We
1681 * always do that, not only if the node is only a source (not
1682 * on the lhs of a dependency operator or [XXX] it has neither
1683 * children or commands) as the old pmake did.
1684 */
1685 static void
1686 FindDepsRegularPath(GNode *gn, Candidate *targ)
1687 {
1688 if (gn->type & (OP_PHONY | OP_NOPATH))
1689 return;
1690
1691 free(gn->path);
1692 gn->path = Dir_FindFile(gn->name,
1693 (targ == NULL ? dirSearchPath :
1694 targ->suff->searchPath));
1695 if (gn->path == NULL)
1696 return;
1697
1698 Var_Set(TARGET, gn->path, gn);
1699
1700 if (targ != NULL) {
1701 /*
1702 * Suffix known for the thing -- trim the suffix off
1703 * the path to form the proper .PREFIX variable.
1704 */
1705 size_t savep = strlen(gn->path) - targ->suff->nameLen;
1706 char savec;
1707 char *ptr;
1708
1709 Suffix_Reassign(&gn->suffix, targ->suff);
1710
1711 savec = gn->path[savep];
1712 gn->path[savep] = '\0';
1713
1714 if ((ptr = strrchr(gn->path, '/')) != NULL)
1715 ptr++;
1716 else
1717 ptr = gn->path;
1718
1719 Var_Set(PREFIX, ptr, gn);
1720
1721 gn->path[savep] = savec;
1722 } else {
1723 char *ptr;
1724
1725 /* The .PREFIX gets the full path if the target has no known suffix. */
1726 Suffix_Unassign(&gn->suffix);
1727
1728 if ((ptr = strrchr(gn->path, '/')) != NULL)
1729 ptr++;
1730 else
1731 ptr = gn->path;
1732
1733 Var_Set(PREFIX, ptr, gn);
1734 }
1735 }
1736
1737 /* Locate implicit dependencies for regular targets.
1738 *
1739 * Input:
1740 * gn Node for which to find sources
1741 *
1742 * Side Effects:
1743 * Same as Suff_FindDeps
1744 */
1745 static void
1746 FindDepsRegular(GNode *gn, CandidateSearcher *cs)
1747 {
1748 CandidateList *srcs; /* List of sources at which to look */
1749 CandidateList *targs; /* List of targets to which things can be
1750 * transformed. They all have the same file,
1751 * but different suff and prefix fields */
1752 Candidate *bottom; /* Start of found transformation path */
1753 Candidate *src;
1754 Candidate *targ;
1755
1756 const char *name = gn->name;
1757 size_t nameLen = strlen(name);
1758
1759 #ifdef DEBUG_SRC
1760 DEBUG1(SUFF, "FindDepsRegular \"%s\"\n", gn->name);
1761 #endif
1762
1763 /*
1764 * Begin at the beginning...
1765 */
1766 srcs = Lst_New();
1767 targs = Lst_New();
1768
1769 /*
1770 * We're caught in a catch-22 here. On the one hand, we want to use any
1771 * transformation implied by the target's sources, but we can't examine
1772 * the sources until we've expanded any variables/wildcards they may hold,
1773 * and we can't do that until we've set up the target's local variables
1774 * and we can't do that until we know what the proper suffix for the
1775 * target is (in case there are two suffixes one of which is a suffix of
1776 * the other) and we can't know that until we've found its implied
1777 * source, which we may not want to use if there's an existing source
1778 * that implies a different transformation.
1779 *
1780 * In an attempt to get around this, which may not work all the time,
1781 * but should work most of the time, we look for implied sources first,
1782 * checking transformations to all possible suffixes of the target,
1783 * use what we find to set the target's local variables, expand the
1784 * children, then look for any overriding transformations they imply.
1785 * Should we find one, we discard the one we found before.
1786 */
1787 bottom = NULL;
1788 targ = NULL;
1789
1790 if (!(gn->type & OP_PHONY)) {
1791
1792 FindDepsRegularKnown(name, nameLen, gn, srcs, targs);
1793
1794 /* Handle target of unknown suffix... */
1795 FindDepsRegularUnknown(gn, name, srcs, targs);
1796
1797 /*
1798 * Using the list of possible sources built up from the target
1799 * suffix(es), try and find an existing file/target that matches.
1800 */
1801 bottom = FindThem(srcs, cs);
1802
1803 if (bottom == NULL) {
1804 /*
1805 * No known transformations -- use the first suffix found
1806 * for setting the local variables.
1807 */
1808 if (targs->first != NULL)
1809 targ = targs->first->datum;
1810 else
1811 targ = NULL;
1812 } else {
1813 /*
1814 * Work up the transformation path to find the suffix of the
1815 * target to which the transformation was made.
1816 */
1817 for (targ = bottom; targ->parent != NULL; targ = targ->parent)
1818 continue;
1819 }
1820 }
1821
1822 Var_Set(TARGET, GNode_Path(gn), gn);
1823 Var_Set(PREFIX, targ != NULL ? targ->prefix : gn->name, gn);
1824
1825 /*
1826 * Now we've got the important local variables set, expand any sources
1827 * that still contain variables or wildcards in their names.
1828 */
1829 {
1830 GNodeListNode *ln, *nln;
1831 for (ln = gn->children->first; ln != NULL; ln = nln) {
1832 nln = ln->next;
1833 ExpandChildren(ln, gn);
1834 }
1835 }
1836
1837 if (targ == NULL) {
1838 SUFF_DEBUG1("\tNo valid suffix on %s\n", gn->name);
1839
1840 sfnd_abort:
1841 FindDepsRegularPath(gn, targ);
1842 goto sfnd_return;
1843 }
1844
1845 /*
1846 * If the suffix indicates that the target is a library, mark that in
1847 * the node's type field.
1848 */
1849 if (targ->suff->flags & SUFF_LIBRARY)
1850 gn->type |= OP_LIB;
1851
1852 /*
1853 * Check for overriding transformation rule implied by sources
1854 */
1855 if (!Lst_IsEmpty(gn->children)) {
1856 src = FindCmds(targ, cs);
1857
1858 if (src != NULL) {
1859 /*
1860 * Free up all the candidates in the transformation path,
1861 * up to but not including the parent node.
1862 */
1863 while (bottom != NULL && bottom->parent != NULL) {
1864 if (Lst_FindDatum(cs->list, bottom) == NULL)
1865 Lst_Append(cs->list, bottom);
1866 bottom = bottom->parent;
1867 }
1868 bottom = src;
1869 }
1870 }
1871
1872 if (bottom == NULL) {
1873 /*
1874 * No idea from where it can come -- return now.
1875 */
1876 goto sfnd_abort;
1877 }
1878
1879 /*
1880 * We now have a list of candidates headed by 'bottom' and linked via
1881 * their 'parent' pointers. What we do next is create links between
1882 * source and target nodes (which may or may not have been created)
1883 * and set the necessary local variables in each target.
1884 *
1885 * The commands for each target are set from the commands of the
1886 * transformation rule used to get from the src suffix to the targ
1887 * suffix. Note that this causes the commands list of the original
1888 * node, gn, to be replaced with the commands of the final
1889 * transformation rule.
1890 */
1891 if (bottom->node == NULL)
1892 bottom->node = Targ_GetNode(bottom->file);
1893
1894 for (src = bottom; src->parent != NULL; src = src->parent) {
1895 targ = src->parent;
1896
1897 Suffix_Reassign(&src->node->suffix, src->suff);
1898
1899 if (targ->node == NULL)
1900 targ->node = Targ_GetNode(targ->file);
1901
1902 ApplyTransform(targ->node, src->node,
1903 targ->suff, src->suff);
1904
1905 if (targ->node != gn) {
1906 /*
1907 * Finish off the dependency-search process for any nodes
1908 * between bottom and gn (no point in questing around the
1909 * filesystem for their implicit source when it's already
1910 * known). Note that the node can't have any sources that
1911 * need expanding, since SuffFindThem will stop on an existing
1912 * node, so all we need to do is set the standard variables.
1913 */
1914 targ->node->type |= OP_DEPS_FOUND;
1915 Var_Set(PREFIX, targ->prefix, targ->node);
1916 Var_Set(TARGET, targ->node->name, targ->node);
1917 }
1918 }
1919
1920 Suffix_Reassign(&gn->suffix, src->suff);
1921
1922 /*
1923 * Nuke the transformation path and the candidates left over in the
1924 * two lists.
1925 */
1926 sfnd_return:
1927 if (bottom != NULL && Lst_FindDatum(cs->list, bottom) == NULL)
1928 Lst_Append(cs->list, bottom);
1929
1930 while (RemoveCandidate(srcs) || RemoveCandidate(targs))
1931 continue;
1932
1933 Lst_MoveAll(cs->list, srcs);
1934 Lst_MoveAll(cs->list, targs);
1935 }
1936
1937
1938 /* Find implicit sources for the target.
1939 *
1940 * Nodes are added to the graph as children of the passed-in node. The nodes
1941 * are marked to have their IMPSRC variable filled in. The PREFIX variable
1942 * is set for the given node and all its implied children.
1943 *
1944 * The path found by this target is the shortest path in the transformation
1945 * graph, which may pass through non-existent targets, to an existing target.
1946 * The search continues on all paths from the root suffix until a file is
1947 * found. I.e. if there's a path .o -> .c -> .l -> .l,v from the root and the
1948 * .l,v file exists but the .c and .l files don't, the search will branch out
1949 * in all directions from .o and again from all the nodes on the next level
1950 * until the .l,v node is encountered.
1951 */
1952 void
1953 Suff_FindDeps(GNode *gn)
1954 {
1955 CandidateSearcher cs = { Lst_New() };
1956
1957 FindDeps(gn, &cs);
1958
1959 while (RemoveCandidate(cs.list))
1960 continue;
1961
1962 assert(Lst_IsEmpty(cs.list));
1963 Lst_Free(cs.list);
1964 }
1965
1966 static void
1967 FindDeps(GNode *gn, CandidateSearcher *cs)
1968 {
1969 if (gn->type & OP_DEPS_FOUND)
1970 return;
1971 gn->type |= OP_DEPS_FOUND;
1972
1973 /*
1974 * Make sure we have these set, may get revised below.
1975 */
1976 Var_Set(TARGET, GNode_Path(gn), gn);
1977 Var_Set(PREFIX, gn->name, gn);
1978
1979 SUFF_DEBUG1("SuffFindDeps \"%s\"\n", gn->name);
1980
1981 if (gn->type & OP_ARCHV)
1982 FindDepsArchive(gn, cs);
1983 else if (gn->type & OP_LIB)
1984 FindDepsLib(gn);
1985 else
1986 FindDepsRegular(gn, cs);
1987 }
1988
1989 /* Define which suffix is the null suffix.
1990 *
1991 * Need to handle the changing of the null suffix gracefully so the old
1992 * transformation rules don't just go away.
1993 *
1994 * Input:
1995 * name Name of null suffix
1996 */
1997 void
1998 Suff_SetNull(const char *name)
1999 {
2000 Suffix *suff = FindSuffixByName(name);
2001 if (suff == NULL) {
2002 Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.",
2003 name);
2004 return;
2005 }
2006
2007 if (nullSuff != NULL)
2008 nullSuff->flags &= ~(unsigned)SUFF_NULL;
2009 suff->flags |= SUFF_NULL;
2010 /*
2011 * XXX: Here's where the transformation mangling would take place
2012 */
2013 nullSuff = suff;
2014 }
2015
2016 /* Initialize the suffixes module. */
2017 void
2018 Suff_Init(void)
2019 {
2020 #ifdef CLEANUP
2021 suffClean = Lst_New();
2022 sufflist = Lst_New();
2023 #endif
2024 transforms = Lst_New();
2025
2026 /*
2027 * Create null suffix for single-suffix rules (POSIX). The thing doesn't
2028 * actually go on the suffix list or everyone will think that's its
2029 * suffix.
2030 */
2031 Suff_ClearSuffixes();
2032 }
2033
2034
2035 /* Clean up the suffixes module. */
2036 void
2037 Suff_End(void)
2038 {
2039 #ifdef CLEANUP
2040 Lst_Destroy(sufflist, SuffFree);
2041 Lst_Destroy(suffClean, SuffFree);
2042 if (nullSuff != NULL)
2043 SuffFree(nullSuff);
2044 Lst_Free(transforms);
2045 #endif
2046 }
2047
2048
2049 static void
2050 PrintSuffNames(const char *prefix, SuffixList *suffs)
2051 {
2052 SuffixListNode *ln;
2053
2054 debug_printf("#\t%s: ", prefix);
2055 for (ln = suffs->first; ln != NULL; ln = ln->next) {
2056 Suffix *suff = ln->datum;
2057 debug_printf("%s ", suff->name);
2058 }
2059 debug_printf("\n");
2060 }
2061
2062 static void
2063 Suffix_Print(Suffix *suff)
2064 {
2065 debug_printf("# \"%s\" (num %d, ref %d)",
2066 suff->name, suff->sNum, suff->refCount);
2067 if (suff->flags != 0) {
2068 char flags_buf[SuffixFlags_ToStringSize];
2069
2070 debug_printf(" (%s)",
2071 Enum_FlagsToString(flags_buf, sizeof flags_buf,
2072 suff->flags,
2073 SuffixFlags_ToStringSpecs));
2074 }
2075 debug_printf("\n");
2076
2077 PrintSuffNames("To", suff->parents);
2078 PrintSuffNames("From", suff->children);
2079
2080 debug_printf("#\tSearch Path: ");
2081 Dir_PrintPath(suff->searchPath);
2082 debug_printf("\n");
2083 }
2084
2085 static void
2086 PrintTransformation(GNode *t)
2087 {
2088 debug_printf("%-16s:", t->name);
2089 Targ_PrintType(t->type);
2090 debug_printf("\n");
2091 Targ_PrintCmds(t);
2092 debug_printf("\n");
2093 }
2094
2095 void
2096 Suff_PrintAll(void)
2097 {
2098 debug_printf("#*** Suffixes:\n");
2099 {
2100 SuffixListNode *ln;
2101 for (ln = sufflist->first; ln != NULL; ln = ln->next)
2102 Suffix_Print(ln->datum);
2103 }
2104
2105 debug_printf("#*** Transformations:\n");
2106 {
2107 GNodeListNode *ln;
2108 for (ln = transforms->first; ln != NULL; ln = ln->next)
2109 PrintTransformation(ln->datum);
2110 }
2111 }
2112