diff options
-rw-r--r-- | src/fix.cc | 47 | ||||
-rw-r--r-- | src/fstate.cc | 265 | ||||
-rw-r--r-- | src/fstate.hh | 2 | ||||
-rw-r--r-- | src/hash.cc | 4 | ||||
-rw-r--r-- | src/hash.hh | 4 | ||||
-rw-r--r-- | src/nix.cc | 39 |
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); |