xref: /freebsd/contrib/bmake/targ.c (revision 3841c287170be8b1cba4d9adf8e727ecaeb64518)
1*3841c287SSimon J. Gerraty /*	$NetBSD: targ.c,v 1.63 2020/07/03 08:02:55 rillig Exp $	*/
23955d011SMarcel Moolenaar 
33955d011SMarcel Moolenaar /*
43955d011SMarcel Moolenaar  * Copyright (c) 1988, 1989, 1990, 1993
53955d011SMarcel Moolenaar  *	The Regents of the University of California.  All rights reserved.
63955d011SMarcel Moolenaar  *
73955d011SMarcel Moolenaar  * This code is derived from software contributed to Berkeley by
83955d011SMarcel Moolenaar  * Adam de Boor.
93955d011SMarcel Moolenaar  *
103955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
113955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
123955d011SMarcel Moolenaar  * are met:
133955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
143955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
153955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
163955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
173955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
183955d011SMarcel Moolenaar  * 3. Neither the name of the University nor the names of its contributors
193955d011SMarcel Moolenaar  *    may be used to endorse or promote products derived from this software
203955d011SMarcel Moolenaar  *    without specific prior written permission.
213955d011SMarcel Moolenaar  *
223955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233955d011SMarcel Moolenaar  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243955d011SMarcel Moolenaar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253955d011SMarcel Moolenaar  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263955d011SMarcel Moolenaar  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273955d011SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283955d011SMarcel Moolenaar  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293955d011SMarcel Moolenaar  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303955d011SMarcel Moolenaar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313955d011SMarcel Moolenaar  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323955d011SMarcel Moolenaar  * SUCH DAMAGE.
333955d011SMarcel Moolenaar  */
343955d011SMarcel Moolenaar 
353955d011SMarcel Moolenaar /*
363955d011SMarcel Moolenaar  * Copyright (c) 1989 by Berkeley Softworks
373955d011SMarcel Moolenaar  * All rights reserved.
383955d011SMarcel Moolenaar  *
393955d011SMarcel Moolenaar  * This code is derived from software contributed to Berkeley by
403955d011SMarcel Moolenaar  * Adam de Boor.
413955d011SMarcel Moolenaar  *
423955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
433955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
443955d011SMarcel Moolenaar  * are met:
453955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
463955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
473955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
483955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
493955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
503955d011SMarcel Moolenaar  * 3. All advertising materials mentioning features or use of this software
513955d011SMarcel Moolenaar  *    must display the following acknowledgement:
523955d011SMarcel Moolenaar  *	This product includes software developed by the University of
533955d011SMarcel Moolenaar  *	California, Berkeley and its contributors.
543955d011SMarcel Moolenaar  * 4. Neither the name of the University nor the names of its contributors
553955d011SMarcel Moolenaar  *    may be used to endorse or promote products derived from this software
563955d011SMarcel Moolenaar  *    without specific prior written permission.
573955d011SMarcel Moolenaar  *
583955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
593955d011SMarcel Moolenaar  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
603955d011SMarcel Moolenaar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
613955d011SMarcel Moolenaar  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
623955d011SMarcel Moolenaar  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
633955d011SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
643955d011SMarcel Moolenaar  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
653955d011SMarcel Moolenaar  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
663955d011SMarcel Moolenaar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
673955d011SMarcel Moolenaar  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
683955d011SMarcel Moolenaar  * SUCH DAMAGE.
693955d011SMarcel Moolenaar  */
703955d011SMarcel Moolenaar 
713955d011SMarcel Moolenaar #ifndef MAKE_NATIVE
72*3841c287SSimon J. Gerraty static char rcsid[] = "$NetBSD: targ.c,v 1.63 2020/07/03 08:02:55 rillig Exp $";
733955d011SMarcel Moolenaar #else
743955d011SMarcel Moolenaar #include <sys/cdefs.h>
753955d011SMarcel Moolenaar #ifndef lint
763955d011SMarcel Moolenaar #if 0
773955d011SMarcel Moolenaar static char sccsid[] = "@(#)targ.c	8.2 (Berkeley) 3/19/94";
783955d011SMarcel Moolenaar #else
79*3841c287SSimon J. Gerraty __RCSID("$NetBSD: targ.c,v 1.63 2020/07/03 08:02:55 rillig Exp $");
803955d011SMarcel Moolenaar #endif
813955d011SMarcel Moolenaar #endif /* not lint */
823955d011SMarcel Moolenaar #endif
833955d011SMarcel Moolenaar 
843955d011SMarcel Moolenaar /*-
853955d011SMarcel Moolenaar  * targ.c --
863955d011SMarcel Moolenaar  *	Functions for maintaining the Lst allTargets. Target nodes are
873955d011SMarcel Moolenaar  * kept in two structures: a Lst, maintained by the list library, and a
883955d011SMarcel Moolenaar  * hash table, maintained by the hash library.
893955d011SMarcel Moolenaar  *
903955d011SMarcel Moolenaar  * Interface:
913955d011SMarcel Moolenaar  *	Targ_Init 	    	Initialization procedure.
923955d011SMarcel Moolenaar  *
933955d011SMarcel Moolenaar  *	Targ_End 	    	Cleanup the module
943955d011SMarcel Moolenaar  *
953955d011SMarcel Moolenaar  *	Targ_List 	    	Return the list of all targets so far.
963955d011SMarcel Moolenaar  *
973955d011SMarcel Moolenaar  *	Targ_NewGN	    	Create a new GNode for the passed target
983955d011SMarcel Moolenaar  *	    	  	    	(string). The node is *not* placed in the
993955d011SMarcel Moolenaar  *	    	  	    	hash table, though all its fields are
1003955d011SMarcel Moolenaar  *	    	  	    	initialized.
1013955d011SMarcel Moolenaar  *
1023955d011SMarcel Moolenaar  *	Targ_FindNode	    	Find the node for a given target, creating
1033955d011SMarcel Moolenaar  *	    	  	    	and storing it if it doesn't exist and the
1043955d011SMarcel Moolenaar  *	    	  	    	flags are right (TARG_CREATE)
1053955d011SMarcel Moolenaar  *
1063955d011SMarcel Moolenaar  *	Targ_FindList	    	Given a list of names, find nodes for all
1073955d011SMarcel Moolenaar  *	    	  	    	of them. If a name doesn't exist and the
1083955d011SMarcel Moolenaar  *	    	  	    	TARG_NOCREATE flag was given, an error message
1093955d011SMarcel Moolenaar  *	    	  	    	is printed. Else, if a name doesn't exist,
1103955d011SMarcel Moolenaar  *	    	  	    	its node is created.
1113955d011SMarcel Moolenaar  *
1123955d011SMarcel Moolenaar  *	Targ_Ignore	    	Return TRUE if errors should be ignored when
1133955d011SMarcel Moolenaar  *	    	  	    	creating the given target.
1143955d011SMarcel Moolenaar  *
1153955d011SMarcel Moolenaar  *	Targ_Silent	    	Return TRUE if we should be silent when
1163955d011SMarcel Moolenaar  *	    	  	    	creating the given target.
1173955d011SMarcel Moolenaar  *
1183955d011SMarcel Moolenaar  *	Targ_Precious	    	Return TRUE if the target is precious and
1193955d011SMarcel Moolenaar  *	    	  	    	should not be removed if we are interrupted.
1203955d011SMarcel Moolenaar  *
1213955d011SMarcel Moolenaar  *	Targ_Propagate		Propagate information between related
1223955d011SMarcel Moolenaar  *				nodes.	Should be called after the
1233955d011SMarcel Moolenaar  *				makefiles are parsed but before any
1243955d011SMarcel Moolenaar  *				action is taken.
1253955d011SMarcel Moolenaar  *
1263955d011SMarcel Moolenaar  * Debugging:
1273955d011SMarcel Moolenaar  *	Targ_PrintGraph	    	Print out the entire graphm all variables
1283955d011SMarcel Moolenaar  *	    	  	    	and statistics for the directory cache. Should
1293955d011SMarcel Moolenaar  *	    	  	    	print something for suffixes, too, but...
1303955d011SMarcel Moolenaar  */
1313955d011SMarcel Moolenaar 
1323955d011SMarcel Moolenaar #include	  <stdio.h>
1333955d011SMarcel Moolenaar #include	  <time.h>
1343955d011SMarcel Moolenaar 
1353955d011SMarcel Moolenaar #include	  "make.h"
1363955d011SMarcel Moolenaar #include	  "hash.h"
1373955d011SMarcel Moolenaar #include	  "dir.h"
1383955d011SMarcel Moolenaar 
1393955d011SMarcel Moolenaar static Lst        allTargets;	/* the list of all targets found so far */
1403955d011SMarcel Moolenaar #ifdef CLEANUP
1413955d011SMarcel Moolenaar static Lst	  allGNs;	/* List of all the GNodes */
1423955d011SMarcel Moolenaar #endif
1433955d011SMarcel Moolenaar static Hash_Table targets;	/* a hash table of same */
1443955d011SMarcel Moolenaar 
1453955d011SMarcel Moolenaar #define HTSIZE	191		/* initial size of hash table */
1463955d011SMarcel Moolenaar 
1473955d011SMarcel Moolenaar static int TargPrintOnlySrc(void *, void *);
1483955d011SMarcel Moolenaar static int TargPrintName(void *, void *);
1493955d011SMarcel Moolenaar #ifdef CLEANUP
1503955d011SMarcel Moolenaar static void TargFreeGN(void *);
1513955d011SMarcel Moolenaar #endif
1523955d011SMarcel Moolenaar static int TargPropagateCohort(void *, void *);
1533955d011SMarcel Moolenaar static int TargPropagateNode(void *, void *);
1543955d011SMarcel Moolenaar 
1553955d011SMarcel Moolenaar /*-
1563955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
1573955d011SMarcel Moolenaar  * Targ_Init --
1583955d011SMarcel Moolenaar  *	Initialize this module
1593955d011SMarcel Moolenaar  *
1603955d011SMarcel Moolenaar  * Results:
1613955d011SMarcel Moolenaar  *	None
1623955d011SMarcel Moolenaar  *
1633955d011SMarcel Moolenaar  * Side Effects:
1643955d011SMarcel Moolenaar  *	The allTargets list and the targets hash table are initialized
1653955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
1663955d011SMarcel Moolenaar  */
1673955d011SMarcel Moolenaar void
1683955d011SMarcel Moolenaar Targ_Init(void)
1693955d011SMarcel Moolenaar {
1703955d011SMarcel Moolenaar     allTargets = Lst_Init(FALSE);
1713955d011SMarcel Moolenaar     Hash_InitTable(&targets, HTSIZE);
1723955d011SMarcel Moolenaar }
1733955d011SMarcel Moolenaar 
1743955d011SMarcel Moolenaar /*-
1753955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
1763955d011SMarcel Moolenaar  * Targ_End --
1773955d011SMarcel Moolenaar  *	Finalize this module
1783955d011SMarcel Moolenaar  *
1793955d011SMarcel Moolenaar  * Results:
1803955d011SMarcel Moolenaar  *	None
1813955d011SMarcel Moolenaar  *
1823955d011SMarcel Moolenaar  * Side Effects:
1833955d011SMarcel Moolenaar  *	All lists and gnodes are cleared
1843955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
1853955d011SMarcel Moolenaar  */
1863955d011SMarcel Moolenaar void
1873955d011SMarcel Moolenaar Targ_End(void)
1883955d011SMarcel Moolenaar {
1893955d011SMarcel Moolenaar #ifdef CLEANUP
1903955d011SMarcel Moolenaar     Lst_Destroy(allTargets, NULL);
1913955d011SMarcel Moolenaar     if (allGNs)
1923955d011SMarcel Moolenaar 	Lst_Destroy(allGNs, TargFreeGN);
1933955d011SMarcel Moolenaar     Hash_DeleteTable(&targets);
1943955d011SMarcel Moolenaar #endif
1953955d011SMarcel Moolenaar }
1963955d011SMarcel Moolenaar 
1973955d011SMarcel Moolenaar /*-
1983955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
1993955d011SMarcel Moolenaar  * Targ_List --
2003955d011SMarcel Moolenaar  *	Return the list of all targets
2013955d011SMarcel Moolenaar  *
2023955d011SMarcel Moolenaar  * Results:
2033955d011SMarcel Moolenaar  *	The list of all targets.
2043955d011SMarcel Moolenaar  *
2053955d011SMarcel Moolenaar  * Side Effects:
2063955d011SMarcel Moolenaar  *	None
2073955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
2083955d011SMarcel Moolenaar  */
2093955d011SMarcel Moolenaar Lst
2103955d011SMarcel Moolenaar Targ_List(void)
2113955d011SMarcel Moolenaar {
2123955d011SMarcel Moolenaar     return allTargets;
2133955d011SMarcel Moolenaar }
2143955d011SMarcel Moolenaar 
2153955d011SMarcel Moolenaar /*-
2163955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
2173955d011SMarcel Moolenaar  * Targ_NewGN  --
2183955d011SMarcel Moolenaar  *	Create and initialize a new graph node
2193955d011SMarcel Moolenaar  *
2203955d011SMarcel Moolenaar  * Input:
2213955d011SMarcel Moolenaar  *	name		the name to stick in the new node
2223955d011SMarcel Moolenaar  *
2233955d011SMarcel Moolenaar  * Results:
2243955d011SMarcel Moolenaar  *	An initialized graph node with the name field filled with a copy
2253955d011SMarcel Moolenaar  *	of the passed name
2263955d011SMarcel Moolenaar  *
2273955d011SMarcel Moolenaar  * Side Effects:
2283955d011SMarcel Moolenaar  *	The gnode is added to the list of all gnodes.
2293955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
2303955d011SMarcel Moolenaar  */
2313955d011SMarcel Moolenaar GNode *
2323955d011SMarcel Moolenaar Targ_NewGN(const char *name)
2333955d011SMarcel Moolenaar {
2343955d011SMarcel Moolenaar     GNode *gn;
2353955d011SMarcel Moolenaar 
2363955d011SMarcel Moolenaar     gn = bmake_malloc(sizeof(GNode));
2373955d011SMarcel Moolenaar     gn->name = bmake_strdup(name);
2383955d011SMarcel Moolenaar     gn->uname = NULL;
2393955d011SMarcel Moolenaar     gn->path = NULL;
2403955d011SMarcel Moolenaar     if (name[0] == '-' && name[1] == 'l') {
2413955d011SMarcel Moolenaar 	gn->type = OP_LIB;
2423955d011SMarcel Moolenaar     } else {
2433955d011SMarcel Moolenaar 	gn->type = 0;
2443955d011SMarcel Moolenaar     }
2453955d011SMarcel Moolenaar     gn->unmade =    	0;
2463955d011SMarcel Moolenaar     gn->unmade_cohorts = 0;
2473955d011SMarcel Moolenaar     gn->cohort_num[0] = 0;
2483955d011SMarcel Moolenaar     gn->centurion =    	NULL;
2493955d011SMarcel Moolenaar     gn->made = 	    	UNMADE;
2503955d011SMarcel Moolenaar     gn->flags = 	0;
2513955d011SMarcel Moolenaar     gn->checked =	0;
2523955d011SMarcel Moolenaar     gn->mtime =		0;
2533955d011SMarcel Moolenaar     gn->cmgn =		NULL;
2543955d011SMarcel Moolenaar     gn->iParents =  	Lst_Init(FALSE);
2553955d011SMarcel Moolenaar     gn->cohorts =   	Lst_Init(FALSE);
2563955d011SMarcel Moolenaar     gn->parents =   	Lst_Init(FALSE);
2573955d011SMarcel Moolenaar     gn->children =  	Lst_Init(FALSE);
2583955d011SMarcel Moolenaar     gn->order_pred =  	Lst_Init(FALSE);
2593955d011SMarcel Moolenaar     gn->order_succ =  	Lst_Init(FALSE);
2603955d011SMarcel Moolenaar     Hash_InitTable(&gn->context, 0);
2613955d011SMarcel Moolenaar     gn->commands =  	Lst_Init(FALSE);
2623955d011SMarcel Moolenaar     gn->suffix =	NULL;
2633955d011SMarcel Moolenaar     gn->lineno =	0;
2643955d011SMarcel Moolenaar     gn->fname = 	NULL;
2653955d011SMarcel Moolenaar 
2663955d011SMarcel Moolenaar #ifdef CLEANUP
2673955d011SMarcel Moolenaar     if (allGNs == NULL)
2683955d011SMarcel Moolenaar 	allGNs = Lst_Init(FALSE);
2693955d011SMarcel Moolenaar     Lst_AtEnd(allGNs, gn);
2703955d011SMarcel Moolenaar #endif
2713955d011SMarcel Moolenaar 
272*3841c287SSimon J. Gerraty     return gn;
2733955d011SMarcel Moolenaar }
2743955d011SMarcel Moolenaar 
2753955d011SMarcel Moolenaar #ifdef CLEANUP
2763955d011SMarcel Moolenaar /*-
2773955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
2783955d011SMarcel Moolenaar  * TargFreeGN  --
2793955d011SMarcel Moolenaar  *	Destroy a GNode
2803955d011SMarcel Moolenaar  *
2813955d011SMarcel Moolenaar  * Results:
2823955d011SMarcel Moolenaar  *	None.
2833955d011SMarcel Moolenaar  *
2843955d011SMarcel Moolenaar  * Side Effects:
2853955d011SMarcel Moolenaar  *	None.
2863955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
2873955d011SMarcel Moolenaar  */
2883955d011SMarcel Moolenaar static void
2893955d011SMarcel Moolenaar TargFreeGN(void *gnp)
2903955d011SMarcel Moolenaar {
2913955d011SMarcel Moolenaar     GNode *gn = (GNode *)gnp;
2923955d011SMarcel Moolenaar 
2933955d011SMarcel Moolenaar 
2943955d011SMarcel Moolenaar     free(gn->name);
2953955d011SMarcel Moolenaar     free(gn->uname);
2963955d011SMarcel Moolenaar     free(gn->path);
2973955d011SMarcel Moolenaar     /* gn->fname points to name allocated when file was opened, don't free */
2983955d011SMarcel Moolenaar 
2993955d011SMarcel Moolenaar     Lst_Destroy(gn->iParents, NULL);
3003955d011SMarcel Moolenaar     Lst_Destroy(gn->cohorts, NULL);
3013955d011SMarcel Moolenaar     Lst_Destroy(gn->parents, NULL);
3023955d011SMarcel Moolenaar     Lst_Destroy(gn->children, NULL);
3033955d011SMarcel Moolenaar     Lst_Destroy(gn->order_succ, NULL);
3043955d011SMarcel Moolenaar     Lst_Destroy(gn->order_pred, NULL);
3053955d011SMarcel Moolenaar     Hash_DeleteTable(&gn->context);
3063955d011SMarcel Moolenaar     Lst_Destroy(gn->commands, NULL);
3073955d011SMarcel Moolenaar     free(gn);
3083955d011SMarcel Moolenaar }
3093955d011SMarcel Moolenaar #endif
3103955d011SMarcel Moolenaar 
3113955d011SMarcel Moolenaar 
3123955d011SMarcel Moolenaar /*-
3133955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
3143955d011SMarcel Moolenaar  * Targ_FindNode  --
3153955d011SMarcel Moolenaar  *	Find a node in the list using the given name for matching
3163955d011SMarcel Moolenaar  *
3173955d011SMarcel Moolenaar  * Input:
3183955d011SMarcel Moolenaar  *	name		the name to find
3193955d011SMarcel Moolenaar  *	flags		flags governing events when target not
3203955d011SMarcel Moolenaar  *			found
3213955d011SMarcel Moolenaar  *
3223955d011SMarcel Moolenaar  * Results:
3233955d011SMarcel Moolenaar  *	The node in the list if it was. If it wasn't, return NULL of
3243955d011SMarcel Moolenaar  *	flags was TARG_NOCREATE or the newly created and initialized node
3253955d011SMarcel Moolenaar  *	if it was TARG_CREATE
3263955d011SMarcel Moolenaar  *
3273955d011SMarcel Moolenaar  * Side Effects:
3283955d011SMarcel Moolenaar  *	Sometimes a node is created and added to the list
3293955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
3303955d011SMarcel Moolenaar  */
3313955d011SMarcel Moolenaar GNode *
3323955d011SMarcel Moolenaar Targ_FindNode(const char *name, int flags)
3333955d011SMarcel Moolenaar {
3343955d011SMarcel Moolenaar     GNode         *gn;	      /* node in that element */
3353955d011SMarcel Moolenaar     Hash_Entry	  *he = NULL; /* New or used hash entry for node */
3363955d011SMarcel Moolenaar     Boolean	  isNew;      /* Set TRUE if Hash_CreateEntry had to create */
3373955d011SMarcel Moolenaar 			      /* an entry for the node */
3383955d011SMarcel Moolenaar 
3393955d011SMarcel Moolenaar     if (!(flags & (TARG_CREATE | TARG_NOHASH))) {
3403955d011SMarcel Moolenaar 	he = Hash_FindEntry(&targets, name);
3413955d011SMarcel Moolenaar 	if (he == NULL)
3423955d011SMarcel Moolenaar 	    return NULL;
3433955d011SMarcel Moolenaar 	return (GNode *)Hash_GetValue(he);
3443955d011SMarcel Moolenaar     }
3453955d011SMarcel Moolenaar 
3463955d011SMarcel Moolenaar     if (!(flags & TARG_NOHASH)) {
3473955d011SMarcel Moolenaar 	he = Hash_CreateEntry(&targets, name, &isNew);
3483955d011SMarcel Moolenaar 	if (!isNew)
3493955d011SMarcel Moolenaar 	    return (GNode *)Hash_GetValue(he);
3503955d011SMarcel Moolenaar     }
3513955d011SMarcel Moolenaar 
3523955d011SMarcel Moolenaar     gn = Targ_NewGN(name);
3533955d011SMarcel Moolenaar     if (!(flags & TARG_NOHASH))
3543955d011SMarcel Moolenaar 	Hash_SetValue(he, gn);
3553955d011SMarcel Moolenaar     Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
3563955d011SMarcel Moolenaar     (void)Lst_AtEnd(allTargets, gn);
3573955d011SMarcel Moolenaar     if (doing_depend)
3583955d011SMarcel Moolenaar 	gn->flags |= FROM_DEPEND;
3593955d011SMarcel Moolenaar     return gn;
3603955d011SMarcel Moolenaar }
3613955d011SMarcel Moolenaar 
3623955d011SMarcel Moolenaar /*-
3633955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
3643955d011SMarcel Moolenaar  * Targ_FindList --
3653955d011SMarcel Moolenaar  *	Make a complete list of GNodes from the given list of names
3663955d011SMarcel Moolenaar  *
3673955d011SMarcel Moolenaar  * Input:
3683955d011SMarcel Moolenaar  *	name		list of names to find
3693955d011SMarcel Moolenaar  *	flags		flags used if no node is found for a given name
3703955d011SMarcel Moolenaar  *
3713955d011SMarcel Moolenaar  * Results:
3723955d011SMarcel Moolenaar  *	A complete list of graph nodes corresponding to all instances of all
3733955d011SMarcel Moolenaar  *	the names in names.
3743955d011SMarcel Moolenaar  *
3753955d011SMarcel Moolenaar  * Side Effects:
3763955d011SMarcel Moolenaar  *	If flags is TARG_CREATE, nodes will be created for all names in
3773955d011SMarcel Moolenaar  *	names which do not yet have graph nodes. If flags is TARG_NOCREATE,
3783955d011SMarcel Moolenaar  *	an error message will be printed for each name which can't be found.
3793955d011SMarcel Moolenaar  * -----------------------------------------------------------------------
3803955d011SMarcel Moolenaar  */
3813955d011SMarcel Moolenaar Lst
3823955d011SMarcel Moolenaar Targ_FindList(Lst names, int flags)
3833955d011SMarcel Moolenaar {
3843955d011SMarcel Moolenaar     Lst            nodes;	/* result list */
3853955d011SMarcel Moolenaar     LstNode	   ln;		/* name list element */
3863955d011SMarcel Moolenaar     GNode	   *gn;		/* node in tLn */
3873955d011SMarcel Moolenaar     char    	   *name;
3883955d011SMarcel Moolenaar 
3893955d011SMarcel Moolenaar     nodes = Lst_Init(FALSE);
3903955d011SMarcel Moolenaar 
3913955d011SMarcel Moolenaar     if (Lst_Open(names) == FAILURE) {
392*3841c287SSimon J. Gerraty 	return nodes;
3933955d011SMarcel Moolenaar     }
3943955d011SMarcel Moolenaar     while ((ln = Lst_Next(names)) != NULL) {
3953955d011SMarcel Moolenaar 	name = (char *)Lst_Datum(ln);
3963955d011SMarcel Moolenaar 	gn = Targ_FindNode(name, flags);
3973955d011SMarcel Moolenaar 	if (gn != NULL) {
3983955d011SMarcel Moolenaar 	    /*
3993955d011SMarcel Moolenaar 	     * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
4003955d011SMarcel Moolenaar 	     * are added to the list in the order in which they were
4013955d011SMarcel Moolenaar 	     * encountered in the makefile.
4023955d011SMarcel Moolenaar 	     */
4033955d011SMarcel Moolenaar 	    (void)Lst_AtEnd(nodes, gn);
4043955d011SMarcel Moolenaar 	} else if (flags == TARG_NOCREATE) {
4053955d011SMarcel Moolenaar 	    Error("\"%s\" -- target unknown.", name);
4063955d011SMarcel Moolenaar 	}
4073955d011SMarcel Moolenaar     }
4083955d011SMarcel Moolenaar     Lst_Close(names);
409*3841c287SSimon J. Gerraty     return nodes;
4103955d011SMarcel Moolenaar }
4113955d011SMarcel Moolenaar 
4123955d011SMarcel Moolenaar /*-
4133955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4143955d011SMarcel Moolenaar  * Targ_Ignore  --
4153955d011SMarcel Moolenaar  *	Return true if should ignore errors when creating gn
4163955d011SMarcel Moolenaar  *
4173955d011SMarcel Moolenaar  * Input:
4183955d011SMarcel Moolenaar  *	gn		node to check for
4193955d011SMarcel Moolenaar  *
4203955d011SMarcel Moolenaar  * Results:
4213955d011SMarcel Moolenaar  *	TRUE if should ignore errors
4223955d011SMarcel Moolenaar  *
4233955d011SMarcel Moolenaar  * Side Effects:
4243955d011SMarcel Moolenaar  *	None
4253955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4263955d011SMarcel Moolenaar  */
4273955d011SMarcel Moolenaar Boolean
4283955d011SMarcel Moolenaar Targ_Ignore(GNode *gn)
4293955d011SMarcel Moolenaar {
4303955d011SMarcel Moolenaar     if (ignoreErrors || gn->type & OP_IGNORE) {
431*3841c287SSimon J. Gerraty 	return TRUE;
4323955d011SMarcel Moolenaar     } else {
433*3841c287SSimon J. Gerraty 	return FALSE;
4343955d011SMarcel Moolenaar     }
4353955d011SMarcel Moolenaar }
4363955d011SMarcel Moolenaar 
4373955d011SMarcel Moolenaar /*-
4383955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4393955d011SMarcel Moolenaar  * Targ_Silent  --
4403955d011SMarcel Moolenaar  *	Return true if be silent when creating gn
4413955d011SMarcel Moolenaar  *
4423955d011SMarcel Moolenaar  * Input:
4433955d011SMarcel Moolenaar  *	gn		node to check for
4443955d011SMarcel Moolenaar  *
4453955d011SMarcel Moolenaar  * Results:
4463955d011SMarcel Moolenaar  *	TRUE if should be silent
4473955d011SMarcel Moolenaar  *
4483955d011SMarcel Moolenaar  * Side Effects:
4493955d011SMarcel Moolenaar  *	None
4503955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4513955d011SMarcel Moolenaar  */
4523955d011SMarcel Moolenaar Boolean
4533955d011SMarcel Moolenaar Targ_Silent(GNode *gn)
4543955d011SMarcel Moolenaar {
4553955d011SMarcel Moolenaar     if (beSilent || gn->type & OP_SILENT) {
456*3841c287SSimon J. Gerraty 	return TRUE;
4573955d011SMarcel Moolenaar     } else {
458*3841c287SSimon J. Gerraty 	return FALSE;
4593955d011SMarcel Moolenaar     }
4603955d011SMarcel Moolenaar }
4613955d011SMarcel Moolenaar 
4623955d011SMarcel Moolenaar /*-
4633955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4643955d011SMarcel Moolenaar  * Targ_Precious --
4653955d011SMarcel Moolenaar  *	See if the given target is precious
4663955d011SMarcel Moolenaar  *
4673955d011SMarcel Moolenaar  * Input:
4683955d011SMarcel Moolenaar  *	gn		the node to check
4693955d011SMarcel Moolenaar  *
4703955d011SMarcel Moolenaar  * Results:
4713955d011SMarcel Moolenaar  *	TRUE if it is precious. FALSE otherwise
4723955d011SMarcel Moolenaar  *
4733955d011SMarcel Moolenaar  * Side Effects:
4743955d011SMarcel Moolenaar  *	None
4753955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4763955d011SMarcel Moolenaar  */
4773955d011SMarcel Moolenaar Boolean
4783955d011SMarcel Moolenaar Targ_Precious(GNode *gn)
4793955d011SMarcel Moolenaar {
4803955d011SMarcel Moolenaar     if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) {
481*3841c287SSimon J. Gerraty 	return TRUE;
4823955d011SMarcel Moolenaar     } else {
483*3841c287SSimon J. Gerraty 	return FALSE;
4843955d011SMarcel Moolenaar     }
4853955d011SMarcel Moolenaar }
4863955d011SMarcel Moolenaar 
4873955d011SMarcel Moolenaar /******************* DEBUG INFO PRINTING ****************/
4883955d011SMarcel Moolenaar 
4893955d011SMarcel Moolenaar static GNode	  *mainTarg;	/* the main target, as set by Targ_SetMain */
4903955d011SMarcel Moolenaar /*-
4913955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
4923955d011SMarcel Moolenaar  * Targ_SetMain --
4933955d011SMarcel Moolenaar  *	Set our idea of the main target we'll be creating. Used for
4943955d011SMarcel Moolenaar  *	debugging output.
4953955d011SMarcel Moolenaar  *
4963955d011SMarcel Moolenaar  * Input:
4973955d011SMarcel Moolenaar  *	gn		The main target we'll create
4983955d011SMarcel Moolenaar  *
4993955d011SMarcel Moolenaar  * Results:
5003955d011SMarcel Moolenaar  *	None.
5013955d011SMarcel Moolenaar  *
5023955d011SMarcel Moolenaar  * Side Effects:
5033955d011SMarcel Moolenaar  *	"mainTarg" is set to the main target's node.
5043955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
5053955d011SMarcel Moolenaar  */
5063955d011SMarcel Moolenaar void
5073955d011SMarcel Moolenaar Targ_SetMain(GNode *gn)
5083955d011SMarcel Moolenaar {
5093955d011SMarcel Moolenaar     mainTarg = gn;
5103955d011SMarcel Moolenaar }
5113955d011SMarcel Moolenaar 
5123955d011SMarcel Moolenaar static int
5133955d011SMarcel Moolenaar TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED)
5143955d011SMarcel Moolenaar {
5153955d011SMarcel Moolenaar     GNode *gn = (GNode *)gnp;
5163955d011SMarcel Moolenaar 
5173955d011SMarcel Moolenaar     fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num);
5183955d011SMarcel Moolenaar 
5193955d011SMarcel Moolenaar     return 0;
5203955d011SMarcel Moolenaar }
5213955d011SMarcel Moolenaar 
5223955d011SMarcel Moolenaar 
5233955d011SMarcel Moolenaar int
524e1cee40dSSimon J. Gerraty Targ_PrintCmd(void *cmd, void *dummy MAKE_ATTR_UNUSED)
5253955d011SMarcel Moolenaar {
5263955d011SMarcel Moolenaar     fprintf(debug_file, "\t%s\n", (char *)cmd);
527e1cee40dSSimon J. Gerraty     return 0;
5283955d011SMarcel Moolenaar }
5293955d011SMarcel Moolenaar 
5303955d011SMarcel Moolenaar /*-
5313955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
5323955d011SMarcel Moolenaar  * Targ_FmtTime --
5333955d011SMarcel Moolenaar  *	Format a modification time in some reasonable way and return it.
5343955d011SMarcel Moolenaar  *
5353955d011SMarcel Moolenaar  * Results:
5363955d011SMarcel Moolenaar  *	The time reformatted.
5373955d011SMarcel Moolenaar  *
5383955d011SMarcel Moolenaar  * Side Effects:
5393955d011SMarcel Moolenaar  *	The time is placed in a static area, so it is overwritten
5403955d011SMarcel Moolenaar  *	with each call.
5413955d011SMarcel Moolenaar  *
5423955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
5433955d011SMarcel Moolenaar  */
5443955d011SMarcel Moolenaar char *
5453955d011SMarcel Moolenaar Targ_FmtTime(time_t tm)
5463955d011SMarcel Moolenaar {
5473955d011SMarcel Moolenaar     struct tm	  	*parts;
5483955d011SMarcel Moolenaar     static char	  	buf[128];
5493955d011SMarcel Moolenaar 
5503955d011SMarcel Moolenaar     parts = localtime(&tm);
5513955d011SMarcel Moolenaar     (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
552*3841c287SSimon J. Gerraty     return buf;
5533955d011SMarcel Moolenaar }
5543955d011SMarcel Moolenaar 
5553955d011SMarcel Moolenaar /*-
5563955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
5573955d011SMarcel Moolenaar  * Targ_PrintType --
5583955d011SMarcel Moolenaar  *	Print out a type field giving only those attributes the user can
5593955d011SMarcel Moolenaar  *	set.
5603955d011SMarcel Moolenaar  *
5613955d011SMarcel Moolenaar  * Results:
5623955d011SMarcel Moolenaar  *
5633955d011SMarcel Moolenaar  * Side Effects:
5643955d011SMarcel Moolenaar  *
5653955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
5663955d011SMarcel Moolenaar  */
5673955d011SMarcel Moolenaar void
5683955d011SMarcel Moolenaar Targ_PrintType(int type)
5693955d011SMarcel Moolenaar {
5703955d011SMarcel Moolenaar     int    tbit;
5713955d011SMarcel Moolenaar 
5723955d011SMarcel Moolenaar #define PRINTBIT(attr)	case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break
5733955d011SMarcel Moolenaar #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break
5743955d011SMarcel Moolenaar 
5753955d011SMarcel Moolenaar     type &= ~OP_OPMASK;
5763955d011SMarcel Moolenaar 
5773955d011SMarcel Moolenaar     while (type) {
5783955d011SMarcel Moolenaar 	tbit = 1 << (ffs(type) - 1);
5793955d011SMarcel Moolenaar 	type &= ~tbit;
5803955d011SMarcel Moolenaar 
5813955d011SMarcel Moolenaar 	switch(tbit) {
5823955d011SMarcel Moolenaar 	    PRINTBIT(OPTIONAL);
5833955d011SMarcel Moolenaar 	    PRINTBIT(USE);
5843955d011SMarcel Moolenaar 	    PRINTBIT(EXEC);
5853955d011SMarcel Moolenaar 	    PRINTBIT(IGNORE);
5863955d011SMarcel Moolenaar 	    PRINTBIT(PRECIOUS);
5873955d011SMarcel Moolenaar 	    PRINTBIT(SILENT);
5883955d011SMarcel Moolenaar 	    PRINTBIT(MAKE);
5893955d011SMarcel Moolenaar 	    PRINTBIT(JOIN);
5903955d011SMarcel Moolenaar 	    PRINTBIT(INVISIBLE);
5913955d011SMarcel Moolenaar 	    PRINTBIT(NOTMAIN);
5923955d011SMarcel Moolenaar 	    PRINTDBIT(LIB);
5933955d011SMarcel Moolenaar 	    /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
5943955d011SMarcel Moolenaar 	    case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break;
5953955d011SMarcel Moolenaar 	    PRINTDBIT(ARCHV);
5963955d011SMarcel Moolenaar 	    PRINTDBIT(MADE);
5973955d011SMarcel Moolenaar 	    PRINTDBIT(PHONY);
5983955d011SMarcel Moolenaar 	}
5993955d011SMarcel Moolenaar     }
6003955d011SMarcel Moolenaar }
6013955d011SMarcel Moolenaar 
6023955d011SMarcel Moolenaar static const char *
6033955d011SMarcel Moolenaar made_name(enum enum_made made)
6043955d011SMarcel Moolenaar {
6053955d011SMarcel Moolenaar     switch (made) {
6063955d011SMarcel Moolenaar     case UNMADE:     return "unmade";
6073955d011SMarcel Moolenaar     case DEFERRED:   return "deferred";
6083955d011SMarcel Moolenaar     case REQUESTED:  return "requested";
6093955d011SMarcel Moolenaar     case BEINGMADE:  return "being made";
6103955d011SMarcel Moolenaar     case MADE:       return "made";
6113955d011SMarcel Moolenaar     case UPTODATE:   return "up-to-date";
6123955d011SMarcel Moolenaar     case ERROR:      return "error when made";
6133955d011SMarcel Moolenaar     case ABORTED:    return "aborted";
6143955d011SMarcel Moolenaar     default:         return "unknown enum_made value";
6153955d011SMarcel Moolenaar     }
6163955d011SMarcel Moolenaar }
6173955d011SMarcel Moolenaar 
6183955d011SMarcel Moolenaar /*-
6193955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
6203955d011SMarcel Moolenaar  * TargPrintNode --
6213955d011SMarcel Moolenaar  *	print the contents of a node
6223955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
6233955d011SMarcel Moolenaar  */
6243955d011SMarcel Moolenaar int
6253955d011SMarcel Moolenaar Targ_PrintNode(void *gnp, void *passp)
6263955d011SMarcel Moolenaar {
6273955d011SMarcel Moolenaar     GNode         *gn = (GNode *)gnp;
6283955d011SMarcel Moolenaar     int	    	  pass = passp ? *(int *)passp : 0;
6293955d011SMarcel Moolenaar 
6303955d011SMarcel Moolenaar     fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n",
6313955d011SMarcel Moolenaar 	    gn->name, gn->cohort_num, gn->flags, gn->type, gn->made);
6323955d011SMarcel Moolenaar     if (gn->flags == 0)
6333955d011SMarcel Moolenaar 	return 0;
6343955d011SMarcel Moolenaar 
6353955d011SMarcel Moolenaar     if (!OP_NOP(gn->type)) {
6363955d011SMarcel Moolenaar 	fprintf(debug_file, "#\n");
6373955d011SMarcel Moolenaar 	if (gn == mainTarg) {
6383955d011SMarcel Moolenaar 	    fprintf(debug_file, "# *** MAIN TARGET ***\n");
6393955d011SMarcel Moolenaar 	}
6403955d011SMarcel Moolenaar 	if (pass >= 2) {
6413955d011SMarcel Moolenaar 	    if (gn->unmade) {
6423955d011SMarcel Moolenaar 		fprintf(debug_file, "# %d unmade children\n", gn->unmade);
6433955d011SMarcel Moolenaar 	    } else {
6443955d011SMarcel Moolenaar 		fprintf(debug_file, "# No unmade children\n");
6453955d011SMarcel Moolenaar 	    }
6463955d011SMarcel Moolenaar 	    if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
6473955d011SMarcel Moolenaar 		if (gn->mtime != 0) {
6483955d011SMarcel Moolenaar 		    fprintf(debug_file, "# last modified %s: %s\n",
6493955d011SMarcel Moolenaar 			      Targ_FmtTime(gn->mtime),
6503955d011SMarcel Moolenaar 			      made_name(gn->made));
6513955d011SMarcel Moolenaar 		} else if (gn->made != UNMADE) {
6523955d011SMarcel Moolenaar 		    fprintf(debug_file, "# non-existent (maybe): %s\n",
6533955d011SMarcel Moolenaar 			      made_name(gn->made));
6543955d011SMarcel Moolenaar 		} else {
6553955d011SMarcel Moolenaar 		    fprintf(debug_file, "# unmade\n");
6563955d011SMarcel Moolenaar 		}
6573955d011SMarcel Moolenaar 	    }
6583955d011SMarcel Moolenaar 	    if (!Lst_IsEmpty (gn->iParents)) {
6593955d011SMarcel Moolenaar 		fprintf(debug_file, "# implicit parents: ");
6603955d011SMarcel Moolenaar 		Lst_ForEach(gn->iParents, TargPrintName, NULL);
6613955d011SMarcel Moolenaar 		fprintf(debug_file, "\n");
6623955d011SMarcel Moolenaar 	    }
6633955d011SMarcel Moolenaar 	} else {
6643955d011SMarcel Moolenaar 	    if (gn->unmade)
6653955d011SMarcel Moolenaar 		fprintf(debug_file, "# %d unmade children\n", gn->unmade);
6663955d011SMarcel Moolenaar 	}
6673955d011SMarcel Moolenaar 	if (!Lst_IsEmpty (gn->parents)) {
6683955d011SMarcel Moolenaar 	    fprintf(debug_file, "# parents: ");
6693955d011SMarcel Moolenaar 	    Lst_ForEach(gn->parents, TargPrintName, NULL);
6703955d011SMarcel Moolenaar 	    fprintf(debug_file, "\n");
6713955d011SMarcel Moolenaar 	}
6723955d011SMarcel Moolenaar 	if (!Lst_IsEmpty (gn->order_pred)) {
6733955d011SMarcel Moolenaar 	    fprintf(debug_file, "# order_pred: ");
6743955d011SMarcel Moolenaar 	    Lst_ForEach(gn->order_pred, TargPrintName, NULL);
6753955d011SMarcel Moolenaar 	    fprintf(debug_file, "\n");
6763955d011SMarcel Moolenaar 	}
6773955d011SMarcel Moolenaar 	if (!Lst_IsEmpty (gn->order_succ)) {
6783955d011SMarcel Moolenaar 	    fprintf(debug_file, "# order_succ: ");
6793955d011SMarcel Moolenaar 	    Lst_ForEach(gn->order_succ, TargPrintName, NULL);
6803955d011SMarcel Moolenaar 	    fprintf(debug_file, "\n");
6813955d011SMarcel Moolenaar 	}
6823955d011SMarcel Moolenaar 
6833955d011SMarcel Moolenaar 	fprintf(debug_file, "%-16s", gn->name);
6843955d011SMarcel Moolenaar 	switch (gn->type & OP_OPMASK) {
6853955d011SMarcel Moolenaar 	    case OP_DEPENDS:
6863955d011SMarcel Moolenaar 		fprintf(debug_file, ": "); break;
6873955d011SMarcel Moolenaar 	    case OP_FORCE:
6883955d011SMarcel Moolenaar 		fprintf(debug_file, "! "); break;
6893955d011SMarcel Moolenaar 	    case OP_DOUBLEDEP:
6903955d011SMarcel Moolenaar 		fprintf(debug_file, ":: "); break;
6913955d011SMarcel Moolenaar 	}
6923955d011SMarcel Moolenaar 	Targ_PrintType(gn->type);
6933955d011SMarcel Moolenaar 	Lst_ForEach(gn->children, TargPrintName, NULL);
6943955d011SMarcel Moolenaar 	fprintf(debug_file, "\n");
6953955d011SMarcel Moolenaar 	Lst_ForEach(gn->commands, Targ_PrintCmd, NULL);
6963955d011SMarcel Moolenaar 	fprintf(debug_file, "\n\n");
6973955d011SMarcel Moolenaar 	if (gn->type & OP_DOUBLEDEP) {
6983955d011SMarcel Moolenaar 	    Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass);
6993955d011SMarcel Moolenaar 	}
7003955d011SMarcel Moolenaar     }
701*3841c287SSimon J. Gerraty     return 0;
7023955d011SMarcel Moolenaar }
7033955d011SMarcel Moolenaar 
7043955d011SMarcel Moolenaar /*-
7053955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
7063955d011SMarcel Moolenaar  * TargPrintOnlySrc --
7073955d011SMarcel Moolenaar  *	Print only those targets that are just a source.
7083955d011SMarcel Moolenaar  *
7093955d011SMarcel Moolenaar  * Results:
7103955d011SMarcel Moolenaar  *	0.
7113955d011SMarcel Moolenaar  *
7123955d011SMarcel Moolenaar  * Side Effects:
7133955d011SMarcel Moolenaar  *	The name of each file is printed preceded by #\t
7143955d011SMarcel Moolenaar  *
7153955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
7163955d011SMarcel Moolenaar  */
7173955d011SMarcel Moolenaar static int
7183955d011SMarcel Moolenaar TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED)
7193955d011SMarcel Moolenaar {
7203955d011SMarcel Moolenaar     GNode   	  *gn = (GNode *)gnp;
7213955d011SMarcel Moolenaar     if (!OP_NOP(gn->type))
7223955d011SMarcel Moolenaar 	return 0;
7233955d011SMarcel Moolenaar 
7243955d011SMarcel Moolenaar     fprintf(debug_file, "#\t%s [%s] ",
7253955d011SMarcel Moolenaar 	    gn->name, gn->path ? gn->path : gn->name);
7263955d011SMarcel Moolenaar     Targ_PrintType(gn->type);
7273955d011SMarcel Moolenaar     fprintf(debug_file, "\n");
7283955d011SMarcel Moolenaar 
7293955d011SMarcel Moolenaar     return 0;
7303955d011SMarcel Moolenaar }
7313955d011SMarcel Moolenaar 
7323955d011SMarcel Moolenaar /*-
7333955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
7343955d011SMarcel Moolenaar  * Targ_PrintGraph --
7353955d011SMarcel Moolenaar  *	print the entire graph. heh heh
7363955d011SMarcel Moolenaar  *
7373955d011SMarcel Moolenaar  * Input:
7383955d011SMarcel Moolenaar  *	pass		Which pass this is. 1 => no processing
7393955d011SMarcel Moolenaar  *			2 => processing done
7403955d011SMarcel Moolenaar  *
7413955d011SMarcel Moolenaar  * Results:
7423955d011SMarcel Moolenaar  *	none
7433955d011SMarcel Moolenaar  *
7443955d011SMarcel Moolenaar  * Side Effects:
7453955d011SMarcel Moolenaar  *	lots o' output
7463955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
7473955d011SMarcel Moolenaar  */
7483955d011SMarcel Moolenaar void
7493955d011SMarcel Moolenaar Targ_PrintGraph(int pass)
7503955d011SMarcel Moolenaar {
7513955d011SMarcel Moolenaar     fprintf(debug_file, "#*** Input graph:\n");
7523955d011SMarcel Moolenaar     Lst_ForEach(allTargets, Targ_PrintNode, &pass);
7533955d011SMarcel Moolenaar     fprintf(debug_file, "\n\n");
7543955d011SMarcel Moolenaar     fprintf(debug_file, "#\n#   Files that are only sources:\n");
7553955d011SMarcel Moolenaar     Lst_ForEach(allTargets, TargPrintOnlySrc, NULL);
7563955d011SMarcel Moolenaar     fprintf(debug_file, "#*** Global Variables:\n");
7573955d011SMarcel Moolenaar     Var_Dump(VAR_GLOBAL);
7583955d011SMarcel Moolenaar     fprintf(debug_file, "#*** Command-line Variables:\n");
7593955d011SMarcel Moolenaar     Var_Dump(VAR_CMD);
7603955d011SMarcel Moolenaar     fprintf(debug_file, "\n");
7613955d011SMarcel Moolenaar     Dir_PrintDirectories();
7623955d011SMarcel Moolenaar     fprintf(debug_file, "\n");
7633955d011SMarcel Moolenaar     Suff_PrintAll();
7643955d011SMarcel Moolenaar }
7653955d011SMarcel Moolenaar 
7663955d011SMarcel Moolenaar /*-
7673955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
7683955d011SMarcel Moolenaar  * TargPropagateNode --
7693955d011SMarcel Moolenaar  *	Propagate information from a single node to related nodes if
7703955d011SMarcel Moolenaar  *	appropriate.
7713955d011SMarcel Moolenaar  *
7723955d011SMarcel Moolenaar  * Input:
7733955d011SMarcel Moolenaar  *	gnp		The node that we are processing.
7743955d011SMarcel Moolenaar  *
7753955d011SMarcel Moolenaar  * Results:
7763955d011SMarcel Moolenaar  *	Always returns 0, for the benefit of Lst_ForEach().
7773955d011SMarcel Moolenaar  *
7783955d011SMarcel Moolenaar  * Side Effects:
7793955d011SMarcel Moolenaar  *	Information is propagated from this node to cohort or child
7803955d011SMarcel Moolenaar  *	nodes.
7813955d011SMarcel Moolenaar  *
7823955d011SMarcel Moolenaar  *	If the node was defined with "::", then TargPropagateCohort()
7833955d011SMarcel Moolenaar  *	will be called for each cohort node.
7843955d011SMarcel Moolenaar  *
7853955d011SMarcel Moolenaar  *	If the node has recursive predecessors, then
7863955d011SMarcel Moolenaar  *	TargPropagateRecpred() will be called for each recursive
7873955d011SMarcel Moolenaar  *	predecessor.
7883955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
7893955d011SMarcel Moolenaar  */
7903955d011SMarcel Moolenaar static int
7913955d011SMarcel Moolenaar TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED)
7923955d011SMarcel Moolenaar {
7933955d011SMarcel Moolenaar     GNode	  *gn = (GNode *)gnp;
7943955d011SMarcel Moolenaar 
7953955d011SMarcel Moolenaar     if (gn->type & OP_DOUBLEDEP)
7963955d011SMarcel Moolenaar 	Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp);
797*3841c287SSimon J. Gerraty     return 0;
7983955d011SMarcel Moolenaar }
7993955d011SMarcel Moolenaar 
8003955d011SMarcel Moolenaar /*-
8013955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
8023955d011SMarcel Moolenaar  * TargPropagateCohort --
8033955d011SMarcel Moolenaar  *	Propagate some bits in the type mask from a node to
8043955d011SMarcel Moolenaar  *	a related cohort node.
8053955d011SMarcel Moolenaar  *
8063955d011SMarcel Moolenaar  * Input:
8073955d011SMarcel Moolenaar  *	cnp		The node that we are processing.
8083955d011SMarcel Moolenaar  *	gnp		Another node that has cnp as a cohort.
8093955d011SMarcel Moolenaar  *
8103955d011SMarcel Moolenaar  * Results:
8113955d011SMarcel Moolenaar  *	Always returns 0, for the benefit of Lst_ForEach().
8123955d011SMarcel Moolenaar  *
8133955d011SMarcel Moolenaar  * Side Effects:
8143955d011SMarcel Moolenaar  *	cnp's type bitmask is modified to incorporate some of the
8153955d011SMarcel Moolenaar  *	bits from gnp's type bitmask.  (XXX need a better explanation.)
8163955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
8173955d011SMarcel Moolenaar  */
8183955d011SMarcel Moolenaar static int
8193955d011SMarcel Moolenaar TargPropagateCohort(void *cgnp, void *pgnp)
8203955d011SMarcel Moolenaar {
8213955d011SMarcel Moolenaar     GNode	  *cgn = (GNode *)cgnp;
8223955d011SMarcel Moolenaar     GNode	  *pgn = (GNode *)pgnp;
8233955d011SMarcel Moolenaar 
8243955d011SMarcel Moolenaar     cgn->type |= pgn->type & ~OP_OPMASK;
825*3841c287SSimon J. Gerraty     return 0;
8263955d011SMarcel Moolenaar }
8273955d011SMarcel Moolenaar 
8283955d011SMarcel Moolenaar /*-
8293955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
8303955d011SMarcel Moolenaar  * Targ_Propagate --
8313955d011SMarcel Moolenaar  *	Propagate information between related nodes.  Should be called
8323955d011SMarcel Moolenaar  *	after the makefiles are parsed but before any action is taken.
8333955d011SMarcel Moolenaar  *
8343955d011SMarcel Moolenaar  * Results:
8353955d011SMarcel Moolenaar  *	none
8363955d011SMarcel Moolenaar  *
8373955d011SMarcel Moolenaar  * Side Effects:
8383955d011SMarcel Moolenaar  *	Information is propagated between related nodes throughout the
8393955d011SMarcel Moolenaar  *	graph.
8403955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
8413955d011SMarcel Moolenaar  */
8423955d011SMarcel Moolenaar void
8433955d011SMarcel Moolenaar Targ_Propagate(void)
8443955d011SMarcel Moolenaar {
8453955d011SMarcel Moolenaar     Lst_ForEach(allTargets, TargPropagateNode, NULL);
8463955d011SMarcel Moolenaar }
847