]> git.sesse.net Git - xml-template/blobdiff - c++0x/xml-template.cpp
Fix a Valgrind hit; we cannot take c_str() of a temporary object.
[xml-template] / c++0x / xml-template.cpp
index 30e5a7e1e3f96a6d740ebefdb68ea1c2d1c6bfb4..317a561779fab53a7177d8376e1bbd37de585909 100644 (file)
@@ -12,7 +12,8 @@ void clean_node(xmlNode *node)
        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;
@@ -47,6 +48,39 @@ void Replace::process(xmlNode *node, bool clean) {
 
 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) {}
 
@@ -162,13 +196,13 @@ void Substitute::process(xmlNode *node, bool clean)
                                // Attribute substitution.
                                if (begins_with(it.first, tag + "/")) {
                                        const xmlChar *attr_key = reinterpret_cast<const xmlChar *>(
-                                               it.first.substr(tag.size() + 1).c_str());
+                                               it.first.c_str() + tag.size() + 1);
                                        const xmlChar *attr_value = reinterpret_cast<const xmlChar *>(
                                                it.second->get_contents().c_str());
                                        xmlSetProp(child, attr_key, attr_value);
                                } else if ((!id.empty() && begins_with(it.first, "#" + id + "/"))) {
                                        const xmlChar *attr_key = reinterpret_cast<const xmlChar *>(
-                                               it.first.substr(tag.size() + 2).c_str());
+                                               it.first.c_str() + tag.size() + 2);
                                        const xmlChar *attr_value = reinterpret_cast<const xmlChar *>(
                                                it.second->get_contents().c_str());
                                        xmlSetProp(child, attr_key, attr_value);
@@ -196,17 +230,22 @@ void Substitute::process(xmlNode *node, bool clean)
        }
 }
        
-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);
 }