diff --git a/src/libexpr/meson.build b/src/libexpr/meson.build
index 622c4c625..73b2fb302 100644
--- a/src/libexpr/meson.build
+++ b/src/libexpr/meson.build
@@ -103,6 +103,7 @@ libexpr_sources = files(
'primops/path.cc',
'primops/string.cc',
'primops/system.cc',
+ 'primops/toXML.cc',
'primops/types.cc',
'value/context.cc',
)
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index ff0842299..d41867a62 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -186,110 +186,6 @@ static void derivationStrictInternal(EvalState & state, const std::string & name
/* Convert the argument (which can be any Nix expression) to an XML
representation returned in a string. Not all Nix expressions can
be sensibly or completely represented (e.g., functions). */
-static void prim_toXML(EvalState & state, const PosIdx pos, Value * * args, Value & v)
-{
- std::ostringstream out;
- NixStringContext context;
- printValueAsXML(state, true, false, *args[0], out, context, pos);
- v.mkString(out.str(), context);
-}
-
-static RegisterPrimOp primop_toXML({
- .name = "__toXML",
- .args = {"e"},
- .doc = R"(
- Return a string containing an XML representation of *e*. The main
- application for `toXML` is to communicate information with the
- builder in a more structured format than plain environment
- variables.
-
- Here is an example where this is the case:
-
- ```nix
- { stdenv, fetchurl, libxslt, jira, uberwiki }:
-
- stdenv.mkDerivation (rec {
- name = "web-server";
-
- buildInputs = [ libxslt ];
-
- builder = builtins.toFile "builder.sh" "
- source $stdenv/setup
- mkdir $out
- echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml ①
- ";
-
- stylesheet = builtins.toFile "stylesheet.xsl" ②
- "
-
-
-
-
-
-
-
-
-
-
-
-
- ";
-
- servlets = builtins.toXML [ ③
- { path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
- { path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
- ];
- })
- ```
-
- The builder is supposed to generate the configuration file for a
- [Jetty servlet container](http://jetty.mortbay.org/). A servlet
- container contains a number of servlets (`*.war` files) each
- exported under a specific URI prefix. So the servlet configuration
- is a list of sets containing the `path` and `war` of the servlet
- (①). This kind of information is difficult to communicate with the
- normal method of passing information through an environment
- variable, which just concatenates everything together into a
- string (which might just work in this case, but wouldn’t work if
- fields are optional or contain lists themselves). Instead the Nix
- expression is converted to an XML representation with `toXML`,
- which is unambiguous and can easily be processed with the
- appropriate tools. For instance, in the example an XSLT stylesheet
- (at point ②) is applied to it (at point ①) to generate the XML
- configuration file for the Jetty server. The XML representation
- produced at point ③ by `toXML` is as follows:
-
- ```xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ```
-
- Note that we used the `toFile` built-in to write the builder and
- the stylesheet “inline” in the Nix expression. The path of the
- stylesheet is spliced into the builder using the syntax `xsltproc
- ${stylesheet}`.
- )",
- .fun = prim_toXML,
-});
/* Store a string in the Nix store as a source file that can be used
diff --git a/src/libexpr/primops/toXML.cc b/src/libexpr/primops/toXML.cc
new file mode 100644
index 000000000..6965c8254
--- /dev/null
+++ b/src/libexpr/primops/toXML.cc
@@ -0,0 +1,115 @@
+#include "primops.hh"
+#include "value-to-xml.hh"
+
+namespace nix {
+
+/**
+ * builtins.toXML
+ */
+
+static void prim_toXML(EvalState & state, const PosIdx pos, Value ** args, Value & v)
+{
+ std::ostringstream out;
+ NixStringContext context;
+ printValueAsXML(state, true, false, *args[0], out, context, pos);
+ v.mkString(out.str(), context);
+}
+
+static RegisterPrimOp primop_toXML({
+ .name = "__toXML",
+ .args = {"e"},
+ .doc = R"(
+ Return a string containing an XML representation of *e*. The main
+ application for `toXML` is to communicate information with the
+ builder in a more structured format than plain environment
+ variables.
+
+ Here is an example where this is the case:
+
+ ```nix
+ { stdenv, fetchurl, libxslt, jira, uberwiki }:
+
+ stdenv.mkDerivation (rec {
+ name = "web-server";
+
+ buildInputs = [ libxslt ];
+
+ builder = builtins.toFile "builder.sh" "
+ source $stdenv/setup
+ mkdir $out
+ echo "$servlets" | xsltproc ${stylesheet} - > $out/server-conf.xml ①
+ ";
+
+ stylesheet = builtins.toFile "stylesheet.xsl" ②
+ "
+
+
+
+
+
+
+
+
+
+
+
+
+ ";
+
+ servlets = builtins.toXML [ ③
+ { path = "/bugtracker"; war = jira + "/lib/atlassian-jira.war"; }
+ { path = "/wiki"; war = uberwiki + "/uberwiki.war"; }
+ ];
+ })
+ ```
+
+ The builder is supposed to generate the configuration file for a
+ [Jetty servlet container](http://jetty.mortbay.org/). A servlet
+ container contains a number of servlets (`*.war` files) each
+ exported under a specific URI prefix. So the servlet configuration
+ is a list of sets containing the `path` and `war` of the servlet
+ (①). This kind of information is difficult to communicate with the
+ normal method of passing information through an environment
+ variable, which just concatenates everything together into a
+ string (which might just work in this case, but wouldn’t work if
+ fields are optional or contain lists themselves). Instead the Nix
+ expression is converted to an XML representation with `toXML`,
+ which is unambiguous and can easily be processed with the
+ appropriate tools. For instance, in the example an XSLT stylesheet
+ (at point ②) is applied to it (at point ①) to generate the XML
+ configuration file for the Jetty server. The XML representation
+ produced at point ③ by `toXML` is as follows:
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+ Note that we used the `toFile` built-in to write the builder and
+ the stylesheet “inline” in the Nix expression. The path of the
+ stylesheet is spliced into the builder using the syntax `xsltproc
+ ${stylesheet}`.
+ )",
+ .fun = prim_toXML,
+});
+
+}