LTP GCOV extension - code coverage report
Current view: directory - src/nix-store - dotgraph.cc
Test: app.info
Date: 2008-11-20 Instrumented lines: 38
Code covered: 92.1 % Executed lines: 35

       1                 : #include "dotgraph.hh"
       2                 : #include "util.hh"
       3                 : #include "store-api.hh"
       4                 : 
       5                 : #include <iostream>
       6                 : 
       7                 : 
       8                 : using std::cout;
       9                 : 
      10                 : namespace nix {
      11                 : 
      12                 : 
      13              42 : static string dotQuote(const string & s)
      14                 : {
      15              42 :     return "\"" + s + "\"";
      16                 : }
      17                 : 
      18                 : 
      19               6 : static string nextColour()
      20                 : {
      21                 :     static int n = 0;
      22                 :     static string colours[] =
      23                 :         { "black", "red", "green", "blue"
      24               8 :         , "magenta", "burlywood" };
      25               6 :     return colours[n++ % (sizeof(colours) / sizeof(string))];
      26                 : }
      27                 : 
      28                 : 
      29               6 : static string makeEdge(const string & src, const string & dst)
      30                 : {
      31                 :     format f = format("%1% -> %2% [color = %3%];\n")
      32               6 :         % dotQuote(src) % dotQuote(dst) % dotQuote(nextColour());
      33              12 :     return f.str();
      34                 : }
      35                 : 
      36                 : 
      37                 : static string makeNode(const string & id, const string & label,
      38               8 :     const string & colour)
      39                 : {
      40                 :     format f = format("%1% [label = %2%, shape = box, "
      41                 :         "style = filled, fillcolor = %3%];\n")
      42               8 :         % dotQuote(id) % dotQuote(label) % dotQuote(colour);
      43              16 :     return f.str();
      44                 : }
      45                 : 
      46                 : 
      47               8 : static string symbolicName(const string & path)
      48                 : {
      49               8 :     string p = baseNameOf(path);
      50               8 :     int dash = p.find('-');
      51               8 :     return string(p, dash + 1);
      52                 : }
      53                 : 
      54                 : 
      55               0 : string pathLabel(const Path & nePath, const string & elemPath)
      56                 : {
      57               0 :     return (string) nePath + "-" + elemPath;
      58                 : }
      59                 : 
      60                 : 
      61                 : #if 0
      62                 : void printClosure(const Path & nePath, const StoreExpr & fs)
      63                 : {
      64                 :     PathSet workList(fs.closure.roots);
      65                 :     PathSet doneSet;
      66                 : 
      67                 :     for (PathSet::iterator i = workList.begin(); i != workList.end(); ++i) {
      68                 :         cout << makeEdge(pathLabel(nePath, *i), nePath);
      69                 :     }
      70                 : 
      71                 :     while (!workList.empty()) {
      72                 :         Path path = *(workList.begin());
      73                 :         workList.erase(path);
      74                 : 
      75                 :         if (doneSet.find(path) == doneSet.end()) {
      76                 :             doneSet.insert(path);
      77                 : 
      78                 :             ClosureElems::const_iterator elem = fs.closure.elems.find(path);
      79                 :             if (elem == fs.closure.elems.end())
      80                 :                 throw Error(format("bad closure, missing path `%1%'") % path);
      81                 : 
      82                 :             for (StringSet::const_iterator i = elem->second.refs.begin();
      83                 :                  i != elem->second.refs.end(); ++i)
      84                 :             {
      85                 :                 workList.insert(*i);
      86                 :                 cout << makeEdge(pathLabel(nePath, *i), pathLabel(nePath, path));
      87                 :             }
      88                 : 
      89                 :             cout << makeNode(pathLabel(nePath, path), 
      90                 :                 symbolicName(path), "#ff0000");
      91                 :         }
      92                 :     }
      93                 : }
      94                 : #endif
      95                 : 
      96                 : 
      97               2 : void printDotGraph(const PathSet & roots)
      98                 : {
      99               2 :     PathSet workList(roots);
     100               2 :     PathSet doneSet;
     101                 :             
     102               2 :     cout << "digraph G {\n";
     103                 : 
     104              20 :     while (!workList.empty()) {
     105               8 :         Path path = *(workList.begin());
     106               8 :         workList.erase(path);
     107                 : 
     108               8 :         if (doneSet.find(path) != doneSet.end()) continue;
     109               8 :         doneSet.insert(path);
     110                 : 
     111               8 :         cout << makeNode(path, symbolicName(path), "#ff0000");
     112                 :         
     113               8 :         PathSet references;
     114               8 :         store->queryReferences(path, references);
     115                 : 
     116              15 :         for (PathSet::iterator i = references.begin();
     117                 :              i != references.end(); ++i)
     118                 :         {
     119               7 :             if (*i != path) {
     120               6 :                 workList.insert(*i);
     121               6 :                 cout << makeEdge(*i, path);
     122                 :             }
     123                 :         }
     124                 :             
     125                 : 
     126                 : #if 0        
     127                 :             StoreExpr ne = storeExprFromPath(path);
     128                 : 
     129                 :             string label, colour;
     130                 :                     
     131                 :             if (ne.type == StoreExpr::neDerivation) {
     132                 :                 for (PathSet::iterator i = ne.derivation.inputs.begin();
     133                 :                      i != ne.derivation.inputs.end(); ++i)
     134                 :                 {
     135                 :                     workList.insert(*i);
     136                 :                     cout << makeEdge(*i, path);
     137                 :                 }
     138                 : 
     139                 :                 label = "derivation";
     140                 :                 colour = "#00ff00";
     141                 :                 for (StringPairs::iterator i = ne.derivation.env.begin();
     142                 :                      i != ne.derivation.env.end(); ++i)
     143                 :                     if (i->first == "name") label = i->second;
     144                 :             }
     145                 : 
     146                 :             else if (ne.type == StoreExpr::neClosure) {
     147                 :                 label = "<closure>";
     148                 :                 colour = "#00ffff";
     149                 :                 printClosure(path, ne);
     150                 :             }
     151                 : 
     152                 :             else abort();
     153                 : 
     154                 :             cout << makeNode(path, label, colour);
     155                 : #endif
     156                 :     }
     157                 : 
     158               2 :     cout << "}\n";
     159               2 : }
     160                 : 
     161               0 :  
     162             414 : }

Generated by: LTP GCOV extension version 1.6