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