xref: /minix3/usr.bin/make/targ.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: targ.c,v 1.60 2015/05/25 09:01:06 manu Exp $	*/
22e2caf59SThomas Veerman 
32e2caf59SThomas Veerman /*
42e2caf59SThomas Veerman  * Copyright (c) 1988, 1989, 1990, 1993
52e2caf59SThomas Veerman  *	The Regents of the University of California.  All rights reserved.
62e2caf59SThomas Veerman  *
72e2caf59SThomas Veerman  * This code is derived from software contributed to Berkeley by
82e2caf59SThomas Veerman  * Adam de Boor.
92e2caf59SThomas Veerman  *
102e2caf59SThomas Veerman  * Redistribution and use in source and binary forms, with or without
112e2caf59SThomas Veerman  * modification, are permitted provided that the following conditions
122e2caf59SThomas Veerman  * are met:
132e2caf59SThomas Veerman  * 1. Redistributions of source code must retain the above copyright
142e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer.
152e2caf59SThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
162e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
172e2caf59SThomas Veerman  *    documentation and/or other materials provided with the distribution.
182e2caf59SThomas Veerman  * 3. Neither the name of the University nor the names of its contributors
192e2caf59SThomas Veerman  *    may be used to endorse or promote products derived from this software
202e2caf59SThomas Veerman  *    without specific prior written permission.
212e2caf59SThomas Veerman  *
222e2caf59SThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
232e2caf59SThomas Veerman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
242e2caf59SThomas Veerman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
252e2caf59SThomas Veerman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
262e2caf59SThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
272e2caf59SThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
282e2caf59SThomas Veerman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
292e2caf59SThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
302e2caf59SThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
312e2caf59SThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
322e2caf59SThomas Veerman  * SUCH DAMAGE.
332e2caf59SThomas Veerman  */
342e2caf59SThomas Veerman 
352e2caf59SThomas Veerman /*
362e2caf59SThomas Veerman  * Copyright (c) 1989 by Berkeley Softworks
372e2caf59SThomas Veerman  * All rights reserved.
382e2caf59SThomas Veerman  *
392e2caf59SThomas Veerman  * This code is derived from software contributed to Berkeley by
402e2caf59SThomas Veerman  * Adam de Boor.
412e2caf59SThomas Veerman  *
422e2caf59SThomas Veerman  * Redistribution and use in source and binary forms, with or without
432e2caf59SThomas Veerman  * modification, are permitted provided that the following conditions
442e2caf59SThomas Veerman  * are met:
452e2caf59SThomas Veerman  * 1. Redistributions of source code must retain the above copyright
462e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer.
472e2caf59SThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
482e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
492e2caf59SThomas Veerman  *    documentation and/or other materials provided with the distribution.
502e2caf59SThomas Veerman  * 3. All advertising materials mentioning features or use of this software
512e2caf59SThomas Veerman  *    must display the following acknowledgement:
522e2caf59SThomas Veerman  *	This product includes software developed by the University of
532e2caf59SThomas Veerman  *	California, Berkeley and its contributors.
542e2caf59SThomas Veerman  * 4. Neither the name of the University nor the names of its contributors
552e2caf59SThomas Veerman  *    may be used to endorse or promote products derived from this software
562e2caf59SThomas Veerman  *    without specific prior written permission.
572e2caf59SThomas Veerman  *
582e2caf59SThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
592e2caf59SThomas Veerman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
602e2caf59SThomas Veerman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
612e2caf59SThomas Veerman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
622e2caf59SThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
632e2caf59SThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
642e2caf59SThomas Veerman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
652e2caf59SThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
662e2caf59SThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
672e2caf59SThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
682e2caf59SThomas Veerman  * SUCH DAMAGE.
692e2caf59SThomas Veerman  */
702e2caf59SThomas Veerman 
712e2caf59SThomas Veerman #ifndef MAKE_NATIVE
72*0a6a1f1dSLionel Sambuc static char rcsid[] = "$NetBSD: targ.c,v 1.60 2015/05/25 09:01:06 manu Exp $";
732e2caf59SThomas Veerman #else
742e2caf59SThomas Veerman #include <sys/cdefs.h>
752e2caf59SThomas Veerman #ifndef lint
762e2caf59SThomas Veerman #if 0
772e2caf59SThomas Veerman static char sccsid[] = "@(#)targ.c	8.2 (Berkeley) 3/19/94";
782e2caf59SThomas Veerman #else
79*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: targ.c,v 1.60 2015/05/25 09:01:06 manu Exp $");
802e2caf59SThomas Veerman #endif
812e2caf59SThomas Veerman #endif /* not lint */
822e2caf59SThomas Veerman #endif
832e2caf59SThomas Veerman 
842e2caf59SThomas Veerman /*-
852e2caf59SThomas Veerman  * targ.c --
862e2caf59SThomas Veerman  *	Functions for maintaining the Lst allTargets. Target nodes are
872e2caf59SThomas Veerman  * kept in two structures: a Lst, maintained by the list library, and a
882e2caf59SThomas Veerman  * hash table, maintained by the hash library.
892e2caf59SThomas Veerman  *
902e2caf59SThomas Veerman  * Interface:
912e2caf59SThomas Veerman  *	Targ_Init 	    	Initialization procedure.
922e2caf59SThomas Veerman  *
932e2caf59SThomas Veerman  *	Targ_End 	    	Cleanup the module
942e2caf59SThomas Veerman  *
952e2caf59SThomas Veerman  *	Targ_List 	    	Return the list of all targets so far.
962e2caf59SThomas Veerman  *
972e2caf59SThomas Veerman  *	Targ_NewGN	    	Create a new GNode for the passed target
982e2caf59SThomas Veerman  *	    	  	    	(string). The node is *not* placed in the
992e2caf59SThomas Veerman  *	    	  	    	hash table, though all its fields are
1002e2caf59SThomas Veerman  *	    	  	    	initialized.
1012e2caf59SThomas Veerman  *
1022e2caf59SThomas Veerman  *	Targ_FindNode	    	Find the node for a given target, creating
1032e2caf59SThomas Veerman  *	    	  	    	and storing it if it doesn't exist and the
1042e2caf59SThomas Veerman  *	    	  	    	flags are right (TARG_CREATE)
1052e2caf59SThomas Veerman  *
1062e2caf59SThomas Veerman  *	Targ_FindList	    	Given a list of names, find nodes for all
1072e2caf59SThomas Veerman  *	    	  	    	of them. If a name doesn't exist and the
1082e2caf59SThomas Veerman  *	    	  	    	TARG_NOCREATE flag was given, an error message
1092e2caf59SThomas Veerman  *	    	  	    	is printed. Else, if a name doesn't exist,
1102e2caf59SThomas Veerman  *	    	  	    	its node is created.
1112e2caf59SThomas Veerman  *
1122e2caf59SThomas Veerman  *	Targ_Ignore	    	Return TRUE if errors should be ignored when
1132e2caf59SThomas Veerman  *	    	  	    	creating the given target.
1142e2caf59SThomas Veerman  *
1152e2caf59SThomas Veerman  *	Targ_Silent	    	Return TRUE if we should be silent when
1162e2caf59SThomas Veerman  *	    	  	    	creating the given target.
1172e2caf59SThomas Veerman  *
1182e2caf59SThomas Veerman  *	Targ_Precious	    	Return TRUE if the target is precious and
1192e2caf59SThomas Veerman  *	    	  	    	should not be removed if we are interrupted.
1202e2caf59SThomas Veerman  *
1212e2caf59SThomas Veerman  *	Targ_Propagate		Propagate information between related
1222e2caf59SThomas Veerman  *				nodes.	Should be called after the
1232e2caf59SThomas Veerman  *				makefiles are parsed but before any
1242e2caf59SThomas Veerman  *				action is taken.
1252e2caf59SThomas Veerman  *
1262e2caf59SThomas Veerman  * Debugging:
1272e2caf59SThomas Veerman  *	Targ_PrintGraph	    	Print out the entire graphm all variables
1282e2caf59SThomas Veerman  *	    	  	    	and statistics for the directory cache. Should
1292e2caf59SThomas Veerman  *	    	  	    	print something for suffixes, too, but...
1302e2caf59SThomas Veerman  */
1312e2caf59SThomas Veerman 
1322e2caf59SThomas Veerman #include	  <stdio.h>
1332e2caf59SThomas Veerman #include	  <time.h>
1342e2caf59SThomas Veerman 
1352e2caf59SThomas Veerman #include	  "make.h"
1362e2caf59SThomas Veerman #include	  "hash.h"
1372e2caf59SThomas Veerman #include	  "dir.h"
1382e2caf59SThomas Veerman 
1392e2caf59SThomas Veerman static Lst        allTargets;	/* the list of all targets found so far */
1402e2caf59SThomas Veerman #ifdef CLEANUP
1412e2caf59SThomas Veerman static Lst	  allGNs;	/* List of all the GNodes */
1422e2caf59SThomas Veerman #endif
1432e2caf59SThomas Veerman static Hash_Table targets;	/* a hash table of same */
1442e2caf59SThomas Veerman 
1452e2caf59SThomas Veerman #define HTSIZE	191		/* initial size of hash table */
1462e2caf59SThomas Veerman 
1472e2caf59SThomas Veerman static int TargPrintOnlySrc(void *, void *);
1482e2caf59SThomas Veerman static int TargPrintName(void *, void *);
1492e2caf59SThomas Veerman #ifdef CLEANUP
1502e2caf59SThomas Veerman static void TargFreeGN(void *);
1512e2caf59SThomas Veerman #endif
1522e2caf59SThomas Veerman static int TargPropagateCohort(void *, void *);
1532e2caf59SThomas Veerman static int TargPropagateNode(void *, void *);
1542e2caf59SThomas Veerman 
1552e2caf59SThomas Veerman /*-
1562e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1572e2caf59SThomas Veerman  * Targ_Init --
1582e2caf59SThomas Veerman  *	Initialize this module
1592e2caf59SThomas Veerman  *
1602e2caf59SThomas Veerman  * Results:
1612e2caf59SThomas Veerman  *	None
1622e2caf59SThomas Veerman  *
1632e2caf59SThomas Veerman  * Side Effects:
1642e2caf59SThomas Veerman  *	The allTargets list and the targets hash table are initialized
1652e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1662e2caf59SThomas Veerman  */
1672e2caf59SThomas Veerman void
Targ_Init(void)1682e2caf59SThomas Veerman Targ_Init(void)
1692e2caf59SThomas Veerman {
1702e2caf59SThomas Veerman     allTargets = Lst_Init(FALSE);
1712e2caf59SThomas Veerman     Hash_InitTable(&targets, HTSIZE);
1722e2caf59SThomas Veerman }
1732e2caf59SThomas Veerman 
1742e2caf59SThomas Veerman /*-
1752e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1762e2caf59SThomas Veerman  * Targ_End --
1772e2caf59SThomas Veerman  *	Finalize this module
1782e2caf59SThomas Veerman  *
1792e2caf59SThomas Veerman  * Results:
1802e2caf59SThomas Veerman  *	None
1812e2caf59SThomas Veerman  *
1822e2caf59SThomas Veerman  * Side Effects:
1832e2caf59SThomas Veerman  *	All lists and gnodes are cleared
1842e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1852e2caf59SThomas Veerman  */
1862e2caf59SThomas Veerman void
Targ_End(void)1872e2caf59SThomas Veerman Targ_End(void)
1882e2caf59SThomas Veerman {
1892e2caf59SThomas Veerman #ifdef CLEANUP
1902e2caf59SThomas Veerman     Lst_Destroy(allTargets, NULL);
1912e2caf59SThomas Veerman     if (allGNs)
1922e2caf59SThomas Veerman 	Lst_Destroy(allGNs, TargFreeGN);
1932e2caf59SThomas Veerman     Hash_DeleteTable(&targets);
1942e2caf59SThomas Veerman #endif
1952e2caf59SThomas Veerman }
1962e2caf59SThomas Veerman 
1972e2caf59SThomas Veerman /*-
1982e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1992e2caf59SThomas Veerman  * Targ_List --
2002e2caf59SThomas Veerman  *	Return the list of all targets
2012e2caf59SThomas Veerman  *
2022e2caf59SThomas Veerman  * Results:
2032e2caf59SThomas Veerman  *	The list of all targets.
2042e2caf59SThomas Veerman  *
2052e2caf59SThomas Veerman  * Side Effects:
2062e2caf59SThomas Veerman  *	None
2072e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2082e2caf59SThomas Veerman  */
2092e2caf59SThomas Veerman Lst
Targ_List(void)2102e2caf59SThomas Veerman Targ_List(void)
2112e2caf59SThomas Veerman {
2122e2caf59SThomas Veerman     return allTargets;
2132e2caf59SThomas Veerman }
2142e2caf59SThomas Veerman 
2152e2caf59SThomas Veerman /*-
2162e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2172e2caf59SThomas Veerman  * Targ_NewGN  --
2182e2caf59SThomas Veerman  *	Create and initialize a new graph node
2192e2caf59SThomas Veerman  *
2202e2caf59SThomas Veerman  * Input:
2212e2caf59SThomas Veerman  *	name		the name to stick in the new node
2222e2caf59SThomas Veerman  *
2232e2caf59SThomas Veerman  * Results:
2242e2caf59SThomas Veerman  *	An initialized graph node with the name field filled with a copy
2252e2caf59SThomas Veerman  *	of the passed name
2262e2caf59SThomas Veerman  *
2272e2caf59SThomas Veerman  * Side Effects:
2282e2caf59SThomas Veerman  *	The gnode is added to the list of all gnodes.
2292e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2302e2caf59SThomas Veerman  */
2312e2caf59SThomas Veerman GNode *
Targ_NewGN(const char * name)2322e2caf59SThomas Veerman Targ_NewGN(const char *name)
2332e2caf59SThomas Veerman {
2342e2caf59SThomas Veerman     GNode *gn;
2352e2caf59SThomas Veerman 
2362e2caf59SThomas Veerman     gn = bmake_malloc(sizeof(GNode));
2372e2caf59SThomas Veerman     gn->name = bmake_strdup(name);
2382e2caf59SThomas Veerman     gn->uname = NULL;
2392e2caf59SThomas Veerman     gn->path = NULL;
2402e2caf59SThomas Veerman     if (name[0] == '-' && name[1] == 'l') {
2412e2caf59SThomas Veerman 	gn->type = OP_LIB;
2422e2caf59SThomas Veerman     } else {
2432e2caf59SThomas Veerman 	gn->type = 0;
2442e2caf59SThomas Veerman     }
2452e2caf59SThomas Veerman     gn->unmade =    	0;
2462e2caf59SThomas Veerman     gn->unmade_cohorts = 0;
2472e2caf59SThomas Veerman     gn->cohort_num[0] = 0;
2482e2caf59SThomas Veerman     gn->centurion =    	NULL;
2492e2caf59SThomas Veerman     gn->made = 	    	UNMADE;
2502e2caf59SThomas Veerman     gn->flags = 	0;
2512e2caf59SThomas Veerman     gn->checked =	0;
2522e2caf59SThomas Veerman     gn->mtime =		0;
2532e2caf59SThomas Veerman     gn->cmgn =		NULL;
2542e2caf59SThomas Veerman     gn->iParents =  	Lst_Init(FALSE);
2552e2caf59SThomas Veerman     gn->cohorts =   	Lst_Init(FALSE);
2562e2caf59SThomas Veerman     gn->parents =   	Lst_Init(FALSE);
2572e2caf59SThomas Veerman     gn->children =  	Lst_Init(FALSE);
2582e2caf59SThomas Veerman     gn->order_pred =  	Lst_Init(FALSE);
2592e2caf59SThomas Veerman     gn->order_succ =  	Lst_Init(FALSE);
2602e2caf59SThomas Veerman     Hash_InitTable(&gn->context, 0);
2612e2caf59SThomas Veerman     gn->commands =  	Lst_Init(FALSE);
2622e2caf59SThomas Veerman     gn->suffix =	NULL;
2632e2caf59SThomas Veerman     gn->lineno =	0;
2642e2caf59SThomas Veerman     gn->fname = 	NULL;
2652e2caf59SThomas Veerman 
2662e2caf59SThomas Veerman #ifdef CLEANUP
2672e2caf59SThomas Veerman     if (allGNs == NULL)
2682e2caf59SThomas Veerman 	allGNs = Lst_Init(FALSE);
2692e2caf59SThomas Veerman     Lst_AtEnd(allGNs, gn);
2702e2caf59SThomas Veerman #endif
2712e2caf59SThomas Veerman 
2722e2caf59SThomas Veerman     return (gn);
2732e2caf59SThomas Veerman }
2742e2caf59SThomas Veerman 
2752e2caf59SThomas Veerman #ifdef CLEANUP
2762e2caf59SThomas Veerman /*-
2772e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2782e2caf59SThomas Veerman  * TargFreeGN  --
2792e2caf59SThomas Veerman  *	Destroy a GNode
2802e2caf59SThomas Veerman  *
2812e2caf59SThomas Veerman  * Results:
2822e2caf59SThomas Veerman  *	None.
2832e2caf59SThomas Veerman  *
2842e2caf59SThomas Veerman  * Side Effects:
2852e2caf59SThomas Veerman  *	None.
2862e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2872e2caf59SThomas Veerman  */
2882e2caf59SThomas Veerman static void
TargFreeGN(void * gnp)2892e2caf59SThomas Veerman TargFreeGN(void *gnp)
2902e2caf59SThomas Veerman {
2912e2caf59SThomas Veerman     GNode *gn = (GNode *)gnp;
2922e2caf59SThomas Veerman 
2932e2caf59SThomas Veerman 
2942e2caf59SThomas Veerman     free(gn->name);
2952e2caf59SThomas Veerman     if (gn->uname)
2962e2caf59SThomas Veerman 	free(gn->uname);
2972e2caf59SThomas Veerman     if (gn->path)
2982e2caf59SThomas Veerman 	free(gn->path);
2992e2caf59SThomas Veerman     /* gn->fname points to name allocated when file was opened, don't free */
3002e2caf59SThomas Veerman 
3012e2caf59SThomas Veerman     Lst_Destroy(gn->iParents, NULL);
3022e2caf59SThomas Veerman     Lst_Destroy(gn->cohorts, NULL);
3032e2caf59SThomas Veerman     Lst_Destroy(gn->parents, NULL);
3042e2caf59SThomas Veerman     Lst_Destroy(gn->children, NULL);
3052e2caf59SThomas Veerman     Lst_Destroy(gn->order_succ, NULL);
3062e2caf59SThomas Veerman     Lst_Destroy(gn->order_pred, NULL);
3072e2caf59SThomas Veerman     Hash_DeleteTable(&gn->context);
3082e2caf59SThomas Veerman     Lst_Destroy(gn->commands, NULL);
3092e2caf59SThomas Veerman     free(gn);
3102e2caf59SThomas Veerman }
3112e2caf59SThomas Veerman #endif
3122e2caf59SThomas Veerman 
3132e2caf59SThomas Veerman 
3142e2caf59SThomas Veerman /*-
3152e2caf59SThomas Veerman  *-----------------------------------------------------------------------
3162e2caf59SThomas Veerman  * Targ_FindNode  --
3172e2caf59SThomas Veerman  *	Find a node in the list using the given name for matching
3182e2caf59SThomas Veerman  *
3192e2caf59SThomas Veerman  * Input:
3202e2caf59SThomas Veerman  *	name		the name to find
3212e2caf59SThomas Veerman  *	flags		flags governing events when target not
3222e2caf59SThomas Veerman  *			found
3232e2caf59SThomas Veerman  *
3242e2caf59SThomas Veerman  * Results:
3252e2caf59SThomas Veerman  *	The node in the list if it was. If it wasn't, return NULL of
3262e2caf59SThomas Veerman  *	flags was TARG_NOCREATE or the newly created and initialized node
3272e2caf59SThomas Veerman  *	if it was TARG_CREATE
3282e2caf59SThomas Veerman  *
3292e2caf59SThomas Veerman  * Side Effects:
3302e2caf59SThomas Veerman  *	Sometimes a node is created and added to the list
3312e2caf59SThomas Veerman  *-----------------------------------------------------------------------
3322e2caf59SThomas Veerman  */
3332e2caf59SThomas Veerman GNode *
Targ_FindNode(const char * name,int flags)3342e2caf59SThomas Veerman Targ_FindNode(const char *name, int flags)
3352e2caf59SThomas Veerman {
3362e2caf59SThomas Veerman     GNode         *gn;	      /* node in that element */
337*0a6a1f1dSLionel Sambuc     Hash_Entry	  *he = NULL; /* New or used hash entry for node */
3382e2caf59SThomas Veerman     Boolean	  isNew;      /* Set TRUE if Hash_CreateEntry had to create */
3392e2caf59SThomas Veerman 			      /* an entry for the node */
3402e2caf59SThomas Veerman 
3412e2caf59SThomas Veerman     if (!(flags & (TARG_CREATE | TARG_NOHASH))) {
3422e2caf59SThomas Veerman 	he = Hash_FindEntry(&targets, name);
3432e2caf59SThomas Veerman 	if (he == NULL)
3442e2caf59SThomas Veerman 	    return NULL;
3452e2caf59SThomas Veerman 	return (GNode *)Hash_GetValue(he);
3462e2caf59SThomas Veerman     }
3472e2caf59SThomas Veerman 
3482e2caf59SThomas Veerman     if (!(flags & TARG_NOHASH)) {
3492e2caf59SThomas Veerman 	he = Hash_CreateEntry(&targets, name, &isNew);
3502e2caf59SThomas Veerman 	if (!isNew)
3512e2caf59SThomas Veerman 	    return (GNode *)Hash_GetValue(he);
3522e2caf59SThomas Veerman     }
3532e2caf59SThomas Veerman 
3542e2caf59SThomas Veerman     gn = Targ_NewGN(name);
3552e2caf59SThomas Veerman     if (!(flags & TARG_NOHASH))
3562e2caf59SThomas Veerman 	Hash_SetValue(he, gn);
3572e2caf59SThomas Veerman     Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
3582e2caf59SThomas Veerman     (void)Lst_AtEnd(allTargets, gn);
3592e2caf59SThomas Veerman     if (doing_depend)
3602e2caf59SThomas Veerman 	gn->flags |= FROM_DEPEND;
3612e2caf59SThomas Veerman     return gn;
3622e2caf59SThomas Veerman }
3632e2caf59SThomas Veerman 
3642e2caf59SThomas Veerman /*-
3652e2caf59SThomas Veerman  *-----------------------------------------------------------------------
3662e2caf59SThomas Veerman  * Targ_FindList --
3672e2caf59SThomas Veerman  *	Make a complete list of GNodes from the given list of names
3682e2caf59SThomas Veerman  *
3692e2caf59SThomas Veerman  * Input:
3702e2caf59SThomas Veerman  *	name		list of names to find
3712e2caf59SThomas Veerman  *	flags		flags used if no node is found for a given name
3722e2caf59SThomas Veerman  *
3732e2caf59SThomas Veerman  * Results:
3742e2caf59SThomas Veerman  *	A complete list of graph nodes corresponding to all instances of all
3752e2caf59SThomas Veerman  *	the names in names.
3762e2caf59SThomas Veerman  *
3772e2caf59SThomas Veerman  * Side Effects:
3782e2caf59SThomas Veerman  *	If flags is TARG_CREATE, nodes will be created for all names in
3792e2caf59SThomas Veerman  *	names which do not yet have graph nodes. If flags is TARG_NOCREATE,
3802e2caf59SThomas Veerman  *	an error message will be printed for each name which can't be found.
3812e2caf59SThomas Veerman  * -----------------------------------------------------------------------
3822e2caf59SThomas Veerman  */
3832e2caf59SThomas Veerman Lst
Targ_FindList(Lst names,int flags)3842e2caf59SThomas Veerman Targ_FindList(Lst names, int flags)
3852e2caf59SThomas Veerman {
3862e2caf59SThomas Veerman     Lst            nodes;	/* result list */
3872e2caf59SThomas Veerman     LstNode	   ln;		/* name list element */
3882e2caf59SThomas Veerman     GNode	   *gn;		/* node in tLn */
3892e2caf59SThomas Veerman     char    	   *name;
3902e2caf59SThomas Veerman 
3912e2caf59SThomas Veerman     nodes = Lst_Init(FALSE);
3922e2caf59SThomas Veerman 
3932e2caf59SThomas Veerman     if (Lst_Open(names) == FAILURE) {
3942e2caf59SThomas Veerman 	return (nodes);
3952e2caf59SThomas Veerman     }
3962e2caf59SThomas Veerman     while ((ln = Lst_Next(names)) != NULL) {
3972e2caf59SThomas Veerman 	name = (char *)Lst_Datum(ln);
3982e2caf59SThomas Veerman 	gn = Targ_FindNode(name, flags);
3992e2caf59SThomas Veerman 	if (gn != NULL) {
4002e2caf59SThomas Veerman 	    /*
4012e2caf59SThomas Veerman 	     * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
4022e2caf59SThomas Veerman 	     * are added to the list in the order in which they were
4032e2caf59SThomas Veerman 	     * encountered in the makefile.
4042e2caf59SThomas Veerman 	     */
4052e2caf59SThomas Veerman 	    (void)Lst_AtEnd(nodes, gn);
4062e2caf59SThomas Veerman 	} else if (flags == TARG_NOCREATE) {
4072e2caf59SThomas Veerman 	    Error("\"%s\" -- target unknown.", name);
4082e2caf59SThomas Veerman 	}
4092e2caf59SThomas Veerman     }
4102e2caf59SThomas Veerman     Lst_Close(names);
4112e2caf59SThomas Veerman     return (nodes);
4122e2caf59SThomas Veerman }
4132e2caf59SThomas Veerman 
4142e2caf59SThomas Veerman /*-
4152e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4162e2caf59SThomas Veerman  * Targ_Ignore  --
4172e2caf59SThomas Veerman  *	Return true if should ignore errors when creating gn
4182e2caf59SThomas Veerman  *
4192e2caf59SThomas Veerman  * Input:
4202e2caf59SThomas Veerman  *	gn		node to check for
4212e2caf59SThomas Veerman  *
4222e2caf59SThomas Veerman  * Results:
4232e2caf59SThomas Veerman  *	TRUE if should ignore errors
4242e2caf59SThomas Veerman  *
4252e2caf59SThomas Veerman  * Side Effects:
4262e2caf59SThomas Veerman  *	None
4272e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4282e2caf59SThomas Veerman  */
4292e2caf59SThomas Veerman Boolean
Targ_Ignore(GNode * gn)4302e2caf59SThomas Veerman Targ_Ignore(GNode *gn)
4312e2caf59SThomas Veerman {
4322e2caf59SThomas Veerman     if (ignoreErrors || gn->type & OP_IGNORE) {
4332e2caf59SThomas Veerman 	return (TRUE);
4342e2caf59SThomas Veerman     } else {
4352e2caf59SThomas Veerman 	return (FALSE);
4362e2caf59SThomas Veerman     }
4372e2caf59SThomas Veerman }
4382e2caf59SThomas Veerman 
4392e2caf59SThomas Veerman /*-
4402e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4412e2caf59SThomas Veerman  * Targ_Silent  --
4422e2caf59SThomas Veerman  *	Return true if be silent when creating gn
4432e2caf59SThomas Veerman  *
4442e2caf59SThomas Veerman  * Input:
4452e2caf59SThomas Veerman  *	gn		node to check for
4462e2caf59SThomas Veerman  *
4472e2caf59SThomas Veerman  * Results:
4482e2caf59SThomas Veerman  *	TRUE if should be silent
4492e2caf59SThomas Veerman  *
4502e2caf59SThomas Veerman  * Side Effects:
4512e2caf59SThomas Veerman  *	None
4522e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4532e2caf59SThomas Veerman  */
4542e2caf59SThomas Veerman Boolean
Targ_Silent(GNode * gn)4552e2caf59SThomas Veerman Targ_Silent(GNode *gn)
4562e2caf59SThomas Veerman {
4572e2caf59SThomas Veerman     if (beSilent || gn->type & OP_SILENT) {
4582e2caf59SThomas Veerman 	return (TRUE);
4592e2caf59SThomas Veerman     } else {
4602e2caf59SThomas Veerman 	return (FALSE);
4612e2caf59SThomas Veerman     }
4622e2caf59SThomas Veerman }
4632e2caf59SThomas Veerman 
4642e2caf59SThomas Veerman /*-
4652e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4662e2caf59SThomas Veerman  * Targ_Precious --
4672e2caf59SThomas Veerman  *	See if the given target is precious
4682e2caf59SThomas Veerman  *
4692e2caf59SThomas Veerman  * Input:
4702e2caf59SThomas Veerman  *	gn		the node to check
4712e2caf59SThomas Veerman  *
4722e2caf59SThomas Veerman  * Results:
4732e2caf59SThomas Veerman  *	TRUE if it is precious. FALSE otherwise
4742e2caf59SThomas Veerman  *
4752e2caf59SThomas Veerman  * Side Effects:
4762e2caf59SThomas Veerman  *	None
4772e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4782e2caf59SThomas Veerman  */
4792e2caf59SThomas Veerman Boolean
Targ_Precious(GNode * gn)4802e2caf59SThomas Veerman Targ_Precious(GNode *gn)
4812e2caf59SThomas Veerman {
4822e2caf59SThomas Veerman     if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) {
4832e2caf59SThomas Veerman 	return (TRUE);
4842e2caf59SThomas Veerman     } else {
4852e2caf59SThomas Veerman 	return (FALSE);
4862e2caf59SThomas Veerman     }
4872e2caf59SThomas Veerman }
4882e2caf59SThomas Veerman 
4892e2caf59SThomas Veerman /******************* DEBUG INFO PRINTING ****************/
4902e2caf59SThomas Veerman 
4912e2caf59SThomas Veerman static GNode	  *mainTarg;	/* the main target, as set by Targ_SetMain */
4922e2caf59SThomas Veerman /*-
4932e2caf59SThomas Veerman  *-----------------------------------------------------------------------
4942e2caf59SThomas Veerman  * Targ_SetMain --
4952e2caf59SThomas Veerman  *	Set our idea of the main target we'll be creating. Used for
4962e2caf59SThomas Veerman  *	debugging output.
4972e2caf59SThomas Veerman  *
4982e2caf59SThomas Veerman  * Input:
4992e2caf59SThomas Veerman  *	gn		The main target we'll create
5002e2caf59SThomas Veerman  *
5012e2caf59SThomas Veerman  * Results:
5022e2caf59SThomas Veerman  *	None.
5032e2caf59SThomas Veerman  *
5042e2caf59SThomas Veerman  * Side Effects:
5052e2caf59SThomas Veerman  *	"mainTarg" is set to the main target's node.
5062e2caf59SThomas Veerman  *-----------------------------------------------------------------------
5072e2caf59SThomas Veerman  */
5082e2caf59SThomas Veerman void
Targ_SetMain(GNode * gn)5092e2caf59SThomas Veerman Targ_SetMain(GNode *gn)
5102e2caf59SThomas Veerman {
5112e2caf59SThomas Veerman     mainTarg = gn;
5122e2caf59SThomas Veerman }
5132e2caf59SThomas Veerman 
5142e2caf59SThomas Veerman static int
TargPrintName(void * gnp,void * pflags MAKE_ATTR_UNUSED)5152bc7c627SLionel Sambuc TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED)
5162e2caf59SThomas Veerman {
5172e2caf59SThomas Veerman     GNode *gn = (GNode *)gnp;
5182e2caf59SThomas Veerman 
5192e2caf59SThomas Veerman     fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num);
5202e2caf59SThomas Veerman 
5212e2caf59SThomas Veerman     return 0;
5222e2caf59SThomas Veerman }
5232e2caf59SThomas Veerman 
5242e2caf59SThomas Veerman 
5252e2caf59SThomas Veerman int
Targ_PrintCmd(void * cmd,void * dummy)5262e2caf59SThomas Veerman Targ_PrintCmd(void *cmd, void *dummy)
5272e2caf59SThomas Veerman {
5282e2caf59SThomas Veerman     fprintf(debug_file, "\t%s\n", (char *)cmd);
5292e2caf59SThomas Veerman     return (dummy ? 0 : 0);
5302e2caf59SThomas Veerman }
5312e2caf59SThomas Veerman 
5322e2caf59SThomas Veerman /*-
5332e2caf59SThomas Veerman  *-----------------------------------------------------------------------
5342e2caf59SThomas Veerman  * Targ_FmtTime --
5352e2caf59SThomas Veerman  *	Format a modification time in some reasonable way and return it.
5362e2caf59SThomas Veerman  *
5372e2caf59SThomas Veerman  * Results:
5382e2caf59SThomas Veerman  *	The time reformatted.
5392e2caf59SThomas Veerman  *
5402e2caf59SThomas Veerman  * Side Effects:
5412e2caf59SThomas Veerman  *	The time is placed in a static area, so it is overwritten
5422e2caf59SThomas Veerman  *	with each call.
5432e2caf59SThomas Veerman  *
5442e2caf59SThomas Veerman  *-----------------------------------------------------------------------
5452e2caf59SThomas Veerman  */
5462e2caf59SThomas Veerman char *
Targ_FmtTime(time_t tm)5472e2caf59SThomas Veerman Targ_FmtTime(time_t tm)
5482e2caf59SThomas Veerman {
5492e2caf59SThomas Veerman     struct tm	  	*parts;
5502e2caf59SThomas Veerman     static char	  	buf[128];
5512e2caf59SThomas Veerman 
5522e2caf59SThomas Veerman     parts = localtime(&tm);
5532e2caf59SThomas Veerman     (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
5542e2caf59SThomas Veerman     return(buf);
5552e2caf59SThomas Veerman }
5562e2caf59SThomas Veerman 
5572e2caf59SThomas Veerman /*-
5582e2caf59SThomas Veerman  *-----------------------------------------------------------------------
5592e2caf59SThomas Veerman  * Targ_PrintType --
5602e2caf59SThomas Veerman  *	Print out a type field giving only those attributes the user can
5612e2caf59SThomas Veerman  *	set.
5622e2caf59SThomas Veerman  *
5632e2caf59SThomas Veerman  * Results:
5642e2caf59SThomas Veerman  *
5652e2caf59SThomas Veerman  * Side Effects:
5662e2caf59SThomas Veerman  *
5672e2caf59SThomas Veerman  *-----------------------------------------------------------------------
5682e2caf59SThomas Veerman  */
5692e2caf59SThomas Veerman void
Targ_PrintType(int type)5702e2caf59SThomas Veerman Targ_PrintType(int type)
5712e2caf59SThomas Veerman {
5722e2caf59SThomas Veerman     int    tbit;
5732e2caf59SThomas Veerman 
5742e2caf59SThomas Veerman #define PRINTBIT(attr)	case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break
5752e2caf59SThomas Veerman #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break
5762e2caf59SThomas Veerman 
5772e2caf59SThomas Veerman     type &= ~OP_OPMASK;
5782e2caf59SThomas Veerman 
5792e2caf59SThomas Veerman     while (type) {
5802e2caf59SThomas Veerman 	tbit = 1 << (ffs(type) - 1);
5812e2caf59SThomas Veerman 	type &= ~tbit;
5822e2caf59SThomas Veerman 
5832e2caf59SThomas Veerman 	switch(tbit) {
5842e2caf59SThomas Veerman 	    PRINTBIT(OPTIONAL);
5852e2caf59SThomas Veerman 	    PRINTBIT(USE);
5862e2caf59SThomas Veerman 	    PRINTBIT(EXEC);
5872e2caf59SThomas Veerman 	    PRINTBIT(IGNORE);
5882e2caf59SThomas Veerman 	    PRINTBIT(PRECIOUS);
5892e2caf59SThomas Veerman 	    PRINTBIT(SILENT);
5902e2caf59SThomas Veerman 	    PRINTBIT(MAKE);
5912e2caf59SThomas Veerman 	    PRINTBIT(JOIN);
5922e2caf59SThomas Veerman 	    PRINTBIT(INVISIBLE);
5932e2caf59SThomas Veerman 	    PRINTBIT(NOTMAIN);
5942e2caf59SThomas Veerman 	    PRINTDBIT(LIB);
5952e2caf59SThomas Veerman 	    /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
5962e2caf59SThomas Veerman 	    case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break;
5972e2caf59SThomas Veerman 	    PRINTDBIT(ARCHV);
5982e2caf59SThomas Veerman 	    PRINTDBIT(MADE);
5992e2caf59SThomas Veerman 	    PRINTDBIT(PHONY);
6002e2caf59SThomas Veerman 	}
6012e2caf59SThomas Veerman     }
6022e2caf59SThomas Veerman }
6032e2caf59SThomas Veerman 
6042e2caf59SThomas Veerman static const char *
made_name(enum enum_made made)6052e2caf59SThomas Veerman made_name(enum enum_made made)
6062e2caf59SThomas Veerman {
6072e2caf59SThomas Veerman     switch (made) {
6082e2caf59SThomas Veerman     case UNMADE:     return "unmade";
6092e2caf59SThomas Veerman     case DEFERRED:   return "deferred";
6102e2caf59SThomas Veerman     case REQUESTED:  return "requested";
6112e2caf59SThomas Veerman     case BEINGMADE:  return "being made";
6122e2caf59SThomas Veerman     case MADE:       return "made";
6132e2caf59SThomas Veerman     case UPTODATE:   return "up-to-date";
6142e2caf59SThomas Veerman     case ERROR:      return "error when made";
6152e2caf59SThomas Veerman     case ABORTED:    return "aborted";
6162e2caf59SThomas Veerman     default:         return "unknown enum_made value";
6172e2caf59SThomas Veerman     }
6182e2caf59SThomas Veerman }
6192e2caf59SThomas Veerman 
6202e2caf59SThomas Veerman /*-
6212e2caf59SThomas Veerman  *-----------------------------------------------------------------------
6222e2caf59SThomas Veerman  * TargPrintNode --
6232e2caf59SThomas Veerman  *	print the contents of a node
6242e2caf59SThomas Veerman  *-----------------------------------------------------------------------
6252e2caf59SThomas Veerman  */
6262e2caf59SThomas Veerman int
Targ_PrintNode(void * gnp,void * passp)6272e2caf59SThomas Veerman Targ_PrintNode(void *gnp, void *passp)
6282e2caf59SThomas Veerman {
6292e2caf59SThomas Veerman     GNode         *gn = (GNode *)gnp;
6302e2caf59SThomas Veerman     int	    	  pass = passp ? *(int *)passp : 0;
6312e2caf59SThomas Veerman 
6322e2caf59SThomas Veerman     fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n",
6332e2caf59SThomas Veerman 	    gn->name, gn->cohort_num, gn->flags, gn->type, gn->made);
6342e2caf59SThomas Veerman     if (gn->flags == 0)
6352e2caf59SThomas Veerman 	return 0;
6362e2caf59SThomas Veerman 
6372e2caf59SThomas Veerman     if (!OP_NOP(gn->type)) {
6382e2caf59SThomas Veerman 	fprintf(debug_file, "#\n");
6392e2caf59SThomas Veerman 	if (gn == mainTarg) {
6402e2caf59SThomas Veerman 	    fprintf(debug_file, "# *** MAIN TARGET ***\n");
6412e2caf59SThomas Veerman 	}
6422e2caf59SThomas Veerman 	if (pass >= 2) {
6432e2caf59SThomas Veerman 	    if (gn->unmade) {
6442e2caf59SThomas Veerman 		fprintf(debug_file, "# %d unmade children\n", gn->unmade);
6452e2caf59SThomas Veerman 	    } else {
6462e2caf59SThomas Veerman 		fprintf(debug_file, "# No unmade children\n");
6472e2caf59SThomas Veerman 	    }
6482e2caf59SThomas Veerman 	    if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
6492e2caf59SThomas Veerman 		if (gn->mtime != 0) {
6502e2caf59SThomas Veerman 		    fprintf(debug_file, "# last modified %s: %s\n",
6512e2caf59SThomas Veerman 			      Targ_FmtTime(gn->mtime),
6522e2caf59SThomas Veerman 			      made_name(gn->made));
6532e2caf59SThomas Veerman 		} else if (gn->made != UNMADE) {
6542e2caf59SThomas Veerman 		    fprintf(debug_file, "# non-existent (maybe): %s\n",
6552e2caf59SThomas Veerman 			      made_name(gn->made));
6562e2caf59SThomas Veerman 		} else {
6572e2caf59SThomas Veerman 		    fprintf(debug_file, "# unmade\n");
6582e2caf59SThomas Veerman 		}
6592e2caf59SThomas Veerman 	    }
6602e2caf59SThomas Veerman 	    if (!Lst_IsEmpty (gn->iParents)) {
6612e2caf59SThomas Veerman 		fprintf(debug_file, "# implicit parents: ");
6622e2caf59SThomas Veerman 		Lst_ForEach(gn->iParents, TargPrintName, NULL);
6632e2caf59SThomas Veerman 		fprintf(debug_file, "\n");
6642e2caf59SThomas Veerman 	    }
6652e2caf59SThomas Veerman 	} else {
6662e2caf59SThomas Veerman 	    if (gn->unmade)
6672e2caf59SThomas Veerman 		fprintf(debug_file, "# %d unmade children\n", gn->unmade);
6682e2caf59SThomas Veerman 	}
6692e2caf59SThomas Veerman 	if (!Lst_IsEmpty (gn->parents)) {
6702e2caf59SThomas Veerman 	    fprintf(debug_file, "# parents: ");
6712e2caf59SThomas Veerman 	    Lst_ForEach(gn->parents, TargPrintName, NULL);
6722e2caf59SThomas Veerman 	    fprintf(debug_file, "\n");
6732e2caf59SThomas Veerman 	}
6742e2caf59SThomas Veerman 	if (!Lst_IsEmpty (gn->order_pred)) {
6752e2caf59SThomas Veerman 	    fprintf(debug_file, "# order_pred: ");
6762e2caf59SThomas Veerman 	    Lst_ForEach(gn->order_pred, TargPrintName, NULL);
6772e2caf59SThomas Veerman 	    fprintf(debug_file, "\n");
6782e2caf59SThomas Veerman 	}
6792e2caf59SThomas Veerman 	if (!Lst_IsEmpty (gn->order_succ)) {
6802e2caf59SThomas Veerman 	    fprintf(debug_file, "# order_succ: ");
6812e2caf59SThomas Veerman 	    Lst_ForEach(gn->order_succ, TargPrintName, NULL);
6822e2caf59SThomas Veerman 	    fprintf(debug_file, "\n");
6832e2caf59SThomas Veerman 	}
6842e2caf59SThomas Veerman 
6852e2caf59SThomas Veerman 	fprintf(debug_file, "%-16s", gn->name);
6862e2caf59SThomas Veerman 	switch (gn->type & OP_OPMASK) {
6872e2caf59SThomas Veerman 	    case OP_DEPENDS:
6882e2caf59SThomas Veerman 		fprintf(debug_file, ": "); break;
6892e2caf59SThomas Veerman 	    case OP_FORCE:
6902e2caf59SThomas Veerman 		fprintf(debug_file, "! "); break;
6912e2caf59SThomas Veerman 	    case OP_DOUBLEDEP:
6922e2caf59SThomas Veerman 		fprintf(debug_file, ":: "); break;
6932e2caf59SThomas Veerman 	}
6942e2caf59SThomas Veerman 	Targ_PrintType(gn->type);
6952e2caf59SThomas Veerman 	Lst_ForEach(gn->children, TargPrintName, NULL);
6962e2caf59SThomas Veerman 	fprintf(debug_file, "\n");
6972e2caf59SThomas Veerman 	Lst_ForEach(gn->commands, Targ_PrintCmd, NULL);
6982e2caf59SThomas Veerman 	fprintf(debug_file, "\n\n");
6992e2caf59SThomas Veerman 	if (gn->type & OP_DOUBLEDEP) {
7002e2caf59SThomas Veerman 	    Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass);
7012e2caf59SThomas Veerman 	}
7022e2caf59SThomas Veerman     }
7032e2caf59SThomas Veerman     return (0);
7042e2caf59SThomas Veerman }
7052e2caf59SThomas Veerman 
7062e2caf59SThomas Veerman /*-
7072e2caf59SThomas Veerman  *-----------------------------------------------------------------------
7082e2caf59SThomas Veerman  * TargPrintOnlySrc --
7092e2caf59SThomas Veerman  *	Print only those targets that are just a source.
7102e2caf59SThomas Veerman  *
7112e2caf59SThomas Veerman  * Results:
7122e2caf59SThomas Veerman  *	0.
7132e2caf59SThomas Veerman  *
7142e2caf59SThomas Veerman  * Side Effects:
7152e2caf59SThomas Veerman  *	The name of each file is printed preceded by #\t
7162e2caf59SThomas Veerman  *
7172e2caf59SThomas Veerman  *-----------------------------------------------------------------------
7182e2caf59SThomas Veerman  */
7192e2caf59SThomas Veerman static int
TargPrintOnlySrc(void * gnp,void * dummy MAKE_ATTR_UNUSED)7202bc7c627SLionel Sambuc TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED)
7212e2caf59SThomas Veerman {
7222e2caf59SThomas Veerman     GNode   	  *gn = (GNode *)gnp;
7232e2caf59SThomas Veerman     if (!OP_NOP(gn->type))
7242e2caf59SThomas Veerman 	return 0;
7252e2caf59SThomas Veerman 
7262e2caf59SThomas Veerman     fprintf(debug_file, "#\t%s [%s] ",
7272e2caf59SThomas Veerman 	    gn->name, gn->path ? gn->path : gn->name);
7282e2caf59SThomas Veerman     Targ_PrintType(gn->type);
7292e2caf59SThomas Veerman     fprintf(debug_file, "\n");
7302e2caf59SThomas Veerman 
7312e2caf59SThomas Veerman     return 0;
7322e2caf59SThomas Veerman }
7332e2caf59SThomas Veerman 
7342e2caf59SThomas Veerman /*-
7352e2caf59SThomas Veerman  *-----------------------------------------------------------------------
7362e2caf59SThomas Veerman  * Targ_PrintGraph --
7372e2caf59SThomas Veerman  *	print the entire graph. heh heh
7382e2caf59SThomas Veerman  *
7392e2caf59SThomas Veerman  * Input:
7402e2caf59SThomas Veerman  *	pass		Which pass this is. 1 => no processing
7412e2caf59SThomas Veerman  *			2 => processing done
7422e2caf59SThomas Veerman  *
7432e2caf59SThomas Veerman  * Results:
7442e2caf59SThomas Veerman  *	none
7452e2caf59SThomas Veerman  *
7462e2caf59SThomas Veerman  * Side Effects:
7472e2caf59SThomas Veerman  *	lots o' output
7482e2caf59SThomas Veerman  *-----------------------------------------------------------------------
7492e2caf59SThomas Veerman  */
7502e2caf59SThomas Veerman void
Targ_PrintGraph(int pass)7512e2caf59SThomas Veerman Targ_PrintGraph(int pass)
7522e2caf59SThomas Veerman {
7532e2caf59SThomas Veerman     fprintf(debug_file, "#*** Input graph:\n");
7542e2caf59SThomas Veerman     Lst_ForEach(allTargets, Targ_PrintNode, &pass);
7552e2caf59SThomas Veerman     fprintf(debug_file, "\n\n");
7562e2caf59SThomas Veerman     fprintf(debug_file, "#\n#   Files that are only sources:\n");
7572e2caf59SThomas Veerman     Lst_ForEach(allTargets, TargPrintOnlySrc, NULL);
7582e2caf59SThomas Veerman     fprintf(debug_file, "#*** Global Variables:\n");
7592e2caf59SThomas Veerman     Var_Dump(VAR_GLOBAL);
7602e2caf59SThomas Veerman     fprintf(debug_file, "#*** Command-line Variables:\n");
7612e2caf59SThomas Veerman     Var_Dump(VAR_CMD);
7622e2caf59SThomas Veerman     fprintf(debug_file, "\n");
7632e2caf59SThomas Veerman     Dir_PrintDirectories();
7642e2caf59SThomas Veerman     fprintf(debug_file, "\n");
7652e2caf59SThomas Veerman     Suff_PrintAll();
7662e2caf59SThomas Veerman }
7672e2caf59SThomas Veerman 
7682e2caf59SThomas Veerman /*-
7692e2caf59SThomas Veerman  *-----------------------------------------------------------------------
7702e2caf59SThomas Veerman  * TargPropagateNode --
7712e2caf59SThomas Veerman  *	Propagate information from a single node to related nodes if
7722e2caf59SThomas Veerman  *	appropriate.
7732e2caf59SThomas Veerman  *
7742e2caf59SThomas Veerman  * Input:
7752e2caf59SThomas Veerman  *	gnp		The node that we are processing.
7762e2caf59SThomas Veerman  *
7772e2caf59SThomas Veerman  * Results:
7782e2caf59SThomas Veerman  *	Always returns 0, for the benefit of Lst_ForEach().
7792e2caf59SThomas Veerman  *
7802e2caf59SThomas Veerman  * Side Effects:
7812e2caf59SThomas Veerman  *	Information is propagated from this node to cohort or child
7822e2caf59SThomas Veerman  *	nodes.
7832e2caf59SThomas Veerman  *
7842e2caf59SThomas Veerman  *	If the node was defined with "::", then TargPropagateCohort()
7852e2caf59SThomas Veerman  *	will be called for each cohort node.
7862e2caf59SThomas Veerman  *
7872e2caf59SThomas Veerman  *	If the node has recursive predecessors, then
7882e2caf59SThomas Veerman  *	TargPropagateRecpred() will be called for each recursive
7892e2caf59SThomas Veerman  *	predecessor.
7902e2caf59SThomas Veerman  *-----------------------------------------------------------------------
7912e2caf59SThomas Veerman  */
7922e2caf59SThomas Veerman static int
TargPropagateNode(void * gnp,void * junk MAKE_ATTR_UNUSED)7932bc7c627SLionel Sambuc TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED)
7942e2caf59SThomas Veerman {
7952e2caf59SThomas Veerman     GNode	  *gn = (GNode *)gnp;
7962e2caf59SThomas Veerman 
7972e2caf59SThomas Veerman     if (gn->type & OP_DOUBLEDEP)
7982e2caf59SThomas Veerman 	Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp);
7992e2caf59SThomas Veerman     return (0);
8002e2caf59SThomas Veerman }
8012e2caf59SThomas Veerman 
8022e2caf59SThomas Veerman /*-
8032e2caf59SThomas Veerman  *-----------------------------------------------------------------------
8042e2caf59SThomas Veerman  * TargPropagateCohort --
8052e2caf59SThomas Veerman  *	Propagate some bits in the type mask from a node to
8062e2caf59SThomas Veerman  *	a related cohort node.
8072e2caf59SThomas Veerman  *
8082e2caf59SThomas Veerman  * Input:
8092e2caf59SThomas Veerman  *	cnp		The node that we are processing.
8102e2caf59SThomas Veerman  *	gnp		Another node that has cnp as a cohort.
8112e2caf59SThomas Veerman  *
8122e2caf59SThomas Veerman  * Results:
8132e2caf59SThomas Veerman  *	Always returns 0, for the benefit of Lst_ForEach().
8142e2caf59SThomas Veerman  *
8152e2caf59SThomas Veerman  * Side Effects:
8162e2caf59SThomas Veerman  *	cnp's type bitmask is modified to incorporate some of the
8172e2caf59SThomas Veerman  *	bits from gnp's type bitmask.  (XXX need a better explanation.)
8182e2caf59SThomas Veerman  *-----------------------------------------------------------------------
8192e2caf59SThomas Veerman  */
8202e2caf59SThomas Veerman static int
TargPropagateCohort(void * cgnp,void * pgnp)8212e2caf59SThomas Veerman TargPropagateCohort(void *cgnp, void *pgnp)
8222e2caf59SThomas Veerman {
8232e2caf59SThomas Veerman     GNode	  *cgn = (GNode *)cgnp;
8242e2caf59SThomas Veerman     GNode	  *pgn = (GNode *)pgnp;
8252e2caf59SThomas Veerman 
8262e2caf59SThomas Veerman     cgn->type |= pgn->type & ~OP_OPMASK;
8272e2caf59SThomas Veerman     return (0);
8282e2caf59SThomas Veerman }
8292e2caf59SThomas Veerman 
8302e2caf59SThomas Veerman /*-
8312e2caf59SThomas Veerman  *-----------------------------------------------------------------------
8322e2caf59SThomas Veerman  * Targ_Propagate --
8332e2caf59SThomas Veerman  *	Propagate information between related nodes.  Should be called
8342e2caf59SThomas Veerman  *	after the makefiles are parsed but before any action is taken.
8352e2caf59SThomas Veerman  *
8362e2caf59SThomas Veerman  * Results:
8372e2caf59SThomas Veerman  *	none
8382e2caf59SThomas Veerman  *
8392e2caf59SThomas Veerman  * Side Effects:
8402e2caf59SThomas Veerman  *	Information is propagated between related nodes throughout the
8412e2caf59SThomas Veerman  *	graph.
8422e2caf59SThomas Veerman  *-----------------------------------------------------------------------
8432e2caf59SThomas Veerman  */
8442e2caf59SThomas Veerman void
Targ_Propagate(void)8452e2caf59SThomas Veerman Targ_Propagate(void)
8462e2caf59SThomas Veerman {
8472e2caf59SThomas Veerman     Lst_ForEach(allTargets, TargPropagateNode, NULL);
8482e2caf59SThomas Veerman }
849