From 6d6f69fcdf45c3afc82212c5c3d8085c93ec4717 Mon Sep 17 00:00:00 2001 From: "sgunderson@bigfoot.com" <> Date: Thu, 22 Sep 2011 02:11:43 +0200 Subject: [PATCH] Add include support, and unit test, to C++0x version. All unit tests pass! --- c++0x/Makefile | 3 +++ c++0x/include.cpp | 23 +++++++++++++++++++++++ c++0x/xml-template.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- c++0x/xml-template.h | 15 ++++++++++++++- 4 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 c++0x/include.cpp diff --git a/c++0x/Makefile b/c++0x/Makefile index 79c4024..9c7cef9 100644 --- a/c++0x/Makefile +++ b/c++0x/Makefile @@ -12,6 +12,9 @@ simple: simple.o $(LIBS) clone: clone.o $(LIBS) $(CXX) -o $@ $< $(LIBS) $(LDFLAGS) +include: include.o $(LIBS) + $(CXX) -o $@ $< $(LIBS) $(LDFLAGS) + attribute: attribute.o $(LIBS) $(CXX) -o $@ $< $(LIBS) $(LDFLAGS) diff --git a/c++0x/include.cpp b/c++0x/include.cpp new file mode 100644 index 0000000..546be7b --- /dev/null +++ b/c++0x/include.cpp @@ -0,0 +1,23 @@ +#include + +#include "xml-template.h" + +using namespace std; + +int main(int argc, char **argv) +{ + Substitute doc_directive = { + make_pair("color", new Replace("red")), + }; + xmlDocPtr doc = process_file("../xml/included.xml", &doc_directive, false); + + Substitute master_directive = { + make_pair("title", new Replace("Main HTML title")), + make_pair("h1", new Replace("Nice heading here")), + make_pair("contents", new ReplaceInclude(doc)), + }; + + xmlDocPtr master = process_file("../xml/master.xml", &master_directive); + output_to_fd_and_free(master, 1); + return(0); +} diff --git a/c++0x/xml-template.cpp b/c++0x/xml-template.cpp index e8fc0ed..5bbcb9b 100644 --- a/c++0x/xml-template.cpp +++ b/c++0x/xml-template.cpp @@ -12,7 +12,8 @@ void clean_node(xmlNode *node) if (node->type != XML_ELEMENT_NODE) { return; } - if (strcmp(reinterpret_cast(node->ns->href), "http://template.sesse.net/") == 0) { + if (node->ns != NULL && + strcmp(reinterpret_cast(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 &subdirectives) : subdirectives(subdirectives) {} @@ -197,12 +231,13 @@ void Substitute::process(xmlNode *node, bool clean) } xmlDocPtr process_file(const string &input_filename, - Directive *root_directive) + Directive *root_directive, + bool clean) { LIBXML_TEST_VERSION xmlDocPtr doc = xmlParseFile(input_filename.c_str()); - root_directive->process(xmlDocGetRootElement(doc), true); + root_directive->process(xmlDocGetRootElement(doc), clean); xmlCleanupParser(); xmlMemoryDump(); return doc; diff --git a/c++0x/xml-template.h b/c++0x/xml-template.h index 3567186..7cfa0d8 100644 --- a/c++0x/xml-template.h +++ b/c++0x/xml-template.h @@ -25,6 +25,18 @@ class Replace : public Directive { const std::string str; }; +class ReplaceInclude : public Directive { + public: + ReplaceInclude(xmlNodePtr included_node); + ReplaceInclude(xmlDocPtr included_doc); + ~ReplaceInclude(); + virtual void process(xmlNode *node, bool clean); + + private: + xmlNodePtr included_node; + xmlDocPtr included_doc; +}; + class Substitute; class Clone : public Directive { @@ -60,7 +72,8 @@ class Alternate : public Clone { }; xmlDocPtr process_file(const std::string &input_filename, - Directive *root_directive); + Directive *root_directive, + bool clean = true); void output_to_fd_and_free(xmlDocPtr doc, int fd); -- 2.39.2