LTP GCOV extension - code coverage report
Current view: directory - src/nix-store - dotgraph.cc
Test: app.info
Date: 2004-12-21 Instrumented lines: 64
Code covered: 3.1 % Executed lines: 2

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

Generated by: LTP GCOV extension version 1.1