Annotation of 43BSDReno/usr.bin/make/targ.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
        !             3:  * Copyright (c) 1988, 1989 by Adam de Boor
        !             4:  * Copyright (c) 1989 by Berkeley Softworks
        !             5:  * All rights reserved.
        !             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 are permitted
        !            11:  * provided that: (1) source distributions retain this entire copyright
        !            12:  * notice and comment, and (2) distributions including binaries display
        !            13:  * the following acknowledgement:  ``This product includes software
        !            14:  * developed by the University of California, Berkeley and its contributors''
        !            15:  * in the documentation or other materials provided with the distribution
        !            16:  * and in all advertising materials mentioning features or use of this
        !            17:  * software. Neither the name of the University nor the names of its
        !            18:  * contributors may be used to endorse or promote products derived
        !            19:  * from this software without specific prior written permission.
        !            20:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            21:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            22:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            23:  */
        !            24: 
        !            25: #ifndef lint
        !            26: static char sccsid[] = "@(#)targ.c     5.7 (Berkeley) 6/1/90";
        !            27: #endif /* not lint */
        !            28: 
        !            29: /*-
        !            30:  * targ.c --
        !            31:  *     Functions for maintaining the Lst allTargets. Target nodes are
        !            32:  * kept in two structures: a Lst, maintained by the list library, and a
        !            33:  * hash table, maintained by the hash library.
        !            34:  *
        !            35:  * Interface:
        !            36:  *     Targ_Init               Initialization procedure.
        !            37:  *
        !            38:  *     Targ_NewGN              Create a new GNode for the passed target
        !            39:  *                             (string). The node is *not* placed in the
        !            40:  *                             hash table, though all its fields are
        !            41:  *                             initialized.
        !            42:  *
        !            43:  *     Targ_FindNode           Find the node for a given target, creating
        !            44:  *                             and storing it if it doesn't exist and the
        !            45:  *                             flags are right (TARG_CREATE)
        !            46:  *
        !            47:  *     Targ_FindList           Given a list of names, find nodes for all
        !            48:  *                             of them. If a name doesn't exist and the
        !            49:  *                             TARG_NOCREATE flag was given, an error message
        !            50:  *                             is printed. Else, if a name doesn't exist,
        !            51:  *                             its node is created.
        !            52:  *
        !            53:  *     Targ_Ignore             Return TRUE if errors should be ignored when
        !            54:  *                             creating the given target.
        !            55:  *
        !            56:  *     Targ_Silent             Return TRUE if we should be silent when
        !            57:  *                             creating the given target.
        !            58:  *
        !            59:  *     Targ_Precious           Return TRUE if the target is precious and
        !            60:  *                             should not be removed if we are interrupted.
        !            61:  *
        !            62:  * Debugging:
        !            63:  *     Targ_PrintGraph         Print out the entire graphm all variables
        !            64:  *                             and statistics for the directory cache. Should
        !            65:  *                             print something for suffixes, too, but...
        !            66:  */
        !            67: 
        !            68: #include         <stdio.h>
        !            69: #include         <time.h>
        !            70: #include         "make.h"
        !            71: #include         "hash.h"
        !            72: 
        !            73: static Lst        allTargets;  /* the list of all targets found so far */
        !            74: static Hash_Table targets;     /* a hash table of same */
        !            75: 
        !            76: #define HTSIZE 191             /* initial size of hash table */
        !            77: 
        !            78: /*-
        !            79:  *-----------------------------------------------------------------------
        !            80:  * Targ_Init --
        !            81:  *     Initialize this module
        !            82:  *
        !            83:  * Results:
        !            84:  *     None
        !            85:  *
        !            86:  * Side Effects:
        !            87:  *     The allTargets list and the targets hash table are initialized
        !            88:  *-----------------------------------------------------------------------
        !            89:  */
        !            90: void
        !            91: Targ_Init ()
        !            92: {
        !            93:     allTargets = Lst_Init (FALSE);
        !            94:     Hash_InitTable (&targets, HTSIZE, HASH_STRING_KEYS);
        !            95: }
        !            96: 
        !            97: /*-
        !            98:  *-----------------------------------------------------------------------
        !            99:  * Targ_NewGN  --
        !           100:  *     Create and initialize a new graph node
        !           101:  *
        !           102:  * Results:
        !           103:  *     An initialized graph node with the name field filled with a copy
        !           104:  *     of the passed name
        !           105:  *
        !           106:  * Side Effects:
        !           107:  *     None.
        !           108:  *-----------------------------------------------------------------------
        !           109:  */
        !           110: GNode *
        !           111: Targ_NewGN (name)
        !           112:     char           *name;      /* the name to stick in the new node */
        !           113: {
        !           114:     register GNode *gn;
        !           115: 
        !           116:     gn = (GNode *) emalloc (sizeof (GNode));
        !           117:     gn->name = strdup (name);
        !           118:     gn->path = (char *) 0;
        !           119:     if (name[0] == '-' && name[1] == 'l') {
        !           120:        gn->type = OP_LIB;
        !           121:     } else {
        !           122:        gn->type = 0;
        !           123:     }
        !           124:     gn->unmade =       0;
        !           125:     gn->make =                 FALSE;
        !           126:     gn->made =                 UNMADE;
        !           127:     gn->childMade =    FALSE;
        !           128:     gn->mtime = gn->cmtime = 0;
        !           129:     gn->iParents =     Lst_Init (FALSE);
        !           130:     gn->cohorts =      Lst_Init (FALSE);
        !           131:     gn->parents =      Lst_Init (FALSE);
        !           132:     gn->children =     Lst_Init (FALSE);
        !           133:     gn->successors =   Lst_Init(FALSE);
        !           134:     gn->preds =        Lst_Init(FALSE);
        !           135:     gn->context =      Lst_Init (FALSE);
        !           136:     gn->commands =     Lst_Init (FALSE);
        !           137: 
        !           138:     return (gn);
        !           139: }
        !           140: 
        !           141: /*-
        !           142:  *-----------------------------------------------------------------------
        !           143:  * Targ_FindNode  --
        !           144:  *     Find a node in the list using the given name for matching
        !           145:  *
        !           146:  * Results:
        !           147:  *     The node in the list if it was. If it wasn't, return NILGNODE of
        !           148:  *     flags was TARG_NOCREATE or the newly created and initialized node
        !           149:  *     if it was TARG_CREATE
        !           150:  *
        !           151:  * Side Effects:
        !           152:  *     Sometimes a node is created and added to the list
        !           153:  *-----------------------------------------------------------------------
        !           154:  */
        !           155: GNode *
        !           156: Targ_FindNode (name, flags)
        !           157:     char           *name;      /* the name to find */
        !           158:     int             flags;     /* flags governing events when target not
        !           159:                                 * found */
        !           160: {
        !           161:     GNode         *gn;       /* node in that element */
        !           162:     Hash_Entry   *he;        /* New or used hash entry for node */
        !           163:     Boolean      isNew;      /* Set TRUE if Hash_CreateEntry had to create */
        !           164:                              /* an entry for the node */
        !           165: 
        !           166: 
        !           167:     if (flags & TARG_CREATE) {
        !           168:        he = Hash_CreateEntry (&targets, name, &isNew);
        !           169:        if (isNew) {
        !           170:            gn = Targ_NewGN (name);
        !           171:            Hash_SetValue (he, gn);
        !           172:            (void) Lst_AtEnd (allTargets, (ClientData)gn);
        !           173:        }
        !           174:     } else {
        !           175:        he = Hash_FindEntry (&targets, name);
        !           176:     }
        !           177: 
        !           178:     if (he == (Hash_Entry *) NULL) {
        !           179:        return (NILGNODE);
        !           180:     } else {
        !           181:        return ((GNode *) Hash_GetValue (he));
        !           182:     }
        !           183: }
        !           184: 
        !           185: /*-
        !           186:  *-----------------------------------------------------------------------
        !           187:  * Targ_FindList --
        !           188:  *     Make a complete list of GNodes from the given list of names 
        !           189:  *
        !           190:  * Results:
        !           191:  *     A complete list of graph nodes corresponding to all instances of all
        !           192:  *     the names in names. 
        !           193:  *
        !           194:  * Side Effects:
        !           195:  *     If flags is TARG_CREATE, nodes will be created for all names in
        !           196:  *     names which do not yet have graph nodes. If flags is TARG_NOCREATE,
        !           197:  *     an error message will be printed for each name which can't be found.
        !           198:  * -----------------------------------------------------------------------
        !           199:  */
        !           200: Lst
        !           201: Targ_FindList (names, flags)
        !           202:     Lst                   names;       /* list of names to find */
        !           203:     int            flags;      /* flags used if no node is found for a given
        !           204:                                 * name */
        !           205: {
        !           206:     Lst            nodes;      /* result list */
        !           207:     register LstNode  ln;              /* name list element */
        !           208:     register GNode *gn;                /* node in tLn */
        !           209:     char         *name;
        !           210: 
        !           211:     nodes = Lst_Init (FALSE);
        !           212: 
        !           213:     if (Lst_Open (names) == FAILURE) {
        !           214:        return (nodes);
        !           215:     }
        !           216:     while ((ln = Lst_Next (names)) != NILLNODE) {
        !           217:        name = (char *)Lst_Datum(ln);
        !           218:        gn = Targ_FindNode (name, flags);
        !           219:        if (gn != NILGNODE) {
        !           220:            /*
        !           221:             * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
        !           222:             * are added to the list in the order in which they were
        !           223:             * encountered in the makefile.
        !           224:             */
        !           225:            (void) Lst_AtEnd (nodes, (ClientData)gn);
        !           226:            if (gn->type & OP_DOUBLEDEP) {
        !           227:                (void)Lst_Concat (nodes, gn->cohorts, LST_CONCNEW);
        !           228:            }
        !           229:        } else if (flags == TARG_NOCREATE) {
        !           230:            Error ("\"%s\" -- target unknown.", name);
        !           231:        }
        !           232:     }
        !           233:     Lst_Close (names);
        !           234:     return (nodes);
        !           235: }
        !           236: 
        !           237: /*-
        !           238:  *-----------------------------------------------------------------------
        !           239:  * Targ_Ignore  --
        !           240:  *     Return true if should ignore errors when creating gn
        !           241:  *
        !           242:  * Results:
        !           243:  *     TRUE if should ignore errors
        !           244:  *
        !           245:  * Side Effects:
        !           246:  *     None
        !           247:  *-----------------------------------------------------------------------
        !           248:  */
        !           249: Boolean
        !           250: Targ_Ignore (gn)
        !           251:     GNode          *gn;                /* node to check for */
        !           252: {
        !           253:     if (ignoreErrors || gn->type & OP_IGNORE) {
        !           254:        return (TRUE);
        !           255:     } else {
        !           256:        return (FALSE);
        !           257:     }
        !           258: }
        !           259: 
        !           260: /*-
        !           261:  *-----------------------------------------------------------------------
        !           262:  * Targ_Silent  --
        !           263:  *     Return true if be silent when creating gn
        !           264:  *
        !           265:  * Results:
        !           266:  *     TRUE if should be silent
        !           267:  *
        !           268:  * Side Effects:
        !           269:  *     None
        !           270:  *-----------------------------------------------------------------------
        !           271:  */
        !           272: Boolean
        !           273: Targ_Silent (gn)
        !           274:     GNode          *gn;                /* node to check for */
        !           275: {
        !           276:     if (beSilent || gn->type & OP_SILENT) {
        !           277:        return (TRUE);
        !           278:     } else {
        !           279:        return (FALSE);
        !           280:     }
        !           281: }
        !           282: 
        !           283: /*-
        !           284:  *-----------------------------------------------------------------------
        !           285:  * Targ_Precious --
        !           286:  *     See if the given target is precious
        !           287:  *
        !           288:  * Results:
        !           289:  *     TRUE if it is precious. FALSE otherwise
        !           290:  *
        !           291:  * Side Effects:
        !           292:  *     None
        !           293:  *-----------------------------------------------------------------------
        !           294:  */
        !           295: Boolean
        !           296: Targ_Precious (gn)
        !           297:     GNode          *gn;                /* the node to check */
        !           298: {
        !           299:     if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) {
        !           300:        return (TRUE);
        !           301:     } else {
        !           302:        return (FALSE);
        !           303:     }
        !           304: }
        !           305: 
        !           306: /******************* DEBUG INFO PRINTING ****************/
        !           307: 
        !           308: static GNode     *mainTarg;    /* the main target, as set by Targ_SetMain */
        !           309: /*- 
        !           310:  *-----------------------------------------------------------------------
        !           311:  * Targ_SetMain --
        !           312:  *     Set our idea of the main target we'll be creating. Used for
        !           313:  *     debugging output.
        !           314:  *
        !           315:  * Results:
        !           316:  *     None.
        !           317:  *
        !           318:  * Side Effects:
        !           319:  *     "mainTarg" is set to the main target's node.
        !           320:  *-----------------------------------------------------------------------
        !           321:  */
        !           322: void
        !           323: Targ_SetMain (gn)
        !           324:     GNode   *gn;       /* The main target we'll create */
        !           325: {
        !           326:     mainTarg = gn;
        !           327: }
        !           328: 
        !           329: static int
        !           330: TargPrintName (gn, ppath)
        !           331:     GNode          *gn;
        !           332:     int                    ppath;
        !           333: {
        !           334:     printf ("%s ", gn->name);
        !           335: #ifdef notdef
        !           336:     if (ppath) {
        !           337:        if (gn->path) {
        !           338:            printf ("[%s]  ", gn->path);
        !           339:        }
        !           340:        if (gn == mainTarg) {
        !           341:            printf ("(MAIN NAME)  ");
        !           342:        }
        !           343:     }
        !           344: #endif notdef
        !           345:     return (0);
        !           346: }
        !           347: 
        !           348: 
        !           349: int
        !           350: Targ_PrintCmd (cmd)
        !           351:     char           *cmd;
        !           352: {
        !           353:     printf ("\t%s\n", cmd);
        !           354:     return (0);
        !           355: }
        !           356: 
        !           357: /*-
        !           358:  *-----------------------------------------------------------------------
        !           359:  * Targ_FmtTime --
        !           360:  *     Format a modification time in some reasonable way and return it.
        !           361:  *
        !           362:  * Results:
        !           363:  *     The time reformatted.
        !           364:  *
        !           365:  * Side Effects:
        !           366:  *     The time is placed in a static area, so it is overwritten
        !           367:  *     with each call.
        !           368:  *
        !           369:  *-----------------------------------------------------------------------
        !           370:  */
        !           371: char *
        !           372: Targ_FmtTime (time)
        !           373:     int    time;
        !           374: {
        !           375:     struct tm          *parts;
        !           376:     static char                buf[40];
        !           377:     static char                *months[] = {
        !           378:        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        !           379:        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        !           380:     };
        !           381: 
        !           382:     parts = localtime(&time);
        !           383: 
        !           384:     sprintf (buf, "%d:%02d:%02d %s %d, 19%d",
        !           385:             parts->tm_hour, parts->tm_min, parts->tm_sec,
        !           386:             months[parts->tm_mon], parts->tm_mday, parts->tm_year);
        !           387:     return(buf);
        !           388: }
        !           389:     
        !           390: /*-
        !           391:  *-----------------------------------------------------------------------
        !           392:  * Targ_PrintType --
        !           393:  *     Print out a type field giving only those attributes the user can
        !           394:  *     set.
        !           395:  *
        !           396:  * Results:
        !           397:  *
        !           398:  * Side Effects:
        !           399:  *
        !           400:  *-----------------------------------------------------------------------
        !           401:  */
        !           402: void
        !           403: Targ_PrintType (type)
        !           404:     register int    type;
        !           405: {
        !           406:     register int    tbit;
        !           407:     
        !           408: #ifdef __STDC__
        !           409: #define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break
        !           410: #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break
        !           411: #else
        !           412: #define PRINTBIT(attr)         case CONCAT(OP_,attr): printf(".attr "); break
        !           413: #define PRINTDBIT(attr)        case CONCAT(OP_,attr): if (DEBUG(TARG)) printf(".attr "); break
        !           414: #endif /* __STDC__ */
        !           415: 
        !           416:     type &= ~OP_OPMASK;
        !           417: 
        !           418:     while (type) {
        !           419:        tbit = 1 << (ffs(type) - 1);
        !           420:        type &= ~tbit;
        !           421: 
        !           422:        switch(tbit) {
        !           423:            PRINTBIT(OPTIONAL);
        !           424:            PRINTBIT(USE);
        !           425:            PRINTBIT(EXEC);
        !           426:            PRINTBIT(IGNORE);
        !           427:            PRINTBIT(PRECIOUS);
        !           428:            PRINTBIT(SILENT);
        !           429:            PRINTBIT(MAKE);
        !           430:            PRINTBIT(JOIN);
        !           431:            PRINTBIT(INVISIBLE);
        !           432:            PRINTBIT(NOTMAIN);
        !           433:            PRINTDBIT(LIB);
        !           434:            /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
        !           435:            case OP_MEMBER: if (DEBUG(TARG)) printf(".MEMBER "); break;
        !           436:            PRINTDBIT(ARCHV);
        !           437:        }
        !           438:     }
        !           439: }
        !           440: 
        !           441: /*-
        !           442:  *-----------------------------------------------------------------------
        !           443:  * TargPrintNode --
        !           444:  *     print the contents of a node
        !           445:  *-----------------------------------------------------------------------
        !           446:  */
        !           447: static int
        !           448: TargPrintNode (gn, pass)
        !           449:     GNode         *gn;
        !           450:     int                  pass;
        !           451: {
        !           452:     if (!OP_NOP(gn->type)) {
        !           453:        printf("#\n");
        !           454:        if (gn == mainTarg) {
        !           455:            printf("# *** MAIN TARGET ***\n");
        !           456:        }
        !           457:        if (pass == 2) {
        !           458:            if (gn->unmade) {
        !           459:                printf("# %d unmade children\n", gn->unmade);
        !           460:            } else {
        !           461:                printf("# No unmade children\n");
        !           462:            }
        !           463:            if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) {
        !           464:                if (gn->mtime != 0) {
        !           465:                    printf("# last modified %s: %s\n",
        !           466:                              Targ_FmtTime(gn->mtime),
        !           467:                              (gn->made == UNMADE ? "unmade" :
        !           468:                               (gn->made == MADE ? "made" :
        !           469:                                (gn->made == UPTODATE ? "up-to-date" :
        !           470:                                 "error when made"))));
        !           471:                } else if (gn->made != UNMADE) {
        !           472:                    printf("# non-existent (maybe): %s\n",
        !           473:                              (gn->made == MADE ? "made" :
        !           474:                               (gn->made == UPTODATE ? "up-to-date" :
        !           475:                                (gn->made == ERROR ? "error when made" :
        !           476:                                 "aborted"))));
        !           477:                } else {
        !           478:                    printf("# unmade\n");
        !           479:                }
        !           480:            }
        !           481:            if (!Lst_IsEmpty (gn->iParents)) {
        !           482:                printf("# implicit parents: ");
        !           483:                Lst_ForEach (gn->iParents, TargPrintName, (ClientData)0);
        !           484:                putc ('\n', stdout);
        !           485:            }
        !           486:        }
        !           487:        if (!Lst_IsEmpty (gn->parents)) {
        !           488:            printf("# parents: ");
        !           489:            Lst_ForEach (gn->parents, TargPrintName, (ClientData)0);
        !           490:            putc ('\n', stdout);
        !           491:        }
        !           492:        
        !           493:        printf("%-16s", gn->name);
        !           494:        switch (gn->type & OP_OPMASK) {
        !           495:            case OP_DEPENDS:
        !           496:                printf(": "); break;
        !           497:            case OP_FORCE:
        !           498:                printf("! "); break;
        !           499:            case OP_DOUBLEDEP:
        !           500:                printf(":: "); break;
        !           501:        }
        !           502:        Targ_PrintType (gn->type);
        !           503:        Lst_ForEach (gn->children, TargPrintName, (ClientData)0);
        !           504:        putc ('\n', stdout);
        !           505:        Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0);
        !           506:        printf("\n\n");
        !           507:        if (gn->type & OP_DOUBLEDEP) {
        !           508:            Lst_ForEach (gn->cohorts, TargPrintNode, (ClientData)pass);
        !           509:        }
        !           510:     }
        !           511:     return (0);
        !           512: }
        !           513: 
        !           514: /*-
        !           515:  *-----------------------------------------------------------------------
        !           516:  * TargPrintOnlySrc --
        !           517:  *     Print only those targets that are just a source.
        !           518:  *
        !           519:  * Results:
        !           520:  *     0.
        !           521:  *
        !           522:  * Side Effects:
        !           523:  *     The name of each file is printed preceeded by #\t
        !           524:  *
        !           525:  *-----------------------------------------------------------------------
        !           526:  */
        !           527: static int
        !           528: TargPrintOnlySrc(gn)
        !           529:     GNode        *gn;
        !           530: {
        !           531:     if (OP_NOP(gn->type)) {
        !           532:        printf("#\t%s [%s]\n", gn->name,
        !           533:                  gn->path ? gn->path : gn->name);
        !           534:     }
        !           535:     return (0);
        !           536: }
        !           537: 
        !           538: /*-
        !           539:  *-----------------------------------------------------------------------
        !           540:  * Targ_PrintGraph --
        !           541:  *     print the entire graph. heh heh
        !           542:  *
        !           543:  * Results:
        !           544:  *     none
        !           545:  *
        !           546:  * Side Effects:
        !           547:  *     lots o' output
        !           548:  *-----------------------------------------------------------------------
        !           549:  */
        !           550: Targ_PrintGraph (pass)
        !           551:     int            pass;       /* Which pass this is. 1 => no processing
        !           552:                         * 2 => processing done */
        !           553: {
        !           554:     printf("#*** Input graph:\n");
        !           555:     Lst_ForEach (allTargets, TargPrintNode, (ClientData)pass);
        !           556:     printf("\n\n");
        !           557:     printf("#\n#   Files that are only sources:\n");
        !           558:     Lst_ForEach (allTargets, TargPrintOnlySrc);
        !           559:     printf("#*** Global Variables:\n");
        !           560:     Var_Dump (VAR_GLOBAL);
        !           561:     printf("#*** Command-line Variables:\n");
        !           562:     Var_Dump (VAR_CMD);
        !           563:     printf("\n");
        !           564:     Dir_PrintDirectories();
        !           565:     printf("\n");
        !           566:     Suff_PrintAll();
        !           567: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.