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

Diff for /src/usr.bin/make/dump.c between version 1.1 and 1.2

version 1.1, 2012/09/21 07:55:20 version 1.2, 2012/10/02 10:29:30
Line 2 
Line 2 
 /*  /*
  * Copyright (c) 2012 Marc Espie.   * Copyright (c) 2012 Marc Espie.
  *   *
  * Extensive code modifications for the OpenBSD project.  
  *  
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
  * are met:   * are met:
Line 25 
Line 23 
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   #include <stdint.h>
   #include <stddef.h>
   #include <stdio.h>
   #include <string.h>
   #include <stdlib.h>
   #include <limits.h>
   #include "ohash.h"
 #include "defines.h"  #include "defines.h"
   #include "gnode.h"
 #include "dump.h"  #include "dump.h"
 #include "targ.h"  #include "targ.h"
   #include "var.h"
   #include "memory.h"
   #include "suff.h"
   #include "lst.h"
   #include "timestamp.h"
   #include "dir.h"
   
   /* since qsort doesn't have user data, this needs to be a global... */
   static ptrdiff_t cmp_offset;
   static void targ_dump(bool);
   
   static int
   compare_names(const void *a, const void *b)
   {
           const char **pa = (const char **)a;
           const char **pb = (const char **)b;
           return strcmp((*pa) + cmp_offset, (*pb) + cmp_offset);
   }
   
   void *
   sort_ohash_by_name(struct ohash *h)
   {
           cmp_offset = h->info.key_offset;
   
           return sort_ohash(h, compare_names);
   }
   
   void *
   sort_ohash(struct ohash *h, int (*comparison)(const void *, const void *))
   {
           unsigned int i, j;
           void *e;
           size_t n = ohash_entries(h);
           void **t = emalloc(sizeof(void *) * (n+1));
           cmp_offset = h->info.key_offset;
   
           for (i = 0, e = ohash_first(h, &j); e != NULL; e = ohash_next(h, &j))
                   t[i++] = e;
           qsort(t, n, sizeof(void *), comparison);
           /* add an extra entry to be able to figure out the end without needing
            * to keep a counter */
           t[n] = NULL;
           return t;
   }
   
   static void
   TargPrintName(void *gnp)
   {
           GNode *gn = (GNode *)gnp;
           printf("%s ", gn->name);
   }
   
   static void
   TargPrintOnlySrc(GNode *gn)
   {
           if (OP_NOP(gn->type) && gn->special == SPECIAL_NONE &&
               !(gn->type & OP_DUMMY)) {
                   if (gn->path != NULL)
                           printf("#\t%s [%s]\n", gn->name,
                               strcmp(gn->path, gn->name) == 0 ? "=" : gn->path);
                   else
                           printf("#\t%s\n", gn->name);
           }
   }
   
   static void
   TargPrintNode(GNode *gn, bool full)
   {
           if (OP_NOP(gn->type))
                   return;
           switch((gn->special & SPECIAL_MASK)) {
           case SPECIAL_SUFFIXES:
           case SPECIAL_PHONY:
           case SPECIAL_ORDER:
           case SPECIAL_DEPRECATED:
           case SPECIAL_MAIN:
           case SPECIAL_IGNORE:
                   return;
           default:
                   break;
           }
           if (full) {
                   printf("# %d unmade prerequisites\n", gn->unmade);
                   if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) {
                           if (!is_out_of_date(gn->mtime)) {
                                   printf("# last modified %s: %s\n",
                                         time_to_string(gn->mtime),
                                         status_to_string(gn));
                           } else if (gn->built_status != UNKNOWN) {
                                   printf("# non-existent (maybe): %s\n",
                                       status_to_string(gn));
                           } else {
                                   printf("# unmade\n");
                           }
                   }
           }
           if (!Lst_IsEmpty(&gn->parents)) {
                   printf("# parent targets: ");
                   Lst_Every(&gn->parents, TargPrintName);
                   fputc('\n', stdout);
           }
           if (gn->impliedsrc)
                   printf("# implied prerequisite: %s\n", gn->impliedsrc->name);
   
           printf("%-16s", gn->name);
           switch (gn->type & OP_OPMASK) {
           case OP_DEPENDS:
                   printf(": "); break;
           case OP_FORCE:
                   printf("! "); break;
           case OP_DOUBLEDEP:
                   printf(":: "); break;
           }
           Targ_PrintType(gn->type);
           Lst_Every(&gn->children, TargPrintName);
           fputc('\n', stdout);
           Lst_Every(&gn->commands, Targ_PrintCmd);
           printf("\n\n");
           if (gn->type & OP_DOUBLEDEP) {
                   LstNode ln;
   
                   for (ln = Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln))
                           TargPrintNode((GNode *)Lst_Datum(ln), full);
           }
   }
   
   static void
   dump_special(GNode **t, const char *name, int prop)
   {
           unsigned int i;
           bool first = true;
   
           for (i = 0; t[i] != NULL; i++)
                   if (t[i]->type & prop) {
                           if (first) {
                                   printf("%s:", name);
                                   first = false;
                           }
                           printf(" %s", t[i]->name);
                   }
           if (!first)
                   printf("\n\n");
   }
   
   static void
   targ_dump(bool full)
   {
           GNode **t = sort_ohash_by_name(targets_hash());
           unsigned int i;
           bool first;
   
           printf("#   Input graph:\n");
           for (i = 0; t[i] != NULL; i++)
                   TargPrintNode(t[i], full);
           printf("\n\n");
   
           dump_special(t, ".PHONY", OP_PHONY);
           dump_special(t, ".PRECIOUS", OP_PRECIOUS);
           dump_special(t, ".SILENT", OP_SILENT);
           dump_special(t, ".IGNORE", OP_IGNORE);
           printf("#   Other target names:\n");
           for (i = 0; t[i] != NULL; i++)
                   TargPrintOnlySrc(t[i]);
           printf("\n");
           free(t);
   }
   
   static bool dumped_once = false;
   
 void  void
 dump_data(void)  dump_data(void)
 {  {
         Targ_PrintGraph(1);          Var_Dump();
           Suff_PrintAll();
           targ_dump(false);
           dumped_once = true;
   }
   
   void
   post_mortem(void)
   {
           if (!dumped_once) {
                   Var_Dump();
                   Suff_PrintAll();
           }
           targ_dump(true);
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2