1*e1cee40dSSimon J. Gerraty /* $NetBSD: suff.c,v 1.86 2017/04/16 20:38:18 riastradh Exp $ */ 23955d011SMarcel Moolenaar 33955d011SMarcel Moolenaar /* 43955d011SMarcel Moolenaar * Copyright (c) 1988, 1989, 1990, 1993 53955d011SMarcel Moolenaar * The Regents of the University of California. All rights reserved. 63955d011SMarcel Moolenaar * 73955d011SMarcel Moolenaar * This code is derived from software contributed to Berkeley by 83955d011SMarcel Moolenaar * Adam de Boor. 93955d011SMarcel Moolenaar * 103955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 113955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions 123955d011SMarcel Moolenaar * are met: 133955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 143955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 153955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 163955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 173955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 183955d011SMarcel Moolenaar * 3. Neither the name of the University nor the names of its contributors 193955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software 203955d011SMarcel Moolenaar * without specific prior written permission. 213955d011SMarcel Moolenaar * 223955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 233955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 243955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 253955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 263955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 273955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 283955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 293955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 303955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 313955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 323955d011SMarcel Moolenaar * SUCH DAMAGE. 333955d011SMarcel Moolenaar */ 343955d011SMarcel Moolenaar 353955d011SMarcel Moolenaar /* 363955d011SMarcel Moolenaar * Copyright (c) 1989 by Berkeley Softworks 373955d011SMarcel Moolenaar * All rights reserved. 383955d011SMarcel Moolenaar * 393955d011SMarcel Moolenaar * This code is derived from software contributed to Berkeley by 403955d011SMarcel Moolenaar * Adam de Boor. 413955d011SMarcel Moolenaar * 423955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 433955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions 443955d011SMarcel Moolenaar * are met: 453955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 463955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 473955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 483955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 493955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 503955d011SMarcel Moolenaar * 3. All advertising materials mentioning features or use of this software 513955d011SMarcel Moolenaar * must display the following acknowledgement: 523955d011SMarcel Moolenaar * This product includes software developed by the University of 533955d011SMarcel Moolenaar * California, Berkeley and its contributors. 543955d011SMarcel Moolenaar * 4. Neither the name of the University nor the names of its contributors 553955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software 563955d011SMarcel Moolenaar * without specific prior written permission. 573955d011SMarcel Moolenaar * 583955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 593955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 603955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 613955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 623955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 633955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 643955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 653955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 663955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 673955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 683955d011SMarcel Moolenaar * SUCH DAMAGE. 693955d011SMarcel Moolenaar */ 703955d011SMarcel Moolenaar 713955d011SMarcel Moolenaar #ifndef MAKE_NATIVE 72*e1cee40dSSimon J. Gerraty static char rcsid[] = "$NetBSD: suff.c,v 1.86 2017/04/16 20:38:18 riastradh Exp $"; 733955d011SMarcel Moolenaar #else 743955d011SMarcel Moolenaar #include <sys/cdefs.h> 753955d011SMarcel Moolenaar #ifndef lint 763955d011SMarcel Moolenaar #if 0 773955d011SMarcel Moolenaar static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; 783955d011SMarcel Moolenaar #else 79*e1cee40dSSimon J. Gerraty __RCSID("$NetBSD: suff.c,v 1.86 2017/04/16 20:38:18 riastradh Exp $"); 803955d011SMarcel Moolenaar #endif 813955d011SMarcel Moolenaar #endif /* not lint */ 823955d011SMarcel Moolenaar #endif 833955d011SMarcel Moolenaar 843955d011SMarcel Moolenaar /*- 853955d011SMarcel Moolenaar * suff.c -- 863955d011SMarcel Moolenaar * Functions to maintain suffix lists and find implicit dependents 873955d011SMarcel Moolenaar * using suffix transformation rules 883955d011SMarcel Moolenaar * 893955d011SMarcel Moolenaar * Interface: 903955d011SMarcel Moolenaar * Suff_Init Initialize all things to do with suffixes. 913955d011SMarcel Moolenaar * 923955d011SMarcel Moolenaar * Suff_End Cleanup the module 933955d011SMarcel Moolenaar * 943955d011SMarcel Moolenaar * Suff_DoPaths This function is used to make life easier 953955d011SMarcel Moolenaar * when searching for a file according to its 963955d011SMarcel Moolenaar * suffix. It takes the global search path, 973955d011SMarcel Moolenaar * as defined using the .PATH: target, and appends 983955d011SMarcel Moolenaar * its directories to the path of each of the 993955d011SMarcel Moolenaar * defined suffixes, as specified using 1003955d011SMarcel Moolenaar * .PATH<suffix>: targets. In addition, all 1013955d011SMarcel Moolenaar * directories given for suffixes labeled as 1023955d011SMarcel Moolenaar * include files or libraries, using the .INCLUDES 1033955d011SMarcel Moolenaar * or .LIBS targets, are played with using 1043955d011SMarcel Moolenaar * Dir_MakeFlags to create the .INCLUDES and 1053955d011SMarcel Moolenaar * .LIBS global variables. 1063955d011SMarcel Moolenaar * 1073955d011SMarcel Moolenaar * Suff_ClearSuffixes Clear out all the suffixes and defined 1083955d011SMarcel Moolenaar * transformations. 1093955d011SMarcel Moolenaar * 1103955d011SMarcel Moolenaar * Suff_IsTransform Return TRUE if the passed string is the lhs 1113955d011SMarcel Moolenaar * of a transformation rule. 1123955d011SMarcel Moolenaar * 1133955d011SMarcel Moolenaar * Suff_AddSuffix Add the passed string as another known suffix. 1143955d011SMarcel Moolenaar * 1153955d011SMarcel Moolenaar * Suff_GetPath Return the search path for the given suffix. 1163955d011SMarcel Moolenaar * 1173955d011SMarcel Moolenaar * Suff_AddInclude Mark the given suffix as denoting an include 1183955d011SMarcel Moolenaar * file. 1193955d011SMarcel Moolenaar * 1203955d011SMarcel Moolenaar * Suff_AddLib Mark the given suffix as denoting a library. 1213955d011SMarcel Moolenaar * 1223955d011SMarcel Moolenaar * Suff_AddTransform Add another transformation to the suffix 1233955d011SMarcel Moolenaar * graph. Returns GNode suitable for framing, I 1243955d011SMarcel Moolenaar * mean, tacking commands, attributes, etc. on. 1253955d011SMarcel Moolenaar * 1263955d011SMarcel Moolenaar * Suff_SetNull Define the suffix to consider the suffix of 1273955d011SMarcel Moolenaar * any file that doesn't have a known one. 1283955d011SMarcel Moolenaar * 1293955d011SMarcel Moolenaar * Suff_FindDeps Find implicit sources for and the location of 1303955d011SMarcel Moolenaar * a target based on its suffix. Returns the 1313955d011SMarcel Moolenaar * bottom-most node added to the graph or NULL 1323955d011SMarcel Moolenaar * if the target had no implicit sources. 1333955d011SMarcel Moolenaar * 1343955d011SMarcel Moolenaar * Suff_FindPath Return the appropriate path to search in 1353955d011SMarcel Moolenaar * order to find the node. 1363955d011SMarcel Moolenaar */ 1373955d011SMarcel Moolenaar 138*e1cee40dSSimon J. Gerraty #include <assert.h> 1393955d011SMarcel Moolenaar #include <stdio.h> 1403955d011SMarcel Moolenaar #include "make.h" 1413955d011SMarcel Moolenaar #include "hash.h" 1423955d011SMarcel Moolenaar #include "dir.h" 1433955d011SMarcel Moolenaar 1443955d011SMarcel Moolenaar static Lst sufflist; /* Lst of suffixes */ 1453955d011SMarcel Moolenaar #ifdef CLEANUP 1463955d011SMarcel Moolenaar static Lst suffClean; /* Lst of suffixes to be cleaned */ 1473955d011SMarcel Moolenaar #endif 1483955d011SMarcel Moolenaar static Lst srclist; /* Lst of sources */ 1493955d011SMarcel Moolenaar static Lst transforms; /* Lst of transformation rules */ 1503955d011SMarcel Moolenaar 1513955d011SMarcel Moolenaar static int sNum = 0; /* Counter for assigning suffix numbers */ 1523955d011SMarcel Moolenaar 1533955d011SMarcel Moolenaar /* 1543955d011SMarcel Moolenaar * Structure describing an individual suffix. 1553955d011SMarcel Moolenaar */ 1563955d011SMarcel Moolenaar typedef struct _Suff { 1573955d011SMarcel Moolenaar char *name; /* The suffix itself */ 1583955d011SMarcel Moolenaar int nameLen; /* Length of the suffix */ 1593955d011SMarcel Moolenaar short flags; /* Type of suffix */ 1603955d011SMarcel Moolenaar #define SUFF_INCLUDE 0x01 /* One which is #include'd */ 1613955d011SMarcel Moolenaar #define SUFF_LIBRARY 0x02 /* One which contains a library */ 1623955d011SMarcel Moolenaar #define SUFF_NULL 0x04 /* The empty suffix */ 1633955d011SMarcel Moolenaar Lst searchPath; /* The path along which files of this suffix 1643955d011SMarcel Moolenaar * may be found */ 1653955d011SMarcel Moolenaar int sNum; /* The suffix number */ 1663955d011SMarcel Moolenaar int refCount; /* Reference count of list membership */ 1673955d011SMarcel Moolenaar Lst parents; /* Suffixes we have a transformation to */ 1683955d011SMarcel Moolenaar Lst children; /* Suffixes we have a transformation from */ 1693955d011SMarcel Moolenaar Lst ref; /* List of lists this suffix is referenced */ 1703955d011SMarcel Moolenaar } Suff; 1713955d011SMarcel Moolenaar 1723955d011SMarcel Moolenaar /* 1733955d011SMarcel Moolenaar * for SuffSuffIsSuffix 1743955d011SMarcel Moolenaar */ 1753955d011SMarcel Moolenaar typedef struct { 1763955d011SMarcel Moolenaar char *ename; /* The end of the name */ 1773955d011SMarcel Moolenaar int len; /* Length of the name */ 1783955d011SMarcel Moolenaar } SuffixCmpData; 1793955d011SMarcel Moolenaar 1803955d011SMarcel Moolenaar /* 1813955d011SMarcel Moolenaar * Structure used in the search for implied sources. 1823955d011SMarcel Moolenaar */ 1833955d011SMarcel Moolenaar typedef struct _Src { 1843955d011SMarcel Moolenaar char *file; /* The file to look for */ 1853955d011SMarcel Moolenaar char *pref; /* Prefix from which file was formed */ 1863955d011SMarcel Moolenaar Suff *suff; /* The suffix on the file */ 1873955d011SMarcel Moolenaar struct _Src *parent; /* The Src for which this is a source */ 1883955d011SMarcel Moolenaar GNode *node; /* The node describing the file */ 1893955d011SMarcel Moolenaar int children; /* Count of existing children (so we don't free 1903955d011SMarcel Moolenaar * this thing too early or never nuke it) */ 1913955d011SMarcel Moolenaar #ifdef DEBUG_SRC 1923955d011SMarcel Moolenaar Lst cp; /* Debug; children list */ 1933955d011SMarcel Moolenaar #endif 1943955d011SMarcel Moolenaar } Src; 1953955d011SMarcel Moolenaar 1963955d011SMarcel Moolenaar /* 1973955d011SMarcel Moolenaar * A structure for passing more than one argument to the Lst-library-invoked 1983955d011SMarcel Moolenaar * function... 1993955d011SMarcel Moolenaar */ 2003955d011SMarcel Moolenaar typedef struct { 2013955d011SMarcel Moolenaar Lst l; 2023955d011SMarcel Moolenaar Src *s; 2033955d011SMarcel Moolenaar } LstSrc; 2043955d011SMarcel Moolenaar 2053955d011SMarcel Moolenaar typedef struct { 2063955d011SMarcel Moolenaar GNode **gn; 2073955d011SMarcel Moolenaar Suff *s; 2083955d011SMarcel Moolenaar Boolean r; 2093955d011SMarcel Moolenaar } GNodeSuff; 2103955d011SMarcel Moolenaar 2113955d011SMarcel Moolenaar static Suff *suffNull; /* The NULL suffix for this run */ 2123955d011SMarcel Moolenaar static Suff *emptySuff; /* The empty suffix required for POSIX 2133955d011SMarcel Moolenaar * single-suffix transformation rules */ 2143955d011SMarcel Moolenaar 2153955d011SMarcel Moolenaar 2163955d011SMarcel Moolenaar static const char *SuffStrIsPrefix(const char *, const char *); 2173955d011SMarcel Moolenaar static char *SuffSuffIsSuffix(const Suff *, const SuffixCmpData *); 2183955d011SMarcel Moolenaar static int SuffSuffIsSuffixP(const void *, const void *); 2193955d011SMarcel Moolenaar static int SuffSuffHasNameP(const void *, const void *); 2203955d011SMarcel Moolenaar static int SuffSuffIsPrefix(const void *, const void *); 2213955d011SMarcel Moolenaar static int SuffGNHasNameP(const void *, const void *); 2223955d011SMarcel Moolenaar static void SuffUnRef(void *, void *); 2233955d011SMarcel Moolenaar static void SuffFree(void *); 2243955d011SMarcel Moolenaar static void SuffInsert(Lst, Suff *); 2253955d011SMarcel Moolenaar static void SuffRemove(Lst, Suff *); 2263955d011SMarcel Moolenaar static Boolean SuffParseTransform(char *, Suff **, Suff **); 2273955d011SMarcel Moolenaar static int SuffRebuildGraph(void *, void *); 2283955d011SMarcel Moolenaar static int SuffScanTargets(void *, void *); 2293955d011SMarcel Moolenaar static int SuffAddSrc(void *, void *); 2303955d011SMarcel Moolenaar static int SuffRemoveSrc(Lst); 2313955d011SMarcel Moolenaar static void SuffAddLevel(Lst, Src *); 2323955d011SMarcel Moolenaar static Src *SuffFindThem(Lst, Lst); 2333955d011SMarcel Moolenaar static Src *SuffFindCmds(Src *, Lst); 2343955d011SMarcel Moolenaar static void SuffExpandChildren(LstNode, GNode *); 2353955d011SMarcel Moolenaar static void SuffExpandWildcards(LstNode, GNode *); 2363955d011SMarcel Moolenaar static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); 2373955d011SMarcel Moolenaar static void SuffFindDeps(GNode *, Lst); 2383955d011SMarcel Moolenaar static void SuffFindArchiveDeps(GNode *, Lst); 2393955d011SMarcel Moolenaar static void SuffFindNormalDeps(GNode *, Lst); 2403955d011SMarcel Moolenaar static int SuffPrintName(void *, void *); 2413955d011SMarcel Moolenaar static int SuffPrintSuff(void *, void *); 2423955d011SMarcel Moolenaar static int SuffPrintTrans(void *, void *); 2433955d011SMarcel Moolenaar 2443955d011SMarcel Moolenaar /*************** Lst Predicates ****************/ 2453955d011SMarcel Moolenaar /*- 2463955d011SMarcel Moolenaar *----------------------------------------------------------------------- 2473955d011SMarcel Moolenaar * SuffStrIsPrefix -- 2483955d011SMarcel Moolenaar * See if pref is a prefix of str. 2493955d011SMarcel Moolenaar * 2503955d011SMarcel Moolenaar * Input: 2513955d011SMarcel Moolenaar * pref possible prefix 2523955d011SMarcel Moolenaar * str string to check 2533955d011SMarcel Moolenaar * 2543955d011SMarcel Moolenaar * Results: 2553955d011SMarcel Moolenaar * NULL if it ain't, pointer to character in str after prefix if so 2563955d011SMarcel Moolenaar * 2573955d011SMarcel Moolenaar * Side Effects: 2583955d011SMarcel Moolenaar * None 2593955d011SMarcel Moolenaar *----------------------------------------------------------------------- 2603955d011SMarcel Moolenaar */ 2613955d011SMarcel Moolenaar static const char * 2623955d011SMarcel Moolenaar SuffStrIsPrefix(const char *pref, const char *str) 2633955d011SMarcel Moolenaar { 2643955d011SMarcel Moolenaar while (*str && *pref == *str) { 2653955d011SMarcel Moolenaar pref++; 2663955d011SMarcel Moolenaar str++; 2673955d011SMarcel Moolenaar } 2683955d011SMarcel Moolenaar 2693955d011SMarcel Moolenaar return (*pref ? NULL : str); 2703955d011SMarcel Moolenaar } 2713955d011SMarcel Moolenaar 2723955d011SMarcel Moolenaar /*- 2733955d011SMarcel Moolenaar *----------------------------------------------------------------------- 2743955d011SMarcel Moolenaar * SuffSuffIsSuffix -- 2753955d011SMarcel Moolenaar * See if suff is a suffix of str. sd->ename should point to THE END 2763955d011SMarcel Moolenaar * of the string to check. (THE END == the null byte) 2773955d011SMarcel Moolenaar * 2783955d011SMarcel Moolenaar * Input: 2793955d011SMarcel Moolenaar * s possible suffix 2803955d011SMarcel Moolenaar * sd string to examine 2813955d011SMarcel Moolenaar * 2823955d011SMarcel Moolenaar * Results: 2833955d011SMarcel Moolenaar * NULL if it ain't, pointer to character in str before suffix if 2843955d011SMarcel Moolenaar * it is. 2853955d011SMarcel Moolenaar * 2863955d011SMarcel Moolenaar * Side Effects: 2873955d011SMarcel Moolenaar * None 2883955d011SMarcel Moolenaar *----------------------------------------------------------------------- 2893955d011SMarcel Moolenaar */ 2903955d011SMarcel Moolenaar static char * 2913955d011SMarcel Moolenaar SuffSuffIsSuffix(const Suff *s, const SuffixCmpData *sd) 2923955d011SMarcel Moolenaar { 2933955d011SMarcel Moolenaar char *p1; /* Pointer into suffix name */ 2943955d011SMarcel Moolenaar char *p2; /* Pointer into string being examined */ 2953955d011SMarcel Moolenaar 2963955d011SMarcel Moolenaar if (sd->len < s->nameLen) 2973955d011SMarcel Moolenaar return NULL; /* this string is shorter than the suffix */ 2983955d011SMarcel Moolenaar 2993955d011SMarcel Moolenaar p1 = s->name + s->nameLen; 3003955d011SMarcel Moolenaar p2 = sd->ename; 3013955d011SMarcel Moolenaar 3023955d011SMarcel Moolenaar while (p1 >= s->name && *p1 == *p2) { 3033955d011SMarcel Moolenaar p1--; 3043955d011SMarcel Moolenaar p2--; 3053955d011SMarcel Moolenaar } 3063955d011SMarcel Moolenaar 3073955d011SMarcel Moolenaar return (p1 == s->name - 1 ? p2 : NULL); 3083955d011SMarcel Moolenaar } 3093955d011SMarcel Moolenaar 3103955d011SMarcel Moolenaar /*- 3113955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3123955d011SMarcel Moolenaar * SuffSuffIsSuffixP -- 3133955d011SMarcel Moolenaar * Predicate form of SuffSuffIsSuffix. Passed as the callback function 3143955d011SMarcel Moolenaar * to Lst_Find. 3153955d011SMarcel Moolenaar * 3163955d011SMarcel Moolenaar * Results: 3173955d011SMarcel Moolenaar * 0 if the suffix is the one desired, non-zero if not. 3183955d011SMarcel Moolenaar * 3193955d011SMarcel Moolenaar * Side Effects: 3203955d011SMarcel Moolenaar * None. 3213955d011SMarcel Moolenaar * 3223955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3233955d011SMarcel Moolenaar */ 3243955d011SMarcel Moolenaar static int 3253955d011SMarcel Moolenaar SuffSuffIsSuffixP(const void *s, const void *sd) 3263955d011SMarcel Moolenaar { 3273955d011SMarcel Moolenaar return(!SuffSuffIsSuffix(s, sd)); 3283955d011SMarcel Moolenaar } 3293955d011SMarcel Moolenaar 3303955d011SMarcel Moolenaar /*- 3313955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3323955d011SMarcel Moolenaar * SuffSuffHasNameP -- 3333955d011SMarcel Moolenaar * Callback procedure for finding a suffix based on its name. Used by 3343955d011SMarcel Moolenaar * Suff_GetPath. 3353955d011SMarcel Moolenaar * 3363955d011SMarcel Moolenaar * Input: 3373955d011SMarcel Moolenaar * s Suffix to check 3383955d011SMarcel Moolenaar * sd Desired name 3393955d011SMarcel Moolenaar * 3403955d011SMarcel Moolenaar * Results: 3413955d011SMarcel Moolenaar * 0 if the suffix is of the given name. non-zero otherwise. 3423955d011SMarcel Moolenaar * 3433955d011SMarcel Moolenaar * Side Effects: 3443955d011SMarcel Moolenaar * None 3453955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3463955d011SMarcel Moolenaar */ 3473955d011SMarcel Moolenaar static int 3483955d011SMarcel Moolenaar SuffSuffHasNameP(const void *s, const void *sname) 3493955d011SMarcel Moolenaar { 3503955d011SMarcel Moolenaar return (strcmp(sname, ((const Suff *)s)->name)); 3513955d011SMarcel Moolenaar } 3523955d011SMarcel Moolenaar 3533955d011SMarcel Moolenaar /*- 3543955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3553955d011SMarcel Moolenaar * SuffSuffIsPrefix -- 3563955d011SMarcel Moolenaar * See if the suffix described by s is a prefix of the string. Care 3573955d011SMarcel Moolenaar * must be taken when using this to search for transformations and 3583955d011SMarcel Moolenaar * what-not, since there could well be two suffixes, one of which 3593955d011SMarcel Moolenaar * is a prefix of the other... 3603955d011SMarcel Moolenaar * 3613955d011SMarcel Moolenaar * Input: 3623955d011SMarcel Moolenaar * s suffix to compare 3633955d011SMarcel Moolenaar * str string to examine 3643955d011SMarcel Moolenaar * 3653955d011SMarcel Moolenaar * Results: 3663955d011SMarcel Moolenaar * 0 if s is a prefix of str. non-zero otherwise 3673955d011SMarcel Moolenaar * 3683955d011SMarcel Moolenaar * Side Effects: 3693955d011SMarcel Moolenaar * None 3703955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3713955d011SMarcel Moolenaar */ 3723955d011SMarcel Moolenaar static int 3733955d011SMarcel Moolenaar SuffSuffIsPrefix(const void *s, const void *str) 3743955d011SMarcel Moolenaar { 3753955d011SMarcel Moolenaar return SuffStrIsPrefix(((const Suff *)s)->name, str) == NULL; 3763955d011SMarcel Moolenaar } 3773955d011SMarcel Moolenaar 3783955d011SMarcel Moolenaar /*- 3793955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3803955d011SMarcel Moolenaar * SuffGNHasNameP -- 3813955d011SMarcel Moolenaar * See if the graph node has the desired name 3823955d011SMarcel Moolenaar * 3833955d011SMarcel Moolenaar * Input: 3843955d011SMarcel Moolenaar * gn current node we're looking at 3853955d011SMarcel Moolenaar * name name we're looking for 3863955d011SMarcel Moolenaar * 3873955d011SMarcel Moolenaar * Results: 3883955d011SMarcel Moolenaar * 0 if it does. non-zero if it doesn't 3893955d011SMarcel Moolenaar * 3903955d011SMarcel Moolenaar * Side Effects: 3913955d011SMarcel Moolenaar * None 3923955d011SMarcel Moolenaar *----------------------------------------------------------------------- 3933955d011SMarcel Moolenaar */ 3943955d011SMarcel Moolenaar static int 3953955d011SMarcel Moolenaar SuffGNHasNameP(const void *gn, const void *name) 3963955d011SMarcel Moolenaar { 3973955d011SMarcel Moolenaar return (strcmp(name, ((const GNode *)gn)->name)); 3983955d011SMarcel Moolenaar } 3993955d011SMarcel Moolenaar 4003955d011SMarcel Moolenaar /*********** Maintenance Functions ************/ 4013955d011SMarcel Moolenaar 4023955d011SMarcel Moolenaar static void 4033955d011SMarcel Moolenaar SuffUnRef(void *lp, void *sp) 4043955d011SMarcel Moolenaar { 4053955d011SMarcel Moolenaar Lst l = (Lst) lp; 4063955d011SMarcel Moolenaar 4073955d011SMarcel Moolenaar LstNode ln = Lst_Member(l, sp); 4083955d011SMarcel Moolenaar if (ln != NULL) { 4093955d011SMarcel Moolenaar Lst_Remove(l, ln); 4103955d011SMarcel Moolenaar ((Suff *)sp)->refCount--; 4113955d011SMarcel Moolenaar } 4123955d011SMarcel Moolenaar } 4133955d011SMarcel Moolenaar 4143955d011SMarcel Moolenaar /*- 4153955d011SMarcel Moolenaar *----------------------------------------------------------------------- 4163955d011SMarcel Moolenaar * SuffFree -- 4173955d011SMarcel Moolenaar * Free up all memory associated with the given suffix structure. 4183955d011SMarcel Moolenaar * 4193955d011SMarcel Moolenaar * Results: 4203955d011SMarcel Moolenaar * none 4213955d011SMarcel Moolenaar * 4223955d011SMarcel Moolenaar * Side Effects: 4233955d011SMarcel Moolenaar * the suffix entry is detroyed 4243955d011SMarcel Moolenaar *----------------------------------------------------------------------- 4253955d011SMarcel Moolenaar */ 4263955d011SMarcel Moolenaar static void 4273955d011SMarcel Moolenaar SuffFree(void *sp) 4283955d011SMarcel Moolenaar { 4293955d011SMarcel Moolenaar Suff *s = (Suff *)sp; 4303955d011SMarcel Moolenaar 4313955d011SMarcel Moolenaar if (s == suffNull) 4323955d011SMarcel Moolenaar suffNull = NULL; 4333955d011SMarcel Moolenaar 4343955d011SMarcel Moolenaar if (s == emptySuff) 4353955d011SMarcel Moolenaar emptySuff = NULL; 4363955d011SMarcel Moolenaar 4373955d011SMarcel Moolenaar #ifdef notdef 4383955d011SMarcel Moolenaar /* We don't delete suffixes in order, so we cannot use this */ 4393955d011SMarcel Moolenaar if (s->refCount) 4403955d011SMarcel Moolenaar Punt("Internal error deleting suffix `%s' with refcount = %d", s->name, 4413955d011SMarcel Moolenaar s->refCount); 4423955d011SMarcel Moolenaar #endif 4433955d011SMarcel Moolenaar 4443955d011SMarcel Moolenaar Lst_Destroy(s->ref, NULL); 4453955d011SMarcel Moolenaar Lst_Destroy(s->children, NULL); 4463955d011SMarcel Moolenaar Lst_Destroy(s->parents, NULL); 4473955d011SMarcel Moolenaar Lst_Destroy(s->searchPath, Dir_Destroy); 4483955d011SMarcel Moolenaar 4493955d011SMarcel Moolenaar free(s->name); 4503955d011SMarcel Moolenaar free(s); 4513955d011SMarcel Moolenaar } 4523955d011SMarcel Moolenaar 4533955d011SMarcel Moolenaar /*- 4543955d011SMarcel Moolenaar *----------------------------------------------------------------------- 4553955d011SMarcel Moolenaar * SuffRemove -- 4563955d011SMarcel Moolenaar * Remove the suffix into the list 4573955d011SMarcel Moolenaar * 4583955d011SMarcel Moolenaar * Results: 4593955d011SMarcel Moolenaar * None 4603955d011SMarcel Moolenaar * 4613955d011SMarcel Moolenaar * Side Effects: 4623955d011SMarcel Moolenaar * The reference count for the suffix is decremented and the 4633955d011SMarcel Moolenaar * suffix is possibly freed 4643955d011SMarcel Moolenaar *----------------------------------------------------------------------- 4653955d011SMarcel Moolenaar */ 4663955d011SMarcel Moolenaar static void 4673955d011SMarcel Moolenaar SuffRemove(Lst l, Suff *s) 4683955d011SMarcel Moolenaar { 4693955d011SMarcel Moolenaar SuffUnRef(l, s); 4703955d011SMarcel Moolenaar if (s->refCount == 0) { 4713955d011SMarcel Moolenaar SuffUnRef(sufflist, s); 4723955d011SMarcel Moolenaar SuffFree(s); 4733955d011SMarcel Moolenaar } 4743955d011SMarcel Moolenaar } 4753955d011SMarcel Moolenaar 4763955d011SMarcel Moolenaar /*- 4773955d011SMarcel Moolenaar *----------------------------------------------------------------------- 4783955d011SMarcel Moolenaar * SuffInsert -- 4793955d011SMarcel Moolenaar * Insert the suffix into the list keeping the list ordered by suffix 4803955d011SMarcel Moolenaar * numbers. 4813955d011SMarcel Moolenaar * 4823955d011SMarcel Moolenaar * Input: 4833955d011SMarcel Moolenaar * l the list where in s should be inserted 4843955d011SMarcel Moolenaar * s the suffix to insert 4853955d011SMarcel Moolenaar * 4863955d011SMarcel Moolenaar * Results: 4873955d011SMarcel Moolenaar * None 4883955d011SMarcel Moolenaar * 4893955d011SMarcel Moolenaar * Side Effects: 4903955d011SMarcel Moolenaar * The reference count of the suffix is incremented 4913955d011SMarcel Moolenaar *----------------------------------------------------------------------- 4923955d011SMarcel Moolenaar */ 4933955d011SMarcel Moolenaar static void 4943955d011SMarcel Moolenaar SuffInsert(Lst l, Suff *s) 4953955d011SMarcel Moolenaar { 4963955d011SMarcel Moolenaar LstNode ln; /* current element in l we're examining */ 4973955d011SMarcel Moolenaar Suff *s2 = NULL; /* the suffix descriptor in this element */ 4983955d011SMarcel Moolenaar 4993955d011SMarcel Moolenaar if (Lst_Open(l) == FAILURE) { 5003955d011SMarcel Moolenaar return; 5013955d011SMarcel Moolenaar } 5023955d011SMarcel Moolenaar while ((ln = Lst_Next(l)) != NULL) { 5033955d011SMarcel Moolenaar s2 = (Suff *)Lst_Datum(ln); 5043955d011SMarcel Moolenaar if (s2->sNum >= s->sNum) { 5053955d011SMarcel Moolenaar break; 5063955d011SMarcel Moolenaar } 5073955d011SMarcel Moolenaar } 5083955d011SMarcel Moolenaar 5093955d011SMarcel Moolenaar Lst_Close(l); 5103955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 5113955d011SMarcel Moolenaar fprintf(debug_file, "inserting %s(%d)...", s->name, s->sNum); 5123955d011SMarcel Moolenaar } 5133955d011SMarcel Moolenaar if (ln == NULL) { 5143955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 5153955d011SMarcel Moolenaar fprintf(debug_file, "at end of list\n"); 5163955d011SMarcel Moolenaar } 5173955d011SMarcel Moolenaar (void)Lst_AtEnd(l, s); 5183955d011SMarcel Moolenaar s->refCount++; 5193955d011SMarcel Moolenaar (void)Lst_AtEnd(s->ref, l); 5203955d011SMarcel Moolenaar } else if (s2->sNum != s->sNum) { 5213955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 5223955d011SMarcel Moolenaar fprintf(debug_file, "before %s(%d)\n", s2->name, s2->sNum); 5233955d011SMarcel Moolenaar } 5243955d011SMarcel Moolenaar (void)Lst_InsertBefore(l, ln, s); 5253955d011SMarcel Moolenaar s->refCount++; 5263955d011SMarcel Moolenaar (void)Lst_AtEnd(s->ref, l); 5273955d011SMarcel Moolenaar } else if (DEBUG(SUFF)) { 5283955d011SMarcel Moolenaar fprintf(debug_file, "already there\n"); 5293955d011SMarcel Moolenaar } 5303955d011SMarcel Moolenaar } 5313955d011SMarcel Moolenaar 5323955d011SMarcel Moolenaar /*- 5333955d011SMarcel Moolenaar *----------------------------------------------------------------------- 5343955d011SMarcel Moolenaar * Suff_ClearSuffixes -- 5353955d011SMarcel Moolenaar * This is gross. Nuke the list of suffixes but keep all transformation 5363955d011SMarcel Moolenaar * rules around. The transformation graph is destroyed in this process, 5373955d011SMarcel Moolenaar * but we leave the list of rules so when a new graph is formed the rules 5383955d011SMarcel Moolenaar * will remain. 5393955d011SMarcel Moolenaar * This function is called from the parse module when a 5403955d011SMarcel Moolenaar * .SUFFIXES:\n line is encountered. 5413955d011SMarcel Moolenaar * 5423955d011SMarcel Moolenaar * Results: 5433955d011SMarcel Moolenaar * none 5443955d011SMarcel Moolenaar * 5453955d011SMarcel Moolenaar * Side Effects: 5463955d011SMarcel Moolenaar * the sufflist and its graph nodes are destroyed 5473955d011SMarcel Moolenaar *----------------------------------------------------------------------- 5483955d011SMarcel Moolenaar */ 5493955d011SMarcel Moolenaar void 5503955d011SMarcel Moolenaar Suff_ClearSuffixes(void) 5513955d011SMarcel Moolenaar { 5523955d011SMarcel Moolenaar #ifdef CLEANUP 5533955d011SMarcel Moolenaar Lst_Concat(suffClean, sufflist, LST_CONCLINK); 5543955d011SMarcel Moolenaar #endif 5553955d011SMarcel Moolenaar sufflist = Lst_Init(FALSE); 5563955d011SMarcel Moolenaar sNum = 0; 5576e050540SSimon J. Gerraty if (suffNull) 5586e050540SSimon J. Gerraty SuffFree(suffNull); 5596e050540SSimon J. Gerraty emptySuff = suffNull = bmake_malloc(sizeof(Suff)); 5606e050540SSimon J. Gerraty 5616e050540SSimon J. Gerraty suffNull->name = bmake_strdup(""); 5626e050540SSimon J. Gerraty suffNull->nameLen = 0; 5636e050540SSimon J. Gerraty suffNull->searchPath = Lst_Init(FALSE); 5646e050540SSimon J. Gerraty Dir_Concat(suffNull->searchPath, dirSearchPath); 5656e050540SSimon J. Gerraty suffNull->children = Lst_Init(FALSE); 5666e050540SSimon J. Gerraty suffNull->parents = Lst_Init(FALSE); 5676e050540SSimon J. Gerraty suffNull->ref = Lst_Init(FALSE); 5686e050540SSimon J. Gerraty suffNull->sNum = sNum++; 5696e050540SSimon J. Gerraty suffNull->flags = SUFF_NULL; 5706e050540SSimon J. Gerraty suffNull->refCount = 1; 5713955d011SMarcel Moolenaar } 5723955d011SMarcel Moolenaar 5733955d011SMarcel Moolenaar /*- 5743955d011SMarcel Moolenaar *----------------------------------------------------------------------- 5753955d011SMarcel Moolenaar * SuffParseTransform -- 5763955d011SMarcel Moolenaar * Parse a transformation string to find its two component suffixes. 5773955d011SMarcel Moolenaar * 5783955d011SMarcel Moolenaar * Input: 5793955d011SMarcel Moolenaar * str String being parsed 5803955d011SMarcel Moolenaar * srcPtr Place to store source of trans. 5813955d011SMarcel Moolenaar * targPtr Place to store target of trans. 5823955d011SMarcel Moolenaar * 5833955d011SMarcel Moolenaar * Results: 5843955d011SMarcel Moolenaar * TRUE if the string is a valid transformation and FALSE otherwise. 5853955d011SMarcel Moolenaar * 5863955d011SMarcel Moolenaar * Side Effects: 5873955d011SMarcel Moolenaar * The passed pointers are overwritten. 5883955d011SMarcel Moolenaar * 5893955d011SMarcel Moolenaar *----------------------------------------------------------------------- 5903955d011SMarcel Moolenaar */ 5913955d011SMarcel Moolenaar static Boolean 5923955d011SMarcel Moolenaar SuffParseTransform(char *str, Suff **srcPtr, Suff **targPtr) 5933955d011SMarcel Moolenaar { 5943955d011SMarcel Moolenaar LstNode srcLn; /* element in suffix list of trans source*/ 5953955d011SMarcel Moolenaar Suff *src; /* Source of transformation */ 5963955d011SMarcel Moolenaar LstNode targLn; /* element in suffix list of trans target*/ 5973955d011SMarcel Moolenaar char *str2; /* Extra pointer (maybe target suffix) */ 5983955d011SMarcel Moolenaar LstNode singleLn; /* element in suffix list of any suffix 5993955d011SMarcel Moolenaar * that exactly matches str */ 6003955d011SMarcel Moolenaar Suff *single = NULL;/* Source of possible transformation to 6013955d011SMarcel Moolenaar * null suffix */ 6023955d011SMarcel Moolenaar 6033955d011SMarcel Moolenaar srcLn = NULL; 6043955d011SMarcel Moolenaar singleLn = NULL; 6053955d011SMarcel Moolenaar 6063955d011SMarcel Moolenaar /* 6073955d011SMarcel Moolenaar * Loop looking first for a suffix that matches the start of the 6083955d011SMarcel Moolenaar * string and then for one that exactly matches the rest of it. If 6093955d011SMarcel Moolenaar * we can find two that meet these criteria, we've successfully 6103955d011SMarcel Moolenaar * parsed the string. 6113955d011SMarcel Moolenaar */ 6123955d011SMarcel Moolenaar for (;;) { 6133955d011SMarcel Moolenaar if (srcLn == NULL) { 6143955d011SMarcel Moolenaar srcLn = Lst_Find(sufflist, str, SuffSuffIsPrefix); 6153955d011SMarcel Moolenaar } else { 6163955d011SMarcel Moolenaar srcLn = Lst_FindFrom(sufflist, Lst_Succ(srcLn), str, 6173955d011SMarcel Moolenaar SuffSuffIsPrefix); 6183955d011SMarcel Moolenaar } 6193955d011SMarcel Moolenaar if (srcLn == NULL) { 6203955d011SMarcel Moolenaar /* 6213955d011SMarcel Moolenaar * Ran out of source suffixes -- no such rule 6223955d011SMarcel Moolenaar */ 6233955d011SMarcel Moolenaar if (singleLn != NULL) { 6243955d011SMarcel Moolenaar /* 6253955d011SMarcel Moolenaar * Not so fast Mr. Smith! There was a suffix that encompassed 6263955d011SMarcel Moolenaar * the entire string, so we assume it was a transformation 6273955d011SMarcel Moolenaar * to the null suffix (thank you POSIX). We still prefer to 6283955d011SMarcel Moolenaar * find a double rule over a singleton, hence we leave this 6293955d011SMarcel Moolenaar * check until the end. 6303955d011SMarcel Moolenaar * 6313955d011SMarcel Moolenaar * XXX: Use emptySuff over suffNull? 6323955d011SMarcel Moolenaar */ 6333955d011SMarcel Moolenaar *srcPtr = single; 6343955d011SMarcel Moolenaar *targPtr = suffNull; 6353955d011SMarcel Moolenaar return(TRUE); 6363955d011SMarcel Moolenaar } 6373955d011SMarcel Moolenaar return (FALSE); 6383955d011SMarcel Moolenaar } 6393955d011SMarcel Moolenaar src = (Suff *)Lst_Datum(srcLn); 6403955d011SMarcel Moolenaar str2 = str + src->nameLen; 6413955d011SMarcel Moolenaar if (*str2 == '\0') { 6423955d011SMarcel Moolenaar single = src; 6433955d011SMarcel Moolenaar singleLn = srcLn; 6443955d011SMarcel Moolenaar } else { 6453955d011SMarcel Moolenaar targLn = Lst_Find(sufflist, str2, SuffSuffHasNameP); 6463955d011SMarcel Moolenaar if (targLn != NULL) { 6473955d011SMarcel Moolenaar *srcPtr = src; 6483955d011SMarcel Moolenaar *targPtr = (Suff *)Lst_Datum(targLn); 6493955d011SMarcel Moolenaar return (TRUE); 6503955d011SMarcel Moolenaar } 6513955d011SMarcel Moolenaar } 6523955d011SMarcel Moolenaar } 6533955d011SMarcel Moolenaar } 6543955d011SMarcel Moolenaar 6553955d011SMarcel Moolenaar /*- 6563955d011SMarcel Moolenaar *----------------------------------------------------------------------- 6573955d011SMarcel Moolenaar * Suff_IsTransform -- 6583955d011SMarcel Moolenaar * Return TRUE if the given string is a transformation rule 6593955d011SMarcel Moolenaar * 6603955d011SMarcel Moolenaar * 6613955d011SMarcel Moolenaar * Input: 6623955d011SMarcel Moolenaar * str string to check 6633955d011SMarcel Moolenaar * 6643955d011SMarcel Moolenaar * Results: 6653955d011SMarcel Moolenaar * TRUE if the string is a concatenation of two known suffixes. 6663955d011SMarcel Moolenaar * FALSE otherwise 6673955d011SMarcel Moolenaar * 6683955d011SMarcel Moolenaar * Side Effects: 6693955d011SMarcel Moolenaar * None 6703955d011SMarcel Moolenaar *----------------------------------------------------------------------- 6713955d011SMarcel Moolenaar */ 6723955d011SMarcel Moolenaar Boolean 6733955d011SMarcel Moolenaar Suff_IsTransform(char *str) 6743955d011SMarcel Moolenaar { 6753955d011SMarcel Moolenaar Suff *src, *targ; 6763955d011SMarcel Moolenaar 6773955d011SMarcel Moolenaar return (SuffParseTransform(str, &src, &targ)); 6783955d011SMarcel Moolenaar } 6793955d011SMarcel Moolenaar 6803955d011SMarcel Moolenaar /*- 6813955d011SMarcel Moolenaar *----------------------------------------------------------------------- 6823955d011SMarcel Moolenaar * Suff_AddTransform -- 6833955d011SMarcel Moolenaar * Add the transformation rule described by the line to the 6843955d011SMarcel Moolenaar * list of rules and place the transformation itself in the graph 6853955d011SMarcel Moolenaar * 6863955d011SMarcel Moolenaar * Input: 6873955d011SMarcel Moolenaar * line name of transformation to add 6883955d011SMarcel Moolenaar * 6893955d011SMarcel Moolenaar * Results: 6903955d011SMarcel Moolenaar * The node created for the transformation in the transforms list 6913955d011SMarcel Moolenaar * 6923955d011SMarcel Moolenaar * Side Effects: 6933955d011SMarcel Moolenaar * The node is placed on the end of the transforms Lst and links are 6943955d011SMarcel Moolenaar * made between the two suffixes mentioned in the target name 6953955d011SMarcel Moolenaar *----------------------------------------------------------------------- 6963955d011SMarcel Moolenaar */ 6973955d011SMarcel Moolenaar GNode * 6983955d011SMarcel Moolenaar Suff_AddTransform(char *line) 6993955d011SMarcel Moolenaar { 7003955d011SMarcel Moolenaar GNode *gn; /* GNode of transformation rule */ 7013955d011SMarcel Moolenaar Suff *s, /* source suffix */ 7023955d011SMarcel Moolenaar *t; /* target suffix */ 7033955d011SMarcel Moolenaar LstNode ln; /* Node for existing transformation */ 7043955d011SMarcel Moolenaar 7053955d011SMarcel Moolenaar ln = Lst_Find(transforms, line, SuffGNHasNameP); 7063955d011SMarcel Moolenaar if (ln == NULL) { 7073955d011SMarcel Moolenaar /* 7083955d011SMarcel Moolenaar * Make a new graph node for the transformation. It will be filled in 7093955d011SMarcel Moolenaar * by the Parse module. 7103955d011SMarcel Moolenaar */ 7113955d011SMarcel Moolenaar gn = Targ_NewGN(line); 7123955d011SMarcel Moolenaar (void)Lst_AtEnd(transforms, gn); 7133955d011SMarcel Moolenaar } else { 7143955d011SMarcel Moolenaar /* 7153955d011SMarcel Moolenaar * New specification for transformation rule. Just nuke the old list 7163955d011SMarcel Moolenaar * of commands so they can be filled in again... We don't actually 7173955d011SMarcel Moolenaar * free the commands themselves, because a given command can be 7183955d011SMarcel Moolenaar * attached to several different transformations. 7193955d011SMarcel Moolenaar */ 7203955d011SMarcel Moolenaar gn = (GNode *)Lst_Datum(ln); 7213955d011SMarcel Moolenaar Lst_Destroy(gn->commands, NULL); 7223955d011SMarcel Moolenaar Lst_Destroy(gn->children, NULL); 7233955d011SMarcel Moolenaar gn->commands = Lst_Init(FALSE); 7243955d011SMarcel Moolenaar gn->children = Lst_Init(FALSE); 7253955d011SMarcel Moolenaar } 7263955d011SMarcel Moolenaar 7273955d011SMarcel Moolenaar gn->type = OP_TRANSFORM; 7283955d011SMarcel Moolenaar 7293955d011SMarcel Moolenaar (void)SuffParseTransform(line, &s, &t); 7303955d011SMarcel Moolenaar 7313955d011SMarcel Moolenaar /* 7323955d011SMarcel Moolenaar * link the two together in the proper relationship and order 7333955d011SMarcel Moolenaar */ 7343955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 7353955d011SMarcel Moolenaar fprintf(debug_file, "defining transformation from `%s' to `%s'\n", 7363955d011SMarcel Moolenaar s->name, t->name); 7373955d011SMarcel Moolenaar } 7383955d011SMarcel Moolenaar SuffInsert(t->children, s); 7393955d011SMarcel Moolenaar SuffInsert(s->parents, t); 7403955d011SMarcel Moolenaar 7413955d011SMarcel Moolenaar return (gn); 7423955d011SMarcel Moolenaar } 7433955d011SMarcel Moolenaar 7443955d011SMarcel Moolenaar /*- 7453955d011SMarcel Moolenaar *----------------------------------------------------------------------- 7463955d011SMarcel Moolenaar * Suff_EndTransform -- 7473955d011SMarcel Moolenaar * Handle the finish of a transformation definition, removing the 7483955d011SMarcel Moolenaar * transformation from the graph if it has neither commands nor 7493955d011SMarcel Moolenaar * sources. This is a callback procedure for the Parse module via 7503955d011SMarcel Moolenaar * Lst_ForEach 7513955d011SMarcel Moolenaar * 7523955d011SMarcel Moolenaar * Input: 7533955d011SMarcel Moolenaar * gnp Node for transformation 7543955d011SMarcel Moolenaar * dummy Node for transformation 7553955d011SMarcel Moolenaar * 7563955d011SMarcel Moolenaar * Results: 7573955d011SMarcel Moolenaar * === 0 7583955d011SMarcel Moolenaar * 7593955d011SMarcel Moolenaar * Side Effects: 7603955d011SMarcel Moolenaar * If the node has no commands or children, the children and parents 7613955d011SMarcel Moolenaar * lists of the affected suffixes are altered. 7623955d011SMarcel Moolenaar * 7633955d011SMarcel Moolenaar *----------------------------------------------------------------------- 7643955d011SMarcel Moolenaar */ 7653955d011SMarcel Moolenaar int 766*e1cee40dSSimon J. Gerraty Suff_EndTransform(void *gnp, void *dummy MAKE_ATTR_UNUSED) 7673955d011SMarcel Moolenaar { 7683955d011SMarcel Moolenaar GNode *gn = (GNode *)gnp; 7693955d011SMarcel Moolenaar 7703955d011SMarcel Moolenaar if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) 7713955d011SMarcel Moolenaar gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts)); 7723955d011SMarcel Moolenaar if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) && 7733955d011SMarcel Moolenaar Lst_IsEmpty(gn->children)) 7743955d011SMarcel Moolenaar { 7753955d011SMarcel Moolenaar Suff *s, *t; 7763955d011SMarcel Moolenaar 7773955d011SMarcel Moolenaar /* 7783955d011SMarcel Moolenaar * SuffParseTransform() may fail for special rules which are not 7793955d011SMarcel Moolenaar * actual transformation rules. (e.g. .DEFAULT) 7803955d011SMarcel Moolenaar */ 7813955d011SMarcel Moolenaar if (SuffParseTransform(gn->name, &s, &t)) { 7823955d011SMarcel Moolenaar Lst p; 7833955d011SMarcel Moolenaar 7843955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 7853955d011SMarcel Moolenaar fprintf(debug_file, "deleting transformation from `%s' to `%s'\n", 7863955d011SMarcel Moolenaar s->name, t->name); 7873955d011SMarcel Moolenaar } 7883955d011SMarcel Moolenaar 7893955d011SMarcel Moolenaar /* 7903955d011SMarcel Moolenaar * Store s->parents because s could be deleted in SuffRemove 7913955d011SMarcel Moolenaar */ 7923955d011SMarcel Moolenaar p = s->parents; 7933955d011SMarcel Moolenaar 7943955d011SMarcel Moolenaar /* 7953955d011SMarcel Moolenaar * Remove the source from the target's children list. We check for a 7963955d011SMarcel Moolenaar * nil return to handle a beanhead saying something like 7973955d011SMarcel Moolenaar * .c.o .c.o: 7983955d011SMarcel Moolenaar * 7993955d011SMarcel Moolenaar * We'll be called twice when the next target is seen, but .c and .o 8003955d011SMarcel Moolenaar * are only linked once... 8013955d011SMarcel Moolenaar */ 8023955d011SMarcel Moolenaar SuffRemove(t->children, s); 8033955d011SMarcel Moolenaar 8043955d011SMarcel Moolenaar /* 8053955d011SMarcel Moolenaar * Remove the target from the source's parents list 8063955d011SMarcel Moolenaar */ 8073955d011SMarcel Moolenaar SuffRemove(p, t); 8083955d011SMarcel Moolenaar } 8093955d011SMarcel Moolenaar } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { 8103955d011SMarcel Moolenaar fprintf(debug_file, "transformation %s complete\n", gn->name); 8113955d011SMarcel Moolenaar } 8123955d011SMarcel Moolenaar 81395e3ed2cSSimon J. Gerraty return 0; 8143955d011SMarcel Moolenaar } 8153955d011SMarcel Moolenaar 8163955d011SMarcel Moolenaar /*- 8173955d011SMarcel Moolenaar *----------------------------------------------------------------------- 8183955d011SMarcel Moolenaar * SuffRebuildGraph -- 8193955d011SMarcel Moolenaar * Called from Suff_AddSuffix via Lst_ForEach to search through the 8203955d011SMarcel Moolenaar * list of existing transformation rules and rebuild the transformation 8213955d011SMarcel Moolenaar * graph when it has been destroyed by Suff_ClearSuffixes. If the 8223955d011SMarcel Moolenaar * given rule is a transformation involving this suffix and another, 8233955d011SMarcel Moolenaar * existing suffix, the proper relationship is established between 8243955d011SMarcel Moolenaar * the two. 8253955d011SMarcel Moolenaar * 8263955d011SMarcel Moolenaar * Input: 8273955d011SMarcel Moolenaar * transformp Transformation to test 8283955d011SMarcel Moolenaar * sp Suffix to rebuild 8293955d011SMarcel Moolenaar * 8303955d011SMarcel Moolenaar * Results: 8313955d011SMarcel Moolenaar * Always 0. 8323955d011SMarcel Moolenaar * 8333955d011SMarcel Moolenaar * Side Effects: 8343955d011SMarcel Moolenaar * The appropriate links will be made between this suffix and 8353955d011SMarcel Moolenaar * others if transformation rules exist for it. 8363955d011SMarcel Moolenaar * 8373955d011SMarcel Moolenaar *----------------------------------------------------------------------- 8383955d011SMarcel Moolenaar */ 8393955d011SMarcel Moolenaar static int 8403955d011SMarcel Moolenaar SuffRebuildGraph(void *transformp, void *sp) 8413955d011SMarcel Moolenaar { 8423955d011SMarcel Moolenaar GNode *transform = (GNode *)transformp; 8433955d011SMarcel Moolenaar Suff *s = (Suff *)sp; 8443955d011SMarcel Moolenaar char *cp; 8453955d011SMarcel Moolenaar LstNode ln; 8463955d011SMarcel Moolenaar Suff *s2; 8473955d011SMarcel Moolenaar SuffixCmpData sd; 8483955d011SMarcel Moolenaar 8493955d011SMarcel Moolenaar /* 8503955d011SMarcel Moolenaar * First see if it is a transformation from this suffix. 8513955d011SMarcel Moolenaar */ 8523955d011SMarcel Moolenaar cp = UNCONST(SuffStrIsPrefix(s->name, transform->name)); 8533955d011SMarcel Moolenaar if (cp != NULL) { 8543955d011SMarcel Moolenaar ln = Lst_Find(sufflist, cp, SuffSuffHasNameP); 8553955d011SMarcel Moolenaar if (ln != NULL) { 8563955d011SMarcel Moolenaar /* 8573955d011SMarcel Moolenaar * Found target. Link in and return, since it can't be anything 8583955d011SMarcel Moolenaar * else. 8593955d011SMarcel Moolenaar */ 8603955d011SMarcel Moolenaar s2 = (Suff *)Lst_Datum(ln); 8613955d011SMarcel Moolenaar SuffInsert(s2->children, s); 8623955d011SMarcel Moolenaar SuffInsert(s->parents, s2); 8633955d011SMarcel Moolenaar return(0); 8643955d011SMarcel Moolenaar } 8653955d011SMarcel Moolenaar } 8663955d011SMarcel Moolenaar 8673955d011SMarcel Moolenaar /* 8683955d011SMarcel Moolenaar * Not from, maybe to? 8693955d011SMarcel Moolenaar */ 8703955d011SMarcel Moolenaar sd.len = strlen(transform->name); 8713955d011SMarcel Moolenaar sd.ename = transform->name + sd.len; 8723955d011SMarcel Moolenaar cp = SuffSuffIsSuffix(s, &sd); 8733955d011SMarcel Moolenaar if (cp != NULL) { 8743955d011SMarcel Moolenaar /* 8753955d011SMarcel Moolenaar * Null-terminate the source suffix in order to find it. 8763955d011SMarcel Moolenaar */ 8773955d011SMarcel Moolenaar cp[1] = '\0'; 8783955d011SMarcel Moolenaar ln = Lst_Find(sufflist, transform->name, SuffSuffHasNameP); 8793955d011SMarcel Moolenaar /* 8803955d011SMarcel Moolenaar * Replace the start of the target suffix 8813955d011SMarcel Moolenaar */ 8823955d011SMarcel Moolenaar cp[1] = s->name[0]; 8833955d011SMarcel Moolenaar if (ln != NULL) { 8843955d011SMarcel Moolenaar /* 8853955d011SMarcel Moolenaar * Found it -- establish the proper relationship 8863955d011SMarcel Moolenaar */ 8873955d011SMarcel Moolenaar s2 = (Suff *)Lst_Datum(ln); 8883955d011SMarcel Moolenaar SuffInsert(s->children, s2); 8893955d011SMarcel Moolenaar SuffInsert(s2->parents, s); 8903955d011SMarcel Moolenaar } 8913955d011SMarcel Moolenaar } 8923955d011SMarcel Moolenaar return(0); 8933955d011SMarcel Moolenaar } 8943955d011SMarcel Moolenaar 8953955d011SMarcel Moolenaar /*- 8963955d011SMarcel Moolenaar *----------------------------------------------------------------------- 8973955d011SMarcel Moolenaar * SuffScanTargets -- 8983955d011SMarcel Moolenaar * Called from Suff_AddSuffix via Lst_ForEach to search through the 8993955d011SMarcel Moolenaar * list of existing targets and find if any of the existing targets 9003955d011SMarcel Moolenaar * can be turned into a transformation rule. 9013955d011SMarcel Moolenaar * 9023955d011SMarcel Moolenaar * Results: 9033955d011SMarcel Moolenaar * 1 if a new main target has been selected, 0 otherwise. 9043955d011SMarcel Moolenaar * 9053955d011SMarcel Moolenaar * Side Effects: 9063955d011SMarcel Moolenaar * If such a target is found and the target is the current main 9073955d011SMarcel Moolenaar * target, the main target is set to NULL and the next target 9083955d011SMarcel Moolenaar * examined (if that exists) becomes the main target. 9093955d011SMarcel Moolenaar * 9103955d011SMarcel Moolenaar *----------------------------------------------------------------------- 9113955d011SMarcel Moolenaar */ 9123955d011SMarcel Moolenaar static int 9133955d011SMarcel Moolenaar SuffScanTargets(void *targetp, void *gsp) 9143955d011SMarcel Moolenaar { 9153955d011SMarcel Moolenaar GNode *target = (GNode *)targetp; 9163955d011SMarcel Moolenaar GNodeSuff *gs = (GNodeSuff *)gsp; 9173955d011SMarcel Moolenaar Suff *s, *t; 9183955d011SMarcel Moolenaar char *ptr; 9193955d011SMarcel Moolenaar 9203955d011SMarcel Moolenaar if (*gs->gn == NULL && gs->r && (target->type & OP_NOTARGET) == 0) { 9213955d011SMarcel Moolenaar *gs->gn = target; 9223955d011SMarcel Moolenaar Targ_SetMain(target); 9233955d011SMarcel Moolenaar return 1; 9243955d011SMarcel Moolenaar } 9253955d011SMarcel Moolenaar 9263955d011SMarcel Moolenaar if ((unsigned int)target->type == OP_TRANSFORM) 9273955d011SMarcel Moolenaar return 0; 9283955d011SMarcel Moolenaar 9293955d011SMarcel Moolenaar if ((ptr = strstr(target->name, gs->s->name)) == NULL || 9303955d011SMarcel Moolenaar ptr == target->name) 9313955d011SMarcel Moolenaar return 0; 9323955d011SMarcel Moolenaar 9333955d011SMarcel Moolenaar if (SuffParseTransform(target->name, &s, &t)) { 9343955d011SMarcel Moolenaar if (*gs->gn == target) { 9353955d011SMarcel Moolenaar gs->r = TRUE; 9363955d011SMarcel Moolenaar *gs->gn = NULL; 9373955d011SMarcel Moolenaar Targ_SetMain(NULL); 9383955d011SMarcel Moolenaar } 9393955d011SMarcel Moolenaar Lst_Destroy(target->children, NULL); 9403955d011SMarcel Moolenaar target->children = Lst_Init(FALSE); 9413955d011SMarcel Moolenaar target->type = OP_TRANSFORM; 9423955d011SMarcel Moolenaar /* 9433955d011SMarcel Moolenaar * link the two together in the proper relationship and order 9443955d011SMarcel Moolenaar */ 9453955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 9463955d011SMarcel Moolenaar fprintf(debug_file, "defining transformation from `%s' to `%s'\n", 9473955d011SMarcel Moolenaar s->name, t->name); 9483955d011SMarcel Moolenaar } 9493955d011SMarcel Moolenaar SuffInsert(t->children, s); 9503955d011SMarcel Moolenaar SuffInsert(s->parents, t); 9513955d011SMarcel Moolenaar } 9523955d011SMarcel Moolenaar return 0; 9533955d011SMarcel Moolenaar } 9543955d011SMarcel Moolenaar 9553955d011SMarcel Moolenaar /*- 9563955d011SMarcel Moolenaar *----------------------------------------------------------------------- 9573955d011SMarcel Moolenaar * Suff_AddSuffix -- 9583955d011SMarcel Moolenaar * Add the suffix in string to the end of the list of known suffixes. 9593955d011SMarcel Moolenaar * Should we restructure the suffix graph? Make doesn't... 9603955d011SMarcel Moolenaar * 9613955d011SMarcel Moolenaar * Input: 9623955d011SMarcel Moolenaar * str the name of the suffix to add 9633955d011SMarcel Moolenaar * 9643955d011SMarcel Moolenaar * Results: 9653955d011SMarcel Moolenaar * None 9663955d011SMarcel Moolenaar * 9673955d011SMarcel Moolenaar * Side Effects: 9683955d011SMarcel Moolenaar * A GNode is created for the suffix and a Suff structure is created and 9693955d011SMarcel Moolenaar * added to the suffixes list unless the suffix was already known. 9703955d011SMarcel Moolenaar * The mainNode passed can be modified if a target mutated into a 9713955d011SMarcel Moolenaar * transform and that target happened to be the main target. 9723955d011SMarcel Moolenaar *----------------------------------------------------------------------- 9733955d011SMarcel Moolenaar */ 9743955d011SMarcel Moolenaar void 9753955d011SMarcel Moolenaar Suff_AddSuffix(char *str, GNode **gn) 9763955d011SMarcel Moolenaar { 9773955d011SMarcel Moolenaar Suff *s; /* new suffix descriptor */ 9783955d011SMarcel Moolenaar LstNode ln; 9793955d011SMarcel Moolenaar GNodeSuff gs; 9803955d011SMarcel Moolenaar 9813955d011SMarcel Moolenaar ln = Lst_Find(sufflist, str, SuffSuffHasNameP); 9823955d011SMarcel Moolenaar if (ln == NULL) { 9833955d011SMarcel Moolenaar s = bmake_malloc(sizeof(Suff)); 9843955d011SMarcel Moolenaar 9853955d011SMarcel Moolenaar s->name = bmake_strdup(str); 9863955d011SMarcel Moolenaar s->nameLen = strlen(s->name); 9873955d011SMarcel Moolenaar s->searchPath = Lst_Init(FALSE); 9883955d011SMarcel Moolenaar s->children = Lst_Init(FALSE); 9893955d011SMarcel Moolenaar s->parents = Lst_Init(FALSE); 9903955d011SMarcel Moolenaar s->ref = Lst_Init(FALSE); 9913955d011SMarcel Moolenaar s->sNum = sNum++; 9923955d011SMarcel Moolenaar s->flags = 0; 9933955d011SMarcel Moolenaar s->refCount = 1; 9943955d011SMarcel Moolenaar 9953955d011SMarcel Moolenaar (void)Lst_AtEnd(sufflist, s); 9963955d011SMarcel Moolenaar /* 9973955d011SMarcel Moolenaar * We also look at our existing targets list to see if adding 9983955d011SMarcel Moolenaar * this suffix will make one of our current targets mutate into 9993955d011SMarcel Moolenaar * a suffix rule. This is ugly, but other makes treat all targets 10003955d011SMarcel Moolenaar * that start with a . as suffix rules. 10013955d011SMarcel Moolenaar */ 10023955d011SMarcel Moolenaar gs.gn = gn; 10033955d011SMarcel Moolenaar gs.s = s; 10043955d011SMarcel Moolenaar gs.r = FALSE; 10053955d011SMarcel Moolenaar Lst_ForEach(Targ_List(), SuffScanTargets, &gs); 10063955d011SMarcel Moolenaar /* 10073955d011SMarcel Moolenaar * Look for any existing transformations from or to this suffix. 10083955d011SMarcel Moolenaar * XXX: Only do this after a Suff_ClearSuffixes? 10093955d011SMarcel Moolenaar */ 10103955d011SMarcel Moolenaar Lst_ForEach(transforms, SuffRebuildGraph, s); 10113955d011SMarcel Moolenaar } 10123955d011SMarcel Moolenaar } 10133955d011SMarcel Moolenaar 10143955d011SMarcel Moolenaar /*- 10153955d011SMarcel Moolenaar *----------------------------------------------------------------------- 10163955d011SMarcel Moolenaar * Suff_GetPath -- 10173955d011SMarcel Moolenaar * Return the search path for the given suffix, if it's defined. 10183955d011SMarcel Moolenaar * 10193955d011SMarcel Moolenaar * Results: 10203955d011SMarcel Moolenaar * The searchPath for the desired suffix or NULL if the suffix isn't 10213955d011SMarcel Moolenaar * defined. 10223955d011SMarcel Moolenaar * 10233955d011SMarcel Moolenaar * Side Effects: 10243955d011SMarcel Moolenaar * None 10253955d011SMarcel Moolenaar *----------------------------------------------------------------------- 10263955d011SMarcel Moolenaar */ 10273955d011SMarcel Moolenaar Lst 10283955d011SMarcel Moolenaar Suff_GetPath(char *sname) 10293955d011SMarcel Moolenaar { 10303955d011SMarcel Moolenaar LstNode ln; 10313955d011SMarcel Moolenaar Suff *s; 10323955d011SMarcel Moolenaar 10333955d011SMarcel Moolenaar ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); 10343955d011SMarcel Moolenaar if (ln == NULL) { 10353955d011SMarcel Moolenaar return NULL; 10363955d011SMarcel Moolenaar } else { 10373955d011SMarcel Moolenaar s = (Suff *)Lst_Datum(ln); 10383955d011SMarcel Moolenaar return (s->searchPath); 10393955d011SMarcel Moolenaar } 10403955d011SMarcel Moolenaar } 10413955d011SMarcel Moolenaar 10423955d011SMarcel Moolenaar /*- 10433955d011SMarcel Moolenaar *----------------------------------------------------------------------- 10443955d011SMarcel Moolenaar * Suff_DoPaths -- 10453955d011SMarcel Moolenaar * Extend the search paths for all suffixes to include the default 10463955d011SMarcel Moolenaar * search path. 10473955d011SMarcel Moolenaar * 10483955d011SMarcel Moolenaar * Results: 10493955d011SMarcel Moolenaar * None. 10503955d011SMarcel Moolenaar * 10513955d011SMarcel Moolenaar * Side Effects: 10523955d011SMarcel Moolenaar * The searchPath field of all the suffixes is extended by the 10533955d011SMarcel Moolenaar * directories in dirSearchPath. If paths were specified for the 10543955d011SMarcel Moolenaar * ".h" suffix, the directories are stuffed into a global variable 10553955d011SMarcel Moolenaar * called ".INCLUDES" with each directory preceded by a -I. The same 10563955d011SMarcel Moolenaar * is done for the ".a" suffix, except the variable is called 10573955d011SMarcel Moolenaar * ".LIBS" and the flag is -L. 10583955d011SMarcel Moolenaar *----------------------------------------------------------------------- 10593955d011SMarcel Moolenaar */ 10603955d011SMarcel Moolenaar void 10613955d011SMarcel Moolenaar Suff_DoPaths(void) 10623955d011SMarcel Moolenaar { 10633955d011SMarcel Moolenaar Suff *s; 10643955d011SMarcel Moolenaar LstNode ln; 10653955d011SMarcel Moolenaar char *ptr; 10663955d011SMarcel Moolenaar Lst inIncludes; /* Cumulative .INCLUDES path */ 10673955d011SMarcel Moolenaar Lst inLibs; /* Cumulative .LIBS path */ 10683955d011SMarcel Moolenaar 10693955d011SMarcel Moolenaar if (Lst_Open(sufflist) == FAILURE) { 10703955d011SMarcel Moolenaar return; 10713955d011SMarcel Moolenaar } 10723955d011SMarcel Moolenaar 10733955d011SMarcel Moolenaar inIncludes = Lst_Init(FALSE); 10743955d011SMarcel Moolenaar inLibs = Lst_Init(FALSE); 10753955d011SMarcel Moolenaar 10763955d011SMarcel Moolenaar while ((ln = Lst_Next(sufflist)) != NULL) { 10773955d011SMarcel Moolenaar s = (Suff *)Lst_Datum(ln); 10783955d011SMarcel Moolenaar if (!Lst_IsEmpty (s->searchPath)) { 10793955d011SMarcel Moolenaar #ifdef INCLUDES 10803955d011SMarcel Moolenaar if (s->flags & SUFF_INCLUDE) { 10813955d011SMarcel Moolenaar Dir_Concat(inIncludes, s->searchPath); 10823955d011SMarcel Moolenaar } 10833955d011SMarcel Moolenaar #endif /* INCLUDES */ 10843955d011SMarcel Moolenaar #ifdef LIBRARIES 10853955d011SMarcel Moolenaar if (s->flags & SUFF_LIBRARY) { 10863955d011SMarcel Moolenaar Dir_Concat(inLibs, s->searchPath); 10873955d011SMarcel Moolenaar } 10883955d011SMarcel Moolenaar #endif /* LIBRARIES */ 10893955d011SMarcel Moolenaar Dir_Concat(s->searchPath, dirSearchPath); 10903955d011SMarcel Moolenaar } else { 10913955d011SMarcel Moolenaar Lst_Destroy(s->searchPath, Dir_Destroy); 10923955d011SMarcel Moolenaar s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir); 10933955d011SMarcel Moolenaar } 10943955d011SMarcel Moolenaar } 10953955d011SMarcel Moolenaar 10963955d011SMarcel Moolenaar Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL, 0); 10973955d011SMarcel Moolenaar free(ptr); 10983955d011SMarcel Moolenaar Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL, 0); 10993955d011SMarcel Moolenaar free(ptr); 11003955d011SMarcel Moolenaar 11013955d011SMarcel Moolenaar Lst_Destroy(inIncludes, Dir_Destroy); 11023955d011SMarcel Moolenaar Lst_Destroy(inLibs, Dir_Destroy); 11033955d011SMarcel Moolenaar 11043955d011SMarcel Moolenaar Lst_Close(sufflist); 11053955d011SMarcel Moolenaar } 11063955d011SMarcel Moolenaar 11073955d011SMarcel Moolenaar /*- 11083955d011SMarcel Moolenaar *----------------------------------------------------------------------- 11093955d011SMarcel Moolenaar * Suff_AddInclude -- 11103955d011SMarcel Moolenaar * Add the given suffix as a type of file which gets included. 11113955d011SMarcel Moolenaar * Called from the parse module when a .INCLUDES line is parsed. 11123955d011SMarcel Moolenaar * The suffix must have already been defined. 11133955d011SMarcel Moolenaar * 11143955d011SMarcel Moolenaar * Input: 11153955d011SMarcel Moolenaar * sname Name of the suffix to mark 11163955d011SMarcel Moolenaar * 11173955d011SMarcel Moolenaar * Results: 11183955d011SMarcel Moolenaar * None. 11193955d011SMarcel Moolenaar * 11203955d011SMarcel Moolenaar * Side Effects: 11213955d011SMarcel Moolenaar * The SUFF_INCLUDE bit is set in the suffix's flags field 11223955d011SMarcel Moolenaar * 11233955d011SMarcel Moolenaar *----------------------------------------------------------------------- 11243955d011SMarcel Moolenaar */ 11253955d011SMarcel Moolenaar void 11263955d011SMarcel Moolenaar Suff_AddInclude(char *sname) 11273955d011SMarcel Moolenaar { 11283955d011SMarcel Moolenaar LstNode ln; 11293955d011SMarcel Moolenaar Suff *s; 11303955d011SMarcel Moolenaar 11313955d011SMarcel Moolenaar ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); 11323955d011SMarcel Moolenaar if (ln != NULL) { 11333955d011SMarcel Moolenaar s = (Suff *)Lst_Datum(ln); 11343955d011SMarcel Moolenaar s->flags |= SUFF_INCLUDE; 11353955d011SMarcel Moolenaar } 11363955d011SMarcel Moolenaar } 11373955d011SMarcel Moolenaar 11383955d011SMarcel Moolenaar /*- 11393955d011SMarcel Moolenaar *----------------------------------------------------------------------- 11403955d011SMarcel Moolenaar * Suff_AddLib -- 11413955d011SMarcel Moolenaar * Add the given suffix as a type of file which is a library. 11423955d011SMarcel Moolenaar * Called from the parse module when parsing a .LIBS line. The 11433955d011SMarcel Moolenaar * suffix must have been defined via .SUFFIXES before this is 11443955d011SMarcel Moolenaar * called. 11453955d011SMarcel Moolenaar * 11463955d011SMarcel Moolenaar * Input: 11473955d011SMarcel Moolenaar * sname Name of the suffix to mark 11483955d011SMarcel Moolenaar * 11493955d011SMarcel Moolenaar * Results: 11503955d011SMarcel Moolenaar * None. 11513955d011SMarcel Moolenaar * 11523955d011SMarcel Moolenaar * Side Effects: 11533955d011SMarcel Moolenaar * The SUFF_LIBRARY bit is set in the suffix's flags field 11543955d011SMarcel Moolenaar * 11553955d011SMarcel Moolenaar *----------------------------------------------------------------------- 11563955d011SMarcel Moolenaar */ 11573955d011SMarcel Moolenaar void 11583955d011SMarcel Moolenaar Suff_AddLib(char *sname) 11593955d011SMarcel Moolenaar { 11603955d011SMarcel Moolenaar LstNode ln; 11613955d011SMarcel Moolenaar Suff *s; 11623955d011SMarcel Moolenaar 11633955d011SMarcel Moolenaar ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); 11643955d011SMarcel Moolenaar if (ln != NULL) { 11653955d011SMarcel Moolenaar s = (Suff *)Lst_Datum(ln); 11663955d011SMarcel Moolenaar s->flags |= SUFF_LIBRARY; 11673955d011SMarcel Moolenaar } 11683955d011SMarcel Moolenaar } 11693955d011SMarcel Moolenaar 11703955d011SMarcel Moolenaar /********** Implicit Source Search Functions *********/ 11713955d011SMarcel Moolenaar 11723955d011SMarcel Moolenaar /*- 11733955d011SMarcel Moolenaar *----------------------------------------------------------------------- 11743955d011SMarcel Moolenaar * SuffAddSrc -- 11753955d011SMarcel Moolenaar * Add a suffix as a Src structure to the given list with its parent 11763955d011SMarcel Moolenaar * being the given Src structure. If the suffix is the null suffix, 11773955d011SMarcel Moolenaar * the prefix is used unaltered as the file name in the Src structure. 11783955d011SMarcel Moolenaar * 11793955d011SMarcel Moolenaar * Input: 11803955d011SMarcel Moolenaar * sp suffix for which to create a Src structure 11813955d011SMarcel Moolenaar * lsp list and parent for the new Src 11823955d011SMarcel Moolenaar * 11833955d011SMarcel Moolenaar * Results: 11843955d011SMarcel Moolenaar * always returns 0 11853955d011SMarcel Moolenaar * 11863955d011SMarcel Moolenaar * Side Effects: 11873955d011SMarcel Moolenaar * A Src structure is created and tacked onto the end of the list 11883955d011SMarcel Moolenaar *----------------------------------------------------------------------- 11893955d011SMarcel Moolenaar */ 11903955d011SMarcel Moolenaar static int 11913955d011SMarcel Moolenaar SuffAddSrc(void *sp, void *lsp) 11923955d011SMarcel Moolenaar { 11933955d011SMarcel Moolenaar Suff *s = (Suff *)sp; 11943955d011SMarcel Moolenaar LstSrc *ls = (LstSrc *)lsp; 11953955d011SMarcel Moolenaar Src *s2; /* new Src structure */ 11963955d011SMarcel Moolenaar Src *targ; /* Target structure */ 11973955d011SMarcel Moolenaar 11983955d011SMarcel Moolenaar targ = ls->s; 11993955d011SMarcel Moolenaar 12003955d011SMarcel Moolenaar if ((s->flags & SUFF_NULL) && (*s->name != '\0')) { 12013955d011SMarcel Moolenaar /* 12023955d011SMarcel Moolenaar * If the suffix has been marked as the NULL suffix, also create a Src 12033955d011SMarcel Moolenaar * structure for a file with no suffix attached. Two birds, and all 12043955d011SMarcel Moolenaar * that... 12053955d011SMarcel Moolenaar */ 12063955d011SMarcel Moolenaar s2 = bmake_malloc(sizeof(Src)); 12073955d011SMarcel Moolenaar s2->file = bmake_strdup(targ->pref); 12083955d011SMarcel Moolenaar s2->pref = targ->pref; 12093955d011SMarcel Moolenaar s2->parent = targ; 12103955d011SMarcel Moolenaar s2->node = NULL; 12113955d011SMarcel Moolenaar s2->suff = s; 12123955d011SMarcel Moolenaar s->refCount++; 12133955d011SMarcel Moolenaar s2->children = 0; 12143955d011SMarcel Moolenaar targ->children += 1; 12153955d011SMarcel Moolenaar (void)Lst_AtEnd(ls->l, s2); 12163955d011SMarcel Moolenaar #ifdef DEBUG_SRC 12173955d011SMarcel Moolenaar s2->cp = Lst_Init(FALSE); 12183955d011SMarcel Moolenaar Lst_AtEnd(targ->cp, s2); 121995e3ed2cSSimon J. Gerraty fprintf(debug_file, "1 add %p %p to %p:", targ, s2, ls->l); 12203955d011SMarcel Moolenaar Lst_ForEach(ls->l, PrintAddr, NULL); 12213955d011SMarcel Moolenaar fprintf(debug_file, "\n"); 12223955d011SMarcel Moolenaar #endif 12233955d011SMarcel Moolenaar } 12243955d011SMarcel Moolenaar s2 = bmake_malloc(sizeof(Src)); 12253955d011SMarcel Moolenaar s2->file = str_concat(targ->pref, s->name, 0); 12263955d011SMarcel Moolenaar s2->pref = targ->pref; 12273955d011SMarcel Moolenaar s2->parent = targ; 12283955d011SMarcel Moolenaar s2->node = NULL; 12293955d011SMarcel Moolenaar s2->suff = s; 12303955d011SMarcel Moolenaar s->refCount++; 12313955d011SMarcel Moolenaar s2->children = 0; 12323955d011SMarcel Moolenaar targ->children += 1; 12333955d011SMarcel Moolenaar (void)Lst_AtEnd(ls->l, s2); 12343955d011SMarcel Moolenaar #ifdef DEBUG_SRC 12353955d011SMarcel Moolenaar s2->cp = Lst_Init(FALSE); 12363955d011SMarcel Moolenaar Lst_AtEnd(targ->cp, s2); 123795e3ed2cSSimon J. Gerraty fprintf(debug_file, "2 add %p %p to %p:", targ, s2, ls->l); 12383955d011SMarcel Moolenaar Lst_ForEach(ls->l, PrintAddr, NULL); 12393955d011SMarcel Moolenaar fprintf(debug_file, "\n"); 12403955d011SMarcel Moolenaar #endif 12413955d011SMarcel Moolenaar 12423955d011SMarcel Moolenaar return(0); 12433955d011SMarcel Moolenaar } 12443955d011SMarcel Moolenaar 12453955d011SMarcel Moolenaar /*- 12463955d011SMarcel Moolenaar *----------------------------------------------------------------------- 12473955d011SMarcel Moolenaar * SuffAddLevel -- 12483955d011SMarcel Moolenaar * Add all the children of targ as Src structures to the given list 12493955d011SMarcel Moolenaar * 12503955d011SMarcel Moolenaar * Input: 12513955d011SMarcel Moolenaar * l list to which to add the new level 12523955d011SMarcel Moolenaar * targ Src structure to use as the parent 12533955d011SMarcel Moolenaar * 12543955d011SMarcel Moolenaar * Results: 12553955d011SMarcel Moolenaar * None 12563955d011SMarcel Moolenaar * 12573955d011SMarcel Moolenaar * Side Effects: 12583955d011SMarcel Moolenaar * Lots of structures are created and added to the list 12593955d011SMarcel Moolenaar *----------------------------------------------------------------------- 12603955d011SMarcel Moolenaar */ 12613955d011SMarcel Moolenaar static void 12623955d011SMarcel Moolenaar SuffAddLevel(Lst l, Src *targ) 12633955d011SMarcel Moolenaar { 12643955d011SMarcel Moolenaar LstSrc ls; 12653955d011SMarcel Moolenaar 12663955d011SMarcel Moolenaar ls.s = targ; 12673955d011SMarcel Moolenaar ls.l = l; 12683955d011SMarcel Moolenaar 12693955d011SMarcel Moolenaar Lst_ForEach(targ->suff->children, SuffAddSrc, &ls); 12703955d011SMarcel Moolenaar } 12713955d011SMarcel Moolenaar 12723955d011SMarcel Moolenaar /*- 12733955d011SMarcel Moolenaar *---------------------------------------------------------------------- 12743955d011SMarcel Moolenaar * SuffRemoveSrc -- 12753955d011SMarcel Moolenaar * Free all src structures in list that don't have a reference count 12763955d011SMarcel Moolenaar * 12773955d011SMarcel Moolenaar * Results: 12783955d011SMarcel Moolenaar * Ture if an src was removed 12793955d011SMarcel Moolenaar * 12803955d011SMarcel Moolenaar * Side Effects: 12813955d011SMarcel Moolenaar * The memory is free'd. 12823955d011SMarcel Moolenaar *---------------------------------------------------------------------- 12833955d011SMarcel Moolenaar */ 12843955d011SMarcel Moolenaar static int 12853955d011SMarcel Moolenaar SuffRemoveSrc(Lst l) 12863955d011SMarcel Moolenaar { 12873955d011SMarcel Moolenaar LstNode ln; 12883955d011SMarcel Moolenaar Src *s; 12893955d011SMarcel Moolenaar int t = 0; 12903955d011SMarcel Moolenaar 12913955d011SMarcel Moolenaar if (Lst_Open(l) == FAILURE) { 12923955d011SMarcel Moolenaar return 0; 12933955d011SMarcel Moolenaar } 12943955d011SMarcel Moolenaar #ifdef DEBUG_SRC 12953955d011SMarcel Moolenaar fprintf(debug_file, "cleaning %lx: ", (unsigned long) l); 12963955d011SMarcel Moolenaar Lst_ForEach(l, PrintAddr, NULL); 12973955d011SMarcel Moolenaar fprintf(debug_file, "\n"); 12983955d011SMarcel Moolenaar #endif 12993955d011SMarcel Moolenaar 13003955d011SMarcel Moolenaar 13013955d011SMarcel Moolenaar while ((ln = Lst_Next(l)) != NULL) { 13023955d011SMarcel Moolenaar s = (Src *)Lst_Datum(ln); 13033955d011SMarcel Moolenaar if (s->children == 0) { 13043955d011SMarcel Moolenaar free(s->file); 13053955d011SMarcel Moolenaar if (!s->parent) 13063955d011SMarcel Moolenaar free(s->pref); 13073955d011SMarcel Moolenaar else { 13083955d011SMarcel Moolenaar #ifdef DEBUG_SRC 130995e3ed2cSSimon J. Gerraty LstNode ln2 = Lst_Member(s->parent->cp, s); 131095e3ed2cSSimon J. Gerraty if (ln2 != NULL) 131195e3ed2cSSimon J. Gerraty Lst_Remove(s->parent->cp, ln2); 13123955d011SMarcel Moolenaar #endif 13133955d011SMarcel Moolenaar --s->parent->children; 13143955d011SMarcel Moolenaar } 13153955d011SMarcel Moolenaar #ifdef DEBUG_SRC 131695e3ed2cSSimon J. Gerraty fprintf(debug_file, "free: [l=%p] p=%p %d\n", l, s, s->children); 13173955d011SMarcel Moolenaar Lst_Destroy(s->cp, NULL); 13183955d011SMarcel Moolenaar #endif 13193955d011SMarcel Moolenaar Lst_Remove(l, ln); 13203955d011SMarcel Moolenaar free(s); 13213955d011SMarcel Moolenaar t |= 1; 13223955d011SMarcel Moolenaar Lst_Close(l); 13233955d011SMarcel Moolenaar return TRUE; 13243955d011SMarcel Moolenaar } 13253955d011SMarcel Moolenaar #ifdef DEBUG_SRC 13263955d011SMarcel Moolenaar else { 132795e3ed2cSSimon J. Gerraty fprintf(debug_file, "keep: [l=%p] p=%p %d: ", l, s, s->children); 13283955d011SMarcel Moolenaar Lst_ForEach(s->cp, PrintAddr, NULL); 13293955d011SMarcel Moolenaar fprintf(debug_file, "\n"); 13303955d011SMarcel Moolenaar } 13313955d011SMarcel Moolenaar #endif 13323955d011SMarcel Moolenaar } 13333955d011SMarcel Moolenaar 13343955d011SMarcel Moolenaar Lst_Close(l); 13353955d011SMarcel Moolenaar 13363955d011SMarcel Moolenaar return t; 13373955d011SMarcel Moolenaar } 13383955d011SMarcel Moolenaar 13393955d011SMarcel Moolenaar /*- 13403955d011SMarcel Moolenaar *----------------------------------------------------------------------- 13413955d011SMarcel Moolenaar * SuffFindThem -- 13423955d011SMarcel Moolenaar * Find the first existing file/target in the list srcs 13433955d011SMarcel Moolenaar * 13443955d011SMarcel Moolenaar * Input: 13453955d011SMarcel Moolenaar * srcs list of Src structures to search through 13463955d011SMarcel Moolenaar * 13473955d011SMarcel Moolenaar * Results: 13483955d011SMarcel Moolenaar * The lowest structure in the chain of transformations 13493955d011SMarcel Moolenaar * 13503955d011SMarcel Moolenaar * Side Effects: 13513955d011SMarcel Moolenaar * None 13523955d011SMarcel Moolenaar *----------------------------------------------------------------------- 13533955d011SMarcel Moolenaar */ 13543955d011SMarcel Moolenaar static Src * 13553955d011SMarcel Moolenaar SuffFindThem(Lst srcs, Lst slst) 13563955d011SMarcel Moolenaar { 13573955d011SMarcel Moolenaar Src *s; /* current Src */ 13583955d011SMarcel Moolenaar Src *rs; /* returned Src */ 13593955d011SMarcel Moolenaar char *ptr; 13603955d011SMarcel Moolenaar 13613955d011SMarcel Moolenaar rs = NULL; 13623955d011SMarcel Moolenaar 13633955d011SMarcel Moolenaar while (!Lst_IsEmpty (srcs)) { 13643955d011SMarcel Moolenaar s = (Src *)Lst_DeQueue(srcs); 13653955d011SMarcel Moolenaar 13663955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 13673955d011SMarcel Moolenaar fprintf(debug_file, "\ttrying %s...", s->file); 13683955d011SMarcel Moolenaar } 13693955d011SMarcel Moolenaar 13703955d011SMarcel Moolenaar /* 13713955d011SMarcel Moolenaar * A file is considered to exist if either a node exists in the 13723955d011SMarcel Moolenaar * graph for it or the file actually exists. 13733955d011SMarcel Moolenaar */ 13743955d011SMarcel Moolenaar if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) { 13753955d011SMarcel Moolenaar #ifdef DEBUG_SRC 137695e3ed2cSSimon J. Gerraty fprintf(debug_file, "remove %p from %p\n", s, srcs); 13773955d011SMarcel Moolenaar #endif 13783955d011SMarcel Moolenaar rs = s; 13793955d011SMarcel Moolenaar break; 13803955d011SMarcel Moolenaar } 13813955d011SMarcel Moolenaar 13823955d011SMarcel Moolenaar if ((ptr = Dir_FindFile(s->file, s->suff->searchPath)) != NULL) { 13833955d011SMarcel Moolenaar rs = s; 13843955d011SMarcel Moolenaar #ifdef DEBUG_SRC 138595e3ed2cSSimon J. Gerraty fprintf(debug_file, "remove %p from %p\n", s, srcs); 13863955d011SMarcel Moolenaar #endif 13873955d011SMarcel Moolenaar free(ptr); 13883955d011SMarcel Moolenaar break; 13893955d011SMarcel Moolenaar } 13903955d011SMarcel Moolenaar 13913955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 13923955d011SMarcel Moolenaar fprintf(debug_file, "not there\n"); 13933955d011SMarcel Moolenaar } 13943955d011SMarcel Moolenaar 13953955d011SMarcel Moolenaar SuffAddLevel(srcs, s); 13963955d011SMarcel Moolenaar Lst_AtEnd(slst, s); 13973955d011SMarcel Moolenaar } 13983955d011SMarcel Moolenaar 13993955d011SMarcel Moolenaar if (DEBUG(SUFF) && rs) { 14003955d011SMarcel Moolenaar fprintf(debug_file, "got it\n"); 14013955d011SMarcel Moolenaar } 14023955d011SMarcel Moolenaar return (rs); 14033955d011SMarcel Moolenaar } 14043955d011SMarcel Moolenaar 14053955d011SMarcel Moolenaar /*- 14063955d011SMarcel Moolenaar *----------------------------------------------------------------------- 14073955d011SMarcel Moolenaar * SuffFindCmds -- 14083955d011SMarcel Moolenaar * See if any of the children of the target in the Src structure is 14093955d011SMarcel Moolenaar * one from which the target can be transformed. If there is one, 14103955d011SMarcel Moolenaar * a Src structure is put together for it and returned. 14113955d011SMarcel Moolenaar * 14123955d011SMarcel Moolenaar * Input: 14133955d011SMarcel Moolenaar * targ Src structure to play with 14143955d011SMarcel Moolenaar * 14153955d011SMarcel Moolenaar * Results: 14163955d011SMarcel Moolenaar * The Src structure of the "winning" child, or NULL if no such beast. 14173955d011SMarcel Moolenaar * 14183955d011SMarcel Moolenaar * Side Effects: 14193955d011SMarcel Moolenaar * A Src structure may be allocated. 14203955d011SMarcel Moolenaar * 14213955d011SMarcel Moolenaar *----------------------------------------------------------------------- 14223955d011SMarcel Moolenaar */ 14233955d011SMarcel Moolenaar static Src * 14243955d011SMarcel Moolenaar SuffFindCmds(Src *targ, Lst slst) 14253955d011SMarcel Moolenaar { 14263955d011SMarcel Moolenaar LstNode ln; /* General-purpose list node */ 14273955d011SMarcel Moolenaar GNode *t, /* Target GNode */ 14283955d011SMarcel Moolenaar *s; /* Source GNode */ 14293955d011SMarcel Moolenaar int prefLen;/* The length of the defined prefix */ 14303955d011SMarcel Moolenaar Suff *suff; /* Suffix on matching beastie */ 14313955d011SMarcel Moolenaar Src *ret; /* Return value */ 14323955d011SMarcel Moolenaar char *cp; 14333955d011SMarcel Moolenaar 14343955d011SMarcel Moolenaar t = targ->node; 14353955d011SMarcel Moolenaar (void)Lst_Open(t->children); 14363955d011SMarcel Moolenaar prefLen = strlen(targ->pref); 14373955d011SMarcel Moolenaar 14383955d011SMarcel Moolenaar for (;;) { 14393955d011SMarcel Moolenaar ln = Lst_Next(t->children); 14403955d011SMarcel Moolenaar if (ln == NULL) { 14413955d011SMarcel Moolenaar Lst_Close(t->children); 14423955d011SMarcel Moolenaar return NULL; 14433955d011SMarcel Moolenaar } 14443955d011SMarcel Moolenaar s = (GNode *)Lst_Datum(ln); 14453955d011SMarcel Moolenaar 14463955d011SMarcel Moolenaar if (s->type & OP_OPTIONAL && Lst_IsEmpty(t->commands)) { 14473955d011SMarcel Moolenaar /* 14483955d011SMarcel Moolenaar * We haven't looked to see if .OPTIONAL files exist yet, so 14493955d011SMarcel Moolenaar * don't use one as the implicit source. 14503955d011SMarcel Moolenaar * This allows us to use .OPTIONAL in .depend files so make won't 14513955d011SMarcel Moolenaar * complain "don't know how to make xxx.h' when a dependent file 14523955d011SMarcel Moolenaar * has been moved/deleted. 14533955d011SMarcel Moolenaar */ 14543955d011SMarcel Moolenaar continue; 14553955d011SMarcel Moolenaar } 14563955d011SMarcel Moolenaar 14573955d011SMarcel Moolenaar cp = strrchr(s->name, '/'); 14583955d011SMarcel Moolenaar if (cp == NULL) { 14593955d011SMarcel Moolenaar cp = s->name; 14603955d011SMarcel Moolenaar } else { 14613955d011SMarcel Moolenaar cp++; 14623955d011SMarcel Moolenaar } 14633955d011SMarcel Moolenaar if (strncmp(cp, targ->pref, prefLen) != 0) 14643955d011SMarcel Moolenaar continue; 14653955d011SMarcel Moolenaar /* 14663955d011SMarcel Moolenaar * The node matches the prefix ok, see if it has a known 14673955d011SMarcel Moolenaar * suffix. 14683955d011SMarcel Moolenaar */ 14693955d011SMarcel Moolenaar ln = Lst_Find(sufflist, &cp[prefLen], SuffSuffHasNameP); 14703955d011SMarcel Moolenaar if (ln == NULL) 14713955d011SMarcel Moolenaar continue; 14723955d011SMarcel Moolenaar /* 14733955d011SMarcel Moolenaar * It even has a known suffix, see if there's a transformation 14743955d011SMarcel Moolenaar * defined between the node's suffix and the target's suffix. 14753955d011SMarcel Moolenaar * 14763955d011SMarcel Moolenaar * XXX: Handle multi-stage transformations here, too. 14773955d011SMarcel Moolenaar */ 14783955d011SMarcel Moolenaar suff = (Suff *)Lst_Datum(ln); 14793955d011SMarcel Moolenaar 14803955d011SMarcel Moolenaar if (Lst_Member(suff->parents, targ->suff) != NULL) 14813955d011SMarcel Moolenaar break; 14823955d011SMarcel Moolenaar } 14833955d011SMarcel Moolenaar 14843955d011SMarcel Moolenaar /* 14853955d011SMarcel Moolenaar * Hot Damn! Create a new Src structure to describe 14863955d011SMarcel Moolenaar * this transformation (making sure to duplicate the 14873955d011SMarcel Moolenaar * source node's name so Suff_FindDeps can free it 14883955d011SMarcel Moolenaar * again (ick)), and return the new structure. 14893955d011SMarcel Moolenaar */ 14903955d011SMarcel Moolenaar ret = bmake_malloc(sizeof(Src)); 14913955d011SMarcel Moolenaar ret->file = bmake_strdup(s->name); 14923955d011SMarcel Moolenaar ret->pref = targ->pref; 14933955d011SMarcel Moolenaar ret->suff = suff; 14943955d011SMarcel Moolenaar suff->refCount++; 14953955d011SMarcel Moolenaar ret->parent = targ; 14963955d011SMarcel Moolenaar ret->node = s; 14973955d011SMarcel Moolenaar ret->children = 0; 14983955d011SMarcel Moolenaar targ->children += 1; 14993955d011SMarcel Moolenaar #ifdef DEBUG_SRC 15003955d011SMarcel Moolenaar ret->cp = Lst_Init(FALSE); 150195e3ed2cSSimon J. Gerraty fprintf(debug_file, "3 add %p %p\n", targ, ret); 15023955d011SMarcel Moolenaar Lst_AtEnd(targ->cp, ret); 15033955d011SMarcel Moolenaar #endif 15043955d011SMarcel Moolenaar Lst_AtEnd(slst, ret); 15053955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 15063955d011SMarcel Moolenaar fprintf(debug_file, "\tusing existing source %s\n", s->name); 15073955d011SMarcel Moolenaar } 15083955d011SMarcel Moolenaar return (ret); 15093955d011SMarcel Moolenaar } 15103955d011SMarcel Moolenaar 15113955d011SMarcel Moolenaar /*- 15123955d011SMarcel Moolenaar *----------------------------------------------------------------------- 15133955d011SMarcel Moolenaar * SuffExpandChildren -- 15143955d011SMarcel Moolenaar * Expand the names of any children of a given node that contain 15153955d011SMarcel Moolenaar * variable invocations or file wildcards into actual targets. 15163955d011SMarcel Moolenaar * 15173955d011SMarcel Moolenaar * Input: 15183955d011SMarcel Moolenaar * cln Child to examine 15193955d011SMarcel Moolenaar * pgn Parent node being processed 15203955d011SMarcel Moolenaar * 15213955d011SMarcel Moolenaar * Results: 15223955d011SMarcel Moolenaar * === 0 (continue) 15233955d011SMarcel Moolenaar * 15243955d011SMarcel Moolenaar * Side Effects: 15253955d011SMarcel Moolenaar * The expanded node is removed from the parent's list of children, 15263955d011SMarcel Moolenaar * and the parent's unmade counter is decremented, but other nodes 15273955d011SMarcel Moolenaar * may be added. 15283955d011SMarcel Moolenaar * 15293955d011SMarcel Moolenaar *----------------------------------------------------------------------- 15303955d011SMarcel Moolenaar */ 15313955d011SMarcel Moolenaar static void 15323955d011SMarcel Moolenaar SuffExpandChildren(LstNode cln, GNode *pgn) 15333955d011SMarcel Moolenaar { 15343955d011SMarcel Moolenaar GNode *cgn = (GNode *)Lst_Datum(cln); 15353955d011SMarcel Moolenaar GNode *gn; /* New source 8) */ 15363955d011SMarcel Moolenaar char *cp; /* Expanded value */ 15373955d011SMarcel Moolenaar 15383955d011SMarcel Moolenaar if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ)) 15393955d011SMarcel Moolenaar /* It is all too hard to process the result of .ORDER */ 15403955d011SMarcel Moolenaar return; 15413955d011SMarcel Moolenaar 15423955d011SMarcel Moolenaar if (cgn->type & OP_WAIT) 15433955d011SMarcel Moolenaar /* Ignore these (& OP_PHONY ?) */ 15443955d011SMarcel Moolenaar return; 15453955d011SMarcel Moolenaar 15463955d011SMarcel Moolenaar /* 15473955d011SMarcel Moolenaar * First do variable expansion -- this takes precedence over 15483955d011SMarcel Moolenaar * wildcard expansion. If the result contains wildcards, they'll be gotten 15493955d011SMarcel Moolenaar * to later since the resulting words are tacked on to the end of 15503955d011SMarcel Moolenaar * the children list. 15513955d011SMarcel Moolenaar */ 15523955d011SMarcel Moolenaar if (strchr(cgn->name, '$') == NULL) { 15533955d011SMarcel Moolenaar SuffExpandWildcards(cln, pgn); 15543955d011SMarcel Moolenaar return; 15553955d011SMarcel Moolenaar } 15563955d011SMarcel Moolenaar 15573955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 15583955d011SMarcel Moolenaar fprintf(debug_file, "Expanding \"%s\"...", cgn->name); 15593955d011SMarcel Moolenaar } 1560be19d90bSSimon J. Gerraty cp = Var_Subst(NULL, cgn->name, pgn, VARF_UNDEFERR|VARF_WANTRES); 15613955d011SMarcel Moolenaar 15623955d011SMarcel Moolenaar if (cp != NULL) { 15633955d011SMarcel Moolenaar Lst members = Lst_Init(FALSE); 15643955d011SMarcel Moolenaar 15653955d011SMarcel Moolenaar if (cgn->type & OP_ARCHV) { 15663955d011SMarcel Moolenaar /* 15673955d011SMarcel Moolenaar * Node was an archive(member) target, so we want to call 15683955d011SMarcel Moolenaar * on the Arch module to find the nodes for us, expanding 15693955d011SMarcel Moolenaar * variables in the parent's context. 15703955d011SMarcel Moolenaar */ 15713955d011SMarcel Moolenaar char *sacrifice = cp; 15723955d011SMarcel Moolenaar 15733955d011SMarcel Moolenaar (void)Arch_ParseArchive(&sacrifice, members, pgn); 15743955d011SMarcel Moolenaar } else { 15753955d011SMarcel Moolenaar /* 15763955d011SMarcel Moolenaar * Break the result into a vector of strings whose nodes 15773955d011SMarcel Moolenaar * we can find, then add those nodes to the members list. 15783955d011SMarcel Moolenaar * Unfortunately, we can't use brk_string b/c it 15793955d011SMarcel Moolenaar * doesn't understand about variable specifications with 15803955d011SMarcel Moolenaar * spaces in them... 15813955d011SMarcel Moolenaar */ 15823955d011SMarcel Moolenaar char *start; 15833955d011SMarcel Moolenaar char *initcp = cp; /* For freeing... */ 15843955d011SMarcel Moolenaar 15853955d011SMarcel Moolenaar for (start = cp; *start == ' ' || *start == '\t'; start++) 15863955d011SMarcel Moolenaar continue; 15873955d011SMarcel Moolenaar for (cp = start; *cp != '\0'; cp++) { 15883955d011SMarcel Moolenaar if (*cp == ' ' || *cp == '\t') { 15893955d011SMarcel Moolenaar /* 15903955d011SMarcel Moolenaar * White-space -- terminate element, find the node, 15913955d011SMarcel Moolenaar * add it, skip any further spaces. 15923955d011SMarcel Moolenaar */ 15933955d011SMarcel Moolenaar *cp++ = '\0'; 15943955d011SMarcel Moolenaar gn = Targ_FindNode(start, TARG_CREATE); 15953955d011SMarcel Moolenaar (void)Lst_AtEnd(members, gn); 15963955d011SMarcel Moolenaar while (*cp == ' ' || *cp == '\t') { 15973955d011SMarcel Moolenaar cp++; 15983955d011SMarcel Moolenaar } 15993955d011SMarcel Moolenaar /* 16003955d011SMarcel Moolenaar * Adjust cp for increment at start of loop, but 16013955d011SMarcel Moolenaar * set start to first non-space. 16023955d011SMarcel Moolenaar */ 16033955d011SMarcel Moolenaar start = cp--; 16043955d011SMarcel Moolenaar } else if (*cp == '$') { 16053955d011SMarcel Moolenaar /* 16063955d011SMarcel Moolenaar * Start of a variable spec -- contact variable module 16073955d011SMarcel Moolenaar * to find the end so we can skip over it. 16083955d011SMarcel Moolenaar */ 16093955d011SMarcel Moolenaar char *junk; 16103955d011SMarcel Moolenaar int len; 16113955d011SMarcel Moolenaar void *freeIt; 16123955d011SMarcel Moolenaar 1613be19d90bSSimon J. Gerraty junk = Var_Parse(cp, pgn, VARF_UNDEFERR|VARF_WANTRES, 1614be19d90bSSimon J. Gerraty &len, &freeIt); 16153955d011SMarcel Moolenaar if (junk != var_Error) { 16163955d011SMarcel Moolenaar cp += len - 1; 16173955d011SMarcel Moolenaar } 16183955d011SMarcel Moolenaar 16193955d011SMarcel Moolenaar free(freeIt); 162095e3ed2cSSimon J. Gerraty } else if (*cp == '\\' && cp[1] != '\0') { 16213955d011SMarcel Moolenaar /* 16223955d011SMarcel Moolenaar * Escaped something -- skip over it 16233955d011SMarcel Moolenaar */ 16243955d011SMarcel Moolenaar cp++; 16253955d011SMarcel Moolenaar } 16263955d011SMarcel Moolenaar } 16273955d011SMarcel Moolenaar 16283955d011SMarcel Moolenaar if (cp != start) { 16293955d011SMarcel Moolenaar /* 16303955d011SMarcel Moolenaar * Stuff left over -- add it to the list too 16313955d011SMarcel Moolenaar */ 16323955d011SMarcel Moolenaar gn = Targ_FindNode(start, TARG_CREATE); 16333955d011SMarcel Moolenaar (void)Lst_AtEnd(members, gn); 16343955d011SMarcel Moolenaar } 16353955d011SMarcel Moolenaar /* 16363955d011SMarcel Moolenaar * Point cp back at the beginning again so the variable value 16373955d011SMarcel Moolenaar * can be freed. 16383955d011SMarcel Moolenaar */ 16393955d011SMarcel Moolenaar cp = initcp; 16403955d011SMarcel Moolenaar } 16413955d011SMarcel Moolenaar 16423955d011SMarcel Moolenaar /* 16433955d011SMarcel Moolenaar * Add all elements of the members list to the parent node. 16443955d011SMarcel Moolenaar */ 16453955d011SMarcel Moolenaar while(!Lst_IsEmpty(members)) { 16463955d011SMarcel Moolenaar gn = (GNode *)Lst_DeQueue(members); 16473955d011SMarcel Moolenaar 16483955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 16493955d011SMarcel Moolenaar fprintf(debug_file, "%s...", gn->name); 16503955d011SMarcel Moolenaar } 16513955d011SMarcel Moolenaar /* Add gn to the parents child list before the original child */ 16523955d011SMarcel Moolenaar (void)Lst_InsertBefore(pgn->children, cln, gn); 16533955d011SMarcel Moolenaar (void)Lst_AtEnd(gn->parents, pgn); 16543955d011SMarcel Moolenaar pgn->unmade++; 16553955d011SMarcel Moolenaar /* Expand wildcards on new node */ 16563955d011SMarcel Moolenaar SuffExpandWildcards(Lst_Prev(cln), pgn); 16573955d011SMarcel Moolenaar } 16583955d011SMarcel Moolenaar Lst_Destroy(members, NULL); 16593955d011SMarcel Moolenaar 16603955d011SMarcel Moolenaar /* 16613955d011SMarcel Moolenaar * Free the result 16623955d011SMarcel Moolenaar */ 16633955d011SMarcel Moolenaar free(cp); 16643955d011SMarcel Moolenaar } 16653955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 16663955d011SMarcel Moolenaar fprintf(debug_file, "\n"); 16673955d011SMarcel Moolenaar } 16683955d011SMarcel Moolenaar 16693955d011SMarcel Moolenaar /* 16703955d011SMarcel Moolenaar * Now the source is expanded, remove it from the list of children to 16713955d011SMarcel Moolenaar * keep it from being processed. 16723955d011SMarcel Moolenaar */ 16733955d011SMarcel Moolenaar pgn->unmade--; 16743955d011SMarcel Moolenaar Lst_Remove(pgn->children, cln); 16753955d011SMarcel Moolenaar Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); 16763955d011SMarcel Moolenaar } 16773955d011SMarcel Moolenaar 16783955d011SMarcel Moolenaar static void 16793955d011SMarcel Moolenaar SuffExpandWildcards(LstNode cln, GNode *pgn) 16803955d011SMarcel Moolenaar { 16813955d011SMarcel Moolenaar GNode *cgn = (GNode *)Lst_Datum(cln); 16823955d011SMarcel Moolenaar GNode *gn; /* New source 8) */ 16833955d011SMarcel Moolenaar char *cp; /* Expanded value */ 16843955d011SMarcel Moolenaar Lst explist; /* List of expansions */ 16853955d011SMarcel Moolenaar 16863955d011SMarcel Moolenaar if (!Dir_HasWildcards(cgn->name)) 16873955d011SMarcel Moolenaar return; 16883955d011SMarcel Moolenaar 16893955d011SMarcel Moolenaar /* 16903955d011SMarcel Moolenaar * Expand the word along the chosen path 16913955d011SMarcel Moolenaar */ 16923955d011SMarcel Moolenaar explist = Lst_Init(FALSE); 16933955d011SMarcel Moolenaar Dir_Expand(cgn->name, Suff_FindPath(cgn), explist); 16943955d011SMarcel Moolenaar 16953955d011SMarcel Moolenaar while (!Lst_IsEmpty(explist)) { 16963955d011SMarcel Moolenaar /* 16973955d011SMarcel Moolenaar * Fetch next expansion off the list and find its GNode 16983955d011SMarcel Moolenaar */ 16993955d011SMarcel Moolenaar cp = (char *)Lst_DeQueue(explist); 17003955d011SMarcel Moolenaar 17013955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 17023955d011SMarcel Moolenaar fprintf(debug_file, "%s...", cp); 17033955d011SMarcel Moolenaar } 17043955d011SMarcel Moolenaar gn = Targ_FindNode(cp, TARG_CREATE); 17053955d011SMarcel Moolenaar 17063955d011SMarcel Moolenaar /* Add gn to the parents child list before the original child */ 17073955d011SMarcel Moolenaar (void)Lst_InsertBefore(pgn->children, cln, gn); 17083955d011SMarcel Moolenaar (void)Lst_AtEnd(gn->parents, pgn); 17093955d011SMarcel Moolenaar pgn->unmade++; 17103955d011SMarcel Moolenaar } 17113955d011SMarcel Moolenaar 17123955d011SMarcel Moolenaar /* 17133955d011SMarcel Moolenaar * Nuke what's left of the list 17143955d011SMarcel Moolenaar */ 17153955d011SMarcel Moolenaar Lst_Destroy(explist, NULL); 17163955d011SMarcel Moolenaar 17173955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 17183955d011SMarcel Moolenaar fprintf(debug_file, "\n"); 17193955d011SMarcel Moolenaar } 17203955d011SMarcel Moolenaar 17213955d011SMarcel Moolenaar /* 17223955d011SMarcel Moolenaar * Now the source is expanded, remove it from the list of children to 17233955d011SMarcel Moolenaar * keep it from being processed. 17243955d011SMarcel Moolenaar */ 17253955d011SMarcel Moolenaar pgn->unmade--; 17263955d011SMarcel Moolenaar Lst_Remove(pgn->children, cln); 17273955d011SMarcel Moolenaar Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); 17283955d011SMarcel Moolenaar } 17293955d011SMarcel Moolenaar 17303955d011SMarcel Moolenaar /*- 17313955d011SMarcel Moolenaar *----------------------------------------------------------------------- 17323955d011SMarcel Moolenaar * Suff_FindPath -- 17333955d011SMarcel Moolenaar * Find a path along which to expand the node. 17343955d011SMarcel Moolenaar * 17353955d011SMarcel Moolenaar * If the word has a known suffix, use that path. 17363955d011SMarcel Moolenaar * If it has no known suffix, use the default system search path. 17373955d011SMarcel Moolenaar * 17383955d011SMarcel Moolenaar * Input: 17393955d011SMarcel Moolenaar * gn Node being examined 17403955d011SMarcel Moolenaar * 17413955d011SMarcel Moolenaar * Results: 17423955d011SMarcel Moolenaar * The appropriate path to search for the GNode. 17433955d011SMarcel Moolenaar * 17443955d011SMarcel Moolenaar * Side Effects: 17453955d011SMarcel Moolenaar * XXX: We could set the suffix here so that we don't have to scan 17463955d011SMarcel Moolenaar * again. 17473955d011SMarcel Moolenaar * 17483955d011SMarcel Moolenaar *----------------------------------------------------------------------- 17493955d011SMarcel Moolenaar */ 17503955d011SMarcel Moolenaar Lst 17513955d011SMarcel Moolenaar Suff_FindPath(GNode* gn) 17523955d011SMarcel Moolenaar { 17533955d011SMarcel Moolenaar Suff *suff = gn->suffix; 17543955d011SMarcel Moolenaar 17553955d011SMarcel Moolenaar if (suff == NULL) { 17563955d011SMarcel Moolenaar SuffixCmpData sd; /* Search string data */ 17573955d011SMarcel Moolenaar LstNode ln; 17583955d011SMarcel Moolenaar sd.len = strlen(gn->name); 17593955d011SMarcel Moolenaar sd.ename = gn->name + sd.len; 17603955d011SMarcel Moolenaar ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP); 17613955d011SMarcel Moolenaar 17623955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 17633955d011SMarcel Moolenaar fprintf(debug_file, "Wildcard expanding \"%s\"...", gn->name); 17643955d011SMarcel Moolenaar } 17653955d011SMarcel Moolenaar if (ln != NULL) 17663955d011SMarcel Moolenaar suff = (Suff *)Lst_Datum(ln); 17673955d011SMarcel Moolenaar /* XXX: Here we can save the suffix so we don't have to do this again */ 17683955d011SMarcel Moolenaar } 17693955d011SMarcel Moolenaar 17703955d011SMarcel Moolenaar if (suff != NULL) { 17713955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 17723955d011SMarcel Moolenaar fprintf(debug_file, "suffix is \"%s\"...", suff->name); 17733955d011SMarcel Moolenaar } 17743955d011SMarcel Moolenaar return suff->searchPath; 17753955d011SMarcel Moolenaar } else { 17763955d011SMarcel Moolenaar /* 17773955d011SMarcel Moolenaar * Use default search path 17783955d011SMarcel Moolenaar */ 17793955d011SMarcel Moolenaar return dirSearchPath; 17803955d011SMarcel Moolenaar } 17813955d011SMarcel Moolenaar } 17823955d011SMarcel Moolenaar 17833955d011SMarcel Moolenaar /*- 17843955d011SMarcel Moolenaar *----------------------------------------------------------------------- 17853955d011SMarcel Moolenaar * SuffApplyTransform -- 17863955d011SMarcel Moolenaar * Apply a transformation rule, given the source and target nodes 17873955d011SMarcel Moolenaar * and suffixes. 17883955d011SMarcel Moolenaar * 17893955d011SMarcel Moolenaar * Input: 17903955d011SMarcel Moolenaar * tGn Target node 17913955d011SMarcel Moolenaar * sGn Source node 17923955d011SMarcel Moolenaar * t Target suffix 17933955d011SMarcel Moolenaar * s Source suffix 17943955d011SMarcel Moolenaar * 17953955d011SMarcel Moolenaar * Results: 17963955d011SMarcel Moolenaar * TRUE if successful, FALSE if not. 17973955d011SMarcel Moolenaar * 17983955d011SMarcel Moolenaar * Side Effects: 17993955d011SMarcel Moolenaar * The source and target are linked and the commands from the 18003955d011SMarcel Moolenaar * transformation are added to the target node's commands list. 18013955d011SMarcel Moolenaar * All attributes but OP_DEPMASK and OP_TRANSFORM are applied 18023955d011SMarcel Moolenaar * to the target. The target also inherits all the sources for 18033955d011SMarcel Moolenaar * the transformation rule. 18043955d011SMarcel Moolenaar * 18053955d011SMarcel Moolenaar *----------------------------------------------------------------------- 18063955d011SMarcel Moolenaar */ 18073955d011SMarcel Moolenaar static Boolean 18083955d011SMarcel Moolenaar SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s) 18093955d011SMarcel Moolenaar { 18103955d011SMarcel Moolenaar LstNode ln, nln; /* General node */ 18113955d011SMarcel Moolenaar char *tname; /* Name of transformation rule */ 18123955d011SMarcel Moolenaar GNode *gn; /* Node for same */ 18133955d011SMarcel Moolenaar 18143955d011SMarcel Moolenaar /* 18153955d011SMarcel Moolenaar * Form the proper links between the target and source. 18163955d011SMarcel Moolenaar */ 18173955d011SMarcel Moolenaar (void)Lst_AtEnd(tGn->children, sGn); 18183955d011SMarcel Moolenaar (void)Lst_AtEnd(sGn->parents, tGn); 18193955d011SMarcel Moolenaar tGn->unmade += 1; 18203955d011SMarcel Moolenaar 18213955d011SMarcel Moolenaar /* 18223955d011SMarcel Moolenaar * Locate the transformation rule itself 18233955d011SMarcel Moolenaar */ 18243955d011SMarcel Moolenaar tname = str_concat(s->name, t->name, 0); 18253955d011SMarcel Moolenaar ln = Lst_Find(transforms, tname, SuffGNHasNameP); 18263955d011SMarcel Moolenaar free(tname); 18273955d011SMarcel Moolenaar 18283955d011SMarcel Moolenaar if (ln == NULL) { 18293955d011SMarcel Moolenaar /* 18303955d011SMarcel Moolenaar * Not really such a transformation rule (can happen when we're 18313955d011SMarcel Moolenaar * called to link an OP_MEMBER and OP_ARCHV node), so return 18323955d011SMarcel Moolenaar * FALSE. 18333955d011SMarcel Moolenaar */ 18343955d011SMarcel Moolenaar return(FALSE); 18353955d011SMarcel Moolenaar } 18363955d011SMarcel Moolenaar 18373955d011SMarcel Moolenaar gn = (GNode *)Lst_Datum(ln); 18383955d011SMarcel Moolenaar 18393955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 18403955d011SMarcel Moolenaar fprintf(debug_file, "\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); 18413955d011SMarcel Moolenaar } 18423955d011SMarcel Moolenaar 18433955d011SMarcel Moolenaar /* 18443955d011SMarcel Moolenaar * Record last child for expansion purposes 18453955d011SMarcel Moolenaar */ 18463955d011SMarcel Moolenaar ln = Lst_Last(tGn->children); 18473955d011SMarcel Moolenaar 18483955d011SMarcel Moolenaar /* 18493955d011SMarcel Moolenaar * Pass the buck to Make_HandleUse to apply the rule 18503955d011SMarcel Moolenaar */ 18513955d011SMarcel Moolenaar (void)Make_HandleUse(gn, tGn); 18523955d011SMarcel Moolenaar 18533955d011SMarcel Moolenaar /* 18543955d011SMarcel Moolenaar * Deal with wildcards and variables in any acquired sources 18553955d011SMarcel Moolenaar */ 18563955d011SMarcel Moolenaar for (ln = Lst_Succ(ln); ln != NULL; ln = nln) { 18573955d011SMarcel Moolenaar nln = Lst_Succ(ln); 18583955d011SMarcel Moolenaar SuffExpandChildren(ln, tGn); 18593955d011SMarcel Moolenaar } 18603955d011SMarcel Moolenaar 18613955d011SMarcel Moolenaar /* 18623955d011SMarcel Moolenaar * Keep track of another parent to which this beast is transformed so 18633955d011SMarcel Moolenaar * the .IMPSRC variable can be set correctly for the parent. 18643955d011SMarcel Moolenaar */ 18653955d011SMarcel Moolenaar (void)Lst_AtEnd(sGn->iParents, tGn); 18663955d011SMarcel Moolenaar 18673955d011SMarcel Moolenaar return(TRUE); 18683955d011SMarcel Moolenaar } 18693955d011SMarcel Moolenaar 18703955d011SMarcel Moolenaar 18713955d011SMarcel Moolenaar /*- 18723955d011SMarcel Moolenaar *----------------------------------------------------------------------- 18733955d011SMarcel Moolenaar * SuffFindArchiveDeps -- 18743955d011SMarcel Moolenaar * Locate dependencies for an OP_ARCHV node. 18753955d011SMarcel Moolenaar * 18763955d011SMarcel Moolenaar * Input: 18773955d011SMarcel Moolenaar * gn Node for which to locate dependencies 18783955d011SMarcel Moolenaar * 18793955d011SMarcel Moolenaar * Results: 18803955d011SMarcel Moolenaar * None 18813955d011SMarcel Moolenaar * 18823955d011SMarcel Moolenaar * Side Effects: 18833955d011SMarcel Moolenaar * Same as Suff_FindDeps 18843955d011SMarcel Moolenaar * 18853955d011SMarcel Moolenaar *----------------------------------------------------------------------- 18863955d011SMarcel Moolenaar */ 18873955d011SMarcel Moolenaar static void 18883955d011SMarcel Moolenaar SuffFindArchiveDeps(GNode *gn, Lst slst) 18893955d011SMarcel Moolenaar { 18903955d011SMarcel Moolenaar char *eoarch; /* End of archive portion */ 18913955d011SMarcel Moolenaar char *eoname; /* End of member portion */ 18923955d011SMarcel Moolenaar GNode *mem; /* Node for member */ 18933955d011SMarcel Moolenaar static const char *copy[] = { 18943955d011SMarcel Moolenaar /* Variables to be copied from the member node */ 18953955d011SMarcel Moolenaar TARGET, /* Must be first */ 18963955d011SMarcel Moolenaar PREFIX, /* Must be second */ 18973955d011SMarcel Moolenaar }; 18983bebe729SSimon J. Gerraty LstNode ln, nln; /* Next suffix node to check */ 18993955d011SMarcel Moolenaar int i; /* Index into copy and vals */ 19003955d011SMarcel Moolenaar Suff *ms; /* Suffix descriptor for member */ 19013955d011SMarcel Moolenaar char *name; /* Start of member's name */ 19023955d011SMarcel Moolenaar 19033955d011SMarcel Moolenaar /* 19043955d011SMarcel Moolenaar * The node is an archive(member) pair. so we must find a 19053955d011SMarcel Moolenaar * suffix for both of them. 19063955d011SMarcel Moolenaar */ 19073955d011SMarcel Moolenaar eoarch = strchr(gn->name, '('); 19083955d011SMarcel Moolenaar eoname = strchr(eoarch, ')'); 19093955d011SMarcel Moolenaar 1910*e1cee40dSSimon J. Gerraty /* 1911*e1cee40dSSimon J. Gerraty * Caller guarantees the format `libname(member)', via 1912*e1cee40dSSimon J. Gerraty * Arch_ParseArchive. 1913*e1cee40dSSimon J. Gerraty */ 1914*e1cee40dSSimon J. Gerraty assert(eoarch != NULL); 1915*e1cee40dSSimon J. Gerraty assert(eoname != NULL); 1916*e1cee40dSSimon J. Gerraty 19173955d011SMarcel Moolenaar *eoname = '\0'; /* Nuke parentheses during suffix search */ 19183955d011SMarcel Moolenaar *eoarch = '\0'; /* So a suffix can be found */ 19193955d011SMarcel Moolenaar 19203955d011SMarcel Moolenaar name = eoarch + 1; 19213955d011SMarcel Moolenaar 19223955d011SMarcel Moolenaar /* 19233955d011SMarcel Moolenaar * To simplify things, call Suff_FindDeps recursively on the member now, 19243955d011SMarcel Moolenaar * so we can simply compare the member's .PREFIX and .TARGET variables 19253955d011SMarcel Moolenaar * to locate its suffix. This allows us to figure out the suffix to 19263955d011SMarcel Moolenaar * use for the archive without having to do a quadratic search over the 19273955d011SMarcel Moolenaar * suffix list, backtracking for each one... 19283955d011SMarcel Moolenaar */ 19293955d011SMarcel Moolenaar mem = Targ_FindNode(name, TARG_CREATE); 19303955d011SMarcel Moolenaar SuffFindDeps(mem, slst); 19313955d011SMarcel Moolenaar 19323955d011SMarcel Moolenaar /* 19333955d011SMarcel Moolenaar * Create the link between the two nodes right off 19343955d011SMarcel Moolenaar */ 19353955d011SMarcel Moolenaar (void)Lst_AtEnd(gn->children, mem); 19363955d011SMarcel Moolenaar (void)Lst_AtEnd(mem->parents, gn); 19373955d011SMarcel Moolenaar gn->unmade += 1; 19383955d011SMarcel Moolenaar 19393955d011SMarcel Moolenaar /* 19403955d011SMarcel Moolenaar * Copy in the variables from the member node to this one. 19413955d011SMarcel Moolenaar */ 19423955d011SMarcel Moolenaar for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) { 19433955d011SMarcel Moolenaar char *p1; 19443955d011SMarcel Moolenaar Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn, 0); 19453955d011SMarcel Moolenaar free(p1); 19463955d011SMarcel Moolenaar 19473955d011SMarcel Moolenaar } 19483955d011SMarcel Moolenaar 19493955d011SMarcel Moolenaar ms = mem->suffix; 19503955d011SMarcel Moolenaar if (ms == NULL) { 19513955d011SMarcel Moolenaar /* 19523955d011SMarcel Moolenaar * Didn't know what it was -- use .NULL suffix if not in make mode 19533955d011SMarcel Moolenaar */ 19543955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 19553955d011SMarcel Moolenaar fprintf(debug_file, "using null suffix\n"); 19563955d011SMarcel Moolenaar } 19573955d011SMarcel Moolenaar ms = suffNull; 19583955d011SMarcel Moolenaar } 19593955d011SMarcel Moolenaar 19603955d011SMarcel Moolenaar 19613955d011SMarcel Moolenaar /* 19623955d011SMarcel Moolenaar * Set the other two local variables required for this target. 19633955d011SMarcel Moolenaar */ 19643955d011SMarcel Moolenaar Var_Set(MEMBER, name, gn, 0); 19653955d011SMarcel Moolenaar Var_Set(ARCHIVE, gn->name, gn, 0); 19663955d011SMarcel Moolenaar 19673bebe729SSimon J. Gerraty /* 19683bebe729SSimon J. Gerraty * Set $@ for compatibility with other makes 19693bebe729SSimon J. Gerraty */ 19703bebe729SSimon J. Gerraty Var_Set(TARGET, gn->name, gn, 0); 19713bebe729SSimon J. Gerraty 19723bebe729SSimon J. Gerraty /* 19733bebe729SSimon J. Gerraty * Now we've got the important local variables set, expand any sources 19743bebe729SSimon J. Gerraty * that still contain variables or wildcards in their names. 19753bebe729SSimon J. Gerraty */ 19763bebe729SSimon J. Gerraty for (ln = Lst_First(gn->children); ln != NULL; ln = nln) { 19773bebe729SSimon J. Gerraty nln = Lst_Succ(ln); 19783bebe729SSimon J. Gerraty SuffExpandChildren(ln, gn); 19793bebe729SSimon J. Gerraty } 19803bebe729SSimon J. Gerraty 19813955d011SMarcel Moolenaar if (ms != NULL) { 19823955d011SMarcel Moolenaar /* 19833955d011SMarcel Moolenaar * Member has a known suffix, so look for a transformation rule from 19843955d011SMarcel Moolenaar * it to a possible suffix of the archive. Rather than searching 19853955d011SMarcel Moolenaar * through the entire list, we just look at suffixes to which the 19863955d011SMarcel Moolenaar * member's suffix may be transformed... 19873955d011SMarcel Moolenaar */ 19883955d011SMarcel Moolenaar SuffixCmpData sd; /* Search string data */ 19893955d011SMarcel Moolenaar 19903955d011SMarcel Moolenaar /* 19913955d011SMarcel Moolenaar * Use first matching suffix... 19923955d011SMarcel Moolenaar */ 19933955d011SMarcel Moolenaar sd.len = eoarch - gn->name; 19943955d011SMarcel Moolenaar sd.ename = eoarch; 19953955d011SMarcel Moolenaar ln = Lst_Find(ms->parents, &sd, SuffSuffIsSuffixP); 19963955d011SMarcel Moolenaar 19973955d011SMarcel Moolenaar if (ln != NULL) { 19983955d011SMarcel Moolenaar /* 19993955d011SMarcel Moolenaar * Got one -- apply it 20003955d011SMarcel Moolenaar */ 20013955d011SMarcel Moolenaar if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && 20023955d011SMarcel Moolenaar DEBUG(SUFF)) 20033955d011SMarcel Moolenaar { 20043955d011SMarcel Moolenaar fprintf(debug_file, "\tNo transformation from %s -> %s\n", 20053955d011SMarcel Moolenaar ms->name, ((Suff *)Lst_Datum(ln))->name); 20063955d011SMarcel Moolenaar } 20073955d011SMarcel Moolenaar } 20083955d011SMarcel Moolenaar } 20093955d011SMarcel Moolenaar 20103955d011SMarcel Moolenaar /* 20113955d011SMarcel Moolenaar * Replace the opening and closing parens now we've no need of the separate 20123955d011SMarcel Moolenaar * pieces. 20133955d011SMarcel Moolenaar */ 20143955d011SMarcel Moolenaar *eoarch = '('; *eoname = ')'; 20153955d011SMarcel Moolenaar 20163955d011SMarcel Moolenaar /* 20173955d011SMarcel Moolenaar * Pretend gn appeared to the left of a dependency operator so 20183955d011SMarcel Moolenaar * the user needn't provide a transformation from the member to the 20193955d011SMarcel Moolenaar * archive. 20203955d011SMarcel Moolenaar */ 20213955d011SMarcel Moolenaar if (OP_NOP(gn->type)) { 20223955d011SMarcel Moolenaar gn->type |= OP_DEPENDS; 20233955d011SMarcel Moolenaar } 20243955d011SMarcel Moolenaar 20253955d011SMarcel Moolenaar /* 20263955d011SMarcel Moolenaar * Flag the member as such so we remember to look in the archive for 20273bebe729SSimon J. Gerraty * its modification time. The OP_JOIN | OP_MADE is needed because this 20283bebe729SSimon J. Gerraty * target should never get made. 20293955d011SMarcel Moolenaar */ 20303bebe729SSimon J. Gerraty mem->type |= OP_MEMBER | OP_JOIN | OP_MADE; 20313955d011SMarcel Moolenaar } 20323955d011SMarcel Moolenaar 20333955d011SMarcel Moolenaar /*- 20343955d011SMarcel Moolenaar *----------------------------------------------------------------------- 20353955d011SMarcel Moolenaar * SuffFindNormalDeps -- 20363955d011SMarcel Moolenaar * Locate implicit dependencies for regular targets. 20373955d011SMarcel Moolenaar * 20383955d011SMarcel Moolenaar * Input: 20393955d011SMarcel Moolenaar * gn Node for which to find sources 20403955d011SMarcel Moolenaar * 20413955d011SMarcel Moolenaar * Results: 20423955d011SMarcel Moolenaar * None. 20433955d011SMarcel Moolenaar * 20443955d011SMarcel Moolenaar * Side Effects: 20453955d011SMarcel Moolenaar * Same as Suff_FindDeps... 20463955d011SMarcel Moolenaar * 20473955d011SMarcel Moolenaar *----------------------------------------------------------------------- 20483955d011SMarcel Moolenaar */ 20493955d011SMarcel Moolenaar static void 20503955d011SMarcel Moolenaar SuffFindNormalDeps(GNode *gn, Lst slst) 20513955d011SMarcel Moolenaar { 20523955d011SMarcel Moolenaar char *eoname; /* End of name */ 20533955d011SMarcel Moolenaar char *sopref; /* Start of prefix */ 20543955d011SMarcel Moolenaar LstNode ln, nln; /* Next suffix node to check */ 20553955d011SMarcel Moolenaar Lst srcs; /* List of sources at which to look */ 20563955d011SMarcel Moolenaar Lst targs; /* List of targets to which things can be 20573955d011SMarcel Moolenaar * transformed. They all have the same file, 20583955d011SMarcel Moolenaar * but different suff and pref fields */ 20593955d011SMarcel Moolenaar Src *bottom; /* Start of found transformation path */ 20603955d011SMarcel Moolenaar Src *src; /* General Src pointer */ 20613955d011SMarcel Moolenaar char *pref; /* Prefix to use */ 20623955d011SMarcel Moolenaar Src *targ; /* General Src target pointer */ 20633955d011SMarcel Moolenaar SuffixCmpData sd; /* Search string data */ 20643955d011SMarcel Moolenaar 20653955d011SMarcel Moolenaar 20663955d011SMarcel Moolenaar sd.len = strlen(gn->name); 20673955d011SMarcel Moolenaar sd.ename = eoname = gn->name + sd.len; 20683955d011SMarcel Moolenaar 20693955d011SMarcel Moolenaar sopref = gn->name; 20703955d011SMarcel Moolenaar 20713955d011SMarcel Moolenaar /* 20723955d011SMarcel Moolenaar * Begin at the beginning... 20733955d011SMarcel Moolenaar */ 20743955d011SMarcel Moolenaar ln = Lst_First(sufflist); 20753955d011SMarcel Moolenaar srcs = Lst_Init(FALSE); 20763955d011SMarcel Moolenaar targs = Lst_Init(FALSE); 20773955d011SMarcel Moolenaar 20783955d011SMarcel Moolenaar /* 20793955d011SMarcel Moolenaar * We're caught in a catch-22 here. On the one hand, we want to use any 20803955d011SMarcel Moolenaar * transformation implied by the target's sources, but we can't examine 20813955d011SMarcel Moolenaar * the sources until we've expanded any variables/wildcards they may hold, 20823955d011SMarcel Moolenaar * and we can't do that until we've set up the target's local variables 20833955d011SMarcel Moolenaar * and we can't do that until we know what the proper suffix for the 20843955d011SMarcel Moolenaar * target is (in case there are two suffixes one of which is a suffix of 20853955d011SMarcel Moolenaar * the other) and we can't know that until we've found its implied 20863955d011SMarcel Moolenaar * source, which we may not want to use if there's an existing source 20873955d011SMarcel Moolenaar * that implies a different transformation. 20883955d011SMarcel Moolenaar * 20893955d011SMarcel Moolenaar * In an attempt to get around this, which may not work all the time, 20903955d011SMarcel Moolenaar * but should work most of the time, we look for implied sources first, 20913955d011SMarcel Moolenaar * checking transformations to all possible suffixes of the target, 20923955d011SMarcel Moolenaar * use what we find to set the target's local variables, expand the 20933955d011SMarcel Moolenaar * children, then look for any overriding transformations they imply. 20943955d011SMarcel Moolenaar * Should we find one, we discard the one we found before. 20953955d011SMarcel Moolenaar */ 20964fc82fe4SSimon J. Gerraty bottom = NULL; 20974fc82fe4SSimon J. Gerraty targ = NULL; 20984fc82fe4SSimon J. Gerraty 20994fc82fe4SSimon J. Gerraty if (!(gn->type & OP_PHONY)) { 21003955d011SMarcel Moolenaar 21013955d011SMarcel Moolenaar while (ln != NULL) { 21023955d011SMarcel Moolenaar /* 21033955d011SMarcel Moolenaar * Look for next possible suffix... 21043955d011SMarcel Moolenaar */ 21053955d011SMarcel Moolenaar ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP); 21063955d011SMarcel Moolenaar 21073955d011SMarcel Moolenaar if (ln != NULL) { 21083955d011SMarcel Moolenaar int prefLen; /* Length of the prefix */ 21093955d011SMarcel Moolenaar 21103955d011SMarcel Moolenaar /* 21113955d011SMarcel Moolenaar * Allocate a Src structure to which things can be transformed 21123955d011SMarcel Moolenaar */ 21133955d011SMarcel Moolenaar targ = bmake_malloc(sizeof(Src)); 21143955d011SMarcel Moolenaar targ->file = bmake_strdup(gn->name); 21153955d011SMarcel Moolenaar targ->suff = (Suff *)Lst_Datum(ln); 21163955d011SMarcel Moolenaar targ->suff->refCount++; 21173955d011SMarcel Moolenaar targ->node = gn; 21183955d011SMarcel Moolenaar targ->parent = NULL; 21193955d011SMarcel Moolenaar targ->children = 0; 21203955d011SMarcel Moolenaar #ifdef DEBUG_SRC 21213955d011SMarcel Moolenaar targ->cp = Lst_Init(FALSE); 21223955d011SMarcel Moolenaar #endif 21233955d011SMarcel Moolenaar 21243955d011SMarcel Moolenaar /* 212552d86256SSimon J. Gerraty * Allocate room for the prefix, whose end is found by 212652d86256SSimon J. Gerraty * subtracting the length of the suffix from 212752d86256SSimon J. Gerraty * the end of the name. 21283955d011SMarcel Moolenaar */ 21293955d011SMarcel Moolenaar prefLen = (eoname - targ->suff->nameLen) - sopref; 21303955d011SMarcel Moolenaar targ->pref = bmake_malloc(prefLen + 1); 21313955d011SMarcel Moolenaar memcpy(targ->pref, sopref, prefLen); 21323955d011SMarcel Moolenaar targ->pref[prefLen] = '\0'; 21333955d011SMarcel Moolenaar 21343955d011SMarcel Moolenaar /* 21353955d011SMarcel Moolenaar * Add nodes from which the target can be made 21363955d011SMarcel Moolenaar */ 21373955d011SMarcel Moolenaar SuffAddLevel(srcs, targ); 21383955d011SMarcel Moolenaar 21393955d011SMarcel Moolenaar /* 21403955d011SMarcel Moolenaar * Record the target so we can nuke it 21413955d011SMarcel Moolenaar */ 21423955d011SMarcel Moolenaar (void)Lst_AtEnd(targs, targ); 21433955d011SMarcel Moolenaar 21443955d011SMarcel Moolenaar /* 21453955d011SMarcel Moolenaar * Search from this suffix's successor... 21463955d011SMarcel Moolenaar */ 21473955d011SMarcel Moolenaar ln = Lst_Succ(ln); 21483955d011SMarcel Moolenaar } 21493955d011SMarcel Moolenaar } 21503955d011SMarcel Moolenaar 21513955d011SMarcel Moolenaar /* 21523955d011SMarcel Moolenaar * Handle target of unknown suffix... 21533955d011SMarcel Moolenaar */ 21543955d011SMarcel Moolenaar if (Lst_IsEmpty(targs) && suffNull != NULL) { 21553955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 21563955d011SMarcel Moolenaar fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name); 21573955d011SMarcel Moolenaar } 21583955d011SMarcel Moolenaar 21593955d011SMarcel Moolenaar targ = bmake_malloc(sizeof(Src)); 21603955d011SMarcel Moolenaar targ->file = bmake_strdup(gn->name); 21613955d011SMarcel Moolenaar targ->suff = suffNull; 21623955d011SMarcel Moolenaar targ->suff->refCount++; 21633955d011SMarcel Moolenaar targ->node = gn; 21643955d011SMarcel Moolenaar targ->parent = NULL; 21653955d011SMarcel Moolenaar targ->children = 0; 21663955d011SMarcel Moolenaar targ->pref = bmake_strdup(sopref); 21673955d011SMarcel Moolenaar #ifdef DEBUG_SRC 21683955d011SMarcel Moolenaar targ->cp = Lst_Init(FALSE); 21693955d011SMarcel Moolenaar #endif 21703955d011SMarcel Moolenaar 21713955d011SMarcel Moolenaar /* 21723955d011SMarcel Moolenaar * Only use the default suffix rules if we don't have commands 21733955d011SMarcel Moolenaar * defined for this gnode; traditional make programs used to 21743955d011SMarcel Moolenaar * not define suffix rules if the gnode had children but we 21753955d011SMarcel Moolenaar * don't do this anymore. 21763955d011SMarcel Moolenaar */ 21773955d011SMarcel Moolenaar if (Lst_IsEmpty(gn->commands)) 21783955d011SMarcel Moolenaar SuffAddLevel(srcs, targ); 21793955d011SMarcel Moolenaar else { 21803955d011SMarcel Moolenaar if (DEBUG(SUFF)) 21813955d011SMarcel Moolenaar fprintf(debug_file, "not "); 21823955d011SMarcel Moolenaar } 21833955d011SMarcel Moolenaar 21843955d011SMarcel Moolenaar if (DEBUG(SUFF)) 21853955d011SMarcel Moolenaar fprintf(debug_file, "adding suffix rules\n"); 21863955d011SMarcel Moolenaar 21873955d011SMarcel Moolenaar (void)Lst_AtEnd(targs, targ); 21883955d011SMarcel Moolenaar } 21893955d011SMarcel Moolenaar 21903955d011SMarcel Moolenaar /* 219152d86256SSimon J. Gerraty * Using the list of possible sources built up from the target 219252d86256SSimon J. Gerraty * suffix(es), try and find an existing file/target that matches. 21933955d011SMarcel Moolenaar */ 21943955d011SMarcel Moolenaar bottom = SuffFindThem(srcs, slst); 21953955d011SMarcel Moolenaar 21963955d011SMarcel Moolenaar if (bottom == NULL) { 21973955d011SMarcel Moolenaar /* 219852d86256SSimon J. Gerraty * No known transformations -- use the first suffix found 219952d86256SSimon J. Gerraty * for setting the local variables. 22003955d011SMarcel Moolenaar */ 22013955d011SMarcel Moolenaar if (!Lst_IsEmpty(targs)) { 22023955d011SMarcel Moolenaar targ = (Src *)Lst_Datum(Lst_First(targs)); 22033955d011SMarcel Moolenaar } else { 22043955d011SMarcel Moolenaar targ = NULL; 22053955d011SMarcel Moolenaar } 22063955d011SMarcel Moolenaar } else { 22073955d011SMarcel Moolenaar /* 22083955d011SMarcel Moolenaar * Work up the transformation path to find the suffix of the 22093955d011SMarcel Moolenaar * target to which the transformation was made. 22103955d011SMarcel Moolenaar */ 22113955d011SMarcel Moolenaar for (targ = bottom; targ->parent != NULL; targ = targ->parent) 22123955d011SMarcel Moolenaar continue; 22133955d011SMarcel Moolenaar } 22144fc82fe4SSimon J. Gerraty } 22153955d011SMarcel Moolenaar 22163955d011SMarcel Moolenaar Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); 22173955d011SMarcel Moolenaar 22183955d011SMarcel Moolenaar pref = (targ != NULL) ? targ->pref : gn->name; 22193955d011SMarcel Moolenaar Var_Set(PREFIX, pref, gn, 0); 22203955d011SMarcel Moolenaar 22213955d011SMarcel Moolenaar /* 22223955d011SMarcel Moolenaar * Now we've got the important local variables set, expand any sources 22233955d011SMarcel Moolenaar * that still contain variables or wildcards in their names. 22243955d011SMarcel Moolenaar */ 22253955d011SMarcel Moolenaar for (ln = Lst_First(gn->children); ln != NULL; ln = nln) { 22263955d011SMarcel Moolenaar nln = Lst_Succ(ln); 22273955d011SMarcel Moolenaar SuffExpandChildren(ln, gn); 22283955d011SMarcel Moolenaar } 22293955d011SMarcel Moolenaar 22303955d011SMarcel Moolenaar if (targ == NULL) { 22313955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 22323955d011SMarcel Moolenaar fprintf(debug_file, "\tNo valid suffix on %s\n", gn->name); 22333955d011SMarcel Moolenaar } 22343955d011SMarcel Moolenaar 22353955d011SMarcel Moolenaar sfnd_abort: 22363955d011SMarcel Moolenaar /* 22373955d011SMarcel Moolenaar * Deal with finding the thing on the default search path. We 22383955d011SMarcel Moolenaar * always do that, not only if the node is only a source (not 22393955d011SMarcel Moolenaar * on the lhs of a dependency operator or [XXX] it has neither 22403955d011SMarcel Moolenaar * children or commands) as the old pmake did. 22413955d011SMarcel Moolenaar */ 22423955d011SMarcel Moolenaar if ((gn->type & (OP_PHONY|OP_NOPATH)) == 0) { 22433955d011SMarcel Moolenaar free(gn->path); 22443955d011SMarcel Moolenaar gn->path = Dir_FindFile(gn->name, 22453955d011SMarcel Moolenaar (targ == NULL ? dirSearchPath : 22463955d011SMarcel Moolenaar targ->suff->searchPath)); 22473955d011SMarcel Moolenaar if (gn->path != NULL) { 22483955d011SMarcel Moolenaar char *ptr; 22493955d011SMarcel Moolenaar Var_Set(TARGET, gn->path, gn, 0); 22503955d011SMarcel Moolenaar 22513955d011SMarcel Moolenaar if (targ != NULL) { 22523955d011SMarcel Moolenaar /* 22533955d011SMarcel Moolenaar * Suffix known for the thing -- trim the suffix off 22543955d011SMarcel Moolenaar * the path to form the proper .PREFIX variable. 22553955d011SMarcel Moolenaar */ 22563955d011SMarcel Moolenaar int savep = strlen(gn->path) - targ->suff->nameLen; 22573955d011SMarcel Moolenaar char savec; 22583955d011SMarcel Moolenaar 22593955d011SMarcel Moolenaar if (gn->suffix) 22603955d011SMarcel Moolenaar gn->suffix->refCount--; 22613955d011SMarcel Moolenaar gn->suffix = targ->suff; 22623955d011SMarcel Moolenaar gn->suffix->refCount++; 22633955d011SMarcel Moolenaar 22643955d011SMarcel Moolenaar savec = gn->path[savep]; 22653955d011SMarcel Moolenaar gn->path[savep] = '\0'; 22663955d011SMarcel Moolenaar 22673955d011SMarcel Moolenaar if ((ptr = strrchr(gn->path, '/')) != NULL) 22683955d011SMarcel Moolenaar ptr++; 22693955d011SMarcel Moolenaar else 22703955d011SMarcel Moolenaar ptr = gn->path; 22713955d011SMarcel Moolenaar 22723955d011SMarcel Moolenaar Var_Set(PREFIX, ptr, gn, 0); 22733955d011SMarcel Moolenaar 22743955d011SMarcel Moolenaar gn->path[savep] = savec; 22753955d011SMarcel Moolenaar } else { 22763955d011SMarcel Moolenaar /* 22773955d011SMarcel Moolenaar * The .PREFIX gets the full path if the target has 22783955d011SMarcel Moolenaar * no known suffix. 22793955d011SMarcel Moolenaar */ 22803955d011SMarcel Moolenaar if (gn->suffix) 22813955d011SMarcel Moolenaar gn->suffix->refCount--; 22823955d011SMarcel Moolenaar gn->suffix = NULL; 22833955d011SMarcel Moolenaar 22843955d011SMarcel Moolenaar if ((ptr = strrchr(gn->path, '/')) != NULL) 22853955d011SMarcel Moolenaar ptr++; 22863955d011SMarcel Moolenaar else 22873955d011SMarcel Moolenaar ptr = gn->path; 22883955d011SMarcel Moolenaar 22893955d011SMarcel Moolenaar Var_Set(PREFIX, ptr, gn, 0); 22903955d011SMarcel Moolenaar } 22913955d011SMarcel Moolenaar } 22923955d011SMarcel Moolenaar } 22933955d011SMarcel Moolenaar 22943955d011SMarcel Moolenaar goto sfnd_return; 22953955d011SMarcel Moolenaar } 22963955d011SMarcel Moolenaar 22973955d011SMarcel Moolenaar /* 22983955d011SMarcel Moolenaar * If the suffix indicates that the target is a library, mark that in 22993955d011SMarcel Moolenaar * the node's type field. 23003955d011SMarcel Moolenaar */ 23013955d011SMarcel Moolenaar if (targ->suff->flags & SUFF_LIBRARY) { 23023955d011SMarcel Moolenaar gn->type |= OP_LIB; 23033955d011SMarcel Moolenaar } 23043955d011SMarcel Moolenaar 23053955d011SMarcel Moolenaar /* 23063955d011SMarcel Moolenaar * Check for overriding transformation rule implied by sources 23073955d011SMarcel Moolenaar */ 23083955d011SMarcel Moolenaar if (!Lst_IsEmpty(gn->children)) { 23093955d011SMarcel Moolenaar src = SuffFindCmds(targ, slst); 23103955d011SMarcel Moolenaar 23113955d011SMarcel Moolenaar if (src != NULL) { 23123955d011SMarcel Moolenaar /* 23133955d011SMarcel Moolenaar * Free up all the Src structures in the transformation path 23143955d011SMarcel Moolenaar * up to, but not including, the parent node. 23153955d011SMarcel Moolenaar */ 23163955d011SMarcel Moolenaar while (bottom && bottom->parent != NULL) { 23173955d011SMarcel Moolenaar if (Lst_Member(slst, bottom) == NULL) { 23183955d011SMarcel Moolenaar Lst_AtEnd(slst, bottom); 23193955d011SMarcel Moolenaar } 23203955d011SMarcel Moolenaar bottom = bottom->parent; 23213955d011SMarcel Moolenaar } 23223955d011SMarcel Moolenaar bottom = src; 23233955d011SMarcel Moolenaar } 23243955d011SMarcel Moolenaar } 23253955d011SMarcel Moolenaar 23263955d011SMarcel Moolenaar if (bottom == NULL) { 23273955d011SMarcel Moolenaar /* 23283955d011SMarcel Moolenaar * No idea from where it can come -- return now. 23293955d011SMarcel Moolenaar */ 23303955d011SMarcel Moolenaar goto sfnd_abort; 23313955d011SMarcel Moolenaar } 23323955d011SMarcel Moolenaar 23333955d011SMarcel Moolenaar /* 23343955d011SMarcel Moolenaar * We now have a list of Src structures headed by 'bottom' and linked via 23353955d011SMarcel Moolenaar * their 'parent' pointers. What we do next is create links between 23363955d011SMarcel Moolenaar * source and target nodes (which may or may not have been created) 23373955d011SMarcel Moolenaar * and set the necessary local variables in each target. The 23383955d011SMarcel Moolenaar * commands for each target are set from the commands of the 23393955d011SMarcel Moolenaar * transformation rule used to get from the src suffix to the targ 23403955d011SMarcel Moolenaar * suffix. Note that this causes the commands list of the original 23413955d011SMarcel Moolenaar * node, gn, to be replaced by the commands of the final 23423955d011SMarcel Moolenaar * transformation rule. Also, the unmade field of gn is incremented. 23433955d011SMarcel Moolenaar * Etc. 23443955d011SMarcel Moolenaar */ 23453955d011SMarcel Moolenaar if (bottom->node == NULL) { 23463955d011SMarcel Moolenaar bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); 23473955d011SMarcel Moolenaar } 23483955d011SMarcel Moolenaar 23493955d011SMarcel Moolenaar for (src = bottom; src->parent != NULL; src = src->parent) { 23503955d011SMarcel Moolenaar targ = src->parent; 23513955d011SMarcel Moolenaar 23523955d011SMarcel Moolenaar if (src->node->suffix) 23533955d011SMarcel Moolenaar src->node->suffix->refCount--; 23543955d011SMarcel Moolenaar src->node->suffix = src->suff; 23553955d011SMarcel Moolenaar src->node->suffix->refCount++; 23563955d011SMarcel Moolenaar 23573955d011SMarcel Moolenaar if (targ->node == NULL) { 23583955d011SMarcel Moolenaar targ->node = Targ_FindNode(targ->file, TARG_CREATE); 23593955d011SMarcel Moolenaar } 23603955d011SMarcel Moolenaar 23613955d011SMarcel Moolenaar SuffApplyTransform(targ->node, src->node, 23623955d011SMarcel Moolenaar targ->suff, src->suff); 23633955d011SMarcel Moolenaar 23643955d011SMarcel Moolenaar if (targ->node != gn) { 23653955d011SMarcel Moolenaar /* 23663955d011SMarcel Moolenaar * Finish off the dependency-search process for any nodes 23673955d011SMarcel Moolenaar * between bottom and gn (no point in questing around the 23683955d011SMarcel Moolenaar * filesystem for their implicit source when it's already 23693955d011SMarcel Moolenaar * known). Note that the node can't have any sources that 23703955d011SMarcel Moolenaar * need expanding, since SuffFindThem will stop on an existing 23713955d011SMarcel Moolenaar * node, so all we need to do is set the standard and System V 23723955d011SMarcel Moolenaar * variables. 23733955d011SMarcel Moolenaar */ 23743955d011SMarcel Moolenaar targ->node->type |= OP_DEPS_FOUND; 23753955d011SMarcel Moolenaar 23763955d011SMarcel Moolenaar Var_Set(PREFIX, targ->pref, targ->node, 0); 23773955d011SMarcel Moolenaar 23783955d011SMarcel Moolenaar Var_Set(TARGET, targ->node->name, targ->node, 0); 23793955d011SMarcel Moolenaar } 23803955d011SMarcel Moolenaar } 23813955d011SMarcel Moolenaar 23823955d011SMarcel Moolenaar if (gn->suffix) 23833955d011SMarcel Moolenaar gn->suffix->refCount--; 23843955d011SMarcel Moolenaar gn->suffix = src->suff; 23853955d011SMarcel Moolenaar gn->suffix->refCount++; 23863955d011SMarcel Moolenaar 23873955d011SMarcel Moolenaar /* 23883955d011SMarcel Moolenaar * Nuke the transformation path and the Src structures left over in the 23893955d011SMarcel Moolenaar * two lists. 23903955d011SMarcel Moolenaar */ 23913955d011SMarcel Moolenaar sfnd_return: 23923955d011SMarcel Moolenaar if (bottom) 23933955d011SMarcel Moolenaar if (Lst_Member(slst, bottom) == NULL) 23943955d011SMarcel Moolenaar Lst_AtEnd(slst, bottom); 23953955d011SMarcel Moolenaar 23963955d011SMarcel Moolenaar while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) 23973955d011SMarcel Moolenaar continue; 23983955d011SMarcel Moolenaar 23993955d011SMarcel Moolenaar Lst_Concat(slst, srcs, LST_CONCLINK); 24003955d011SMarcel Moolenaar Lst_Concat(slst, targs, LST_CONCLINK); 24013955d011SMarcel Moolenaar } 24023955d011SMarcel Moolenaar 24033955d011SMarcel Moolenaar 24043955d011SMarcel Moolenaar /*- 24053955d011SMarcel Moolenaar *----------------------------------------------------------------------- 24063955d011SMarcel Moolenaar * Suff_FindDeps -- 24073955d011SMarcel Moolenaar * Find implicit sources for the target described by the graph node 24083955d011SMarcel Moolenaar * gn 24093955d011SMarcel Moolenaar * 24103955d011SMarcel Moolenaar * Results: 24113955d011SMarcel Moolenaar * Nothing. 24123955d011SMarcel Moolenaar * 24133955d011SMarcel Moolenaar * Side Effects: 24143955d011SMarcel Moolenaar * Nodes are added to the graph below the passed-in node. The nodes 24153955d011SMarcel Moolenaar * are marked to have their IMPSRC variable filled in. The 24163955d011SMarcel Moolenaar * PREFIX variable is set for the given node and all its 24173955d011SMarcel Moolenaar * implied children. 24183955d011SMarcel Moolenaar * 24193955d011SMarcel Moolenaar * Notes: 24203955d011SMarcel Moolenaar * The path found by this target is the shortest path in the 24213955d011SMarcel Moolenaar * transformation graph, which may pass through non-existent targets, 24223955d011SMarcel Moolenaar * to an existing target. The search continues on all paths from the 24233955d011SMarcel Moolenaar * root suffix until a file is found. I.e. if there's a path 24243955d011SMarcel Moolenaar * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but 24253955d011SMarcel Moolenaar * the .c and .l files don't, the search will branch out in 24263955d011SMarcel Moolenaar * all directions from .o and again from all the nodes on the 24273955d011SMarcel Moolenaar * next level until the .l,v node is encountered. 24283955d011SMarcel Moolenaar * 24293955d011SMarcel Moolenaar *----------------------------------------------------------------------- 24303955d011SMarcel Moolenaar */ 24313955d011SMarcel Moolenaar 24323955d011SMarcel Moolenaar void 24333955d011SMarcel Moolenaar Suff_FindDeps(GNode *gn) 24343955d011SMarcel Moolenaar { 24353955d011SMarcel Moolenaar 24363955d011SMarcel Moolenaar SuffFindDeps(gn, srclist); 24373955d011SMarcel Moolenaar while (SuffRemoveSrc(srclist)) 24383955d011SMarcel Moolenaar continue; 24393955d011SMarcel Moolenaar } 24403955d011SMarcel Moolenaar 24413955d011SMarcel Moolenaar 24423955d011SMarcel Moolenaar /* 24433955d011SMarcel Moolenaar * Input: 24443955d011SMarcel Moolenaar * gn node we're dealing with 24453955d011SMarcel Moolenaar * 24463955d011SMarcel Moolenaar */ 24473955d011SMarcel Moolenaar static void 24483955d011SMarcel Moolenaar SuffFindDeps(GNode *gn, Lst slst) 24493955d011SMarcel Moolenaar { 24503955d011SMarcel Moolenaar if (gn->type & OP_DEPS_FOUND) { 24513955d011SMarcel Moolenaar /* 24523955d011SMarcel Moolenaar * If dependencies already found, no need to do it again... 24533955d011SMarcel Moolenaar */ 24543955d011SMarcel Moolenaar return; 24553955d011SMarcel Moolenaar } else { 24563955d011SMarcel Moolenaar gn->type |= OP_DEPS_FOUND; 24573955d011SMarcel Moolenaar } 24583955d011SMarcel Moolenaar /* 24593955d011SMarcel Moolenaar * Make sure we have these set, may get revised below. 24603955d011SMarcel Moolenaar */ 24613955d011SMarcel Moolenaar Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); 24623955d011SMarcel Moolenaar Var_Set(PREFIX, gn->name, gn, 0); 24634fc82fe4SSimon J. Gerraty 24643955d011SMarcel Moolenaar if (DEBUG(SUFF)) { 24653955d011SMarcel Moolenaar fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name); 24663955d011SMarcel Moolenaar } 24673955d011SMarcel Moolenaar 24683955d011SMarcel Moolenaar if (gn->type & OP_ARCHV) { 24693955d011SMarcel Moolenaar SuffFindArchiveDeps(gn, slst); 24703955d011SMarcel Moolenaar } else if (gn->type & OP_LIB) { 24713955d011SMarcel Moolenaar /* 24723955d011SMarcel Moolenaar * If the node is a library, it is the arch module's job to find it 24733955d011SMarcel Moolenaar * and set the TARGET variable accordingly. We merely provide the 24743955d011SMarcel Moolenaar * search path, assuming all libraries end in ".a" (if the suffix 24753955d011SMarcel Moolenaar * hasn't been defined, there's nothing we can do for it, so we just 24763955d011SMarcel Moolenaar * set the TARGET variable to the node's name in order to give it a 24773955d011SMarcel Moolenaar * value). 24783955d011SMarcel Moolenaar */ 24793955d011SMarcel Moolenaar LstNode ln; 24803955d011SMarcel Moolenaar Suff *s; 24813955d011SMarcel Moolenaar 24823955d011SMarcel Moolenaar ln = Lst_Find(sufflist, LIBSUFF, SuffSuffHasNameP); 24833955d011SMarcel Moolenaar if (gn->suffix) 24843955d011SMarcel Moolenaar gn->suffix->refCount--; 24853955d011SMarcel Moolenaar if (ln != NULL) { 24863955d011SMarcel Moolenaar gn->suffix = s = (Suff *)Lst_Datum(ln); 24873955d011SMarcel Moolenaar gn->suffix->refCount++; 24883955d011SMarcel Moolenaar Arch_FindLib(gn, s->searchPath); 24893955d011SMarcel Moolenaar } else { 24903955d011SMarcel Moolenaar gn->suffix = NULL; 24913955d011SMarcel Moolenaar Var_Set(TARGET, gn->name, gn, 0); 24923955d011SMarcel Moolenaar } 24933955d011SMarcel Moolenaar /* 24943955d011SMarcel Moolenaar * Because a library (-lfoo) target doesn't follow the standard 24953955d011SMarcel Moolenaar * filesystem conventions, we don't set the regular variables for 24963955d011SMarcel Moolenaar * the thing. .PREFIX is simply made empty... 24973955d011SMarcel Moolenaar */ 24983955d011SMarcel Moolenaar Var_Set(PREFIX, "", gn, 0); 24993955d011SMarcel Moolenaar } else { 25003955d011SMarcel Moolenaar SuffFindNormalDeps(gn, slst); 25013955d011SMarcel Moolenaar } 25023955d011SMarcel Moolenaar } 25033955d011SMarcel Moolenaar 25043955d011SMarcel Moolenaar /*- 25053955d011SMarcel Moolenaar *----------------------------------------------------------------------- 25063955d011SMarcel Moolenaar * Suff_SetNull -- 25073955d011SMarcel Moolenaar * Define which suffix is the null suffix. 25083955d011SMarcel Moolenaar * 25093955d011SMarcel Moolenaar * Input: 25103955d011SMarcel Moolenaar * name Name of null suffix 25113955d011SMarcel Moolenaar * 25123955d011SMarcel Moolenaar * Results: 25133955d011SMarcel Moolenaar * None. 25143955d011SMarcel Moolenaar * 25153955d011SMarcel Moolenaar * Side Effects: 25163955d011SMarcel Moolenaar * 'suffNull' is altered. 25173955d011SMarcel Moolenaar * 25183955d011SMarcel Moolenaar * Notes: 25193955d011SMarcel Moolenaar * Need to handle the changing of the null suffix gracefully so the 25203955d011SMarcel Moolenaar * old transformation rules don't just go away. 25213955d011SMarcel Moolenaar * 25223955d011SMarcel Moolenaar *----------------------------------------------------------------------- 25233955d011SMarcel Moolenaar */ 25243955d011SMarcel Moolenaar void 25253955d011SMarcel Moolenaar Suff_SetNull(char *name) 25263955d011SMarcel Moolenaar { 25273955d011SMarcel Moolenaar Suff *s; 25283955d011SMarcel Moolenaar LstNode ln; 25293955d011SMarcel Moolenaar 25303955d011SMarcel Moolenaar ln = Lst_Find(sufflist, name, SuffSuffHasNameP); 25313955d011SMarcel Moolenaar if (ln != NULL) { 25323955d011SMarcel Moolenaar s = (Suff *)Lst_Datum(ln); 25333955d011SMarcel Moolenaar if (suffNull != NULL) { 25343955d011SMarcel Moolenaar suffNull->flags &= ~SUFF_NULL; 25353955d011SMarcel Moolenaar } 25363955d011SMarcel Moolenaar s->flags |= SUFF_NULL; 25373955d011SMarcel Moolenaar /* 25383955d011SMarcel Moolenaar * XXX: Here's where the transformation mangling would take place 25393955d011SMarcel Moolenaar */ 25403955d011SMarcel Moolenaar suffNull = s; 25413955d011SMarcel Moolenaar } else { 25423955d011SMarcel Moolenaar Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.", 25433955d011SMarcel Moolenaar name); 25443955d011SMarcel Moolenaar } 25453955d011SMarcel Moolenaar } 25463955d011SMarcel Moolenaar 25473955d011SMarcel Moolenaar /*- 25483955d011SMarcel Moolenaar *----------------------------------------------------------------------- 25493955d011SMarcel Moolenaar * Suff_Init -- 25503955d011SMarcel Moolenaar * Initialize suffixes module 25513955d011SMarcel Moolenaar * 25523955d011SMarcel Moolenaar * Results: 25533955d011SMarcel Moolenaar * None 25543955d011SMarcel Moolenaar * 25553955d011SMarcel Moolenaar * Side Effects: 25563955d011SMarcel Moolenaar * Many 25573955d011SMarcel Moolenaar *----------------------------------------------------------------------- 25583955d011SMarcel Moolenaar */ 25593955d011SMarcel Moolenaar void 25603955d011SMarcel Moolenaar Suff_Init(void) 25613955d011SMarcel Moolenaar { 25623955d011SMarcel Moolenaar #ifdef CLEANUP 25633955d011SMarcel Moolenaar suffClean = Lst_Init(FALSE); 25643955d011SMarcel Moolenaar #endif 25653955d011SMarcel Moolenaar srclist = Lst_Init(FALSE); 25663955d011SMarcel Moolenaar transforms = Lst_Init(FALSE); 25673955d011SMarcel Moolenaar 25683955d011SMarcel Moolenaar /* 25693955d011SMarcel Moolenaar * Create null suffix for single-suffix rules (POSIX). The thing doesn't 25703955d011SMarcel Moolenaar * actually go on the suffix list or everyone will think that's its 25713955d011SMarcel Moolenaar * suffix. 25723955d011SMarcel Moolenaar */ 25736e050540SSimon J. Gerraty Suff_ClearSuffixes(); 25743955d011SMarcel Moolenaar } 25753955d011SMarcel Moolenaar 25763955d011SMarcel Moolenaar 25773955d011SMarcel Moolenaar /*- 25783955d011SMarcel Moolenaar *---------------------------------------------------------------------- 25793955d011SMarcel Moolenaar * Suff_End -- 25803955d011SMarcel Moolenaar * Cleanup the this module 25813955d011SMarcel Moolenaar * 25823955d011SMarcel Moolenaar * Results: 25833955d011SMarcel Moolenaar * None 25843955d011SMarcel Moolenaar * 25853955d011SMarcel Moolenaar * Side Effects: 25863955d011SMarcel Moolenaar * The memory is free'd. 25873955d011SMarcel Moolenaar *---------------------------------------------------------------------- 25883955d011SMarcel Moolenaar */ 25893955d011SMarcel Moolenaar 25903955d011SMarcel Moolenaar void 25913955d011SMarcel Moolenaar Suff_End(void) 25923955d011SMarcel Moolenaar { 25933955d011SMarcel Moolenaar #ifdef CLEANUP 25943955d011SMarcel Moolenaar Lst_Destroy(sufflist, SuffFree); 25953955d011SMarcel Moolenaar Lst_Destroy(suffClean, SuffFree); 25963955d011SMarcel Moolenaar if (suffNull) 25973955d011SMarcel Moolenaar SuffFree(suffNull); 25983955d011SMarcel Moolenaar Lst_Destroy(srclist, NULL); 25993955d011SMarcel Moolenaar Lst_Destroy(transforms, NULL); 26003955d011SMarcel Moolenaar #endif 26013955d011SMarcel Moolenaar } 26023955d011SMarcel Moolenaar 26033955d011SMarcel Moolenaar 26043955d011SMarcel Moolenaar /********************* DEBUGGING FUNCTIONS **********************/ 26053955d011SMarcel Moolenaar 2606*e1cee40dSSimon J. Gerraty static int SuffPrintName(void *s, void *dummy MAKE_ATTR_UNUSED) 26073955d011SMarcel Moolenaar { 260895e3ed2cSSimon J. Gerraty 26093955d011SMarcel Moolenaar fprintf(debug_file, "%s ", ((Suff *)s)->name); 261095e3ed2cSSimon J. Gerraty return 0; 26113955d011SMarcel Moolenaar } 26123955d011SMarcel Moolenaar 26133955d011SMarcel Moolenaar static int 2614*e1cee40dSSimon J. Gerraty SuffPrintSuff(void *sp, void *dummy MAKE_ATTR_UNUSED) 26153955d011SMarcel Moolenaar { 26163955d011SMarcel Moolenaar Suff *s = (Suff *)sp; 26173955d011SMarcel Moolenaar int flags; 26183955d011SMarcel Moolenaar int flag; 26193955d011SMarcel Moolenaar 26203955d011SMarcel Moolenaar fprintf(debug_file, "# `%s' [%d] ", s->name, s->refCount); 26213955d011SMarcel Moolenaar 26223955d011SMarcel Moolenaar flags = s->flags; 26233955d011SMarcel Moolenaar if (flags) { 26243955d011SMarcel Moolenaar fputs(" (", debug_file); 26253955d011SMarcel Moolenaar while (flags) { 26263955d011SMarcel Moolenaar flag = 1 << (ffs(flags) - 1); 26273955d011SMarcel Moolenaar flags &= ~flag; 26283955d011SMarcel Moolenaar switch (flag) { 26293955d011SMarcel Moolenaar case SUFF_NULL: 26303955d011SMarcel Moolenaar fprintf(debug_file, "NULL"); 26313955d011SMarcel Moolenaar break; 26323955d011SMarcel Moolenaar case SUFF_INCLUDE: 26333955d011SMarcel Moolenaar fprintf(debug_file, "INCLUDE"); 26343955d011SMarcel Moolenaar break; 26353955d011SMarcel Moolenaar case SUFF_LIBRARY: 26363955d011SMarcel Moolenaar fprintf(debug_file, "LIBRARY"); 26373955d011SMarcel Moolenaar break; 26383955d011SMarcel Moolenaar } 26393955d011SMarcel Moolenaar fputc(flags ? '|' : ')', debug_file); 26403955d011SMarcel Moolenaar } 26413955d011SMarcel Moolenaar } 26423955d011SMarcel Moolenaar fputc('\n', debug_file); 26433955d011SMarcel Moolenaar fprintf(debug_file, "#\tTo: "); 26443955d011SMarcel Moolenaar Lst_ForEach(s->parents, SuffPrintName, NULL); 26453955d011SMarcel Moolenaar fputc('\n', debug_file); 26463955d011SMarcel Moolenaar fprintf(debug_file, "#\tFrom: "); 26473955d011SMarcel Moolenaar Lst_ForEach(s->children, SuffPrintName, NULL); 26483955d011SMarcel Moolenaar fputc('\n', debug_file); 26493955d011SMarcel Moolenaar fprintf(debug_file, "#\tSearch Path: "); 26503955d011SMarcel Moolenaar Dir_PrintPath(s->searchPath); 26513955d011SMarcel Moolenaar fputc('\n', debug_file); 265295e3ed2cSSimon J. Gerraty return 0; 26533955d011SMarcel Moolenaar } 26543955d011SMarcel Moolenaar 26553955d011SMarcel Moolenaar static int 2656*e1cee40dSSimon J. Gerraty SuffPrintTrans(void *tp, void *dummy MAKE_ATTR_UNUSED) 26573955d011SMarcel Moolenaar { 26583955d011SMarcel Moolenaar GNode *t = (GNode *)tp; 26593955d011SMarcel Moolenaar 26603955d011SMarcel Moolenaar fprintf(debug_file, "%-16s: ", t->name); 26613955d011SMarcel Moolenaar Targ_PrintType(t->type); 26623955d011SMarcel Moolenaar fputc('\n', debug_file); 26633955d011SMarcel Moolenaar Lst_ForEach(t->commands, Targ_PrintCmd, NULL); 26643955d011SMarcel Moolenaar fputc('\n', debug_file); 266595e3ed2cSSimon J. Gerraty return 0; 26663955d011SMarcel Moolenaar } 26673955d011SMarcel Moolenaar 26683955d011SMarcel Moolenaar void 26693955d011SMarcel Moolenaar Suff_PrintAll(void) 26703955d011SMarcel Moolenaar { 26713955d011SMarcel Moolenaar fprintf(debug_file, "#*** Suffixes:\n"); 26723955d011SMarcel Moolenaar Lst_ForEach(sufflist, SuffPrintSuff, NULL); 26733955d011SMarcel Moolenaar 26743955d011SMarcel Moolenaar fprintf(debug_file, "#*** Transformations:\n"); 26753955d011SMarcel Moolenaar Lst_ForEach(transforms, SuffPrintTrans, NULL); 26763955d011SMarcel Moolenaar } 2677