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

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

1.84    ! espie       1: /*     $OpenBSD: targ.c,v 1.83 2020/01/13 13:50:41 espie Exp $ */
1.6       millert     2: /*     $NetBSD: targ.c,v 1.11 1997/02/20 16:51:50 christos Exp $       */
1.1       deraadt     3:
                      4: /*
1.31      espie       5:  * Copyright (c) 1999 Marc Espie.
                      6:  *
                      7:  * Extensive code changes for the OpenBSD project.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
                     19:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     20:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
                     21:  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
                     22:  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     23:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
                     24:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     25:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     26:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     27:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     28:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30: /*
1.5       millert    31:  * Copyright (c) 1988, 1989, 1990, 1993
                     32:  *     The Regents of the University of California.  All rights reserved.
1.1       deraadt    33:  * Copyright (c) 1989 by Berkeley Softworks
                     34:  * All rights reserved.
                     35:  *
                     36:  * This code is derived from software contributed to Berkeley by
                     37:  * Adam de Boor.
                     38:  *
                     39:  * Redistribution and use in source and binary forms, with or without
                     40:  * modification, are permitted provided that the following conditions
                     41:  * are met:
                     42:  * 1. Redistributions of source code must retain the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer.
                     44:  * 2. Redistributions in binary form must reproduce the above copyright
                     45:  *    notice, this list of conditions and the following disclaimer in the
                     46:  *    documentation and/or other materials provided with the distribution.
1.38      millert    47:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    48:  *    may be used to endorse or promote products derived from this software
                     49:  *    without specific prior written permission.
                     50:  *
                     51:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     52:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     53:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     54:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     55:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     56:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     57:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     58:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     59:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     60:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     61:  * SUCH DAMAGE.
                     62:  */
                     63:
                     64: /*-
                     65:  * targ.c --
1.27      espie      66:  *             Target nodes are kept into a hash table.
1.1       deraadt    67:  *
                     68:  * Interface:
1.31      espie      69:  *     Targ_Init               Initialization procedure.
1.1       deraadt    70:  *
1.31      espie      71:  *     Targ_NewGN              Create a new GNode for the passed target
                     72:  *                             (string). The node is *not* placed in the
                     73:  *                             hash table, though all its fields are
                     74:  *                             initialized.
1.1       deraadt    75:  *
1.31      espie      76:  *     Targ_FindNode           Find the node for a given target, creating
                     77:  *                             and storing it if it doesn't exist and the
                     78:  *                             flags are right (TARG_CREATE)
1.1       deraadt    79:  *
1.31      espie      80:  *     Targ_FindList           Given a list of names, find nodes for all
                     81:  *                             of them, creating nodes if needed.
1.1       deraadt    82:  *
1.32      espie      83:  *     Targ_Ignore             Return true if errors should be ignored when
1.31      espie      84:  *                             creating the given target.
1.1       deraadt    85:  *
1.32      espie      86:  *     Targ_Silent             Return true if we should be silent when
1.31      espie      87:  *                             creating the given target.
1.1       deraadt    88:  *
1.32      espie      89:  *     Targ_Precious           Return true if the target is precious and
1.31      espie      90:  *                             should not be removed if we are interrupted.
1.1       deraadt    91:  *
                     92:  * Debugging:
1.31      espie      93:  *     Targ_PrintGraph         Print out the entire graphm all variables
                     94:  *                             and statistics for the directory cache. Should
                     95:  *                             print something for suffixes, too, but...
1.1       deraadt    96:  */
                     97:
1.34      espie      98: #include <limits.h>
1.32      espie      99: #include <stddef.h>
1.70      espie     100: #include <stdint.h>
1.32      espie     101: #include <stdio.h>
1.67      espie     102: #include <stdlib.h>
1.33      espie     103: #include <string.h>
1.70      espie     104: #include <ohash.h>
1.32      espie     105: #include "config.h"
                    106: #include "defines.h"
                    107: #include "stats.h"
                    108: #include "suff.h"
                    109: #include "var.h"
                    110: #include "targ.h"
                    111: #include "memory.h"
                    112: #include "gnode.h"
                    113: #include "extern.h"
                    114: #include "timestamp.h"
                    115: #include "lst.h"
1.46      espie     116: #include "node_int.h"
                    117: #include "nodehashconsts.h"
1.67      espie     118: #include "dump.h"
1.31      espie     119:
1.57      espie     120: static struct ohash targets;   /* hash table of targets */
1.46      espie     121: struct ohash_info gnode_info = {
1.75      espie     122:        offsetof(GNode, name), NULL, hash_calloc, hash_free, element_alloc
1.42      espie     123: };
1.1       deraadt   124:
1.83      espie     125: static GNode *Targ_mk_node(const char *, const char *, unsigned int,
                    126:     unsigned char, unsigned int);
1.48      espie     127:
1.83      espie     128: #define Targ_mk_constant(n, type) \
                    129:     Targ_mk_special_node(n, sizeof(n), K_##n, type, SPECIAL_NONE, 0)
1.1       deraadt   130:
1.46      espie     131: GNode *begin_node, *end_node, *interrupt_node, *DEFAULT;
                    132:
1.1       deraadt   133: void
1.39      espie     134: Targ_Init(void)
1.1       deraadt   135: {
1.42      espie     136:        /* A small make file already creates 200 targets.  */
                    137:        ohash_init(&targets, 10, &gnode_info);
1.83      espie     138:        begin_node = Targ_mk_constant(NODE_BEGIN,
                    139:            OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT);
                    140:        end_node = Targ_mk_constant(NODE_END,
                    141:            OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT);
                    142:        interrupt_node = Targ_mk_constant(NODE_INTERRUPT,
                    143:            OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT);
                    144:        DEFAULT = Targ_mk_constant(NODE_DEFAULT,
                    145:            OP_DUMMY | OP_NOTMAIN| OP_TRANSFORM | OP_NODEFAULT);
1.46      espie     146:
1.1       deraadt   147: }
                    148:
1.83      espie     149: static GNode *
                    150: Targ_mk_node(const char *name, const char *ename,
                    151:     unsigned int type, unsigned char special, unsigned int special_op)
1.1       deraadt   152: {
1.42      espie     153:        GNode *gn;
1.1       deraadt   154:
1.42      espie     155:        gn = ohash_create_entry(&gnode_info, name, &ename);
                    156:        gn->path = NULL;
1.83      espie     157:        gn->type = type;
                    158:        gn->special = special;
                    159:        gn->special_op = special_op;
1.80      espie     160:        gn->children_left = 0;
1.51      espie     161:        gn->must_make = false;
1.53      espie     162:        gn->built_status = UNKNOWN;
1.78      espie     163:        gn->in_cycle = false;
1.80      espie     164:        gn->child_rebuilt = false;
1.46      espie     165:        gn->order = 0;
1.42      espie     166:        ts_set_out_of_date(gn->mtime);
1.71      espie     167:        gn->youngest = gn;
1.42      espie     168:        Lst_Init(&gn->cohorts);
                    169:        Lst_Init(&gn->parents);
                    170:        Lst_Init(&gn->children);
1.80      espie     171:        Lst_Init(&gn->predecessors);
1.42      espie     172:        Lst_Init(&gn->successors);
1.81      espie     173:        SymTable_Init(&gn->localvars);
1.50      espie     174:        gn->impliedsrc = NULL;
1.42      espie     175:        Lst_Init(&gn->commands);
1.56      espie     176:        gn->suffix = NULL;
1.57      espie     177:        gn->next = NULL;
                    178:        gn->basename = NULL;
                    179:        gn->sibling = gn;
1.69      espie     180:        gn->groupling = NULL;
1.1       deraadt   181:
1.31      espie     182: #ifdef STATS_GN_CREATION
1.42      espie     183:        STAT_GN_COUNT++;
1.10      espie     184: #endif
1.1       deraadt   185:
1.42      espie     186:        return gn;
1.1       deraadt   187: }
                    188:
1.46      espie     189: GNode *
1.83      espie     190: Targ_NewGNi(const char *name, const char *ename)
1.46      espie     191: {
1.83      espie     192:        return Targ_mk_node(name, ename, OP_ZERO, SPECIAL_NONE, 0);
1.46      espie     193: }
1.1       deraadt   194:
                    195: GNode *
1.83      espie     196: Targ_FindNodei(const char *name, const char *ename, int flags)
1.1       deraadt   197: {
1.83      espie     198:        uint32_t hv;
1.46      espie     199:        GNode *gn;
1.42      espie     200:        unsigned int slot;
1.27      espie     201:
1.83      espie     202:        hv = ohash_interval(name, &ename);
                    203:
1.46      espie     204:        slot = ohash_lookup_interval(&targets, name, ename, hv);
1.27      espie     205:
1.42      espie     206:        gn = ohash_find(&targets, slot);
1.31      espie     207:
1.42      espie     208:        if (gn == NULL && (flags & TARG_CREATE)) {
                    209:                gn = Targ_NewGNi(name, ename);
                    210:                ohash_insert(&targets, slot, gn);
                    211:        }
1.1       deraadt   212:
1.42      espie     213:        return gn;
1.1       deraadt   214: }
                    215:
1.83      espie     216: GNode *
                    217: Targ_mk_special_node(const char *name, size_t n, uint32_t hv,
                    218:     unsigned int type, unsigned char special, unsigned int special_op)
                    219: {
                    220:        GNode *gn;
                    221:        unsigned int slot;
                    222:        const char *ename = name + n - 1;
                    223:
                    224:        slot = ohash_lookup_interval(&targets, name, ename, hv);
                    225:
                    226:        assert(ohash_find(&targets, slot) == NULL);
                    227:
                    228:        gn = Targ_mk_node(name, ename, type, special, special_op);
                    229:        ohash_insert(&targets, slot, gn);
                    230:
                    231:        return gn;
                    232: }
                    233:
1.20      espie     234: void
1.46      espie     235: Targ_FindList(Lst nodes, Lst names)
1.1       deraadt   236: {
1.46      espie     237:        LstNode ln;
                    238:        GNode *gn;
1.42      espie     239:        char *name;
                    240:
                    241:        for (ln = Lst_First(names); ln != NULL; ln = Lst_Adv(ln)) {
1.77      espie     242:                name = Lst_Datum(ln);
1.42      espie     243:                gn = Targ_FindNode(name, TARG_CREATE);
                    244:                /* Note: Lst_AtEnd must come before the Lst_Concat so the nodes
                    245:                 * are added to the list in the order in which they were
                    246:                 * encountered in the makefile.  */
                    247:                Lst_AtEnd(nodes, gn);
                    248:                if (gn->type & OP_DOUBLEDEP)
                    249:                        Lst_Concat(nodes, &gn->cohorts);
                    250:        }
1.1       deraadt   251: }
                    252:
1.32      espie     253: bool
1.39      espie     254: Targ_Ignore(GNode *gn)
1.1       deraadt   255: {
1.42      espie     256:        if (ignoreErrors || gn->type & OP_IGNORE)
                    257:                return true;
                    258:        else
                    259:                return false;
1.1       deraadt   260: }
                    261:
1.32      espie     262: bool
1.39      espie     263: Targ_Silent(GNode *gn)
1.1       deraadt   264: {
1.42      espie     265:        if (beSilent || gn->type & OP_SILENT)
                    266:                return true;
                    267:        else
                    268:                return false;
1.1       deraadt   269: }
                    270:
1.32      espie     271: bool
1.39      espie     272: Targ_Precious(GNode *gn)
1.1       deraadt   273: {
1.58      espie     274:        if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP|OP_PHONY)))
1.42      espie     275:                return true;
                    276:        else
                    277:                return false;
1.84    ! espie     278: }
        !           279:
        !           280: bool
        !           281: node_is_real(GNode *gn)
        !           282: {
        !           283:        return (gn->type & OP_DUMMY) == 0;
1.1       deraadt   284: }
                    285:
1.17      espie     286: void
1.66      espie     287: Targ_PrintCmd(void *p)
1.1       deraadt   288: {
1.76      espie     289:        const struct command *cmd = p;
1.66      espie     290:        printf("\t%s\n", cmd->string);
1.1       deraadt   291: }
                    292:
                    293: void
1.39      espie     294: Targ_PrintType(int type)
1.1       deraadt   295: {
1.42      espie     296:        int    tbit;
1.5       millert   297:
1.46      espie     298: #define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break
                    299: #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break
1.42      espie     300:
                    301:        type &= ~OP_OPMASK;
                    302:
                    303:        while (type) {
                    304:                tbit = 1 << (ffs(type) - 1);
                    305:                type &= ~tbit;
                    306:
                    307:                switch (tbit) {
                    308:                PRINTBIT(OPTIONAL);
                    309:                PRINTBIT(USE);
                    310:                PRINTBIT(EXEC);
                    311:                PRINTBIT(IGNORE);
                    312:                PRINTBIT(PRECIOUS);
                    313:                PRINTBIT(SILENT);
                    314:                PRINTBIT(MAKE);
                    315:                PRINTBIT(JOIN);
                    316:                PRINTBIT(INVISIBLE);
                    317:                PRINTBIT(NOTMAIN);
                    318:                /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
1.45      espie     319:                case OP_MEMBER:
                    320:                        if (DEBUG(TARG))
                    321:                                printf(".MEMBER ");
1.42      espie     322:                        break;
                    323:                PRINTDBIT(ARCHV);
                    324:                }
1.46      espie     325:     }
1.1       deraadt   326: }
1.67      espie     327:
1.54      espie     328: const char *
1.52      espie     329: status_to_string(GNode *gn)
                    330: {
                    331:        switch (gn->built_status) {
1.53      espie     332:        case UNKNOWN:
                    333:                return "unknown";
1.79      espie     334:        case REBUILT:
1.52      espie     335:                return "made";
                    336:        case UPTODATE:
                    337:                return "up-to-date";
                    338:        case ERROR:
                    339:                return "error when made";
                    340:        case ABORTED:
                    341:                return "aborted";
                    342:        default:
                    343:                return "other status";
                    344:        }
1.49      espie     345: }
                    346:
1.57      espie     347: struct ohash *
                    348: targets_hash()
1.49      espie     349: {
1.57      espie     350:        return &targets;
1.65      espie     351: }