diff options
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/expr-to-xml.cc | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/src/libexpr/expr-to-xml.cc b/src/libexpr/expr-to-xml.cc index 1a7302df1293..6d27bcffb69c 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); } |