targ.c revision 69527
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 411590Srgrimes#ifndef lint 4262833Swsanchez#include <sys/cdefs.h> 4362833Swsanchez__RCSID("$FreeBSD: head/usr.bin/make/targ.c 69527 2000-12-02 18:58:01Z will $"); 441590Srgrimes#endif /* not lint */ 451590Srgrimes 461590Srgrimes/*- 471590Srgrimes * targ.c -- 481590Srgrimes * Functions for maintaining the Lst allTargets. Target nodes are 491590Srgrimes * kept in two structures: a Lst, maintained by the list library, and a 501590Srgrimes * hash table, maintained by the hash library. 511590Srgrimes * 521590Srgrimes * Interface: 531590Srgrimes * Targ_Init Initialization procedure. 541590Srgrimes * 555814Sjkh * Targ_End Cleanup the module 565814Sjkh * 571590Srgrimes * Targ_NewGN Create a new GNode for the passed target 581590Srgrimes * (string). The node is *not* placed in the 591590Srgrimes * hash table, though all its fields are 601590Srgrimes * initialized. 611590Srgrimes * 621590Srgrimes * Targ_FindNode Find the node for a given target, creating 631590Srgrimes * and storing it if it doesn't exist and the 641590Srgrimes * flags are right (TARG_CREATE) 651590Srgrimes * 661590Srgrimes * Targ_FindList Given a list of names, find nodes for all 671590Srgrimes * of them. If a name doesn't exist and the 681590Srgrimes * TARG_NOCREATE flag was given, an error message 691590Srgrimes * is printed. Else, if a name doesn't exist, 701590Srgrimes * its node is created. 711590Srgrimes * 721590Srgrimes * Targ_Ignore Return TRUE if errors should be ignored when 731590Srgrimes * creating the given target. 741590Srgrimes * 751590Srgrimes * Targ_Silent Return TRUE if we should be silent when 761590Srgrimes * creating the given target. 771590Srgrimes * 781590Srgrimes * Targ_Precious Return TRUE if the target is precious and 791590Srgrimes * should not be removed if we are interrupted. 801590Srgrimes * 811590Srgrimes * Debugging: 821590Srgrimes * Targ_PrintGraph Print out the entire graphm all variables 831590Srgrimes * and statistics for the directory cache. Should 841590Srgrimes * print something for suffixes, too, but... 851590Srgrimes */ 861590Srgrimes 871590Srgrimes#include <stdio.h> 881590Srgrimes#include <time.h> 891590Srgrimes#include "make.h" 901590Srgrimes#include "hash.h" 911590Srgrimes#include "dir.h" 921590Srgrimes 931590Srgrimesstatic Lst allTargets; /* the list of all targets found so far */ 945814Sjkhstatic Lst allGNs; /* List of all the GNodes */ 951590Srgrimesstatic Hash_Table targets; /* a hash table of same */ 961590Srgrimes 971590Srgrimes#define HTSIZE 191 /* initial size of hash table */ 981590Srgrimes 995814Sjkhstatic int TargPrintOnlySrc __P((ClientData, ClientData)); 1005814Sjkhstatic int TargPrintName __P((ClientData, ClientData)); 1015814Sjkhstatic int TargPrintNode __P((ClientData, ClientData)); 1025814Sjkhstatic void TargFreeGN __P((ClientData)); 1035814Sjkh 1041590Srgrimes/*- 1051590Srgrimes *----------------------------------------------------------------------- 1061590Srgrimes * Targ_Init -- 1071590Srgrimes * Initialize this module 1081590Srgrimes * 1091590Srgrimes * Results: 1101590Srgrimes * None 1111590Srgrimes * 1121590Srgrimes * Side Effects: 1131590Srgrimes * The allTargets list and the targets hash table are initialized 1141590Srgrimes *----------------------------------------------------------------------- 1151590Srgrimes */ 1161590Srgrimesvoid 1171590SrgrimesTarg_Init () 1181590Srgrimes{ 1191590Srgrimes allTargets = Lst_Init (FALSE); 1201590Srgrimes Hash_InitTable (&targets, HTSIZE); 1211590Srgrimes} 1221590Srgrimes 1231590Srgrimes/*- 1241590Srgrimes *----------------------------------------------------------------------- 1255814Sjkh * Targ_End -- 1265814Sjkh * Finalize this module 1275814Sjkh * 1285814Sjkh * Results: 1295814Sjkh * None 1305814Sjkh * 1315814Sjkh * Side Effects: 1325814Sjkh * All lists and gnodes are cleared 1335814Sjkh *----------------------------------------------------------------------- 1345814Sjkh */ 1355814Sjkhvoid 1365814SjkhTarg_End () 1375814Sjkh{ 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 * 1581590SrgrimesTarg_NewGN (name) 1591590Srgrimes char *name; /* the name to stick in the new node */ 1601590Srgrimes{ 1611590Srgrimes register GNode *gn; 1621590Srgrimes 1631590Srgrimes gn = (GNode *) emalloc (sizeof (GNode)); 16418730Ssteve gn->name = estrdup (name); 1651590Srgrimes gn->path = (char *) 0; 1661590Srgrimes if (name[0] == '-' && name[1] == 'l') { 1671590Srgrimes gn->type = OP_LIB; 1681590Srgrimes } else { 1691590Srgrimes gn->type = 0; 1701590Srgrimes } 1711590Srgrimes gn->unmade = 0; 1721590Srgrimes gn->make = FALSE; 1731590Srgrimes gn->made = UNMADE; 1741590Srgrimes gn->childMade = FALSE; 17518730Ssteve gn->order = 0; 1761590Srgrimes gn->mtime = gn->cmtime = 0; 1771590Srgrimes gn->iParents = Lst_Init (FALSE); 1781590Srgrimes gn->cohorts = Lst_Init (FALSE); 1791590Srgrimes gn->parents = Lst_Init (FALSE); 1801590Srgrimes gn->children = Lst_Init (FALSE); 1815814Sjkh gn->successors = Lst_Init (FALSE); 1825814Sjkh gn->preds = Lst_Init (FALSE); 1831590Srgrimes gn->context = Lst_Init (FALSE); 1841590Srgrimes gn->commands = Lst_Init (FALSE); 1851590Srgrimes gn->suffix = NULL; 1861590Srgrimes 1875814Sjkh if (allGNs == NULL) 1885814Sjkh allGNs = Lst_Init(FALSE); 1895814Sjkh Lst_AtEnd(allGNs, (ClientData) gn); 1905814Sjkh 1911590Srgrimes return (gn); 1921590Srgrimes} 1931590Srgrimes 1941590Srgrimes/*- 1951590Srgrimes *----------------------------------------------------------------------- 1965814Sjkh * TargFreeGN -- 1975814Sjkh * Destroy a GNode 1985814Sjkh * 1995814Sjkh * Results: 2005814Sjkh * None. 2015814Sjkh * 2025814Sjkh * Side Effects: 2035814Sjkh * None. 2045814Sjkh *----------------------------------------------------------------------- 2055814Sjkh */ 2065814Sjkhstatic void 2075814SjkhTargFreeGN (gnp) 2085814Sjkh ClientData gnp; 2095814Sjkh{ 2105814Sjkh GNode *gn = (GNode *) gnp; 2115814Sjkh 2125814Sjkh 2135814Sjkh free(gn->name); 21449938Shoek efree(gn->path); 2155814Sjkh 2165814Sjkh Lst_Destroy(gn->iParents, NOFREE); 2175814Sjkh Lst_Destroy(gn->cohorts, NOFREE); 2185814Sjkh Lst_Destroy(gn->parents, NOFREE); 2195814Sjkh Lst_Destroy(gn->children, NOFREE); 2205814Sjkh Lst_Destroy(gn->successors, NOFREE); 2215814Sjkh Lst_Destroy(gn->preds, NOFREE); 2225814Sjkh Lst_Destroy(gn->context, NOFREE); 2235814Sjkh Lst_Destroy(gn->commands, NOFREE); 2245814Sjkh free((Address)gn); 2255814Sjkh} 2265814Sjkh 2275814Sjkh 2285814Sjkh/*- 2295814Sjkh *----------------------------------------------------------------------- 2301590Srgrimes * Targ_FindNode -- 2311590Srgrimes * Find a node in the list using the given name for matching 2321590Srgrimes * 2331590Srgrimes * Results: 23469527Swill * The node in the list if it was. If it wasn't, return NULL of 2351590Srgrimes * flags was TARG_NOCREATE or the newly created and initialized node 2361590Srgrimes * if it was TARG_CREATE 2371590Srgrimes * 2381590Srgrimes * Side Effects: 2391590Srgrimes * Sometimes a node is created and added to the list 2401590Srgrimes *----------------------------------------------------------------------- 2411590Srgrimes */ 2421590SrgrimesGNode * 2431590SrgrimesTarg_FindNode (name, flags) 2441590Srgrimes char *name; /* the name to find */ 2451590Srgrimes int flags; /* flags governing events when target not 2461590Srgrimes * found */ 2471590Srgrimes{ 2481590Srgrimes GNode *gn; /* node in that element */ 2491590Srgrimes Hash_Entry *he; /* New or used hash entry for node */ 2501590Srgrimes Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */ 2511590Srgrimes /* an entry for the node */ 2521590Srgrimes 2531590Srgrimes 2541590Srgrimes if (flags & TARG_CREATE) { 2551590Srgrimes he = Hash_CreateEntry (&targets, name, &isNew); 2561590Srgrimes if (isNew) { 2571590Srgrimes gn = Targ_NewGN (name); 2581590Srgrimes Hash_SetValue (he, gn); 2591590Srgrimes (void) Lst_AtEnd (allTargets, (ClientData)gn); 2601590Srgrimes } 2611590Srgrimes } else { 2621590Srgrimes he = Hash_FindEntry (&targets, name); 2631590Srgrimes } 2641590Srgrimes 2651590Srgrimes if (he == (Hash_Entry *) NULL) { 26669527Swill return (NULL); 2671590Srgrimes } else { 2681590Srgrimes return ((GNode *) Hash_GetValue (he)); 2691590Srgrimes } 2701590Srgrimes} 2711590Srgrimes 2721590Srgrimes/*- 2731590Srgrimes *----------------------------------------------------------------------- 2741590Srgrimes * Targ_FindList -- 2758874Srgrimes * Make a complete list of GNodes from the given list of names 2761590Srgrimes * 2771590Srgrimes * Results: 2781590Srgrimes * A complete list of graph nodes corresponding to all instances of all 2798874Srgrimes * the names in names. 2801590Srgrimes * 2811590Srgrimes * Side Effects: 2821590Srgrimes * If flags is TARG_CREATE, nodes will be created for all names in 2831590Srgrimes * names which do not yet have graph nodes. If flags is TARG_NOCREATE, 2841590Srgrimes * an error message will be printed for each name which can't be found. 2851590Srgrimes * ----------------------------------------------------------------------- 2861590Srgrimes */ 2871590SrgrimesLst 2881590SrgrimesTarg_FindList (names, flags) 2891590Srgrimes Lst names; /* list of names to find */ 2901590Srgrimes int flags; /* flags used if no node is found for a given 2911590Srgrimes * name */ 2921590Srgrimes{ 2931590Srgrimes Lst nodes; /* result list */ 2941590Srgrimes register LstNode ln; /* name list element */ 2951590Srgrimes register GNode *gn; /* node in tLn */ 2961590Srgrimes char *name; 2971590Srgrimes 2981590Srgrimes nodes = Lst_Init (FALSE); 2991590Srgrimes 3001590Srgrimes if (Lst_Open (names) == FAILURE) { 3011590Srgrimes return (nodes); 3021590Srgrimes } 30369527Swill while ((ln = Lst_Next (names)) != NULL) { 3041590Srgrimes name = (char *)Lst_Datum(ln); 3051590Srgrimes gn = Targ_FindNode (name, flags); 30669527Swill if (gn != NULL) { 3071590Srgrimes /* 3081590Srgrimes * Note: Lst_AtEnd must come before the Lst_Concat so the nodes 3091590Srgrimes * are added to the list in the order in which they were 3101590Srgrimes * encountered in the makefile. 3111590Srgrimes */ 3121590Srgrimes (void) Lst_AtEnd (nodes, (ClientData)gn); 3131590Srgrimes if (gn->type & OP_DOUBLEDEP) { 3141590Srgrimes (void)Lst_Concat (nodes, gn->cohorts, LST_CONCNEW); 3151590Srgrimes } 3161590Srgrimes } else if (flags == TARG_NOCREATE) { 3171590Srgrimes Error ("\"%s\" -- target unknown.", name); 3181590Srgrimes } 3191590Srgrimes } 3201590Srgrimes Lst_Close (names); 3211590Srgrimes return (nodes); 3221590Srgrimes} 3231590Srgrimes 3241590Srgrimes/*- 3251590Srgrimes *----------------------------------------------------------------------- 3261590Srgrimes * Targ_Ignore -- 3271590Srgrimes * Return true if should ignore errors when creating gn 3281590Srgrimes * 3291590Srgrimes * Results: 3301590Srgrimes * TRUE if should ignore errors 3311590Srgrimes * 3321590Srgrimes * Side Effects: 3331590Srgrimes * None 3341590Srgrimes *----------------------------------------------------------------------- 3351590Srgrimes */ 3361590SrgrimesBoolean 3371590SrgrimesTarg_Ignore (gn) 3381590Srgrimes GNode *gn; /* node to check for */ 3391590Srgrimes{ 3401590Srgrimes if (ignoreErrors || gn->type & OP_IGNORE) { 3411590Srgrimes return (TRUE); 3421590Srgrimes } else { 3431590Srgrimes return (FALSE); 3441590Srgrimes } 3451590Srgrimes} 3461590Srgrimes 3471590Srgrimes/*- 3481590Srgrimes *----------------------------------------------------------------------- 3491590Srgrimes * Targ_Silent -- 3501590Srgrimes * Return true if be silent when creating gn 3511590Srgrimes * 3521590Srgrimes * Results: 3531590Srgrimes * TRUE if should be silent 3541590Srgrimes * 3551590Srgrimes * Side Effects: 3561590Srgrimes * None 3571590Srgrimes *----------------------------------------------------------------------- 3581590Srgrimes */ 3591590SrgrimesBoolean 3601590SrgrimesTarg_Silent (gn) 3611590Srgrimes GNode *gn; /* node to check for */ 3621590Srgrimes{ 3631590Srgrimes if (beSilent || gn->type & OP_SILENT) { 3641590Srgrimes return (TRUE); 3651590Srgrimes } else { 3661590Srgrimes return (FALSE); 3671590Srgrimes } 3681590Srgrimes} 3691590Srgrimes 3701590Srgrimes/*- 3711590Srgrimes *----------------------------------------------------------------------- 3721590Srgrimes * Targ_Precious -- 3731590Srgrimes * See if the given target is precious 3741590Srgrimes * 3751590Srgrimes * Results: 3761590Srgrimes * TRUE if it is precious. FALSE otherwise 3771590Srgrimes * 3781590Srgrimes * Side Effects: 3791590Srgrimes * None 3801590Srgrimes *----------------------------------------------------------------------- 3811590Srgrimes */ 3821590SrgrimesBoolean 3831590SrgrimesTarg_Precious (gn) 3841590Srgrimes GNode *gn; /* the node to check */ 3851590Srgrimes{ 3861590Srgrimes if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) { 3871590Srgrimes return (TRUE); 3881590Srgrimes } else { 3891590Srgrimes return (FALSE); 3901590Srgrimes } 3911590Srgrimes} 3921590Srgrimes 3931590Srgrimes/******************* DEBUG INFO PRINTING ****************/ 3941590Srgrimes 3951590Srgrimesstatic GNode *mainTarg; /* the main target, as set by Targ_SetMain */ 3968874Srgrimes/*- 3971590Srgrimes *----------------------------------------------------------------------- 3981590Srgrimes * Targ_SetMain -- 3991590Srgrimes * Set our idea of the main target we'll be creating. Used for 4001590Srgrimes * debugging output. 4011590Srgrimes * 4021590Srgrimes * Results: 4031590Srgrimes * None. 4041590Srgrimes * 4051590Srgrimes * Side Effects: 4061590Srgrimes * "mainTarg" is set to the main target's node. 4071590Srgrimes *----------------------------------------------------------------------- 4081590Srgrimes */ 4091590Srgrimesvoid 4101590SrgrimesTarg_SetMain (gn) 4111590Srgrimes GNode *gn; /* The main target we'll create */ 4121590Srgrimes{ 4131590Srgrimes mainTarg = gn; 4141590Srgrimes} 4151590Srgrimes 4161590Srgrimesstatic int 4175814SjkhTargPrintName (gnp, ppath) 4185814Sjkh ClientData gnp; 4195814Sjkh ClientData ppath; 4201590Srgrimes{ 4215814Sjkh GNode *gn = (GNode *) gnp; 4221590Srgrimes printf ("%s ", gn->name); 4231590Srgrimes#ifdef notdef 4241590Srgrimes if (ppath) { 4251590Srgrimes if (gn->path) { 4261590Srgrimes printf ("[%s] ", gn->path); 4271590Srgrimes } 4281590Srgrimes if (gn == mainTarg) { 4291590Srgrimes printf ("(MAIN NAME) "); 4301590Srgrimes } 4311590Srgrimes } 4321590Srgrimes#endif /* notdef */ 4335814Sjkh return (ppath ? 0 : 0); 4341590Srgrimes} 4351590Srgrimes 4361590Srgrimes 4371590Srgrimesint 4385814SjkhTarg_PrintCmd (cmd, dummy) 4395814Sjkh ClientData cmd; 4405814Sjkh ClientData dummy; 4411590Srgrimes{ 4425814Sjkh printf ("\t%s\n", (char *) cmd); 4435814Sjkh return (dummy ? 0 : 0); 4441590Srgrimes} 4451590Srgrimes 4461590Srgrimes/*- 4471590Srgrimes *----------------------------------------------------------------------- 4481590Srgrimes * Targ_FmtTime -- 4491590Srgrimes * Format a modification time in some reasonable way and return it. 4501590Srgrimes * 4511590Srgrimes * Results: 4521590Srgrimes * The time reformatted. 4531590Srgrimes * 4541590Srgrimes * Side Effects: 4551590Srgrimes * The time is placed in a static area, so it is overwritten 4561590Srgrimes * with each call. 4571590Srgrimes * 4581590Srgrimes *----------------------------------------------------------------------- 4591590Srgrimes */ 4601590Srgrimeschar * 4611590SrgrimesTarg_FmtTime (time) 4621590Srgrimes time_t time; 4631590Srgrimes{ 4641590Srgrimes struct tm *parts; 46549938Shoek static char buf[128]; 4661590Srgrimes 4671590Srgrimes parts = localtime(&time); 4681590Srgrimes 46949938Shoek strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts); 47049938Shoek buf[sizeof(buf) - 1] = '\0'; 4711590Srgrimes return(buf); 4721590Srgrimes} 4738874Srgrimes 4741590Srgrimes/*- 4751590Srgrimes *----------------------------------------------------------------------- 4761590Srgrimes * Targ_PrintType -- 4771590Srgrimes * Print out a type field giving only those attributes the user can 4781590Srgrimes * set. 4791590Srgrimes * 4801590Srgrimes * Results: 4811590Srgrimes * 4821590Srgrimes * Side Effects: 4831590Srgrimes * 4841590Srgrimes *----------------------------------------------------------------------- 4851590Srgrimes */ 4861590Srgrimesvoid 4871590SrgrimesTarg_PrintType (type) 4881590Srgrimes register int type; 4891590Srgrimes{ 4901590Srgrimes register int tbit; 4918874Srgrimes 4921590Srgrimes#ifdef __STDC__ 4931590Srgrimes#define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break 4941590Srgrimes#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break 4951590Srgrimes#else 4961590Srgrimes#define PRINTBIT(attr) case CONCAT(OP_,attr): printf(".attr "); break 4971590Srgrimes#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf(".attr "); break 4981590Srgrimes#endif /* __STDC__ */ 4991590Srgrimes 5001590Srgrimes type &= ~OP_OPMASK; 5011590Srgrimes 5021590Srgrimes while (type) { 5031590Srgrimes tbit = 1 << (ffs(type) - 1); 5041590Srgrimes type &= ~tbit; 5051590Srgrimes 5061590Srgrimes switch(tbit) { 5071590Srgrimes PRINTBIT(OPTIONAL); 5081590Srgrimes PRINTBIT(USE); 5091590Srgrimes PRINTBIT(EXEC); 5101590Srgrimes PRINTBIT(IGNORE); 5111590Srgrimes PRINTBIT(PRECIOUS); 5121590Srgrimes PRINTBIT(SILENT); 5131590Srgrimes PRINTBIT(MAKE); 5141590Srgrimes PRINTBIT(JOIN); 5151590Srgrimes PRINTBIT(INVISIBLE); 5161590Srgrimes PRINTBIT(NOTMAIN); 5171590Srgrimes PRINTDBIT(LIB); 5181590Srgrimes /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */ 5191590Srgrimes case OP_MEMBER: if (DEBUG(TARG)) printf(".MEMBER "); break; 5201590Srgrimes PRINTDBIT(ARCHV); 5211590Srgrimes } 5221590Srgrimes } 5231590Srgrimes} 5241590Srgrimes 5251590Srgrimes/*- 5261590Srgrimes *----------------------------------------------------------------------- 5271590Srgrimes * TargPrintNode -- 5281590Srgrimes * print the contents of a node 5291590Srgrimes *----------------------------------------------------------------------- 5301590Srgrimes */ 5311590Srgrimesstatic int 5325814SjkhTargPrintNode (gnp, passp) 5335814Sjkh ClientData gnp; 5345814Sjkh ClientData passp; 5351590Srgrimes{ 5365814Sjkh GNode *gn = (GNode *) gnp; 5375814Sjkh int pass = *(int *) passp; 5381590Srgrimes if (!OP_NOP(gn->type)) { 5391590Srgrimes printf("#\n"); 5401590Srgrimes if (gn == mainTarg) { 5411590Srgrimes printf("# *** MAIN TARGET ***\n"); 5421590Srgrimes } 5431590Srgrimes if (pass == 2) { 5441590Srgrimes if (gn->unmade) { 5451590Srgrimes printf("# %d unmade children\n", gn->unmade); 5461590Srgrimes } else { 5471590Srgrimes printf("# No unmade children\n"); 5481590Srgrimes } 5491590Srgrimes if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) { 5501590Srgrimes if (gn->mtime != 0) { 5511590Srgrimes printf("# last modified %s: %s\n", 5521590Srgrimes Targ_FmtTime(gn->mtime), 5531590Srgrimes (gn->made == UNMADE ? "unmade" : 5541590Srgrimes (gn->made == MADE ? "made" : 5551590Srgrimes (gn->made == UPTODATE ? "up-to-date" : 5561590Srgrimes "error when made")))); 5571590Srgrimes } else if (gn->made != UNMADE) { 5581590Srgrimes printf("# non-existent (maybe): %s\n", 5591590Srgrimes (gn->made == MADE ? "made" : 5601590Srgrimes (gn->made == UPTODATE ? "up-to-date" : 5611590Srgrimes (gn->made == ERROR ? "error when made" : 5621590Srgrimes "aborted")))); 5631590Srgrimes } else { 5641590Srgrimes printf("# unmade\n"); 5651590Srgrimes } 5661590Srgrimes } 5671590Srgrimes if (!Lst_IsEmpty (gn->iParents)) { 5681590Srgrimes printf("# implicit parents: "); 5691590Srgrimes Lst_ForEach (gn->iParents, TargPrintName, (ClientData)0); 5701590Srgrimes fputc ('\n', stdout); 5711590Srgrimes } 5721590Srgrimes } 5731590Srgrimes if (!Lst_IsEmpty (gn->parents)) { 5741590Srgrimes printf("# parents: "); 5751590Srgrimes Lst_ForEach (gn->parents, TargPrintName, (ClientData)0); 5761590Srgrimes fputc ('\n', stdout); 5771590Srgrimes } 5788874Srgrimes 5791590Srgrimes printf("%-16s", gn->name); 5801590Srgrimes switch (gn->type & OP_OPMASK) { 5811590Srgrimes case OP_DEPENDS: 5821590Srgrimes printf(": "); break; 5831590Srgrimes case OP_FORCE: 5841590Srgrimes printf("! "); break; 5851590Srgrimes case OP_DOUBLEDEP: 5861590Srgrimes printf(":: "); break; 5871590Srgrimes } 5881590Srgrimes Targ_PrintType (gn->type); 5891590Srgrimes Lst_ForEach (gn->children, TargPrintName, (ClientData)0); 5901590Srgrimes fputc ('\n', stdout); 5911590Srgrimes Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0); 5921590Srgrimes printf("\n\n"); 5931590Srgrimes if (gn->type & OP_DOUBLEDEP) { 5945814Sjkh Lst_ForEach (gn->cohorts, TargPrintNode, (ClientData)&pass); 5951590Srgrimes } 5961590Srgrimes } 5971590Srgrimes return (0); 5981590Srgrimes} 5991590Srgrimes 6001590Srgrimes/*- 6011590Srgrimes *----------------------------------------------------------------------- 6021590Srgrimes * TargPrintOnlySrc -- 6031590Srgrimes * Print only those targets that are just a source. 6041590Srgrimes * 6051590Srgrimes * Results: 6061590Srgrimes * 0. 6071590Srgrimes * 6081590Srgrimes * Side Effects: 6091590Srgrimes * The name of each file is printed preceeded by #\t 6101590Srgrimes * 6111590Srgrimes *----------------------------------------------------------------------- 6121590Srgrimes */ 6131590Srgrimesstatic int 6145814SjkhTargPrintOnlySrc(gnp, dummy) 6155814Sjkh ClientData gnp; 6165814Sjkh ClientData dummy; 6171590Srgrimes{ 6185814Sjkh GNode *gn = (GNode *) gnp; 6195814Sjkh if (OP_NOP(gn->type)) 6205814Sjkh printf("#\t%s [%s]\n", gn->name, gn->path ? gn->path : gn->name); 6215814Sjkh 6225814Sjkh return (dummy ? 0 : 0); 6231590Srgrimes} 6241590Srgrimes 6251590Srgrimes/*- 6261590Srgrimes *----------------------------------------------------------------------- 6271590Srgrimes * Targ_PrintGraph -- 6281590Srgrimes * print the entire graph. heh heh 6291590Srgrimes * 6301590Srgrimes * Results: 6311590Srgrimes * none 6321590Srgrimes * 6331590Srgrimes * Side Effects: 6341590Srgrimes * lots o' output 6351590Srgrimes *----------------------------------------------------------------------- 6361590Srgrimes */ 6371590Srgrimesvoid 6381590SrgrimesTarg_PrintGraph (pass) 6391590Srgrimes int pass; /* Which pass this is. 1 => no processing 6401590Srgrimes * 2 => processing done */ 6411590Srgrimes{ 6421590Srgrimes printf("#*** Input graph:\n"); 6435814Sjkh Lst_ForEach (allTargets, TargPrintNode, (ClientData)&pass); 6441590Srgrimes printf("\n\n"); 6451590Srgrimes printf("#\n# Files that are only sources:\n"); 6465814Sjkh Lst_ForEach (allTargets, TargPrintOnlySrc, (ClientData) 0); 6471590Srgrimes printf("#*** Global Variables:\n"); 6481590Srgrimes Var_Dump (VAR_GLOBAL); 6491590Srgrimes printf("#*** Command-line Variables:\n"); 6501590Srgrimes Var_Dump (VAR_CMD); 6511590Srgrimes printf("\n"); 6521590Srgrimes Dir_PrintDirectories(); 6531590Srgrimes printf("\n"); 6541590Srgrimes Suff_PrintAll(); 6551590Srgrimes} 656