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

1.2     ! espie       1: /* $OpenBSD: dump.c,v 1.1 2012/09/21 07:55:20 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:
        !           111:        case SPECIAL_DEPRECATED:
        !           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:        bool first;
        !           187:
        !           188:        printf("#   Input graph:\n");
        !           189:        for (i = 0; t[i] != NULL; i++)
        !           190:                TargPrintNode(t[i], full);
        !           191:        printf("\n\n");
        !           192:
        !           193:        dump_special(t, ".PHONY", OP_PHONY);
        !           194:        dump_special(t, ".PRECIOUS", OP_PRECIOUS);
        !           195:        dump_special(t, ".SILENT", OP_SILENT);
        !           196:        dump_special(t, ".IGNORE", OP_IGNORE);
        !           197:        printf("#   Other target names:\n");
        !           198:        for (i = 0; t[i] != NULL; i++)
        !           199:                TargPrintOnlySrc(t[i]);
        !           200:        printf("\n");
        !           201:        free(t);
        !           202: }
        !           203:
        !           204: static bool dumped_once = false;
1.1       espie     205:
                    206: void
                    207: dump_data(void)
                    208: {
1.2     ! espie     209:        Var_Dump();
        !           210:        Suff_PrintAll();
        !           211:        targ_dump(false);
        !           212:        dumped_once = true;
        !           213: }
        !           214:
        !           215: void
        !           216: post_mortem(void)
        !           217: {
        !           218:        if (!dumped_once) {
        !           219:                Var_Dump();
        !           220:                Suff_PrintAll();
        !           221:        }
        !           222:        targ_dump(true);
1.1       espie     223: }