aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-01-13 15:11:10 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-01-13 15:11:10 +0000
commit501158845919c8bdf4297a8a76a916dc5b9a7943 (patch)
tree3b1cdebf531a374750ee1fd9aa626181c837eff0
parent792878af911bd1913706a1a8ee5a18f7230352ef (diff)
* printTermAsXML: treat derivations specially; emit an element
<derivation outPath=... drvPath=...> attrs </derivation>. Only emit the attributes of any specific derivation only. This prevents exponententially large XML output due to the absense of sharing.
-rw-r--r--src/libexpr/expr-to-xml.cc66
1 files changed, 55 insertions, 11 deletions
diff --git a/src/libexpr/expr-to-xml.cc b/src/libexpr/expr-to-xml.cc
index 1a7302df1..6d27bcffb 100644
--- a/src/libexpr/expr-to-xml.cc
+++ b/src/libexpr/expr-to-xml.cc
@@ -16,7 +16,30 @@ static XMLAttrs singletonAttrs(const string & name, const string & value)
}
-static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context)
+/* set<Expr> is safe because all the expressions are also reachable
+ from the stack, therefore can't be garbage-collected. */
+typedef set<Expr> ExprSet;
+
+
+static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
+ ExprSet & drvsSeen);
+
+
+static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
+ PathSet & context, ExprSet & drvsSeen)
+{
+ StringSet names;
+ for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
+ names.insert(aterm2String(i->key));
+ for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
+ XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
+ printTermAsXML(attrs.get(toATerm(*i)), doc, context, drvsSeen);
+ }
+}
+
+
+static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
+ ExprSet & drvsSeen)
{
XMLAttrs attrs;
string s;
@@ -46,22 +69,42 @@ static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context)
doc.writeEmptyElement("bool", singletonAttrs("value", "false"));
else if (matchAttrs(e, as)) {
- XMLOpenElement _(doc, "attrs");
ATermMap attrs;
queryAllAttrs(e, attrs);
- StringSet names;
- for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
- names.insert(aterm2String(i->key));
- for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
- XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
- printTermAsXML(attrs.get(toATerm(*i)), doc, context);
+
+ Expr a = attrs.get(toATerm("type"));
+ if (a && matchStr(a, s, context) && s == "derivation") {
+
+ XMLAttrs xmlAttrs;
+ Path outPath, drvPath;
+
+ a = attrs.get(toATerm("drvPath"));
+ if (matchStr(a, drvPath, context))
+ xmlAttrs["drvPath"] = drvPath;
+
+ a = attrs.get(toATerm("outPath"));
+ if (matchStr(a, outPath, context))
+ xmlAttrs["outPath"] = outPath;
+
+ XMLOpenElement _(doc, "derivation", xmlAttrs);
+
+ if (drvsSeen.find(e) == drvsSeen.end()) {
+ drvsSeen.insert(e);
+ showAttrs(attrs, doc, context, drvsSeen);
+ } else
+ doc.writeEmptyElement("repeated");
+ }
+
+ else {
+ XMLOpenElement _(doc, "attrs");
+ showAttrs(attrs, doc, context, drvsSeen);
}
}
else if (matchList(e, es)) {
XMLOpenElement _(doc, "list");
for (ATermIterator i(es); i; ++i)
- printTermAsXML(*i, doc, context);
+ printTermAsXML(*i, doc, context, drvsSeen);
}
else if (matchFunction(e, formals, body, pos)) {
@@ -76,7 +119,7 @@ static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context)
if (matchValidValues(valids, valids2)) {
for (ATermIterator j(valids2); j; ++j) {
XMLOpenElement _(doc, "value");
- printTermAsXML(*j, doc, context);
+ printTermAsXML(*j, doc, context, drvsSeen);
}
}
}
@@ -91,7 +134,8 @@ void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
{
XMLWriter doc(true, out);
XMLOpenElement root(doc, "expr");
- printTermAsXML(e, doc, context);
+ ExprSet drvsSeen;
+ printTermAsXML(e, doc, context, drvsSeen);
}