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