about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-19T13·46+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-19T13·46+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 c5579679ca..b282015933 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 d9cf9a8626..825e876210 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 8638715193..47681242f6 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 574529ae76..0000000000
--- 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 bc2ec1f907..3d0f1eb424 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 042f4738d4..95e49d42c9 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 a83ba55e2b..2c0aa35792 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 2d7d13a0e7..f2cc206269 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 55135e3736..aa862208c6 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 25d7047857..0000000000
--- 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 b1cbc3b6d8..0000000000
--- 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 d28d0e823c..98912e7a00 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 4de33d3eff..ff710077ce 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 8bb760094d..f040f8c115 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;