[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.113

1.113   ! rillig      1: /*     $NetBSD: targ.c,v 1.112 2020/10/05 22:15:45 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:
                     71: /*-
                     72:  * targ.c --
                     73:  *     Functions for maintaining the Lst allTargets. Target nodes are
1.77      rillig     74:  *     kept in two structures: a Lst and a hash table.
1.1       cgd        75:  *
                     76:  * Interface:
1.106     rillig     77:  *     Targ_Init       Initialization procedure.
1.1       cgd        78:  *
1.113   ! rillig     79:  *     Targ_End        Clean up the module
1.4       jtc        80:  *
1.106     rillig     81:  *     Targ_List       Return the list of all targets so far.
1.12      christos   82:  *
1.106     rillig     83:  *     Targ_NewGN      Create a new GNode for the passed target
                     84:  *                     (string). The node is *not* placed in the
                     85:  *                     hash table, though all its fields are
                     86:  *                     initialized.
1.1       cgd        87:  *
1.106     rillig     88:  *     Targ_FindNode   Find the node, or return NULL.
1.98      rillig     89:  *
1.106     rillig     90:  *     Targ_GetNode    Find the node, or create it.
1.98      rillig     91:  *
1.106     rillig     92:  *     Targ_NewInternalNode
                     93:  *                     Create an internal node.
1.1       cgd        94:  *
1.106     rillig     95:  *     Targ_FindList   Given a list of names, find nodes for all
                     96:  *                     of them, creating them as necessary.
1.1       cgd        97:  *
1.106     rillig     98:  *     Targ_Ignore     Return TRUE if errors should be ignored when
                     99:  *                     creating the given target.
1.1       cgd       100:  *
1.106     rillig    101:  *     Targ_Silent     Return TRUE if we should be silent when
                    102:  *                     creating the given target.
1.1       cgd       103:  *
1.106     rillig    104:  *     Targ_Precious   Return TRUE if the target is precious and
                    105:  *                     should not be removed if we are interrupted.
1.1       cgd       106:  *
1.106     rillig    107:  *     Targ_Propagate  Propagate information between related nodes.
                    108:  *                     Should be called after the makefiles are parsed
                    109:  *                     but before any action is taken.
1.42      apb       110:  *
1.1       cgd       111:  * Debugging:
1.106     rillig    112:  *     Targ_PrintGraph
                    113:  *                     Print out the entire graphm all variables and
                    114:  *                     statistics for the directory cache. Should print
                    115:  *                     something for suffixes, too, but...
1.1       cgd       116:  */
                    117:
1.111     rillig    118: #include <time.h>
1.28      wiz       119:
1.111     rillig    120: #include "make.h"
                    121: #include "dir.h"
1.1       cgd       122:
1.88      rillig    123: /*     "@(#)targ.c     8.2 (Berkeley) 3/19/94" */
1.113   ! rillig    124: MAKE_RCSID("$NetBSD: targ.c,v 1.112 2020/10/05 22:15:45 rillig Exp $");
1.88      rillig    125:
1.89      rillig    126: static GNodeList *allTargets;  /* the list of all targets found so far */
1.18      mycroft   127: #ifdef CLEANUP
1.89      rillig    128: static GNodeList *allGNs;      /* List of all the GNodes */
1.18      mycroft   129: #endif
1.1       cgd       130: static Hash_Table targets;     /* a hash table of same */
                    131:
1.18      mycroft   132: #ifdef CLEANUP
1.55      dsl       133: static void TargFreeGN(void *);
1.18      mycroft   134: #endif
1.4       jtc       135:
1.1       cgd       136: void
1.28      wiz       137: Targ_Init(void)
1.1       cgd       138: {
1.65      rillig    139:     allTargets = Lst_Init();
1.83      rillig    140:     Hash_InitTable(&targets);
1.1       cgd       141: }
                    142:
1.4       jtc       143: void
1.28      wiz       144: Targ_End(void)
1.4       jtc       145: {
1.64      sjg       146:     Targ_Stats();
1.18      mycroft   147: #ifdef CLEANUP
1.76      rillig    148:     Lst_Free(allTargets);
1.73      rillig    149:     if (allGNs != NULL)
1.76      rillig    150:        Lst_Destroy(allGNs, TargFreeGN);
1.4       jtc       151:     Hash_DeleteTable(&targets);
1.18      mycroft   152: #endif
1.12      christos  153: }
                    154:
1.64      sjg       155: void
                    156: Targ_Stats(void)
                    157: {
                    158:     Hash_DebugStats(&targets, "targets");
                    159: }
                    160:
1.77      rillig    161: /* Return the list of all targets. */
1.89      rillig    162: GNodeList *
1.28      wiz       163: Targ_List(void)
1.12      christos  164: {
                    165:     return allTargets;
1.4       jtc       166: }
                    167:
1.77      rillig    168: /* Create and initialize a new graph node. The gnode is added to the list of
                    169:  * all gnodes.
1.1       cgd       170:  *
1.28      wiz       171:  * Input:
1.91      rillig    172:  *     name            the name of the node, such as "clean", "src.c", ".END"
1.1       cgd       173:  */
                    174: GNode *
1.29      christos  175: Targ_NewGN(const char *name)
1.1       cgd       176: {
1.28      wiz       177:     GNode *gn;
1.1       cgd       178:
1.53      joerg     179:     gn = bmake_malloc(sizeof(GNode));
                    180:     gn->name = bmake_strdup(name);
1.11      christos  181:     gn->uname = NULL;
1.29      christos  182:     gn->path = NULL;
1.77      rillig    183:     gn->type = name[0] == '-' && name[1] == 'l' ? OP_LIB : 0;
1.106     rillig    184:     gn->unmade = 0;
1.27      pk        185:     gn->unmade_cohorts = 0;
1.112     rillig    186:     gn->cohort_num[0] = '\0';
1.106     rillig    187:     gn->centurion = NULL;
                    188:     gn->made = UNMADE;
                    189:     gn->flags = 0;
                    190:     gn->checked = 0;
                    191:     gn->mtime = 0;
                    192:     gn->cmgn = NULL;
1.80      rillig    193:     gn->implicitParents = Lst_Init();
1.106     rillig    194:     gn->cohorts = Lst_Init();
                    195:     gn->parents = Lst_Init();
                    196:     gn->children = Lst_Init();
                    197:     gn->order_pred = Lst_Init();
                    198:     gn->order_succ = Lst_Init();
1.83      rillig    199:     Hash_InitTable(&gn->context);
1.106     rillig    200:     gn->commands = Lst_Init();
                    201:     gn->suffix = NULL;
                    202:     gn->fname = NULL;
                    203:     gn->lineno = 0;
1.1       cgd       204:
1.18      mycroft   205: #ifdef CLEANUP
1.4       jtc       206:     if (allGNs == NULL)
1.65      rillig    207:        allGNs = Lst_Init();
1.76      rillig    208:     Lst_Append(allGNs, gn);
1.18      mycroft   209: #endif
1.4       jtc       210:
1.63      rillig    211:     return gn;
1.1       cgd       212: }
                    213:
1.18      mycroft   214: #ifdef CLEANUP
1.4       jtc       215: static void
1.55      dsl       216: TargFreeGN(void *gnp)
1.4       jtc       217: {
1.37      christos  218:     GNode *gn = (GNode *)gnp;
1.4       jtc       219:
                    220:     free(gn->name);
1.61      christos  221:     free(gn->uname);
                    222:     free(gn->path);
1.4       jtc       223:
1.80      rillig    224:     Lst_Free(gn->implicitParents);
1.76      rillig    225:     Lst_Free(gn->cohorts);
                    226:     Lst_Free(gn->parents);
                    227:     Lst_Free(gn->children);
                    228:     Lst_Free(gn->order_succ);
                    229:     Lst_Free(gn->order_pred);
1.17      mycroft   230:     Hash_DeleteTable(&gn->context);
1.76      rillig    231:     Lst_Free(gn->commands);
1.77      rillig    232:
                    233:     /* XXX: does gn->suffix need to be freed? It is reference-counted. */
                    234:
1.36      christos  235:     free(gn);
1.4       jtc       236: }
1.18      mycroft   237: #endif
1.4       jtc       238:
1.95      rillig    239: /* Get the existing global node, or return NULL. */
                    240: GNode *
                    241: Targ_FindNode(const char *name)
                    242: {
1.96      rillig    243:     return Hash_FindValue(&targets, name);
1.95      rillig    244: }
                    245:
                    246: /* Get the existing global node, or create it. */
                    247: GNode *
                    248: Targ_GetNode(const char *name)
                    249: {
1.96      rillig    250:     Boolean isNew;
                    251:     Hash_Entry *he = Hash_CreateEntry(&targets, name, &isNew);
                    252:     if (!isNew)
                    253:        return Hash_GetValue(he);
                    254:
                    255:     {
                    256:        GNode *gn = Targ_NewInternalNode(name);
                    257:        Hash_SetValue(he, gn);
                    258:        return gn;
                    259:     }
1.95      rillig    260: }
                    261:
                    262: /* Create a node, register it in .ALLTARGETS but don't store it in the
                    263:  * table of global nodes.  This means it cannot be found by name.
                    264:  *
                    265:  * This is used for internal nodes, such as cohorts or .WAIT nodes. */
                    266: GNode *
                    267: Targ_NewInternalNode(const char *name)
                    268: {
1.96      rillig    269:     GNode *gn = Targ_NewGN(name);
                    270:     Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
                    271:     Lst_Append(allTargets, gn);
                    272:     if (doing_depend)
                    273:        gn->flags |= FROM_DEPEND;
                    274:     return gn;
1.95      rillig    275: }
                    276:
1.90      rillig    277: /* Return the .END node, which contains the commands to be executed when
                    278:  * everything else is done. */
                    279: GNode *Targ_GetEndNode(void)
                    280: {
                    281:     /* Save the node locally to avoid having to search for it all the time. */
                    282:     static GNode *endNode = NULL;
                    283:     if (endNode == NULL) {
1.95      rillig    284:        endNode = Targ_GetNode(".END");
1.90      rillig    285:        endNode->type = OP_SPECIAL;
                    286:     }
                    287:     return endNode;
                    288: }
                    289:
1.98      rillig    290: /* Return the named nodes, creating them as necessary. */
1.89      rillig    291: GNodeList *
1.95      rillig    292: Targ_FindList(StringList *names)
1.1       cgd       293: {
1.89      rillig    294:     StringListNode *ln;
1.108     rillig    295:     GNodeList *nodes = Lst_Init();
                    296:     for (ln = names->first; ln != NULL; ln = ln->next) {
                    297:        const char *name = ln->datum;
1.96      rillig    298:        GNode *gn = Targ_GetNode(name);
1.95      rillig    299:        Lst_Append(nodes, gn);
1.1       cgd       300:     }
1.63      rillig    301:     return nodes;
1.1       cgd       302: }
                    303:
1.77      rillig    304: /* Return true if should ignore errors when creating gn. */
1.1       cgd       305: Boolean
1.28      wiz       306: Targ_Ignore(GNode *gn)
1.1       cgd       307: {
1.77      rillig    308:     return ignoreErrors || gn->type & OP_IGNORE;
1.1       cgd       309: }
                    310:
1.77      rillig    311: /* Return true if be silent when creating gn. */
1.1       cgd       312: Boolean
1.28      wiz       313: Targ_Silent(GNode *gn)
1.1       cgd       314: {
1.77      rillig    315:     return beSilent || gn->type & OP_SILENT;
1.1       cgd       316: }
                    317:
1.77      rillig    318: /* See if the given target is precious. */
1.1       cgd       319: Boolean
1.28      wiz       320: Targ_Precious(GNode *gn)
1.1       cgd       321: {
1.77      rillig    322:     return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP);
1.1       cgd       323: }
                    324:
                    325: /******************* DEBUG INFO PRINTING ****************/
                    326:
                    327: static GNode     *mainTarg;    /* the main target, as set by Targ_SetMain */
1.77      rillig    328:
                    329: /* Set our idea of the main target we'll be creating. Used for debugging
                    330:  * output. */
1.1       cgd       331: void
1.28      wiz       332: Targ_SetMain(GNode *gn)
1.1       cgd       333: {
                    334:     mainTarg = gn;
                    335: }
                    336:
1.86      rillig    337: static void
1.89      rillig    338: PrintNodeNames(GNodeList *gnodes)
1.1       cgd       339: {
1.89      rillig    340:     GNodeListNode *node;
1.38      dsl       341:
1.101     rillig    342:     for (node = gnodes->first; node != NULL; node = node->next) {
                    343:        GNode *gn = node->datum;
1.107     rillig    344:        debug_printf(" %s%s", gn->name, gn->cohort_num);
1.85      rillig    345:     }
                    346: }
1.38      dsl       347:
1.85      rillig    348: static void
1.89      rillig    349: PrintNodeNamesLine(const char *label, GNodeList *gnodes)
1.85      rillig    350: {
                    351:     if (Lst_IsEmpty(gnodes))
                    352:        return;
1.107     rillig    353:     debug_printf("# %s:", label);
1.85      rillig    354:     PrintNodeNames(gnodes);
1.107     rillig    355:     debug_printf("\n");
1.1       cgd       356: }
                    357:
1.84      rillig    358: void
                    359: Targ_PrintCmds(GNode *gn)
                    360: {
1.101     rillig    361:     StringListNode *node = gn->commands->first;
                    362:     for (; node != NULL; node = node->next) {
1.93      rillig    363:        const char *cmd = LstNode_Datum(node);
1.107     rillig    364:        debug_printf("\t%s\n", cmd);
1.93      rillig    365:     }
1.84      rillig    366: }
                    367:
1.77      rillig    368: /* Format a modification time in some reasonable way and return it.
                    369:  * The time is placed in a static area, so it is overwritten with each call. */
1.1       cgd       370: char *
1.28      wiz       371: Targ_FmtTime(time_t tm)
1.1       cgd       372: {
1.106     rillig    373:     struct tm *parts;
                    374:     static char buf[128];
1.1       cgd       375:
1.25      reinoud   376:     parts = localtime(&tm);
1.15      christos  377:     (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
1.63      rillig    378:     return buf;
1.1       cgd       379: }
1.10      christos  380:
1.77      rillig    381: /* Print out a type field giving only those attributes the user can set. */
1.1       cgd       382: void
1.52      christos  383: Targ_PrintType(int type)
1.1       cgd       384: {
1.28      wiz       385:     int    tbit;
1.10      christos  386:
1.107     rillig    387: #define PRINTBIT(attr) case CONCAT(OP_,attr): debug_printf(" ." #attr); break
                    388: #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))debug_printf(" ." #attr); break
1.1       cgd       389:
                    390:     type &= ~OP_OPMASK;
                    391:
                    392:     while (type) {
1.52      christos  393:        tbit = 1 << (ffs(type) - 1);
1.1       cgd       394:        type &= ~tbit;
                    395:
                    396:        switch(tbit) {
1.96      rillig    397:        PRINTBIT(OPTIONAL);
                    398:        PRINTBIT(USE);
                    399:        PRINTBIT(EXEC);
                    400:        PRINTBIT(IGNORE);
                    401:        PRINTBIT(PRECIOUS);
                    402:        PRINTBIT(SILENT);
                    403:        PRINTBIT(MAKE);
                    404:        PRINTBIT(JOIN);
                    405:        PRINTBIT(INVISIBLE);
                    406:        PRINTBIT(NOTMAIN);
                    407:        PRINTDBIT(LIB);
1.1       cgd       408:            /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
1.107     rillig    409:        case OP_MEMBER: if (DEBUG(TARG))debug_printf(" .MEMBER"); break;
1.96      rillig    410:        PRINTDBIT(ARCHV);
                    411:        PRINTDBIT(MADE);
                    412:        PRINTDBIT(PHONY);
1.1       cgd       413:        }
                    414:     }
                    415: }
                    416:
1.45      dsl       417: static const char *
1.71      rillig    418: made_name(GNodeMade made)
1.45      dsl       419: {
                    420:     switch (made) {
                    421:     case UNMADE:     return "unmade";
                    422:     case DEFERRED:   return "deferred";
                    423:     case REQUESTED:  return "requested";
                    424:     case BEINGMADE:  return "being made";
                    425:     case MADE:       return "made";
                    426:     case UPTODATE:   return "up-to-date";
                    427:     case ERROR:      return "error when made";
                    428:     case ABORTED:    return "aborted";
                    429:     default:         return "unknown enum_made value";
                    430:     }
                    431: }
                    432:
1.105     rillig    433: /* Print the contents of a node. */
                    434: void
                    435: Targ_PrintNode(GNode *gn, int pass)
1.1       cgd       436: {
1.107     rillig    437:     debug_printf("# %s%s", gn->name, gn->cohort_num);
1.72      rillig    438:     GNode_FprintDetails(debug_file, ", ", gn, "\n");
1.45      dsl       439:     if (gn->flags == 0)
1.104     rillig    440:        return;
1.45      dsl       441:
1.1       cgd       442:     if (!OP_NOP(gn->type)) {
1.107     rillig    443:        debug_printf("#\n");
1.1       cgd       444:        if (gn == mainTarg) {
1.107     rillig    445:            debug_printf("# *** MAIN TARGET ***\n");
1.1       cgd       446:        }
1.45      dsl       447:        if (pass >= 2) {
1.1       cgd       448:            if (gn->unmade) {
1.107     rillig    449:                debug_printf("# %d unmade children\n", gn->unmade);
1.1       cgd       450:            } else {
1.107     rillig    451:                debug_printf("# No unmade children\n");
1.1       cgd       452:            }
1.22      christos  453:            if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
1.1       cgd       454:                if (gn->mtime != 0) {
1.107     rillig    455:                    debug_printf("# last modified %s: %s\n",
1.96      rillig    456:                            Targ_FmtTime(gn->mtime),
                    457:                            made_name(gn->made));
1.1       cgd       458:                } else if (gn->made != UNMADE) {
1.107     rillig    459:                    debug_printf("# non-existent (maybe): %s\n",
1.96      rillig    460:                            made_name(gn->made));
1.1       cgd       461:                } else {
1.107     rillig    462:                    debug_printf("# unmade\n");
1.1       cgd       463:                }
                    464:            }
1.85      rillig    465:            PrintNodeNamesLine("implicit parents", gn->implicitParents);
1.41      dsl       466:        } else {
                    467:            if (gn->unmade)
1.107     rillig    468:                debug_printf("# %d unmade children\n", gn->unmade);
1.1       cgd       469:        }
1.85      rillig    470:        PrintNodeNamesLine("parents", gn->parents);
                    471:        PrintNodeNamesLine("order_pred", gn->order_pred);
                    472:        PrintNodeNamesLine("order_succ", gn->order_succ);
1.10      christos  473:
1.107     rillig    474:        debug_printf("%-16s", gn->name);
1.1       cgd       475:        switch (gn->type & OP_OPMASK) {
1.96      rillig    476:        case OP_DEPENDS:
1.107     rillig    477:            debug_printf(":"); break;
1.96      rillig    478:        case OP_FORCE:
1.107     rillig    479:            debug_printf("!"); break;
1.96      rillig    480:        case OP_DOUBLEDEP:
1.107     rillig    481:            debug_printf("::"); break;
1.1       cgd       482:        }
1.34      christos  483:        Targ_PrintType(gn->type);
1.85      rillig    484:        PrintNodeNames(gn->children);
1.107     rillig    485:        debug_printf("\n");
1.84      rillig    486:        Targ_PrintCmds(gn);
1.107     rillig    487:        debug_printf("\n\n");
1.20      mycroft   488:        if (gn->type & OP_DOUBLEDEP) {
1.104     rillig    489:            Targ_PrintNodes(gn->cohorts, pass);
1.1       cgd       490:        }
                    491:     }
                    492: }
                    493:
1.87      rillig    494: void
1.89      rillig    495: Targ_PrintNodes(GNodeList *gnodes, int pass)
1.87      rillig    496: {
1.104     rillig    497:     GNodeListNode *ln;
                    498:     for (ln = gnodes->first; ln != NULL; ln = ln->next)
1.105     rillig    499:        Targ_PrintNode(ln->datum, pass);
1.87      rillig    500: }
                    501:
1.100     rillig    502: /* Print only those targets that are just a source. */
1.103     mrg       503: static void
1.100     rillig    504: PrintOnlySources(void)
1.4       jtc       505: {
1.100     rillig    506:     GNodeListNode *ln;
                    507:
                    508:     for (ln = allTargets->first; ln != NULL; ln = ln->next) {
                    509:        GNode *gn = ln->datum;
                    510:        if (!OP_NOP(gn->type))
                    511:            continue;
1.4       jtc       512:
1.107     rillig    513:        debug_printf("#\t%s [%s]",
1.100     rillig    514:                gn->name, gn->path ? gn->path : gn->name);
                    515:        Targ_PrintType(gn->type);
1.107     rillig    516:        debug_printf("\n");
1.100     rillig    517:     }
1.1       cgd       518: }
                    519:
1.77      rillig    520: /* Input:
                    521:  *     pass            1 => before processing
                    522:  *                     2 => after processing
                    523:  *                     3 => after processing, an error occurred
1.1       cgd       524:  */
1.3       cgd       525: void
1.28      wiz       526: Targ_PrintGraph(int pass)
1.1       cgd       527: {
1.107     rillig    528:     debug_printf("#*** Input graph:\n");
1.100     rillig    529:     Targ_PrintNodes(allTargets, pass);
1.107     rillig    530:     debug_printf("\n\n");
                    531:     debug_printf("#\n#   Files that are only sources:\n");
1.100     rillig    532:     PrintOnlySources();
1.107     rillig    533:     debug_printf("#*** Global Variables:\n");
1.34      christos  534:     Var_Dump(VAR_GLOBAL);
1.107     rillig    535:     debug_printf("#*** Command-line Variables:\n");
1.34      christos  536:     Var_Dump(VAR_CMD);
1.107     rillig    537:     debug_printf("\n");
1.1       cgd       538:     Dir_PrintDirectories();
1.107     rillig    539:     debug_printf("\n");
1.1       cgd       540:     Suff_PrintAll();
1.19      mycroft   541: }
                    542:
1.78      rillig    543: /* Propagate some type information to cohort nodes (those from the ::
                    544:  * dependency operator).
1.77      rillig    545:  *
1.78      rillig    546:  * Should be called after the makefiles are parsed but before any action is
                    547:  * taken. */
                    548: void
                    549: Targ_Propagate(void)
1.19      mycroft   550: {
1.89      rillig    551:     GNodeListNode *pn, *cn;
1.45      dsl       552:
1.101     rillig    553:     for (pn = allTargets->first; pn != NULL; pn = pn->next) {
                    554:        GNode *pgn = pn->datum;
1.19      mycroft   555:
1.78      rillig    556:        if (!(pgn->type & OP_DOUBLEDEP))
                    557:            continue;
1.42      apb       558:
1.101     rillig    559:        for (cn = pgn->cohorts->first; cn != NULL; cn = cn->next) {
                    560:            GNode *cgn = cn->datum;
1.42      apb       561:
1.78      rillig    562:            cgn->type |= pgn->type & ~OP_OPMASK;
                    563:        }
                    564:     }
1.1       cgd       565: }

CVSweb <webmaster@jp.NetBSD.org>