aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-19 13:46:58 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-19 13:46:58 +0000
commitefc7a579e880ec15ebe9afc0d8766c85c7d53ec2 (patch)
treec83d553fcdc3f3497b6645baa198288d499054a1
parent55b5ddd3ca1ff4dfe4cfbfab92a4025d88ef6443 (diff)
* Don't use the ATerm library for parsing/printing .drv files.
-rw-r--r--src/libexpr/primops.cc2
-rw-r--r--src/libmain/shared.cc10
-rw-r--r--src/libstore/Makefile.am7
-rw-r--r--src/libstore/derivations-ast.def10
-rw-r--r--src/libstore/derivations.cc223
-rw-r--r--src/libstore/derivations.hh11
-rw-r--r--src/libstore/local-store.cc2
-rw-r--r--src/libstore/misc.cc6
-rw-r--r--src/libutil/Makefile.am6
-rw-r--r--src/libutil/aterm.cc55
-rw-r--r--src/libutil/aterm.hh55
-rw-r--r--src/libutil/util.cc41
-rw-r--r--src/libutil/util.hh35
-rw-r--r--src/nix-env/user-env.cc41
14 files changed, 174 insertions, 330 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index c5579679c..b28201593 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -262,7 +262,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
}
drv.inputDrvs = inputs2;
- return hashTerm(unparseDerivation(drv));
+ return hashString(htSHA256, unparseDerivation(drv));
}
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index d9cf9a862..825e87621 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -87,9 +87,6 @@ static void setLogType(string lt)
}
-void initDerivationsHelpers();
-
-
static void closeStore()
{
try {
@@ -176,9 +173,6 @@ static void initAndRun(int argc, char * * argv)
string lt = getEnv("NIX_LOG_TYPE");
if (lt != "") setLogType(lt);
- /* ATerm stuff. !!! find a better place to put this */
- initDerivationsHelpers();
-
/* Put the arguments in a vector. */
Strings args, remaining;
while (argc--) args.push_back(*argv++);
@@ -333,10 +327,6 @@ int main(int argc, char * * argv)
if (argc == 0) abort();
setuidInit();
- /* ATerm setup. */
- ATerm bottomOfStack;
- ATinit(argc, argv, &bottomOfStack);
-
/* Turn on buffering for cerr. */
#if HAVE_PUBSETBUF
std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
diff --git a/src/libstore/Makefile.am b/src/libstore/Makefile.am
index 863871519..47681242f 100644
--- a/src/libstore/Makefile.am
+++ b/src/libstore/Makefile.am
@@ -12,12 +12,5 @@ pkginclude_HEADERS = \
libstore_la_LIBADD = ../libutil/libutil.la ../boost/format/libformat.la @ADDITIONAL_NETWORK_LIBS@
-BUILT_SOURCES = derivations-ast.cc derivations-ast.hh
-
-EXTRA_DIST = derivations-ast.def derivations-ast.cc
-
AM_CXXFLAGS = -Wall \
-I$(srcdir)/.. ${aterm_include} -I$(srcdir)/../libutil
-
-derivations-ast.cc derivations-ast.hh: ../aterm-helper.pl derivations-ast.def
- $(perl) $(srcdir)/../aterm-helper.pl derivations-ast.hh derivations-ast.cc < $(srcdir)/derivations-ast.def
diff --git a/src/libstore/derivations-ast.def b/src/libstore/derivations-ast.def
deleted file mode 100644
index 574529ae7..000000000
--- a/src/libstore/derivations-ast.def
+++ /dev/null
@@ -1,10 +0,0 @@
-init initDerivationsHelpers
-
-Derive | ATermList ATermList ATermList string string ATermList ATermList | ATerm |
-
-| string string | ATerm | EnvBinding |
-| string ATermList | ATerm | DerivationInput |
-| string string string string | ATerm | DerivationOutput |
-
-Closure | ATermList ATermList | ATerm | OldClosure |
-| string ATermList | ATerm | OldClosureElem |
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index bc2ec1f90..3d0f1eb42 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,150 @@ 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;
+void printString(std::ostream & str, const string & s)
+{
+ str << "\"";
+ for (const char * i = s.c_str(); *i; i++)
+ if (*i == '\"' || *i == '\\') str << "\\" << *i;
+ else if (*i == '\n') str << "\\n";
+ else if (*i == '\r') str << "\\r";
+ else if (*i == '\t') str << "\\t";
+ else str << *i;
+ str << "\"";
}
-ATerm unparseDerivation(const Derivation & drv)
+template<class ForwardIterator>
+void printStrings(std::ostream & str, 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)));
+ str << "[";
+ bool first = true;
+ for ( ; i != j; ++i) {
+ if (first) first = false; else str << ",";
+ printString(str, *i);
+ }
+ str << "]";
+}
+
+
+string unparseDerivation(const Derivation & drv)
+{
+ std::ostringstream str;
+ str << "Derive([";
+
+ bool first = true;
+ foreach (DerivationOutputs::const_iterator, i, drv.outputs) {
+ if (first) first = false; else str << ",";
+ str << "("; printString(str, i->first);
+ str << ","; printString(str, i->second.path);
+ str << ","; printString(str, i->second.hashAlgo);
+ str << ","; printString(str, i->second.hash);
+ str << ")";
+ }
+
+ str << "],[";
+ first = true;
+ foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
+ if (first) first = false; else str << ",";
+ str << "("; printString(str, i->first);
+ str << ","; printStrings(str, i->second.begin(), i->second.end());
+ str << ")";
+ }
+
+ str << "],";
+ printStrings(str, drv.inputSrcs.begin(), drv.inputSrcs.end());
+
+ str << ","; printString(str, drv.platform);
+ str << ","; printString(str, drv.builder);
+ str << ","; printStrings(str, drv.args.begin(), drv.args.end());
+
+ str << ",[";
+ first = true;
+ foreach (StringPairs::const_iterator, i, drv.env) {
+ if (first) first = false; else str << ",";
+ str << "("; printString(str, i->first);
+ str << ","; printString(str, i->second);
+ str << ")";
+ }
+
+ str << "])";
- 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 str.str();
}
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index 042f4738d..95e49d42c 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -1,8 +1,6 @@
#ifndef __DERIVATIONS_H
#define __DERIVATIONS_H
-#include <aterm1.h>
-
#include "hash.hh"
#include <map>
@@ -53,17 +51,14 @@ struct Derivation
};
-/* Hash an aterm. */
-Hash hashTerm(ATerm t);
-
/* Write a derivation to the Nix store, and return its path. */
Path writeDerivation(const Derivation & drv, const string & name);
/* Parse a derivation. */
-Derivation parseDerivation(ATerm t);
+Derivation parseDerivation(const string & s);
-/* Parse a derivation. */
-ATerm unparseDerivation(const Derivation & drv);
+/* Print a derivation. */
+string unparseDerivation(const Derivation & drv);
/* Check whether a file name ends with the extensions for
derivations. */
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index a83ba55e2..2c0aa3579 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -3,8 +3,6 @@
#include "globals.hh"
#include "archive.hh"
#include "pathlocks.hh"
-#include "aterm.hh"
-#include "derivations-ast.hh"
#include "worker-protocol.hh"
#include <iostream>
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 2d7d13a0e..f2cc20626 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -2,8 +2,6 @@
#include "store-api.hh"
#include "local-store.hh"
-#include <aterm2.h>
-
namespace nix {
@@ -12,9 +10,7 @@ Derivation derivationFromPath(const Path & drvPath)
{
assertStorePath(drvPath);
store->ensurePath(drvPath);
- ATerm t = ATreadFromNamedFile(drvPath.c_str());
- if (!t) throw Error(format("cannot read aterm from `%1%'") % drvPath);
- return parseDerivation(t);
+ return parseDerivation(readFile(drvPath));
}
diff --git a/src/libutil/Makefile.am b/src/libutil/Makefile.am
index 55135e373..aa862208c 100644
--- a/src/libutil/Makefile.am
+++ b/src/libutil/Makefile.am
@@ -1,16 +1,16 @@
pkglib_LTLIBRARIES = libutil.la
libutil_la_SOURCES = util.cc hash.cc serialise.cc \
- archive.cc aterm.cc xml-writer.cc
+ archive.cc xml-writer.cc
libutil_la_LIBADD = ../boost/format/libformat.la
pkginclude_HEADERS = util.hh hash.hh serialise.hh \
- archive.hh aterm.hh xml-writer.hh types.hh
+ archive.hh xml-writer.hh types.hh
if !HAVE_OPENSSL
libutil_la_SOURCES += \
md5.c md5.h sha1.c sha1.h sha256.c sha256.h md32_common.h
endif
-AM_CXXFLAGS = -Wall -I$(srcdir)/.. ${aterm_include}
+AM_CXXFLAGS = -Wall -I$(srcdir)/..
diff --git a/src/libutil/aterm.cc b/src/libutil/aterm.cc
deleted file mode 100644
index 25d704785..000000000
--- a/src/libutil/aterm.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "aterm.hh"
-
-#include <cstring>
-
-using std::string;
-
-
-string nix::atPrint(ATerm t)
-{
- if (!t) throw Error("attempt to print null aterm");
- char * s = ATwriteToString(t);
- if (!s) throw Error("cannot print term");
- return s;
-}
-
-
-std::ostream & operator << (std::ostream & stream, ATerm e)
-{
- return stream << nix::atPrint(e);
-}
-
-
-nix::Error nix::badTerm(const format & f, ATerm t)
-{
- char * s = ATwriteToString(t);
- if (!s) throw Error("cannot print term");
- if (strlen(s) > 1000) {
- int len;
- s = ATwriteToSharedString(t, &len);
- if (!s) throw Error("cannot print term");
- }
- return Error(format("%1%, in `%2%'") % f.str() % (string) s);
-}
-
-
-ATerm nix::toATerm(const char * s)
-{
- return (ATerm) ATmakeAppl0(ATmakeAFun((char *) s, 0, ATtrue));
-}
-
-
-ATerm nix::toATerm(const string & s)
-{
- return toATerm(s.c_str());
-}
-
-
-ATermList nix::toATermList(const StringSet & ss)
-{
- ATermList l = ATempty;
- for (StringSet::const_reverse_iterator i = ss.rbegin();
- i != ss.rend(); ++i)
- l = ATinsert(l, toATerm(*i));
- return l;
-}
diff --git a/src/libutil/aterm.hh b/src/libutil/aterm.hh
deleted file mode 100644
index b1cbc3b6d..000000000
--- a/src/libutil/aterm.hh
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __ATERM_H
-#define __ATERM_H
-
-#include <aterm2.h>
-
-#include "types.hh"
-
-
-namespace nix {
-
-
-/* Print an ATerm. */
-string atPrint(ATerm t);
-
-class ATermIterator
-{
- ATermList t;
-
-public:
- ATermIterator(ATermList _t) : t(_t) { }
- ATermIterator & operator ++ ()
- {
- t = ATgetNext(t);
- return *this;
- }
- ATerm operator * ()
- {
- return ATgetFirst(t);
- }
- operator bool ()
- {
- return t != ATempty;
- }
-};
-
-
-/* Throw an exception with an error message containing the given
- aterm. */
-Error badTerm(const format & f, ATerm t);
-
-
-/* Convert strings to ATerms. */
-ATerm toATerm(const char * s);
-ATerm toATerm(const string & s);
-
-ATermList toATermList(const StringSet & ss);
-
-}
-
-
-/* Write an ATerm to an output stream. */
-std::ostream & operator << (std::ostream & stream, ATerm e);
-
-
-#endif /* !__ATERM_H */
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index d28d0e823..98912e7a0 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -1006,6 +1006,47 @@ bool hasSuffix(const string & s, const string & suffix)
}
+void expect(std::istream & str, const string & s)
+{
+ char s2[s.size()];
+ str.read(s2, s.size());
+ if (string(s2, s.size()) != s)
+ throw Error(format("expected string `%1%'") % s);
+}
+
+
+string parseString(std::istream & str)
+{
+ string res;
+ expect(str, "\"");
+ int c;
+ while ((c = str.get()) != '"')
+ if (c == '\\') {
+ c = str.get();
+ if (c == 'n') res += '\n';
+ else if (c == 'r') res += '\r';
+ else if (c == 't') res += '\t';
+ else res += c;
+ }
+ else res += c;
+ return res;
+}
+
+
+bool endOfList(std::istream & str)
+{
+ if (str.peek() == ',') {
+ str.get();
+ return false;
+ }
+ if (str.peek() == ']') {
+ str.get();
+ return true;
+ }
+ return false;
+}
+
+
void ignoreException()
{
try {
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 4de33d3ef..ff710077c 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -302,32 +302,21 @@ string int2String(int n);
bool hasSuffix(const string & s, const string & suffix);
-/* Exception handling in destructors: print an error message, then
- ignore the exception. */
-void ignoreException();
+/* Read string `s' from stream `str'. */
+void expect(std::istream & str, const string & s);
-/* STL functions such as sort() pass a binary function object around
- by value, so it gets cloned a lot. This is bad if the function
- object has state or is simply large. This adapter wraps the
- function object to simulate passing by reference. */
-template<class F>
-struct binary_function_ref_adapter
-{
- F * p;
+/* Read a C-style string from stream `str'. */
+string parseString(std::istream & str);
- binary_function_ref_adapter(F * _p)
- {
- p = _p;
- }
-
- typename F::result_type operator () (
- const typename F::first_argument_type & x,
- const typename F::second_argument_type & y)
- {
- return (*p)(x, y);
- }
-};
+
+/* Utility function used to parse legacy ATerms. */
+bool endOfList(std::istream & str);
+
+
+/* Exception handling in destructors: print an error message, then
+ ignore the exception. */
+void ignoreException();
}
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index 8bb760094..f040f8c11 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -25,33 +25,6 @@ DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
/* Code for parsing manifests in the old textual ATerm format. */
-static void expect(std::istream & str, const string & s)
-{
- char s2[s.size()];
- str.read(s2, s.size());
- if (string(s2, s.size()) != s)
- throw Error(format("expected string `%1%'") % s);
-}
-
-
-static string parseString(std::istream & str)
-{
- string res;
- expect(str, "\"");
- int c;
- while ((c = str.get()) != '"')
- if (c == '\\') {
- c = str.get();
- if (c == 'n') res += '\n';
- else if (c == 'r') res += '\r';
- else if (c == 't') res += '\t';
- else res += c;
- }
- else res += c;
- return res;
-}
-
-
static string parseStr(std::istream & str)
{
expect(str, "Str(");
@@ -70,20 +43,6 @@ static string parseWord(std::istream & str)
}
-static bool endOfList(std::istream & str)
-{
- if (str.peek() == ',') {
- str.get();
- return false;
- }
- if (str.peek() == ']') {
- str.get();
- return true;
- }
- return false;
-}
-
-
static MetaInfo parseMeta(std::istream & str)
{
MetaInfo meta;