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

Annotation of src/usr.bin/make/make.c, Revision 1.47

1.47    ! pk          1: /*     $NetBSD: make.c,v 1.46 2002/03/12 23:52:35 pk Exp $     */
1.7       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.1       cgd         6:  * Copyright (c) 1989 by Berkeley Softworks
                      7:  * All rights reserved.
                      8:  *
                      9:  * This code is derived from software contributed to Berkeley by
                     10:  * Adam de Boor.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the University of
                     23:  *     California, Berkeley and its contributors.
                     24:  * 4. Neither the name of the University nor the names of its contributors
                     25:  *    may be used to endorse or promote products derived from this software
                     26:  *    without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     29:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     30:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     31:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     32:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     33:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     34:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     35:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     36:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     37:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     38:  * SUCH DAMAGE.
                     39:  */
                     40:
1.19      lukem      41: #ifdef MAKE_BOOTSTRAP
1.47    ! pk         42: static char rcsid[] = "$NetBSD: make.c,v 1.46 2002/03/12 23:52:35 pk Exp $";
1.19      lukem      43: #else
1.18      christos   44: #include <sys/cdefs.h>
1.1       cgd        45: #ifndef lint
1.7       christos   46: #if 0
1.10      christos   47: static char sccsid[] = "@(#)make.c     8.1 (Berkeley) 6/6/93";
1.7       christos   48: #else
1.47    ! pk         49: __RCSID("$NetBSD: make.c,v 1.46 2002/03/12 23:52:35 pk Exp $");
1.7       christos   50: #endif
1.1       cgd        51: #endif /* not lint */
1.19      lukem      52: #endif
1.1       cgd        53:
                     54: /*-
                     55:  * make.c --
                     56:  *     The functions which perform the examination of targets and
                     57:  *     their suitability for creation
                     58:  *
                     59:  * Interface:
                     60:  *     Make_Run                Initialize things for the module and recreate
                     61:  *                             whatever needs recreating. Returns TRUE if
                     62:  *                             work was (or would have been) done and FALSE
                     63:  *                             otherwise.
                     64:  *
                     65:  *     Make_Update             Update all parents of a given child. Performs
                     66:  *                             various bookkeeping chores like the updating
                     67:  *                             of the cmtime field of the parent, filling
                     68:  *                             of the IMPSRC context variable, etc. It will
                     69:  *                             place the parent on the toBeMade queue if it
                     70:  *                             should be.
                     71:  *
                     72:  *     Make_TimeStamp          Function to set the parent's cmtime field
                     73:  *                             based on a child's modification time.
                     74:  *
                     75:  *     Make_DoAllVar           Set up the various local variables for a
                     76:  *                             target, including the .ALLSRC variable, making
                     77:  *                             sure that any variable that needs to exist
                     78:  *                             at the very least has the empty value.
                     79:  *
                     80:  *     Make_OODate             Determine if a target is out-of-date.
                     81:  *
                     82:  *     Make_HandleUse          See if a child is a .USE node for a parent
                     83:  *                             and perform the .USE actions if so.
1.11      christos   84:  *
                     85:  *     Make_ExpandUse          Expand .USE nodes and return the new list of
                     86:  *                             targets.
1.1       cgd        87:  */
                     88:
                     89: #include    "make.h"
1.4       cgd        90: #include    "hash.h"
                     91: #include    "dir.h"
                     92: #include    "job.h"
1.1       cgd        93:
                     94: static Lst             toBeMade;       /* The current fringe of the graph. These
                     95:                                 * are nodes which await examination by
                     96:                                 * MakeOODate. It is added to by
                     97:                                 * Make_Update and subtracted from by
                     98:                                 * MakeStartJobs */
                     99: static int     numNodes;       /* Number of nodes to be processed. If this
                    100:                                 * is non-zero when Job_Empty() returns
                    101:                                 * TRUE, there's a cycle in the graph */
                    102:
1.5       jtc       103: static int MakeAddChild __P((ClientData, ClientData));
1.13      christos  104: static int MakeFindChild __P((ClientData, ClientData));
1.31      mycroft   105: static int MakeUnmark __P((ClientData, ClientData));
1.5       jtc       106: static int MakeAddAllSrc __P((ClientData, ClientData));
                    107: static int MakeTimeStamp __P((ClientData, ClientData));
                    108: static int MakeHandleUse __P((ClientData, ClientData));
1.4       cgd       109: static Boolean MakeStartJobs __P((void));
1.5       jtc       110: static int MakePrintStatus __P((ClientData, ClientData));
1.1       cgd       111: /*-
                    112:  *-----------------------------------------------------------------------
                    113:  * Make_TimeStamp --
                    114:  *     Set the cmtime field of a parent node based on the mtime stamp in its
1.10      christos  115:  *     child. Called from MakeOODate via Lst_ForEach.
1.1       cgd       116:  *
                    117:  * Results:
1.10      christos  118:  *     Always returns 0.
1.1       cgd       119:  *
                    120:  * Side Effects:
                    121:  *     The cmtime of the parent node will be changed if the mtime
                    122:  *     field of the child is greater than it.
                    123:  *-----------------------------------------------------------------------
                    124:  */
                    125: int
                    126: Make_TimeStamp (pgn, cgn)
1.5       jtc       127:     GNode *pgn;        /* the current parent */
                    128:     GNode *cgn;        /* the child we've just examined */
1.1       cgd       129: {
                    130:     if (cgn->mtime > pgn->cmtime) {
                    131:        pgn->cmtime = cgn->mtime;
                    132:     }
                    133:     return (0);
                    134: }
1.5       jtc       135:
                    136: static int
                    137: MakeTimeStamp (pgn, cgn)
                    138:     ClientData pgn;    /* the current parent */
                    139:     ClientData cgn;    /* the child we've just examined */
                    140: {
                    141:     return Make_TimeStamp((GNode *) pgn, (GNode *) cgn);
                    142: }
1.1       cgd       143: 
                    144: /*-
                    145:  *-----------------------------------------------------------------------
                    146:  * Make_OODate --
                    147:  *     See if a given node is out of date with respect to its sources.
                    148:  *     Used by Make_Run when deciding which nodes to place on the
                    149:  *     toBeMade queue initially and by Make_Update to screen out USE and
                    150:  *     EXEC nodes. In the latter case, however, any other sort of node
                    151:  *     must be considered out-of-date since at least one of its children
                    152:  *     will have been recreated.
                    153:  *
                    154:  * Results:
1.10      christos  155:  *     TRUE if the node is out of date. FALSE otherwise.
1.1       cgd       156:  *
                    157:  * Side Effects:
                    158:  *     The mtime field of the node and the cmtime field of its parents
                    159:  *     will/may be changed.
                    160:  *-----------------------------------------------------------------------
                    161:  */
                    162: Boolean
                    163: Make_OODate (gn)
1.44      pk        164:     GNode *gn;       /* the node to check */
1.1       cgd       165: {
                    166:     Boolean         oodate;
                    167:
                    168:     /*
                    169:      * Certain types of targets needn't even be sought as their datedness
                    170:      * doesn't depend on their modification time...
                    171:      */
1.39      christos  172:     if ((gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC)) == 0) {
1.1       cgd       173:        (void) Dir_MTime (gn);
                    174:        if (DEBUG(MAKE)) {
                    175:            if (gn->mtime != 0) {
                    176:                printf ("modified %s...", Targ_FmtTime(gn->mtime));
                    177:            } else {
                    178:                printf ("non-existent...");
                    179:            }
                    180:        }
                    181:     }
                    182:
                    183:     /*
                    184:      * A target is remade in one of the following circumstances:
                    185:      * its modification time is smaller than that of its youngest child
                    186:      *     and it would actually be run (has commands or type OP_NOP)
                    187:      * it's the object of a force operator
                    188:      * it has no children, was on the lhs of an operator and doesn't exist
                    189:      *     already.
                    190:      *
                    191:      * Libraries are only considered out-of-date if the archive module says
                    192:      * they are.
                    193:      *
1.37      wiz       194:      * These weird rules are brought to you by Backward-Compatibility and
1.1       cgd       195:      * the strange people who wrote 'Make'.
                    196:      */
1.39      christos  197:     if (gn->type & (OP_USE|OP_USEBEFORE)) {
1.1       cgd       198:        /*
                    199:         * If the node is a USE node it is *never* out of date
                    200:         * no matter *what*.
                    201:         */
                    202:        if (DEBUG(MAKE)) {
                    203:            printf(".USE node...");
                    204:        }
                    205:        oodate = FALSE;
1.25      sjg       206:     } else if ((gn->type & OP_LIB) &&
                    207:               ((gn->mtime==0) || Arch_IsLib(gn))) {
1.1       cgd       208:        if (DEBUG(MAKE)) {
                    209:            printf("library...");
                    210:        }
1.6       christos  211:
                    212:        /*
                    213:         * always out of date if no children and :: target
1.26      sjg       214:         * or non-existent.
1.6       christos  215:         */
1.36      sjg       216:        oodate = (gn->mtime == 0 || Arch_LibOODate (gn) ||
1.27      sjg       217:                  (gn->cmtime == 0 && (gn->type & OP_DOUBLEDEP)));
1.1       cgd       218:     } else if (gn->type & OP_JOIN) {
                    219:        /*
                    220:         * A target with the .JOIN attribute is only considered
                    221:         * out-of-date if any of its children was out-of-date.
                    222:         */
                    223:        if (DEBUG(MAKE)) {
                    224:            printf(".JOIN node...");
                    225:        }
1.22      christos  226:        if (DEBUG(MAKE)) {
                    227:            printf("source %smade...", gn->flags & CHILDMADE ? "" : "not ");
                    228:        }
                    229:        oodate = (gn->flags & CHILDMADE) ? 1 : 0;
1.8       christos  230:     } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
1.1       cgd       231:        /*
                    232:         * A node which is the object of the force (!) operator or which has
                    233:         * the .EXEC attribute is always considered out-of-date.
                    234:         */
                    235:        if (DEBUG(MAKE)) {
                    236:            if (gn->type & OP_FORCE) {
                    237:                printf("! operator...");
1.8       christos  238:            } else if (gn->type & OP_PHONY) {
                    239:                printf(".PHONY node...");
1.1       cgd       240:            } else {
                    241:                printf(".EXEC node...");
                    242:            }
                    243:        }
                    244:        oodate = TRUE;
                    245:     } else if ((gn->mtime < gn->cmtime) ||
                    246:               ((gn->cmtime == 0) &&
                    247:                ((gn->mtime==0) || (gn->type & OP_DOUBLEDEP))))
                    248:     {
                    249:        /*
                    250:         * A node whose modification time is less than that of its
                    251:         * youngest child or that has no children (cmtime == 0) and
                    252:         * either doesn't exist (mtime == 0) or was the object of a
                    253:         * :: operator is out-of-date. Why? Because that's the way Make does
                    254:         * it.
                    255:         */
                    256:        if (DEBUG(MAKE)) {
                    257:            if (gn->mtime < gn->cmtime) {
                    258:                printf("modified before source...");
                    259:            } else if (gn->mtime == 0) {
                    260:                printf("non-existent and no sources...");
                    261:            } else {
                    262:                printf(":: operator and no sources...");
                    263:            }
                    264:        }
                    265:        oodate = TRUE;
                    266:     } else {
1.21      christos  267:        /*
1.22      christos  268:         * When a non-existing child with no sources
1.21      christos  269:         * (such as a typically used FORCE source) has been made and
                    270:         * the target of the child (usually a directory) has the same
                    271:         * timestamp as the timestamp just given to the non-existing child
                    272:         * after it was considered made.
                    273:         */
1.1       cgd       274:        if (DEBUG(MAKE)) {
1.22      christos  275:            if (gn->flags & FORCE)
                    276:                printf("non existing child...");
1.1       cgd       277:        }
1.22      christos  278:        oodate = (gn->flags & FORCE) ? 1 : 0;
1.1       cgd       279:     }
                    280:
                    281:     /*
                    282:      * If the target isn't out-of-date, the parents need to know its
                    283:      * modification time. Note that targets that appear to be out-of-date
                    284:      * but aren't, because they have no commands and aren't of type OP_NOP,
                    285:      * have their mtime stay below their children's mtime to keep parents from
                    286:      * thinking they're out-of-date.
                    287:      */
                    288:     if (!oodate) {
1.5       jtc       289:        Lst_ForEach (gn->parents, MakeTimeStamp, (ClientData)gn);
1.1       cgd       290:     }
                    291:
                    292:     return (oodate);
                    293: }
                    294: 
                    295: /*-
                    296:  *-----------------------------------------------------------------------
                    297:  * MakeAddChild  --
                    298:  *     Function used by Make_Run to add a child to the list l.
                    299:  *     It will only add the child if its make field is FALSE.
                    300:  *
                    301:  * Results:
                    302:  *     Always returns 0
                    303:  *
                    304:  * Side Effects:
                    305:  *     The given list is extended
                    306:  *-----------------------------------------------------------------------
                    307:  */
                    308: static int
1.5       jtc       309: MakeAddChild (gnp, lp)
                    310:     ClientData     gnp;                /* the node to add */
                    311:     ClientData     lp;         /* the list to which to add it */
1.1       cgd       312: {
1.5       jtc       313:     GNode          *gn = (GNode *) gnp;
                    314:     Lst            l = (Lst) lp;
1.14      christos  315:
1.39      christos  316:     if ((gn->flags & REMAKE) == 0 && !(gn->type & (OP_USE|OP_USEBEFORE))) {
1.1       cgd       317:        (void)Lst_EnQueue (l, (ClientData)gn);
                    318:     }
                    319:     return (0);
                    320: }
1.13      christos  321: 
                    322: /*-
                    323:  *-----------------------------------------------------------------------
                    324:  * MakeFindChild  --
                    325:  *     Function used by Make_Run to find the pathname of a child
                    326:  *     that was already made.
                    327:  *
                    328:  * Results:
                    329:  *     Always returns 0
                    330:  *
                    331:  * Side Effects:
1.14      christos  332:  *     The path and mtime of the node and the cmtime of the parent are
1.42      pk        333:  *     updated; the unmade children count of the parent is decremented.
1.13      christos  334:  *-----------------------------------------------------------------------
                    335:  */
                    336: static int
1.14      christos  337: MakeFindChild (gnp, pgnp)
1.13      christos  338:     ClientData     gnp;                /* the node to find */
1.14      christos  339:     ClientData     pgnp;
1.13      christos  340: {
                    341:     GNode          *gn = (GNode *) gnp;
1.14      christos  342:     GNode          *pgn = (GNode *) pgnp;
                    343:
                    344:     (void) Dir_MTime(gn);
1.22      christos  345:     Make_TimeStamp(pgn, gn);
1.42      pk        346:     pgn->unmade--;
1.14      christos  347:
1.13      christos  348:     return (0);
                    349: }
                    350: 
1.1       cgd       351: /*-
                    352:  *-----------------------------------------------------------------------
                    353:  * Make_HandleUse --
                    354:  *     Function called by Make_Run and SuffApplyTransform on the downward
1.44      pk        355:  *     pass to handle .USE and transformation nodes. It implements the
                    356:  *     .USE and transformation functionality by copying the node's commands,
                    357:  *     type flags and children to the parent node.
1.1       cgd       358:  *
                    359:  *     A .USE node is much like an explicit transformation rule, except
                    360:  *     its commands are always added to the target node, even if the
                    361:  *     target already has commands.
                    362:  *
                    363:  * Results:
1.44      pk        364:  *     none
1.1       cgd       365:  *
                    366:  * Side Effects:
                    367:  *     Children and commands may be added to the parent and the parent's
                    368:  *     type may be changed.
                    369:  *
                    370:  *-----------------------------------------------------------------------
                    371:  */
1.43      pk        372: void
1.1       cgd       373: Make_HandleUse (cgn, pgn)
1.44      pk        374:     GNode      *cgn;   /* The .USE node */
                    375:     GNode      *pgn;   /* The target of the .USE node */
1.1       cgd       376: {
1.44      pk        377:     LstNode    ln;     /* An element in the children list */
                    378:
                    379: #ifdef DEBUG_SRC
                    380:     if ((cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) == 0) {
                    381:        printf("Make_HandleUse: called for plain node %s\n", cgn->name);
                    382:        return;
                    383:     }
                    384: #endif
1.1       cgd       385:
1.44      pk        386:     if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) {
1.39      christos  387:            if (cgn->type & OP_USEBEFORE) {
                    388:                /*
                    389:                 * .USEBEFORE --
                    390:                 *      prepend the child's commands to the parent.
                    391:                 */
                    392:                Lst cmds = pgn->commands;
                    393:                pgn->commands = Lst_Duplicate (cgn->commands, NOCOPY);
                    394:                (void) Lst_Concat (pgn->commands, cmds, LST_CONCNEW);
                    395:                Lst_Destroy (cmds, NOFREE);
                    396:            } else {
                    397:                /*
                    398:                 * .USE or target has no commands --
                    399:                 *      append the child's commands to the parent.
                    400:                 */
                    401:                (void) Lst_Concat (pgn->commands, cgn->commands, LST_CONCNEW);
                    402:            }
1.44      pk        403:     }
1.10      christos  404:
1.44      pk        405:     if (Lst_Open (cgn->children) == SUCCESS) {
                    406:        while ((ln = Lst_Next (cgn->children)) != NILLNODE) {
                    407:            GNode *tgn, *gn = (GNode *)Lst_Datum (ln);
1.11      christos  408:
1.44      pk        409:            /*
                    410:             * Expand variables in the .USE node's name
                    411:             * and save the unexpanded form.
                    412:             * We don't need to do this for commands.
                    413:             * They get expanded properly when we execute.
                    414:             */
                    415:            if (gn->uname == NULL) {
                    416:                gn->uname = gn->name;
                    417:            } else {
                    418:                if (gn->name)
                    419:                    free(gn->name);
                    420:            }
                    421:            gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE);
                    422:            if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) {
                    423:                /* See if we have a target for this node. */
                    424:                tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
                    425:                if (tgn != NILGNODE)
                    426:                    gn = tgn;
                    427:            }
1.1       cgd       428:
1.44      pk        429:            (void) Lst_AtEnd (pgn->children, gn);
                    430:            (void) Lst_AtEnd (gn->parents, pgn);
                    431:            pgn->unmade += 1;
1.1       cgd       432:        }
1.44      pk        433:        Lst_Close (cgn->children);
                    434:     }
1.10      christos  435:
1.44      pk        436:     pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM);
1.1       cgd       437: }
1.31      mycroft   438:
1.44      pk        439: /*-
                    440:  *-----------------------------------------------------------------------
                    441:  * MakeHandleUse --
                    442:  *     Callback function for Lst_ForEach, used by Make_Run on the downward
                    443:  *     pass to handle .USE nodes. Should be called before the children
                    444:  *     are enqueued to be looked at by MakeAddChild.
                    445:  *     This function calls Make_HandleUse to copy the .USE node's commands,
                    446:  *     type flags and children to the parent node.
                    447:  *
                    448:  * Results:
                    449:  *     returns 0.
                    450:  *
                    451:  * Side Effects:
                    452:  *     After expansion, .USE child nodes are removed from the parent
                    453:  *
                    454:  *-----------------------------------------------------------------------
                    455:  */
1.5       jtc       456: static int
1.31      mycroft   457: MakeHandleUse (cgnp, pgnp)
                    458:     ClientData cgnp;   /* the child we've just examined */
                    459:     ClientData pgnp;   /* the current parent */
1.5       jtc       460: {
1.31      mycroft   461:     GNode      *cgn = (GNode *) cgnp;
                    462:     GNode      *pgn = (GNode *) pgnp;
1.43      pk        463:     LstNode    ln;     /* An element in the children list */
1.44      pk        464:     int                unmarked;
                    465:
                    466:     unmarked = ((cgn->type & OP_MARK) == 0);
                    467:     cgn->type |= OP_MARK;
1.31      mycroft   468:
1.44      pk        469:     if ((cgn->type & (OP_USE|OP_USEBEFORE)) == 0)
                    470:        return (0);
                    471:
                    472:     if (unmarked)
1.43      pk        473:        Make_HandleUse(cgn, pgn);
1.31      mycroft   474:
1.43      pk        475:     /*
                    476:      * This child node is now "made", so we decrement the count of
                    477:      * unmade children in the parent... We also remove the child
                    478:      * from the parent's list to accurately reflect the number of decent
                    479:      * children the parent has. This is used by Make_Run to decide
                    480:      * whether to queue the parent or examine its children...
                    481:      */
1.44      pk        482:     if ((ln = Lst_Member (pgn->children, (ClientData) cgn)) != NILLNODE) {
1.43      pk        483:        Lst_Remove(pgn->children, ln);
                    484:        pgn->unmade--;
                    485:     }
                    486:     return (0);
1.5       jtc       487: }
1.22      christos  488:
                    489:
                    490: /*-
                    491:  *-----------------------------------------------------------------------
                    492:  * Make_Recheck --
                    493:  *     Check the modification time of a gnode, and update it as described
                    494:  *     in the comments below.
                    495:  *
                    496:  * Results:
                    497:  *     returns 0 if the gnode does not exist, or it's filesystem
                    498:  *     time if it does.
                    499:  *
                    500:  * Side Effects:
                    501:  *     the gnode's modification time and path name are affected.
                    502:  *
                    503:  *-----------------------------------------------------------------------
                    504:  */
                    505: time_t
                    506: Make_Recheck (gn)
                    507:     GNode      *gn;
                    508: {
                    509:     time_t mtime = Dir_MTime(gn);
                    510:
                    511: #ifndef RECHECK
                    512:     /*
                    513:      * We can't re-stat the thing, but we can at least take care of rules
                    514:      * where a target depends on a source that actually creates the
                    515:      * target, but only if it has changed, e.g.
                    516:      *
                    517:      * parse.h : parse.o
                    518:      *
                    519:      * parse.o : parse.y
                    520:      *         yacc -d parse.y
                    521:      *         cc -c y.tab.c
                    522:      *         mv y.tab.o parse.o
                    523:      *         cmp -s y.tab.h parse.h || mv y.tab.h parse.h
                    524:      *
                    525:      * In this case, if the definitions produced by yacc haven't changed
                    526:      * from before, parse.h won't have been updated and gn->mtime will
                    527:      * reflect the current modification time for parse.h. This is
                    528:      * something of a kludge, I admit, but it's a useful one..
                    529:      * XXX: People like to use a rule like
                    530:      *
                    531:      * FRC:
                    532:      *
                    533:      * To force things that depend on FRC to be made, so we have to
                    534:      * check for gn->children being empty as well...
                    535:      */
                    536:     if (!Lst_IsEmpty(gn->commands) || Lst_IsEmpty(gn->children)) {
                    537:        gn->mtime = now;
                    538:     }
                    539: #else
                    540:     /*
                    541:      * This is what Make does and it's actually a good thing, as it
                    542:      * allows rules like
                    543:      *
                    544:      * cmp -s y.tab.h parse.h || cp y.tab.h parse.h
                    545:      *
                    546:      * to function as intended. Unfortunately, thanks to the stateless
                    547:      * nature of NFS (by which I mean the loose coupling of two clients
                    548:      * using the same file from a common server), there are times
                    549:      * when the modification time of a file created on a remote
                    550:      * machine will not be modified before the local stat() implied by
                    551:      * the Dir_MTime occurs, thus leading us to believe that the file
                    552:      * is unchanged, wreaking havoc with files that depend on this one.
                    553:      *
                    554:      * I have decided it is better to make too much than to make too
                    555:      * little, so this stuff is commented out unless you're sure it's ok.
                    556:      * -- ardeb 1/12/88
                    557:      */
                    558:     /*
                    559:      * Christos, 4/9/92: If we are  saving commands pretend that
                    560:      * the target is made now. Otherwise archives with ... rules
                    561:      * don't work!
                    562:      */
1.34      sommerfe  563:     if (NoExecute(gn) ||
1.22      christos  564:        (gn->type & OP_SAVE_CMDS) || mtime == 0) {
                    565:        if (DEBUG(MAKE)) {
1.42      pk        566:            printf(" recheck(%s): update time to now: %s\n",
                    567:                   gn->name, Targ_FmtTime(gn->mtime));
1.22      christos  568:        }
                    569:        gn->mtime = now;
                    570:     }
                    571:     else {
                    572:        if (DEBUG(MAKE)) {
1.42      pk        573:            printf(" recheck(%s): current update time: %s\n",
                    574:                   gn->name, Targ_FmtTime(gn->mtime));
1.22      christos  575:        }
                    576:     }
                    577: #endif
                    578:     return mtime;
                    579: }
                    580:
1.1       cgd       581: /*-
                    582:  *-----------------------------------------------------------------------
                    583:  * Make_Update  --
                    584:  *     Perform update on the parents of a node. Used by JobFinish once
                    585:  *     a node has been dealt with and by MakeStartJobs if it finds an
1.10      christos  586:  *     up-to-date node.
1.1       cgd       587:  *
                    588:  * Results:
                    589:  *     Always returns 0
                    590:  *
                    591:  * Side Effects:
                    592:  *     The unmade field of pgn is decremented and pgn may be placed on
                    593:  *     the toBeMade queue if this field becomes 0.
                    594:  *
1.22      christos  595:  *     If the child was made, the parent's flag CHILDMADE field will be
                    596:  *     set true and its cmtime set to now.
                    597:  *
                    598:  *     If the child is not up-to-date and still does not exist,
                    599:  *     set the FORCE flag on the parents.
1.1       cgd       600:  *
                    601:  *     If the child wasn't made, the cmtime field of the parent will be
                    602:  *     altered if the child's mtime is big enough.
                    603:  *
                    604:  *     Finally, if the child is the implied source for the parent, the
                    605:  *     parent's IMPSRC variable is set appropriately.
                    606:  *
                    607:  *-----------------------------------------------------------------------
                    608:  */
                    609: void
                    610: Make_Update (cgn)
1.44      pk        611:     GNode *cgn;        /* the child node */
1.1       cgd       612: {
1.44      pk        613:     GNode      *pgn;   /* the parent node */
                    614:     char       *cname; /* the child's name */
                    615:     LstNode    ln;     /* Element in parents and iParents lists */
                    616:     time_t     mtime = -1;
                    617:     char       *p1;
1.47    ! pk        618:     Lst                parents;
        !           619:     GNode      *centurion;
1.1       cgd       620:
1.5       jtc       621:     cname = Var_Value (TARGET, cgn, &p1);
                    622:     if (p1)
                    623:        free(p1);
1.1       cgd       624:
                    625:     /*
                    626:      * If the child was actually made, see what its modification time is
                    627:      * now -- some rules won't actually update the file. If the file still
                    628:      * doesn't exist, make its mtime now.
                    629:      */
                    630:     if (cgn->made != UPTODATE) {
1.22      christos  631:        mtime = Make_Recheck(cgn);
1.1       cgd       632:     }
1.10      christos  633:
1.47    ! pk        634:     /*
        !           635:      * If this is a `::' node, we must consult its first instance
        !           636:      * which is where all parents are linked.
        !           637:      */
        !           638:     if ((centurion = cgn->centurion) != NULL) {
        !           639:        if (!Lst_IsEmpty(cgn->parents))
        !           640:                Punt("%s: cohort has parents", cgn->name);
        !           641:        centurion->unmade_cohorts -= 1;
        !           642:        if (centurion->unmade_cohorts < 0)
        !           643:            Error ("Graph cycles through centurion %s", centurion->name);
        !           644:        parents = centurion->parents;
        !           645:     } else {
        !           646:        centurion = cgn;
        !           647:        parents = cgn->parents;
        !           648:     }
        !           649:     if (Lst_Open (parents) == SUCCESS) {
        !           650:        while ((ln = Lst_Next (parents)) != NILLNODE) {
1.1       cgd       651:            pgn = (GNode *)Lst_Datum (ln);
1.22      christos  652:            if (mtime == 0)
                    653:                pgn->flags |= FORCE;
1.42      pk        654:            /*
                    655:             * If the parent has the .MADE attribute, it has already
                    656:             * been queued on the `toBeMade' list in Make_ExpandUse()
                    657:             * and its unmade children counter is zero.
                    658:             */
1.47    ! pk        659:            if ((pgn->flags & REMAKE) == 0 || (pgn->type & OP_MADE) != 0)
        !           660:                continue;
        !           661:
        !           662:            if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
        !           663:                if (cgn->made == MADE)
        !           664:                    pgn->flags |= CHILDMADE;
        !           665:                (void)Make_TimeStamp (pgn, cgn);
        !           666:            }
1.1       cgd       667:
1.47    ! pk        668:            /*
        !           669:             * A parent must wait for the completion of all instances
        !           670:             * of a `::' dependency.
        !           671:             */
        !           672:            if (centurion->unmade_cohorts != 0 || centurion->made == UNMADE)
        !           673:                continue;
        !           674:
        !           675:            /* One more child of this parent is now made */
        !           676:            pgn->unmade -= 1;
        !           677:            if (pgn->unmade == 0) {
        !           678:                /*
        !           679:                 * Queue the node up -- any unmade predecessors will
        !           680:                 * be dealt with in MakeStartJobs.
        !           681:                 */
        !           682:                (void)Lst_EnQueue (toBeMade, (ClientData)pgn);
        !           683:            } else if (pgn->unmade < 0) {
        !           684:                Error ("Graph cycles through %s", pgn->name);
1.1       cgd       685:            }
                    686:        }
1.47    ! pk        687:        Lst_Close (parents);
1.1       cgd       688:     }
                    689:     /*
                    690:      * Deal with successor nodes. If any is marked for making and has an unmade
                    691:      * count of 0, has not been made and isn't in the examination queue,
                    692:      * it means we need to place it in the queue as it restrained itself
                    693:      * before.
                    694:      */
                    695:     for (ln = Lst_First(cgn->successors); ln != NILLNODE; ln = Lst_Succ(ln)) {
                    696:        GNode   *succ = (GNode *)Lst_Datum(ln);
                    697:
1.22      christos  698:        if ((succ->flags & REMAKE) && succ->unmade == 0 && succ->made == UNMADE &&
1.1       cgd       699:            Lst_Member(toBeMade, (ClientData)succ) == NILLNODE)
                    700:        {
                    701:            (void)Lst_EnQueue(toBeMade, (ClientData)succ);
                    702:        }
                    703:     }
1.10      christos  704:
1.1       cgd       705:     /*
                    706:      * Set the .PREFIX and .IMPSRC variables for all the implied parents
                    707:      * of this node.
                    708:      */
                    709:     if (Lst_Open (cgn->iParents) == SUCCESS) {
1.5       jtc       710:        char    *cpref = Var_Value(PREFIX, cgn, &p1);
1.1       cgd       711:
                    712:        while ((ln = Lst_Next (cgn->iParents)) != NILLNODE) {
                    713:            pgn = (GNode *)Lst_Datum (ln);
1.22      christos  714:            if (pgn->flags & REMAKE) {
1.38      sjg       715:                Var_Set (IMPSRC, cname, pgn, 0);
1.35      christos  716:                if (cpref != NULL)
1.38      sjg       717:                    Var_Set (PREFIX, cpref, pgn, 0);
1.1       cgd       718:            }
                    719:        }
1.5       jtc       720:        if (p1)
                    721:            free(p1);
1.1       cgd       722:        Lst_Close (cgn->iParents);
                    723:     }
                    724: }
                    725: 
                    726: /*-
                    727:  *-----------------------------------------------------------------------
                    728:  * MakeAddAllSrc --
                    729:  *     Add a child's name to the ALLSRC and OODATE variables of the given
                    730:  *     node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
                    731:  *     if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
                    732:  *     .EXEC and .USE children are very rarely going to be files, so...
1.45      pk        733:  *     If the child is a .JOIN node, its ALLSRC is propagated to the parent.
                    734:  *
1.1       cgd       735:  *     A child is added to the OODATE variable if its modification time is
                    736:  *     later than that of its parent, as defined by Make, except if the
                    737:  *     parent is a .JOIN node. In that case, it is only added to the OODATE
                    738:  *     variable if it was actually made (since .JOIN nodes don't have
                    739:  *     modification times, the comparison is rather unfair...)..
                    740:  *
                    741:  * Results:
                    742:  *     Always returns 0
                    743:  *
                    744:  * Side Effects:
                    745:  *     The ALLSRC variable for the given node is extended.
                    746:  *-----------------------------------------------------------------------
                    747:  */
                    748: static int
1.31      mycroft   749: MakeUnmark (cgnp, pgnp)
                    750:     ClientData cgnp;
                    751:     ClientData pgnp;
                    752: {
                    753:     GNode      *cgn = (GNode *) cgnp;
                    754:
                    755:     cgn->type &= ~OP_MARK;
                    756:     return (0);
                    757: }
                    758:
                    759: static int
1.5       jtc       760: MakeAddAllSrc (cgnp, pgnp)
                    761:     ClientData cgnp;   /* The child to add */
                    762:     ClientData pgnp;   /* The parent to whose ALLSRC variable it should be */
1.1       cgd       763:                        /* added */
                    764: {
1.5       jtc       765:     GNode      *cgn = (GNode *) cgnp;
                    766:     GNode      *pgn = (GNode *) pgnp;
1.31      mycroft   767:
                    768:     if (cgn->type & OP_MARK)
                    769:        return (0);
                    770:     cgn->type |= OP_MARK;
                    771:
1.39      christos  772:     if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) {
1.45      pk        773:        char *child, *allsrc;
                    774:        char *p1 = NULL, *p2 = NULL;
1.1       cgd       775:
1.17      christos  776:        if (cgn->type & OP_ARCHV)
                    777:            child = Var_Value (MEMBER, cgn, &p1);
                    778:        else
                    779:            child = cgn->path ? cgn->path : cgn->name;
1.45      pk        780:        if (cgn->type & OP_JOIN) {
                    781:            allsrc = Var_Value (ALLSRC, cgn, &p2);
                    782:        } else {
                    783:            allsrc = child;
                    784:        }
1.46      pk        785:        if (allsrc != NULL)
                    786:                Var_Append (ALLSRC, allsrc, pgn);
1.45      pk        787:        if (p2)
                    788:            free(p2);
1.1       cgd       789:        if (pgn->type & OP_JOIN) {
                    790:            if (cgn->made == MADE) {
                    791:                Var_Append(OODATE, child, pgn);
                    792:            }
                    793:        } else if ((pgn->mtime < cgn->mtime) ||
                    794:                   (cgn->mtime >= now && cgn->made == MADE))
                    795:        {
                    796:            /*
                    797:             * It goes in the OODATE variable if the parent is younger than the
                    798:             * child or if the child has been modified more recently than
                    799:             * the start of the make. This is to keep pmake from getting
                    800:             * confused if something else updates the parent after the
                    801:             * make starts (shouldn't happen, I know, but sometimes it
                    802:             * does). In such a case, if we've updated the kid, the parent
                    803:             * is likely to have a modification time later than that of
                    804:             * the kid and anything that relies on the OODATE variable will
                    805:             * be hosed.
                    806:             *
                    807:             * XXX: This will cause all made children to go in the OODATE
                    808:             * variable, even if they're not touched, if RECHECK isn't defined,
                    809:             * since cgn->mtime is set to now in Make_Update. According to
                    810:             * some people, this is good...
                    811:             */
                    812:            Var_Append(OODATE, child, pgn);
                    813:        }
1.5       jtc       814:        if (p1)
                    815:            free(p1);
1.1       cgd       816:     }
                    817:     return (0);
                    818: }
                    819: 
                    820: /*-
                    821:  *-----------------------------------------------------------------------
                    822:  * Make_DoAllVar --
                    823:  *     Set up the ALLSRC and OODATE variables. Sad to say, it must be
                    824:  *     done separately, rather than while traversing the graph. This is
                    825:  *     because Make defined OODATE to contain all sources whose modification
                    826:  *     times were later than that of the target, *not* those sources that
                    827:  *     were out-of-date. Since in both compatibility and native modes,
                    828:  *     the modification time of the parent isn't found until the child
                    829:  *     has been dealt with, we have to wait until now to fill in the
                    830:  *     variable. As for ALLSRC, the ordering is important and not
                    831:  *     guaranteed when in native mode, so it must be set here, too.
                    832:  *
                    833:  * Results:
                    834:  *     None
                    835:  *
                    836:  * Side Effects:
                    837:  *     The ALLSRC and OODATE variables of the given node is filled in.
                    838:  *     If the node is a .JOIN node, its TARGET variable will be set to
                    839:  *     match its ALLSRC variable.
                    840:  *-----------------------------------------------------------------------
                    841:  */
                    842: void
                    843: Make_DoAllVar (gn)
                    844:     GNode      *gn;
                    845: {
1.31      mycroft   846:     Lst_ForEach (gn->children, MakeUnmark, (ClientData) gn);
1.5       jtc       847:     Lst_ForEach (gn->children, MakeAddAllSrc, (ClientData) gn);
1.1       cgd       848:
                    849:     if (!Var_Exists (OODATE, gn)) {
1.38      sjg       850:        Var_Set (OODATE, "", gn, 0);
1.1       cgd       851:     }
                    852:     if (!Var_Exists (ALLSRC, gn)) {
1.38      sjg       853:        Var_Set (ALLSRC, "", gn, 0);
1.1       cgd       854:     }
                    855:
                    856:     if (gn->type & OP_JOIN) {
1.5       jtc       857:        char *p1;
1.38      sjg       858:        Var_Set (TARGET, Var_Value (ALLSRC, gn, &p1), gn, 0);
1.5       jtc       859:        if (p1)
                    860:            free(p1);
1.1       cgd       861:     }
                    862: }
                    863: 
                    864: /*-
                    865:  *-----------------------------------------------------------------------
                    866:  * MakeStartJobs --
                    867:  *     Start as many jobs as possible.
                    868:  *
                    869:  * Results:
                    870:  *     If the query flag was given to pmake, no job will be started,
                    871:  *     but as soon as an out-of-date target is found, this function
                    872:  *     returns TRUE. At all other times, this function returns FALSE.
                    873:  *
                    874:  * Side Effects:
                    875:  *     Nodes are removed from the toBeMade queue and job table slots
                    876:  *     are filled.
                    877:  *
                    878:  *-----------------------------------------------------------------------
                    879:  */
                    880: static Boolean
                    881: MakeStartJobs ()
                    882: {
1.44      pk        883:     GNode      *gn;
1.10      christos  884:
1.32      sommerfe  885:     while (!Lst_IsEmpty (toBeMade)) {
1.1       cgd       886:        gn = (GNode *) Lst_DeQueue (toBeMade);
                    887:        if (DEBUG(MAKE)) {
                    888:            printf ("Examining %s...", gn->name);
                    889:        }
                    890:        /*
                    891:         * Make sure any and all predecessors that are going to be made,
                    892:         * have been.
                    893:         */
                    894:        if (!Lst_IsEmpty(gn->preds)) {
                    895:            LstNode ln;
                    896:
                    897:            for (ln = Lst_First(gn->preds); ln != NILLNODE; ln = Lst_Succ(ln)){
                    898:                GNode   *pgn = (GNode *)Lst_Datum(ln);
                    899:
1.22      christos  900:                if ((pgn->flags & REMAKE) && pgn->made == UNMADE) {
1.1       cgd       901:                    if (DEBUG(MAKE)) {
                    902:                        printf("predecessor %s not made yet.\n", pgn->name);
                    903:                    }
                    904:                    break;
                    905:                }
                    906:            }
                    907:            /*
                    908:             * If ln isn't nil, there's a predecessor as yet unmade, so we
                    909:             * just drop this node on the floor. When the node in question
                    910:             * has been made, it will notice this node as being ready to
                    911:             * make but as yet unmade and will place the node on the queue.
                    912:             */
                    913:            if (ln != NILLNODE) {
                    914:                continue;
                    915:            }
                    916:        }
1.10      christos  917:
1.32      sommerfe  918:        if (!Job_TokenWithdraw()) {
                    919:            Lst_AtFront(toBeMade, gn);
                    920:            break;
                    921:        }
                    922:
1.1       cgd       923:        numNodes--;
                    924:        if (Make_OODate (gn)) {
                    925:            if (DEBUG(MAKE)) {
                    926:                printf ("out-of-date\n");
                    927:            }
                    928:            if (queryFlag) {
                    929:                return (TRUE);
                    930:            }
                    931:            Make_DoAllVar (gn);
                    932:            Job_Make (gn);
                    933:        } else {
                    934:            if (DEBUG(MAKE)) {
                    935:                printf ("up-to-date\n");
                    936:            }
                    937:            gn->made = UPTODATE;
                    938:            if (gn->type & OP_JOIN) {
                    939:                /*
                    940:                 * Even for an up-to-date .JOIN node, we need it to have its
                    941:                 * context variables so references to it get the correct
                    942:                 * value for .TARGET when building up the context variables
                    943:                 * of its parent(s)...
                    944:                 */
                    945:                Make_DoAllVar (gn);
                    946:            }
1.33      sommerfe  947:            Job_TokenReturn();
1.1       cgd       948:            Make_Update (gn);
                    949:        }
                    950:     }
                    951:     return (FALSE);
                    952: }
                    953: 
                    954: /*-
                    955:  *-----------------------------------------------------------------------
                    956:  * MakePrintStatus --
                    957:  *     Print the status of a top-level node, viz. it being up-to-date
                    958:  *     already or not created due to an error in a lower level.
                    959:  *     Callback function for Make_Run via Lst_ForEach.
                    960:  *
                    961:  * Results:
                    962:  *     Always returns 0.
                    963:  *
                    964:  * Side Effects:
                    965:  *     A message may be printed.
                    966:  *
                    967:  *-----------------------------------------------------------------------
                    968:  */
                    969: static int
1.5       jtc       970: MakePrintStatus(gnp, cyclep)
                    971:     ClientData  gnp;       /* Node to examine */
                    972:     ClientData         cyclep;     /* True if gn->unmade being non-zero implies
1.1       cgd       973:                             * a cycle in the graph, not an error in an
                    974:                             * inferior */
                    975: {
1.5       jtc       976:     GNode      *gn = (GNode *) gnp;
                    977:     Boolean    cycle = *(Boolean *) cyclep;
1.1       cgd       978:     if (gn->made == UPTODATE) {
                    979:        printf ("`%s' is up to date.\n", gn->name);
                    980:     } else if (gn->unmade != 0) {
                    981:        if (cycle) {
1.5       jtc       982:            Boolean t = TRUE;
1.1       cgd       983:            /*
                    984:             * If printing cycles and came to one that has unmade children,
                    985:             * print out the cycle by recursing on its children. Note a
                    986:             * cycle like:
                    987:             *  a : b
                    988:             *  b : c
                    989:             *  c : b
                    990:             * will cause this to erroneously complain about a being in
                    991:             * the cycle, but this is a good approximation.
                    992:             */
                    993:            if (gn->made == CYCLE) {
                    994:                Error("Graph cycles through `%s'", gn->name);
                    995:                gn->made = ENDCYCLE;
1.5       jtc       996:                Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t);
1.1       cgd       997:                gn->made = UNMADE;
                    998:            } else if (gn->made != ENDCYCLE) {
                    999:                gn->made = CYCLE;
1.5       jtc      1000:                Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t);
1.1       cgd      1001:            }
                   1002:        } else {
                   1003:            printf ("`%s' not remade because of errors.\n", gn->name);
                   1004:        }
                   1005:     }
                   1006:     return (0);
                   1007: }
                   1008: 
1.11      christos 1009:
1.1       cgd      1010: /*-
                   1011:  *-----------------------------------------------------------------------
1.11      christos 1012:  * Make_ExpandUse --
                   1013:  *     Expand .USE nodes and create a new targets list
1.1       cgd      1014:  * Results:
1.11      christos 1015:  *     The new list of targets.
1.1       cgd      1016:  *
                   1017:  * Side Effects:
1.11      christos 1018:  *     numNodes is set to the number of elements in the list of targets.
1.1       cgd      1019:  *-----------------------------------------------------------------------
                   1020:  */
1.11      christos 1021: Lst
                   1022: Make_ExpandUse (targs)
1.1       cgd      1023:     Lst             targs;     /* the initial list of targets */
                   1024: {
1.44      pk       1025:     GNode  *gn;                /* a temporary pointer */
                   1026:     Lst    examine;    /* List of targets to examine */
                   1027:     Lst    ntargs;     /* List of new targets to be made */
1.1       cgd      1028:
1.11      christos 1029:     ntargs = Lst_Init (FALSE);
1.1       cgd      1030:
                   1031:     examine = Lst_Duplicate(targs, NOCOPY);
                   1032:     numNodes = 0;
1.10      christos 1033:
1.1       cgd      1034:     /*
                   1035:      * Make an initial downward pass over the graph, marking nodes to be made
                   1036:      * as we go down. We call Suff_FindDeps to find where a node is and
                   1037:      * to get some children for it if it has none and also has no commands.
                   1038:      * If the node is a leaf, we stick it on the toBeMade queue to
                   1039:      * be looked at in a minute, otherwise we add its children to our queue
1.10      christos 1040:      * and go on about our business.
1.1       cgd      1041:      */
                   1042:     while (!Lst_IsEmpty (examine)) {
                   1043:        gn = (GNode *) Lst_DeQueue (examine);
1.10      christos 1044:
1.24      mycroft  1045:        if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) {
1.23      mycroft  1046:            Lst new;
                   1047:            new = Lst_Duplicate (gn->cohorts, NOCOPY);
                   1048:            Lst_Concat (new, examine, LST_CONCLINK);
                   1049:            examine = new;
                   1050:        }
                   1051:
1.22      christos 1052:        if ((gn->flags & REMAKE) == 0) {
                   1053:            gn->flags |= REMAKE;
1.1       cgd      1054:            numNodes++;
1.10      christos 1055:
1.1       cgd      1056:            /*
                   1057:             * Apply any .USE rules before looking for implicit dependencies
                   1058:             * to make sure everything has commands that should...
1.11      christos 1059:             * Make sure that the TARGET is set, so that we can make
                   1060:             * expansions.
1.1       cgd      1061:             */
1.17      christos 1062:            if (gn->type & OP_ARCHV) {
                   1063:                char *eoa, *eon;
                   1064:                eoa = strchr(gn->name, '(');
                   1065:                eon = strchr(gn->name, ')');
                   1066:                if (eoa == NULL || eon == NULL)
                   1067:                    continue;
                   1068:                *eoa = '\0';
                   1069:                *eon = '\0';
1.38      sjg      1070:                Var_Set (MEMBER, eoa + 1, gn, 0);
                   1071:                Var_Set (ARCHIVE, gn->name, gn, 0);
1.17      christos 1072:                *eoa = '(';
                   1073:                *eon = ')';
                   1074:            }
                   1075:
1.22      christos 1076:            (void)Dir_MTime(gn);
1.38      sjg      1077:            Var_Set (TARGET, gn->path ? gn->path : gn->name, gn, 0);
1.31      mycroft  1078:            Lst_ForEach (gn->children, MakeUnmark, (ClientData)gn);
1.5       jtc      1079:            Lst_ForEach (gn->children, MakeHandleUse, (ClientData)gn);
1.42      pk       1080:
1.41      pk       1081:            if ((gn->type & OP_MADE) == 0)
                   1082:                Suff_FindDeps (gn);
1.42      pk       1083:            else {
                   1084:                /* Pretend we made all this node's children */
                   1085:                Lst_ForEach (gn->children, MakeFindChild, (ClientData)gn);
                   1086:                if (gn->unmade != 0)
                   1087:                        printf("Warning: %s still has %d unmade children\n",
                   1088:                                gn->name, gn->unmade);
                   1089:            }
1.1       cgd      1090:
1.42      pk       1091:            if (gn->unmade != 0) {
1.1       cgd      1092:                Lst_ForEach (gn->children, MakeAddChild, (ClientData)examine);
                   1093:            } else {
1.11      christos 1094:                (void)Lst_EnQueue (ntargs, (ClientData)gn);
1.1       cgd      1095:            }
                   1096:        }
                   1097:     }
1.10      christos 1098:
1.1       cgd      1099:     Lst_Destroy (examine, NOFREE);
1.11      christos 1100:     return ntargs;
                   1101: }
                   1102:
                   1103: /*-
                   1104:  *-----------------------------------------------------------------------
                   1105:  * Make_Run --
                   1106:  *     Initialize the nodes to remake and the list of nodes which are
                   1107:  *     ready to be made by doing a breadth-first traversal of the graph
                   1108:  *     starting from the nodes in the given list. Once this traversal
                   1109:  *     is finished, all the 'leaves' of the graph are in the toBeMade
                   1110:  *     queue.
                   1111:  *     Using this queue and the Job module, work back up the graph,
                   1112:  *     calling on MakeStartJobs to keep the job table as full as
                   1113:  *     possible.
                   1114:  *
                   1115:  * Results:
                   1116:  *     TRUE if work was done. FALSE otherwise.
                   1117:  *
                   1118:  * Side Effects:
                   1119:  *     The make field of all nodes involved in the creation of the given
                   1120:  *     targets is set to 1. The toBeMade list is set to contain all the
                   1121:  *     'leaves' of these subgraphs.
                   1122:  *-----------------------------------------------------------------------
                   1123:  */
                   1124: Boolean
                   1125: Make_Run (targs)
                   1126:     Lst             targs;     /* the initial list of targets */
                   1127: {
                   1128:     int                    errors;     /* Number of errors the Job module reports */
                   1129:
                   1130:     toBeMade = Make_ExpandUse (targs);
1.1       cgd      1131:
                   1132:     if (queryFlag) {
                   1133:        /*
                   1134:         * We wouldn't do any work unless we could start some jobs in the
                   1135:         * next loop... (we won't actually start any, of course, this is just
                   1136:         * to see if any of the targets was out of date)
                   1137:         */
                   1138:        return (MakeStartJobs());
                   1139:     } else {
                   1140:        /*
                   1141:         * Initialization. At the moment, no jobs are running and until some
                   1142:         * get started, nothing will happen since the remaining upward
                   1143:         * traversal of the graph is performed by the routines in job.c upon
                   1144:         * the finishing of a job. So we fill the Job table as much as we can
1.10      christos 1145:         * before going into our loop.
1.1       cgd      1146:         */
                   1147:        (void) MakeStartJobs();
                   1148:     }
                   1149:
                   1150:     /*
                   1151:      * Main Loop: The idea here is that the ending of jobs will take
                   1152:      * care of the maintenance of data structures and the waiting for output
                   1153:      * will cause us to be idle most of the time while our children run as
                   1154:      * much as possible. Because the job table is kept as full as possible,
                   1155:      * the only time when it will be empty is when all the jobs which need
                   1156:      * running have been run, so that is the end condition of this loop.
                   1157:      * Note that the Job module will exit if there were any errors unless the
                   1158:      * keepgoing flag was given.
                   1159:      */
1.32      sommerfe 1160:     while (!Lst_IsEmpty(toBeMade) || !Job_Empty ()) {
1.1       cgd      1161:        Job_CatchOutput ();
                   1162:        Job_CatchChildren (!usePipes);
                   1163:        (void)MakeStartJobs();
                   1164:     }
                   1165:
1.20      christos 1166:     errors = Job_Finish();
1.1       cgd      1167:
                   1168:     /*
                   1169:      * Print the final status of each target. E.g. if it wasn't made
                   1170:      * because some inferior reported an error.
                   1171:      */
1.5       jtc      1172:     errors = ((errors == 0) && (numNodes != 0));
                   1173:     Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors);
1.10      christos 1174:
1.1       cgd      1175:     return (TRUE);
                   1176: }

CVSweb <webmaster@jp.NetBSD.org>