suff.c revision 1.72       1 /*	$NetBSD: suff.c,v 1.72 2014/08/27 08:50:38 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, 1989, 1990, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Adam de Boor.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 /*
     36  * Copyright (c) 1989 by Berkeley Softworks
     37  * All rights reserved.
     38  *
     39  * This code is derived from software contributed to Berkeley by
     40  * Adam de Boor.
     41  *
     42  * Redistribution and use in source and binary forms, with or without
     43  * modification, are permitted provided that the following conditions
     44  * are met:
     45  * 1. Redistributions of source code must retain the above copyright
     46  *    notice, this list of conditions and the following disclaimer.
     47  * 2. Redistributions in binary form must reproduce the above copyright
     48  *    notice, this list of conditions and the following disclaimer in the
     49  *    documentation and/or other materials provided with the distribution.
     50  * 3. All advertising materials mentioning features or use of this software
     51  *    must display the following acknowledgement:
     52  *	This product includes software developed by the University of
     53  *	California, Berkeley and its contributors.
     54  * 4. Neither the name of the University nor the names of its contributors
     55  *    may be used to endorse or promote products derived from this software
     56  *    without specific prior written permission.
     57  *
     58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  * SUCH DAMAGE.
     69  */
     70 
     71 #ifndef MAKE_NATIVE
     72 static char rcsid[] = "$NetBSD: suff.c,v 1.72 2014/08/27 08:50:38 christos Exp $";
     73 #else
     74 #include <sys/cdefs.h>
     75 #ifndef lint
     76 #if 0
     77 static char sccsid[] = "@(#)suff.c	8.4 (Berkeley) 3/21/94";
     78 #else
     79 __RCSID("$NetBSD: suff.c,v 1.72 2014/08/27 08:50:38 christos Exp $");
     80 #endif
     81 #endif /* not lint */
     82 #endif
     83 
     84 /*-
     85  * suff.c --
     86  *	Functions to maintain suffix lists and find implicit dependents
     87  *	using suffix transformation rules
     88  *
     89  * Interface:
     90  *	Suff_Init 	    	Initialize all things to do with suffixes.
     91  *
     92  *	Suff_End 	    	Clean up the module.  Must be called after
     93  *				Targ_End() so suffix references in nodes
     94  *				have been dealt with.
     95  *
     96  *	Suff_UnsetSuffix	Helper for Targ_End() to unset node's suffix
     97  *				so as to not mess up reference counting.
     98  *
     99  *	Suff_DoPaths	    	This function is used to make life easier
    100  *	    	  	    	when searching for a file according to its
    101  *	    	  	    	suffix. It takes the global search path,
    102  *	    	  	    	as defined using the .PATH: target, and appends
    103  *	    	  	    	its directories to the path of each of the
    104  *	    	  	    	defined suffixes, as specified using
    105  *	    	  	    	.PATH<suffix>: targets. In addition, all
    106  *	    	  	    	directories given for suffixes labeled as
    107  *	    	  	    	include files or libraries, using the .INCLUDES
    108  *	    	  	    	or .LIBS targets, are played with using
    109  *	    	  	    	Dir_MakeFlags to create the .INCLUDES and
    110  *	    	  	    	.LIBS global variables.
    111  *
    112  *	Suff_ClearSuffixes  	Clear out all the suffixes and defined
    113  *	    	  	    	transformations.
    114  *
    115  *	Suff_IsTransform    	Return TRUE if the passed string is the lhs
    116  *	    	  	    	of a transformation rule.
    117  *
    118  *	Suff_AddSuffix	    	Add the passed string as another known suffix.
    119  *
    120  *	Suff_GetPath	    	Return the search path for the given suffix.
    121  *
    122  *	Suff_AddInclude	    	Mark the given suffix as denoting an include
    123  *	    	  	    	file.
    124  *
    125  *	Suff_AddLib	    	Mark the given suffix as denoting a library.
    126  *
    127  *	Suff_AddTransform   	Add another transformation to the suffix
    128  *	    	  	    	graph. Returns  GNode suitable for framing, I
    129  *	    	  	    	mean, tacking commands, attributes, etc. on.
    130  *
    131  *	Suff_FindDeps	    	Find implicit sources for and the location of
    132  *	    	  	    	a target based on its suffix. Returns the
    133  *	    	  	    	bottom-most node added to the graph or NULL
    134  *	    	  	    	if the target had no implicit sources.
    135  *
    136  *	Suff_FindPath	    	Return the appropriate path to search in
    137  *				order to find the node.
    138  */
    139 
    140 #include	  <assert.h>
    141 #include	  <limits.h>
    142 #include	  <stdarg.h>
    143 #include    	  <stdio.h>
    144 #include	  "make.h"
    145 #include	  "hash.h"
    146 #include	  "dir.h"
    147 
    148 /*
    149  * Currently known suffixes:
    150  * All currently known suffixes are stored in sufflist (data: Suff *) and
    151  * the next suffix added will get sNum as its suffix number (incremented
    152  * after each use).   Lookup is used as a lookup table for quick rejection,
    153  * when it needs to be known if a string matches a known suffix.  All indexes
    154  * corresponding to the first character of a suffix in sufflist are true
    155  * and others are false.
    156  */
    157 static int	sNum = 0;
    158 static Lst	sufflist;
    159 #define LOOKUP_SIZE 256
    160 static int	lookup[LOOKUP_SIZE] = { 0 };
    161 
    162 /*
    163  * Currently known transformations:
    164  * References to nodes of currently active transformation rules (i.e. all
    165  * which have OP_TRANSFORM set).  It is used to remove the need to iterate
    166  * through all targets when a transformation node needs to be accessed.
    167  * (data: GNode *)
    168  */
    169 static Lst       transforms;
    170 
    171 /*
    172  * Structure describing an individual suffix.
    173  *
    174  * When a target has a known suffix, a reference is stored in the suffix
    175  * field of its node.  The same field is also used in OP_TRANSFORM nodes to
    176  * store the /target/ of the transformation.  This enables SuffScanTargets()
    177  * to recognize single suffix transformations by the fact that the field
    178  * references emptySuff.  This also happens to be the known suffix of
    179  * the field if the node is used as a regular target.
    180  *
    181  * Use the provided maintenance functions for creating, destroying and moving
    182  * these around to keep the reference counts in order.  The suffix will be
    183  * free'd when the count reaches zero.
    184  *
    185  * The SUFF_NULL type flag is required for SuffAddLevelForSuffix() to
    186  * detect when a suffix is used as a regular suffix and when as the .NULL
    187  * suffix.  This is achieved by only setting it for the duration of
    188  * the call when the "remove a suffix" aspect of .NULL is used.  When
    189  * the .NULL feature is used in its "add a suffix" aspect, the transformation
    190  * from a suffixless file is added after the regular transformation by
    191  * SuffNewChildSrc() when a suffix == nullSuff is used.
    192  */
    193 typedef struct _Suff {
    194     char	*name;		/* The suffix itself (e.g. ".c") */
    195     size_t	nameLen;	/* Length of the suffix */
    196 
    197     short	flags;		/* Filetype implied by the suffix (bitfield) */
    198 #define SUFF_INCLUDE	  0x01		/* One which is #include'd.
    199 					 * XXX: Not used?  Remove? */
    200 #define SUFF_LIBRARY	  0x02		/* ar(1) archive */
    201 #define SUFF_NULL	  0x04		/* The .NULL suffix */
    202 
    203     Lst		searchPath;	/* The path along which files of this suffix
    204 				 * may be found */
    205 
    206     /*
    207      * The suffix number.  Unique for each suffix.  Doubles as suffix
    208      * priority, i.e. shows the relative .SUFFIXES ordering of suffixes:
    209      * smaller sNums are earlier in the list.
    210      */
    211     int		sNum;
    212 
    213     /*
    214      * Reference count.  Counted references are: membership in sufflist,
    215      * membership in parents or children list of another suffix, assignment
    216      * to GNode->suffix, assignment as emptySuff, and assignment as nullSuff.
    217      */
    218     int		refCount;
    219 
    220     /*
    221      * Suffixes we have a transformation to (parents) and from (children).
    222      * Kept in .SUFFIXES order, as implied by sNum (data: Suff *)
    223      * XXX: renaming these to "to" and "from" or "targets" and "sources"
    224      * could make sense as parents and children on a suffix are not very
    225      * intuitive.
    226      */
    227     Lst		parents;
    228     Lst		children;
    229 
    230 #ifdef DEBUG_SRC
    231     /*
    232      * Lists this suffix is referenced in.  Contains sufflist for all but
    233      * emptySuff, parents list of all suffixes referenced in own children
    234      * list, and children list of all suffixes referenced in own parents
    235      * list.  (data: Lst)
    236      */
    237     Lst		ref;
    238 #endif
    239 } Suff;
    240 
    241 /*
    242  * for SuffSuffIsSuffix
    243  */
    244 typedef struct {
    245     char	*ename;		/* The end of the name (the final '\0') */
    246     size_t	len;		/* The length of the name */
    247 } SuffixCmpData;
    248 
    249 /*
    250  * Structure used in the search for implied sources.
    251  */
    252 typedef struct _Src {
    253     char            *file;	/* The file to look for */
    254 
    255     /*
    256      * Prefix from which file was formed.  In an effort to reduce
    257      * unnecessary memory allocations, only those with parent != NULL
    258      * own their pref, others refer to their parents'.
    259      */
    260     char    	    *pref;
    261 
    262     Suff            *suff;	/* The suffix on the file */
    263     struct _Src     *parent;	/* The Src for which this is a source */
    264     GNode           *node;	/* The node describing the file */
    265 
    266     /*
    267      * Steps to top of chain.  Used in debug prints to show chain length
    268      * with indentation so multi-stage transformations are more readable.
    269      */
    270     int		    depth;
    271 } Src;
    272 
    273 /* Extra arguments to SuffAddSrc() via Lst_ForEach(). */
    274 typedef struct {
    275     Src	*target;	/* get possible transformations for this target */
    276     Lst	possible;	/* list of possible transformation not yet tried */
    277     Lst	cleanup;	/* list of all transformations created (for freeing) */
    278 } LstSrc;
    279 
    280 /*
    281  * Empty suffix for implementing POSIX single-suffix transformation rules.
    282  * It won't go in sufflist lest all targets consider it as their suffix.
    283  * Also, single suffix rules must only be checked if the target does not
    284  * have a known suffix.  This suffix is always the first one created, but
    285  * its sNum field is forced to INT_MAX to keep it in its proper place
    286  * at the end of the parents list of any of its children.  (Hopefully no one
    287  * will create that many suffixes)
    288  */
    289 static Suff 	    *emptySuff = NULL;
    290 
    291 /*
    292  * XXX: replace this ugly hack of a feature with pattern rules!
    293  */
    294 static Suff	    *nullSuff = NULL;
    295 
    296 /* Flags for SuffCleanUp() */
    297 #define SCU_CLEAR	(1 << 1)	/* called from Suff_ClearSuffixes() */
    298 #define SCU_END		(1 << 2)	/* called from Suff_End() */
    299 /* Flags for SuffApplyTransformation*() */
    300 #define SAT_REGULAR	(1 << 0)	/* Standard behavior */
    301 #define SAT_NO_EXPAND	(1 << 1)	/* Don't expand children of top node */
    302 
    303 /* Definitions (and map) for local functions. */
    304 
    305 /* Lst Predicates */
    306 static const char *SuffStrIsPrefix(const char *, const char *);
    307 static char *SuffSuffIsSuffix(const Suff *, const SuffixCmpData *);
    308 static int SuffSuffIsSuffixP(const void *, const void *);
    309 static int SuffSuffHasNameP(const void *, const void *);
    310 static int SuffSuffIsPrefixP(const void *, const void *);
    311 static int SuffGNHasNameP(const void *, const void *);
    312 static int SuffSuffHasPriorityLEP(const void *, const void *);
    313 
    314 /* Maintenance Functions */
    315 static Suff *SuffNewSuff(const char *);
    316 static void SuffFreeSuff(Suff *);
    317 static Src *SuffNewSrc(char *, char *, Suff *, GNode *, Src *);
    318 static Src *SuffNewTopSrc(GNode *, Suff *);
    319 static Src *SuffNewChildSrc(Src *, Suff *, Src **);
    320 static void SuffFreeSrc(void *);
    321 static void SuffLinkSuffixes(Suff *, Suff *);
    322 static int SuffUnlinkSuffixes(void *f, void *t);
    323 static void SuffSetSuffix(GNode *, Suff *);
    324 static void Suff_UnsetSuffix(GNode *);
    325 static void SuffAddToList(Suff *, Lst, LstNode);
    326 static void SuffRemoveFromList(Suff *, Lst);
    327 static void SuffInsertIntoList(Suff *, Lst);
    328 static void SuffUnsetOpTransform(void *);
    329 static int SuffUnlinkChildren(void *, void *);
    330 static void SuffFreeSuffSufflist(void *);
    331 static void SuffCleanUp(int);
    332 
    333 /* Parsing Helpers */
    334 /* Suff_ClearSuffixes */
    335 static Boolean SuffParseTransform(char *, Suff **, Suff **);
    336 /* Suff_IsTransform */
    337 /* Suff_AddTransform */
    338 /* Suff_EndTransform */
    339 static int SuffScanTargets(void *, void *);
    340 /* Suff_AddSuffix */
    341 /* Suff_GetPath */
    342 /* Suff_DoPaths */
    343 /* Suff_AddInclude */
    344 /* Suff_AddLib */
    345 
    346 /* Implicit Source Search Functions */
    347 static int SuffAddSrc(void *, void *);
    348 static void SuffAddLevel(Lst, Src *, Lst);
    349 static Src *SuffFindThem(Lst, Lst);
    350 static void SuffExpandChildren(GNode *, LstNode);
    351 static void SuffExpandChild(LstNode, GNode *);
    352 static void SuffExpandWildcards(LstNode, GNode *);
    353 /* Suff_FindPath */
    354 static Suff *SuffApplyTransformations(Src *, GNode *);
    355 static Boolean SuffApplyTransformation(GNode *, GNode *, Suff *, Suff *, int);
    356 static Suff *SuffFirstKnownSuffix(char* name);
    357 static void SuffSetPrefixLocalVar(Suff *suffix, char *name, GNode *node);
    358 static void SuffFindArchiveDeps(GNode *, Lst);
    359 static void SuffFindNormalDeps(GNode *, Lst);
    360 /* Suff_FindDeps */
    361 /* Suff_SetNull */
    362 /* Suff_Init */
    363 /* Suff_End */
    364 
    365 /* Debugging Functions */
    366 static int SuffDebug(const char *,...) MAKE_ATTR_PRINTFLIKE(1, 2);
    367 static void SuffDebugChain(Src *);
    368 static int SuffPrintName(void *, void *);
    369 static int SuffPrintSuff(void *, void *);
    370 static int SuffPrintTrans(void *, void *);
    371 
    372 
    373 /*
    374  ******************************************************************************
    375  *			Lst Predicates
    376  ******************************************************************************
    377  */
    378 
    379 /*-
    380  *-----------------------------------------------------------------------
    381  * SuffStrIsPrefix  --
    382  *	See if pref is a prefix of str.
    383  *
    384  * Input:
    385  *	pref		possible prefix
    386  *	str		string to check
    387  *
    388  * Results:
    389  *	NULL if it ain't, pointer to character in str after prefix if so
    390  *
    391  * Side Effects:
    392  *	None
    393  *-----------------------------------------------------------------------
    394  */
    395 static const char *
    396 SuffStrIsPrefix(const char *pref, const char *str)
    397 {
    398     while (*str && *pref == *str) {
    399 	pref++;
    400 	str++;
    401     }
    402 
    403     return (*pref ? NULL : str);
    404 }
    405 
    406 /*-
    407  *-----------------------------------------------------------------------
    408  * SuffSuffIsSuffix  --
    409  *	See if suff is a suffix of str. sd->ename should point to THE END
    410  *	of the string to check. (THE END == the null byte)
    411  *
    412  * Input:
    413  *	s		possible suffix
    414  *	sd		string to examine
    415  *
    416  * Results:
    417  *	NULL if it ain't, pointer to character in str before suffix if
    418  *	it is.
    419  *
    420  * Side Effects:
    421  *	None
    422  *-----------------------------------------------------------------------
    423  */
    424 static char *
    425 SuffSuffIsSuffix(const Suff *s, const SuffixCmpData *sd)
    426 {
    427     char  *p1;	    	/* Pointer into suffix name */
    428     char  *p2;	    	/* Pointer into string being examined */
    429 
    430     if (sd->len < s->nameLen)
    431 	return NULL;		/* this string is shorter than the suffix */
    432 
    433     p1 = s->name + s->nameLen;
    434     p2 = sd->ename;
    435 
    436     while (p1 >= s->name && *p1 == *p2) {
    437 	p1--;
    438 	p2--;
    439     }
    440 
    441     return (p1 == s->name - 1 ? p2 : NULL);
    442 }
    443 
    444 /*-
    445  *-----------------------------------------------------------------------
    446  * SuffSuffIsSuffixP --
    447  *	Predicate form of SuffSuffIsSuffix. Passed as the callback function
    448  *	to Lst_Find.
    449  *
    450  * Results:
    451  *	0 if the suffix is the one desired, non-zero if not.
    452  *
    453  * Side Effects:
    454  *	None.
    455  *
    456  *-----------------------------------------------------------------------
    457  */
    458 static int
    459 SuffSuffIsSuffixP(const void *s, const void *sd)
    460 {
    461     return(!SuffSuffIsSuffix(s, sd));
    462 }
    463 
    464 /*-
    465  *-----------------------------------------------------------------------
    466  * SuffSuffHasNameP --
    467  *	Callback procedure for finding a suffix based on its name. Used by
    468  *	Suff_GetPath.
    469  *
    470  * Input:
    471  *	s		Suffix to check
    472  *	sd		Desired name
    473  *
    474  * Results:
    475  *	0 if the suffix is of the given name. non-zero otherwise.
    476  *
    477  * Side Effects:
    478  *	None
    479  *-----------------------------------------------------------------------
    480  */
    481 static int
    482 SuffSuffHasNameP(const void *s, const void *sname)
    483 {
    484     return (strcmp(sname, ((const Suff *)s)->name));
    485 }
    486 
    487 /*-
    488  *-----------------------------------------------------------------------
    489  * SuffSuffIsPrefixP -- see if str starts with s->name.
    490  *
    491  *	Care must be taken when using this to search for transformations and
    492  *	what-not, since there could well be two suffixes, one of which
    493  *	is a prefix of the other...
    494  *
    495  * Input:
    496  *	s		suffix to compare
    497  *	str		string to examine
    498  *
    499  * Results:
    500  *	0 if s is a prefix of str. non-zero otherwise
    501  *
    502  * Side Effects:
    503  *	None
    504  *-----------------------------------------------------------------------
    505  */
    506 static int
    507 SuffSuffIsPrefixP(const void *s, const void *str)
    508 {
    509     return SuffStrIsPrefix(((const Suff *)s)->name, str) == NULL;
    510 }
    511 
    512 /*-
    513  *-----------------------------------------------------------------------
    514  * SuffGNHasNameP  --
    515  *	See if the graph node has the desired name
    516  *
    517  * Input:
    518  *	gn		current node we're looking at
    519  *	name		name we're looking for
    520  *
    521  * Results:
    522  *	0 if it does. non-zero if it doesn't
    523  *
    524  * Side Effects:
    525  *	None
    526  *-----------------------------------------------------------------------
    527  */
    528 static int
    529 SuffGNHasNameP(const void *gn, const void *name)
    530 {
    531     return (strcmp(name, ((const GNode *)gn)->name));
    532 }
    533 
    534 /*-
    535  *-----------------------------------------------------------------------
    536  * SuffSuffHasPriorityLEP -- (Less Than or Equal To [Predicate])
    537  *
    538  * Check if the second suffix should preceed the first one.  This is
    539  * a predicate function for Lst_Find(), used by SuffInsertIntoList()
    540  * for finding the insertion position of the new suffix.
    541  *
    542  * Input:
    543  * 	first	The first suffix. (Suff *)
    544  * 	second	The second suffix. (Suff *)
    545  *
    546  * Returns:
    547  * 	Return 0 if the first suffix has a priority less than or
    548  * 	equal to the second one, i.e. the second one preceeds the first
    549  * 	one in the .SUFFIXES list or they are in fact the same suffix.
    550  * 	Otherwise non-zero is returned.
    551  *-----------------------------------------------------------------------
    552  */
    553 static int
    554 SuffSuffHasPriorityLEP(const void *first, const void* second)
    555 {
    556     return !(((const Suff *)first)->sNum >= ((const Suff *)second)->sNum);
    557 }
    558 
    559 
    560 /*
    561  ******************************************************************************
    562  *			Maintenance Functions
    563  ******************************************************************************
    564  */
    565 
    566 /*
    567  *-----------------------------------------------------------------------
    568  * SuffNewSuff -- allocate and initialize a Suff structure.
    569  *
    570  * The contained lists are initialized and empty.  No flags are set and
    571  * the reference count is zero.  The next serial number is allocated
    572  * for this struct.
    573  *
    574  * Input:
    575  * 	name	The suffix this structure describes (e.g. ".c").  A copy
    576  * 		is made of this string.
    577  *
    578  * Results:
    579  * 	The allocated and initialized structure.
    580  *-----------------------------------------------------------------------
    581  */
    582 static Suff*
    583 SuffNewSuff(const char* name)
    584 {
    585     Suff *s = bmake_malloc(sizeof(Suff));
    586 
    587     s->name =		bmake_strdup(name);
    588     s->nameLen =	strlen(name);
    589     s->flags =		(strcmp(name, LIBSUFF) == 0 ? SUFF_LIBRARY : 0);
    590     s->searchPath =	Lst_Init(FALSE);
    591     s->sNum =		sNum++;
    592     s->refCount =	0;
    593     s->children =	Lst_Init(FALSE);
    594     s->parents =	Lst_Init(FALSE);
    595 #ifdef DEBUG_SRC
    596     s->ref =		Lst_Init(FALSE);
    597 #endif
    598 
    599     return s;
    600 }
    601 
    602 /*
    603  *-----------------------------------------------------------------------
    604  * SuffFreeSuff -- release resources held by a Suff structure.
    605  *
    606  * There are no other resources than memory, which is free'd.
    607  *
    608  * Input:
    609  * 	s	the struct to free
    610  *-----------------------------------------------------------------------
    611  */
    612 static void
    613 SuffFreeSuff(Suff *s)
    614 {
    615     /* Make reference counting bugs unpleasantly obvious. */
    616     if (s->refCount != 0)
    617 	Punt("Internal error deleting suffix `%s' with reference count %d",
    618 	    s->name, s->refCount);
    619 
    620     free(s->name);
    621     Lst_Destroy(s->searchPath, Dir_Destroy);
    622     Lst_Destroy(s->parents, NULL);
    623     Lst_Destroy(s->children, NULL);
    624 #ifdef DEBUG_SRC
    625     Lst_Destroy(s->ref, NULL);
    626 #endif
    627     free(s);
    628 }
    629 
    630 /*-
    631  *-----------------------------------------------------------------------
    632  * SuffNewSrc -- allocate and initialize a new Src structure.
    633  *
    634  * The depth field is set to 0 if parent is NULL and to parent->depth + 1
    635  * otherwise.
    636  *
    637  * You probably want to use the convenience functions SuffNewTopSrc() and
    638  * SuffNewChildSrc().  These convenience functions take the relevant
    639  * information from their parameters, making copies as needed.
    640  *
    641  * Input:
    642  *	file, pref, suffix, node, parent
    643  *		Contents of the corresponding fields.  No copies are
    644  *		made, they are used as they are!
    645  *
    646  * Results:
    647  *	The allocated and initialized structure.
    648  *-----------------------------------------------------------------------
    649  */
    650 static Src*
    651 SuffNewSrc(char* file, char* pref, Suff *suffix, GNode *node, Src *parent)
    652 {
    653     Src *s = bmake_malloc(sizeof(Src));
    654 
    655     s->file = file;
    656     s->pref = pref;
    657 
    658     s->suff = suffix;
    659 
    660     s->parent = parent;
    661     s->depth =	0;
    662     if (parent != NULL)
    663 	s->depth = parent->depth + 1;
    664 
    665     s->node = node;
    666 
    667     return s;
    668 }
    669 
    670 /*-
    671  *-----------------------------------------------------------------------
    672  * SuffNewTopSrc -- create a new Src for node->name, using suffix.
    673  *-----------------------------------------------------------------------
    674  */
    675 static Src*
    676 SuffNewTopSrc(GNode *node, Suff *suffix)
    677 {
    678     return SuffNewSrc(
    679 	bmake_strdup(node->name),
    680 	bmake_strndup(node->name, strlen(node->name) - suffix->nameLen),
    681 	suffix,
    682 	node,
    683 	NULL);
    684 }
    685 
    686 /*-
    687  *-----------------------------------------------------------------------
    688  * SuffNewTopSrc -- create a new Src for node->name, faking suffix as "".
    689  *-----------------------------------------------------------------------
    690  */
    691 static Src*
    692 SuffNewTopSrcNull(GNode *node, Suff *suffix)
    693 {
    694     return SuffNewSrc(
    695 	bmake_strdup(node->name),
    696 	bmake_strdup(node->name),
    697 	suffix,
    698 	node,
    699 	NULL);
    700 }
    701 
    702 /*-
    703  *-----------------------------------------------------------------------
    704  * SuffNewChildSrc -- create a new Src for (parent->pref + suffix->name).
    705  *
    706  * Input:
    707  *	nullChild	for storing the .NULL child
    708  *
    709  * Side Effects:
    710  *	If suffix == nullSuff, a possible source is created for parent->pref
    711  *	also and stored into nullChild.  Otherwise nullChild is set to NULL.
    712  *-----------------------------------------------------------------------
    713  */
    714 static Src*
    715 SuffNewChildSrc(Src *parent, Suff *suffix, Src **nullChild)
    716 {
    717     if (suffix == nullSuff)
    718 	*nullChild = SuffNewSrc(
    719 	    bmake_strdup(parent->pref),
    720 	    parent->pref,
    721 	    suffix,
    722 	    NULL,
    723 	    parent);
    724     else
    725 	*nullChild = NULL;
    726 
    727     return SuffNewSrc(
    728 	str_concat(parent->pref, suffix->name, 0),
    729 	parent->pref,
    730 	suffix,
    731 	NULL,
    732 	parent);
    733 }
    734 
    735 /*
    736  *-----------------------------------------------------------------------
    737  * SuffFreeSrc -- release resources held by an Src structure.
    738  *
    739  * There are no other resources than memory, which is free'd.  The signature
    740  * is chosen so as to be able to call this from Lst_Destroy().
    741  *
    742  * Input:
    743  * 	sp	the struct to free
    744  *-----------------------------------------------------------------------
    745  */
    746 static void
    747 SuffFreeSrc(void *sp)
    748 {
    749     Src *s = (Src *)sp;
    750 
    751     free(s->file);
    752     if (s->parent == NULL)
    753 	free(s->pref);
    754     free(s);
    755 }
    756 
    757 /*-
    758  *-----------------------------------------------------------------------
    759  * SuffLinkSuffixes -- relate two suffixes.
    760  *
    761  * Makes "from" aware that "to" is a possible target and "to" aware that
    762  * "from" is a possible source.  Proper .SUFFIXES ordering is maintained.
    763  *
    764  * Pre-condition:
    765  *	The suffixes are not already linked.
    766  *
    767  * Input:
    768  * 	from	source file suffix
    769  * 	to	target file suffix
    770  *-----------------------------------------------------------------------
    771  */
    772 static void
    773 SuffLinkSuffixes(Suff *from, Suff *to)
    774 {
    775     SuffDebug("Defining a transformation from `%s' to `%s'.\n",
    776 	    from->name, to->name);
    777 
    778     SuffInsertIntoList(to, from->parents);
    779     SuffInsertIntoList(from, to->children);
    780 }
    781 
    782 /*-
    783  *-----------------------------------------------------------------------
    784  * SuffUnlinkSuffixes -- undo what SuffLinkSuffixes() did.
    785  *-----------------------------------------------------------------------
    786  */
    787 static int
    788 SuffUnlinkSuffixes(void *f, void *t)
    789 {
    790     Suff *from = (Suff *)f;
    791     Suff *to = (Suff *)t;
    792 
    793     SuffDebug("Undefining a transformation from `%s' to `%s'.\n",
    794 	from->name, to->name);
    795 
    796     SuffRemoveFromList(to, from->parents);
    797     SuffRemoveFromList(from, to->children);
    798     /* The suffixes are still in sufflist, refCount must be > 0. */
    799     assert(to->refCount > 0);
    800     assert(from->refCount > 0);
    801 
    802     return 0;
    803 }
    804 
    805 /*-
    806  *-----------------------------------------------------------------------
    807  * SuffSetSuffix -- set a new suffix for node.
    808  *
    809  * The old suffix, if any, is removed by calling Suff_UnsetSuffix().
    810  *
    811  * Input:
    812  * 	node	node to set the suffix for
    813  * 	suffix	new suffix for the node
    814  *
    815  * Side Effects:
    816  * 	OP_LIB is set / unset on node if SUFF_LIBRARY is set / unset on
    817  * 	suffix.
    818  *-----------------------------------------------------------------------
    819  */
    820 static void
    821 SuffSetSuffix(GNode *node, Suff *suffix)
    822 {
    823     Suff_UnsetSuffix(node);
    824 
    825     node->suffix = suffix;
    826 
    827     if (suffix != NULL) {
    828 	suffix->refCount++;
    829 	if (suffix->flags & SUFF_LIBRARY)
    830 	    node->type |= OP_LIB;
    831     }
    832 }
    833 
    834 /*-
    835  *-----------------------------------------------------------------------
    836  * Suff_UnsetSuffix -- remove the current suffix of a node.
    837  *
    838  * Input:
    839  *	node	Node whose suffix is to be cleared.
    840  *
    841  * Side Effects:
    842  *	OP_LIB is cleared from node if it was set.  The library status
    843  *	of nodes stems from their suffixes, so it can't be a library
    844  *	if it has no suffix.
    845  *-----------------------------------------------------------------------
    846  */
    847 static void
    848 Suff_UnsetSuffix(GNode *node)
    849 {
    850     if (node->suffix != NULL) {
    851 	--node->suffix->refCount;
    852 	/* Suffix is still in sufflist, so refCount must be > 0 */
    853 	assert(node->suffix->refCount > 0);
    854 
    855 	node->type &= ~OP_LIB;
    856 	node->suffix = NULL;
    857     }
    858 }
    859 
    860 /*-
    861  *-----------------------------------------------------------------------
    862  * SuffAddToList -- add a suffix to a suffix list.
    863  *
    864  * Input:
    865  *	suffix	suffix to add
    866  *	list	list to receive the suffix
    867  *	succ	The intended successor of the suffix in the list.
    868  *		NULL means no successor, i.e. append.
    869  *-----------------------------------------------------------------------
    870  */
    871 static void
    872 SuffAddToList(Suff *suffix, Lst list, LstNode succ)
    873 {
    874     if (list != sufflist)
    875 	SuffDebug("\t`%s'(%d) ", suffix->name, suffix->sNum);
    876 
    877     if (succ == NULL) {
    878 	(void)Lst_AtEnd(list, suffix);
    879 	if (list != sufflist)
    880 	    SuffDebug("inserted at the end of the list.\n");
    881     } else {
    882 	Suff *s = (Suff *)Lst_Datum(succ);
    883 	(void)Lst_InsertBefore(list, succ, suffix);
    884 	if (list != sufflist)
    885 	    SuffDebug("inserted before `%s'(%d).\n", s->name, s->sNum);
    886     }
    887     ++suffix->refCount;
    888 
    889 #ifdef DEBUG_SRC
    890     (void)Lst_AtEnd(suffix->ref, list);
    891 #endif
    892 }
    893 
    894 /*-
    895  *-----------------------------------------------------------------------
    896  * SuffRemoveFromList -- remove a suffix from a suffix list.
    897  *
    898  * The reference count of the suffix might be zero afterwards.  It is
    899  * the responsibility of the caller to handle this.
    900  *
    901  * Input:
    902  * 	suffix	suffix to remove
    903  * 	list	list to remove the suffix from
    904  *-----------------------------------------------------------------------
    905  */
    906 static void
    907 SuffRemoveFromList(Suff *suffix, Lst list)
    908 {
    909     if (Lst_Remove(list, Lst_Member(list, suffix)) == SUCCESS) {
    910 	suffix->refCount--;
    911 
    912 #ifdef DEBUG_SRC
    913 	Lst_Remove(suffix->ref, Lst_Member(suffix->ref, list));
    914 #endif
    915     }
    916 }
    917 
    918 /*-
    919  *-----------------------------------------------------------------------
    920  * SuffInsertIntoList  -- insert a suffix into its proper place in a list.
    921  *
    922  * The suffixes in the list are kept ordered by suffix numbers (sNum).
    923  *
    924  * Pre-condition:
    925  *	suffix is not already in the list.
    926  *
    927  * Input:
    928  * 	suffix	suffix to add
    929  * 	list	list to receive the suffix
    930  *-----------------------------------------------------------------------
    931  */
    932 static void
    933 SuffInsertIntoList(Suff *suffix, Lst list)
    934 {
    935     LstNode successor;
    936 
    937     successor = Lst_Find(list, suffix, SuffSuffHasPriorityLEP);
    938 
    939     if (successor == NULL || ((Suff *)Lst_Datum(successor)) != suffix)
    940 	SuffAddToList(suffix, list, successor);
    941     else
    942 	/*
    943 	 * This function is only used by SuffLinkSuffixes(), which in turn
    944 	 * should only be called to link previously unlinked suffixes.
    945 	 */
    946 	Punt("Internal error: tried to insert duplicate suffix `%s'(%d) "
    947 	    "into a list.\n", suffix->name, suffix->sNum);
    948 }
    949 
    950 /*
    951  *-----------------------------------------------------------------------
    952  * SuffUnsetOpTransform -- clear the OP_TRANSFORM flag from a target.
    953  *
    954  * Input:
    955  *	target	The target node whose type is modified. (GNode *)
    956  *
    957  * Side Effects:
    958  *	The suffix of the node is unset.
    959  *-----------------------------------------------------------------------
    960  */
    961 static void
    962 SuffUnsetOpTransform(void *tp)
    963 {
    964     GNode *target = (GNode *)tp;
    965     Suff_UnsetSuffix(target);
    966     target->type &= ~OP_TRANSFORM;
    967 }
    968 
    969 /*
    970  *-----------------------------------------------------------------------
    971  * SuffUnlinkChildren --  SuffUnlinkSuffixes(child, suffix) with all chidren.
    972  *
    973  * Calling this function for all suffixes undoes all links between suffixes
    974  * and this is what Suff_ClearSuffixes() uses it for.
    975  *
    976  * Input:
    977  *	suff	undo links to children for this suffix (Suff *)
    978  *-----------------------------------------------------------------------
    979  */
    980 static int
    981 SuffUnlinkChildren(void *suff, void *unused)
    982 {
    983     Suff *suffix = (Suff *)suff;
    984     (void)unused;
    985     Lst_ForEach(suffix->children, SuffUnlinkSuffixes, suffix);
    986 
    987     return 0;
    988 }
    989 
    990 /*
    991  *-----------------------------------------------------------------------
    992  * SuffFreeSuffSufflist -- frontend to SuffFreeSuff() for destroying sufflist.
    993  *
    994  * Reduce the reference count of the suffix by one because it is
    995  * no longer in sufflist, preventing SuffFreeSuff() from throwing a fit.
    996  *
    997  * Input:
    998  *	suff	suffix to free
    999  *-----------------------------------------------------------------------
   1000  */
   1001 static void
   1002 SuffFreeSuffSufflist(void *suff)
   1003 {
   1004     Suff *suffix = (Suff *)suff;
   1005     --suffix->refCount;
   1006     SuffFreeSuff(suffix);
   1007 }
   1008 
   1009 /*
   1010  *-----------------------------------------------------------------------
   1011  * SuffCleanUp -- uninitialize the module.
   1012  *
   1013  * Clears OP_TRANSFORM from transformation rules and deletes all suffixes.
   1014  *
   1015  * This is a separate function instead of being built in to Suff_End()
   1016  * because coincidentally this exact same functionality is needed
   1017  * by Suff_ClearSuffixes().
   1018  *
   1019  * Input:
   1020  *	flags	tweak behavior
   1021  *		SCU_CLEAR
   1022  *			regular behavior
   1023  *		SCU_END
   1024  *			do not clear transforms, they've been deleted
   1025  *			already by Targ_End()
   1026  *-----------------------------------------------------------------------
   1027  */
   1028 static void
   1029 SuffCleanUp(int flags)
   1030 {
   1031     /*
   1032      * Undo all references between the suffixes before deleting them
   1033      * so SuffFreeSuff() can catch any bugs we might have with reference
   1034      * counting.
   1035      */
   1036 
   1037     Lst_Destroy(transforms,
   1038 	((flags & SCU_CLEAR) ? SuffUnsetOpTransform : NULL));
   1039 
   1040     if (nullSuff != NULL) {
   1041 	--nullSuff->refCount;
   1042 	nullSuff = NULL;
   1043     }
   1044 
   1045     SuffUnlinkChildren(emptySuff, NULL);
   1046     --emptySuff->refCount;
   1047     SuffFreeSuff(emptySuff);
   1048 
   1049     Lst_ForEach(sufflist, SuffUnlinkChildren, NULL);
   1050     Lst_Destroy(sufflist, SuffFreeSuffSufflist);
   1051 }
   1052 
   1053 
   1054 /*
   1055  ******************************************************************************
   1056  *			Parsing Helpers
   1057  ******************************************************************************
   1058  */
   1059 
   1060 /*-
   1061  *-----------------------------------------------------------------------
   1062  * Suff_ClearSuffixes -- remove all known suffixes.
   1063  *
   1064  * Effectively, the module is re-initialized.
   1065  *
   1066  * Side Effects:
   1067  *	All OP_TRANSFORM nodes in the graph are reset to regular nodes.
   1068  *-----------------------------------------------------------------------
   1069  */
   1070 void
   1071 Suff_ClearSuffixes(void)
   1072 {
   1073     SuffCleanUp(SCU_CLEAR);
   1074     Suff_Init();
   1075 }
   1076 
   1077 /*-
   1078  *-----------------------------------------------------------------------
   1079  * SuffParseTransform -- get component suffixes from transformation name.
   1080  *
   1081  * Double suffix rules are preferred over single suffix ones (i.e.
   1082  * transformations to the empty suffix).  This only matters if any suffix
   1083  * is a catenation of two others: if .tar.gz, .tar, and .gz are known, then
   1084  * ".tar.gz" is double suffix transformation from .tar to .gz, not a single
   1085  * suffix one from .tar.gz.
   1086  *
   1087  * Input:
   1088  *	name		transformation name
   1089  *	sourceSuff	place to store the source suffix
   1090  *	targetSuff	place to store the target suffix
   1091  *
   1092  * Results:
   1093  *	TRUE if the string is a valid transformation and FALSE otherwise.
   1094  *
   1095  * Side Effects:
   1096  *	The passed pointers are overwritten: by the actual suffixes when
   1097  *	TRUE is returned, with NULLs otherwise.
   1098  *
   1099  *-----------------------------------------------------------------------
   1100  */
   1101 static Boolean
   1102 SuffParseTransform(char *name, Suff **sourceSuff, Suff **targetSuff)
   1103 {
   1104     LstNode s;		/* sufflist iterator for source */
   1105     Suff *from, *to;	/* source and target suffixes */
   1106     Suff *single;	/* the suffix that matches the whole name */
   1107 
   1108     s = NULL;
   1109     from = to = single = NULL;
   1110 
   1111     /* Don't bother with obviously invalid names. */
   1112     if (!lookup[(unsigned char)name[0]])
   1113 	goto end;
   1114 
   1115     /*
   1116      * Is it a double suffix transformation?  For each suffix that matches
   1117      * the start of the name, see if another one matches the rest of it.
   1118      * The first valid pair is chosen.  The first suffix that matches
   1119      * the whole name is remembered, so the suffixes need not to be checked
   1120      * again for a single suffix transformation.  from and to stay as
   1121      * NULLs if no valid transformation is found.
   1122      */
   1123     for (s = Lst_Find(sufflist, name, SuffSuffIsPrefixP); s != NULL;
   1124 	s = Lst_FindFrom(sufflist, Lst_Succ(s), name, SuffSuffIsPrefixP))
   1125     {
   1126 	from = (Suff *)Lst_Datum(s);
   1127 	char *targetName = name + from->nameLen;
   1128 
   1129 	if (*targetName == '\0') {
   1130 	    single = from;
   1131 	} else {
   1132 	    LstNode t = Lst_Find(sufflist, targetName, SuffSuffHasNameP);
   1133 	    if (t != NULL) {
   1134 		to = (Suff *)Lst_Datum(t);
   1135 		break;
   1136 	    }
   1137 	}
   1138 	from = NULL;
   1139     }
   1140 
   1141     /* Use the full match for a single if it wasn't a double. */
   1142     if (from == NULL && single != NULL) {
   1143 	from = single;
   1144 	to = emptySuff;
   1145     }
   1146 
   1147 end:
   1148     if (sourceSuff != NULL && targetSuff != NULL) {
   1149 	*sourceSuff = from;
   1150 	*targetSuff = to;
   1151     }
   1152 
   1153     return from != NULL;
   1154 }
   1155 
   1156 /*-
   1157  *-----------------------------------------------------------------------
   1158  * Suff_IsTransform  -- check if the given string is a transformation rule.
   1159  *
   1160  * Figuring out if the name is a transformation requires us to find
   1161  * the suffixes which would make up the transformation.  The same
   1162  * information will be calculated if Suff_AddTransform() is then called
   1163  * with the same name.  The information from this call can be cached by
   1164  * providing non-NULL values for fromCache and toCache and passing all
   1165  * the same parameters to Suff_AddTransform() if this function returns
   1166  * true..
   1167  *
   1168  * Input:
   1169  *	str		string to check
   1170  *	fromCache	opaque cache pointer
   1171  *	toCache		opaque cache pointer
   1172  *
   1173  * Results:
   1174  *	TRUE if the string is a catenation of two known suffixes or
   1175  *	matches one suffix exactly,  FALSE otherwise
   1176  *-----------------------------------------------------------------------
   1177  */
   1178 Boolean
   1179 Suff_IsTransform(char *str, void **fromCache, void **toCache)
   1180 {
   1181     return SuffParseTransform(str, (Suff **)fromCache, (Suff **)toCache);
   1182 }
   1183 
   1184 /*-
   1185  *-----------------------------------------------------------------------
   1186  * Suff_AddTransform -- record the transformation defined by name.
   1187  *
   1188  * A node is created into the graph to store the transformation, if one
   1189  * does not already exist.
   1190  *
   1191  * Pre-condition:
   1192  *	If src and targ are non-NULL, they must have been parameters
   1193  *	of a call to Suff_IsTransform() that returned true for the same
   1194  *	set of parameters.
   1195  *
   1196  * Input:
   1197  *	name		name of new transformation
   1198  *	fromCache	opaque cache pointer
   1199  *	toCache		opaque cache pointer
   1200  *
   1201  * Results:
   1202  *	The node of the transformation.
   1203  *-----------------------------------------------------------------------
   1204  */
   1205 GNode *
   1206 Suff_AddTransform(char *name, void **fromCache, void **toCache)
   1207 {
   1208     GNode *node;
   1209     Suff *from, *to;
   1210     if (fromCache != NULL && toCache != NULL) {
   1211 	from = (Suff *)*fromCache;
   1212 	to = (Suff *)*toCache;
   1213     } else
   1214 	from = to = NULL;
   1215 
   1216     node = Targ_FindNode(name, TARG_CREATE);
   1217 
   1218     if ((from != NULL || SuffParseTransform(name, &from, &to))
   1219 	&& !(node->type & OP_TRANSFORM))
   1220     {
   1221 	node->type |= OP_TRANSFORM;
   1222 	Lst_AtEnd(transforms, node);
   1223 	SuffSetSuffix(node, to);
   1224 
   1225 	/* Pre-cond: this did not exist before, can't be linked yet. */
   1226 	SuffLinkSuffixes(from, to);
   1227     }
   1228 
   1229     return node;
   1230 }
   1231 
   1232 /*-
   1233  *-----------------------------------------------------------------------
   1234  * Suff_EndTransform --
   1235  *	Handle the finish of a transformation definition, removing the
   1236  *	transformation from the graph if it has neither commands nor
   1237  *	sources. This is a callback procedure for the Parse module via
   1238  *	Lst_ForEach
   1239  *
   1240  * Input:
   1241  *	gnp		Node for transformation
   1242  *
   1243  * Results:
   1244  *	=== 0
   1245  *
   1246  * Side Effects:
   1247  *	If the node has no commands or children, the children and parents
   1248  *	lists of the affected suffixes are altered.
   1249  *
   1250  *-----------------------------------------------------------------------
   1251  */
   1252 int
   1253 Suff_EndTransform(void *gnp, void *unused)
   1254 {
   1255     GNode *gn = (GNode *)gnp;
   1256 
   1257     (void)unused;
   1258 
   1259     if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts))
   1260 	gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts));
   1261     if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) &&
   1262 	Lst_IsEmpty(gn->children))
   1263     {
   1264 	/* So it is an empty target. */
   1265 	Suff	*s, *t;
   1266 
   1267 	/* But is it a transformation? (.DEFAULT is also OP_TRANSFORM) */
   1268 	if (SuffParseTransform(gn->name, &s, &t)) {
   1269 	    SuffDebug("Deleting a transformation with no commands.\n");
   1270 	    SuffUnlinkSuffixes(s, t);
   1271 	    gn->type |= ~OP_TRANSFORM;
   1272 	}
   1273     } else if ((gn->type & OP_TRANSFORM))
   1274 	SuffDebug("Transformation %s completed.\n", gn->name);
   1275 
   1276     return 0;
   1277 }
   1278 
   1279 /*-
   1280  *-----------------------------------------------------------------------
   1281  * SuffScanTargets --
   1282  *	Called from Suff_AddSuffix via Lst_ForEach to search through the
   1283  *	list of existing targets for necessary changes.
   1284  *
   1285  *	Any target that was not already a transformation and according to
   1286  *	SuffParseTransform() now is, is made into one.  Existing
   1287  *	single suffix transformations, that are now valid two suffix ones,
   1288  *	are converted.  There's no change in double prefix rules.
   1289  *	The single suffix conversion could not happen if we were to accept
   1290  *	only POSIX suffixes, but we accept everything.
   1291  *
   1292  *	What is so special about single suffix transformations?  Consider
   1293  *	the case in which suffixes s1, s2, ..., and sN are given.  Then
   1294  *	any double prefix rule is sXsY such that sX is the first suffix
   1295  *	in the list for which the remainder sY is also in the list.
   1296  *	Thus X and Y are both at most N.  No matter what suffix we add
   1297  *	to the list, X and Y cannot change.
   1298  *
   1299  *	For a single suffix rule the case is different.  Given suffixes
   1300  *	.a.b and .a, the transformation ".a.b" is a single prefix rule.
   1301  *	We always give precedence for double prefix rules, so when
   1302  *	.b is added as a suffix, the transformation should now be
   1303  *	a double suffix rule .a -> .b.
   1304  *
   1305  * Input:
   1306  * 	targetNode	Current target to check.
   1307  * 	newSuffix	The newly added suffix.
   1308  *
   1309  * Results:
   1310  *	Always 0, so Lst_ForEach() won't stop prematurely.
   1311  *
   1312  * Side Effects:
   1313  *
   1314  *-----------------------------------------------------------------------
   1315  */
   1316 static int
   1317 SuffScanTargets(void *targetGNode, void *newSuffix)
   1318 {
   1319     GNode *target = (GNode *)targetGNode;
   1320     Suff *from, *to;
   1321     Suff *suffix = (Suff *)newSuffix;
   1322 
   1323     from = to = NULL;
   1324 
   1325     /* Reject obviously irrelevant targets. */
   1326     if (!(lookup[(unsigned char)target->name[0]]
   1327 	&& strstr(target->name, suffix->name) != NULL))
   1328     {
   1329 	goto out;
   1330     }
   1331 
   1332     if (SuffParseTransform(target->name, &from, &to)) {
   1333 	if (target->type & OP_TRANSFORM) {
   1334 	    if (target->suffix == emptySuff && to != emptySuff)
   1335 		SuffUnlinkSuffixes(from, to); /* single to double */
   1336 	    else
   1337 		from = to = NULL; /* still a single, or was double */
   1338 	} else
   1339 	    target->type |= OP_TRANSFORM; /* regular to transformation */
   1340 
   1341 	if (from != NULL && to != NULL) {
   1342 	    /* Pre-cond: new double or completely new, can't be linked yet. */
   1343 	    SuffLinkSuffixes(from, to);
   1344             Lst_AtEnd(transforms, target);
   1345         }
   1346     }
   1347 
   1348 out:
   1349     return 0;
   1350 }
   1351 
   1352 /*-
   1353  *-----------------------------------------------------------------------
   1354  * Suff_AddSuffix --
   1355  *	Add the named suffix to the end of the list of known suffixes.
   1356  *	Existing targets are checked to see if any of them becomes
   1357  *	a transformation.
   1358  *
   1359  *	If the suffix is already in the list of known suffixes, nothing
   1360  *	is done.
   1361  *
   1362  *	After this function is called, the target list should be re-scanned
   1363  *	in case the current main target was made into a transformation rule.
   1364  *
   1365  * Input:
   1366  *	name	the name of the suffix to add
   1367  *
   1368  * Results:
   1369  *	TRUE if a new suffix was added, FALSE otherwise.
   1370  *
   1371  * Side Effects:
   1372  *	A GNode is created for the suffix and a Suff structure is created and
   1373  *	appended to the suffixes list unless the suffix was already known.
   1374  *-----------------------------------------------------------------------
   1375  */
   1376 void
   1377 Suff_AddSuffix(char *name)
   1378 {
   1379     Suff          *s;	/* New one for adding */
   1380     LstNode 	  old;
   1381 
   1382     old = Lst_Find(sufflist, name, SuffSuffHasNameP);
   1383     if (old == NULL) {
   1384 	s = SuffNewSuff(name);
   1385 	SuffAddToList(s, sufflist, NULL);
   1386 
   1387 	lookup[(unsigned char)s->name[0]] = 1;
   1388 
   1389 	Lst_ForEach(Targ_List(), SuffScanTargets, s);
   1390     }
   1391 }
   1392 
   1393 /*-
   1394  *-----------------------------------------------------------------------
   1395  * Suff_GetPath --
   1396  *	Return the search path for the given suffix, if it's defined.
   1397  *
   1398  * Results:
   1399  *	The searchPath for the desired suffix or NULL if the suffix isn't
   1400  *	defined.
   1401  *
   1402  * Side Effects:
   1403  *	None
   1404  *-----------------------------------------------------------------------
   1405  */
   1406 Lst
   1407 Suff_GetPath(char *sname)
   1408 {
   1409     LstNode   	  ln;
   1410     Suff    	  *s;
   1411 
   1412     ln = Lst_Find(sufflist, sname, SuffSuffHasNameP);
   1413     if (ln != NULL)
   1414 	s = (Suff *)Lst_Datum(ln);
   1415 
   1416     return (ln == NULL ? NULL : s->searchPath);
   1417 }
   1418 
   1419 /*-
   1420  *-----------------------------------------------------------------------
   1421  * Suff_DoPaths --
   1422  *	Extend the search paths for all suffixes to include the default
   1423  *	search path.
   1424  *
   1425  * Results:
   1426  *	None.
   1427  *
   1428  * Side Effects:
   1429  *	The searchPath field of all the suffixes is extended by the
   1430  *	directories in dirSearchPath. If paths were specified for the
   1431  *	".h" suffix, the directories are stuffed into a global variable
   1432  *	called ".INCLUDES" with each directory preceded by a -I. The same
   1433  *	is done for the ".a" suffix, except the variable is called
   1434  *	".LIBS" and the flag is -L.
   1435  *-----------------------------------------------------------------------
   1436  */
   1437 void
   1438 Suff_DoPaths(void)
   1439 {
   1440     Suff	   	*s;
   1441     LstNode  		ln;
   1442     char		*ptr;
   1443     Lst	    	    	inIncludes; /* Cumulative .INCLUDES path */
   1444     Lst	    	    	inLibs;	    /* Cumulative .LIBS path */
   1445 
   1446     if (Lst_Open(sufflist) == FAILURE) {
   1447 	return;
   1448     }
   1449 
   1450     inIncludes = Lst_Init(FALSE);
   1451     inLibs = Lst_Init(FALSE);
   1452 
   1453     while ((ln = Lst_Next(sufflist)) != NULL) {
   1454 	s = (Suff *)Lst_Datum(ln);
   1455 	if (!Lst_IsEmpty (s->searchPath)) {
   1456 #ifdef INCLUDES
   1457 	    if (s->flags & SUFF_INCLUDE) {
   1458 		Dir_Concat(inIncludes, s->searchPath);
   1459 	    }
   1460 #endif /* INCLUDES */
   1461 #ifdef LIBRARIES
   1462 	    if (s->flags & SUFF_LIBRARY) {
   1463 		Dir_Concat(inLibs, s->searchPath);
   1464 	    }
   1465 #endif /* LIBRARIES */
   1466 	    Dir_Concat(s->searchPath, dirSearchPath);
   1467 	} else {
   1468 	    Lst_Destroy(s->searchPath, Dir_Destroy);
   1469 	    s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir);
   1470 	}
   1471     }
   1472 
   1473     Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL, 0);
   1474     free(ptr);
   1475     Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL, 0);
   1476     free(ptr);
   1477 
   1478     Lst_Destroy(inIncludes, Dir_Destroy);
   1479     Lst_Destroy(inLibs, Dir_Destroy);
   1480 
   1481     Lst_Close(sufflist);
   1482 }
   1483 
   1484 /*-
   1485  *-----------------------------------------------------------------------
   1486  * Suff_AddInclude --
   1487  *	Add the given suffix as a type of file which gets included.
   1488  *	Called from the parse module when a .INCLUDES line is parsed.
   1489  *	The suffix must have already been defined.
   1490  *
   1491  * Input:
   1492  *	sname		Name of the suffix to mark
   1493  *
   1494  * Results:
   1495  *	None.
   1496  *
   1497  * Side Effects:
   1498  *	The SUFF_INCLUDE bit is set in the suffix's flags field
   1499  *
   1500  *-----------------------------------------------------------------------
   1501  */
   1502 void
   1503 Suff_AddInclude(char *sname)
   1504 {
   1505     LstNode	  ln;
   1506     Suff	  *s;
   1507 
   1508     ln = Lst_Find(sufflist, sname, SuffSuffHasNameP);
   1509     if (ln != NULL) {
   1510 	s = (Suff *)Lst_Datum(ln);
   1511 	s->flags |= SUFF_INCLUDE;
   1512     }
   1513 }
   1514 
   1515 /*-
   1516  *-----------------------------------------------------------------------
   1517  * Suff_AddLib --
   1518  *	Add the given suffix as a type of file which is a library.
   1519  *	Called from the parse module when parsing a .LIBS line. The
   1520  *	suffix must have been defined via .SUFFIXES before this is
   1521  *	called.
   1522  *
   1523  * Input:
   1524  *	sname		Name of the suffix to mark
   1525  *
   1526  * Results:
   1527  *	None.
   1528  *
   1529  * Side Effects:
   1530  *	The SUFF_LIBRARY bit is set in the suffix's flags field
   1531  *
   1532  *-----------------------------------------------------------------------
   1533  */
   1534 void
   1535 Suff_AddLib(char *sname)
   1536 {
   1537     LstNode	  ln;
   1538     Suff	  *s;
   1539 
   1540     ln = Lst_Find(sufflist, sname, SuffSuffHasNameP);
   1541     if (ln != NULL) {
   1542 	s = (Suff *)Lst_Datum(ln);
   1543 	s->flags |= SUFF_LIBRARY;
   1544     }
   1545 }
   1546 
   1547 
   1548 /*
   1549  ******************************************************************************
   1550  *			Implicit Source Search Functions
   1551  ******************************************************************************
   1552  */
   1553 
   1554 /*-
   1555  *-----------------------------------------------------------------------
   1556  * SuffAddSrc -- add transformation possibility.
   1557  *
   1558  * Create an Src structure describing a transformation from a file with
   1559  * the given suffix to the given target (target.from -> target.to).
   1560  * If the suffix happens to be the .NULL suffix, create a transformation
   1561  * from target's prefix also (target -> target.to).
   1562  *
   1563  * This is callback function for Lst_ForEach().
   1564  *
   1565  * Input:
   1566  *	suffix		the source's suffix
   1567  *	arguments	more arguments: target, transformations not yet tried,
   1568  *			cleanup list.
   1569  *
   1570  * Results:
   1571  *	Always return 0 to prevent Lst_ForEach() from exiting prematurely.
   1572  *-----------------------------------------------------------------------
   1573  */
   1574 static int
   1575 SuffAddSrc(void *suffix, void *arguments)
   1576 {
   1577     Suff	*fromSuffix;
   1578     LstSrc	*args;
   1579     Src		*from, *nullChild, *to;
   1580 
   1581     fromSuffix = (Suff *)suffix;
   1582     args = (LstSrc *)arguments;
   1583     to = args->target;
   1584 
   1585     /*
   1586      * Don't add a transformation that is already in the chain or we
   1587      * might get stuck in an infinite loop.
   1588      */
   1589     for (to = args->target; to != NULL; to = to->parent) {
   1590 	if (to->suff == fromSuffix) {
   1591 	    SuffDebug("\t%*.s%s%s: ignored (already tried in this chain)\n",
   1592 		args->target->depth + 1, " ", to->pref, fromSuffix->name);
   1593 	    goto end;
   1594 	}
   1595     }
   1596     to = args->target;
   1597 
   1598     from = SuffNewChildSrc(to, fromSuffix, &nullChild);
   1599 #ifdef DEBUG_SRC
   1600     fprintf(debug_file, "1 add %x %x to %x:", to, from, args->possible);
   1601     if (nullChild != NULL)
   1602 	fprintf(debug_file, "2 add %x %x to %x:", to, nullChild,
   1603 	    args->possible);
   1604     Lst_ForEach(args->possible, PrintAddr, NULL);
   1605     fprintf(debug_file, "\n");
   1606 #endif
   1607     Lst_AtEnd(args->possible, from);
   1608     Lst_AtEnd(args->cleanup, from);
   1609     if (nullChild != NULL) {
   1610 	Lst_AtEnd(args->possible, nullChild);
   1611 	Lst_AtEnd(args->cleanup, nullChild);
   1612     }
   1613 
   1614 end:
   1615     return 0;
   1616 }
   1617 
   1618 /*-
   1619  *-----------------------------------------------------------------------
   1620  * SuffAddLevelForSuffix -- get possible transformations to target node.
   1621  *
   1622  * A new top level Src structure (parent == NULL) is created for target
   1623  * using the provided suffix.  Then Src structures describing all
   1624  * the possible ways to create the target node are appended into the list
   1625  * possible.  If the target node has multiple known suffixes, this function
   1626  * should be called for each suffix separately to get all the possible ways
   1627  * to create the node.
   1628  *
   1629  * The top level Src and the possible transformations are added into
   1630  * cleanup.
   1631  *
   1632  * Input:
   1633  *	suffix		target node's suffix
   1634  *	possible	list to add the possible transformations into
   1635  *			(data: Src *)
   1636  *	end		desired transformation target
   1637  *	cleanup		list of all Srcs for eventual cleanup (data: Src *)
   1638  *-----------------------------------------------------------------------
   1639  */
   1640 static void
   1641 SuffAddLevelForSuffix(Suff *suffix, Lst possible, GNode *end, Lst cleanup)
   1642 {
   1643     Src *s;
   1644     if (suffix != NULL) {
   1645 	if (suffix->flags & SUFF_NULL)
   1646 	    /* Only set when "remove a suffix" aspect of .NULL is used. */
   1647 	    s = SuffNewTopSrcNull(end, suffix);
   1648 	else
   1649 	    s = SuffNewTopSrc(end, suffix);
   1650 	Lst_AtEnd(cleanup, s);
   1651 
   1652 	SuffAddLevel(possible, s, cleanup);
   1653     }
   1654 }
   1655 
   1656 /*-
   1657  *-----------------------------------------------------------------------
   1658  * SuffAddLevel -- get possible transformations to target Src.
   1659  *
   1660  * Src structures describing all the possible ways to create target are
   1661  * appended into the list possible.
   1662  *
   1663  * The possible transformations are also added into cleanup.
   1664  *
   1665  * Input:
   1666  *	possible	list to add the possible transformations to
   1667  *			(data: Src *)
   1668  *	target		desired transformation target
   1669  *	cleanup		list of all Srcs for eventual clean-up (data: Src *)
   1670  *-----------------------------------------------------------------------
   1671  */
   1672 static void
   1673 SuffAddLevel(Lst possible, Src *target, Lst cleanup) {
   1674     LstSrc ls;
   1675 
   1676     ls.target = target;
   1677     ls.possible = possible;
   1678     ls.cleanup = cleanup;
   1679 
   1680     Lst_ForEach(target->suff->children, SuffAddSrc, &ls);
   1681 }
   1682 
   1683 /*-
   1684  *-----------------------------------------------------------------------
   1685  * SuffFindThem -- find a transformation chain from a list of possibilities.
   1686  *
   1687  * A valid transformation chain is one which starts from an existing
   1688  * target node or file and can be converted into the desired target by
   1689  * repeated application of transformation rules.  If any such chain
   1690  * can be found, this function will return the one which is the shortest.
   1691  * If there are multiple equally short chains, the steps required are
   1692  * compared, starting from the /last/ one, and on the first differing
   1693  * step the one whose target suffix occurs first in .SUFFIXES is chosen.
   1694  *
   1695  * Input:
   1696  *	possible	all possible last steps in the transformation,
   1697  *			in the proper .SUFFIXES order
   1698  *			chain (data: Src *)
   1699  *	cleanup		list of all Srcs for eventual clean-up (data: Src *)
   1700  *
   1701  * Results:
   1702  *	The starting point of the shortest, highest priority transformation
   1703  *	chain.  Taking the node described by the returned value and
   1704  *	applying to it the transformations defined by the parent pointers
   1705  *	will result in the initially desired target.
   1706  *
   1707  *	If no chain terminates at an existing target or file, NULL is
   1708  *	returned.
   1709  *-----------------------------------------------------------------------
   1710  */
   1711 static Src *
   1712 SuffFindThem(Lst possible, Lst cleanup)
   1713 {
   1714     Src	*i, *result, *parent;
   1715     char *tf;
   1716 
   1717     result = NULL;
   1718     /*
   1719      * Parent of the current candidate.  When it changes, debug print
   1720      * the chain of transformations so far.
   1721      */
   1722     parent = NULL;
   1723 
   1724     /*
   1725      * You've been lied to.  There wont be any step priority comparisons.
   1726      * Because the list initially contains the possible transformations
   1727      * in the correct order, the first existing one is the correct result.
   1728      * Each possible transformation is removed from the front of the list
   1729      * as it is checked and if it does not exist, all the ways to create
   1730      * it are appended to the list.  This way the one step longer chains
   1731      * are also in the correct priority order and the item at the front
   1732      * of the list is always the correct result, should it exist.  It is
   1733      * then easy to keep popping the list until the result is found or all
   1734      * possibilities are exhausted.
   1735      */
   1736     while ((i = (Src *)Lst_DeQueue(possible)) != NULL) {
   1737 	GNode *n;
   1738 	if (parent != i->parent) {
   1739 	    SuffDebugChain(i->parent);
   1740 	    parent = i->parent;
   1741 	}
   1742 	SuffDebug ("\t%*.s%s: ", i->depth, " ", i->file);
   1743 
   1744 	/*
   1745 	 * XXX: should only targets with commands be accepted?  The node
   1746 	 * exists even if it only has had extra dependencies added.
   1747 	 */
   1748 	if ((n = Targ_FindNode(i->file, TARG_NOCREATE)) != NULL) {
   1749 #ifdef DEBUG_SRC
   1750 	    fprintf(debug_file, "remove %x from %x\n", i, possible);
   1751 #endif
   1752 	    SuffDebug(": Node %s %x: ", i->file, n->type);
   1753 	    if ((n->type & OP_INVISIBLE) == 0) {
   1754 		result = i;
   1755 		break;
   1756 	    }
   1757 	} else if ((tf = Dir_FindFile(i->file, i->suff->searchPath)) != NULL) {
   1758 	    result = i;
   1759 #ifdef DEBUG_SRC
   1760 	    fprintf(debug_file, "remove %x from %x\n", i, possible);
   1761 #endif
   1762 	    SuffDebug(": File %s %s: ", i->file, tf);
   1763 	    free(tf);
   1764 	    break;
   1765 	}
   1766 
   1767 	SuffDebug("not there.\n");
   1768 
   1769 	SuffAddLevel(possible, i, cleanup);
   1770     }
   1771 
   1772     if (result)
   1773 	SuffDebug("got it.\n");
   1774 
   1775     return result;
   1776 }
   1777 
   1778 /*-
   1779  *-----------------------------------------------------------------------
   1780  * SuffExpandChildren -- call SuffExpandChild() on node's children.
   1781  *
   1782  * Input:
   1783  *	parent	parent node
   1784  *	first	child to start from
   1785  *-----------------------------------------------------------------------
   1786  */
   1787 static void
   1788 SuffExpandChildren(GNode *parent, LstNode first)
   1789 {
   1790     LstNode i, next;
   1791 
   1792     /*
   1793      * SuffExpandChild() replaces the curren node with the expanded values,
   1794      * so we won't try to expand the already expanded values
   1795      */
   1796     for (i = first; i != NULL; i = next) {
   1797 	/* SuffExpandChild() might remove i, so get the successor now. */
   1798 	next = Lst_Succ(i);
   1799 	SuffExpandChild(i, parent);
   1800     }
   1801 }
   1802 
   1803 /*-
   1804  *-----------------------------------------------------------------------
   1805  * SuffExpandChild -- expand variables and wildcards in a child name.
   1806  *
   1807  * Expand variables and wildcards in a child's name and replace the child
   1808  * with the results if an expansion happened.  This means that when
   1809  * expansion occurred, cln will point to free'd memory!
   1810  *
   1811  * Input:
   1812  *	cln		child to expand.
   1813  *	pgn		parent node being processed
   1814  *
   1815  * Results:
   1816  *	=== 0 (continue)
   1817  *-----------------------------------------------------------------------
   1818  */
   1819 static void
   1820 SuffExpandChild(LstNode cln, GNode *pgn)
   1821 {
   1822     GNode   	*cgn = (GNode *)Lst_Datum(cln);
   1823     GNode	*gn;		/* helper for adding expanded nodes */
   1824     char	*expanded;	/* expanded child name */
   1825     char	*cp;		/* current position in expanded value */
   1826 
   1827     if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ))
   1828 	/* It is all too hard to process the result of .ORDER */
   1829 	return;
   1830 
   1831     if (cgn->type & OP_WAIT)
   1832 	/* Ignore these (& OP_PHONY ?) */
   1833 	return;
   1834 
   1835     /*
   1836      * First do variable expansion -- this takes precedence over
   1837      * wildcard expansion. If the result contains wildcards, they'll be gotten
   1838      * to later since the resulting words are tacked on to the end of
   1839      * the children list.
   1840      */
   1841     if (strchr(cgn->name, '$') == NULL) {
   1842 	SuffExpandWildcards(cln, pgn);
   1843 	return;
   1844     }
   1845 
   1846     SuffDebug("\tVariable expanding dependency `%s'\n", cgn->name);
   1847     cp = expanded = Var_Subst(NULL, cgn->name, pgn, TRUE);
   1848 
   1849     if (cp != NULL) {
   1850 	Lst	    members = Lst_Init(FALSE);
   1851 
   1852 	if (cgn->type & OP_ARCHV) {
   1853 	    /*
   1854 	     * Node was an archive(member) target, so we want to call
   1855 	     * on the Arch module to find the nodes for us, expanding
   1856 	     * variables in the parent's context.
   1857 	     */
   1858 	    char	*sacrifice = cp;
   1859 
   1860 	    (void)Arch_ParseArchive(&sacrifice, members, pgn);
   1861 	} else {
   1862 	    /*
   1863 	     * Break the result into a vector of strings whose nodes
   1864 	     * we can find, then add those nodes to the members list.
   1865 	     * Unfortunately, we can't use brk_string b/c it
   1866 	     * doesn't understand about variable specifications with
   1867 	     * spaces in them...
   1868 	     * XXX: what variable specs?!  I thought we already expanded
   1869 	     * all of the variables and there shouldn't be any variable
   1870 	     * expansion stages left before the name is used as target!
   1871 	     */
   1872 	    char	    *start;
   1873 
   1874 	    for (start = cp; *start == ' ' || *start == '\t'; start++)
   1875 		continue;
   1876 	    for (cp = start; *cp != '\0'; cp++) {
   1877 		if (*cp == ' ' || *cp == '\t') {
   1878 		    /*
   1879 		     * White-space -- terminate element, find the node,
   1880 		     * add it, skip any further spaces.
   1881 		     */
   1882 		    *cp++ = '\0';
   1883 		    gn = Targ_FindNode(start, TARG_CREATE);
   1884 		    (void)Lst_AtEnd(members, gn);
   1885 		    while (*cp == ' ' || *cp == '\t') {
   1886 			cp++;
   1887 		    }
   1888 		    /*
   1889 		     * Adjust cp for increment at start of loop, but
   1890 		     * set start to first non-space.
   1891 		     */
   1892 		    start = cp--;
   1893 		} else if (*cp == '$') {
   1894 		    /*
   1895 		     * Start of a variable spec -- contact variable module
   1896 		     * to find the end so we can skip over it.
   1897 		     */
   1898 		    char	*junk;
   1899 		    int 	len;
   1900 		    void	*freeIt;
   1901 
   1902 		    junk = Var_Parse(cp, pgn, TRUE, &len, &freeIt);
   1903 		    if (junk != var_Error) {
   1904 			cp += len - 1;
   1905 		    }
   1906 
   1907 		    if (freeIt)
   1908 			free(freeIt);
   1909 		} else if (*cp == '\\' && *cp != '\0') {
   1910 		    /*
   1911 		     * Escaped something -- skip over it
   1912 		     */
   1913 		    cp++;
   1914 		}
   1915 	    }
   1916 
   1917 	    if (cp != start) {
   1918 		/*
   1919 		 * Stuff left over -- add it to the list too
   1920 		 */
   1921 		gn = Targ_FindNode(start, TARG_CREATE);
   1922 		(void)Lst_AtEnd(members, gn);
   1923 	    }
   1924 	}
   1925 
   1926 	/*
   1927 	 * Add all elements of the members list to the parent node.
   1928 	 */
   1929 	while(!Lst_IsEmpty(members)) {
   1930 	    gn = (GNode *)Lst_DeQueue(members);
   1931 
   1932 	    SuffDebug("\t\t%s\n", gn->name);
   1933 	    /* Add gn to the parents child list before the original child */
   1934 	    (void)Lst_InsertBefore(pgn->children, cln, gn);
   1935             if ((GNode *)Lst_Datum(pgn->first_local_child) == cgn)
   1936                 pgn->first_local_child = Lst_Prev(cln);
   1937 	    (void)Lst_AtEnd(gn->parents, pgn);
   1938 	    pgn->unmade++;
   1939 	    /* Expand wildcards on new node */
   1940 	    SuffExpandWildcards(Lst_Prev(cln), pgn);
   1941 	}
   1942 	Lst_Destroy(members, NULL);
   1943 
   1944 	free(expanded);
   1945 	expanded = NULL;
   1946     }
   1947 
   1948     /*
   1949      * Now the source is expanded, remove it from the list of children to
   1950      * keep it from being processed.
   1951      */
   1952     pgn->unmade--;
   1953     Lst_Remove(pgn->children, cln);
   1954     Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn));
   1955 }
   1956 
   1957 static void
   1958 SuffExpandWildcards(LstNode cln, GNode *pgn)
   1959 {
   1960     GNode   	*cgn = (GNode *)Lst_Datum(cln);
   1961     GNode	*gn;	    /* New source 8) */
   1962     char	*cp;	    /* Expanded value */
   1963     Lst 	explist;    /* List of expansions */
   1964 
   1965     if (!Dir_HasWildcards(cgn->name))
   1966 	return;
   1967 
   1968     /*
   1969      * Expand the word along the chosen path
   1970      */
   1971     SuffDebug("\tWildcard expanding dependency `%s'\n", cgn->name);
   1972     explist = Lst_Init(FALSE);
   1973     Dir_Expand(cgn->name, Suff_FindPath(cgn), explist);
   1974 
   1975     while (!Lst_IsEmpty(explist)) {
   1976 	/*
   1977 	 * Fetch next expansion off the list and find its GNode
   1978 	 */
   1979 	cp = (char *)Lst_DeQueue(explist);
   1980 
   1981 	SuffDebug("\t\t%s\n", cp);
   1982 	gn = Targ_FindNode(cp, TARG_CREATE);
   1983 
   1984 	/* Add gn to the parents child list before the original child */
   1985 	(void)Lst_InsertBefore(pgn->children, cln, gn);
   1986         if ((GNode *)Lst_Datum(pgn->first_local_child) == cgn)
   1987             pgn->first_local_child = Lst_Prev(cln);
   1988 	(void)Lst_AtEnd(gn->parents, pgn);
   1989 	pgn->unmade++;
   1990     }
   1991 
   1992     /*
   1993      * Nuke what's left of the list
   1994      */
   1995     Lst_Destroy(explist, NULL);
   1996 
   1997     /*
   1998      * Now the source is expanded, remove it from the list of children to
   1999      * keep it from being processed.
   2000      */
   2001     pgn->unmade--;
   2002     Lst_Remove(pgn->children, cln);
   2003     Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn));
   2004 }
   2005 
   2006 /*-
   2007  *-----------------------------------------------------------------------
   2008  * Suff_FindPath --
   2009  *	Find a path along which to expand the node.
   2010  *
   2011  *	If the word has a known suffix, use that path.
   2012  *	If it has no known suffix, use the default system search path.
   2013  *
   2014  * Input:
   2015  *	gn		Node being examined
   2016  *
   2017  * Results:
   2018  *	The appropriate path to search for the GNode.
   2019  *
   2020  * Side Effects:
   2021  *	XXX: We could set the suffix here so that we don't have to scan
   2022  *	again.
   2023  *
   2024  *-----------------------------------------------------------------------
   2025  */
   2026 Lst
   2027 Suff_FindPath(GNode* gn)
   2028 {
   2029     Suff *suff = gn->suffix;
   2030 
   2031     if (suff == NULL) {
   2032 	SuffixCmpData sd;   /* Search string data */
   2033 	LstNode ln;
   2034 	sd.len = strlen(gn->name);
   2035 	sd.ename = gn->name + sd.len;
   2036 	ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP);
   2037 
   2038 	if (ln != NULL)
   2039 	    suff = (Suff *)Lst_Datum(ln);
   2040 	/* XXX: Here we can save the suffix so we don't have to do this again */
   2041     }
   2042 
   2043     if (suff != NULL)
   2044 	return suff->searchPath;
   2045     else
   2046 	return dirSearchPath;
   2047 }
   2048 
   2049 
   2050 /*-
   2051  *-----------------------------------------------------------------------
   2052  * SuffApplyTransformations -- apply a transformation chain.
   2053  *
   2054  * Apply transformations beginning at start, until the node end is
   2055  * reached.  A node is created for each intermediate target, if one does
   2056  * not already exist and the relevant suffixes are set on the nodes.
   2057  *
   2058  * Each target except for the start and end of the chain gets TARGET
   2059  * and PREFIX set and their children expanded.  The start of the chain
   2060  * cannot be expanded as it could turn out to be the result of another
   2061  * transformation chain and have a different suffix as a part of that
   2062  * chain.  The end of the chain cannot be expanded because the node's
   2063  * name might be a fake one (see SuffFindArchiveDeps()).
   2064  *
   2065  * Input:
   2066  *	start	transformation chain's starting
   2067  *	end	transformation chain's end,  i.e. the node for which we were
   2068  *		initially looking dependencies for
   2069  *
   2070  * Results:
   2071  *	The suffix that was set on end.
   2072  *-----------------------------------------------------------------------
   2073  */
   2074 static Suff *
   2075 SuffApplyTransformations(Src *start, GNode *end)
   2076 {
   2077     Src *target, *source;
   2078 
   2079     if (start->node == NULL)
   2080 	start->node = Targ_FindNode(start->file, TARG_CREATE);
   2081 
   2082     for (source = start; source->parent != NULL; source = source->parent) {
   2083 	target = source->parent;
   2084 
   2085 	SuffSetSuffix(source->node, source->suff);
   2086 
   2087 	if (target->node == NULL)
   2088 	    target->node = Targ_FindNode(target->file, TARG_CREATE);
   2089 
   2090 	if (target->node != end) {
   2091 	    /*
   2092 	     * Dependency search for intermediate targets is finished:
   2093 	     * if they had dependencies to check, they would have
   2094 	     * a target or an existing file and therefore wouldn't be
   2095 	     * intermediate targets.
   2096 	     */
   2097 	    target->node->type |= OP_DEPS_FOUND;
   2098 	    Var_Set(TARGET, target->node->name, target->node, 0);
   2099 	    Var_Set(PREFIX, target->pref, target->node, 0);
   2100 	}
   2101 
   2102 	SuffApplyTransformation(target->node, source->node,
   2103 	    target->suff, source->suff,
   2104 	    (target->node == end ? SAT_NO_EXPAND : SAT_REGULAR));
   2105     }
   2106 
   2107     SuffSetSuffix(end, source->suff);
   2108 
   2109     return end->suffix;
   2110 }
   2111 
   2112 /*-
   2113  *-----------------------------------------------------------------------
   2114  * SuffApplyTransformation -- apply a transformation from source to target.
   2115  *
   2116  * Input:
   2117  *	tGn	Target node
   2118  *	sGn	Source node
   2119  *	t	Target suffix
   2120  *	s	Source suffix
   2121  *	flags	Request modifications for standard behavior.
   2122  *		SAT_REGULAR:
   2123  *			Normal behavior.
   2124  *		SAT_NO_EXPAND:
   2125  *			Do not expand children.
   2126  *
   2127  * Results:
   2128  *	TRUE if successful, FALSE if not.
   2129  *
   2130  * Side Effects:
   2131  *	The source and target are linked and the commands from the
   2132  *	transformation are added to the target node's commands list.
   2133  *	All attributes but OP_DEPMASK and OP_TRANSFORM are applied
   2134  *	to the target. The target also inherits all the sources for
   2135  *	the transformation rule.
   2136  *
   2137  *-----------------------------------------------------------------------
   2138  */
   2139 static Boolean
   2140 SuffApplyTransformation(GNode *tGn, GNode *sGn, Suff *t, Suff *s, int flags)
   2141 {
   2142     LstNode 	ln;         /* General node */
   2143     char    	*tname;	    /* Name of transformation rule */
   2144     GNode   	*gn;	    /* Node for same */
   2145 
   2146     /*
   2147      * Form the proper links between the target and source.
   2148      */
   2149     (void)Lst_AtEnd(tGn->children, sGn);
   2150     (void)Lst_AtEnd(sGn->parents, tGn);
   2151     tGn->unmade += 1;
   2152 
   2153     /*
   2154      * Locate the transformation rule itself
   2155      */
   2156     tname = str_concat(s->name, t->name, 0);
   2157     ln = Lst_Find(transforms, tname, SuffGNHasNameP);
   2158     free(tname);
   2159 
   2160     gn = (GNode *)Lst_Datum(ln);
   2161 
   2162     SuffDebug("\tApplying `%s' -> `%s' to `%s'\n", s->name, t->name,
   2163 	tGn->name);
   2164 
   2165     /* Record last child so only the new children get expanded. */
   2166     ln = Lst_Last(tGn->children);
   2167 
   2168     /*
   2169      * Pass the buck to Make_HandleUse to apply the rule
   2170      */
   2171     (void)Make_HandleUse(gn, tGn);
   2172 
   2173     /*
   2174      * Deal with wildcards and variables in any acquired sources
   2175      */
   2176     if (!(flags & SAT_NO_EXPAND))
   2177 	SuffExpandChildren(tGn, Lst_Succ(ln));
   2178 
   2179     /*
   2180      * Keep track of another parent to which this beast is transformed so
   2181      * the .IMPSRC variable can be set correctly for the parent.
   2182      */
   2183     (void)Lst_AtEnd(sGn->iParents, tGn);
   2184 
   2185     return(TRUE);
   2186 }
   2187 
   2188 
   2189 /*-
   2190  *-----------------------------------------------------------------------
   2191  * SuffFirstKnownSuffix -- find the first suffix that fits name.
   2192  *
   2193  * Used by SuffFindArchiveDeps() and SuffFindNormalDeps() to figure
   2194  * out suffixes for explicit rules.
   2195  *
   2196  * Input:
   2197  *	name	The name to try the suffixes on.
   2198  *
   2199  * Results:
   2200  *	The first matching suffix structure or NULL if there isn't one.
   2201  *-----------------------------------------------------------------------
   2202  */
   2203 static Suff*
   2204 SuffFirstKnownSuffix(char* name)
   2205 {
   2206     LstNode ln;
   2207     SuffixCmpData sd;
   2208 
   2209     sd.len = strlen(name);
   2210     sd.ename = name + sd.len;
   2211 
   2212     ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP);
   2213     return (ln == NULL ? NULL : (Suff *)Lst_Datum(ln));
   2214 }
   2215 
   2216 /*-
   2217  *-----------------------------------------------------------------------
   2218  * SuffSetPrefixLocalVar -- set .PREFIX properly on target.
   2219  *
   2220  * The value of the .PREFIX variable is the node's name less suffix->name.
   2221  * Used by SuffFindArchiveDeps() and SuffFindNormalDeps().
   2222  *
   2223  * Input:
   2224  *	suffix	The suffix structure to base the prefix on.  If it is NULL,
   2225  *		the whole name is used.
   2226  *	name	The name to get the prefix from, as it is not necessarily
   2227  *		the node's name.
   2228  *	node	The context to set the variable in.
   2229  *-----------------------------------------------------------------------
   2230  */
   2231 static void
   2232 SuffSetPrefixLocalVar(Suff *suffix, char *name, GNode *node)
   2233 {
   2234     if (suffix != NULL) {
   2235 	char save, *save_pos;
   2236 
   2237 	save_pos = name + (strlen(name) - suffix->nameLen);
   2238 	save = *save_pos;
   2239 	*save_pos = '\0';
   2240 	Var_Set(PREFIX, name, node, 0);
   2241 	*save_pos = save;
   2242     }
   2243     else
   2244 	Var_Set(PREFIX, name, node, 0);
   2245 }
   2246 
   2247 /*-
   2248  *-----------------------------------------------------------------------
   2249  * SuffFindArchiveDeps --
   2250  *	Locate dependencies for an OP_ARCHV node.
   2251  *
   2252  * Input:
   2253  *	target	Node for which to locate dependencies
   2254  *	cleanup	List to add all created Srcs into, so the caller can
   2255  *		destroy them.
   2256  *
   2257  * Results:
   2258  *	None
   2259  *
   2260  * Side Effects:
   2261  *	Same as Suff_FindDeps.  ARCHIVE and MEMBER variables are set as
   2262  *	well as gn->type is modified to include OP_MEMBER
   2263  *	on the relevant nodes and are so the modifications
   2264  *
   2265  *-----------------------------------------------------------------------
   2266  */
   2267 static void
   2268 SuffFindArchiveDeps(GNode *target, Lst cleanup)
   2269 {
   2270     Lst possible;	/* Possible transformation starting points. */
   2271     Src *start;		/* The start of the chain of transformations that
   2272 			 * results in this target being built. */
   2273     Suff *suffix;	/* Suffix of the member. */
   2274     char *temp;
   2275 
   2276     char *lib, *member;		/* Copies of lib and member parts, */
   2277     char *libEnd, *memberEnd;   /* their terminating NULs, and */
   2278     size_t libLen, memberLen;	/* their lengths. */
   2279 
   2280     possible = Lst_Init(FALSE);
   2281     start = NULL;
   2282     suffix = NULL;
   2283 
   2284     lib = target->name;
   2285     member = strchr(lib, '(') + 1;
   2286     libLen = member - target->name - 1;
   2287     memberLen = strchr(member, ')') - member;
   2288 
   2289     lib = bmake_strndup(lib, libLen);
   2290     member = bmake_strndup(member, memberLen);
   2291     libEnd = lib + libLen;
   2292     memberEnd = member + memberLen;
   2293 
   2294     /*
   2295      * Explicit rules always take precedence.  Explicit <=> appeared as
   2296      * a target in a rule with commands.
   2297      */
   2298     if (!OP_NOP(target->type) && !Lst_IsEmpty(target->commands)) {
   2299 	SuffDebug("\tIt has an explicit rule.\n");
   2300 
   2301 	suffix = SuffFirstKnownSuffix(member);
   2302 	goto expand_children;
   2303     }
   2304 
   2305     /*
   2306      * Try with POSIX semantics first, if applicable: library rules are only
   2307      * supported for "lib(member.o)" and ".s2.a" is the transformation rule
   2308      * from "member.s2" to "lib(member.o)", regardless of the suffix, if any,
   2309      * "lib" might have.  We pretend to be "member.a" and look for
   2310      * transformations.
   2311      */
   2312     if (memberLen > 2 && strcmp(memberEnd - 2, ".o") == 0) {
   2313 	LstNode ln;
   2314 	SuffDebug("\tTrying POSIX \".s2.a\" transformation.\n");
   2315 
   2316 	*(memberEnd - 1) = 'a';
   2317 	temp = target->name; target->name = member;
   2318 	ln = Lst_Find(sufflist, ".a", SuffSuffHasNameP);
   2319 	SuffAddLevelForSuffix((ln == NULL ? NULL : (Suff *)Lst_Datum(ln)),
   2320 	    possible, target, cleanup);
   2321 	target->name = temp;
   2322 	*(memberEnd - 1) = 'o';
   2323 
   2324 	start = SuffFindThem(possible, cleanup);
   2325     }
   2326 
   2327     /*
   2328      * Given lib.s2(member.s1), if a ".s1.s2" transformation exists, try
   2329      * to find a way to make member.s1 so it could be added to lib.s2.
   2330      * The problem is, all suffixes are accepted, not just POSIX ones
   2331      * (\.[^./]+), so more than one may match either lib or member and
   2332      * not all permutations are valid.
   2333      *
   2334      * Here are a couple of examples of what has to be taken into account.
   2335      * Consider "lib.a.b(member.c)" in a case where "member.d" exists, and
   2336      * with ".SUFFIXES: .b .a.b .c .d".  The transformations are ".d.c" and
   2337      * ".c.b".  If one were to swap the longest suffixes and try with
   2338      * "member.a.b", the transformation would not be found.  Now consider
   2339      * if the transformation ".d.a.b" also existed.  If one were to try
   2340      * in order each suffix of the lib against each suffix of the member
   2341      * and take the first one that works, the chain ".d" -> ".c" -> ".b"
   2342      * would be found but traditionally transformations choose the shortest
   2343      * chain, which would be ".d" -> ".a.b".
   2344      *
   2345      * These issues mean that trying to shoehorn SuffFindNormalDeps()
   2346      * to be useful here would be more trouble than it is worth.  Gladly
   2347      * that use would have mainly been as a frontend for SuffFindThem() and
   2348      * SuffApplyTransformations() and things actually become cleaner if
   2349      * they are used directly.
   2350      *
   2351      * Single suffix rules are not acceptable because they're usually used
   2352      * to create executables.
   2353      */
   2354     if (start == NULL) {
   2355 	/* One set for lib (l) and one for member (m). */
   2356 	LstNode l, m;		/* Suffix list iterators. */
   2357 	SuffixCmpData ld, md;	/* Parameters for predicates. */
   2358 	Suff *ls, *ms;		/* Current suffix. */
   2359 
   2360 	SuffDebug("\tTrying \".s1.s2\" transformation extension.\n");
   2361 
   2362 	ld.len = libLen;
   2363 	ld.ename = libEnd;
   2364 	md.len = memberLen;
   2365 	md.ename = memberEnd;
   2366 
   2367 	/* Get all possible transformations from member to lib. */
   2368 	for (l = Lst_Find(sufflist, &ld, SuffSuffIsSuffixP); l != NULL;
   2369 	    l = Lst_FindFrom(sufflist, Lst_Succ(l), &ld, SuffSuffIsSuffixP))
   2370 	{
   2371 	    ls = ((Suff *)Lst_Datum(l));
   2372 
   2373 	    for (m = Lst_Find(ls->children, &md, SuffSuffIsSuffixP);
   2374 		m != NULL;
   2375 		m = Lst_FindFrom(ls->children, Lst_Succ(m), &md,
   2376 		    SuffSuffIsSuffixP))
   2377 	    {
   2378 		char *fakename, save, *save_pos;
   2379 
   2380 		ms = (Suff *)Lst_Datum(m);
   2381 		save_pos = memberEnd - ms->nameLen;
   2382 		save = *save_pos;
   2383 
   2384 		*save_pos = '\0';
   2385 		fakename = str_concat(member, ls->name, 0);
   2386 		*save_pos = save;
   2387 
   2388 		temp = target->name; target->name = fakename;
   2389 		SuffAddLevelForSuffix(ms, possible, target, cleanup);
   2390 		target->name = temp;
   2391 		free(fakename);
   2392 	    }
   2393 	}
   2394 
   2395 	start = SuffFindThem(possible, cleanup);
   2396     }
   2397 
   2398     if (start != NULL)
   2399 	suffix = SuffApplyTransformations(start, target);
   2400 
   2401 expand_children:
   2402     /*
   2403      * POSIX: in a lib(member.o) and a .s2.a rule, the values for
   2404      * the local variables are:
   2405      *	$* = member	$@ = lib	$? = member.s2 	$% = member.o.
   2406      * Additionally, for the .s2.a inference rule:
   2407      *	$< = member.s2
   2408      *
   2409      * ARCHIVE and MEMBER are used by Arch_MTime() to find the modification
   2410      * time.
   2411      */
   2412     Var_Set(ARCHIVE, lib, target, 0);
   2413     Var_Set(MEMBER, member, target, 0);
   2414     Var_Set(TARGET, lib, target, 0);
   2415 
   2416     if (suffix == NULL && memberLen > 2 && strcmp(memberEnd - 2, ".o") == 0)
   2417     {
   2418 	/*
   2419 	 * POSIX compatibility: in case ".o" was not a known suffix, force it.
   2420 	 * The target is not POSIX compliant if a suffix other than ".o" was
   2421 	 * already matched, so there's no need to try to force e.g. ".fo.o"
   2422 	 * or "o" into ".o".  (Compliant suffixes start with a period
   2423 	 * and contain neither periods nor slashes.)
   2424 	 */
   2425 	*(memberEnd - 2) = '\0';
   2426 	Var_Set(PREFIX, member, target, 0);
   2427 	*(memberEnd - 2) = '.';
   2428     } else
   2429 	SuffSetPrefixLocalVar(suffix, member, target);
   2430 
   2431     SuffExpandChildren(target, Lst_First(target->children));
   2432 
   2433     free(lib);
   2434     free(member);
   2435 }
   2436 
   2437 /*-
   2438  *-----------------------------------------------------------------------
   2439  * SuffFindNormalDeps -- locate dependencies for regular targets.
   2440  *
   2441  * If the target does not have an explicit rule a suffix transformation
   2442  * rule search is performed to see if it can be inferred.
   2443  *
   2444  * Input:
   2445  *	target	Node for which to find sources.
   2446  *	cleanup	List to add all created Srcs into, so the caller can
   2447  *		destroy them.
   2448  *
   2449  * Results:
   2450  *	None.
   2451  *
   2452  * Side Effects:
   2453  *	Same as Suff_FindDeps.
   2454  *-----------------------------------------------------------------------
   2455  */
   2456 
   2457 static void
   2458 SuffFindNormalDeps(GNode *target, Lst cleanup)
   2459 {
   2460     Lst possible;	/* List of possible transformations (Src). */
   2461     Suff *suffix;	/* The suffix that applies to target. */
   2462     Src *bottom;	/* Start of found transformation chain. */
   2463 
   2464     possible = Lst_Init(FALSE);
   2465     suffix = NULL;
   2466     bottom = NULL;
   2467 
   2468     /*
   2469      * Explicit rules always take precedence.  Explicit <=> appeared as
   2470      * a target in a rule with commands.
   2471      */
   2472     if (!OP_NOP(target->type) && !Lst_IsEmpty(target->commands)) {
   2473 	SuffDebug("\tIt has an explicit rule.\n");
   2474 	suffix = SuffFirstKnownSuffix(target->name);
   2475     	goto expand_children;
   2476     }
   2477 
   2478     /*
   2479      * Try transformation rules.  They're used to make files from other files,
   2480      * so don't try them for .PHONY targets, which are not actual files.
   2481      * All suffixes are accepted, not just POSIX ones (\.[^./]+), so more
   2482      * than one may match.  Matching ones are collected in .SUFFIXES order
   2483      * and the one to give the shortest working chain is used for creating
   2484      * the missing links and setting PREFIX.  In the case that at least one
   2485      * suffix matched but none resulted in a chain, use the first one to set
   2486      * PREFIX.
   2487      */
   2488     if (!(target->type & OP_PHONY)) {
   2489 	LstNode ln;
   2490 	SuffixCmpData sd;
   2491 
   2492 	sd.len = strlen(target->name);
   2493 	sd.ename = target->name + sd.len;
   2494 
   2495 	SuffDebug("\tTrying double suffix transformations.\n");
   2496 	for (ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP); ln != NULL;
   2497 	    ln = Lst_FindFrom(sufflist, Lst_Succ(ln), &sd, SuffSuffIsSuffixP))
   2498 	{
   2499             if (suffix == NULL)
   2500                 suffix = (Suff *)Lst_Datum(ln);
   2501 	    SuffAddLevelForSuffix((Suff *)Lst_Datum(ln), possible, target,
   2502 		cleanup);
   2503 	}
   2504 
   2505 	if (suffix == NULL) {
   2506 	    SuffDebug("\tNo known suffix, trying single suffix "
   2507 		"transformations.\n");
   2508 	    SuffAddLevelForSuffix(emptySuff, possible, target, cleanup);
   2509 
   2510 	    if (nullSuff != NULL) {
   2511 		SuffDebug("\tTrying with .NULL too.\n");
   2512 		nullSuff->flags |= SUFF_NULL;
   2513 		SuffAddLevelForSuffix(nullSuff, possible, target, cleanup);
   2514 		nullSuff->flags &= ~SUFF_NULL;
   2515 	    }
   2516 	}
   2517 
   2518 	bottom = SuffFindThem(possible, cleanup);
   2519     }
   2520 
   2521     if (bottom != NULL) {
   2522 	suffix = SuffApplyTransformations(bottom, target);
   2523     } else {
   2524 	/* If there's no transformation, try search paths. */
   2525 	SuffDebug("\tNo transformations, trying path search.\n");
   2526 
   2527 	if ((target->type & (OP_PHONY|OP_NOPATH)) == 0) {
   2528 	    free(target->path);
   2529 	    target->path = Dir_FindFile(target->name,
   2530 		(suffix == NULL ? dirSearchPath : suffix->searchPath));
   2531 	}
   2532     }
   2533 
   2534 expand_children:
   2535     SuffSetSuffix(target, suffix);
   2536 
   2537     Var_Set(TARGET, (target->path ? target->path : target->name), target, 0);
   2538     if (bottom != NULL)
   2539 	/* Only because of nullSuff: use "" instead of the real suffix. */
   2540 	SuffSetPrefixLocalVar(NULL, bottom->pref, target);
   2541     else
   2542 	SuffSetPrefixLocalVar(target->suffix, target->name, target);
   2543 
   2544     SuffExpandChildren(target, Lst_First(target->children));
   2545 }
   2546 
   2547 
   2548 /*-
   2549  *-----------------------------------------------------------------------
   2550  * Suff_FindDeps  --
   2551  *	Do suffix transformation rule search for the given target.
   2552  *	Explicit rules always take precedence, so the search will not be
   2553  *	done, if an explicit rule is detected.
   2554  *
   2555  * Input:
   2556  *	gn	node to check inference rules for
   2557  *
   2558  * Results:
   2559  *	Nothing.
   2560  *
   2561  * Side Effects:
   2562  *	Nodes may be added as dependencies to the target if implied so
   2563  *	by suffix search.  Any newly created nodes are also added to
   2564  *	the graph.  The implied sources are linked via their iParents
   2565  *	field to the target that uses them so the target will get its
   2566  *	IMPSRC variable filled in properly later.
   2567  *
   2568  *	The TARGET, PREFIX, ARCHIVE and MEMBER variables get set on
   2569  *	the target and its children as needed.
   2570  *
   2571  * Notes:
   2572  *	The path found by this target is the shortest path in the
   2573  *	transformation graph, which may pass through non-existent targets,
   2574  *	to an existing target. The search continues on all paths from the
   2575  *	root suffix until a file or an existing target node is found.
   2576  *	I.e. if there's a path .o -> .c -> .l -> .l,v from the root and
   2577  *	the .l,v file exists but the .c and .l files don't, the search
   2578  *	will branch out in all directions from .o and again from all
   2579  *	the nodes on the next level until the .l,v node is encountered.
   2580  *
   2581  *-----------------------------------------------------------------------
   2582  */
   2583 
   2584 void
   2585 Suff_FindDeps(GNode *target)
   2586 {
   2587     /*
   2588      * Storage for all Src structures created during the search.  This is
   2589      * purely a convenience for the implementation of the helper functions.
   2590      * This way there does not need to be logic for deciding what is safe
   2591      * to remove and what is not.  After the search is complete, they can
   2592      * all be safely removed.
   2593      */
   2594     Lst cleanup = Lst_Init(FALSE);
   2595 
   2596     if (target->type & OP_DEPS_FOUND) {
   2597 	/*
   2598 	 * If dependencies already found, no need to do it again...
   2599 	 */
   2600 	return;
   2601     } else {
   2602 	target->type |= OP_DEPS_FOUND;
   2603     }
   2604     /*
   2605      * Make sure we have these set, may get revised below.
   2606      */
   2607     Var_Set(TARGET, target->path ? target->path : target->name, target, 0);
   2608     Var_Set(PREFIX, target->name, target, 0);
   2609 
   2610     SuffDebug("SuffFindDeps (%s)\n", target->name);
   2611 
   2612     if (target->type & OP_ARCHV)
   2613 	SuffFindArchiveDeps(target, cleanup);
   2614     else if (target->type & OP_LIB) {
   2615 	/*
   2616 	 * If the node is a library, it is the arch module's job to find it
   2617 	 * and set the TARGET variable accordingly. We merely provide the
   2618 	 * search path, assuming all libraries end in ".a" (if the suffix
   2619 	 * hasn't been defined, there's nothing we can do for it, so we just
   2620 	 * set the TARGET variable to the node's name in order to give it a
   2621 	 * value).
   2622 	 * XXX: try all suffixes with SUFF_LIBRARY set?
   2623 	 */
   2624 	LstNode	ln;
   2625 	Suff	*s;
   2626 
   2627 	ln = Lst_Find(sufflist, LIBSUFF, SuffSuffHasNameP);
   2628 	s = (ln == NULL ? NULL : (Suff *)Lst_Datum(ln));
   2629 	SuffSetSuffix(target, s);
   2630 	if (s != NULL)
   2631 	    Arch_FindLib(target, s->searchPath);
   2632 	else
   2633 	    Var_Set(TARGET, target->name, target, 0);
   2634 	/*
   2635 	 * Because a library (-lfoo) target doesn't follow the standard
   2636 	 * filesystem conventions, we don't set the regular variables for
   2637 	 * the thing. .PREFIX is simply made empty...
   2638 	 */
   2639 	Var_Set(PREFIX, "", target, 0);
   2640     } else
   2641 	SuffFindNormalDeps(target, cleanup);
   2642 
   2643     Lst_Destroy(cleanup, SuffFreeSrc);
   2644 }
   2645 /*-
   2646  *-----------------------------------------------------------------------
   2647  * Suff_SetNull -- define which suffix is the .NULL suffix.
   2648  *
   2649  * Input:
   2650  *	name	Name of null suffix
   2651  *-----------------------------------------------------------------------
   2652  */
   2653 void
   2654 Suff_SetNull(char *name)
   2655 {
   2656     LstNode i;
   2657 
   2658     i = Lst_Find(sufflist, name, SuffSuffHasNameP);
   2659     if (i != NULL) {
   2660 	if (nullSuff != NULL)
   2661 	    --nullSuff->refCount;
   2662 	nullSuff = (Suff *)Lst_Datum(i);
   2663 	++nullSuff->refCount;
   2664     }
   2665     else
   2666 	Parse_Error(PARSE_WARNING,
   2667 	    ".NULL not set because %s is not in .SUFFIXES.", name);
   2668 }
   2669 
   2670 /*-
   2671  *-----------------------------------------------------------------------
   2672  * Suff_Init --
   2673  *	Initialize suffixes module so all of its services can be used.
   2674  *-----------------------------------------------------------------------
   2675  */
   2676 void
   2677 Suff_Init(void)
   2678 {
   2679     sufflist = Lst_Init(FALSE);
   2680     /*
   2681      * Do explicit initialization for .SUFFIXES related things with static
   2682      * initialization because we get called by Suff_ClearSuffixes() too.
   2683      */
   2684     sNum = 0;
   2685     memset(lookup, 0, sizeof(lookup[0]) * LOOKUP_SIZE);
   2686 
   2687     transforms = Lst_Init(FALSE);
   2688 
   2689     emptySuff = SuffNewSuff("");
   2690     emptySuff->sNum = INT_MAX;
   2691     ++emptySuff->refCount;
   2692     Dir_Concat(emptySuff->searchPath, dirSearchPath);
   2693 
   2694     nullSuff = NULL;
   2695 }
   2696 
   2697 
   2698 /*-
   2699  *----------------------------------------------------------------------
   2700  * Suff_End -- release resources used by the module.
   2701  *
   2702  * It is not safe to call functions from this module after calling this.
   2703  *----------------------------------------------------------------------
   2704  */
   2705 void
   2706 Suff_End(void)
   2707 {
   2708 #ifdef CLEANUP
   2709     SuffCleanUp(SCU_END);
   2710 #endif
   2711 }
   2712 
   2713 
   2714 /*
   2715  ******************************************************************************
   2716  *			Debugging Functions
   2717  ******************************************************************************
   2718  */
   2719 
   2720 /*
   2721  *----------------------------------------------------------------------
   2722  * SuffDebug -- print a message to debug_file if debugging is enabled.
   2723  *
   2724  * Input:
   2725  *	fmt	printf format specification
   2726  *	...	print arguments
   2727  *
   2728  * Results:
   2729  *	See vfprintf().
   2730  *----------------------------------------------------------------------
   2731  */
   2732 static int
   2733 SuffDebug(const char * fmt, ...)
   2734 {
   2735     va_list ap;
   2736     int rv;
   2737 
   2738     rv = 0;
   2739     if (DEBUG(SUFF)) {
   2740 	va_start(ap, fmt);
   2741 	rv = vfprintf(debug_file, fmt, ap);
   2742 	va_end(ap);
   2743     }
   2744     return rv;
   2745 }
   2746 
   2747 /*
   2748  *----------------------------------------------------------------------
   2749  * SuffDebugChain -- print transformation chain to debug_file.
   2750  *
   2751  * Print the transformation chain that begins with start in reverse
   2752  * order (end result first).  Each suffix in the chain is printed
   2753  * on one line separated by " <- ".
   2754  *
   2755  * Input:
   2756  *	start	chain's first transformation
   2757  *----------------------------------------------------------------------
   2758  */
   2759 static void
   2760 SuffDebugChain(Src *start)
   2761 {
   2762     if (DEBUG(SUFF)){
   2763 	Lst tmp = Lst_Init(FALSE);
   2764 	Src *i;
   2765 	LstNode j;
   2766 
   2767 	for (i = start; i != NULL; i = i->parent)
   2768 	    Lst_AtFront(tmp, i);
   2769 	fprintf(debug_file, "\t");
   2770 	for (j = Lst_First(tmp); j != NULL; j = Lst_Succ(j)) {
   2771 	    i = (Src *)Lst_Datum(j);
   2772 	    fprintf(debug_file, "`%s' <- ", i->suff->name);
   2773 	}
   2774 	fprintf(debug_file, "\n");
   2775 
   2776 	Lst_Destroy(tmp, NULL);
   2777     }
   2778 }
   2779 
   2780 static int SuffPrintName(void *s, void *unused)
   2781 {
   2782     (void)unused;
   2783     fprintf(debug_file, "`%s' ", ((Suff *)s)->name);
   2784     return 0;
   2785 }
   2786 
   2787 static int
   2788 SuffPrintSuff(void *sp, void *unused)
   2789 {
   2790     Suff    *s = (Suff *)sp;
   2791     int	    flags;
   2792     int	    flag;
   2793 
   2794     (void)unused;
   2795 
   2796     fprintf(debug_file, "# `%s' [%d] ", s->name, s->refCount);
   2797 
   2798     flags = s->flags;
   2799     if (flags) {
   2800 	fputs(" (", debug_file);
   2801 	while (flags) {
   2802 	    flag = 1 << (ffs(flags) - 1);
   2803 	    flags &= ~flag;
   2804 	    switch (flag) {
   2805 		case SUFF_INCLUDE:
   2806 		    fprintf(debug_file, "INCLUDE");
   2807 		    break;
   2808 		case SUFF_LIBRARY:
   2809 		    fprintf(debug_file, "LIBRARY");
   2810 		    break;
   2811 	    }
   2812 	    fputc(flags ? '|' : ')', debug_file);
   2813 	}
   2814     }
   2815     fputc('\n', debug_file);
   2816     fprintf(debug_file, "#\tTo: ");
   2817     Lst_ForEach(s->parents, SuffPrintName, NULL);
   2818     fputc('\n', debug_file);
   2819     fprintf(debug_file, "#\tFrom: ");
   2820     Lst_ForEach(s->children, SuffPrintName, NULL);
   2821     fputc('\n', debug_file);
   2822     fprintf(debug_file, "#\tSearch Path: ");
   2823     Dir_PrintPath(s->searchPath);
   2824     fputc('\n', debug_file);
   2825     return 0;
   2826 }
   2827 
   2828 static int
   2829 SuffPrintTrans(void *tp, void *unused)
   2830 {
   2831     GNode   *t = (GNode *)tp;
   2832 
   2833     (void)unused;
   2834 
   2835     fprintf(debug_file, "%-16s: ", t->name);
   2836     Targ_PrintType(t->type);
   2837     fputc('\n', debug_file);
   2838     Lst_ForEach(t->commands, Targ_PrintCmd, NULL);
   2839     fputc('\n', debug_file);
   2840     return 0;
   2841 }
   2842 
   2843 void
   2844 Suff_PrintAll(void)
   2845 {
   2846     fprintf(debug_file, "#*** Suffixes:\n");
   2847     Lst_ForEach(sufflist, SuffPrintSuff, NULL);
   2848     SuffPrintSuff(emptySuff, NULL);
   2849 
   2850     fprintf(debug_file, "#*** Transformations:\n");
   2851     Lst_ForEach(transforms, SuffPrintTrans, NULL);
   2852 }
   2853