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