LTP GCOV extension - code coverage report
Current view: directory - src/libstore - storeexpr.cc
Test: app.info
Date: 2004-12-21 Instrumented lines: 101
Code covered: 87.1 % Executed lines: 88

       1                 : #include "storeexpr.hh"
       2                 : #include "globals.hh"
       3                 : #include "store.hh"
       4                 : 
       5                 : #include "storeexpr-ast.hh"
       6                 : #include "storeexpr-ast.cc"
       7                 : 
       8                 : 
       9                 : Hash hashTerm(ATerm t)
      10             135 : {
      11             135 :     return hashString(atPrint(t));
      12                 : }
      13                 : 
      14                 : 
      15                 : Path writeTerm(ATerm t, const string & suffix)
      16              66 : {
      17                 :     /* The id of a term is its hash. */
      18              66 :     Hash h = hashTerm(t);
      19                 : 
      20                 :     Path path = canonPath(nixStore + "/" + 
      21              66 :         (string) h + suffix + ".store");
      22                 : 
      23              66 :     if (!readOnlyMode && !isValidPath(path)) {
      24              50 :         char * s = ATwriteToString(t);
      25              50 :         if (!s) throw Error(format("cannot write aterm to `%1%'") % path);
      26              50 :         addTextToStore(path, string(s));
      27                 :     }
      28                 :     
      29              50 :     return path;
      30                 : }
      31                 : 
      32                 : 
      33                 : static void parsePaths(ATermList paths, PathSet & out)
      34             435 : {
      35             747 :     for (ATermIterator i(paths); i; ++i) {
      36             312 :         if (ATgetType(*i) != AT_APPL)
      37               0 :             throw badTerm("not a path", *i);
      38             312 :         string s = aterm2String(*i);
      39             312 :         if (s.size() == 0 || s[0] != '/')
      40               0 :             throw badTerm("not a path", *i);
      41             312 :         out.insert(s);
      42                 :     }
      43                 : }
      44                 : 
      45                 : 
      46                 : static void checkClosure(const Closure & closure)
      47             169 : {
      48             169 :     if (closure.elems.size() == 0)
      49               0 :         throw Error("empty closure");
      50                 : 
      51             169 :     PathSet decl;
      52             343 :     for (ClosureElems::const_iterator i = closure.elems.begin();
      53                 :          i != closure.elems.end(); i++)
      54             174 :         decl.insert(i->first);
      55                 :     
      56             338 :     for (PathSet::const_iterator i = closure.roots.begin();
      57                 :          i != closure.roots.end(); i++)
      58             169 :         if (decl.find(*i) == decl.end())
      59               0 :             throw Error(format("undefined root path `%1%'") % *i);
      60                 :     
      61             343 :     for (ClosureElems::const_iterator i = closure.elems.begin();
      62                 :          i != closure.elems.end(); i++)
      63             179 :         for (PathSet::const_iterator j = i->second.refs.begin();
      64                 :              j != i->second.refs.end(); j++)
      65               5 :             if (decl.find(*j) == decl.end())
      66               0 :                 throw Error(
      67                 :                     format("undefined path `%1%' referenced by `%2%'")
      68                 :                     % *j % i->first);
      69                 : }
      70                 : 
      71                 : 
      72                 : /* Parse a closure. */
      73                 : static bool parseClosure(ATerm t, Closure & closure)
      74             215 : {
      75             215 :     ATermList roots, elems;
      76                 : 
      77             215 :     if (!matchClosure(t, roots, elems))
      78              46 :         return false;
      79                 : 
      80             169 :     parsePaths(roots, closure.roots);
      81                 : 
      82             343 :     for (ATermIterator i(elems); i; ++i) {
      83             174 :         ATerm path;
      84             174 :         ATermList refs;
      85             174 :         if (!matchClosureElem(*i, path, refs))
      86               0 :             throw badTerm("not a closure element", *i);
      87            1026 :         ClosureElem elem;
      88             174 :         parsePaths(refs, elem.refs);
      89             638 :         closure.elems[aterm2String(path)] = elem;
      90                 :     }
      91                 : 
      92             169 :     checkClosure(closure);
      93             169 :     return true;
      94                 : }
      95                 : 
      96                 : 
      97                 : static bool parseDerivation(ATerm t, Derivation & derivation)
      98              46 : {
      99              46 :     ATermList outs, ins, args, bnds;
     100              46 :     ATerm builder, platform;
     101                 : 
     102              46 :     if (!matchDerive(t, outs, ins, platform, builder, args, bnds))
     103               0 :         return false;
     104                 : 
     105              46 :     parsePaths(outs, derivation.outputs);
     106              46 :     parsePaths(ins, derivation.inputs);
     107                 : 
     108              46 :     derivation.builder = aterm2String(builder);
     109              46 :     derivation.platform = aterm2String(platform);
     110                 :     
     111             184 :     for (ATermIterator i(args); i; ++i) {
     112             138 :         if (ATgetType(*i) != AT_APPL)
     113               0 :             throw badTerm("string expected", *i);
     114             138 :         derivation.args.push_back(aterm2String(*i));
     115                 :     }
     116                 : 
     117             307 :     for (ATermIterator i(bnds); i; ++i) {
     118             261 :         ATerm s1, s2;
     119             261 :         if (!matchEnvBinding(*i, s1, s2))
     120               0 :             throw badTerm("tuple of strings expected", *i);
     121             261 :         derivation.env[aterm2String(s1)] = aterm2String(s2);
     122                 :     }
     123                 : 
     124              46 :     return true;
     125                 : }
     126                 : 
     127                 : 
     128                 : StoreExpr parseStoreExpr(ATerm t)
     129             215 : {
     130            2411 :     StoreExpr ne;
     131             215 :     if (parseClosure(t, ne.closure))
     132             169 :         ne.type = StoreExpr::neClosure;
     133              46 :     else if (parseDerivation(t, ne.derivation))
     134              46 :         ne.type = StoreExpr::neDerivation;
     135               0 :     else throw badTerm("not a store expression", t);
     136               0 :     return ne;
     137                 : }
     138                 : 
     139                 : 
     140                 : static ATermList unparsePaths(const PathSet & paths)
     141             272 : {
     142             272 :     ATermList l = ATempty;
     143             503 :     for (PathSet::const_iterator i = paths.begin();
     144                 :          i != paths.end(); i++)
     145             231 :         l = ATinsert(l, toATerm(*i));
     146             272 :     return ATreverse(l);
     147                 : }
     148                 : 
     149                 : 
     150                 : static ATerm unparseClosure(const Closure & closure)
     151              66 : {
     152              66 :     ATermList roots = unparsePaths(closure.roots);
     153                 :     
     154              66 :     ATermList elems = ATempty;
     155             134 :     for (ClosureElems::const_iterator i = closure.elems.begin();
     156                 :          i != closure.elems.end(); i++)
     157              68 :         elems = ATinsert(elems,
     158                 :             makeClosureElem(
     159                 :                 toATerm(i->first),
     160                 :                 unparsePaths(i->second.refs)));
     161                 : 
     162              66 :     return makeClosure(roots, elems);
     163                 : }
     164                 : 
     165                 : 
     166                 : static ATerm unparseDerivation(const Derivation & derivation)
     167              69 : {
     168              69 :     ATermList args = ATempty;
     169             276 :     for (Strings::const_iterator i = derivation.args.begin();
     170                 :          i != derivation.args.end(); i++)
     171             207 :         args = ATinsert(args, toATerm(*i));
     172                 : 
     173              69 :     ATermList env = ATempty;
     174             409 :     for (StringPairs::const_iterator i = derivation.env.begin();
     175                 :          i != derivation.env.end(); i++)
     176             340 :         env = ATinsert(env,
     177                 :             makeEnvBinding(
     178                 :                 toATerm(i->first),
     179                 :                 toATerm(i->second)));
     180                 : 
     181              69 :     return makeDerive(
     182                 :         unparsePaths(derivation.outputs),
     183                 :         unparsePaths(derivation.inputs),
     184                 :         toATerm(derivation.platform),
     185                 :         toATerm(derivation.builder),
     186                 :         ATreverse(args),
     187                 :         ATreverse(env));
     188                 : }
     189                 : 
     190                 : 
     191                 : ATerm unparseStoreExpr(const StoreExpr & ne)
     192             135 : {
     193             135 :     if (ne.type == StoreExpr::neClosure)
     194              66 :         return unparseClosure(ne.closure);
     195              69 :     else if (ne.type == StoreExpr::neDerivation)
     196              69 :         return unparseDerivation(ne.derivation);
     197               0 :     else abort();
     198              51 : }

Generated by: LTP GCOV extension version 1.1