xref: /freebsd/contrib/bmake/targ.c (revision 3955d011f8d241ebed0fa997923e7566f5485c07)
1*3955d011SMarcel Moolenaar /*	$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $	*/
2*3955d011SMarcel Moolenaar 
3*3955d011SMarcel Moolenaar /*
4*3955d011SMarcel Moolenaar  * Copyright (c) 1988, 1989, 1990, 1993
5*3955d011SMarcel Moolenaar  *	The Regents of the University of California.  All rights reserved.
6*3955d011SMarcel Moolenaar  *
7*3955d011SMarcel Moolenaar  * This code is derived from software contributed to Berkeley by
8*3955d011SMarcel Moolenaar  * Adam de Boor.
9*3955d011SMarcel Moolenaar  *
10*3955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
11*3955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
12*3955d011SMarcel Moolenaar  * are met:
13*3955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
14*3955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
15*3955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
16*3955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
17*3955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
18*3955d011SMarcel Moolenaar  * 3. Neither the name of the University nor the names of its contributors
19*3955d011SMarcel Moolenaar  *    may be used to endorse or promote products derived from this software
20*3955d011SMarcel Moolenaar  *    without specific prior written permission.
21*3955d011SMarcel Moolenaar  *
22*3955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*3955d011SMarcel Moolenaar  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*3955d011SMarcel Moolenaar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*3955d011SMarcel Moolenaar  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*3955d011SMarcel Moolenaar  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*3955d011SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*3955d011SMarcel Moolenaar  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*3955d011SMarcel Moolenaar  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*3955d011SMarcel Moolenaar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*3955d011SMarcel Moolenaar  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*3955d011SMarcel Moolenaar  * SUCH DAMAGE.
33*3955d011SMarcel Moolenaar  */
34*3955d011SMarcel Moolenaar 
35*3955d011SMarcel Moolenaar /*
36*3955d011SMarcel Moolenaar  * Copyright (c) 1989 by Berkeley Softworks
37*3955d011SMarcel Moolenaar  * All rights reserved.
38*3955d011SMarcel Moolenaar  *
39*3955d011SMarcel Moolenaar  * This code is derived from software contributed to Berkeley by
40*3955d011SMarcel Moolenaar  * Adam de Boor.
41*3955d011SMarcel Moolenaar  *
42*3955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
43*3955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
44*3955d011SMarcel Moolenaar  * are met:
45*3955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
46*3955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
47*3955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
48*3955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
49*3955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
50*3955d011SMarcel Moolenaar  * 3. All advertising materials mentioning features or use of this software
51*3955d011SMarcel Moolenaar  *    must display the following acknowledgement:
52*3955d011SMarcel Moolenaar  *	This product includes software developed by the University of
53*3955d011SMarcel Moolenaar  *	California, Berkeley and its contributors.
54*3955d011SMarcel Moolenaar  * 4. Neither the name of the University nor the names of its contributors
55*3955d011SMarcel Moolenaar  *    may be used to endorse or promote products derived from this software
56*3955d011SMarcel Moolenaar  *    without specific prior written permission.
57*3955d011SMarcel Moolenaar  *
58*3955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59*3955d011SMarcel Moolenaar  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60*3955d011SMarcel Moolenaar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61*3955d011SMarcel Moolenaar  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62*3955d011SMarcel Moolenaar  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63*3955d011SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64*3955d011SMarcel Moolenaar  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65*3955d011SMarcel Moolenaar  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66*3955d011SMarcel Moolenaar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67*3955d011SMarcel Moolenaar  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68*3955d011SMarcel Moolenaar  * SUCH DAMAGE.
69*3955d011SMarcel Moolenaar  */
70*3955d011SMarcel Moolenaar 
71*3955d011SMarcel Moolenaar #ifndef MAKE_NATIVE
72*3955d011SMarcel Moolenaar static char rcsid[] = "$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $";
73*3955d011SMarcel Moolenaar #else
74*3955d011SMarcel Moolenaar #include <sys/cdefs.h>
75*3955d011SMarcel Moolenaar #ifndef lint
76*3955d011SMarcel Moolenaar #if 0
77*3955d011SMarcel Moolenaar static char sccsid[] = "@(#)targ.c	8.2 (Berkeley) 3/19/94";
78*3955d011SMarcel Moolenaar #else
79*3955d011SMarcel Moolenaar __RCSID("$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $");
80*3955d011SMarcel Moolenaar #endif
81*3955d011SMarcel Moolenaar #endif /* not lint */
82*3955d011SMarcel Moolenaar #endif
83*3955d011SMarcel Moolenaar 
84*3955d011SMarcel Moolenaar /*-
85*3955d011SMarcel Moolenaar  * targ.c --
86*3955d011SMarcel Moolenaar  *	Functions for maintaining the Lst allTargets. Target nodes are
87*3955d011SMarcel Moolenaar  * kept in two structures: a Lst, maintained by the list library, and a
88*3955d011SMarcel Moolenaar  * hash table, maintained by the hash library.
89*3955d011SMarcel Moolenaar  *
90*3955d011SMarcel Moolenaar  * Interface:
91*3955d011SMarcel Moolenaar  *	Targ_Init 	    	Initialization procedure.
92*3955d011SMarcel Moolenaar  *
93*3955d011SMarcel Moolenaar  *	Targ_End 	    	Cleanup the module
94*3955d011SMarcel Moolenaar  *
95*3955d011SMarcel Moolenaar  *	Targ_List 	    	Return the list of all targets so far.
96*3955d011SMarcel Moolenaar  *
97*3955d011SMarcel Moolenaar  *	Targ_NewGN	    	Create a new GNode for the passed target
98*3955d011SMarcel Moolenaar  *	    	  	    	(string). The node is *not* placed in the
99*3955d011SMarcel Moolenaar  *	    	  	    	hash table, though all its fields are
100*3955d011SMarcel Moolenaar  *	    	  	    	initialized.
101*3955d011SMarcel Moolenaar  *
102*3955d011SMarcel Moolenaar  *	Targ_FindNode	    	Find the node for a given target, creating
103*3955d011SMarcel Moolenaar  *	    	  	    	and storing it if it doesn't exist and the
104*3955d011SMarcel Moolenaar  *	    	  	    	flags are right (TARG_CREATE)
105*3955d011SMarcel Moolenaar  *
106*3955d011SMarcel Moolenaar  *	Targ_FindList	    	Given a list of names, find nodes for all
107*3955d011SMarcel Moolenaar  *	    	  	    	of them. If a name doesn't exist and the
108*3955d011SMarcel Moolenaar  *	    	  	    	TARG_NOCREATE flag was given, an error message
109*3955d011SMarcel Moolenaar  *	    	  	    	is printed. Else, if a name doesn't exist,
110*3955d011SMarcel Moolenaar  *	    	  	    	its node is created.
111*3955d011SMarcel Moolenaar  *
112*3955d011SMarcel Moolenaar  *	Targ_Ignore	    	Return TRUE if errors should be ignored when
113*3955d011SMarcel Moolenaar  *	    	  	    	creating the given target.
114*3955d011SMarcel Moolenaar  *
115*3955d011SMarcel Moolenaar  *	Targ_Silent	    	Return TRUE if we should be silent when
116*3955d011SMarcel Moolenaar  *	    	  	    	creating the given target.
117*3955d011SMarcel Moolenaar  *
118*3955d011SMarcel Moolenaar  *	Targ_Precious	    	Return TRUE if the target is precious and
119*3955d011SMarcel Moolenaar  *	    	  	    	should not be removed if we are interrupted.
120*3955d011SMarcel Moolenaar  *
121*3955d011SMarcel Moolenaar  *	Targ_Propagate		Propagate information between related
122*3955d011SMarcel Moolenaar  *				nodes.	Should be called after the
123*3955d011SMarcel Moolenaar  *				makefiles are parsed but before any
124*3955d011SMarcel Moolenaar  *				action is taken.
125*3955d011SMarcel Moolenaar  *
126*3955d011SMarcel Moolenaar  * Debugging:
127*3955d011SMarcel Moolenaar  *	Targ_PrintGraph	    	Print out the entire graphm all variables
128*3955d011SMarcel Moolenaar  *	    	  	    	and statistics for the directory cache. Should
129*3955d011SMarcel Moolenaar  *	    	  	    	print something for suffixes, too, but...
130*3955d011SMarcel Moolenaar  */
131*3955d011SMarcel Moolenaar 
132*3955d011SMarcel Moolenaar #include	  <stdio.h>
133*3955d011SMarcel Moolenaar #include	  <time.h>
134*3955d011SMarcel Moolenaar 
135*3955d011SMarcel Moolenaar #include	  "make.h"
136*3955d011SMarcel Moolenaar #include	  "hash.h"
137*3955d011SMarcel Moolenaar #include	  "dir.h"
138*3955d011SMarcel Moolenaar 
139*3955d011SMarcel Moolenaar static Lst        allTargets;	/* the list of all targets found so far */
140*3955d011SMarcel Moolenaar #ifdef CLEANUP
141*3955d011SMarcel Moolenaar static Lst	  allGNs;	/* List of all the GNodes */
142*3955d011SMarcel Moolenaar #endif
143*3955d011SMarcel Moolenaar static Hash_Table targets;	/* a hash table of same */
144*3955d011SMarcel Moolenaar 
145*3955d011SMarcel Moolenaar #define HTSIZE	191		/* initial size of hash table */
146*3955d011SMarcel Moolenaar 
147*3955d011SMarcel Moolenaar static int TargPrintOnlySrc(void *, void *);
148*3955d011SMarcel Moolenaar static int TargPrintName(void *, void *);
149*3955d011SMarcel Moolenaar #ifdef CLEANUP
150*3955d011SMarcel Moolenaar static void TargFreeGN(void *);
151*3955d011SMarcel Moolenaar #endif
152*3955d011SMarcel Moolenaar static int TargPropagateCohort(void *, void *);
153*3955d011SMarcel Moolenaar static int TargPropagateNode(void *, void *);
154*3955d011SMarcel Moolenaar 
155*3955d011SMarcel Moolenaar /*-
156*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
157*3955d011SMarcel Moolenaar  * Targ_Init --
158*3955d011SMarcel Moolenaar  *	Initialize this module
159*3955d011SMarcel Moolenaar  *
160*3955d011SMarcel Moolenaar  * Results:
161*3955d011SMarcel Moolenaar  *	None
162*3955d011SMarcel Moolenaar  *
163*3955d011SMarcel Moolenaar  * Side Effects:
164*3955d011SMarcel Moolenaar  *	The allTargets list and the targets hash table are initialized
165*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
166*3955d011SMarcel Moolenaar  */
167*3955d011SMarcel Moolenaar void
168*3955d011SMarcel Moolenaar Targ_Init(void)
169*3955d011SMarcel Moolenaar {
170*3955d011SMarcel Moolenaar     allTargets = Lst_Init(FALSE);
171*3955d011SMarcel Moolenaar     Hash_InitTable(&targets, HTSIZE);
172*3955d011SMarcel Moolenaar }
173*3955d011SMarcel Moolenaar 
174*3955d011SMarcel Moolenaar /*-
175*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
176*3955d011SMarcel Moolenaar  * Targ_End --
177*3955d011SMarcel Moolenaar  *	Finalize this module
178*3955d011SMarcel Moolenaar  *
179*3955d011SMarcel Moolenaar  * Results:
180*3955d011SMarcel Moolenaar  *	None
181*3955d011SMarcel Moolenaar  *
182*3955d011SMarcel Moolenaar  * Side Effects:
183*3955d011SMarcel Moolenaar  *	All lists and gnodes are cleared
184*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
185*3955d011SMarcel Moolenaar  */
186*3955d011SMarcel Moolenaar void
187*3955d011SMarcel Moolenaar Targ_End(void)
188*3955d011SMarcel Moolenaar {
189*3955d011SMarcel Moolenaar #ifdef CLEANUP
190*3955d011SMarcel Moolenaar     Lst_Destroy(allTargets, NULL);
191*3955d011SMarcel Moolenaar     if (allGNs)
192*3955d011SMarcel Moolenaar 	Lst_Destroy(allGNs, TargFreeGN);
193*3955d011SMarcel Moolenaar     Hash_DeleteTable(&targets);
194*3955d011SMarcel Moolenaar #endif
195*3955d011SMarcel Moolenaar }
196*3955d011SMarcel Moolenaar 
197*3955d011SMarcel Moolenaar /*-
198*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
199*3955d011SMarcel Moolenaar  * Targ_List --
200*3955d011SMarcel Moolenaar  *	Return the list of all targets
201*3955d011SMarcel Moolenaar  *
202*3955d011SMarcel Moolenaar  * Results:
203*3955d011SMarcel Moolenaar  *	The list of all targets.
204*3955d011SMarcel Moolenaar  *
205*3955d011SMarcel Moolenaar  * Side Effects:
206*3955d011SMarcel Moolenaar  *	None
207*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
208*3955d011SMarcel Moolenaar  */
209*3955d011SMarcel Moolenaar Lst
210*3955d011SMarcel Moolenaar Targ_List(void)
211*3955d011SMarcel Moolenaar {
212*3955d011SMarcel Moolenaar     return allTargets;
213*3955d011SMarcel Moolenaar }
214*3955d011SMarcel Moolenaar 
215*3955d011SMarcel Moolenaar /*-
216*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
217*3955d011SMarcel Moolenaar  * Targ_NewGN  --
218*3955d011SMarcel Moolenaar  *	Create and initialize a new graph node
219*3955d011SMarcel Moolenaar  *
220*3955d011SMarcel Moolenaar  * Input:
221*3955d011SMarcel Moolenaar  *	name		the name to stick in the new node
222*3955d011SMarcel Moolenaar  *
223*3955d011SMarcel Moolenaar  * Results:
224*3955d011SMarcel Moolenaar  *	An initialized graph node with the name field filled with a copy
225*3955d011SMarcel Moolenaar  *	of the passed name
226*3955d011SMarcel Moolenaar  *
227*3955d011SMarcel Moolenaar  * Side Effects:
228*3955d011SMarcel Moolenaar  *	The gnode is added to the list of all gnodes.
229*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
230*3955d011SMarcel Moolenaar  */
231*3955d011SMarcel Moolenaar GNode *
232*3955d011SMarcel Moolenaar Targ_NewGN(const char *name)
233*3955d011SMarcel Moolenaar {
234*3955d011SMarcel Moolenaar     GNode *gn;
235*3955d011SMarcel Moolenaar 
236*3955d011SMarcel Moolenaar     gn = bmake_malloc(sizeof(GNode));
237*3955d011SMarcel Moolenaar     gn->name = bmake_strdup(name);
238*3955d011SMarcel Moolenaar     gn->uname = NULL;
239*3955d011SMarcel Moolenaar     gn->path = NULL;
240*3955d011SMarcel Moolenaar     if (name[0] == '-' && name[1] == 'l') {
241*3955d011SMarcel Moolenaar 	gn->type = OP_LIB;
242*3955d011SMarcel Moolenaar     } else {
243*3955d011SMarcel Moolenaar 	gn->type = 0;
244*3955d011SMarcel Moolenaar     }
245*3955d011SMarcel Moolenaar     gn->unmade =    	0;
246*3955d011SMarcel Moolenaar     gn->unmade_cohorts = 0;
247*3955d011SMarcel Moolenaar     gn->cohort_num[0] = 0;
248*3955d011SMarcel Moolenaar     gn->centurion =    	NULL;
249*3955d011SMarcel Moolenaar     gn->made = 	    	UNMADE;
250*3955d011SMarcel Moolenaar     gn->flags = 	0;
251*3955d011SMarcel Moolenaar     gn->checked =	0;
252*3955d011SMarcel Moolenaar     gn->mtime =		0;
253*3955d011SMarcel Moolenaar     gn->cmgn =		NULL;
254*3955d011SMarcel Moolenaar     gn->iParents =  	Lst_Init(FALSE);
255*3955d011SMarcel Moolenaar     gn->cohorts =   	Lst_Init(FALSE);
256*3955d011SMarcel Moolenaar     gn->parents =   	Lst_Init(FALSE);
257*3955d011SMarcel Moolenaar     gn->children =  	Lst_Init(FALSE);
258*3955d011SMarcel Moolenaar     gn->order_pred =  	Lst_Init(FALSE);
259*3955d011SMarcel Moolenaar     gn->order_succ =  	Lst_Init(FALSE);
260*3955d011SMarcel Moolenaar     Hash_InitTable(&gn->context, 0);
261*3955d011SMarcel Moolenaar     gn->commands =  	Lst_Init(FALSE);
262*3955d011SMarcel Moolenaar     gn->suffix =	NULL;
263*3955d011SMarcel Moolenaar     gn->lineno =	0;
264*3955d011SMarcel Moolenaar     gn->fname = 	NULL;
265*3955d011SMarcel Moolenaar 
266*3955d011SMarcel Moolenaar #ifdef CLEANUP
267*3955d011SMarcel Moolenaar     if (allGNs == NULL)
268*3955d011SMarcel Moolenaar 	allGNs = Lst_Init(FALSE);
269*3955d011SMarcel Moolenaar     Lst_AtEnd(allGNs, gn);
270*3955d011SMarcel Moolenaar #endif
271*3955d011SMarcel Moolenaar 
272*3955d011SMarcel Moolenaar     return (gn);
273*3955d011SMarcel Moolenaar }
274*3955d011SMarcel Moolenaar 
275*3955d011SMarcel Moolenaar #ifdef CLEANUP
276*3955d011SMarcel Moolenaar /*-
277*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
278*3955d011SMarcel Moolenaar  * TargFreeGN  --
279*3955d011SMarcel Moolenaar  *	Destroy a GNode
280*3955d011SMarcel Moolenaar  *
281*3955d011SMarcel Moolenaar  * Results:
282*3955d011SMarcel Moolenaar  *	None.
283*3955d011SMarcel Moolenaar  *
284*3955d011SMarcel Moolenaar  * Side Effects:
285*3955d011SMarcel Moolenaar  *	None.
286*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
287*3955d011SMarcel Moolenaar  */
288*3955d011SMarcel Moolenaar static void
289*3955d011SMarcel Moolenaar TargFreeGN(void *gnp)
290*3955d011SMarcel Moolenaar {
291*3955d011SMarcel Moolenaar     GNode *gn = (GNode *)gnp;
292*3955d011SMarcel Moolenaar 
293*3955d011SMarcel Moolenaar 
294*3955d011SMarcel Moolenaar     free(gn->name);
295*3955d011SMarcel Moolenaar     if (gn->uname)
296*3955d011SMarcel Moolenaar 	free(gn->uname);
297*3955d011SMarcel Moolenaar     if (gn->path)
298*3955d011SMarcel Moolenaar 	free(gn->path);
299*3955d011SMarcel Moolenaar     /* gn->fname points to name allocated when file was opened, don't free */
300*3955d011SMarcel Moolenaar 
301*3955d011SMarcel Moolenaar     Lst_Destroy(gn->iParents, NULL);
302*3955d011SMarcel Moolenaar     Lst_Destroy(gn->cohorts, NULL);
303*3955d011SMarcel Moolenaar     Lst_Destroy(gn->parents, NULL);
304*3955d011SMarcel Moolenaar     Lst_Destroy(gn->children, NULL);
305*3955d011SMarcel Moolenaar     Lst_Destroy(gn->order_succ, NULL);
306*3955d011SMarcel Moolenaar     Lst_Destroy(gn->order_pred, NULL);
307*3955d011SMarcel Moolenaar     Hash_DeleteTable(&gn->context);
308*3955d011SMarcel Moolenaar     Lst_Destroy(gn->commands, NULL);
309*3955d011SMarcel Moolenaar     free(gn);
310*3955d011SMarcel Moolenaar }
311*3955d011SMarcel Moolenaar #endif
312*3955d011SMarcel Moolenaar 
313*3955d011SMarcel Moolenaar 
314*3955d011SMarcel Moolenaar /*-
315*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
316*3955d011SMarcel Moolenaar  * Targ_FindNode  --
317*3955d011SMarcel Moolenaar  *	Find a node in the list using the given name for matching
318*3955d011SMarcel Moolenaar  *
319*3955d011SMarcel Moolenaar  * Input:
320*3955d011SMarcel Moolenaar  *	name		the name to find
321*3955d011SMarcel Moolenaar  *	flags		flags governing events when target not
322*3955d011SMarcel Moolenaar  *			found
323*3955d011SMarcel Moolenaar  *
324*3955d011SMarcel Moolenaar  * Results:
325*3955d011SMarcel Moolenaar  *	The node in the list if it was. If it wasn't, return NULL of
326*3955d011SMarcel Moolenaar  *	flags was TARG_NOCREATE or the newly created and initialized node
327*3955d011SMarcel Moolenaar  *	if it was TARG_CREATE
328*3955d011SMarcel Moolenaar  *
329*3955d011SMarcel Moolenaar  * Side Effects:
330*3955d011SMarcel Moolenaar  *	Sometimes a node is created and added to the list
331*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
332*3955d011SMarcel Moolenaar  */
333*3955d011SMarcel Moolenaar GNode *
334*3955d011SMarcel Moolenaar Targ_FindNode(const char *name, int flags)
335*3955d011SMarcel Moolenaar {
336*3955d011SMarcel Moolenaar     GNode         *gn;	      /* node in that element */
337*3955d011SMarcel Moolenaar     Hash_Entry	  *he = NULL; /* New or used hash entry for node */
338*3955d011SMarcel Moolenaar     Boolean	  isNew;      /* Set TRUE if Hash_CreateEntry had to create */
339*3955d011SMarcel Moolenaar 			      /* an entry for the node */
340*3955d011SMarcel Moolenaar 
341*3955d011SMarcel Moolenaar     if (!(flags & (TARG_CREATE | TARG_NOHASH))) {
342*3955d011SMarcel Moolenaar 	he = Hash_FindEntry(&targets, name);
343*3955d011SMarcel Moolenaar 	if (he == NULL)
344*3955d011SMarcel Moolenaar 	    return NULL;
345*3955d011SMarcel Moolenaar 	return (GNode *)Hash_GetValue(he);
346*3955d011SMarcel Moolenaar     }
347*3955d011SMarcel Moolenaar 
348*3955d011SMarcel Moolenaar     if (!(flags & TARG_NOHASH)) {
349*3955d011SMarcel Moolenaar 	he = Hash_CreateEntry(&targets, name, &isNew);
350*3955d011SMarcel Moolenaar 	if (!isNew)
351*3955d011SMarcel Moolenaar 	    return (GNode *)Hash_GetValue(he);
352*3955d011SMarcel Moolenaar     }
353*3955d011SMarcel Moolenaar 
354*3955d011SMarcel Moolenaar     gn = Targ_NewGN(name);
355*3955d011SMarcel Moolenaar     if (!(flags & TARG_NOHASH))
356*3955d011SMarcel Moolenaar 	Hash_SetValue(he, gn);
357*3955d011SMarcel Moolenaar     Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
358*3955d011SMarcel Moolenaar     (void)Lst_AtEnd(allTargets, gn);
359*3955d011SMarcel Moolenaar     if (doing_depend)
360*3955d011SMarcel Moolenaar 	gn->flags |= FROM_DEPEND;
361*3955d011SMarcel Moolenaar     return gn;
362*3955d011SMarcel Moolenaar }
363*3955d011SMarcel Moolenaar 
364*3955d011SMarcel Moolenaar /*-
365*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
366*3955d011SMarcel Moolenaar  * Targ_FindList --
367*3955d011SMarcel Moolenaar  *	Make a complete list of GNodes from the given list of names
368*3955d011SMarcel Moolenaar  *
369*3955d011SMarcel Moolenaar  * Input:
370*3955d011SMarcel Moolenaar  *	name		list of names to find
371*3955d011SMarcel Moolenaar  *	flags		flags used if no node is found for a given name
372*3955d011SMarcel Moolenaar  *
373*3955d011SMarcel Moolenaar  * Results:
374*3955d011SMarcel Moolenaar  *	A complete list of graph nodes corresponding to all instances of all
375*3955d011SMarcel Moolenaar  *	the names in names.
376*3955d011SMarcel Moolenaar  *
377*3955d011SMarcel Moolenaar  * Side Effects:
378*3955d011SMarcel Moolenaar  *	If flags is TARG_CREATE, nodes will be created for all names in
379*3955d011SMarcel Moolenaar  *	names which do not yet have graph nodes. If flags is TARG_NOCREATE,
380*3955d011SMarcel Moolenaar  *	an error message will be printed for each name which can't be found.
381*3955d011SMarcel Moolenaar  * -----------------------------------------------------------------------
382*3955d011SMarcel Moolenaar  */
383*3955d011SMarcel Moolenaar Lst
384*3955d011SMarcel Moolenaar Targ_FindList(Lst names, int flags)
385*3955d011SMarcel Moolenaar {
386*3955d011SMarcel Moolenaar     Lst            nodes;	/* result list */
387*3955d011SMarcel Moolenaar     LstNode	   ln;		/* name list element */
388*3955d011SMarcel Moolenaar     GNode	   *gn;		/* node in tLn */
389*3955d011SMarcel Moolenaar     char    	   *name;
390*3955d011SMarcel Moolenaar 
391*3955d011SMarcel Moolenaar     nodes = Lst_Init(FALSE);
392*3955d011SMarcel Moolenaar 
393*3955d011SMarcel Moolenaar     if (Lst_Open(names) == FAILURE) {
394*3955d011SMarcel Moolenaar 	return (nodes);
395*3955d011SMarcel Moolenaar     }
396*3955d011SMarcel Moolenaar     while ((ln = Lst_Next(names)) != NULL) {
397*3955d011SMarcel Moolenaar 	name = (char *)Lst_Datum(ln);
398*3955d011SMarcel Moolenaar 	gn = Targ_FindNode(name, flags);
399*3955d011SMarcel Moolenaar 	if (gn != NULL) {
400*3955d011SMarcel Moolenaar 	    /*
401*3955d011SMarcel Moolenaar 	     * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
402*3955d011SMarcel Moolenaar 	     * are added to the list in the order in which they were
403*3955d011SMarcel Moolenaar 	     * encountered in the makefile.
404*3955d011SMarcel Moolenaar 	     */
405*3955d011SMarcel Moolenaar 	    (void)Lst_AtEnd(nodes, gn);
406*3955d011SMarcel Moolenaar 	} else if (flags == TARG_NOCREATE) {
407*3955d011SMarcel Moolenaar 	    Error("\"%s\" -- target unknown.", name);
408*3955d011SMarcel Moolenaar 	}
409*3955d011SMarcel Moolenaar     }
410*3955d011SMarcel Moolenaar     Lst_Close(names);
411*3955d011SMarcel Moolenaar     return (nodes);
412*3955d011SMarcel Moolenaar }
413*3955d011SMarcel Moolenaar 
414*3955d011SMarcel Moolenaar /*-
415*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
416*3955d011SMarcel Moolenaar  * Targ_Ignore  --
417*3955d011SMarcel Moolenaar  *	Return true if should ignore errors when creating gn
418*3955d011SMarcel Moolenaar  *
419*3955d011SMarcel Moolenaar  * Input:
420*3955d011SMarcel Moolenaar  *	gn		node to check for
421*3955d011SMarcel Moolenaar  *
422*3955d011SMarcel Moolenaar  * Results:
423*3955d011SMarcel Moolenaar  *	TRUE if should ignore errors
424*3955d011SMarcel Moolenaar  *
425*3955d011SMarcel Moolenaar  * Side Effects:
426*3955d011SMarcel Moolenaar  *	None
427*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
428*3955d011SMarcel Moolenaar  */
429*3955d011SMarcel Moolenaar Boolean
430*3955d011SMarcel Moolenaar Targ_Ignore(GNode *gn)
431*3955d011SMarcel Moolenaar {
432*3955d011SMarcel Moolenaar     if (ignoreErrors || gn->type & OP_IGNORE) {
433*3955d011SMarcel Moolenaar 	return (TRUE);
434*3955d011SMarcel Moolenaar     } else {
435*3955d011SMarcel Moolenaar 	return (FALSE);
436*3955d011SMarcel Moolenaar     }
437*3955d011SMarcel Moolenaar }
438*3955d011SMarcel Moolenaar 
439*3955d011SMarcel Moolenaar /*-
440*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
441*3955d011SMarcel Moolenaar  * Targ_Silent  --
442*3955d011SMarcel Moolenaar  *	Return true if be silent when creating gn
443*3955d011SMarcel Moolenaar  *
444*3955d011SMarcel Moolenaar  * Input:
445*3955d011SMarcel Moolenaar  *	gn		node to check for
446*3955d011SMarcel Moolenaar  *
447*3955d011SMarcel Moolenaar  * Results:
448*3955d011SMarcel Moolenaar  *	TRUE if should be silent
449*3955d011SMarcel Moolenaar  *
450*3955d011SMarcel Moolenaar  * Side Effects:
451*3955d011SMarcel Moolenaar  *	None
452*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
453*3955d011SMarcel Moolenaar  */
454*3955d011SMarcel Moolenaar Boolean
455*3955d011SMarcel Moolenaar Targ_Silent(GNode *gn)
456*3955d011SMarcel Moolenaar {
457*3955d011SMarcel Moolenaar     if (beSilent || gn->type & OP_SILENT) {
458*3955d011SMarcel Moolenaar 	return (TRUE);
459*3955d011SMarcel Moolenaar     } else {
460*3955d011SMarcel Moolenaar 	return (FALSE);
461*3955d011SMarcel Moolenaar     }
462*3955d011SMarcel Moolenaar }
463*3955d011SMarcel Moolenaar 
464*3955d011SMarcel Moolenaar /*-
465*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
466*3955d011SMarcel Moolenaar  * Targ_Precious --
467*3955d011SMarcel Moolenaar  *	See if the given target is precious
468*3955d011SMarcel Moolenaar  *
469*3955d011SMarcel Moolenaar  * Input:
470*3955d011SMarcel Moolenaar  *	gn		the node to check
471*3955d011SMarcel Moolenaar  *
472*3955d011SMarcel Moolenaar  * Results:
473*3955d011SMarcel Moolenaar  *	TRUE if it is precious. FALSE otherwise
474*3955d011SMarcel Moolenaar  *
475*3955d011SMarcel Moolenaar  * Side Effects:
476*3955d011SMarcel Moolenaar  *	None
477*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
478*3955d011SMarcel Moolenaar  */
479*3955d011SMarcel Moolenaar Boolean
480*3955d011SMarcel Moolenaar Targ_Precious(GNode *gn)
481*3955d011SMarcel Moolenaar {
482*3955d011SMarcel Moolenaar     if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) {
483*3955d011SMarcel Moolenaar 	return (TRUE);
484*3955d011SMarcel Moolenaar     } else {
485*3955d011SMarcel Moolenaar 	return (FALSE);
486*3955d011SMarcel Moolenaar     }
487*3955d011SMarcel Moolenaar }
488*3955d011SMarcel Moolenaar 
489*3955d011SMarcel Moolenaar /******************* DEBUG INFO PRINTING ****************/
490*3955d011SMarcel Moolenaar 
491*3955d011SMarcel Moolenaar static GNode	  *mainTarg;	/* the main target, as set by Targ_SetMain */
492*3955d011SMarcel Moolenaar /*-
493*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
494*3955d011SMarcel Moolenaar  * Targ_SetMain --
495*3955d011SMarcel Moolenaar  *	Set our idea of the main target we'll be creating. Used for
496*3955d011SMarcel Moolenaar  *	debugging output.
497*3955d011SMarcel Moolenaar  *
498*3955d011SMarcel Moolenaar  * Input:
499*3955d011SMarcel Moolenaar  *	gn		The main target we'll create
500*3955d011SMarcel Moolenaar  *
501*3955d011SMarcel Moolenaar  * Results:
502*3955d011SMarcel Moolenaar  *	None.
503*3955d011SMarcel Moolenaar  *
504*3955d011SMarcel Moolenaar  * Side Effects:
505*3955d011SMarcel Moolenaar  *	"mainTarg" is set to the main target's node.
506*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
507*3955d011SMarcel Moolenaar  */
508*3955d011SMarcel Moolenaar void
509*3955d011SMarcel Moolenaar Targ_SetMain(GNode *gn)
510*3955d011SMarcel Moolenaar {
511*3955d011SMarcel Moolenaar     mainTarg = gn;
512*3955d011SMarcel Moolenaar }
513*3955d011SMarcel Moolenaar 
514*3955d011SMarcel Moolenaar static int
515*3955d011SMarcel Moolenaar TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED)
516*3955d011SMarcel Moolenaar {
517*3955d011SMarcel Moolenaar     GNode *gn = (GNode *)gnp;
518*3955d011SMarcel Moolenaar 
519*3955d011SMarcel Moolenaar     fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num);
520*3955d011SMarcel Moolenaar 
521*3955d011SMarcel Moolenaar     return 0;
522*3955d011SMarcel Moolenaar }
523*3955d011SMarcel Moolenaar 
524*3955d011SMarcel Moolenaar 
525*3955d011SMarcel Moolenaar int
526*3955d011SMarcel Moolenaar Targ_PrintCmd(void *cmd, void *dummy)
527*3955d011SMarcel Moolenaar {
528*3955d011SMarcel Moolenaar     fprintf(debug_file, "\t%s\n", (char *)cmd);
529*3955d011SMarcel Moolenaar     return (dummy ? 0 : 0);
530*3955d011SMarcel Moolenaar }
531*3955d011SMarcel Moolenaar 
532*3955d011SMarcel Moolenaar /*-
533*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
534*3955d011SMarcel Moolenaar  * Targ_FmtTime --
535*3955d011SMarcel Moolenaar  *	Format a modification time in some reasonable way and return it.
536*3955d011SMarcel Moolenaar  *
537*3955d011SMarcel Moolenaar  * Results:
538*3955d011SMarcel Moolenaar  *	The time reformatted.
539*3955d011SMarcel Moolenaar  *
540*3955d011SMarcel Moolenaar  * Side Effects:
541*3955d011SMarcel Moolenaar  *	The time is placed in a static area, so it is overwritten
542*3955d011SMarcel Moolenaar  *	with each call.
543*3955d011SMarcel Moolenaar  *
544*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
545*3955d011SMarcel Moolenaar  */
546*3955d011SMarcel Moolenaar char *
547*3955d011SMarcel Moolenaar Targ_FmtTime(time_t tm)
548*3955d011SMarcel Moolenaar {
549*3955d011SMarcel Moolenaar     struct tm	  	*parts;
550*3955d011SMarcel Moolenaar     static char	  	buf[128];
551*3955d011SMarcel Moolenaar 
552*3955d011SMarcel Moolenaar     parts = localtime(&tm);
553*3955d011SMarcel Moolenaar     (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
554*3955d011SMarcel Moolenaar     return(buf);
555*3955d011SMarcel Moolenaar }
556*3955d011SMarcel Moolenaar 
557*3955d011SMarcel Moolenaar /*-
558*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
559*3955d011SMarcel Moolenaar  * Targ_PrintType --
560*3955d011SMarcel Moolenaar  *	Print out a type field giving only those attributes the user can
561*3955d011SMarcel Moolenaar  *	set.
562*3955d011SMarcel Moolenaar  *
563*3955d011SMarcel Moolenaar  * Results:
564*3955d011SMarcel Moolenaar  *
565*3955d011SMarcel Moolenaar  * Side Effects:
566*3955d011SMarcel Moolenaar  *
567*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
568*3955d011SMarcel Moolenaar  */
569*3955d011SMarcel Moolenaar void
570*3955d011SMarcel Moolenaar Targ_PrintType(int type)
571*3955d011SMarcel Moolenaar {
572*3955d011SMarcel Moolenaar     int    tbit;
573*3955d011SMarcel Moolenaar 
574*3955d011SMarcel Moolenaar #define PRINTBIT(attr)	case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break
575*3955d011SMarcel Moolenaar #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break
576*3955d011SMarcel Moolenaar 
577*3955d011SMarcel Moolenaar     type &= ~OP_OPMASK;
578*3955d011SMarcel Moolenaar 
579*3955d011SMarcel Moolenaar     while (type) {
580*3955d011SMarcel Moolenaar 	tbit = 1 << (ffs(type) - 1);
581*3955d011SMarcel Moolenaar 	type &= ~tbit;
582*3955d011SMarcel Moolenaar 
583*3955d011SMarcel Moolenaar 	switch(tbit) {
584*3955d011SMarcel Moolenaar 	    PRINTBIT(OPTIONAL);
585*3955d011SMarcel Moolenaar 	    PRINTBIT(USE);
586*3955d011SMarcel Moolenaar 	    PRINTBIT(EXEC);
587*3955d011SMarcel Moolenaar 	    PRINTBIT(IGNORE);
588*3955d011SMarcel Moolenaar 	    PRINTBIT(PRECIOUS);
589*3955d011SMarcel Moolenaar 	    PRINTBIT(SILENT);
590*3955d011SMarcel Moolenaar 	    PRINTBIT(MAKE);
591*3955d011SMarcel Moolenaar 	    PRINTBIT(JOIN);
592*3955d011SMarcel Moolenaar 	    PRINTBIT(INVISIBLE);
593*3955d011SMarcel Moolenaar 	    PRINTBIT(NOTMAIN);
594*3955d011SMarcel Moolenaar 	    PRINTDBIT(LIB);
595*3955d011SMarcel Moolenaar 	    /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
596*3955d011SMarcel Moolenaar 	    case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break;
597*3955d011SMarcel Moolenaar 	    PRINTDBIT(ARCHV);
598*3955d011SMarcel Moolenaar 	    PRINTDBIT(MADE);
599*3955d011SMarcel Moolenaar 	    PRINTDBIT(PHONY);
600*3955d011SMarcel Moolenaar 	}
601*3955d011SMarcel Moolenaar     }
602*3955d011SMarcel Moolenaar }
603*3955d011SMarcel Moolenaar 
604*3955d011SMarcel Moolenaar static const char *
605*3955d011SMarcel Moolenaar made_name(enum enum_made made)
606*3955d011SMarcel Moolenaar {
607*3955d011SMarcel Moolenaar     switch (made) {
608*3955d011SMarcel Moolenaar     case UNMADE:     return "unmade";
609*3955d011SMarcel Moolenaar     case DEFERRED:   return "deferred";
610*3955d011SMarcel Moolenaar     case REQUESTED:  return "requested";
611*3955d011SMarcel Moolenaar     case BEINGMADE:  return "being made";
612*3955d011SMarcel Moolenaar     case MADE:       return "made";
613*3955d011SMarcel Moolenaar     case UPTODATE:   return "up-to-date";
614*3955d011SMarcel Moolenaar     case ERROR:      return "error when made";
615*3955d011SMarcel Moolenaar     case ABORTED:    return "aborted";
616*3955d011SMarcel Moolenaar     default:         return "unknown enum_made value";
617*3955d011SMarcel Moolenaar     }
618*3955d011SMarcel Moolenaar }
619*3955d011SMarcel Moolenaar 
620*3955d011SMarcel Moolenaar /*-
621*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
622*3955d011SMarcel Moolenaar  * TargPrintNode --
623*3955d011SMarcel Moolenaar  *	print the contents of a node
624*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
625*3955d011SMarcel Moolenaar  */
626*3955d011SMarcel Moolenaar int
627*3955d011SMarcel Moolenaar Targ_PrintNode(void *gnp, void *passp)
628*3955d011SMarcel Moolenaar {
629*3955d011SMarcel Moolenaar     GNode         *gn = (GNode *)gnp;
630*3955d011SMarcel Moolenaar     int	    	  pass = passp ? *(int *)passp : 0;
631*3955d011SMarcel Moolenaar 
632*3955d011SMarcel Moolenaar     fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n",
633*3955d011SMarcel Moolenaar 	    gn->name, gn->cohort_num, gn->flags, gn->type, gn->made);
634*3955d011SMarcel Moolenaar     if (gn->flags == 0)
635*3955d011SMarcel Moolenaar 	return 0;
636*3955d011SMarcel Moolenaar 
637*3955d011SMarcel Moolenaar     if (!OP_NOP(gn->type)) {
638*3955d011SMarcel Moolenaar 	fprintf(debug_file, "#\n");
639*3955d011SMarcel Moolenaar 	if (gn == mainTarg) {
640*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "# *** MAIN TARGET ***\n");
641*3955d011SMarcel Moolenaar 	}
642*3955d011SMarcel Moolenaar 	if (pass >= 2) {
643*3955d011SMarcel Moolenaar 	    if (gn->unmade) {
644*3955d011SMarcel Moolenaar 		fprintf(debug_file, "# %d unmade children\n", gn->unmade);
645*3955d011SMarcel Moolenaar 	    } else {
646*3955d011SMarcel Moolenaar 		fprintf(debug_file, "# No unmade children\n");
647*3955d011SMarcel Moolenaar 	    }
648*3955d011SMarcel Moolenaar 	    if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
649*3955d011SMarcel Moolenaar 		if (gn->mtime != 0) {
650*3955d011SMarcel Moolenaar 		    fprintf(debug_file, "# last modified %s: %s\n",
651*3955d011SMarcel Moolenaar 			      Targ_FmtTime(gn->mtime),
652*3955d011SMarcel Moolenaar 			      made_name(gn->made));
653*3955d011SMarcel Moolenaar 		} else if (gn->made != UNMADE) {
654*3955d011SMarcel Moolenaar 		    fprintf(debug_file, "# non-existent (maybe): %s\n",
655*3955d011SMarcel Moolenaar 			      made_name(gn->made));
656*3955d011SMarcel Moolenaar 		} else {
657*3955d011SMarcel Moolenaar 		    fprintf(debug_file, "# unmade\n");
658*3955d011SMarcel Moolenaar 		}
659*3955d011SMarcel Moolenaar 	    }
660*3955d011SMarcel Moolenaar 	    if (!Lst_IsEmpty (gn->iParents)) {
661*3955d011SMarcel Moolenaar 		fprintf(debug_file, "# implicit parents: ");
662*3955d011SMarcel Moolenaar 		Lst_ForEach(gn->iParents, TargPrintName, NULL);
663*3955d011SMarcel Moolenaar 		fprintf(debug_file, "\n");
664*3955d011SMarcel Moolenaar 	    }
665*3955d011SMarcel Moolenaar 	} else {
666*3955d011SMarcel Moolenaar 	    if (gn->unmade)
667*3955d011SMarcel Moolenaar 		fprintf(debug_file, "# %d unmade children\n", gn->unmade);
668*3955d011SMarcel Moolenaar 	}
669*3955d011SMarcel Moolenaar 	if (!Lst_IsEmpty (gn->parents)) {
670*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "# parents: ");
671*3955d011SMarcel Moolenaar 	    Lst_ForEach(gn->parents, TargPrintName, NULL);
672*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "\n");
673*3955d011SMarcel Moolenaar 	}
674*3955d011SMarcel Moolenaar 	if (!Lst_IsEmpty (gn->order_pred)) {
675*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "# order_pred: ");
676*3955d011SMarcel Moolenaar 	    Lst_ForEach(gn->order_pred, TargPrintName, NULL);
677*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "\n");
678*3955d011SMarcel Moolenaar 	}
679*3955d011SMarcel Moolenaar 	if (!Lst_IsEmpty (gn->order_succ)) {
680*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "# order_succ: ");
681*3955d011SMarcel Moolenaar 	    Lst_ForEach(gn->order_succ, TargPrintName, NULL);
682*3955d011SMarcel Moolenaar 	    fprintf(debug_file, "\n");
683*3955d011SMarcel Moolenaar 	}
684*3955d011SMarcel Moolenaar 
685*3955d011SMarcel Moolenaar 	fprintf(debug_file, "%-16s", gn->name);
686*3955d011SMarcel Moolenaar 	switch (gn->type & OP_OPMASK) {
687*3955d011SMarcel Moolenaar 	    case OP_DEPENDS:
688*3955d011SMarcel Moolenaar 		fprintf(debug_file, ": "); break;
689*3955d011SMarcel Moolenaar 	    case OP_FORCE:
690*3955d011SMarcel Moolenaar 		fprintf(debug_file, "! "); break;
691*3955d011SMarcel Moolenaar 	    case OP_DOUBLEDEP:
692*3955d011SMarcel Moolenaar 		fprintf(debug_file, ":: "); break;
693*3955d011SMarcel Moolenaar 	}
694*3955d011SMarcel Moolenaar 	Targ_PrintType(gn->type);
695*3955d011SMarcel Moolenaar 	Lst_ForEach(gn->children, TargPrintName, NULL);
696*3955d011SMarcel Moolenaar 	fprintf(debug_file, "\n");
697*3955d011SMarcel Moolenaar 	Lst_ForEach(gn->commands, Targ_PrintCmd, NULL);
698*3955d011SMarcel Moolenaar 	fprintf(debug_file, "\n\n");
699*3955d011SMarcel Moolenaar 	if (gn->type & OP_DOUBLEDEP) {
700*3955d011SMarcel Moolenaar 	    Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass);
701*3955d011SMarcel Moolenaar 	}
702*3955d011SMarcel Moolenaar     }
703*3955d011SMarcel Moolenaar     return (0);
704*3955d011SMarcel Moolenaar }
705*3955d011SMarcel Moolenaar 
706*3955d011SMarcel Moolenaar /*-
707*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
708*3955d011SMarcel Moolenaar  * TargPrintOnlySrc --
709*3955d011SMarcel Moolenaar  *	Print only those targets that are just a source.
710*3955d011SMarcel Moolenaar  *
711*3955d011SMarcel Moolenaar  * Results:
712*3955d011SMarcel Moolenaar  *	0.
713*3955d011SMarcel Moolenaar  *
714*3955d011SMarcel Moolenaar  * Side Effects:
715*3955d011SMarcel Moolenaar  *	The name of each file is printed preceded by #\t
716*3955d011SMarcel Moolenaar  *
717*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
718*3955d011SMarcel Moolenaar  */
719*3955d011SMarcel Moolenaar static int
720*3955d011SMarcel Moolenaar TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED)
721*3955d011SMarcel Moolenaar {
722*3955d011SMarcel Moolenaar     GNode   	  *gn = (GNode *)gnp;
723*3955d011SMarcel Moolenaar     if (!OP_NOP(gn->type))
724*3955d011SMarcel Moolenaar 	return 0;
725*3955d011SMarcel Moolenaar 
726*3955d011SMarcel Moolenaar     fprintf(debug_file, "#\t%s [%s] ",
727*3955d011SMarcel Moolenaar 	    gn->name, gn->path ? gn->path : gn->name);
728*3955d011SMarcel Moolenaar     Targ_PrintType(gn->type);
729*3955d011SMarcel Moolenaar     fprintf(debug_file, "\n");
730*3955d011SMarcel Moolenaar 
731*3955d011SMarcel Moolenaar     return 0;
732*3955d011SMarcel Moolenaar }
733*3955d011SMarcel Moolenaar 
734*3955d011SMarcel Moolenaar /*-
735*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
736*3955d011SMarcel Moolenaar  * Targ_PrintGraph --
737*3955d011SMarcel Moolenaar  *	print the entire graph. heh heh
738*3955d011SMarcel Moolenaar  *
739*3955d011SMarcel Moolenaar  * Input:
740*3955d011SMarcel Moolenaar  *	pass		Which pass this is. 1 => no processing
741*3955d011SMarcel Moolenaar  *			2 => processing done
742*3955d011SMarcel Moolenaar  *
743*3955d011SMarcel Moolenaar  * Results:
744*3955d011SMarcel Moolenaar  *	none
745*3955d011SMarcel Moolenaar  *
746*3955d011SMarcel Moolenaar  * Side Effects:
747*3955d011SMarcel Moolenaar  *	lots o' output
748*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
749*3955d011SMarcel Moolenaar  */
750*3955d011SMarcel Moolenaar void
751*3955d011SMarcel Moolenaar Targ_PrintGraph(int pass)
752*3955d011SMarcel Moolenaar {
753*3955d011SMarcel Moolenaar     fprintf(debug_file, "#*** Input graph:\n");
754*3955d011SMarcel Moolenaar     Lst_ForEach(allTargets, Targ_PrintNode, &pass);
755*3955d011SMarcel Moolenaar     fprintf(debug_file, "\n\n");
756*3955d011SMarcel Moolenaar     fprintf(debug_file, "#\n#   Files that are only sources:\n");
757*3955d011SMarcel Moolenaar     Lst_ForEach(allTargets, TargPrintOnlySrc, NULL);
758*3955d011SMarcel Moolenaar     fprintf(debug_file, "#*** Global Variables:\n");
759*3955d011SMarcel Moolenaar     Var_Dump(VAR_GLOBAL);
760*3955d011SMarcel Moolenaar     fprintf(debug_file, "#*** Command-line Variables:\n");
761*3955d011SMarcel Moolenaar     Var_Dump(VAR_CMD);
762*3955d011SMarcel Moolenaar     fprintf(debug_file, "\n");
763*3955d011SMarcel Moolenaar     Dir_PrintDirectories();
764*3955d011SMarcel Moolenaar     fprintf(debug_file, "\n");
765*3955d011SMarcel Moolenaar     Suff_PrintAll();
766*3955d011SMarcel Moolenaar }
767*3955d011SMarcel Moolenaar 
768*3955d011SMarcel Moolenaar /*-
769*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
770*3955d011SMarcel Moolenaar  * TargPropagateNode --
771*3955d011SMarcel Moolenaar  *	Propagate information from a single node to related nodes if
772*3955d011SMarcel Moolenaar  *	appropriate.
773*3955d011SMarcel Moolenaar  *
774*3955d011SMarcel Moolenaar  * Input:
775*3955d011SMarcel Moolenaar  *	gnp		The node that we are processing.
776*3955d011SMarcel Moolenaar  *
777*3955d011SMarcel Moolenaar  * Results:
778*3955d011SMarcel Moolenaar  *	Always returns 0, for the benefit of Lst_ForEach().
779*3955d011SMarcel Moolenaar  *
780*3955d011SMarcel Moolenaar  * Side Effects:
781*3955d011SMarcel Moolenaar  *	Information is propagated from this node to cohort or child
782*3955d011SMarcel Moolenaar  *	nodes.
783*3955d011SMarcel Moolenaar  *
784*3955d011SMarcel Moolenaar  *	If the node was defined with "::", then TargPropagateCohort()
785*3955d011SMarcel Moolenaar  *	will be called for each cohort node.
786*3955d011SMarcel Moolenaar  *
787*3955d011SMarcel Moolenaar  *	If the node has recursive predecessors, then
788*3955d011SMarcel Moolenaar  *	TargPropagateRecpred() will be called for each recursive
789*3955d011SMarcel Moolenaar  *	predecessor.
790*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
791*3955d011SMarcel Moolenaar  */
792*3955d011SMarcel Moolenaar static int
793*3955d011SMarcel Moolenaar TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED)
794*3955d011SMarcel Moolenaar {
795*3955d011SMarcel Moolenaar     GNode	  *gn = (GNode *)gnp;
796*3955d011SMarcel Moolenaar 
797*3955d011SMarcel Moolenaar     if (gn->type & OP_DOUBLEDEP)
798*3955d011SMarcel Moolenaar 	Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp);
799*3955d011SMarcel Moolenaar     return (0);
800*3955d011SMarcel Moolenaar }
801*3955d011SMarcel Moolenaar 
802*3955d011SMarcel Moolenaar /*-
803*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
804*3955d011SMarcel Moolenaar  * TargPropagateCohort --
805*3955d011SMarcel Moolenaar  *	Propagate some bits in the type mask from a node to
806*3955d011SMarcel Moolenaar  *	a related cohort node.
807*3955d011SMarcel Moolenaar  *
808*3955d011SMarcel Moolenaar  * Input:
809*3955d011SMarcel Moolenaar  *	cnp		The node that we are processing.
810*3955d011SMarcel Moolenaar  *	gnp		Another node that has cnp as a cohort.
811*3955d011SMarcel Moolenaar  *
812*3955d011SMarcel Moolenaar  * Results:
813*3955d011SMarcel Moolenaar  *	Always returns 0, for the benefit of Lst_ForEach().
814*3955d011SMarcel Moolenaar  *
815*3955d011SMarcel Moolenaar  * Side Effects:
816*3955d011SMarcel Moolenaar  *	cnp's type bitmask is modified to incorporate some of the
817*3955d011SMarcel Moolenaar  *	bits from gnp's type bitmask.  (XXX need a better explanation.)
818*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
819*3955d011SMarcel Moolenaar  */
820*3955d011SMarcel Moolenaar static int
821*3955d011SMarcel Moolenaar TargPropagateCohort(void *cgnp, void *pgnp)
822*3955d011SMarcel Moolenaar {
823*3955d011SMarcel Moolenaar     GNode	  *cgn = (GNode *)cgnp;
824*3955d011SMarcel Moolenaar     GNode	  *pgn = (GNode *)pgnp;
825*3955d011SMarcel Moolenaar 
826*3955d011SMarcel Moolenaar     cgn->type |= pgn->type & ~OP_OPMASK;
827*3955d011SMarcel Moolenaar     return (0);
828*3955d011SMarcel Moolenaar }
829*3955d011SMarcel Moolenaar 
830*3955d011SMarcel Moolenaar /*-
831*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
832*3955d011SMarcel Moolenaar  * Targ_Propagate --
833*3955d011SMarcel Moolenaar  *	Propagate information between related nodes.  Should be called
834*3955d011SMarcel Moolenaar  *	after the makefiles are parsed but before any action is taken.
835*3955d011SMarcel Moolenaar  *
836*3955d011SMarcel Moolenaar  * Results:
837*3955d011SMarcel Moolenaar  *	none
838*3955d011SMarcel Moolenaar  *
839*3955d011SMarcel Moolenaar  * Side Effects:
840*3955d011SMarcel Moolenaar  *	Information is propagated between related nodes throughout the
841*3955d011SMarcel Moolenaar  *	graph.
842*3955d011SMarcel Moolenaar  *-----------------------------------------------------------------------
843*3955d011SMarcel Moolenaar  */
844*3955d011SMarcel Moolenaar void
845*3955d011SMarcel Moolenaar Targ_Propagate(void)
846*3955d011SMarcel Moolenaar {
847*3955d011SMarcel Moolenaar     Lst_ForEach(allTargets, TargPropagateNode, NULL);
848*3955d011SMarcel Moolenaar }
849