about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libutil/xml-writer.cc17
-rw-r--r--src/libutil/xml-writer.hh5
-rw-r--r--src/nix-env/main.cc7
-rw-r--r--src/nix-instantiate/main.cc64
4 files changed, 81 insertions, 12 deletions
diff --git a/src/libutil/xml-writer.cc b/src/libutil/xml-writer.cc
index e5f0d9455e40..cd37dff5608f 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 << "<?xml version='1.0' encoding='utf-8'?>\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 << "</" << pendingElems.back() << ">";
+    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 ae6c76ff2c9b..8c203a3486f0 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<string> 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 7ec2667e75c8..0fb115533f18 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<DrvInfo>::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 b781e2f2ab7c..3e0b10f6a0a0 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);