From 18e4ac0fc6bd1bc01d92d011e4629cacc3bec016 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Aug 2006 10:32:30 +0000 Subject: [PATCH] * `nix-instantiate --{eval|parse}-only --xml': print an XML representation instead of an ATerm. * Indent XML output. --- corepkgs/buildenv/builder.pl.in | 2 +- src/libutil/xml-writer.cc | 17 +++++++-- src/libutil/xml-writer.hh | 5 ++- src/nix-env/main.cc | 7 ++-- src/nix-instantiate/main.cc | 64 ++++++++++++++++++++++++++++++--- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/corepkgs/buildenv/builder.pl.in b/corepkgs/buildenv/builder.pl.in index 1597ffa29..f54945809 100755 --- a/corepkgs/buildenv/builder.pl.in +++ b/corepkgs/buildenv/builder.pl.in @@ -91,7 +91,7 @@ sub addPkg { close PROP; my @propagated = split ' ', $propagated; foreach my $p (@propagated) { - addPkg $p; +# addPkg $p; } } diff --git a/src/libutil/xml-writer.cc b/src/libutil/xml-writer.cc index e5f0d9455..cd37dff56 100644 --- a/src/libutil/xml-writer.cc +++ b/src/libutil/xml-writer.cc @@ -3,8 +3,8 @@ #include "xml-writer.hh" -XMLWriter::XMLWriter(ostream & output) - : output(output) +XMLWriter::XMLWriter(bool indent, ostream & output) + : output(output), indent(indent) { output << "\n"; closed = false; @@ -25,13 +25,22 @@ void XMLWriter::close() } +void XMLWriter::indent_(unsigned int depth) +{ + if (!indent) return; + output << string(depth * 2, ' '); +} + + void XMLWriter::openElement(const string & name, const XMLAttrs & attrs) { assert(!closed); + indent_(pendingElems.size()); output << "<" << name; writeAttrs(attrs); output << ">"; + if (indent) output << "\n"; pendingElems.push_back(name); } @@ -39,7 +48,9 @@ void XMLWriter::openElement(const string & name, void XMLWriter::closeElement() { assert(!pendingElems.empty()); + indent_(pendingElems.size() - 1); output << ""; + if (indent) output << "\n"; pendingElems.pop_back(); if (pendingElems.empty()) closed = true; } @@ -49,9 +60,11 @@ void XMLWriter::writeEmptyElement(const string & name, const XMLAttrs & attrs) { assert(!closed); + indent_(pendingElems.size()); output << "<" << name; writeAttrs(attrs); output << " />"; + if (indent) output << "\n"; } diff --git a/src/libutil/xml-writer.hh b/src/libutil/xml-writer.hh index ae6c76ff2..8c203a348 100644 --- a/src/libutil/xml-writer.hh +++ b/src/libutil/xml-writer.hh @@ -18,13 +18,14 @@ private: ostream & output; + bool indent; bool closed; list pendingElems; public: - XMLWriter(ostream & output); + XMLWriter(bool indent, ostream & output); ~XMLWriter(); void close(); @@ -40,6 +41,8 @@ public: private: void writeAttrs(const XMLAttrs & attrs); + + void indent_(unsigned int depth); }; diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index 7ec2667e7..0fb115533 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -804,7 +804,7 @@ static void opQuery(Globals & globals, /* Print the desired columns, or XML output. */ Table table; ostringstream dummy; - XMLWriter xml(*(xmlOutput ? &cout : &dummy)); + XMLWriter xml(true, *(xmlOutput ? &cout : &dummy)); XMLOpenElement xmlRoot(xml, "items"); for (vector::iterator i = elems2.begin(); @@ -903,10 +903,9 @@ static void opQuery(Globals & globals, columns.push_back(descr); } - if (xmlOutput) { + if (xmlOutput) xml.writeEmptyElement("item", attrs); - xml.writeCharData("\n"); - } else + else table.push_back(columns); } catch (AssertionError & e) { diff --git a/src/nix-instantiate/main.cc b/src/nix-instantiate/main.cc index b781e2f2a..3e0b10f6a 100644 --- a/src/nix-instantiate/main.cc +++ b/src/nix-instantiate/main.cc @@ -34,14 +34,65 @@ static int rootNr = 0; static bool indirectRoot = false; +static XMLAttrs singletonAttrs(const string & name, const string & value) +{ + XMLAttrs attrs; + attrs[name] = value; + return attrs; +} + + +static void printTermAsXML(EvalState & state, Expr e, XMLWriter & doc) +{ + XMLAttrs attrs; + ATerm s; + int i; + ATermList as; + + if (matchStr(e, s)) + doc.writeEmptyElement("string", singletonAttrs("value", aterm2String(s))); + + else if (matchPath(e, s)) + doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s))); + + else if (matchUri(e, s)) + doc.writeEmptyElement("uri", singletonAttrs("value", aterm2String(s))); + + else if (matchNull(e)) + doc.writeEmptyElement("null"); + + else if (matchInt(e, i)) + doc.writeEmptyElement("int",singletonAttrs("value", (format("%1%") % i).str())); + + else if (matchAttrs(e, as)) { + XMLOpenElement _(doc, "attrs"); + ATermMap attrs(128); + queryAllAttrs(e, attrs); + for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i) { + XMLOpenElement _(doc, "attr", singletonAttrs("name", aterm2String(i->key))); + printTermAsXML(state, i->value, doc); + } + } + + else + doc.writeEmptyElement("unknown"); +} + + static void printResult(EvalState & state, Expr e, - bool evalOnly, bool printArgs, const ATermMap & autoArgs) + bool evalOnly, bool printArgs, bool xmlOutput, + const ATermMap & autoArgs) { if (evalOnly) - cout << format("%1%\n") % e; + if (xmlOutput) { + XMLWriter doc(true, cout); + XMLOpenElement root(doc, "expr"); + printTermAsXML(state, e, doc); + } else + cout << format("%1%\n") % e; else if (printArgs) { - XMLWriter doc(cout); + XMLWriter doc(true, cout); XMLOpenElement root(doc, "args"); ATermList formals; @@ -95,6 +146,7 @@ void run(Strings args) bool evalOnly = false; bool parseOnly = false; bool printArgs = false; + bool xmlOutput = false; string attrPath; ATermMap autoArgs(128); @@ -138,6 +190,8 @@ void run(Strings args) } else if (arg == "--indirect") indirectRoot = true; + else if (arg == "--xml") + xmlOutput = true; else if (arg[0] == '-') throw UsageError(format("unknown flag `%1%'") % arg); else @@ -149,7 +203,7 @@ void run(Strings args) if (readStdin) { Expr e = findAlongAttrPath(state, attrPath, parseStdin(state)); if (!parseOnly) e = evalExpr(state, e); - printResult(state, e, evalOnly, printArgs, autoArgs); + printResult(state, e, evalOnly, printArgs, xmlOutput, autoArgs); } for (Strings::iterator i = files.begin(); @@ -159,7 +213,7 @@ void run(Strings args) Expr e = findAlongAttrPath(state, attrPath, parseExprFromFile(state, path)); if (!parseOnly) e = evalExpr(state, e); - printResult(state, e, evalOnly, printArgs, autoArgs); + printResult(state, e, evalOnly, printArgs, xmlOutput, autoArgs); } printEvalStats(state);