1 : #include "expr-to-xml.hh"
2 : #include "xml-writer.hh"
3 : #include "nixexpr-ast.hh"
4 : #include "aterm.hh"
5 : #include "util.hh"
6 :
7 : #include <cstdlib>
8 :
9 :
10 : namespace nix {
11 :
12 :
13 193 : static XMLAttrs singletonAttrs(const string & name, const string & value)
14 : {
15 193 : XMLAttrs attrs;
16 193 : attrs[name] = value;
17 0 : return attrs;
18 : }
19 :
20 :
21 : /* set<Expr> is safe because all the expressions are also reachable
22 : from the stack, therefore can't be garbage-collected. */
23 : typedef set<Expr> ExprSet;
24 :
25 :
26 : static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
27 : ExprSet & drvsSeen);
28 :
29 :
30 : static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
31 48 : PathSet & context, ExprSet & drvsSeen)
32 : {
33 48 : StringSet names;
34 280 : for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
35 92 : names.insert(aterm2String(i->key));
36 140 : for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
37 92 : XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
38 184 : printTermAsXML(attrs.get(toATerm(*i)), doc, context, drvsSeen);
39 48 : }
40 48 : }
41 :
42 :
43 6 : static void printPatternAsXML(Pattern pat, XMLWriter & doc)
44 : {
45 : ATerm name;
46 : ATermList formals;
47 : Pattern pat1, pat2;
48 : ATermBool ellipsis;
49 6 : if (matchVarPat(pat, name))
50 2 : doc.writeEmptyElement("varpat", singletonAttrs("name", aterm2String(name)));
51 4 : else if (matchAttrsPat(pat, formals, ellipsis)) {
52 3 : XMLOpenElement _(doc, "attrspat");
53 24 : for (ATermIterator i(formals); i; ++i) {
54 : Expr name; ATerm dummy;
55 9 : if (!matchFormal(*i, name, dummy)) abort();
56 9 : doc.writeEmptyElement("attr", singletonAttrs("name", aterm2String(name)));
57 : }
58 3 : if (ellipsis == eTrue) doc.writeEmptyElement("ellipsis");
59 : }
60 1 : else if (matchAtPat(pat, pat1, pat2)) {
61 1 : XMLOpenElement _(doc, "at");
62 1 : printPatternAsXML(pat1, doc);
63 1 : printPatternAsXML(pat2, doc);
64 : }
65 6 : }
66 :
67 :
68 : static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
69 144 : ExprSet & drvsSeen)
70 : {
71 144 : XMLAttrs attrs;
72 144 : string s;
73 : ATerm s2;
74 : int i;
75 : ATermList as, es;
76 : ATerm pat, body, pos;
77 :
78 144 : checkInterrupt();
79 :
80 144 : if (matchStr(e, s, context)) /* !!! show the context? */
81 6 : doc.writeEmptyElement("string", singletonAttrs("value", s));
82 :
83 138 : else if (matchPath(e, s2))
84 0 : doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s2)));
85 :
86 138 : else if (matchNull(e))
87 0 : doc.writeEmptyElement("null");
88 :
89 138 : else if (matchInt(e, i))
90 48 : doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % i).str()));
91 :
92 90 : else if (e == eTrue)
93 36 : doc.writeEmptyElement("bool", singletonAttrs("value", "true"));
94 :
95 54 : else if (e == eFalse)
96 0 : doc.writeEmptyElement("bool", singletonAttrs("value", "false"));
97 :
98 54 : else if (matchAttrs(e, as)) {
99 48 : ATermMap attrs;
100 48 : queryAllAttrs(e, attrs);
101 :
102 48 : Expr a = attrs.get(toATerm("type"));
103 48 : if (a && matchStr(a, s, context) && s == "derivation") {
104 :
105 0 : XMLAttrs xmlAttrs;
106 0 : Path outPath, drvPath;
107 :
108 0 : a = attrs.get(toATerm("drvPath"));
109 0 : if (matchStr(a, drvPath, context))
110 0 : xmlAttrs["drvPath"] = drvPath;
111 :
112 0 : a = attrs.get(toATerm("outPath"));
113 0 : if (matchStr(a, outPath, context))
114 0 : xmlAttrs["outPath"] = outPath;
115 :
116 0 : XMLOpenElement _(doc, "derivation", xmlAttrs);
117 :
118 0 : if (drvsSeen.find(e) == drvsSeen.end()) {
119 0 : drvsSeen.insert(e);
120 0 : showAttrs(attrs, doc, context, drvsSeen);
121 : } else
122 0 : doc.writeEmptyElement("repeated");
123 : }
124 :
125 : else {
126 48 : XMLOpenElement _(doc, "attrs");
127 48 : showAttrs(attrs, doc, context, drvsSeen);
128 48 : }
129 : }
130 :
131 6 : else if (matchList(e, es)) {
132 2 : XMLOpenElement _(doc, "list");
133 51 : for (ATermIterator i(es); i; ++i)
134 51 : printTermAsXML(*i, doc, context, drvsSeen);
135 : }
136 :
137 4 : else if (matchFunction(e, pat, body, pos)) {
138 4 : XMLOpenElement _(doc, "function");
139 4 : printPatternAsXML(pat, doc);
140 : }
141 :
142 : else
143 0 : doc.writeEmptyElement("unevaluated");
144 144 : }
145 :
146 :
147 3 : void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
148 : {
149 3 : XMLWriter doc(true, out);
150 3 : XMLOpenElement root(doc, "expr");
151 3 : ExprSet drvsSeen;
152 3 : printTermAsXML(e, doc, context, drvsSeen);
153 3 : }
154 :
155 0 :
156 478 : }
|