[BACK]Return to targ.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / make

Annotation of src/usr.bin/make/targ.c, Revision 1.151

1.151   ! rillig      1: /*     $NetBSD: targ.c,v 1.150 2020/12/05 15:35:34 rillig Exp $        */
1.5       christos    2:
1.1       cgd         3: /*
1.10      christos    4:  * Copyright (c) 1988, 1989, 1990, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.30      agc         6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Adam de Boor.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
1.1       cgd        36:  * Copyright (c) 1989 by Berkeley Softworks
                     37:  * All rights reserved.
                     38:  *
                     39:  * This code is derived from software contributed to Berkeley by
                     40:  * Adam de Boor.
                     41:  *
                     42:  * Redistribution and use in source and binary forms, with or without
                     43:  * modification, are permitted provided that the following conditions
                     44:  * are met:
                     45:  * 1. Redistributions of source code must retain the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer.
                     47:  * 2. Redistributions in binary form must reproduce the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer in the
                     49:  *    documentation and/or other materials provided with the distribution.
                     50:  * 3. All advertising materials mentioning features or use of this software
                     51:  *    must display the following acknowledgement:
                     52:  *     This product includes software developed by the University of
                     53:  *     California, Berkeley and its contributors.
                     54:  * 4. Neither the name of the University nor the names of its contributors
                     55:  *    may be used to endorse or promote products derived from this software
                     56:  *    without specific prior written permission.
                     57:  *
                     58:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     59:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     60:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     61:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     62:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     63:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     64:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     65:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     66:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     67:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     68:  * SUCH DAMAGE.
                     69:  */
                     70:
1.132     rillig     71: /*
                     72:  * Maintaining the targets and sources, which are both implemented as GNode.
1.1       cgd        73:  *
                     74:  * Interface:
1.132     rillig     75:  *     Targ_Init       Initialize the module.
1.1       cgd        76:  *
1.132     rillig     77:  *     Targ_End        Clean up the module.
1.4       jtc        78:  *
1.106     rillig     79:  *     Targ_List       Return the list of all targets so far.
1.12      christos   80:  *
1.128     rillig     81:  *     GNode_New       Create a new GNode for the passed target
1.106     rillig     82:  *                     (string). The node is *not* placed in the
                     83:  *                     hash table, though all its fields are
                     84:  *                     initialized.
1.1       cgd        85:  *
1.106     rillig     86:  *     Targ_FindNode   Find the node, or return NULL.
1.98      rillig     87:  *
1.106     rillig     88:  *     Targ_GetNode    Find the node, or create it.
1.98      rillig     89:  *
1.106     rillig     90:  *     Targ_NewInternalNode
                     91:  *                     Create an internal node.
1.1       cgd        92:  *
1.106     rillig     93:  *     Targ_FindList   Given a list of names, find nodes for all
                     94:  *                     of them, creating them as necessary.
1.1       cgd        95:  *
1.106     rillig     96:  *     Targ_Ignore     Return TRUE if errors should be ignored when
                     97:  *                     creating the given target.
1.1       cgd        98:  *
1.106     rillig     99:  *     Targ_Silent     Return TRUE if we should be silent when
                    100:  *                     creating the given target.
1.1       cgd       101:  *
1.106     rillig    102:  *     Targ_Precious   Return TRUE if the target is precious and
                    103:  *                     should not be removed if we are interrupted.
1.1       cgd       104:  *
1.106     rillig    105:  *     Targ_Propagate  Propagate information between related nodes.
                    106:  *                     Should be called after the makefiles are parsed
                    107:  *                     but before any action is taken.
1.42      apb       108:  *
1.1       cgd       109:  * Debugging:
1.106     rillig    110:  *     Targ_PrintGraph
1.148     rillig    111:  *                     Print out the entire graph, all variables and
1.106     rillig    112:  *                     statistics for the directory cache. Should print
                    113:  *                     something for suffixes, too, but...
1.1       cgd       114:  */
                    115:
1.111     rillig    116: #include <time.h>
1.28      wiz       117:
1.111     rillig    118: #include "make.h"
                    119: #include "dir.h"
1.1       cgd       120:
1.88      rillig    121: /*     "@(#)targ.c     8.2 (Berkeley) 3/19/94" */
1.151   ! rillig    122: MAKE_RCSID("$NetBSD: targ.c,v 1.150 2020/12/05 15:35:34 rillig Exp $");
1.88      rillig    123:
1.136     rillig    124: /*
                    125:  * All target nodes that appeared on the left-hand side of one of the
                    126:  * dependency operators ':', '::', '!'.
                    127:  */
1.148     rillig    128: static GNodeList allTargets = LST_INIT;
1.133     rillig    129: static HashTable allTargetsByName;
1.130     rillig    130:
1.18      mycroft   131: #ifdef CLEANUP
1.148     rillig    132: static GNodeList allNodes = LST_INIT;
1.1       cgd       133:
1.129     rillig    134: static void GNode_Free(void *);
1.18      mycroft   135: #endif
1.4       jtc       136:
1.1       cgd       137: void
1.28      wiz       138: Targ_Init(void)
1.1       cgd       139: {
1.150     rillig    140:        HashTable_Init(&allTargetsByName);
1.1       cgd       141: }
                    142:
1.4       jtc       143: void
1.28      wiz       144: Targ_End(void)
1.4       jtc       145: {
1.150     rillig    146:        Targ_Stats();
1.18      mycroft   147: #ifdef CLEANUP
1.150     rillig    148:        Lst_Done(&allTargets);
                    149:        HashTable_Done(&allTargetsByName);
                    150:        Lst_DoneCall(&allNodes, GNode_Free);
1.18      mycroft   151: #endif
1.12      christos  152: }
                    153:
1.64      sjg       154: void
                    155: Targ_Stats(void)
                    156: {
1.150     rillig    157:        HashTable_DebugStats(&allTargetsByName, "targets");
1.64      sjg       158: }
                    159:
1.132     rillig    160: /*
                    161:  * Return the list of all targets, which are all nodes that appear on the
                    162:  * left-hand side of a dependency declaration such as "target: source".
                    163:  * The returned list does not contain pure sources.
                    164:  */
1.89      rillig    165: GNodeList *
1.28      wiz       166: Targ_List(void)
1.12      christos  167: {
1.150     rillig    168:        return &allTargets;
1.4       jtc       169: }
                    170:
1.150     rillig    171: /*
                    172:  * Create a new graph node, but don't register it anywhere.
1.1       cgd       173:  *
1.132     rillig    174:  * Graph nodes that appear on the left-hand side of a dependency line such
                    175:  * as "target: source" are called targets.  XXX: In some cases (like the
                    176:  * .ALLTARGETS variable), all nodes are called targets as well, even if they
                    177:  * never appear on the left-hand side.  This is a mistake.
                    178:  *
                    179:  * Typical names for graph nodes are:
                    180:  *     "src.c" (an ordinary file)
                    181:  *     "clean" (a .PHONY target)
                    182:  *     ".END" (a special hook target)
                    183:  *     "-lm" (a library)
                    184:  *     "libc.a(isspace.o)" (an archive member)
1.1       cgd       185:  */
                    186: GNode *
1.128     rillig    187: GNode_New(const char *name)
1.1       cgd       188: {
1.150     rillig    189:        GNode *gn;
1.1       cgd       190:
1.150     rillig    191:        gn = bmake_malloc(sizeof *gn);
                    192:        gn->name = bmake_strdup(name);
                    193:        gn->uname = NULL;
                    194:        gn->path = NULL;
                    195:        gn->type = name[0] == '-' && name[1] == 'l' ? OP_LIB : 0;
                    196:        gn->flags = 0;
                    197:        gn->made = UNMADE;
                    198:        gn->unmade = 0;
                    199:        gn->mtime = 0;
                    200:        gn->youngestChild = NULL;
                    201:        Lst_Init(&gn->implicitParents);
                    202:        Lst_Init(&gn->parents);
                    203:        Lst_Init(&gn->children);
                    204:        Lst_Init(&gn->order_pred);
                    205:        Lst_Init(&gn->order_succ);
                    206:        Lst_Init(&gn->cohorts);
                    207:        gn->cohort_num[0] = '\0';
                    208:        gn->unmade_cohorts = 0;
                    209:        gn->centurion = NULL;
                    210:        gn->checked_seqno = 0;
                    211:        HashTable_Init(&gn->vars);
                    212:        Lst_Init(&gn->commands);
                    213:        gn->suffix = NULL;
                    214:        gn->fname = NULL;
                    215:        gn->lineno = 0;
1.1       cgd       216:
1.18      mycroft   217: #ifdef CLEANUP
1.150     rillig    218:        Lst_Append(&allNodes, gn);
1.18      mycroft   219: #endif
1.4       jtc       220:
1.150     rillig    221:        return gn;
1.1       cgd       222: }
                    223:
1.18      mycroft   224: #ifdef CLEANUP
1.4       jtc       225: static void
1.129     rillig    226: GNode_Free(void *gnp)
1.4       jtc       227: {
1.150     rillig    228:        GNode *gn = gnp;
1.4       jtc       229:
1.150     rillig    230:        free(gn->name);
                    231:        free(gn->uname);
                    232:        free(gn->path);
                    233:
                    234:        /* Don't free gn->youngestChild since it is not owned by this node. */
                    235:
                    236:        /*
                    237:         * In the following lists, only free the list nodes, but not the
                    238:         * GNodes in them since these are not owned by this node.
                    239:         */
                    240:        Lst_Done(&gn->implicitParents);
                    241:        Lst_Done(&gn->parents);
                    242:        Lst_Done(&gn->children);
                    243:        Lst_Done(&gn->order_pred);
                    244:        Lst_Done(&gn->order_succ);
                    245:        Lst_Done(&gn->cohorts);
                    246:
                    247:        /*
                    248:         * Do not free the variables themselves, even though they are owned
                    249:         * by this node.
                    250:         *
                    251:         * XXX: For the nodes that represent targets or sources (and not
                    252:         * VAR_GLOBAL), it should be safe to free the variables as well,
                    253:         * since each node manages the memory for all its variables itself.
                    254:         *
                    255:         * XXX: The GNodes that are only used as variable contexts (VAR_CMD,
                    256:         * VAR_GLOBAL, VAR_INTERNAL) are not freed at all (see Var_End, where
                    257:         * they are not mentioned).  These might be freed at all, if their
                    258:         * variable values are indeed not used anywhere else (see Trace_Init
                    259:         * for the only suspicious use).
                    260:         */
                    261:        HashTable_Done(&gn->vars);
                    262:
                    263:        /*
                    264:         * Do not free the commands themselves, as they may be shared with
                    265:         * other nodes.
                    266:         */
                    267:        Lst_Done(&gn->commands);
                    268:
                    269:        /*
                    270:         * gn->suffix is not owned by this node.
                    271:         *
                    272:         * XXX: gn->suffix should be unreferenced here.  This requires a
                    273:         * thorough check that the reference counting is done correctly in
                    274:         * all places, otherwise a suffix might be freed too early.
                    275:         */
1.77      rillig    276:
1.150     rillig    277:        free(gn);
1.4       jtc       278: }
1.18      mycroft   279: #endif
1.4       jtc       280:
1.95      rillig    281: /* Get the existing global node, or return NULL. */
                    282: GNode *
                    283: Targ_FindNode(const char *name)
                    284: {
1.150     rillig    285:        return HashTable_FindValue(&allTargetsByName, name);
1.95      rillig    286: }
                    287:
                    288: /* Get the existing global node, or create it. */
                    289: GNode *
                    290: Targ_GetNode(const char *name)
                    291: {
1.150     rillig    292:        Boolean isNew;
                    293:        HashEntry *he = HashTable_CreateEntry(&allTargetsByName, name, &isNew);
                    294:        if (!isNew)
                    295:                return HashEntry_Get(he);
                    296:
                    297:        {
                    298:                GNode *gn = Targ_NewInternalNode(name);
                    299:                HashEntry_Set(he, gn);
                    300:                return gn;
                    301:        }
1.95      rillig    302: }
                    303:
1.132     rillig    304: /*
                    305:  * Create a node, register it in .ALLTARGETS but don't store it in the
1.95      rillig    306:  * table of global nodes.  This means it cannot be found by name.
                    307:  *
1.132     rillig    308:  * This is used for internal nodes, such as cohorts or .WAIT nodes.
                    309:  */
1.95      rillig    310: GNode *
                    311: Targ_NewInternalNode(const char *name)
                    312: {
1.150     rillig    313:        GNode *gn = GNode_New(name);
                    314:        Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
                    315:        Lst_Append(&allTargets, gn);
                    316:        DEBUG1(TARG, "Adding \"%s\" to all targets.\n", gn->name);
                    317:        if (doing_depend)
                    318:                gn->flags |= FROM_DEPEND;
                    319:        return gn;
1.95      rillig    320: }
                    321:
1.132     rillig    322: /*
                    323:  * Return the .END node, which contains the commands to be run when
                    324:  * everything else has been made.
                    325:  */
1.90      rillig    326: GNode *Targ_GetEndNode(void)
                    327: {
1.150     rillig    328:        /*
                    329:         * Save the node locally to avoid having to search for it all
                    330:         * the time.
                    331:         */
                    332:        static GNode *endNode = NULL;
                    333:
                    334:        if (endNode == NULL) {
                    335:                endNode = Targ_GetNode(".END");
                    336:                endNode->type = OP_SPECIAL;
                    337:        }
                    338:        return endNode;
1.90      rillig    339: }
                    340:
1.149     rillig    341: /* Add the named nodes to the list, creating them as necessary. */
1.147     rillig    342: void
1.149     rillig    343: Targ_FindList(GNodeList *gns, StringList *names)
1.1       cgd       344: {
1.150     rillig    345:        StringListNode *ln;
1.149     rillig    346:
1.150     rillig    347:        for (ln = names->first; ln != NULL; ln = ln->next) {
                    348:                const char *name = ln->datum;
                    349:                GNode *gn = Targ_GetNode(name);
                    350:                Lst_Append(gns, gn);
                    351:        }
1.1       cgd       352: }
                    353:
1.149     rillig    354: /*
                    355:  * Return true if errors from shell commands should be ignored when
                    356:  * creating gn.
                    357:  */
1.1       cgd       358: Boolean
1.131     rillig    359: Targ_Ignore(const GNode *gn)
1.1       cgd       360: {
1.150     rillig    361:        return opts.ignoreErrors || gn->type & OP_IGNORE;
1.1       cgd       362: }
                    363:
1.77      rillig    364: /* Return true if be silent when creating gn. */
1.1       cgd       365: Boolean
1.131     rillig    366: Targ_Silent(const GNode *gn)
1.1       cgd       367: {
1.150     rillig    368:        return opts.beSilent || gn->type & OP_SILENT;
1.1       cgd       369: }
                    370:
1.77      rillig    371: /* See if the given target is precious. */
1.1       cgd       372: Boolean
1.131     rillig    373: Targ_Precious(const GNode *gn)
1.1       cgd       374: {
1.150     rillig    375:        /* XXX: Why are '::' targets precious? */
                    376:        return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP);
1.1       cgd       377: }
                    378:
1.132     rillig    379: /*
                    380:  * The main target to be made; only for debugging output.
                    381:  * See mainNode in parse.c for the definitive source.
                    382:  */
                    383: static GNode *mainTarg;
1.77      rillig    384:
1.132     rillig    385: /* Remember the main target to make; only used for debugging. */
1.1       cgd       386: void
1.28      wiz       387: Targ_SetMain(GNode *gn)
1.1       cgd       388: {
1.150     rillig    389:        mainTarg = gn;
1.1       cgd       390: }
                    391:
1.86      rillig    392: static void
1.89      rillig    393: PrintNodeNames(GNodeList *gnodes)
1.1       cgd       394: {
1.150     rillig    395:        GNodeListNode *ln;
1.38      dsl       396:
1.150     rillig    397:        for (ln = gnodes->first; ln != NULL; ln = ln->next) {
                    398:                GNode *gn = ln->datum;
                    399:                debug_printf(" %s%s", gn->name, gn->cohort_num);
                    400:        }
1.85      rillig    401: }
1.38      dsl       402:
1.85      rillig    403: static void
1.89      rillig    404: PrintNodeNamesLine(const char *label, GNodeList *gnodes)
1.85      rillig    405: {
1.150     rillig    406:        if (Lst_IsEmpty(gnodes))
                    407:                return;
                    408:        debug_printf("# %s:", label);
                    409:        PrintNodeNames(gnodes);
                    410:        debug_printf("\n");
1.1       cgd       411: }
                    412:
1.84      rillig    413: void
                    414: Targ_PrintCmds(GNode *gn)
                    415: {
1.150     rillig    416:        StringListNode *ln;
                    417:
                    418:        for (ln = gn->commands.first; ln != NULL; ln = ln->next) {
                    419:                const char *cmd = ln->datum;
                    420:                debug_printf("\t%s\n", cmd);
                    421:        }
1.84      rillig    422: }
                    423:
1.150     rillig    424: /*
                    425:  * Format a modification time in some reasonable way and return it.
                    426:  * The time is placed in a static area, so it is overwritten with each call.
                    427:  */
1.1       cgd       428: char *
1.28      wiz       429: Targ_FmtTime(time_t tm)
1.1       cgd       430: {
1.150     rillig    431:        struct tm *parts;
                    432:        static char buf[128];
1.1       cgd       433:
1.150     rillig    434:        /* TODO: Add special case for 0, which often means ENOENT, to make it
                    435:         * independent from time zones. */
                    436:        parts = localtime(&tm);
                    437:        (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
                    438:        return buf;
1.1       cgd       439: }
1.10      christos  440:
1.77      rillig    441: /* Print out a type field giving only those attributes the user can set. */
1.1       cgd       442: void
1.52      christos  443: Targ_PrintType(int type)
1.1       cgd       444: {
1.150     rillig    445:        int tbit;
1.10      christos  446:
1.150     rillig    447:        type &= ~OP_OPMASK;
1.1       cgd       448:
1.150     rillig    449:        while (type != 0) {
                    450:                tbit = 1 << (ffs(type) - 1);
                    451:                type &= ~tbit;
                    452:
                    453:                switch (tbit) {
1.151   ! rillig    454: #define PRINTBIT(bit, name) case bit: debug_printf(" " name); break
        !           455: #define PRINTDBIT(bit, attr) case bit: if (DEBUG(TARG)) debug_printf(" " attr); break
        !           456:                PRINTBIT(OP_OPTIONAL, ".OPTIONAL");
        !           457:                PRINTBIT(OP_USE, ".USE");
        !           458:                PRINTBIT(OP_EXEC, ".EXEC");
        !           459:                PRINTBIT(OP_IGNORE, ".IGNORE");
        !           460:                PRINTBIT(OP_PRECIOUS, ".PRECIOUS");
        !           461:                PRINTBIT(OP_SILENT, ".SILENT");
        !           462:                PRINTBIT(OP_MAKE, ".MAKE");
        !           463:                PRINTBIT(OP_JOIN, ".JOIN");
        !           464:                PRINTBIT(OP_INVISIBLE, ".INVISIBLE");
        !           465:                PRINTBIT(OP_NOTMAIN, ".NOTMAIN");
        !           466:                PRINTDBIT(OP_LIB, ".LIB");
        !           467:                PRINTDBIT(OP_MEMBER, ".MEMBER");
        !           468:                PRINTDBIT(OP_ARCHV, ".ARCHV");
        !           469:                PRINTDBIT(OP_MADE, ".MADE");
        !           470:                PRINTDBIT(OP_PHONY, ".PHONY");
        !           471: #undef PRINTBIT
        !           472: #undef PRINTDBIT
1.150     rillig    473:                }
1.1       cgd       474:        }
                    475: }
                    476:
1.45      dsl       477: static const char *
1.71      rillig    478: made_name(GNodeMade made)
1.45      dsl       479: {
1.150     rillig    480:        switch (made) {
                    481:        case UNMADE:    return "unmade";
                    482:        case DEFERRED:  return "deferred";
                    483:        case REQUESTED: return "requested";
                    484:        case BEINGMADE: return "being made";
                    485:        case MADE:      return "made";
                    486:        case UPTODATE:  return "up-to-date";
                    487:        case ERROR:     return "error when made";
                    488:        case ABORTED:   return "aborted";
                    489:        default:        return "unknown enum_made value";
                    490:        }
1.45      dsl       491: }
                    492:
1.114     rillig    493: static const char *
                    494: GNode_OpName(const GNode *gn)
                    495: {
1.150     rillig    496:        switch (gn->type & OP_OPMASK) {
                    497:        case OP_DEPENDS:
                    498:                return ":";
                    499:        case OP_FORCE:
                    500:                return "!";
                    501:        case OP_DOUBLEDEP:
                    502:                return "::";
                    503:        }
                    504:        return "";
1.114     rillig    505: }
                    506:
1.105     rillig    507: /* Print the contents of a node. */
                    508: void
                    509: Targ_PrintNode(GNode *gn, int pass)
1.1       cgd       510: {
1.150     rillig    511:        debug_printf("# %s%s", gn->name, gn->cohort_num);
                    512:        GNode_FprintDetails(opts.debug_file, ", ", gn, "\n");
                    513:        if (gn->flags == 0)
                    514:                return;
                    515:
                    516:        if (!GNode_IsTarget(gn))
                    517:                return;
1.45      dsl       518:
1.107     rillig    519:        debug_printf("#\n");
1.150     rillig    520:        if (gn == mainTarg)
                    521:                debug_printf("# *** MAIN TARGET ***\n");
                    522:
1.45      dsl       523:        if (pass >= 2) {
1.150     rillig    524:                if (gn->unmade > 0)
                    525:                        debug_printf("# %d unmade children\n", gn->unmade);
                    526:                else
                    527:                        debug_printf("# No unmade children\n");
                    528:                if (!(gn->type & (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC))) {
                    529:                        if (gn->mtime != 0) {
                    530:                                debug_printf("# last modified %s: %s\n",
                    531:                                    Targ_FmtTime(gn->mtime),
                    532:                                    made_name(gn->made));
                    533:                        } else if (gn->made != UNMADE) {
                    534:                                debug_printf("# non-existent (maybe): %s\n",
                    535:                                    made_name(gn->made));
                    536:                        } else
                    537:                                debug_printf("# unmade\n");
1.1       cgd       538:                }
1.150     rillig    539:                PrintNodeNamesLine("implicit parents", &gn->implicitParents);
1.41      dsl       540:        } else {
1.150     rillig    541:                if (gn->unmade)
                    542:                        debug_printf("# %d unmade children\n", gn->unmade);
1.1       cgd       543:        }
1.150     rillig    544:
1.143     rillig    545:        PrintNodeNamesLine("parents", &gn->parents);
1.144     rillig    546:        PrintNodeNamesLine("order_pred", &gn->order_pred);
                    547:        PrintNodeNamesLine("order_succ", &gn->order_succ);
1.10      christos  548:
1.114     rillig    549:        debug_printf("%-16s%s", gn->name, GNode_OpName(gn));
1.34      christos  550:        Targ_PrintType(gn->type);
1.143     rillig    551:        PrintNodeNames(&gn->children);
1.107     rillig    552:        debug_printf("\n");
1.84      rillig    553:        Targ_PrintCmds(gn);
1.107     rillig    554:        debug_printf("\n\n");
1.150     rillig    555:        if (gn->type & OP_DOUBLEDEP)
                    556:                Targ_PrintNodes(&gn->cohorts, pass);
1.1       cgd       557: }
                    558:
1.87      rillig    559: void
1.89      rillig    560: Targ_PrintNodes(GNodeList *gnodes, int pass)
1.87      rillig    561: {
1.150     rillig    562:        GNodeListNode *ln;
                    563:
                    564:        for (ln = gnodes->first; ln != NULL; ln = ln->next)
                    565:                Targ_PrintNode(ln->datum, pass);
1.87      rillig    566: }
                    567:
1.100     rillig    568: /* Print only those targets that are just a source. */
1.103     mrg       569: static void
1.100     rillig    570: PrintOnlySources(void)
1.4       jtc       571: {
1.150     rillig    572:        GNodeListNode *ln;
1.100     rillig    573:
1.150     rillig    574:        for (ln = allTargets.first; ln != NULL; ln = ln->next) {
                    575:                GNode *gn = ln->datum;
                    576:                if (GNode_IsTarget(gn))
                    577:                        continue;
                    578:
                    579:                debug_printf("#\t%s [%s]", gn->name, GNode_Path(gn));
                    580:                Targ_PrintType(gn->type);
                    581:                debug_printf("\n");
                    582:        }
1.1       cgd       583: }
                    584:
1.150     rillig    585: /*
                    586:  * Input:
1.77      rillig    587:  *     pass            1 => before processing
                    588:  *                     2 => after processing
                    589:  *                     3 => after processing, an error occurred
1.1       cgd       590:  */
1.3       cgd       591: void
1.28      wiz       592: Targ_PrintGraph(int pass)
1.1       cgd       593: {
1.150     rillig    594:        debug_printf("#*** Input graph:\n");
                    595:        Targ_PrintNodes(&allTargets, pass);
                    596:        debug_printf("\n");
                    597:        debug_printf("\n");
1.135     rillig    598:
1.150     rillig    599:        debug_printf("#\n");
                    600:        debug_printf("#   Files that are only sources:\n");
                    601:        PrintOnlySources();
1.135     rillig    602:
1.150     rillig    603:        debug_printf("#*** Global Variables:\n");
                    604:        Var_Dump(VAR_GLOBAL);
1.135     rillig    605:
1.150     rillig    606:        debug_printf("#*** Command-line Variables:\n");
                    607:        Var_Dump(VAR_CMDLINE);
1.135     rillig    608:
1.150     rillig    609:        debug_printf("\n");
                    610:        Dir_PrintDirectories();
                    611:        debug_printf("\n");
1.135     rillig    612:
1.150     rillig    613:        Suff_PrintAll();
1.19      mycroft   614: }
                    615:
1.150     rillig    616: /*
                    617:  * Propagate some type information to cohort nodes (those from the '::'
1.78      rillig    618:  * dependency operator).
1.77      rillig    619:  *
1.78      rillig    620:  * Should be called after the makefiles are parsed but before any action is
1.150     rillig    621:  * taken.
                    622:  */
1.78      rillig    623: void
                    624: Targ_Propagate(void)
1.19      mycroft   625: {
1.150     rillig    626:        GNodeListNode *ln, *cln;
1.45      dsl       627:
1.150     rillig    628:        for (ln = allTargets.first; ln != NULL; ln = ln->next) {
                    629:                GNode *gn = ln->datum;
                    630:                GNodeType type = gn->type;
1.19      mycroft   631:
1.150     rillig    632:                if (!(type & OP_DOUBLEDEP))
                    633:                        continue;
1.42      apb       634:
1.150     rillig    635:                for (cln = gn->cohorts.first; cln != NULL; cln = cln->next) {
                    636:                        GNode *cohort = cln->datum;
1.42      apb       637:
1.150     rillig    638:                        cohort->type |= type & ~OP_OPMASK;
                    639:                }
1.78      rillig    640:        }
1.1       cgd       641: }

CVSweb <webmaster@jp.NetBSD.org>