about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fix.cc47
-rw-r--r--src/fstate.cc265
-rw-r--r--src/fstate.hh2
-rw-r--r--src/hash.cc4
-rw-r--r--src/hash.hh4
-rw-r--r--src/nix.cc39
6 files changed, 93 insertions, 268 deletions
diff --git a/src/fix.cc b/src/fix.cc
index 445d682837ff..f5f92a87b568 100644
--- a/src/fix.cc
+++ b/src/fix.cc
@@ -107,11 +107,10 @@ static Expr evalExpr(Expr e)
 
     /* Normal forms. */
     if (ATmatch(e, "<str>", &s1) ||
-        ATmatch(e, "Function([<list>], <term>)", &e1, &e2))
+        ATmatch(e, "Function([<list>], <term>)", &e1, &e2) ||
+        ATmatch(e, "FSId(<str>)", &s1))
         return e;
 
-    if (fstatePath(e) != "") return e; /* !!! hack */
-
     /* Application. */
     if (ATmatch(e, "App(<term>, [<list>])", &e1, &e2)) {
         e1 = evalExpr(e1);
@@ -130,10 +129,12 @@ static Expr evalExpr(Expr e)
     if (ATmatch(e, "Relative(<str>)", &s1)) {
         string srcPath = searchPath(s1);
         string dstPath;
-        Hash hash;
-        addToStore(srcPath, dstPath, hash, true);
-        return ATmake("Path(<str>, Hash(<str>), [])",
-            dstPath.c_str(), ((string) hash).c_str());
+        FSId id;
+        addToStore(srcPath, dstPath, id, true);
+        FState fs = ATmake("Slice([<str>], [(<str>, <str>, [])])",
+            ((string) id).c_str(), dstPath.c_str(), ((string) id).c_str());
+        return ATmake("FSId(<str>)", 
+            ((string) writeTerm(fs, "", 0)).c_str());
     }
 
     /* Packages are transformed into Derive fstate expressions. */
@@ -160,10 +161,13 @@ static Expr evalExpr(Expr e)
         {
             string key = it->first;
             ATerm value = it->second;
+            char * id;
 
-            string path = fstatePath(value);
-            if (path != "") {
-                ins = ATinsert(ins, value);
+            if (ATmatch(value, "FSId(<str>)", &id)) {
+                Strings paths = fstatePaths(parseHash(id));
+                if (paths.size() != 1) abort();
+                string path = *(paths.begin());
+                ins = ATinsert(ins, ATmake("<str>", id));
                 env = ATinsert(env, ATmake("(<str>, <str>)",
                     key.c_str(), path.c_str()));
                 if (key == "build") builder = path;
@@ -182,7 +186,7 @@ static Expr evalExpr(Expr e)
         /* Hash the normal form to produce a unique but deterministic
            path name for this package. */
         ATerm nf = ATmake("Package(<term>)", ATreverse(bnds));
-        Hash hash = hashTerm(nf);
+        FSId outId = hashTerm(nf);
 
         if (builder == "")
             throw badTerm("no builder specified", nf);
@@ -190,19 +194,20 @@ static Expr evalExpr(Expr e)
         if (name == "")
             throw badTerm("no package name specified", nf);
         
-        string out = 
-            canonPath(nixStore + "/" + ((string) hash).c_str() + "-" + name);
-
-        env = ATinsert(env, ATmake("(<str>, <str>)", "out", out.c_str()));
+        string outPath = 
+            canonPath(nixStore + "/" + ((string) outId).c_str() + "-" + name);
 
+        env = ATinsert(env, ATmake("(<str>, <str>)", "out", outPath.c_str()));
+        
         /* Construct the result. */
-        e = ATmake("Derive(<str>, <str>, <term>, <str>, <term>)",
-            SYSTEM, builder.c_str(), ins, out.c_str(), env);
+        FState fs = 
+            ATmake("Derive([(<str>, <str>)], <term>, <str>, <str>, <term>)",
+                outPath.c_str(), ((string) outId).c_str(),
+                ins, builder.c_str(), SYSTEM, env);
 
         /* Write the resulting term into the Nix store directory. */
-        Hash eHash = writeTerm(e, "-d-" + name);
-
-        return ATmake("Include(<str>)", ((string) eHash).c_str());
+        return ATmake("FSId(<str>)", 
+            ((string) writeTerm(fs, "-d-" + name, 0)).c_str());
     }
 
     /* BaseName primitive function. */
@@ -258,7 +263,7 @@ void run(Strings args)
     {
         Expr e = evalFile(*it);
         char * s;
-        if (ATmatch(e, "Include(<str>)", &s)) {
+        if (ATmatch(e, "FSId(<str>)", &s)) {
             cout << format("%1%\n") % s;
         }
         else throw badTerm("top level is not a package", e);
diff --git a/src/fstate.cc b/src/fstate.cc
index aad961ef58e8..d15219344fc9 100644
--- a/src/fstate.cc
+++ b/src/fstate.cc
@@ -194,228 +194,6 @@ static FSId storeSuccessor(const FSId & id1, FState sc)
 }
 
 
-#if 0
-static FState realise(FState fs, StringSet & paths)
-{
-    char * s1, * s2, * s3;
-    Content content;
-    ATermList refs, ins, bnds;
-
-    /* First repeatedly try to substitute $fs$ by any known successors
-       in order to speed up the rewrite process. */
-    {
-        string fsHash, scHash;
-        while (queryDB(nixDB, dbSuccessors, fsHash = hashTerm(fs), scHash)) {
-            debug(format("successor %1% -> %2%") % (string) fsHash % 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;
-            }
-            fs = fs2;
-        }
-    }
-
-    /* Fall through. */
-
-    if (ATmatch(fs, "Include(<str>)", &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)) {
-        string path(s1);
-
-        msg(format("realising atomic path %1%") % path);
-        Nest nest(true);
-
-        if (path[0] != '/')
-            throw Error(format("path `%1% is not absolute") % path);
-
-        /* Realise referenced paths. */
-        ATermList refs2 = ATempty;
-        while (!ATisEmpty(refs)) {
-            refs2 = ATinsert(refs2, realise(ATgetFirst(refs), paths));
-            refs = ATgetNext(refs);
-        }
-        refs2 = ATreverse(refs2);
-
-        if (!ATmatch(content, "Hash(<str>)", &s1))
-            throw badTerm("hash expected", content);
-        Hash hash = parseHash(s1);
-
-        /* Normal form. */
-        ATerm nf = ATmake("Path(<str>, <term>, <term>)",
-            path.c_str(), content, refs2);
-
-        /* Register the normal form. */
-        nf = storeSuccessor(fs, nf, paths);
-        
-        /* Expand the hash into the target path. */
-        expandHash(hash, path);
-
-        return nf;
-    }
-
-    else if (ATmatch(fs, "Derive(<str>, <str>, [<list>], <str>, [<list>])",
-                 &s1, &s2, &ins, &s3, &bnds)) 
-    {
-        string platform(s1), builder(s2), outPath(s3);
-
-        msg(format("realising derivate path %1%") % outPath);
-        Nest nest(true);
-
-        checkPlatform(platform);
-        
-        /* Realise inputs. */
-        Strings inPaths;
-        ATermList ins2 = ATempty;
-        while (!ATisEmpty(ins)) {
-            FState in = realise(ATgetFirst(ins), paths);
-            inPaths.push_back(fstatePath(in));
-            ins2 = ATinsert(ins2, in);
-            ins = ATgetNext(ins);
-        }
-        ins = ATreverse(ins2);
-
-        /* Build the environment. */
-        Environment env;
-        while (!ATisEmpty(bnds)) {
-            ATerm bnd = ATgetFirst(bnds);
-            if (!ATmatch(bnd, "(<str>, <str>)", &s1, &s2))
-                throw badTerm("tuple of strings expected", bnd);
-            env[s1] = s2;
-            bnds = ATgetNext(bnds);
-        }
-
-        /* Check whether the target already exists. */
-        if (pathExists(outPath))
-            deleteFromStore(outPath);
-//             throw Error(format("path %1% already exists") % outPath);
-
-        /* Run the builder. */
-        runProgram(builder, env);
-        
-        /* Check whether the result was created. */
-        if (!pathExists(outPath))
-            throw Error(format("program %1% failed to create a result in %2%")
-                % builder % outPath);
-
-#if 0
-        /* Remove write permission from the value. */
-        int res = system(("chmod -R -w " + targetPath).c_str()); // !!! escaping
-        if (WEXITSTATUS(res) != 0)
-            throw Error("cannot remove write permission from " + targetPath);
-#endif
-
-        /* Hash the result. */
-        Hash outHash = hashPath(outPath);
-
-        /* Register targetHash -> targetPath.  !!! this should be in
-           values.cc. */
-        registerPath(outPath, outHash);
-
-        /* Filter out inputs that are not referenced in the output. */
-        for (Strings::iterator i = inPaths.begin();
-             i != inPaths.end(); i++)
-            debug(format("in: %1%") % *i);
-
-        Strings outPaths = filterReferences(outPath, inPaths);
-
-        for (Strings::iterator i = outPaths.begin();
-             i != outPaths.end(); i++)
-            debug(format("out: %1%") % *i);
-
-        ins2 = ATempty;
-        while (!ATisEmpty(ins)) {
-            FState in = ATgetFirst(ins);
-            string path = fstatePath(in);
-            for (Strings::iterator i = outPaths.begin();
-                 i != outPaths.end(); i++)
-                if (path.find(*i) != string::npos) {
-                    debug(format("out2: %1%") % path);
-                    ins2 = ATinsert(ins2, in);
-                }
-            ins = ATgetNext(ins);
-        }
-        ins = ATreverse(ins2);
-        
-        /* Register the normal form of fs. */
-        FState nf = ATmake("Path(<str>, Hash(<str>), <term>)",
-            outPath.c_str(), ((string) outHash).c_str(), ins);
-        nf = storeSuccessor(fs, nf, paths);
-
-        return nf;
-    }
-
-    throw badTerm("bad fstate expression", fs);
-}
-
-
-FState realiseFState(FState fs, StringSet & paths)
-{
-    return realise(fs, paths);
-}
-
-
-string fstatePath(FState fs)
-{
-    char * s1, * s2, * s3;
-    FState e1, e2;
-    if (ATmatch(fs, "Path(<str>, <term>, [<list>])", &s1, &e1, &e2))
-        return s1;
-    else if (ATmatch(fs, "Derive(<str>, <str>, [<list>], <str>, [<list>])",
-                   &s1, &s2, &e1, &s3, &e2))
-        return s3;
-    else if (ATmatch(fs, "Include(<str>)", &s1))
-        return fstatePath(termFromHash(parseHash(s1)));
-    else
-        return "";
-}
-
-
-void fstateRefs2(FState fs, StringSet & paths)
-{
-    char * s1, * s2, * s3;
-    FState e1, e2;
-    ATermList refs, ins;
-
-    if (ATmatch(fs, "Path(<str>, <term>, [<list>])", &s1, &e1, &refs)) {
-        paths.insert(s1);
-
-        while (!ATisEmpty(refs)) {
-            fstateRefs2(ATgetFirst(refs), paths);
-            refs = ATgetNext(refs);
-        }
-    }
-
-    else if (ATmatch(fs, "Derive(<str>, <str>, [<list>], <str>, [<list>])", 
-            &s1, &s2, &ins, &s3, &e2))
-    {
-        while (!ATisEmpty(ins)) {
-            fstateRefs2(ATgetFirst(ins), paths);
-            ins = ATgetNext(ins);
-        }
-    }
-
-    else if (ATmatch(fs, "Include(<str>)", &s1))
-        fstateRefs2(termFromHash(parseHash(s1)), paths);
-
-    else throw badTerm("bad fstate expression", fs);
-}
-
-
-void fstateRefs(FState fs, StringSet & paths)
-{
-    fstateRefs2(fs, paths);
-}
-#endif
-
-
 static void parseIds(ATermList ids, FSIds & out)
 {
     while (!ATisEmpty(ids)) {
@@ -424,7 +202,6 @@ static void parseIds(ATermList ids, FSIds & out)
         if (!ATmatch(id, "<str>", &s))
             throw badTerm("not an id", id);
         out.push_back(parseHash(s));
-        debug(s);
         ids = ATgetNext(ids);
     }
 }
@@ -691,3 +468,45 @@ void realiseSlice(const Slice & slice)
         expandId(elem.id, elem.path);
     }
 }
+
+
+Strings fstatePaths(FSId id)
+{
+    Strings paths;
+
+    FState fs = termFromId(id);
+
+    ATermList outs, ins, bnds;
+    char * builder;
+    char * platform;
+
+    if (ATgetType(fs) == AT_APPL && 
+        (string) ATgetName(ATgetAFun(fs)) == "Slice")
+    {
+        Slice slice = parseSlice(fs);
+
+        /* !!! fix complexity */
+        for (FSIds::const_iterator i = slice.roots.begin();
+             i != slice.roots.end(); i++)
+            for (SliceElems::const_iterator j = slice.elems.begin();
+                 j != slice.elems.end(); j++)
+                if (*i == j->id) paths.push_back(j->path);
+    }
+
+    else if (ATmatch(fs, "Derive([<list>], [<list>], <str>, <str>, [<list>])",
+                 &outs, &ins, &builder, &platform, &bnds))
+    {
+        while (!ATisEmpty(outs)) {
+            ATerm t = ATgetFirst(outs);
+            char * s1, * s2;
+            if (!ATmatch(t, "(<str>, <str>)", &s1, &s2))
+                throw badTerm("string expected", t);
+            paths.push_back(s1);
+            outs = ATgetNext(outs);
+        }
+    }
+    
+    else throw badTerm("in fstatePaths", fs);
+
+    return paths;
+}
diff --git a/src/fstate.hh b/src/fstate.hh
index a195281646b6..afbf34dab28a 100644
--- a/src/fstate.hh
+++ b/src/fstate.hh
@@ -115,5 +115,7 @@ Slice normaliseFState(FSId id);
 /* Realise a Slice in the file system. */
 void realiseSlice(const Slice & slice);
 
+Strings fstatePaths(FSId id);
+
 
 #endif /* !__FSTATE_H */
diff --git a/src/hash.cc b/src/hash.cc
index 97bf8f7856f0..b59c4f214831 100644
--- a/src/hash.cc
+++ b/src/hash.cc
@@ -14,7 +14,7 @@ Hash::Hash()
 }
 
 
-bool Hash::operator == (Hash h2)
+bool Hash::operator == (const Hash & h2) const
 {
     for (unsigned int i = 0; i < hashSize; i++)
         if (hash[i] != h2.hash[i]) return false;
@@ -22,7 +22,7 @@ bool Hash::operator == (Hash h2)
 }
 
 
-bool Hash::operator != (Hash h2)
+bool Hash::operator != (const Hash & h2) const
 {
     return !(*this == h2);
 }
diff --git a/src/hash.hh b/src/hash.hh
index 5ae5dc22aed8..387939e9311a 100644
--- a/src/hash.hh
+++ b/src/hash.hh
@@ -17,10 +17,10 @@ struct Hash
     Hash();
 
     /* Check whether two hash are equal. */
-    bool operator == (Hash h2);
+    bool operator == (const Hash & h2) const;
 
     /* Check whether two hash are not equal. */
-    bool operator != (Hash h2);
+    bool operator != (const Hash & h2) const;
 
     /* For sorting. */
     bool operator < (const Hash & h) const;
diff --git a/src/nix.cc b/src/nix.cc
index 8fc0fa2c325c..9c77c68f4110 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -41,7 +41,7 @@ static ArgType argType = atpUnknown;
    Source selection for --install, --dump:
 
      --file / -f: by file name  !!! -> path
-     --hash / -h: by hash
+     --hash / -h: by hash (identifier)
 
    Query flags:
 
@@ -76,15 +76,15 @@ static void getArgType(Strings & flags)
 }
 
 
-static Hash argToHash(const string & arg)
+static FSId argToId(const string & arg)
 {
     if (argType == atpHash)
         return parseHash(arg);
     else if (argType == atpPath) {
         string path;
-        Hash hash;
-        addToStore(arg, path, hash);
-        return hash;
+        FSId id;
+        addToStore(arg, path, id);
+        return id;
     }
     else abort();
 }
@@ -99,10 +99,7 @@ static void opInstall(Strings opFlags, Strings opArgs)
 
     for (Strings::iterator it = opArgs.begin();
          it != opArgs.end(); it++)
-    {
-        StringSet paths;
-        realiseFState(hash2fstate(argToHash(*it)), paths);
-    }
+        realiseSlice(normaliseFState(argToId(*it)));
 }
 
 
@@ -128,9 +125,9 @@ static void opAdd(Strings opFlags, Strings opArgs)
          it != opArgs.end(); it++)
     {
         string path;
-        Hash hash;
-        addToStore(*it, path, hash);
-        cout << format("%1% %2%\n") % (string) hash % path;
+        FSId id;
+        addToStore(*it, path, id);
+        cout << format("%1% %2%\n") % (string) id % path;
     }
 }
 
@@ -156,10 +153,11 @@ static void opQuery(Strings opFlags, Strings opArgs)
     for (Strings::iterator it = opArgs.begin();
          it != opArgs.end(); it++)
     {
-        Hash hash = argToHash(*it);
+        FSId id = argToId(*it);
 
         switch (query) {
 
+#if 0
         case qPath: {
             StringSet refs;
             cout << format("%s\n") % 
@@ -176,6 +174,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
                 cout << format("%s\n") % *j;
             break;
         }
+#endif
 
         default:
             abort();
@@ -192,9 +191,9 @@ static void opSuccessor(Strings opFlags, Strings opArgs)
     for (Strings::iterator i = opArgs.begin();
          i != opArgs.end(); )
     {
-        Hash fsHash = parseHash(*i++);
-        Hash scHash = parseHash(*i++);
-        registerSuccessor(fsHash, scHash);
+        FSId id1 = parseHash(*i++);
+        FSId id2 = parseHash(*i++);
+        registerSuccessor(id1, id2);
     }
 }
 
@@ -207,9 +206,9 @@ static void opSubstitute(Strings opFlags, Strings opArgs)
     for (Strings::iterator i = opArgs.begin();
          i != opArgs.end(); )
     {
-        Hash srcHash = parseHash(*i++);
-        Hash subHash = parseHash(*i++);
-        registerSubstitute(srcHash, subHash);
+        FSId src = parseHash(*i++);
+        FSId sub = parseHash(*i++);
+        registerSubstitute(src, sub);
     }
 }
 
@@ -238,7 +237,7 @@ static void opDump(Strings opFlags, Strings opArgs)
     string arg = *opArgs.begin();
     string path;
     
-    if (argType == atpHash) path = expandHash(parseHash(arg));
+    if (argType == atpHash) path = expandId(parseHash(arg));
     else if (argType == atpPath) path = arg;
 
     dumpPath(path, sink);