diff options
Diffstat (limited to 'src/libstore/derivations.cc')
-rw-r--r-- | src/libstore/derivations.cc | 224 |
1 files changed, 114 insertions, 110 deletions
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index bc2ec1f90..e321ae8aa 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -1,22 +1,12 @@ #include "derivations.hh" #include "store-api.hh" -#include "aterm.hh" #include "globals.hh" #include "util.hh" -#include "derivations-ast.hh" -#include "derivations-ast.cc" - namespace nix { -Hash hashTerm(ATerm t) -{ - return hashString(htSHA256, atPrint(t)); -} - - Path writeDerivation(const Derivation & drv, const string & name) { PathSet references; @@ -27,137 +17,151 @@ Path writeDerivation(const Derivation & drv, const string & name) (that can be missing (of course) and should not necessarily be held during a garbage collection). */ string suffix = name + drvExtension; - string contents = atPrint(unparseDerivation(drv)); + string contents = unparseDerivation(drv); return readOnlyMode ? computeStorePathForText(suffix, contents, references) : store->addTextToStore(suffix, contents, references); } -static void checkPath(const string & s) +static Path parsePath(std::istream & str) { + string s = parseString(str); if (s.size() == 0 || s[0] != '/') throw Error(format("bad path `%1%' in derivation") % s); + return s; } -static void parseStrings(ATermList paths, StringSet & out, bool arePaths) +static StringSet parseStrings(std::istream & str, bool arePaths) { - for (ATermIterator i(paths); i; ++i) { - if (ATgetType(*i) != AT_APPL) - throw badTerm("not a path", *i); - string s = aterm2String(*i); - if (arePaths) checkPath(s); - out.insert(s); - } + StringSet res; + while (!endOfList(str)) + res.insert(arePaths ? parsePath(str) : parseString(str)); + return res; } + - -/* Shut up warnings. */ -void throwBadDrv(ATerm t) __attribute__ ((noreturn)); - -void throwBadDrv(ATerm t) -{ - throw badTerm("not a valid derivation", t); -} - - -Derivation parseDerivation(ATerm t) +Derivation parseDerivation(const string & s) { Derivation drv; - ATermList outs, inDrvs, inSrcs, args, bnds; - ATerm builder, platform; + std::istringstream str(s); + expect(str, "Derive(["); - 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)) - throwBadDrv(t); + /* Parse the list of outputs. */ + while (!endOfList(str)) { DerivationOutput out; - out.path = aterm2String(path); - checkPath(out.path); - out.hashAlgo = aterm2String(hashAlgo); - out.hash = aterm2String(hash); - drv.outputs[aterm2String(id)] = out; + expect(str, "("); string id = parseString(str); + expect(str, ","); out.path = parsePath(str); + expect(str, ","); out.hashAlgo = parseString(str); + expect(str, ","); out.hash = parseString(str); + expect(str, ")"); + drv.outputs[id] = out; } - for (ATermIterator i(inDrvs); i; ++i) { - ATerm drvPath; - ATermList ids; - if (!matchDerivationInput(*i, drvPath, ids)) - throwBadDrv(t); - Path drvPath2 = aterm2String(drvPath); - checkPath(drvPath2); - StringSet ids2; - parseStrings(ids, ids2, false); - drv.inputDrvs[drvPath2] = ids2; + /* Parse the list of input derivations. */ + expect(str, ",["); + while (!endOfList(str)) { + expect(str, "("); + Path drvPath = parsePath(str); + expect(str, ",["); + drv.inputDrvs[drvPath] = parseStrings(str, false); + expect(str, ")"); } - - parseStrings(inSrcs, drv.inputSrcs, true); - drv.builder = aterm2String(builder); - drv.platform = aterm2String(platform); - - for (ATermIterator i(args); i; ++i) { - if (ATgetType(*i) != AT_APPL) - throw badTerm("string expected", *i); - drv.args.push_back(aterm2String(*i)); + expect(str, ",["); drv.inputSrcs = parseStrings(str, true); + expect(str, ","); drv.platform = parseString(str); + expect(str, ","); drv.builder = parseString(str); + + /* Parse the builder arguments. */ + expect(str, ",["); + while (!endOfList(str)) + drv.args.push_back(parseString(str)); + + /* Parse the environment variables. */ + expect(str, ",["); + while (!endOfList(str)) { + expect(str, "("); string name = parseString(str); + expect(str, ","); string value = parseString(str); + expect(str, ")"); + drv.env[name] = value; } + + expect(str, ")"); + return drv; +} - for (ATermIterator i(bnds); i; ++i) { - ATerm s1, s2; - if (!matchEnvBinding(*i, s1, s2)) - throw badTerm("tuple of strings expected", *i); - drv.env[aterm2String(s1)] = aterm2String(s2); - } - return drv; +static void printString(string & res, const string & s) +{ + res += '"'; + for (const char * i = s.c_str(); *i; i++) + if (*i == '\"' || *i == '\\') { res += "\\"; res += *i; } + else if (*i == '\n') res += "\\n"; + else if (*i == '\r') res += "\\r"; + else if (*i == '\t') res += "\\t"; + else res += *i; + res += '"'; } -ATerm unparseDerivation(const Derivation & drv) +template<class ForwardIterator> +static void printStrings(string & res, ForwardIterator i, ForwardIterator j) { - ATermList outputs = ATempty; - for (DerivationOutputs::const_reverse_iterator i = drv.outputs.rbegin(); - i != drv.outputs.rend(); ++i) - outputs = ATinsert(outputs, - makeDerivationOutput( - toATerm(i->first), - toATerm(i->second.path), - toATerm(i->second.hashAlgo), - toATerm(i->second.hash))); - - ATermList inDrvs = ATempty; - for (DerivationInputs::const_reverse_iterator i = drv.inputDrvs.rbegin(); - i != drv.inputDrvs.rend(); ++i) - inDrvs = ATinsert(inDrvs, - makeDerivationInput( - toATerm(i->first), - toATermList(i->second))); + res += '['; + bool first = true; + for ( ; i != j; ++i) { + if (first) first = false; else res += ','; + printString(res, *i); + } + res += ']'; +} + + +string unparseDerivation(const Derivation & drv) +{ + string s; + s.reserve(65536); + s += "Derive(["; + + bool first = true; + foreach (DerivationOutputs::const_iterator, i, drv.outputs) { + if (first) first = false; else s += ','; + s += '('; printString(s, i->first); + s += ','; printString(s, i->second.path); + s += ','; printString(s, i->second.hashAlgo); + s += ','; printString(s, i->second.hash); + s += ')'; + } + + s += "],["; + first = true; + foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) { + if (first) first = false; else s += ','; + s += '('; printString(s, i->first); + s += ','; printStrings(s, i->second.begin(), i->second.end()); + s += ')'; + } + + s += "],"; + printStrings(s, drv.inputSrcs.begin(), drv.inputSrcs.end()); + + s += ','; printString(s, drv.platform); + s += ','; printString(s, drv.builder); + s += ','; printStrings(s, drv.args.begin(), drv.args.end()); + + s += ",["; + first = true; + foreach (StringPairs::const_iterator, i, drv.env) { + if (first) first = false; else s += ','; + s += '('; printString(s, i->first); + s += ','; printString(s, i->second); + s += ')'; + } + + s += "])"; - ATermList args = ATempty; - for (Strings::const_reverse_iterator i = drv.args.rbegin(); - i != drv.args.rend(); ++i) - args = ATinsert(args, toATerm(*i)); - - ATermList env = ATempty; - for (StringPairs::const_reverse_iterator i = drv.env.rbegin(); - i != drv.env.rend(); ++i) - env = ATinsert(env, - makeEnvBinding( - toATerm(i->first), - toATerm(i->second))); - - return makeDerive( - outputs, - inDrvs, - toATermList(drv.inputSrcs), - toATerm(drv.platform), - toATerm(drv.builder), - args, - env); + return s; } |