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

Annotation of src/usr.bin/make/dump.c, Revision 1.3

1.3     ! espie       1: /* $OpenBSD: dump.c,v 1.2 2012/10/02 10:29:30 espie Exp $ */
1.1       espie       2: /*
                      3:  * Copyright (c) 2012 Marc Espie.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
                     15:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     16:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
                     17:  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
                     18:  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     19:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
                     20:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     21:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     22:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     23:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     24:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
1.2       espie      26: #include <stdint.h>
                     27: #include <stddef.h>
                     28: #include <stdio.h>
                     29: #include <string.h>
                     30: #include <stdlib.h>
                     31: #include <limits.h>
                     32: #include "ohash.h"
1.1       espie      33: #include "defines.h"
1.2       espie      34: #include "gnode.h"
1.1       espie      35: #include "dump.h"
                     36: #include "targ.h"
1.2       espie      37: #include "var.h"
                     38: #include "memory.h"
                     39: #include "suff.h"
                     40: #include "lst.h"
                     41: #include "timestamp.h"
                     42: #include "dir.h"
                     43:
                     44: /* since qsort doesn't have user data, this needs to be a global... */
                     45: static ptrdiff_t cmp_offset;
                     46: static void targ_dump(bool);
                     47:
                     48: static int
                     49: compare_names(const void *a, const void *b)
                     50: {
                     51:        const char **pa = (const char **)a;
                     52:        const char **pb = (const char **)b;
                     53:        return strcmp((*pa) + cmp_offset, (*pb) + cmp_offset);
                     54: }
                     55:
                     56: void *
                     57: sort_ohash_by_name(struct ohash *h)
                     58: {
                     59:        cmp_offset = h->info.key_offset;
                     60:
                     61:        return sort_ohash(h, compare_names);
                     62: }
                     63:
                     64: void *
                     65: sort_ohash(struct ohash *h, int (*comparison)(const void *, const void *))
                     66: {
                     67:        unsigned int i, j;
                     68:        void *e;
                     69:        size_t n = ohash_entries(h);
                     70:        void **t = emalloc(sizeof(void *) * (n+1));
                     71:        cmp_offset = h->info.key_offset;
                     72:
                     73:        for (i = 0, e = ohash_first(h, &j); e != NULL; e = ohash_next(h, &j))
                     74:                t[i++] = e;
                     75:        qsort(t, n, sizeof(void *), comparison);
                     76:        /* add an extra entry to be able to figure out the end without needing
                     77:         * to keep a counter */
                     78:        t[n] = NULL;
                     79:        return t;
                     80: }
                     81:
                     82: static void
                     83: TargPrintName(void *gnp)
                     84: {
                     85:        GNode *gn = (GNode *)gnp;
                     86:        printf("%s ", gn->name);
                     87: }
                     88:
                     89: static void
                     90: TargPrintOnlySrc(GNode *gn)
                     91: {
                     92:        if (OP_NOP(gn->type) && gn->special == SPECIAL_NONE &&
                     93:            !(gn->type & OP_DUMMY)) {
                     94:                if (gn->path != NULL)
                     95:                        printf("#\t%s [%s]\n", gn->name,
                     96:                            strcmp(gn->path, gn->name) == 0 ? "=" : gn->path);
                     97:                else
                     98:                        printf("#\t%s\n", gn->name);
                     99:        }
                    100: }
                    101:
                    102: static void
                    103: TargPrintNode(GNode *gn, bool full)
                    104: {
                    105:        if (OP_NOP(gn->type))
                    106:                return;
                    107:        switch((gn->special & SPECIAL_MASK)) {
                    108:        case SPECIAL_SUFFIXES:
                    109:        case SPECIAL_PHONY:
                    110:        case SPECIAL_ORDER:
1.3     ! espie     111:        case SPECIAL_NOTHING:
1.2       espie     112:        case SPECIAL_MAIN:
                    113:        case SPECIAL_IGNORE:
                    114:                return;
                    115:        default:
                    116:                break;
                    117:        }
                    118:        if (full) {
                    119:                printf("# %d unmade prerequisites\n", gn->unmade);
                    120:                if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) {
                    121:                        if (!is_out_of_date(gn->mtime)) {
                    122:                                printf("# last modified %s: %s\n",
                    123:                                      time_to_string(gn->mtime),
                    124:                                      status_to_string(gn));
                    125:                        } else if (gn->built_status != UNKNOWN) {
                    126:                                printf("# non-existent (maybe): %s\n",
                    127:                                    status_to_string(gn));
                    128:                        } else {
                    129:                                printf("# unmade\n");
                    130:                        }
                    131:                }
                    132:        }
                    133:        if (!Lst_IsEmpty(&gn->parents)) {
                    134:                printf("# parent targets: ");
                    135:                Lst_Every(&gn->parents, TargPrintName);
                    136:                fputc('\n', stdout);
                    137:        }
                    138:        if (gn->impliedsrc)
                    139:                printf("# implied prerequisite: %s\n", gn->impliedsrc->name);
                    140:
                    141:        printf("%-16s", gn->name);
                    142:        switch (gn->type & OP_OPMASK) {
                    143:        case OP_DEPENDS:
                    144:                printf(": "); break;
                    145:        case OP_FORCE:
                    146:                printf("! "); break;
                    147:        case OP_DOUBLEDEP:
                    148:                printf(":: "); break;
                    149:        }
                    150:        Targ_PrintType(gn->type);
                    151:        Lst_Every(&gn->children, TargPrintName);
                    152:        fputc('\n', stdout);
                    153:        Lst_Every(&gn->commands, Targ_PrintCmd);
                    154:        printf("\n\n");
                    155:        if (gn->type & OP_DOUBLEDEP) {
                    156:                LstNode ln;
                    157:
                    158:                for (ln = Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln))
                    159:                        TargPrintNode((GNode *)Lst_Datum(ln), full);
                    160:        }
                    161: }
                    162:
                    163: static void
                    164: dump_special(GNode **t, const char *name, int prop)
                    165: {
                    166:        unsigned int i;
                    167:        bool first = true;
                    168:
                    169:        for (i = 0; t[i] != NULL; i++)
                    170:                if (t[i]->type & prop) {
                    171:                        if (first) {
                    172:                                printf("%s:", name);
                    173:                                first = false;
                    174:                        }
                    175:                        printf(" %s", t[i]->name);
                    176:                }
                    177:        if (!first)
                    178:                printf("\n\n");
                    179: }
                    180:
                    181: static void
                    182: targ_dump(bool full)
                    183: {
                    184:        GNode **t = sort_ohash_by_name(targets_hash());
                    185:        unsigned int i;
                    186:
                    187:        printf("#   Input graph:\n");
                    188:        for (i = 0; t[i] != NULL; i++)
                    189:                TargPrintNode(t[i], full);
                    190:        printf("\n\n");
                    191:
                    192:        dump_special(t, ".PHONY", OP_PHONY);
                    193:        dump_special(t, ".PRECIOUS", OP_PRECIOUS);
                    194:        dump_special(t, ".SILENT", OP_SILENT);
                    195:        dump_special(t, ".IGNORE", OP_IGNORE);
                    196:        printf("#   Other target names:\n");
                    197:        for (i = 0; t[i] != NULL; i++)
                    198:                TargPrintOnlySrc(t[i]);
                    199:        printf("\n");
                    200:        free(t);
                    201: }
                    202:
                    203: static bool dumped_once = false;
1.1       espie     204:
                    205: void
                    206: dump_data(void)
                    207: {
1.2       espie     208:        Var_Dump();
                    209:        Suff_PrintAll();
                    210:        targ_dump(false);
                    211:        dumped_once = true;
                    212: }
                    213:
                    214: void
                    215: post_mortem(void)
                    216: {
                    217:        if (!dumped_once) {
                    218:                Var_Dump();
                    219:                Suff_PrintAll();
                    220:        }
                    221:        targ_dump(true);
1.1       espie     222: }