aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/derivations.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/derivations.cc')
-rw-r--r--src/libstore/derivations.cc224
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;
}