targ.c revision 138264
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1988, 1989, 1990, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes * Copyright (c) 1989 by Berkeley Softworks
51590Srgrimes * All rights reserved.
61590Srgrimes *
71590Srgrimes * This code is derived from software contributed to Berkeley by
81590Srgrimes * Adam de Boor.
91590Srgrimes *
101590Srgrimes * Redistribution and use in source and binary forms, with or without
111590Srgrimes * modification, are permitted provided that the following conditions
121590Srgrimes * are met:
131590Srgrimes * 1. Redistributions of source code must retain the above copyright
141590Srgrimes *    notice, this list of conditions and the following disclaimer.
151590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161590Srgrimes *    notice, this list of conditions and the following disclaimer in the
171590Srgrimes *    documentation and/or other materials provided with the distribution.
181590Srgrimes * 3. All advertising materials mentioning features or use of this software
191590Srgrimes *    must display the following acknowledgement:
201590Srgrimes *	This product includes software developed by the University of
211590Srgrimes *	California, Berkeley and its contributors.
221590Srgrimes * 4. Neither the name of the University nor the names of its contributors
231590Srgrimes *    may be used to endorse or promote products derived from this software
241590Srgrimes *    without specific prior written permission.
251590Srgrimes *
261590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
271590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
281590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
291590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
301590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
311590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
321590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
331590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
341590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
351590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
361590Srgrimes * SUCH DAMAGE.
3762833Swsanchez *
3862833Swsanchez * @(#)targ.c	8.2 (Berkeley) 3/19/94
391590Srgrimes */
401590Srgrimes
4162833Swsanchez#include <sys/cdefs.h>
4294587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/targ.c 138264 2004-12-01 10:29:20Z harti $");
431590Srgrimes
441590Srgrimes/*-
451590Srgrimes * targ.c --
461590Srgrimes *	Functions for maintaining the Lst allTargets. Target nodes are
471590Srgrimes * kept in two structures: a Lst, maintained by the list library, and a
481590Srgrimes * hash table, maintained by the hash library.
491590Srgrimes *
501590Srgrimes * Interface:
511590Srgrimes *	Targ_Init 	    	Initialization procedure.
521590Srgrimes *
535814Sjkh *	Targ_End 	    	Cleanup the module
545814Sjkh *
551590Srgrimes *	Targ_NewGN	    	Create a new GNode for the passed target
561590Srgrimes *	    	  	    	(string). The node is *not* placed in the
571590Srgrimes *	    	  	    	hash table, though all its fields are
581590Srgrimes *	    	  	    	initialized.
591590Srgrimes *
601590Srgrimes *	Targ_FindNode	    	Find the node for a given target, creating
611590Srgrimes *	    	  	    	and storing it if it doesn't exist and the
621590Srgrimes *	    	  	    	flags are right (TARG_CREATE)
631590Srgrimes *
641590Srgrimes *	Targ_FindList	    	Given a list of names, find nodes for all
651590Srgrimes *	    	  	    	of them. If a name doesn't exist and the
661590Srgrimes *	    	  	    	TARG_NOCREATE flag was given, an error message
671590Srgrimes *	    	  	    	is printed. Else, if a name doesn't exist,
681590Srgrimes *	    	  	    	its node is created.
691590Srgrimes *
701590Srgrimes *	Targ_Ignore	    	Return TRUE if errors should be ignored when
711590Srgrimes *	    	  	    	creating the given target.
721590Srgrimes *
731590Srgrimes *	Targ_Silent	    	Return TRUE if we should be silent when
741590Srgrimes *	    	  	    	creating the given target.
751590Srgrimes *
761590Srgrimes *	Targ_Precious	    	Return TRUE if the target is precious and
771590Srgrimes *	    	  	    	should not be removed if we are interrupted.
781590Srgrimes *
791590Srgrimes * Debugging:
801590Srgrimes *	Targ_PrintGraph	    	Print out the entire graphm all variables
811590Srgrimes *	    	  	    	and statistics for the directory cache. Should
821590Srgrimes *	    	  	    	print something for suffixes, too, but...
831590Srgrimes */
841590Srgrimes
851590Srgrimes#include	  <stdio.h>
861590Srgrimes#include	  <time.h>
871590Srgrimes#include	  "make.h"
881590Srgrimes#include	  "hash.h"
891590Srgrimes#include	  "dir.h"
901590Srgrimes
911590Srgrimesstatic Lst        allTargets;	/* the list of all targets found so far */
925814Sjkhstatic Lst	  allGNs;	/* List of all the GNodes */
931590Srgrimesstatic Hash_Table targets;	/* a hash table of same */
941590Srgrimes
95103503Sjmallett#define	HTSIZE	191		/* initial size of hash table */
961590Srgrimes
9792921Simpstatic int TargPrintOnlySrc(void *, void *);
9892921Simpstatic int TargPrintName(void *, void *);
9992921Simpstatic int TargPrintNode(void *, void *);
10092921Simpstatic void TargFreeGN(void *);
1015814Sjkh
1021590Srgrimes/*-
1031590Srgrimes *-----------------------------------------------------------------------
1041590Srgrimes * Targ_Init --
1051590Srgrimes *	Initialize this module
1061590Srgrimes *
1071590Srgrimes * Results:
1081590Srgrimes *	None
1091590Srgrimes *
1101590Srgrimes * Side Effects:
1111590Srgrimes *	The allTargets list and the targets hash table are initialized
1121590Srgrimes *-----------------------------------------------------------------------
1131590Srgrimes */
1141590Srgrimesvoid
115138232ShartiTarg_Init(void)
1161590Srgrimes{
117138232Sharti
118138232Sharti    allTargets = Lst_Init(FALSE);
119138232Sharti    Hash_InitTable(&targets, HTSIZE);
1201590Srgrimes}
1211590Srgrimes
1221590Srgrimes/*-
1231590Srgrimes *-----------------------------------------------------------------------
1245814Sjkh * Targ_End --
1255814Sjkh *	Finalize this module
1265814Sjkh *
1275814Sjkh * Results:
1285814Sjkh *	None
1295814Sjkh *
1305814Sjkh * Side Effects:
1315814Sjkh *	All lists and gnodes are cleared
1325814Sjkh *-----------------------------------------------------------------------
1335814Sjkh */
1345814Sjkhvoid
135138232ShartiTarg_End(void)
1365814Sjkh{
137138232Sharti
1385814Sjkh    Lst_Destroy(allTargets, NOFREE);
1395814Sjkh    if (allGNs)
1405814Sjkh	Lst_Destroy(allGNs, TargFreeGN);
1415814Sjkh    Hash_DeleteTable(&targets);
1425814Sjkh}
1435814Sjkh
1445814Sjkh/*-
1455814Sjkh *-----------------------------------------------------------------------
1461590Srgrimes * Targ_NewGN  --
1471590Srgrimes *	Create and initialize a new graph node
1481590Srgrimes *
1491590Srgrimes * Results:
1501590Srgrimes *	An initialized graph node with the name field filled with a copy
1511590Srgrimes *	of the passed name
1521590Srgrimes *
1531590Srgrimes * Side Effects:
1545814Sjkh *	The gnode is added to the list of all gnodes.
1551590Srgrimes *-----------------------------------------------------------------------
1561590Srgrimes */
1571590SrgrimesGNode *
158138232ShartiTarg_NewGN(char *name)
1591590Srgrimes{
16094584Sobrien    GNode *gn;
1611590Srgrimes
162138264Sharti    gn = emalloc(sizeof(GNode));
163138232Sharti    gn->name = estrdup(name);
164138264Sharti    gn->path = NULL;
1651590Srgrimes    if (name[0] == '-' && name[1] == 'l') {
1661590Srgrimes	gn->type = OP_LIB;
1671590Srgrimes    } else {
1681590Srgrimes	gn->type = 0;
1691590Srgrimes    }
170138232Sharti    gn->unmade = 0;
171138232Sharti    gn->make = FALSE;
172138232Sharti    gn->made = UNMADE;
173138232Sharti    gn->childMade = FALSE;
174138232Sharti    gn->order = 0;
1751590Srgrimes    gn->mtime = gn->cmtime = 0;
176138232Sharti    gn->iParents = Lst_Init(FALSE);
177138232Sharti    gn->cohorts = Lst_Init(FALSE);
178138232Sharti    gn->parents = Lst_Init(FALSE);
179138232Sharti    gn->children = Lst_Init(FALSE);
180138232Sharti    gn->successors = Lst_Init(FALSE);
181138232Sharti    gn->preds = Lst_Init(FALSE);
182138232Sharti    gn->context = Lst_Init(FALSE);
183138232Sharti    gn->commands = Lst_Init(FALSE);
184138232Sharti    gn->suffix = NULL;
1851590Srgrimes
1865814Sjkh    if (allGNs == NULL)
1875814Sjkh	allGNs = Lst_Init(FALSE);
188138232Sharti    Lst_AtEnd(allGNs, (void *)gn);
1895814Sjkh
1901590Srgrimes    return (gn);
1911590Srgrimes}
1921590Srgrimes
1931590Srgrimes/*-
1941590Srgrimes *-----------------------------------------------------------------------
1955814Sjkh * TargFreeGN  --
1965814Sjkh *	Destroy a GNode
1975814Sjkh *
1985814Sjkh * Results:
1995814Sjkh *	None.
2005814Sjkh *
2015814Sjkh * Side Effects:
2025814Sjkh *	None.
2035814Sjkh *-----------------------------------------------------------------------
2045814Sjkh */
2055814Sjkhstatic void
206138232ShartiTargFreeGN(void *gnp)
2075814Sjkh{
208138264Sharti    GNode *gn = gnp;
2095814Sjkh
2105814Sjkh    free(gn->name);
211105826Sjmallett    free(gn->path);
2125814Sjkh
2135814Sjkh    Lst_Destroy(gn->iParents, NOFREE);
2145814Sjkh    Lst_Destroy(gn->cohorts, NOFREE);
2155814Sjkh    Lst_Destroy(gn->parents, NOFREE);
2165814Sjkh    Lst_Destroy(gn->children, NOFREE);
2175814Sjkh    Lst_Destroy(gn->successors, NOFREE);
2185814Sjkh    Lst_Destroy(gn->preds, NOFREE);
2195814Sjkh    Lst_Destroy(gn->context, NOFREE);
2205814Sjkh    Lst_Destroy(gn->commands, NOFREE);
22169531Swill    free(gn);
2225814Sjkh}
2235814Sjkh
2245814Sjkh/*-
2255814Sjkh *-----------------------------------------------------------------------
2261590Srgrimes * Targ_FindNode  --
2271590Srgrimes *	Find a node in the list using the given name for matching
2281590Srgrimes *
2291590Srgrimes * Results:
23069527Swill *	The node in the list if it was. If it wasn't, return NULL of
2311590Srgrimes *	flags was TARG_NOCREATE or the newly created and initialized node
2321590Srgrimes *	if it was TARG_CREATE
2331590Srgrimes *
2341590Srgrimes * Side Effects:
2351590Srgrimes *	Sometimes a node is created and added to the list
2361590Srgrimes *-----------------------------------------------------------------------
2371590Srgrimes */
2381590SrgrimesGNode *
239138232ShartiTarg_FindNode(char *name, int flags)
2401590Srgrimes{
2411590Srgrimes    GNode         *gn;	      /* node in that element */
2421590Srgrimes    Hash_Entry	  *he;	      /* New or used hash entry for node */
2431590Srgrimes    Boolean	  isNew;      /* Set TRUE if Hash_CreateEntry had to create */
2441590Srgrimes			      /* an entry for the node */
2451590Srgrimes
2461590Srgrimes    if (flags & TARG_CREATE) {
247138232Sharti	he = Hash_CreateEntry(&targets, name, &isNew);
2481590Srgrimes	if (isNew) {
249138232Sharti	    gn = Targ_NewGN(name);
2501590Srgrimes	    Hash_SetValue (he, gn);
251138264Sharti	    Lst_AtEnd(allTargets, gn);
2521590Srgrimes	}
2531590Srgrimes    } else {
254138232Sharti	he = Hash_FindEntry(&targets, name);
2551590Srgrimes    }
2561590Srgrimes
257138264Sharti    if (he == NULL) {
25869527Swill	return (NULL);
2591590Srgrimes    } else {
260138264Sharti	return (Hash_GetValue(he));
2611590Srgrimes    }
2621590Srgrimes}
2631590Srgrimes
2641590Srgrimes/*-
2651590Srgrimes *-----------------------------------------------------------------------
2661590Srgrimes * Targ_FindList --
2678874Srgrimes *	Make a complete list of GNodes from the given list of names
2681590Srgrimes *
2691590Srgrimes * Results:
2701590Srgrimes *	A complete list of graph nodes corresponding to all instances of all
2718874Srgrimes *	the names in names.
2721590Srgrimes *
2731590Srgrimes * Side Effects:
2741590Srgrimes *	If flags is TARG_CREATE, nodes will be created for all names in
2751590Srgrimes *	names which do not yet have graph nodes. If flags is TARG_NOCREATE,
2761590Srgrimes *	an error message will be printed for each name which can't be found.
2771590Srgrimes * -----------------------------------------------------------------------
2781590Srgrimes */
2791590SrgrimesLst
280138232ShartiTarg_FindList(Lst names, int flags)
2811590Srgrimes{
2821590Srgrimes    Lst            nodes;	/* result list */
28394584Sobrien    LstNode	   ln;		/* name list element */
28494584Sobrien    GNode	   *gn;		/* node in tLn */
28594584Sobrien    char    	   *name;
2861590Srgrimes
287138232Sharti    nodes = Lst_Init(FALSE);
2881590Srgrimes
289138232Sharti    if (Lst_Open(names) == FAILURE) {
2901590Srgrimes	return (nodes);
2911590Srgrimes    }
292138232Sharti    while ((ln = Lst_Next(names)) != NULL) {
293138264Sharti	name = Lst_Datum(ln);
294138232Sharti	gn = Targ_FindNode(name, flags);
29569527Swill	if (gn != NULL) {
2961590Srgrimes	    /*
2971590Srgrimes	     * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
2981590Srgrimes	     * are added to the list in the order in which they were
2991590Srgrimes	     * encountered in the makefile.
3001590Srgrimes	     */
301138264Sharti	    Lst_AtEnd(nodes, gn);
3021590Srgrimes	    if (gn->type & OP_DOUBLEDEP) {
303138232Sharti		Lst_Concat(nodes, gn->cohorts, LST_CONCNEW);
3041590Srgrimes	    }
3051590Srgrimes	} else if (flags == TARG_NOCREATE) {
306138232Sharti	    Error("\"%s\" -- target unknown.", name);
3071590Srgrimes	}
3081590Srgrimes    }
309138232Sharti    Lst_Close(names);
3101590Srgrimes    return (nodes);
3111590Srgrimes}
3121590Srgrimes
3131590Srgrimes/*-
3141590Srgrimes *-----------------------------------------------------------------------
3151590Srgrimes * Targ_Ignore  --
3161590Srgrimes *	Return true if should ignore errors when creating gn
3171590Srgrimes *
3181590Srgrimes * Results:
3191590Srgrimes *	TRUE if should ignore errors
3201590Srgrimes *
3211590Srgrimes * Side Effects:
3221590Srgrimes *	None
3231590Srgrimes *-----------------------------------------------------------------------
3241590Srgrimes */
3251590SrgrimesBoolean
326138232ShartiTarg_Ignore(GNode *gn)
3271590Srgrimes{
328138232Sharti
329138232Sharti    if (ignoreErrors || (gn->type & OP_IGNORE)) {
3301590Srgrimes	return (TRUE);
3311590Srgrimes    } else {
3321590Srgrimes	return (FALSE);
3331590Srgrimes    }
3341590Srgrimes}
3351590Srgrimes
3361590Srgrimes/*-
3371590Srgrimes *-----------------------------------------------------------------------
3381590Srgrimes * Targ_Silent  --
3391590Srgrimes *	Return true if be silent when creating gn
3401590Srgrimes *
3411590Srgrimes * Results:
3421590Srgrimes *	TRUE if should be silent
3431590Srgrimes *
3441590Srgrimes * Side Effects:
3451590Srgrimes *	None
3461590Srgrimes *-----------------------------------------------------------------------
3471590Srgrimes */
3481590SrgrimesBoolean
349138232ShartiTarg_Silent(GNode *gn)
3501590Srgrimes{
351138232Sharti
352138232Sharti    if (beSilent || (gn->type & OP_SILENT)) {
3531590Srgrimes	return (TRUE);
3541590Srgrimes    } else {
3551590Srgrimes	return (FALSE);
3561590Srgrimes    }
3571590Srgrimes}
3581590Srgrimes
3591590Srgrimes/*-
3601590Srgrimes *-----------------------------------------------------------------------
3611590Srgrimes * Targ_Precious --
3621590Srgrimes *	See if the given target is precious
3631590Srgrimes *
3641590Srgrimes * Results:
3651590Srgrimes *	TRUE if it is precious. FALSE otherwise
3661590Srgrimes *
3671590Srgrimes * Side Effects:
3681590Srgrimes *	None
3691590Srgrimes *-----------------------------------------------------------------------
3701590Srgrimes */
3711590SrgrimesBoolean
372138232ShartiTarg_Precious(GNode *gn)
3731590Srgrimes{
374138232Sharti
375138232Sharti    if (allPrecious || (gn->type & (OP_PRECIOUS | OP_DOUBLEDEP))) {
3761590Srgrimes	return (TRUE);
3771590Srgrimes    } else {
3781590Srgrimes	return (FALSE);
3791590Srgrimes    }
3801590Srgrimes}
3811590Srgrimes
3821590Srgrimes/******************* DEBUG INFO PRINTING ****************/
3831590Srgrimes
3841590Srgrimesstatic GNode	  *mainTarg;	/* the main target, as set by Targ_SetMain */
385138232Sharti
3868874Srgrimes/*-
3871590Srgrimes *-----------------------------------------------------------------------
3881590Srgrimes * Targ_SetMain --
3891590Srgrimes *	Set our idea of the main target we'll be creating. Used for
3901590Srgrimes *	debugging output.
3911590Srgrimes *
3921590Srgrimes * Results:
3931590Srgrimes *	None.
3941590Srgrimes *
3951590Srgrimes * Side Effects:
3961590Srgrimes *	"mainTarg" is set to the main target's node.
3971590Srgrimes *-----------------------------------------------------------------------
3981590Srgrimes */
3991590Srgrimesvoid
400138232ShartiTarg_SetMain(GNode *gn)
4011590Srgrimes{
402138232Sharti
4031590Srgrimes    mainTarg = gn;
4041590Srgrimes}
4051590Srgrimes
4061590Srgrimesstatic int
407138232ShartiTargPrintName(void *gnp, void *ppath)
4081590Srgrimes{
4095814Sjkh    GNode *gn = (GNode *) gnp;
410138232Sharti
411138232Sharti    printf("%s ", gn->name);
4121590Srgrimes#ifdef notdef
4131590Srgrimes    if (ppath) {
4141590Srgrimes	if (gn->path) {
415138232Sharti	    printf("[%s]  ", gn->path);
4161590Srgrimes	}
4171590Srgrimes	if (gn == mainTarg) {
418138232Sharti	    printf("(MAIN NAME)  ");
4191590Srgrimes	}
4201590Srgrimes    }
4211590Srgrimes#endif /* notdef */
4225814Sjkh    return (ppath ? 0 : 0);
4231590Srgrimes}
4241590Srgrimes
4251590Srgrimes
4261590Srgrimesint
427138232ShartiTarg_PrintCmd(void *cmd, void *dummy __unused)
4281590Srgrimes{
429138232Sharti
430138232Sharti    printf("\t%s\n", (char *)cmd);
431104696Sjmallett    return (0);
4321590Srgrimes}
4331590Srgrimes
4341590Srgrimes/*-
4351590Srgrimes *-----------------------------------------------------------------------
4361590Srgrimes * Targ_FmtTime --
4371590Srgrimes *	Format a modification time in some reasonable way and return it.
4381590Srgrimes *
4391590Srgrimes * Results:
4401590Srgrimes *	The time reformatted.
4411590Srgrimes *
4421590Srgrimes * Side Effects:
4431590Srgrimes *	The time is placed in a static area, so it is overwritten
4441590Srgrimes *	with each call.
4451590Srgrimes *
4461590Srgrimes *-----------------------------------------------------------------------
4471590Srgrimes */
4481590Srgrimeschar *
449138232ShartiTarg_FmtTime(time_t modtime)
4501590Srgrimes{
4511590Srgrimes    struct tm	  	*parts;
45249938Shoek    static char	  	buf[128];
4531590Srgrimes
454104121Sjmallett    parts = localtime(&modtime);
4551590Srgrimes
456103990Sjmallett    strftime(buf, sizeof buf, "%H:%M:%S %b %d, %Y", parts);
45749938Shoek    buf[sizeof(buf) - 1] = '\0';
458138232Sharti    return (buf);
4591590Srgrimes}
4608874Srgrimes
4611590Srgrimes/*-
4621590Srgrimes *-----------------------------------------------------------------------
4631590Srgrimes * Targ_PrintType --
4641590Srgrimes *	Print out a type field giving only those attributes the user can
4651590Srgrimes *	set.
4661590Srgrimes *
4671590Srgrimes * Results:
4681590Srgrimes *
4691590Srgrimes * Side Effects:
4701590Srgrimes *
4711590Srgrimes *-----------------------------------------------------------------------
4721590Srgrimes */
4731590Srgrimesvoid
474138232ShartiTarg_PrintType(int type)
4751590Srgrimes{
47694584Sobrien    int    tbit;
4778874Srgrimes
478103503Sjmallett#define	PRINTBIT(attr)	case CONCAT(OP_,attr): printf("." #attr " "); break
479103545Sjmallett#define	PRINTDBIT(attr) case CONCAT(OP_,attr): DEBUGF(TARG, ("." #attr " ")); break
4801590Srgrimes
4811590Srgrimes    type &= ~OP_OPMASK;
4821590Srgrimes
4831590Srgrimes    while (type) {
4841590Srgrimes	tbit = 1 << (ffs(type) - 1);
4851590Srgrimes	type &= ~tbit;
4861590Srgrimes
4871590Srgrimes	switch(tbit) {
4881590Srgrimes	    PRINTBIT(OPTIONAL);
4891590Srgrimes	    PRINTBIT(USE);
4901590Srgrimes	    PRINTBIT(EXEC);
4911590Srgrimes	    PRINTBIT(IGNORE);
4921590Srgrimes	    PRINTBIT(PRECIOUS);
4931590Srgrimes	    PRINTBIT(SILENT);
4941590Srgrimes	    PRINTBIT(MAKE);
4951590Srgrimes	    PRINTBIT(JOIN);
4961590Srgrimes	    PRINTBIT(INVISIBLE);
4971590Srgrimes	    PRINTBIT(NOTMAIN);
4981590Srgrimes	    PRINTDBIT(LIB);
4991590Srgrimes	    /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
500103545Sjmallett	    case OP_MEMBER: DEBUGF(TARG, (".MEMBER ")); break;
5011590Srgrimes	    PRINTDBIT(ARCHV);
5021590Srgrimes	}
5031590Srgrimes    }
5041590Srgrimes}
5051590Srgrimes
5061590Srgrimes/*-
5071590Srgrimes *-----------------------------------------------------------------------
5081590Srgrimes * TargPrintNode --
5091590Srgrimes *	print the contents of a node
5101590Srgrimes *-----------------------------------------------------------------------
5111590Srgrimes */
5121590Srgrimesstatic int
513138232ShartiTargPrintNode(void *gnp, void *passp)
5141590Srgrimes{
515138264Sharti    GNode         *gn = gnp;
516138232Sharti    int	    	  pass = *(int *)passp;
517138232Sharti
5181590Srgrimes    if (!OP_NOP(gn->type)) {
5191590Srgrimes	printf("#\n");
5201590Srgrimes	if (gn == mainTarg) {
5211590Srgrimes	    printf("# *** MAIN TARGET ***\n");
5221590Srgrimes	}
5231590Srgrimes	if (pass == 2) {
5241590Srgrimes	    if (gn->unmade) {
5251590Srgrimes		printf("# %d unmade children\n", gn->unmade);
5261590Srgrimes	    } else {
5271590Srgrimes		printf("# No unmade children\n");
5281590Srgrimes	    }
529138264Sharti	    if (!(gn->type & (OP_JOIN | OP_USE | OP_EXEC))) {
5301590Srgrimes		if (gn->mtime != 0) {
5311590Srgrimes		    printf("# last modified %s: %s\n",
5321590Srgrimes			      Targ_FmtTime(gn->mtime),
5331590Srgrimes			      (gn->made == UNMADE ? "unmade" :
5341590Srgrimes			       (gn->made == MADE ? "made" :
5351590Srgrimes				(gn->made == UPTODATE ? "up-to-date" :
5361590Srgrimes				 "error when made"))));
5371590Srgrimes		} else if (gn->made != UNMADE) {
5381590Srgrimes		    printf("# non-existent (maybe): %s\n",
5391590Srgrimes			      (gn->made == MADE ? "made" :
5401590Srgrimes			       (gn->made == UPTODATE ? "up-to-date" :
5411590Srgrimes				(gn->made == ERROR ? "error when made" :
5421590Srgrimes				 "aborted"))));
5431590Srgrimes		} else {
5441590Srgrimes		    printf("# unmade\n");
5451590Srgrimes		}
5461590Srgrimes	    }
5471590Srgrimes	    if (!Lst_IsEmpty (gn->iParents)) {
5481590Srgrimes		printf("# implicit parents: ");
549138264Sharti		Lst_ForEach(gn->iParents, TargPrintName, (void *)NULL);
550138232Sharti		fputc('\n', stdout);
5511590Srgrimes	    }
5521590Srgrimes	}
5531590Srgrimes	if (!Lst_IsEmpty (gn->parents)) {
5541590Srgrimes	    printf("# parents: ");
555138264Sharti	    Lst_ForEach(gn->parents, TargPrintName, (void *)NULL);
556138232Sharti	    fputc('\n', stdout);
5571590Srgrimes	}
5588874Srgrimes
5591590Srgrimes	printf("%-16s", gn->name);
5601590Srgrimes	switch (gn->type & OP_OPMASK) {
5611590Srgrimes	    case OP_DEPENDS:
5621590Srgrimes		printf(": "); break;
5631590Srgrimes	    case OP_FORCE:
5641590Srgrimes		printf("! "); break;
5651590Srgrimes	    case OP_DOUBLEDEP:
5661590Srgrimes		printf(":: "); break;
567104108Sjmallett	    default:
568104108Sjmallett		break;
5691590Srgrimes	}
570138232Sharti	Targ_PrintType(gn->type);
571138264Sharti	Lst_ForEach(gn->children, TargPrintName, (void *)NULL);
572138232Sharti	fputc('\n', stdout);
573138264Sharti	Lst_ForEach(gn->commands, Targ_PrintCmd, (void *)NULL);
5741590Srgrimes	printf("\n\n");
5751590Srgrimes	if (gn->type & OP_DOUBLEDEP) {
576138264Sharti	    Lst_ForEach(gn->cohorts, TargPrintNode, &pass);
5771590Srgrimes	}
5781590Srgrimes    }
5791590Srgrimes    return (0);
5801590Srgrimes}
5811590Srgrimes
5821590Srgrimes/*-
5831590Srgrimes *-----------------------------------------------------------------------
5841590Srgrimes * TargPrintOnlySrc --
5851590Srgrimes *	Print only those targets that are just a source.
5861590Srgrimes *
5871590Srgrimes * Results:
5881590Srgrimes *	0.
5891590Srgrimes *
5901590Srgrimes * Side Effects:
59172645Sasmodai *	The name of each file is printed preceded by #\t
5921590Srgrimes *
5931590Srgrimes *-----------------------------------------------------------------------
5941590Srgrimes */
5951590Srgrimesstatic int
596104696SjmallettTargPrintOnlySrc(void *gnp, void *dummy __unused)
5971590Srgrimes{
598138264Sharti    GNode   	  *gn = gnp;
599138232Sharti
6005814Sjkh    if (OP_NOP(gn->type))
6015814Sjkh	printf("#\t%s [%s]\n", gn->name, gn->path ? gn->path : gn->name);
6025814Sjkh
603104696Sjmallett    return (0);
6041590Srgrimes}
6051590Srgrimes
6061590Srgrimes/*-
6071590Srgrimes *-----------------------------------------------------------------------
6081590Srgrimes * Targ_PrintGraph --
609104696Sjmallett *	Print the entire graph.
6101590Srgrimes *
6111590Srgrimes * Results:
6121590Srgrimes *	none
6131590Srgrimes *
6141590Srgrimes * Side Effects:
6151590Srgrimes *	lots o' output
6161590Srgrimes *-----------------------------------------------------------------------
6171590Srgrimes */
6181590Srgrimesvoid
619138232ShartiTarg_PrintGraph(int pass)
6201590Srgrimes{
621138264Sharti
6221590Srgrimes    printf("#*** Input graph:\n");
623138264Sharti    Lst_ForEach(allTargets, TargPrintNode, &pass);
6241590Srgrimes    printf("\n\n");
6251590Srgrimes    printf("#\n#   Files that are only sources:\n");
626138264Sharti    Lst_ForEach(allTargets, TargPrintOnlySrc, (void *)NULL);
6271590Srgrimes    printf("#*** Global Variables:\n");
628138232Sharti    Var_Dump(VAR_GLOBAL);
6291590Srgrimes    printf("#*** Command-line Variables:\n");
630138232Sharti    Var_Dump(VAR_CMD);
6311590Srgrimes    printf("\n");
6321590Srgrimes    Dir_PrintDirectories();
6331590Srgrimes    printf("\n");
6341590Srgrimes    Suff_PrintAll();
6351590Srgrimes}
636