aboutsummaryrefslogtreecommitdiff
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 445d68283..f5f92a87b 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 aad961ef5..d15219344 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 a19528164..afbf34dab 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 97bf8f785..b59c4f214 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 5ae5dc22a..387939e93 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 8fc0fa2c3..9c77c68f4 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);