about summary refs log tree commit diff
path: root/src/libstore/storeexpr.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T11·16+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T11·16+0000
commit863dcff6c5ffc163010ec1f9e6819bb9aaaadc29 (patch)
tree4747222c7f8c471e6cbfa07c49023853d2f6b957 /src/libstore/storeexpr.cc
parente9762e2d10c4a837e3d75d53e3a24452f07f47ec (diff)
* Started removing closure store expressions, i.e., the explicit
  representation of closures as ATerms in the Nix store.  Instead, the
  file system pointer graph is now stored in the Nix database.  This
  has many advantages:

  - It greatly simplifies the implementation (we can drop the notion
    of `successors', and so on).

  - It makes registering roots for the garbage collector much easier.
    Instead of specifying the closure expression as a root, you can
    simply specify the store path that must be retained as a root.
    This could not be done previously, since there was no way to find
    the closure store expression containing a given store path.
    
  - Better traceability: it is now possible to query what paths are
    referenced by a path, and what paths refer to a path.

Diffstat (limited to 'src/libstore/storeexpr.cc')
-rw-r--r--src/libstore/storeexpr.cc136
1 files changed, 28 insertions, 108 deletions
diff --git a/src/libstore/storeexpr.cc b/src/libstore/storeexpr.cc
index d8300a066a..d7c87bfa15 100644
--- a/src/libstore/storeexpr.cc
+++ b/src/libstore/storeexpr.cc
@@ -20,7 +20,7 @@ Path writeTerm(ATerm t, const string & suffix)
 }
 
 
-void checkPath(const string & s)
+static void checkPath(const string & s)
 {
     if (s.size() == 0 || s[0] != '/')
         throw Error(format("bad path `%1%' in store expression") % s);
@@ -39,108 +39,53 @@ static void parsePaths(ATermList paths, PathSet & out)
 }
 
 
-static void checkClosure(const Closure & closure)
+void throwBadDrv(ATerm t)
 {
-    if (closure.elems.size() == 0)
-        throw Error("empty closure");
-
-    PathSet decl;
-    for (ClosureElems::const_iterator i = closure.elems.begin();
-         i != closure.elems.end(); i++)
-        decl.insert(i->first);
-    
-    for (PathSet::const_iterator i = closure.roots.begin();
-         i != closure.roots.end(); i++)
-        if (decl.find(*i) == decl.end())
-            throw Error(format("undefined root path `%1%'") % *i);
-    
-    for (ClosureElems::const_iterator i = closure.elems.begin();
-         i != closure.elems.end(); i++)
-        for (PathSet::const_iterator j = i->second.refs.begin();
-             j != i->second.refs.end(); j++)
-            if (decl.find(*j) == decl.end())
-                throw Error(
-		    format("undefined path `%1%' referenced by `%2%'")
-		    % *j % i->first);
-}
-
-
-/* Parse a closure. */
-static bool parseClosure(ATerm t, Closure & closure)
-{
-    ATermList roots, elems;
-
-    if (!matchClosure(t, roots, elems))
-        return false;
-
-    parsePaths(roots, closure.roots);
-
-    for (ATermIterator i(elems); i; ++i) {
-        ATerm path;
-        ATermList refs;
-        if (!matchClosureElem(*i, path, refs))
-            throw badTerm("not a closure element", *i);
-        ClosureElem elem;
-        parsePaths(refs, elem.refs);
-        closure.elems[aterm2String(path)] = elem;
-    }
-
-    checkClosure(closure);
-    return true;
+    throw badTerm("not a valid derivation", t);
 }
 
 
-static bool parseDerivation(ATerm t, Derivation & derivation)
+Derivation parseDerivation(ATerm t)
 {
-    ATermList outs, ins, args, bnds;
+    Derivation drv;
+    ATermList outs, inDrvs, inSrcs, args, bnds;
     ATerm builder, platform;
 
-    if (!matchDerive(t, outs, ins, platform, builder, args, bnds))
-        return false;
+    if (!matchDerive(t, outs, inDrvs, inSrcs, platform, builder, args, bnds))
+        throwBadDrv(t);
 
     for (ATermIterator i(outs); i; ++i) {
         ATerm id, path, hashAlgo, hash;
         if (!matchDerivationOutput(*i, id, path, hashAlgo, hash))
-            return false;
+            throwBadDrv(t);
         DerivationOutput out;
         out.path = aterm2String(path);
         checkPath(out.path);
         out.hashAlgo = aterm2String(hashAlgo);
         out.hash = aterm2String(hash);
-        derivation.outputs[aterm2String(id)] = out;
+        drv.outputs[aterm2String(id)] = out;
     }
 
-    parsePaths(ins, derivation.inputs);
+    parsePaths(inDrvs, drv.inputDrvs);
+    parsePaths(inSrcs, drv.inputSrcs);
 
-    derivation.builder = aterm2String(builder);
-    derivation.platform = aterm2String(platform);
+    drv.builder = aterm2String(builder);
+    drv.platform = aterm2String(platform);
     
     for (ATermIterator i(args); i; ++i) {
         if (ATgetType(*i) != AT_APPL)
             throw badTerm("string expected", *i);
-        derivation.args.push_back(aterm2String(*i));
+        drv.args.push_back(aterm2String(*i));
     }
 
     for (ATermIterator i(bnds); i; ++i) {
         ATerm s1, s2;
         if (!matchEnvBinding(*i, s1, s2))
             throw badTerm("tuple of strings expected", *i);
-        derivation.env[aterm2String(s1)] = aterm2String(s2);
+        drv.env[aterm2String(s1)] = aterm2String(s2);
     }
 
-    return true;
-}
-
-
-StoreExpr parseStoreExpr(ATerm t)
-{
-    StoreExpr ne;
-    if (parseClosure(t, ne.closure))
-        ne.type = StoreExpr::neClosure;
-    else if (parseDerivation(t, ne.derivation))
-        ne.type = StoreExpr::neDerivation;
-    else throw badTerm("not a store expression", t);
-    return ne;
+    return drv;
 }
 
 
@@ -154,27 +99,11 @@ static ATermList unparsePaths(const PathSet & paths)
 }
 
 
-static ATerm unparseClosure(const Closure & closure)
-{
-    ATermList roots = unparsePaths(closure.roots);
-    
-    ATermList elems = ATempty;
-    for (ClosureElems::const_iterator i = closure.elems.begin();
-         i != closure.elems.end(); i++)
-        elems = ATinsert(elems,
-            makeClosureElem(
-                toATerm(i->first),
-                unparsePaths(i->second.refs)));
-
-    return makeClosure(roots, elems);
-}
-
-
-static ATerm unparseDerivation(const Derivation & derivation)
+ATerm unparseDerivation(const Derivation & drv)
 {
     ATermList outputs = ATempty;
-    for (DerivationOutputs::const_iterator i = derivation.outputs.begin();
-         i != derivation.outputs.end(); i++)
+    for (DerivationOutputs::const_iterator i = drv.outputs.begin();
+         i != drv.outputs.end(); i++)
         outputs = ATinsert(outputs,
             makeDerivationOutput(
                 toATerm(i->first),
@@ -183,13 +112,13 @@ static ATerm unparseDerivation(const Derivation & derivation)
                 toATerm(i->second.hash)));
 
     ATermList args = ATempty;
-    for (Strings::const_iterator i = derivation.args.begin();
-         i != derivation.args.end(); i++)
+    for (Strings::const_iterator i = drv.args.begin();
+         i != drv.args.end(); i++)
         args = ATinsert(args, toATerm(*i));
 
     ATermList env = ATempty;
-    for (StringPairs::const_iterator i = derivation.env.begin();
-         i != derivation.env.end(); i++)
+    for (StringPairs::const_iterator i = drv.env.begin();
+         i != drv.env.end(); i++)
         env = ATinsert(env,
             makeEnvBinding(
                 toATerm(i->first),
@@ -197,19 +126,10 @@ static ATerm unparseDerivation(const Derivation & derivation)
 
     return makeDerive(
         ATreverse(outputs),
-        unparsePaths(derivation.inputs),
-        toATerm(derivation.platform),
-        toATerm(derivation.builder),
+        unparsePaths(drv.inputDrvs),
+        unparsePaths(drv.inputSrcs),
+        toATerm(drv.platform),
+        toATerm(drv.builder),
         ATreverse(args),
         ATreverse(env));
 }
-
-
-ATerm unparseStoreExpr(const StoreExpr & ne)
-{
-    if (ne.type == StoreExpr::neClosure)
-        return unparseClosure(ne.closure);
-    else if (ne.type == StoreExpr::neDerivation)
-        return unparseDerivation(ne.derivation);
-    else abort();
-}