if (node->type != XML_ELEMENT_NODE) {
return;
}
- if (strcmp(reinterpret_cast<const char *>(node->ns->href), "http://template.sesse.net/") == 0) {
+ if (node->ns != NULL &&
+ strcmp(reinterpret_cast<const char *>(node->ns->href), "http://template.sesse.net/") == 0) {
xmlNode *frag = xmlNewDocFragment(node->doc);
xmlReplaceNode(node, frag);
frag->children = node->children;
string Replace::get_contents() { return str; }
+ReplaceInclude::ReplaceInclude(xmlNodePtr included_node)
+ : included_node(included_node),
+ included_doc(NULL) {}
+
+ReplaceInclude::ReplaceInclude(xmlDocPtr included_doc)
+ : included_node(xmlDocGetRootElement(included_doc)),
+ included_doc(included_doc) {}
+
+ReplaceInclude::~ReplaceInclude()
+{
+ if (included_doc != NULL) {
+ xmlFreeDoc(included_doc);
+ } else {
+ xmlFreeNode(included_node);
+ }
+}
+
+void ReplaceInclude::process(xmlNode *node, bool clean) {
+ xmlFreeNodeList(node->children);
+ node->content = NULL;
+ node->children = node->last = NULL;
+
+ xmlNode *new_node;
+ xmlDOMWrapCloneNode(NULL, NULL, included_node, &new_node, node->doc, node, 1, 0);
+ xmlAddChild(node, new_node);
+
+ if (clean) {
+ Substitute dummy_subs {};
+ dummy_subs.process(new_node, clean);
+ clean_node(node);
+ }
+}
+
Clone::Clone(const vector<Directive *> &subdirectives)
: subdirectives(subdirectives) {}
vector<xmlNode *> new_nodes;
for (auto it : subdirectives) {
+ if (it == NULL) {
+ continue;
+ }
xmlNode *new_node;
xmlDOMWrapCloneNode(NULL, node->doc, node, &new_node, node->doc, NULL, 1, 0);
it->process(new_node, clean);
const vector<string> &alternatives)
: Clone(subdirectives_subs)
{
+ unsigned jx = 0;
for (unsigned ix = 0; ix < subdirectives_subs.size(); ++ix) {
- string value = alternatives[ix % alternatives.size()];
+ if (subdirectives_subs[ix] == NULL) {
+ continue;
+ }
+ string value = alternatives[jx++ % alternatives.size()];
subdirectives_subs[ix]->substitution_map.insert(make_pair(
attribute,
new Replace { value }));
}
}
-void process_file(const string &input_filename,
- const string &output_filename,
- Directive *root_directive)
+xmlDocPtr process_file(const string &input_filename,
+ Directive *root_directive,
+ bool clean)
{
LIBXML_TEST_VERSION
xmlDocPtr doc = xmlParseFile(input_filename.c_str());
- root_directive->process(xmlDocGetRootElement(doc), true);
- xmlSaveFile(output_filename.c_str(), doc);
- xmlFreeDoc(doc);
-
+ root_directive->process(xmlDocGetRootElement(doc), clean);
xmlCleanupParser();
xmlMemoryDump();
+ return doc;
+}
+
+void output_to_fd_and_free(xmlDocPtr doc, int fd)
+{
+ xmlOutputBufferPtr buf = xmlOutputBufferCreateFd(fd, NULL);
+ xmlSaveFileTo(buf, doc, NULL);
+ xmlFreeDoc(doc);
}