about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/fix.cc2
-rw-r--r--src/fstate.cc87
-rw-r--r--src/fstate.hh12
-rw-r--r--src/nix.cc11
4 files changed, 68 insertions, 44 deletions
diff --git a/src/fix.cc b/src/fix.cc
index b4626f71f329..d17e7b550276 100644
--- a/src/fix.cc
+++ b/src/fix.cc
@@ -180,7 +180,7 @@ static Expr evalExpr(Expr e)
             SYSTEM, builder.c_str(), ins, out.c_str(), env);
 
         /* Write the resulting term into the Nix store directory. */
-        Hash eHash = writeTerm(e);
+        Hash eHash = writeTerm(e, "-d-" + name);
 
         return ATmake("Include(<str>)", ((string) eHash).c_str());
     }
diff --git a/src/fstate.cc b/src/fstate.cc
index 344197748444..2f0e50fb2d0e 100644
--- a/src/fstate.cc
+++ b/src/fstate.cc
@@ -1,5 +1,4 @@
 #include <map>
-#include <set>
 #include <iostream>
 
 #include <sys/types.h>
@@ -148,30 +147,50 @@ Hash hashTerm(ATerm t)
 }
 
 
-ATerm termFromHash(const Hash & hash)
+ATerm termFromHash(const Hash & hash, string * p)
 {
     string path = queryPathByHash(hash);
+    if (p) *p = path;
     ATerm t = ATreadFromNamedFile(path.c_str());
     if (!t) throw Error(format("cannot read aterm %1%") % path);
     return t;
 }
 
 
-Hash writeTerm(ATerm t)
+Hash writeTerm(ATerm t, const string & suffix, string * p)
 {
     string path = nixStore + "/tmp.nix"; /* !!! */
     if (!ATwriteToNamedTextFile(t, path.c_str()))
         throw Error(format("cannot write aterm %1%") % path);
     Hash hash = hashPath(path);
-    string path2 = canonPath(nixStore + "/" + (string) hash + ".nix");
+    string path2 = canonPath(nixStore + "/" + 
+        (string) hash + suffix + ".nix");
     if (rename(path.c_str(), path2.c_str()) == -1)
         throw SysError(format("renaming %1% to %2%") % path % path2);
     registerPath(path2, hash);
+    if (p) *p = path2;
     return hash;
 }
 
 
-static FState realise(FState fs)
+FState storeSuccessor(FState fs, FState sc, StringSet & paths)
+{
+    if (fs == sc) return sc;
+    
+    string path;
+    Hash fsHash = hashTerm(fs);
+    Hash scHash = writeTerm(sc, "-s-" + (string) fsHash, &path);
+    setDB(nixDB, dbSuccessors, fsHash, scHash);
+    paths.insert(path);
+
+#if 0
+    return ATmake("Include(<str>)", ((string) scHash).c_str());
+#endif
+    return sc;
+}
+
+
+static FState realise(FState fs, StringSet & paths)
 {
     char * s1, * s2, * s3;
     Content content;
@@ -183,7 +202,9 @@ static FState realise(FState fs)
         string fsHash, scHash;
         while (queryDB(nixDB, dbSuccessors, fsHash = hashTerm(fs), scHash)) {
             debug(format("successor %1% -> %2%") % (string) fsHash % scHash);
-            FState fs2 = termFromHash(parseHash(scHash));
+            string path;
+            FState fs2 = termFromHash(parseHash(scHash), &path);
+            paths.insert(path);
             if (fs == fs2) {
                 debug(format("successor cycle detected in %1%") % printTerm(fs));
                 break;
@@ -195,7 +216,10 @@ static FState realise(FState fs)
     /* Fall through. */
 
     if (ATmatch(fs, "Include(<str>)", &s1)) {
-        return realise(termFromHash(parseHash(s1)));
+        string path;
+        fs = termFromHash(parseHash(s1), &path);
+        paths.insert(path);
+        return realise(fs, paths);
     }
     
     else if (ATmatch(fs, "Path(<str>, <term>, [<list>])", &s1, &content, &refs)) {
@@ -210,7 +234,7 @@ static FState realise(FState fs)
         /* Realise referenced paths. */
         ATermList refs2 = ATempty;
         while (!ATisEmpty(refs)) {
-            refs2 = ATinsert(refs2, realise(ATgetFirst(refs)));
+            refs2 = ATinsert(refs2, realise(ATgetFirst(refs), paths));
             refs = ATgetNext(refs);
         }
         refs2 = ATreverse(refs2);
@@ -224,27 +248,26 @@ static FState realise(FState fs)
             path.c_str(), content, refs2);
 
         /* Register the normal form. */
-        if (fs != nf) {
-            Hash nfHash = writeTerm(nf);
-            setDB(nixDB, dbSuccessors, hashTerm(fs), nfHash);
-        }
-
+        nf = storeSuccessor(fs, nf, paths);
+        
         /* Perhaps the path already exists and has the right hash? */
         if (pathExists(path)) {
-            if (hash == hashPath(path)) {
-                debug(format("path %1% already has hash %2%")
+
+            if (hash != hashPath(path))
+                throw Error(format("path %1% exists, but does not have hash %2%")
                     % path % (string) hash);
-                return nf;
-            }
 
-            throw Error(format("path %1% exists, but does not have hash %2%")
+            debug(format("path %1% already has hash %2%")
                 % path % (string) hash);
-        }
-
-        /* Do we know a path with that hash?  If so, copy it. */
-        string path2 = queryPathByHash(hash);
-        copyPath(path2, path);
 
+        } else {
+            
+            /* Do we know a path with that hash?  If so, copy it. */
+            string path2 = queryPathByHash(hash);
+            copyPath(path2, path);
+            
+        }
+        
         return nf;
     }
 
@@ -261,7 +284,7 @@ static FState realise(FState fs)
         /* Realise inputs. */
         ATermList ins2 = ATempty;
         while (!ATisEmpty(ins)) {
-            ins2 = ATinsert(ins2, realise(ATgetFirst(ins)));
+            ins2 = ATinsert(ins2, realise(ATgetFirst(ins), paths));
             ins = ATgetNext(ins);
         }
         ins2 = ATreverse(ins2);
@@ -306,8 +329,7 @@ static FState realise(FState fs)
         /* Register the normal form of fs. */
         FState nf = ATmake("Path(<str>, Hash(<str>), <term>)",
             outPath.c_str(), ((string) outHash).c_str(), ins2);
-        Hash nfHash = writeTerm(nf);
-        setDB(nixDB, dbSuccessors, hashTerm(fs), nfHash);
+        nf = storeSuccessor(fs, nf, paths);
 
         return nf;
     }
@@ -316,9 +338,9 @@ static FState realise(FState fs)
 }
 
 
-FState realiseFState(FState fs)
+FState realiseFState(FState fs, StringSet & paths)
 {
-    return realise(fs);
+    return realise(fs, paths);
 }
 
 
@@ -338,9 +360,6 @@ string fstatePath(FState fs)
 }
 
 
-typedef set<string> StringSet;
-
-
 void fstateRefs2(FState fs, StringSet & paths)
 {
     char * s1, * s2, * s3;
@@ -372,11 +391,7 @@ void fstateRefs2(FState fs, StringSet & paths)
 }
 
 
-Strings fstateRefs(FState fs)
+void fstateRefs(FState fs, StringSet & paths)
 {
-    StringSet paths;
     fstateRefs2(fs, paths);
-    Strings paths2(paths.size());
-    copy(paths.begin(), paths.end(), paths2.begin());
-    return paths2;
 }
diff --git a/src/fstate.hh b/src/fstate.hh
index de6303dca1e4..159c7ba46338 100644
--- a/src/fstate.hh
+++ b/src/fstate.hh
@@ -1,6 +1,8 @@
 #ifndef __EVAL_H
 #define __EVAL_H
 
+#include <set>
+
 extern "C" {
 #include <aterm2.h>
 }
@@ -59,17 +61,19 @@ using namespace std;
 typedef ATerm FState;
 typedef ATerm Content;
 
+typedef set<string> StringSet;
+
 
 /* Realise an fstate expression in the file system.  This requires
    execution of all Derive() nodes. */
-FState realiseFState(FState fs);
+FState realiseFState(FState fs, StringSet & paths);
 
 /* Return the path of an fstate expression.  An empty string is
    returned if the term is not a valid fstate expression. (!!!) */
 string fstatePath(FState fs);
 
 /* Return the paths referenced by fstate expression. */
-Strings fstateRefs(FState fs);
+void fstateRefs(FState fs, StringSet & paths);
 
 /* Return a canonical textual representation of an expression. */
 string printTerm(ATerm t);
@@ -82,10 +86,10 @@ Error badTerm(const format & f, ATerm t);
 Hash hashTerm(ATerm t);
 
 /* Read an aterm from disk, given its hash. */
-ATerm termFromHash(const Hash & hash);
+ATerm termFromHash(const Hash & hash, string * p = 0);
 
 /* Write an aterm to the Nix store directory, and return its hash. */
-Hash writeTerm(ATerm t);
+Hash writeTerm(ATerm t, const string & suffix, string * p = 0);
 
 
 #endif /* !__EVAL_H */
diff --git a/src/nix.cc b/src/nix.cc
index f3549ead8442..d6f2db4fefd1 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -96,7 +96,10 @@ static void opInstall(Strings opFlags, Strings opArgs)
 
     for (Strings::iterator it = opArgs.begin();
          it != opArgs.end(); it++)
-        realiseFState(termFromHash(argToHash(*it)));
+    {
+        StringSet paths;
+        realiseFState(termFromHash(argToHash(*it)), paths);
+    }
 }
 
 
@@ -160,8 +163,10 @@ static void opQuery(Strings opFlags, Strings opArgs)
             break;
 
         case qRefs: {
-            Strings refs = fstateRefs(realiseFState(termFromHash(hash)));
-            for (Strings::iterator j = refs.begin(); 
+            StringSet refs;
+            FState fs = ATmake("Include(<str>)", ((string) hash).c_str());
+            fstateRefs(realiseFState(fs, refs), refs);
+            for (StringSet::iterator j = refs.begin(); 
                  j != refs.end(); j++)
                 cout << format("%s\n") % *j;
             break;