[expatpp] Initial import #868325
mrceresa
mrceresa at fedoraproject.org
Mon Oct 29 14:24:44 UTC 2012
commit 416f4340057a5ecf0d090dc099800dfb8dff288d
Author: Mario Ceresa <mrceresa at gmail.com>
Date: Mon Oct 29 15:24:27 2012 +0100
Initial import #868325
.gitignore | 1 +
0001-Added-CMake-config-file.patch | 27 +
0002-Fix-case-of-required-arg.patch | 26 +
0003-Include-string-header.patch | 27 +
...onverted-to-lib-standalone-program-layout.patch | 2347 ++++++++++++++++++++
0005-Added-test-code.patch | 659 ++++++
0006-Build-testexpatpp1.patch | 28 +
0007-Fix-subdir-command.patch | 27 +
0008-Added-cPack.patch | 39 +
0009-Install-library.patch | 25 +
0010-Use-lib-or-lib64-automatically.patch | 25 +
0011-added-soname-info.patch | 58 +
0012-Fixed-missing-api-version.patch | 26 +
0013-Install-header-file.patch | 26 +
0014-Removed-windows-static-lib-header.patch | 39 +
0015-Reworked-documentation.patch | 897 ++++++++
expatpp.spec | 111 +
sources | 1 +
18 files changed, 4389 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e69de29..1870173 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/expatpp.tar.bz2
diff --git a/0001-Added-CMake-config-file.patch b/0001-Added-CMake-config-file.patch
new file mode 100644
index 0000000..2a5d553
--- /dev/null
+++ b/0001-Added-CMake-config-file.patch
@@ -0,0 +1,27 @@
+From ca4376c9b94b8be9308fd3ec77a18548672213bc Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:07:42 +0200
+Subject: [PATCH 01/15] Added CMake config file
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 6 ++++++
+ 1 file changed, 6 insertions(+)
+ create mode 100644 CMakeLists.txt
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+new file mode 100644
+index 0000000..a9607b2
+--- /dev/null
++++ b/CMakeLists.txt
+@@ -0,0 +1,6 @@
++project(expatpp)
++
++find_package(EXPAT required)
++
++add_library(expatpp SHARED expatpp.cpp)
++target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0002-Fix-case-of-required-arg.patch b/0002-Fix-case-of-required-arg.patch
new file mode 100644
index 0000000..f3dc979
--- /dev/null
+++ b/0002-Fix-case-of-required-arg.patch
@@ -0,0 +1,26 @@
+From 180c1e17264c2c0dd64520157fb8aa54e91be44c Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:09:32 +0200
+Subject: [PATCH 02/15] Fix case of required arg
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index a9607b2..e3bdd8f 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,6 +1,6 @@
+ project(expatpp)
+
+-find_package(EXPAT required)
++find_package(EXPAT REQUIRED)
+
+ add_library(expatpp SHARED expatpp.cpp)
+ target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0003-Include-string-header.patch b/0003-Include-string-header.patch
new file mode 100644
index 0000000..a412272
--- /dev/null
+++ b/0003-Include-string-header.patch
@@ -0,0 +1,27 @@
+From 547c1015793c55d5c899a4fe4afe448d305512a6 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:13:01 +0200
+Subject: [PATCH 03/15] Include string header
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ expatpp.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/expatpp.cpp b/expatpp.cpp
+index 3eaa913..8a7c532 100755
+--- a/expatpp.cpp
++++ b/expatpp.cpp
+@@ -26,6 +26,9 @@
+ #define BUFSIZ 4096
+ #endif
+
++#include <stdio.h>
++#include <string.h>
++
+ expatpp::expatpp(bool createParser) :
+ mParser(0), // in case of exception below
+ mHaveParsed(false)
+--
+1.7.11.7
+
diff --git a/0004-Converted-to-lib-standalone-program-layout.patch b/0004-Converted-to-lib-standalone-program-layout.patch
new file mode 100644
index 0000000..e7e1cef
--- /dev/null
+++ b/0004-Converted-to-lib-standalone-program-layout.patch
@@ -0,0 +1,2347 @@
+From a902dec4fd4b94dddba0f534bb5e2cfd1742d7ba Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:15:06 +0200
+Subject: [PATCH 04/15] Converted to lib+standalone program layout
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 4 +-
+ expatpp.cpp | 799 -----------------------------------------------------
+ expatpp.h | 339 -----------------------
+ lib/CMakeLists.txt | 3 +
+ lib/expatpp.cpp | 799 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ lib/expatpp.h | 339 +++++++++++++++++++++++
+ 6 files changed, 1143 insertions(+), 1140 deletions(-)
+ delete mode 100755 expatpp.cpp
+ delete mode 100755 expatpp.h
+ create mode 100644 lib/CMakeLists.txt
+ create mode 100755 lib/expatpp.cpp
+ create mode 100755 lib/expatpp.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index e3bdd8f..8db8529 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -2,5 +2,5 @@ project(expatpp)
+
+ find_package(EXPAT REQUIRED)
+
+-add_library(expatpp SHARED expatpp.cpp)
+-target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+\ No newline at end of file
++add_dir(lib)
++add_dir(test)
+\ No newline at end of file
+diff --git a/expatpp.cpp b/expatpp.cpp
+deleted file mode 100755
+index 8a7c532..0000000
+--- a/expatpp.cpp
++++ /dev/null
+@@ -1,799 +0,0 @@
+-// expatpp
+-#ifdef UNDER_CE
+- #include <string.h>
+- #include <windows.h>
+- #include <dbgapi.h>
+- #define assert ASSERT
+-#else
+- #include <string>
+- using namespace std;
+- #include <assert.h>
+-#endif
+-#include "expatpp.h"
+-
+-
+-// may be defined in xmltchar.h or elsewhere
+-#ifndef tcscmp
+- #ifdef XML_UNICODE
+- #define tcscmp wcscmp
+- #else
+- #define tcscmp strcmp
+- #endif // XML_UNICODE
+-#endif // tcscmp
+-
+-
+-#ifndef BUFSIZ
+- #define BUFSIZ 4096
+-#endif
+-
+-#include <stdio.h>
+-#include <string.h>
+-
+-expatpp::expatpp(bool createParser) :
+- mParser(0), // in case of exception below
+- mHaveParsed(false)
+-{
+- if (createParser) {
+- // subclasses may call this ctor after parser created!
+- mParser = XML_ParserCreate(0);
+- SetupHandlers();
+- }
+-}
+-
+-
+-void
+-expatpp::SetupHandlers()
+-{
+- ::XML_SetUserData(mParser, this);
+- ::XML_SetElementHandler(mParser, startElementCallback, endElementCallback);
+- ::XML_SetCharacterDataHandler(mParser, charDataCallback);
+- ::XML_SetProcessingInstructionHandler(mParser, processingInstructionCallback);
+- ::XML_SetDefaultHandler(mParser, defaultHandlerCallback);
+- ::XML_SetUnparsedEntityDeclHandler(mParser, unParsedEntityDeclCallback);
+- ::XML_SetNotationDeclHandler(mParser, notationDeclCallback);
+- ::XML_SetNotStandaloneHandler(mParser, notStandaloneHandlerCallback);
+- ::XML_SetNamespaceDeclHandler(mParser, startNamespaceCallback, endNamespaceCallback);
+-#ifndef EXPATPP_COMPATIBLE_EXPAT12
+- ::XML_SetAttlistDeclHandler(mParser, attlistDeclCallback);
+- ::XML_SetCdataSectionHandler(mParser, startCdataSectionCallback, endCdataSectionCallback);
+- ::XML_SetCommentHandler(mParser, commentCallback);
+- ::XML_SetDoctypeDeclHandler(mParser, startDoctypeDeclCallback, endDoctypeDeclCallback);
+- ::XML_SetElementDeclHandler(mParser, elementDeclCallback);
+- ::XML_SetEntityDeclHandler(mParser, entityDeclCallback);
+- ::XML_SetSkippedEntityHandler(mParser, skippedEntityCallback);
+- ::XML_SetXmlDeclHandler(mParser, xmlDeclCallback);
+-#endif
+-}
+-
+-
+-expatpp::~expatpp()
+-{
+- if (mParser) // allows subclasses to avoid finishing parsing
+- ReleaseParser();
+-}
+-
+-
+-/**
+- Provide single point that will call XML_ParserFree.
+- Nothing else in this code should call XML_ParserFree!
+-*/
+-void
+-expatpp::ReleaseParser()
+-{
+- ::XML_ParserFree(mParser);
+- mParser = 0;
+-}
+-
+-
+-
+-/**
+- Provide single point that will call XML_ParserReset.
+- Guarded against trivial reset before use in case that breaks
+- expat or creates overhead.
+-
+- \todo pass in encoding to XML_ParserReset when we support encodings
+-*/
+-void
+-expatpp::ResetParser()
+-{
+-#ifdef EXPATPP_COMPATIBLE_EXPAT12
+- assert(!"Reset not available in earlier than expat 1.95.3");s
+-#else
+- if (mHaveParsed) {
+- ::XML_ParserReset(mParser, NULL);
+- SetupHandlers();
+- mHaveParsed = false;
+- }
+-#endif
+-}
+-
+-
+-/**
+- Parse entire file, basically copy of the loop from the elements.c example.
+-*/
+-XML_Status
+-expatpp::parseFile(FILE* inFile)
+-{
+- ResetParser();
+-
+- char buf[BUFSIZ];
+- int done;
+- if (!inFile)
+- return XML_STATUS_ERROR;
+- fseek(inFile, 0, SEEK_SET); // reset for reading
+- do {
+- size_t len = fread(buf, 1, sizeof(buf), inFile);
+- done = len < sizeof(buf);
+- enum XML_Status parseStatus;
+- if ((parseStatus = XML_Parse(buf, len, done))!=XML_STATUS_OK) {
+- return parseStatus;
+- }
+- } while (!done);
+- return XML_STATUS_OK;
+-}
+-
+-
+-XML_Status
+-expatpp::XML_Parse(const char *s, int len, int isFinal)
+-{
+- mHaveParsed = true;
+- const XML_Status retStatus = ::XML_Parse(mParser, s, len, isFinal);
+- if (isFinal)
+- CheckFinalStatus(retStatus);
+- return retStatus;
+-}
+-
+-
+-XML_Error
+-expatpp::XML_GetErrorCode()
+-{
+- return ::XML_GetErrorCode(mParser);
+-}
+-
+-
+-int
+-expatpp::XML_GetCurrentLineNumber()
+-{
+- return ::XML_GetCurrentLineNumber(mParser);
+-}
+-
+-
+-int
+-expatpp::XML_GetCurrentColumnNumber()
+-{
+- return ::XML_GetCurrentColumnNumber(mParser);
+-}
+-
+-
+-
+-
+-/**
+- Parse string which is assumed to be entire XML document.
+- Written to stop stupid errors of being off by one in the string length causing
+- wasted debugging time, such as:
+-\verbatim
+- const char[] kSampleSettings = "<settings/>";
+- const int sampleSize = sizeof(kSampleSettings)-1; // unless you remember to subtract one here will get invalid token error
+- if (!parser.XML_Parse(kSampleSettings, sampleSize, 1)) {
+-\endverbatim
+-*/
+-XML_Status
+-expatpp::parseString(const char* inString)
+-{
+- ResetParser();
+- const int inLen = strlen(inString);
+- return XML_Parse(inString, inLen, 1);
+-}
+-
+-void
+-expatpp::startElementCallback(void *userData, const XML_Char* name, const XML_Char** atts)
+-{
+- ((expatpp*)userData)->startElement(name, atts);
+-}
+-
+-
+-void
+-expatpp::endElementCallback(void *userData, const XML_Char* name)
+-{
+- ((expatpp*)userData)->endElement(name);
+-}
+-
+-
+-void
+-expatpp::startNamespaceCallback(void *userData, const XML_Char* prefix, const XML_Char* uri)
+-{
+- ((expatpp*)userData)->startNamespace(prefix, uri);
+-}
+-
+-
+-void
+-expatpp::endNamespaceCallback(void *userData, const XML_Char* prefix)
+-{
+- ((expatpp*)userData)->endNamespace(prefix);
+-}
+-
+-
+-void
+-expatpp::charDataCallback(void *userData, const XML_Char* s, int len)
+-{
+- ((expatpp*)userData)->charData(s, len);
+-}
+-
+-
+-void
+-expatpp:: processingInstructionCallback(void *userData, const XML_Char* target, const XML_Char* data)
+-{
+- ((expatpp*)userData)->processingInstruction(target, data);
+-}
+-
+-
+-void
+-expatpp::defaultHandlerCallback(void* userData, const XML_Char* s, int len)
+-{
+- ((expatpp*)userData)->defaultHandler(s, len);
+-}
+-
+-
+-int
+-expatpp::notStandaloneHandlerCallback(void* userData)
+-{
+- return ((expatpp*)userData)->notStandaloneHandler();
+-}
+-
+-
+-void
+-expatpp::unParsedEntityDeclCallback(void* userData, const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName)
+-{
+- ((expatpp*)userData)->unparsedEntityDecl(entityName, base, systemId, publicId, notationName);
+-}
+-
+-
+-void
+-expatpp::notationDeclCallback(void *userData, const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId)
+-{
+- ((expatpp*)userData)->notationDecl(notationName, base, systemId, publicId);
+-}
+-
+-
+-void
+-expatpp::startElement(const XML_Char*, const XML_Char**)
+-{}
+-
+-
+-void
+-expatpp::endElement(const XML_Char*)
+-{}
+-
+-
+-void
+-expatpp::startNamespace(const XML_Char* /* prefix */, const XML_Char* /* uri */)
+-{}
+-
+-
+-void
+-expatpp::endNamespace(const XML_Char*)
+-{}
+-
+-
+-void
+-expatpp::charData(const XML_Char*, int )
+-{
+-}
+-
+-
+-void
+-expatpp::processingInstruction(const XML_Char*, const XML_Char*)
+-{
+-}
+-
+-
+-void
+-expatpp::defaultHandler(const XML_Char*, int)
+-{
+-}
+-
+-
+-int
+-expatpp::notStandaloneHandler()
+-{
+- return 0;
+-}
+-
+-
+-void
+-expatpp::unparsedEntityDecl(const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*)
+-{
+-}
+-
+-
+-void
+-expatpp::notationDecl(const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*)
+-{
+-}
+-
+-
+-int
+-expatpp::skipWhiteSpace(const XML_Char* startFrom)
+-{
+- // use our own XML definition of white space
+- // TO DO - confirm this is correct!
+- const XML_Char* s = startFrom;
+- XML_Char c = *s;
+- while ((c==' ') || (c=='\t') || (c=='\n') || (c=='\r')) {
+- s++;
+- c = *s;
+- }
+- const int numSkipped = s - startFrom;
+- return numSkipped;
+-}
+-
+-
+-/**
+- Iterate the paired attribute name/value until find a pair with matching name.
+- \return pointer to the value or null if not found.
+-*/
+-const XML_Char*
+-expatpp::getAttribute(const XML_Char* matchingName, const XML_Char** atts)
+-{
+- for (int i=0; atts[i]; i++) {
+- const XML_Char* attributeName = atts[i++];
+- assert(attributeName); // shouldn't fail this because of loop test above
+- if(tcscmp(attributeName, matchingName)==0) {
+- return atts[i]; // if 2nd item was missing, this returns 0 safely indicating failure
+- }
+- }
+- return 0;
+-}
+-
+-
+-/**
+-\bug will always return 0 for PPC
+-*/
+-bool
+-expatpp::getIntegerAttribute(const XML_Char *matchingName, const XML_Char **atts, int& outAtt)
+-{
+- const XML_Char* attStr = getAttribute(matchingName, atts);
+- if (!attStr)
+- return false;
+- int i=0;
+-#ifdef XML_UNICODE
+-fail to compile because need this now
+-#else
+- sscanf(attStr, "%d", &i);
+-#endif
+- outAtt = i;
+- return true;
+-}
+-
+-
+-/**
+-\bug will always return 0 for PPC
+-*/
+-bool
+-expatpp::getDoubleAttribute(const XML_Char *matchingName, const XML_Char **atts, double& outAtt)
+-{
+- const XML_Char* attStr = getAttribute(matchingName, atts);
+- if (!attStr)
+- return false;
+- float f = 0.0; // sscanf doesn't allow point to double
+-#ifdef XML_UNICODE
+-fail to compile because need this now
+-#else
+- sscanf(attStr, "%f", &f);
+-#endif
+- outAtt = f;
+- return true;
+-}
+-
+-
+-bool
+-expatpp::emptyCharData(const XML_Char *s, int len)
+-{
+-// usually call from top of overriden charData methods
+- if (len==0)
+- return true; //*** early exit - empty string, may never occur??
+-
+-// skip newline and empty whitespace
+- if (
+- ((len==1) && ( (s[0]=='\n') || (s[0]=='\r')) ) || // just CR or just LF
+- ((len==2) && (s[0]=='\r') && (s[1]=='\n')) // DOS-style CRLF
+- )
+- return true; //*** early exit - newline
+-
+- const int lastCharAt = len-1;
+- if (s[lastCharAt]==' ') { // maybe all whitespace
+- int i;
+- for (i=0; i<lastCharAt; i++) {
+- if (s[i]!=' ')
+- break;
+- }
+- if (i==lastCharAt)
+- return true; //*** early exit - all spaces
+- }
+- return false;
+-}
+-
+-
+-//-------- Added for expat 1.95.5---------------
+-void
+-expatpp::attlistDeclCallback(void *userData,
+- const XML_Char *elname,
+- const XML_Char *attname,
+- const XML_Char *att_type,
+- const XML_Char *dflt,
+- int isrequired)
+-{
+- ((expatpp*)userData)->attlistDecl(elname, attname, att_type, dflt, isrequired);
+-}
+-
+-
+-void
+-expatpp::commentCallback(void *userData, const XML_Char *data)
+-{
+- ((expatpp*)userData)->comment(data);
+-}
+-
+-
+-void
+-expatpp::elementDeclCallback(void *userData, const XML_Char *name, XML_Content *model)
+-{
+- ((expatpp*)userData)->elementDecl(name, model);
+-}
+-
+-
+-void
+-expatpp::endCdataSectionCallback(void *userData)
+-{
+- ((expatpp*)userData)->endCdataSection();
+-}
+-
+-
+-void
+-expatpp::endDoctypeDeclCallback(void *userData)
+-{
+- ((expatpp*)userData)->endDoctypeDecl();
+-}
+-
+-
+-void
+-expatpp::entityDeclCallback(void *userData,
+- const XML_Char *entityName,
+- int is_parameter_entity,
+- const XML_Char *value,
+- int value_length,
+- const XML_Char *base,
+- const XML_Char *systemId,
+- const XML_Char *publicId,
+- const XML_Char *notationName)
+-{
+- ((expatpp*)userData)->entityDecl(entityName, is_parameter_entity, value, value_length, base, systemId, publicId, notationName);
+-}
+-
+-
+-void
+-expatpp::skippedEntityCallback(void *userData, const XML_Char *entityName, int is_parameter_entity)
+-{
+- ((expatpp*)userData)->skippedEntity(entityName, is_parameter_entity);
+-}
+-
+-
+-void
+-expatpp::startCdataSectionCallback(void *userData)
+-{
+- ((expatpp*)userData)->startCdataSection();
+-}
+-
+-
+-void
+-expatpp::startDoctypeDeclCallback(void *userData,
+- const XML_Char *doctypeName,
+- const XML_Char *sysid,
+- const XML_Char *pubid,
+- int has_internal_subset)
+-{
+- ((expatpp*)userData)->startDoctypeDecl(doctypeName, sysid, pubid, has_internal_subset);
+-}
+-
+-
+-void
+-expatpp::xmlDeclCallback(void *userData, const XML_Char *version,
+- const XML_Char *encoding,
+- int standalone)
+-{
+- ((expatpp*)userData)->xmlDecl(version, encoding, standalone);
+-}
+-
+-
+-void
+-expatpp::attlistDecl(
+- const XML_Char *elname,
+- const XML_Char *attname,
+- const XML_Char *att_type,
+- const XML_Char *dflt,
+- int isrequired)
+-{
+-}
+-
+-
+-void
+-expatpp::comment( const XML_Char *data)
+-{
+-}
+-
+-
+-void
+-expatpp::elementDecl( const XML_Char *name, XML_Content *model)
+-{
+-}
+-
+-
+-void
+-expatpp::endCdataSection()
+-{
+-}
+-
+-
+-void
+-expatpp::endDoctypeDecl()
+-{
+-}
+-
+-
+-void
+-expatpp::entityDecl(
+- const XML_Char *entityName,
+- int is_parameter_entity,
+- const XML_Char *value,
+- int value_length,
+- const XML_Char *base,
+- const XML_Char *systemId,
+- const XML_Char *publicId,
+- const XML_Char *notationName)
+-{
+-}
+-
+-
+-void
+-expatpp::skippedEntity( const XML_Char *entityName, int is_parameter_entity)
+-{
+-}
+-
+-
+-void
+-expatpp::startCdataSection()
+-{
+-}
+-
+-
+-void
+-expatpp::startDoctypeDecl(const XML_Char *doctypeName,
+- const XML_Char *sysid,
+- const XML_Char *pubid,
+- int has_internal_subset)
+-{
+-}
+-
+-
+-void
+-expatpp::xmlDecl( const XML_Char *version,
+- const XML_Char *encoding,
+- int standalone)
+-{
+-}
+-
+-
+-
+-
+-// -------------------------------------------------------
+-// e x p a t p p N e s t i n g
+-// -------------------------------------------------------
+-/**
+- \param parent can be null in which case this is root parser
+-
+- \note The handlers set in here MUST be also set in SetupHandlers
+- which is a virtual method invoked by expatpp::ResetParser. Otherwise
+- you can have subtle bugs with a nested parser not properly returning
+- after reusing a parser (nasty and found rapidly only via extensive unit
+- tests and plentiful assertions!).
+-
+- \WARNING
+- The assumption that is not obvious here is that if you want to use
+- nested parsers, then your topmost parser must also be an expatppNesting
+- subclass, NOT an expatpp subclass, because we need the
+- nestedStartElementCallback and nestedEndElementCallback
+- callbacks to override those in the expatpp ctor.
+-
+-
+-
+- \todo go back over code in detail and confirm above warning still valid
+- I think if we used expat's functions to invoke the registered callback
+- might be safer - the explicit function call we have in nestedEndElementCallback
+- certainly assumes the parent type.
+-*/
+-expatppNesting::expatppNesting(expatppNesting* parent) :
+- expatpp(parent==0), // don't create parser - we're taking over from parent if given
+- mDepth(0),
+- mParent(parent),
+- mOwnedChild(0),
+- mSelfDeleting(true)
+-{
+- if ( parent )
+- {
+- RegisterWithParentXMLParser();
+- parent->AdoptChild(this);
+- }
+- else
+- {
+- // No parent - the expatpp constructor will have created a new mParser (expat parser)
+- ::XML_SetElementHandler(mParser, nestedStartElementCallback, nestedEndElementCallback);
+- }
+- assert(mParser); // either we created above or expatpp
+-}
+-
+-
+-expatppNesting::~expatppNesting()
+-{
+- assert(!mParent); // if we are a sub-parser, should not delete without calling returnToParent
+- DeleteChild();
+-}
+-
+-
+-/**
+- Call parent version then override same as in our ctor.
+-*/
+-void
+-expatppNesting::SetupHandlers()
+-{
+- expatpp::SetupHandlers();
+- ::XML_SetElementHandler(mParser, nestedStartElementCallback, nestedEndElementCallback);
+-}
+-
+-/**
+- Must use if you have adopted a child parser and want to dispose of it early.
+-*/
+-void
+-expatppNesting::DeleteChild()
+-{
+- delete mOwnedChild;
+- mOwnedChild = 0;
+-}
+-
+-
+-/**
+- Invoked as a callback from a child ctor when we pass in a parent pointer.
+- OR used from switchToNewSubParser, in which case it may be the 2nd time
+- we're called for a given child (see scenarios in expatppNesting class comment).
+-*/
+-void
+-expatppNesting::AdoptChild(expatppNesting* adoptingChild)
+-{
+- if ( mOwnedChild != adoptingChild )
+- {
+- delete mOwnedChild;
+- mOwnedChild = adoptingChild;
+- }
+-}
+-
+-
+-/**
+- to use parent's underlying expat parser
+-*/
+-void
+-expatppNesting::RegisterWithParentXMLParser()
+-{
+- mParser = mParent->mParser;
+- ::XML_SetUserData(mParser, this);
+-}
+-
+-
+-/**
+- User code (typically the startElement handler of user parsers derived from expatppNesting)
+- may call
+- switchToNewSubParser( new UserChildParser() );
+- to hand off the current document to a child parser that understands the next segment of XML.
+- Control will be returned to the original (parent) parser when the end of the child element
+- is reached.
+- In its lifetime a 'parent' parser may switch control to several child parsers (one at a time
+- of course) as it moves through the document encoutering various types of child element.
+-
+- A child to which older code (eg: OOFILE) has just switched control by
+- new childParser(this) will be self-deleting and will clear our mOwnedChild in its dtor.
+-*/
+-void expatppNesting::switchToNewSubParser( expatppNesting* pAdoptedChild )
+-{
+- assert(pAdoptedChild);
+- AdoptChild(pAdoptedChild);
+- pAdoptedChild->BeAdopted(this);
+-}
+-
+-
+-/**
+- If this is root parser, nestedEndElementCallback won't call returnToParent.
+- Therefore it is safe to put parsers on the stack.
+-*/
+-expatppNesting*
+-expatppNesting::returnToParent()
+-{
+- expatppNesting* ret = mParent;
+- ::XML_SetUserData(mParser, mParent);
+- mParent=0;
+- mParser=0; // prevent parser shutdown by expatpp::~expatpp!!
+- if (mSelfDeleting) {
+- ret->OwnedChildOrphansItself(this);
+- delete this; // MUST BE LAST THING CALLED IN NON-VIRTUAL FUNCTION, NO MEMBER ACCESS
+- }
+- return ret;
+-}
+-
+-
+-void
+-expatppNesting::nestedStartElementCallback(void *userData, const XML_Char* name, const XML_Char** atts)
+-{
+- assert(userData);
+- expatppNesting* nestedParser = (expatppNesting*)userData;
+- nestedParser->mDepth++;
+- nestedParser->startElement(name, atts); // probably user override
+-}
+-
+-
+-/**
+- If this is root parser, will never hit nestedEndElementCallback after closing element,
+- except for when we call it.
+- \param userData should be non-nil except for specific case of ending root
+-*/
+-void
+-expatppNesting::nestedEndElementCallback(void *userData, const XML_Char* name)
+-{
+- if (!userData)
+- return; // end tag for root
+-
+- expatppNesting* nestedParser = (expatppNesting*)userData;
+-// we don't know until we hit a closing tag 'outside' us that our run is done
+- if (nestedParser->mDepth==0) {
+- expatppNesting* parentParser = nestedParser->returnToParent();
+- nestedEndElementCallback(parentParser, name); // callbacks for expatppNesting stay registered, so safe
+- //if we don't invoke their callback, they will not balance their mDepth
+- }
+- else {
+- // end of an element this parser has started - normal case
+- nestedParser->endElement(name); // probably user override
+- nestedParser->mDepth--;
+- }
+-}
+-
+-
+-/**
+- Called by switchToNewSubParser to indicate a newly created child parser
+- is now the currently active child for adoptingParent and the child
+- isn't expected to be self deleting.
+-
+- Normal code to create an owned child would be either
+- switchToNewSubParser( new UserChildParser(this) );
+- where this is the currently active parser and you want to be deleting it, or
+- new UserChildParser(this);
+- to have a child parser self-delete
+-
+- \par Important Safety Note
+- Copes with the situation of people forgetting to pass
+- in the parent parser (and hence creating a new one by default)
+- if invoked by switchToNewSubParser( new UserChildParser() )
+- by somewhat wastefully deleting the parser created in expatpp::expatpp
+- by us being a root parser.
+-*/
+-void
+-expatppNesting::BeAdopted(expatppNesting* adoptingParent)
+-{
+- if (mParent) {
+- assert(mParent==adoptingParent);
+- }
+- else { // root parser being adopted, cleanup!
+- ReleaseParser();
+- mParent = adoptingParent;
+- RegisterWithParentXMLParser();
+- }
+- mSelfDeleting = false;
+-}
+-
+-
+-
+-
+diff --git a/expatpp.h b/expatpp.h
+deleted file mode 100755
+index 098c69d..0000000
+--- a/expatpp.h
++++ /dev/null
+@@ -1,339 +0,0 @@
+-// expatpp
+-#ifndef H_EXPATPP
+-#define H_EXPATPP
+-
+-#ifdef EXPATPP_COMPATIBLE_EXPAT12 // earlier versions of expat up to v1.2
+- #include "xmlparse.h"
+-#else
+- #include "expat.h" // since some version of expat moved to SourceForge
+-#endif
+-#include <stdio.h>
+-#include <assert.h>
+-
+-
+-/**
+-\file expatpp.h
+-Latest version 29-Dec-2002 compatible with expat 1.95.6
+-*/
+-
+-/**
+-expatpp follows a simple pattern for converting the semi-OOP callback design of
+-expat into a true class which allows you to override virtual methods to supply
+-callbacks.
+-
+-\par USING expatpp
+-see testexpatpp.cpp for a detailed example
+-
+-1) decide which callbacks you wish to use, eg: just startElement
+-
+-2) declare a subclass of expatpp, eg:
+-class myExpat : public expatpp {
+- virtual void startElement(const XML_Char* name, const XML_Char** atts);
+-};
+-
+-3) create an instance of your object and pass in a buffer to parse
+-myExpat parser;
+-parser.XML_Parse(buf, len, done)
+-
+-
+-\par HOW IT WORKS
+-The User Data which expat maintains is simply a pointer to an instance of your object.
+-
+-Inline static functions are specified as the callbacks to expat.
+-These static functions take the user data parameter returned from expat and cast it
+-to a pointer to an expatpp object.
+-
+-Using that typed pointer they then call the appropriate virtual method.
+-
+-If you have overriden a given virtual method then your version will be called, otherwise
+-the (empty) method in the base expatpp class is called.
+-
+-\par Possible Efficiency Tactic
+-For efficiency, you could provide your own constructor and set some of the callbacks
+-to 0, so expat doesn't call the static functions. (untested idea).
+-
+-\par Naming Conventions
+-The virtual functions violate the usual AD Software convention of lowercase first letter
+-for public methods but this was a late change to protected and too much user code out there.
+-
+-
+-\todo Possibly implement some handling for XML_SetExternalEntityRefHandler which does NOT
+-receive user data, just the parser, so can't use normal pattern for invoking virtual methods
+-
+-\todo Possibly implement handling for XML_UnknownEncodingHandler.
+-
+-\todo review design for nested calls - not happy that it is the right thing that they don't see
+-their start and ending elements - makes it harder to unit test them in isolation.
+-
+-\todo unit tests
+-
+-\todo especially test abort mechanism
+-
+-\todo reinstate copy constrution and assignment with child parser cleanup
+-
+-\todo allow specification of encoding
+-*/
+-class expatpp {
+-public:
+- expatpp(bool createParser=true);
+- virtual ~expatpp();
+-
+- operator XML_Parser() const;
+-
+-protected: // callback virtuals should only be invoked through our Callback static functions
+- bool emptyCharData(const XML_Char* s, int len); // utility often used in overridden charData
+-
+-// overrideable callbacks
+- virtual void startElement(const XML_Char* name, const XML_Char** atts);
+- virtual void endElement(const XML_Char*);
+- virtual void charData(const XML_Char*, int len);
+- virtual void processingInstruction(const XML_Char* target, const XML_Char* data);
+- virtual void defaultHandler(const XML_Char*, int len);
+- virtual int notStandaloneHandler();
+- virtual void unparsedEntityDecl(const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName);
+- virtual void notationDecl(const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
+- virtual void startNamespace(const XML_Char* prefix, const XML_Char* uri);
+- virtual void endNamespace(const XML_Char*);
+-/// \name Callbacks added to support expat 1.95.5
+-//@{
+- virtual void attlistDecl(
+- const XML_Char *elname,
+- const XML_Char *attname,
+- const XML_Char *att_type,
+- const XML_Char *dflt,
+- int isrequired);
+- virtual void endCdataSection();
+- virtual void endDoctypeDecl();
+- virtual void comment( const XML_Char *data);
+- virtual void elementDecl( const XML_Char *name, XML_Content *model);
+- virtual void entityDecl(
+- const XML_Char *entityName,
+- int is_parameter_entity,
+- const XML_Char *value,
+- int value_length,
+- const XML_Char *base,
+- const XML_Char *systemId,
+- const XML_Char *publicId,
+- const XML_Char *notationName);
+- virtual void skippedEntity(const XML_Char *entityName, int is_parameter_entity);
+- virtual void startCdataSection();
+- virtual void startDoctypeDecl(const XML_Char *doctypeName,
+- const XML_Char *sysid,
+- const XML_Char *pubid,
+- int has_internal_subset);
+- virtual void xmlDecl( const XML_Char *version,
+- const XML_Char *encoding,
+- int standalone);
+-//@}
+-
+-public:
+-/// \name XML interfaces
+-//@{
+- XML_Status XML_Parse(const char* buffer, int len, int isFinal);
+- virtual XML_Status parseFile(FILE* inFile);
+- virtual XML_Status parseString(const char*);
+- XML_Error XML_GetErrorCode();
+- int XML_GetCurrentLineNumber();
+- int XML_GetCurrentColumnNumber();
+-//@}
+-
+-protected:
+- XML_Parser mParser;
+- bool mHaveParsed;
+-
+-/// \name overrideables to customise behaviour, must call parent
+-//@{
+- virtual void ReleaseParser();
+- virtual void ResetParser();
+- virtual void SetupHandlers();
+-//@}
+-
+-/**
+- Override so subclass can react to an error causing exit from parse.
+- rather than leave it for application code to check status.
+- Useful point to insert logging to silently grab failed parses
+-*/
+- virtual void CheckFinalStatus(XML_Status) {};
+-
+-// static interface functions for callbacks
+-public:
+- static void startElementCallback(void *userData, const XML_Char* name, const XML_Char** atts);
+- static void endElementCallback(void *userData, const XML_Char* name);
+- static void startNamespaceCallback(void *userData, const XML_Char* prefix, const XML_Char* uri);
+- static void endNamespaceCallback(void *userData, const XML_Char* prefix);
+- static void charDataCallback(void *userData, const XML_Char* s, int len);
+- static void processingInstructionCallback(void *userData, const XML_Char* target, const XML_Char* data);
+- static void defaultHandlerCallback(void* userData, const XML_Char* s, int len);
+- static int notStandaloneHandlerCallback(void* userData);
+- static void unParsedEntityDeclCallback(void* userData, const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName);
+- static void notationDeclCallback(void *userData, const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
+-/// \name Callback interfacess added to support expat 1.95.5
+-//@{
+- static void attlistDeclCallback(void *userData,
+- const XML_Char *elname,
+- const XML_Char *attname,
+- const XML_Char *att_type,
+- const XML_Char *dflt,
+- int isrequired);
+- static void commentCallback(void *userData, const XML_Char *data);
+- static void elementDeclCallback(void *userData, const XML_Char *name, XML_Content *model);
+- static void endCdataSectionCallback(void *userData);
+- static void endDoctypeDeclCallback(void *userData);
+- static void entityDeclCallback(void *userData,
+- const XML_Char *entityName,
+- int is_parameter_entity,
+- const XML_Char *value,
+- int value_length,
+- const XML_Char *base,
+- const XML_Char *systemId,
+- const XML_Char *publicId,
+- const XML_Char *notationName);
+- static void skippedEntityCallback(void *userData, const XML_Char *entityName, int is_parameter_entity);
+- static void startCdataSectionCallback(void *userData);
+- static void startDoctypeDeclCallback(void *userData,
+- const XML_Char *doctypeName,
+- const XML_Char *sysid,
+- const XML_Char *pubid,
+- int has_internal_subset);
+- static void xmlDeclCallback(void *userData, const XML_Char *version,
+- const XML_Char *encoding,
+- int standalone);
+-//@}
+-
+-
+-// utilities
+- static int skipWhiteSpace(const XML_Char*);
+- static const XML_Char* getAttribute(const XML_Char *matchingName, const XML_Char **atts);
+- static bool getIntegerAttribute(const XML_Char *matchingName, const XML_Char **atts, int& outAtt);
+- static bool getDoubleAttribute(const XML_Char *matchingName, const XML_Char **atts, double& outAtt);
+-};
+-
+-
+-/**
+- subclass to support a hierarchy of parsers, in a sort of recursion or
+- 'nesting' approach, where a top-level parser might create sub-parsers
+- for part of a file.
+-
+- The currently active child parser is owned (mOwnedChild) and is deleted
+- by DeleteChild (invoked from the dtor) so error handling can propagate
+- up the tree, closing parsers, without leaks.
+-
+- \par Switching to sub-parsers
+- You can transfer to a sub-parser with
+- - new UserChildParser(this) // carries on using our parser, is self-deleting
+- - switchToNewSubParser( someVar = new UserChildParser(this) ) // if want to get values back after end parsing
+-
+- \warning You can accidentally invoke a new parser without it doing anything
+- - new UserChildParser() // will be new top-level parser, nothing to do with our XML
+-
+- \par Self-deletion
+- If you transfer control to a sub-parser with just new UserChildParser(this) then
+- it will be automatically self-deleting in its returnToParent method and
+- will invoke OwnedChildOrphansItself to clear our mOwnedChild.
+-
+- The reason for self-deletion being governed by a somewhat complex chain of
+- calls rather than simply a boolean flag is because expatpp has been in use
+- worldwide for many years and it was deemed too unfriendly to break code in
+- a manner which could cause unwanted side effects - the current approach safely
+- preserves self-deletion but also allows for expatpp to have parent parsers
+- own and delete children, without compiling with different options.
+-
+- \note
+- If you invoke a sub-parser with switchToNewSubParser( new UserChildParser() );
+- then the user child parser will start with a new XML parser instance
+- created by the expatpp ctor. This is safe but slightly wasteful of processing
+- as the new parser will be discarded by BeAdopted().
+-
+- \par Switching to child and explicitly deleting
+- switchToNewSubParser( somevar = new UserChildParser(this) ) allows you to get values
+- back out of the child parser, in the context of the parent, eg:
+-
+-\verbatim
+-
+-void MultiFilterParser::startElement(const XML_Char* name, const XML_Char **atts)
+-{
+- if(strcmp(name,"FilterRequest")==0) {
+- switchToNewSubParser(
+- mCurrentFilterParser = new FilterRequestParser(this, atts)
+- ); // we own and will have to explicitly delete
+-...
+-}
+-
+-void MultiFilterParser::endElement(const XML_Char *name)
+-{
+- if(strcmp(name,"FilterRequest")==0) {
+- assert(mCurrentFilterParser);
+- FilterClause* newClause = mCurrentFilterParser->orphanBuiltClause(); // retrieve data built by sub-parser
+-...
+- mCurrentFilterParser = 0;
+- DeleteChild();
+- }
+-}
+-\endverbatim
+-*/
+-class expatppNesting : public expatpp {
+-
+-public:
+- expatppNesting(expatppNesting* parent=0); ///< NOT a copy ctor!! this is a recursive situation
+- virtual ~expatppNesting();
+-
+- void switchToNewSubParser( expatppNesting* pAdoptedChild );
+- expatppNesting* returnToParent();
+-
+-protected:
+- void BeAdopted(expatppNesting* adoptingParent);
+- void OwnedChildOrphansItself(expatppNesting* callingChild);
+- void RegisterWithParentXMLParser();
+- virtual void AdoptChild(expatppNesting* adoptingChild);
+- virtual void DeleteChild();
+-
+- int mDepth;
+- bool mSelfDeleting; ///< only valid if mParent not null
+- expatppNesting* mParent; ///< may be null the parent owns this object
+- expatppNesting* mOwnedChild; ///< owned, optional currently active child (auto_ptr not used to avoid STL dependency)
+-
+-public:
+-/// \name interface functions for callbacks
+-//@{
+- static void nestedStartElementCallback(void* userData, const XML_Char* name, const XML_Char** atts);
+- static void nestedEndElementCallback(void* userData, const XML_Char* name);
+-//@}
+-
+-
+-/// \name overrideables to customise behaviour, must call parent
+-//@{
+- virtual void SetupHandlers();
+-//@}
+-
+-private:
+- // Forbid copy-construction and assignment, to prevent double-deletion of mOwnedChild
+- expatppNesting( const expatppNesting & );
+- expatppNesting & operator=( const expatppNesting & );
+-};
+-
+-
+-// inlines
+-
+-// -------------------------------------------------------
+-// e x p a t p p
+-// -------------------------------------------------------
+-inline
+-expatpp::operator XML_Parser() const
+-{
+- return mParser;
+-}
+-
+-
+-// -------------------------------------------------------
+-// e x p a t p p N e s t i n g
+-// -------------------------------------------------------
+-inline void
+-expatppNesting::OwnedChildOrphansItself(expatppNesting* callingChild)
+-{
+- assert(callingChild==mOwnedChild);
+- mOwnedChild = 0;
+-}
+-
+-
+-
+-#endif // H_EXPATPP
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+new file mode 100644
+index 0000000..ed70f58
+--- /dev/null
++++ b/lib/CMakeLists.txt
+@@ -0,0 +1,3 @@
++
++add_library(expatpp SHARED expatpp.cpp)
++target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+\ No newline at end of file
+diff --git a/lib/expatpp.cpp b/lib/expatpp.cpp
+new file mode 100755
+index 0000000..8a7c532
+--- /dev/null
++++ b/lib/expatpp.cpp
+@@ -0,0 +1,799 @@
++// expatpp
++#ifdef UNDER_CE
++ #include <string.h>
++ #include <windows.h>
++ #include <dbgapi.h>
++ #define assert ASSERT
++#else
++ #include <string>
++ using namespace std;
++ #include <assert.h>
++#endif
++#include "expatpp.h"
++
++
++// may be defined in xmltchar.h or elsewhere
++#ifndef tcscmp
++ #ifdef XML_UNICODE
++ #define tcscmp wcscmp
++ #else
++ #define tcscmp strcmp
++ #endif // XML_UNICODE
++#endif // tcscmp
++
++
++#ifndef BUFSIZ
++ #define BUFSIZ 4096
++#endif
++
++#include <stdio.h>
++#include <string.h>
++
++expatpp::expatpp(bool createParser) :
++ mParser(0), // in case of exception below
++ mHaveParsed(false)
++{
++ if (createParser) {
++ // subclasses may call this ctor after parser created!
++ mParser = XML_ParserCreate(0);
++ SetupHandlers();
++ }
++}
++
++
++void
++expatpp::SetupHandlers()
++{
++ ::XML_SetUserData(mParser, this);
++ ::XML_SetElementHandler(mParser, startElementCallback, endElementCallback);
++ ::XML_SetCharacterDataHandler(mParser, charDataCallback);
++ ::XML_SetProcessingInstructionHandler(mParser, processingInstructionCallback);
++ ::XML_SetDefaultHandler(mParser, defaultHandlerCallback);
++ ::XML_SetUnparsedEntityDeclHandler(mParser, unParsedEntityDeclCallback);
++ ::XML_SetNotationDeclHandler(mParser, notationDeclCallback);
++ ::XML_SetNotStandaloneHandler(mParser, notStandaloneHandlerCallback);
++ ::XML_SetNamespaceDeclHandler(mParser, startNamespaceCallback, endNamespaceCallback);
++#ifndef EXPATPP_COMPATIBLE_EXPAT12
++ ::XML_SetAttlistDeclHandler(mParser, attlistDeclCallback);
++ ::XML_SetCdataSectionHandler(mParser, startCdataSectionCallback, endCdataSectionCallback);
++ ::XML_SetCommentHandler(mParser, commentCallback);
++ ::XML_SetDoctypeDeclHandler(mParser, startDoctypeDeclCallback, endDoctypeDeclCallback);
++ ::XML_SetElementDeclHandler(mParser, elementDeclCallback);
++ ::XML_SetEntityDeclHandler(mParser, entityDeclCallback);
++ ::XML_SetSkippedEntityHandler(mParser, skippedEntityCallback);
++ ::XML_SetXmlDeclHandler(mParser, xmlDeclCallback);
++#endif
++}
++
++
++expatpp::~expatpp()
++{
++ if (mParser) // allows subclasses to avoid finishing parsing
++ ReleaseParser();
++}
++
++
++/**
++ Provide single point that will call XML_ParserFree.
++ Nothing else in this code should call XML_ParserFree!
++*/
++void
++expatpp::ReleaseParser()
++{
++ ::XML_ParserFree(mParser);
++ mParser = 0;
++}
++
++
++
++/**
++ Provide single point that will call XML_ParserReset.
++ Guarded against trivial reset before use in case that breaks
++ expat or creates overhead.
++
++ \todo pass in encoding to XML_ParserReset when we support encodings
++*/
++void
++expatpp::ResetParser()
++{
++#ifdef EXPATPP_COMPATIBLE_EXPAT12
++ assert(!"Reset not available in earlier than expat 1.95.3");s
++#else
++ if (mHaveParsed) {
++ ::XML_ParserReset(mParser, NULL);
++ SetupHandlers();
++ mHaveParsed = false;
++ }
++#endif
++}
++
++
++/**
++ Parse entire file, basically copy of the loop from the elements.c example.
++*/
++XML_Status
++expatpp::parseFile(FILE* inFile)
++{
++ ResetParser();
++
++ char buf[BUFSIZ];
++ int done;
++ if (!inFile)
++ return XML_STATUS_ERROR;
++ fseek(inFile, 0, SEEK_SET); // reset for reading
++ do {
++ size_t len = fread(buf, 1, sizeof(buf), inFile);
++ done = len < sizeof(buf);
++ enum XML_Status parseStatus;
++ if ((parseStatus = XML_Parse(buf, len, done))!=XML_STATUS_OK) {
++ return parseStatus;
++ }
++ } while (!done);
++ return XML_STATUS_OK;
++}
++
++
++XML_Status
++expatpp::XML_Parse(const char *s, int len, int isFinal)
++{
++ mHaveParsed = true;
++ const XML_Status retStatus = ::XML_Parse(mParser, s, len, isFinal);
++ if (isFinal)
++ CheckFinalStatus(retStatus);
++ return retStatus;
++}
++
++
++XML_Error
++expatpp::XML_GetErrorCode()
++{
++ return ::XML_GetErrorCode(mParser);
++}
++
++
++int
++expatpp::XML_GetCurrentLineNumber()
++{
++ return ::XML_GetCurrentLineNumber(mParser);
++}
++
++
++int
++expatpp::XML_GetCurrentColumnNumber()
++{
++ return ::XML_GetCurrentColumnNumber(mParser);
++}
++
++
++
++
++/**
++ Parse string which is assumed to be entire XML document.
++ Written to stop stupid errors of being off by one in the string length causing
++ wasted debugging time, such as:
++\verbatim
++ const char[] kSampleSettings = "<settings/>";
++ const int sampleSize = sizeof(kSampleSettings)-1; // unless you remember to subtract one here will get invalid token error
++ if (!parser.XML_Parse(kSampleSettings, sampleSize, 1)) {
++\endverbatim
++*/
++XML_Status
++expatpp::parseString(const char* inString)
++{
++ ResetParser();
++ const int inLen = strlen(inString);
++ return XML_Parse(inString, inLen, 1);
++}
++
++void
++expatpp::startElementCallback(void *userData, const XML_Char* name, const XML_Char** atts)
++{
++ ((expatpp*)userData)->startElement(name, atts);
++}
++
++
++void
++expatpp::endElementCallback(void *userData, const XML_Char* name)
++{
++ ((expatpp*)userData)->endElement(name);
++}
++
++
++void
++expatpp::startNamespaceCallback(void *userData, const XML_Char* prefix, const XML_Char* uri)
++{
++ ((expatpp*)userData)->startNamespace(prefix, uri);
++}
++
++
++void
++expatpp::endNamespaceCallback(void *userData, const XML_Char* prefix)
++{
++ ((expatpp*)userData)->endNamespace(prefix);
++}
++
++
++void
++expatpp::charDataCallback(void *userData, const XML_Char* s, int len)
++{
++ ((expatpp*)userData)->charData(s, len);
++}
++
++
++void
++expatpp:: processingInstructionCallback(void *userData, const XML_Char* target, const XML_Char* data)
++{
++ ((expatpp*)userData)->processingInstruction(target, data);
++}
++
++
++void
++expatpp::defaultHandlerCallback(void* userData, const XML_Char* s, int len)
++{
++ ((expatpp*)userData)->defaultHandler(s, len);
++}
++
++
++int
++expatpp::notStandaloneHandlerCallback(void* userData)
++{
++ return ((expatpp*)userData)->notStandaloneHandler();
++}
++
++
++void
++expatpp::unParsedEntityDeclCallback(void* userData, const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName)
++{
++ ((expatpp*)userData)->unparsedEntityDecl(entityName, base, systemId, publicId, notationName);
++}
++
++
++void
++expatpp::notationDeclCallback(void *userData, const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId)
++{
++ ((expatpp*)userData)->notationDecl(notationName, base, systemId, publicId);
++}
++
++
++void
++expatpp::startElement(const XML_Char*, const XML_Char**)
++{}
++
++
++void
++expatpp::endElement(const XML_Char*)
++{}
++
++
++void
++expatpp::startNamespace(const XML_Char* /* prefix */, const XML_Char* /* uri */)
++{}
++
++
++void
++expatpp::endNamespace(const XML_Char*)
++{}
++
++
++void
++expatpp::charData(const XML_Char*, int )
++{
++}
++
++
++void
++expatpp::processingInstruction(const XML_Char*, const XML_Char*)
++{
++}
++
++
++void
++expatpp::defaultHandler(const XML_Char*, int)
++{
++}
++
++
++int
++expatpp::notStandaloneHandler()
++{
++ return 0;
++}
++
++
++void
++expatpp::unparsedEntityDecl(const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*)
++{
++}
++
++
++void
++expatpp::notationDecl(const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*)
++{
++}
++
++
++int
++expatpp::skipWhiteSpace(const XML_Char* startFrom)
++{
++ // use our own XML definition of white space
++ // TO DO - confirm this is correct!
++ const XML_Char* s = startFrom;
++ XML_Char c = *s;
++ while ((c==' ') || (c=='\t') || (c=='\n') || (c=='\r')) {
++ s++;
++ c = *s;
++ }
++ const int numSkipped = s - startFrom;
++ return numSkipped;
++}
++
++
++/**
++ Iterate the paired attribute name/value until find a pair with matching name.
++ \return pointer to the value or null if not found.
++*/
++const XML_Char*
++expatpp::getAttribute(const XML_Char* matchingName, const XML_Char** atts)
++{
++ for (int i=0; atts[i]; i++) {
++ const XML_Char* attributeName = atts[i++];
++ assert(attributeName); // shouldn't fail this because of loop test above
++ if(tcscmp(attributeName, matchingName)==0) {
++ return atts[i]; // if 2nd item was missing, this returns 0 safely indicating failure
++ }
++ }
++ return 0;
++}
++
++
++/**
++\bug will always return 0 for PPC
++*/
++bool
++expatpp::getIntegerAttribute(const XML_Char *matchingName, const XML_Char **atts, int& outAtt)
++{
++ const XML_Char* attStr = getAttribute(matchingName, atts);
++ if (!attStr)
++ return false;
++ int i=0;
++#ifdef XML_UNICODE
++fail to compile because need this now
++#else
++ sscanf(attStr, "%d", &i);
++#endif
++ outAtt = i;
++ return true;
++}
++
++
++/**
++\bug will always return 0 for PPC
++*/
++bool
++expatpp::getDoubleAttribute(const XML_Char *matchingName, const XML_Char **atts, double& outAtt)
++{
++ const XML_Char* attStr = getAttribute(matchingName, atts);
++ if (!attStr)
++ return false;
++ float f = 0.0; // sscanf doesn't allow point to double
++#ifdef XML_UNICODE
++fail to compile because need this now
++#else
++ sscanf(attStr, "%f", &f);
++#endif
++ outAtt = f;
++ return true;
++}
++
++
++bool
++expatpp::emptyCharData(const XML_Char *s, int len)
++{
++// usually call from top of overriden charData methods
++ if (len==0)
++ return true; //*** early exit - empty string, may never occur??
++
++// skip newline and empty whitespace
++ if (
++ ((len==1) && ( (s[0]=='\n') || (s[0]=='\r')) ) || // just CR or just LF
++ ((len==2) && (s[0]=='\r') && (s[1]=='\n')) // DOS-style CRLF
++ )
++ return true; //*** early exit - newline
++
++ const int lastCharAt = len-1;
++ if (s[lastCharAt]==' ') { // maybe all whitespace
++ int i;
++ for (i=0; i<lastCharAt; i++) {
++ if (s[i]!=' ')
++ break;
++ }
++ if (i==lastCharAt)
++ return true; //*** early exit - all spaces
++ }
++ return false;
++}
++
++
++//-------- Added for expat 1.95.5---------------
++void
++expatpp::attlistDeclCallback(void *userData,
++ const XML_Char *elname,
++ const XML_Char *attname,
++ const XML_Char *att_type,
++ const XML_Char *dflt,
++ int isrequired)
++{
++ ((expatpp*)userData)->attlistDecl(elname, attname, att_type, dflt, isrequired);
++}
++
++
++void
++expatpp::commentCallback(void *userData, const XML_Char *data)
++{
++ ((expatpp*)userData)->comment(data);
++}
++
++
++void
++expatpp::elementDeclCallback(void *userData, const XML_Char *name, XML_Content *model)
++{
++ ((expatpp*)userData)->elementDecl(name, model);
++}
++
++
++void
++expatpp::endCdataSectionCallback(void *userData)
++{
++ ((expatpp*)userData)->endCdataSection();
++}
++
++
++void
++expatpp::endDoctypeDeclCallback(void *userData)
++{
++ ((expatpp*)userData)->endDoctypeDecl();
++}
++
++
++void
++expatpp::entityDeclCallback(void *userData,
++ const XML_Char *entityName,
++ int is_parameter_entity,
++ const XML_Char *value,
++ int value_length,
++ const XML_Char *base,
++ const XML_Char *systemId,
++ const XML_Char *publicId,
++ const XML_Char *notationName)
++{
++ ((expatpp*)userData)->entityDecl(entityName, is_parameter_entity, value, value_length, base, systemId, publicId, notationName);
++}
++
++
++void
++expatpp::skippedEntityCallback(void *userData, const XML_Char *entityName, int is_parameter_entity)
++{
++ ((expatpp*)userData)->skippedEntity(entityName, is_parameter_entity);
++}
++
++
++void
++expatpp::startCdataSectionCallback(void *userData)
++{
++ ((expatpp*)userData)->startCdataSection();
++}
++
++
++void
++expatpp::startDoctypeDeclCallback(void *userData,
++ const XML_Char *doctypeName,
++ const XML_Char *sysid,
++ const XML_Char *pubid,
++ int has_internal_subset)
++{
++ ((expatpp*)userData)->startDoctypeDecl(doctypeName, sysid, pubid, has_internal_subset);
++}
++
++
++void
++expatpp::xmlDeclCallback(void *userData, const XML_Char *version,
++ const XML_Char *encoding,
++ int standalone)
++{
++ ((expatpp*)userData)->xmlDecl(version, encoding, standalone);
++}
++
++
++void
++expatpp::attlistDecl(
++ const XML_Char *elname,
++ const XML_Char *attname,
++ const XML_Char *att_type,
++ const XML_Char *dflt,
++ int isrequired)
++{
++}
++
++
++void
++expatpp::comment( const XML_Char *data)
++{
++}
++
++
++void
++expatpp::elementDecl( const XML_Char *name, XML_Content *model)
++{
++}
++
++
++void
++expatpp::endCdataSection()
++{
++}
++
++
++void
++expatpp::endDoctypeDecl()
++{
++}
++
++
++void
++expatpp::entityDecl(
++ const XML_Char *entityName,
++ int is_parameter_entity,
++ const XML_Char *value,
++ int value_length,
++ const XML_Char *base,
++ const XML_Char *systemId,
++ const XML_Char *publicId,
++ const XML_Char *notationName)
++{
++}
++
++
++void
++expatpp::skippedEntity( const XML_Char *entityName, int is_parameter_entity)
++{
++}
++
++
++void
++expatpp::startCdataSection()
++{
++}
++
++
++void
++expatpp::startDoctypeDecl(const XML_Char *doctypeName,
++ const XML_Char *sysid,
++ const XML_Char *pubid,
++ int has_internal_subset)
++{
++}
++
++
++void
++expatpp::xmlDecl( const XML_Char *version,
++ const XML_Char *encoding,
++ int standalone)
++{
++}
++
++
++
++
++// -------------------------------------------------------
++// e x p a t p p N e s t i n g
++// -------------------------------------------------------
++/**
++ \param parent can be null in which case this is root parser
++
++ \note The handlers set in here MUST be also set in SetupHandlers
++ which is a virtual method invoked by expatpp::ResetParser. Otherwise
++ you can have subtle bugs with a nested parser not properly returning
++ after reusing a parser (nasty and found rapidly only via extensive unit
++ tests and plentiful assertions!).
++
++ \WARNING
++ The assumption that is not obvious here is that if you want to use
++ nested parsers, then your topmost parser must also be an expatppNesting
++ subclass, NOT an expatpp subclass, because we need the
++ nestedStartElementCallback and nestedEndElementCallback
++ callbacks to override those in the expatpp ctor.
++
++
++
++ \todo go back over code in detail and confirm above warning still valid
++ I think if we used expat's functions to invoke the registered callback
++ might be safer - the explicit function call we have in nestedEndElementCallback
++ certainly assumes the parent type.
++*/
++expatppNesting::expatppNesting(expatppNesting* parent) :
++ expatpp(parent==0), // don't create parser - we're taking over from parent if given
++ mDepth(0),
++ mParent(parent),
++ mOwnedChild(0),
++ mSelfDeleting(true)
++{
++ if ( parent )
++ {
++ RegisterWithParentXMLParser();
++ parent->AdoptChild(this);
++ }
++ else
++ {
++ // No parent - the expatpp constructor will have created a new mParser (expat parser)
++ ::XML_SetElementHandler(mParser, nestedStartElementCallback, nestedEndElementCallback);
++ }
++ assert(mParser); // either we created above or expatpp
++}
++
++
++expatppNesting::~expatppNesting()
++{
++ assert(!mParent); // if we are a sub-parser, should not delete without calling returnToParent
++ DeleteChild();
++}
++
++
++/**
++ Call parent version then override same as in our ctor.
++*/
++void
++expatppNesting::SetupHandlers()
++{
++ expatpp::SetupHandlers();
++ ::XML_SetElementHandler(mParser, nestedStartElementCallback, nestedEndElementCallback);
++}
++
++/**
++ Must use if you have adopted a child parser and want to dispose of it early.
++*/
++void
++expatppNesting::DeleteChild()
++{
++ delete mOwnedChild;
++ mOwnedChild = 0;
++}
++
++
++/**
++ Invoked as a callback from a child ctor when we pass in a parent pointer.
++ OR used from switchToNewSubParser, in which case it may be the 2nd time
++ we're called for a given child (see scenarios in expatppNesting class comment).
++*/
++void
++expatppNesting::AdoptChild(expatppNesting* adoptingChild)
++{
++ if ( mOwnedChild != adoptingChild )
++ {
++ delete mOwnedChild;
++ mOwnedChild = adoptingChild;
++ }
++}
++
++
++/**
++ to use parent's underlying expat parser
++*/
++void
++expatppNesting::RegisterWithParentXMLParser()
++{
++ mParser = mParent->mParser;
++ ::XML_SetUserData(mParser, this);
++}
++
++
++/**
++ User code (typically the startElement handler of user parsers derived from expatppNesting)
++ may call
++ switchToNewSubParser( new UserChildParser() );
++ to hand off the current document to a child parser that understands the next segment of XML.
++ Control will be returned to the original (parent) parser when the end of the child element
++ is reached.
++ In its lifetime a 'parent' parser may switch control to several child parsers (one at a time
++ of course) as it moves through the document encoutering various types of child element.
++
++ A child to which older code (eg: OOFILE) has just switched control by
++ new childParser(this) will be self-deleting and will clear our mOwnedChild in its dtor.
++*/
++void expatppNesting::switchToNewSubParser( expatppNesting* pAdoptedChild )
++{
++ assert(pAdoptedChild);
++ AdoptChild(pAdoptedChild);
++ pAdoptedChild->BeAdopted(this);
++}
++
++
++/**
++ If this is root parser, nestedEndElementCallback won't call returnToParent.
++ Therefore it is safe to put parsers on the stack.
++*/
++expatppNesting*
++expatppNesting::returnToParent()
++{
++ expatppNesting* ret = mParent;
++ ::XML_SetUserData(mParser, mParent);
++ mParent=0;
++ mParser=0; // prevent parser shutdown by expatpp::~expatpp!!
++ if (mSelfDeleting) {
++ ret->OwnedChildOrphansItself(this);
++ delete this; // MUST BE LAST THING CALLED IN NON-VIRTUAL FUNCTION, NO MEMBER ACCESS
++ }
++ return ret;
++}
++
++
++void
++expatppNesting::nestedStartElementCallback(void *userData, const XML_Char* name, const XML_Char** atts)
++{
++ assert(userData);
++ expatppNesting* nestedParser = (expatppNesting*)userData;
++ nestedParser->mDepth++;
++ nestedParser->startElement(name, atts); // probably user override
++}
++
++
++/**
++ If this is root parser, will never hit nestedEndElementCallback after closing element,
++ except for when we call it.
++ \param userData should be non-nil except for specific case of ending root
++*/
++void
++expatppNesting::nestedEndElementCallback(void *userData, const XML_Char* name)
++{
++ if (!userData)
++ return; // end tag for root
++
++ expatppNesting* nestedParser = (expatppNesting*)userData;
++// we don't know until we hit a closing tag 'outside' us that our run is done
++ if (nestedParser->mDepth==0) {
++ expatppNesting* parentParser = nestedParser->returnToParent();
++ nestedEndElementCallback(parentParser, name); // callbacks for expatppNesting stay registered, so safe
++ //if we don't invoke their callback, they will not balance their mDepth
++ }
++ else {
++ // end of an element this parser has started - normal case
++ nestedParser->endElement(name); // probably user override
++ nestedParser->mDepth--;
++ }
++}
++
++
++/**
++ Called by switchToNewSubParser to indicate a newly created child parser
++ is now the currently active child for adoptingParent and the child
++ isn't expected to be self deleting.
++
++ Normal code to create an owned child would be either
++ switchToNewSubParser( new UserChildParser(this) );
++ where this is the currently active parser and you want to be deleting it, or
++ new UserChildParser(this);
++ to have a child parser self-delete
++
++ \par Important Safety Note
++ Copes with the situation of people forgetting to pass
++ in the parent parser (and hence creating a new one by default)
++ if invoked by switchToNewSubParser( new UserChildParser() )
++ by somewhat wastefully deleting the parser created in expatpp::expatpp
++ by us being a root parser.
++*/
++void
++expatppNesting::BeAdopted(expatppNesting* adoptingParent)
++{
++ if (mParent) {
++ assert(mParent==adoptingParent);
++ }
++ else { // root parser being adopted, cleanup!
++ ReleaseParser();
++ mParent = adoptingParent;
++ RegisterWithParentXMLParser();
++ }
++ mSelfDeleting = false;
++}
++
++
++
++
+diff --git a/lib/expatpp.h b/lib/expatpp.h
+new file mode 100755
+index 0000000..098c69d
+--- /dev/null
++++ b/lib/expatpp.h
+@@ -0,0 +1,339 @@
++// expatpp
++#ifndef H_EXPATPP
++#define H_EXPATPP
++
++#ifdef EXPATPP_COMPATIBLE_EXPAT12 // earlier versions of expat up to v1.2
++ #include "xmlparse.h"
++#else
++ #include "expat.h" // since some version of expat moved to SourceForge
++#endif
++#include <stdio.h>
++#include <assert.h>
++
++
++/**
++\file expatpp.h
++Latest version 29-Dec-2002 compatible with expat 1.95.6
++*/
++
++/**
++expatpp follows a simple pattern for converting the semi-OOP callback design of
++expat into a true class which allows you to override virtual methods to supply
++callbacks.
++
++\par USING expatpp
++see testexpatpp.cpp for a detailed example
++
++1) decide which callbacks you wish to use, eg: just startElement
++
++2) declare a subclass of expatpp, eg:
++class myExpat : public expatpp {
++ virtual void startElement(const XML_Char* name, const XML_Char** atts);
++};
++
++3) create an instance of your object and pass in a buffer to parse
++myExpat parser;
++parser.XML_Parse(buf, len, done)
++
++
++\par HOW IT WORKS
++The User Data which expat maintains is simply a pointer to an instance of your object.
++
++Inline static functions are specified as the callbacks to expat.
++These static functions take the user data parameter returned from expat and cast it
++to a pointer to an expatpp object.
++
++Using that typed pointer they then call the appropriate virtual method.
++
++If you have overriden a given virtual method then your version will be called, otherwise
++the (empty) method in the base expatpp class is called.
++
++\par Possible Efficiency Tactic
++For efficiency, you could provide your own constructor and set some of the callbacks
++to 0, so expat doesn't call the static functions. (untested idea).
++
++\par Naming Conventions
++The virtual functions violate the usual AD Software convention of lowercase first letter
++for public methods but this was a late change to protected and too much user code out there.
++
++
++\todo Possibly implement some handling for XML_SetExternalEntityRefHandler which does NOT
++receive user data, just the parser, so can't use normal pattern for invoking virtual methods
++
++\todo Possibly implement handling for XML_UnknownEncodingHandler.
++
++\todo review design for nested calls - not happy that it is the right thing that they don't see
++their start and ending elements - makes it harder to unit test them in isolation.
++
++\todo unit tests
++
++\todo especially test abort mechanism
++
++\todo reinstate copy constrution and assignment with child parser cleanup
++
++\todo allow specification of encoding
++*/
++class expatpp {
++public:
++ expatpp(bool createParser=true);
++ virtual ~expatpp();
++
++ operator XML_Parser() const;
++
++protected: // callback virtuals should only be invoked through our Callback static functions
++ bool emptyCharData(const XML_Char* s, int len); // utility often used in overridden charData
++
++// overrideable callbacks
++ virtual void startElement(const XML_Char* name, const XML_Char** atts);
++ virtual void endElement(const XML_Char*);
++ virtual void charData(const XML_Char*, int len);
++ virtual void processingInstruction(const XML_Char* target, const XML_Char* data);
++ virtual void defaultHandler(const XML_Char*, int len);
++ virtual int notStandaloneHandler();
++ virtual void unparsedEntityDecl(const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName);
++ virtual void notationDecl(const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
++ virtual void startNamespace(const XML_Char* prefix, const XML_Char* uri);
++ virtual void endNamespace(const XML_Char*);
++/// \name Callbacks added to support expat 1.95.5
++//@{
++ virtual void attlistDecl(
++ const XML_Char *elname,
++ const XML_Char *attname,
++ const XML_Char *att_type,
++ const XML_Char *dflt,
++ int isrequired);
++ virtual void endCdataSection();
++ virtual void endDoctypeDecl();
++ virtual void comment( const XML_Char *data);
++ virtual void elementDecl( const XML_Char *name, XML_Content *model);
++ virtual void entityDecl(
++ const XML_Char *entityName,
++ int is_parameter_entity,
++ const XML_Char *value,
++ int value_length,
++ const XML_Char *base,
++ const XML_Char *systemId,
++ const XML_Char *publicId,
++ const XML_Char *notationName);
++ virtual void skippedEntity(const XML_Char *entityName, int is_parameter_entity);
++ virtual void startCdataSection();
++ virtual void startDoctypeDecl(const XML_Char *doctypeName,
++ const XML_Char *sysid,
++ const XML_Char *pubid,
++ int has_internal_subset);
++ virtual void xmlDecl( const XML_Char *version,
++ const XML_Char *encoding,
++ int standalone);
++//@}
++
++public:
++/// \name XML interfaces
++//@{
++ XML_Status XML_Parse(const char* buffer, int len, int isFinal);
++ virtual XML_Status parseFile(FILE* inFile);
++ virtual XML_Status parseString(const char*);
++ XML_Error XML_GetErrorCode();
++ int XML_GetCurrentLineNumber();
++ int XML_GetCurrentColumnNumber();
++//@}
++
++protected:
++ XML_Parser mParser;
++ bool mHaveParsed;
++
++/// \name overrideables to customise behaviour, must call parent
++//@{
++ virtual void ReleaseParser();
++ virtual void ResetParser();
++ virtual void SetupHandlers();
++//@}
++
++/**
++ Override so subclass can react to an error causing exit from parse.
++ rather than leave it for application code to check status.
++ Useful point to insert logging to silently grab failed parses
++*/
++ virtual void CheckFinalStatus(XML_Status) {};
++
++// static interface functions for callbacks
++public:
++ static void startElementCallback(void *userData, const XML_Char* name, const XML_Char** atts);
++ static void endElementCallback(void *userData, const XML_Char* name);
++ static void startNamespaceCallback(void *userData, const XML_Char* prefix, const XML_Char* uri);
++ static void endNamespaceCallback(void *userData, const XML_Char* prefix);
++ static void charDataCallback(void *userData, const XML_Char* s, int len);
++ static void processingInstructionCallback(void *userData, const XML_Char* target, const XML_Char* data);
++ static void defaultHandlerCallback(void* userData, const XML_Char* s, int len);
++ static int notStandaloneHandlerCallback(void* userData);
++ static void unParsedEntityDeclCallback(void* userData, const XML_Char* entityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName);
++ static void notationDeclCallback(void *userData, const XML_Char* notationName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
++/// \name Callback interfacess added to support expat 1.95.5
++//@{
++ static void attlistDeclCallback(void *userData,
++ const XML_Char *elname,
++ const XML_Char *attname,
++ const XML_Char *att_type,
++ const XML_Char *dflt,
++ int isrequired);
++ static void commentCallback(void *userData, const XML_Char *data);
++ static void elementDeclCallback(void *userData, const XML_Char *name, XML_Content *model);
++ static void endCdataSectionCallback(void *userData);
++ static void endDoctypeDeclCallback(void *userData);
++ static void entityDeclCallback(void *userData,
++ const XML_Char *entityName,
++ int is_parameter_entity,
++ const XML_Char *value,
++ int value_length,
++ const XML_Char *base,
++ const XML_Char *systemId,
++ const XML_Char *publicId,
++ const XML_Char *notationName);
++ static void skippedEntityCallback(void *userData, const XML_Char *entityName, int is_parameter_entity);
++ static void startCdataSectionCallback(void *userData);
++ static void startDoctypeDeclCallback(void *userData,
++ const XML_Char *doctypeName,
++ const XML_Char *sysid,
++ const XML_Char *pubid,
++ int has_internal_subset);
++ static void xmlDeclCallback(void *userData, const XML_Char *version,
++ const XML_Char *encoding,
++ int standalone);
++//@}
++
++
++// utilities
++ static int skipWhiteSpace(const XML_Char*);
++ static const XML_Char* getAttribute(const XML_Char *matchingName, const XML_Char **atts);
++ static bool getIntegerAttribute(const XML_Char *matchingName, const XML_Char **atts, int& outAtt);
++ static bool getDoubleAttribute(const XML_Char *matchingName, const XML_Char **atts, double& outAtt);
++};
++
++
++/**
++ subclass to support a hierarchy of parsers, in a sort of recursion or
++ 'nesting' approach, where a top-level parser might create sub-parsers
++ for part of a file.
++
++ The currently active child parser is owned (mOwnedChild) and is deleted
++ by DeleteChild (invoked from the dtor) so error handling can propagate
++ up the tree, closing parsers, without leaks.
++
++ \par Switching to sub-parsers
++ You can transfer to a sub-parser with
++ - new UserChildParser(this) // carries on using our parser, is self-deleting
++ - switchToNewSubParser( someVar = new UserChildParser(this) ) // if want to get values back after end parsing
++
++ \warning You can accidentally invoke a new parser without it doing anything
++ - new UserChildParser() // will be new top-level parser, nothing to do with our XML
++
++ \par Self-deletion
++ If you transfer control to a sub-parser with just new UserChildParser(this) then
++ it will be automatically self-deleting in its returnToParent method and
++ will invoke OwnedChildOrphansItself to clear our mOwnedChild.
++
++ The reason for self-deletion being governed by a somewhat complex chain of
++ calls rather than simply a boolean flag is because expatpp has been in use
++ worldwide for many years and it was deemed too unfriendly to break code in
++ a manner which could cause unwanted side effects - the current approach safely
++ preserves self-deletion but also allows for expatpp to have parent parsers
++ own and delete children, without compiling with different options.
++
++ \note
++ If you invoke a sub-parser with switchToNewSubParser( new UserChildParser() );
++ then the user child parser will start with a new XML parser instance
++ created by the expatpp ctor. This is safe but slightly wasteful of processing
++ as the new parser will be discarded by BeAdopted().
++
++ \par Switching to child and explicitly deleting
++ switchToNewSubParser( somevar = new UserChildParser(this) ) allows you to get values
++ back out of the child parser, in the context of the parent, eg:
++
++\verbatim
++
++void MultiFilterParser::startElement(const XML_Char* name, const XML_Char **atts)
++{
++ if(strcmp(name,"FilterRequest")==0) {
++ switchToNewSubParser(
++ mCurrentFilterParser = new FilterRequestParser(this, atts)
++ ); // we own and will have to explicitly delete
++...
++}
++
++void MultiFilterParser::endElement(const XML_Char *name)
++{
++ if(strcmp(name,"FilterRequest")==0) {
++ assert(mCurrentFilterParser);
++ FilterClause* newClause = mCurrentFilterParser->orphanBuiltClause(); // retrieve data built by sub-parser
++...
++ mCurrentFilterParser = 0;
++ DeleteChild();
++ }
++}
++\endverbatim
++*/
++class expatppNesting : public expatpp {
++
++public:
++ expatppNesting(expatppNesting* parent=0); ///< NOT a copy ctor!! this is a recursive situation
++ virtual ~expatppNesting();
++
++ void switchToNewSubParser( expatppNesting* pAdoptedChild );
++ expatppNesting* returnToParent();
++
++protected:
++ void BeAdopted(expatppNesting* adoptingParent);
++ void OwnedChildOrphansItself(expatppNesting* callingChild);
++ void RegisterWithParentXMLParser();
++ virtual void AdoptChild(expatppNesting* adoptingChild);
++ virtual void DeleteChild();
++
++ int mDepth;
++ bool mSelfDeleting; ///< only valid if mParent not null
++ expatppNesting* mParent; ///< may be null the parent owns this object
++ expatppNesting* mOwnedChild; ///< owned, optional currently active child (auto_ptr not used to avoid STL dependency)
++
++public:
++/// \name interface functions for callbacks
++//@{
++ static void nestedStartElementCallback(void* userData, const XML_Char* name, const XML_Char** atts);
++ static void nestedEndElementCallback(void* userData, const XML_Char* name);
++//@}
++
++
++/// \name overrideables to customise behaviour, must call parent
++//@{
++ virtual void SetupHandlers();
++//@}
++
++private:
++ // Forbid copy-construction and assignment, to prevent double-deletion of mOwnedChild
++ expatppNesting( const expatppNesting & );
++ expatppNesting & operator=( const expatppNesting & );
++};
++
++
++// inlines
++
++// -------------------------------------------------------
++// e x p a t p p
++// -------------------------------------------------------
++inline
++expatpp::operator XML_Parser() const
++{
++ return mParser;
++}
++
++
++// -------------------------------------------------------
++// e x p a t p p N e s t i n g
++// -------------------------------------------------------
++inline void
++expatppNesting::OwnedChildOrphansItself(expatppNesting* callingChild)
++{
++ assert(callingChild==mOwnedChild);
++ mOwnedChild = 0;
++}
++
++
++
++#endif // H_EXPATPP
+--
+1.7.11.7
+
diff --git a/0005-Added-test-code.patch b/0005-Added-test-code.patch
new file mode 100644
index 0000000..62f58de
--- /dev/null
+++ b/0005-Added-test-code.patch
@@ -0,0 +1,659 @@
+From daf99e1143d6c9ec5b140d9f574aa54f3e39df81 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:16:00 +0200
+Subject: [PATCH 05/15] Added test code
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ test/carb.r | 1 +
+ test/testexpat.c | 87 +++++++++++++++++++
+ test/testexpatpp.cpp | 103 +++++++++++++++++++++++
+ test/testexpatpp2.cpp | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ test/testexpatpp3.cpp | 188 +++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 605 insertions(+)
+ create mode 100644 test/carb.r
+ create mode 100755 test/testexpat.c
+ create mode 100755 test/testexpatpp.cpp
+ create mode 100755 test/testexpatpp2.cpp
+ create mode 100644 test/testexpatpp3.cpp
+
+diff --git a/test/carb.r b/test/carb.r
+new file mode 100644
+index 0000000..e214e4b
+--- /dev/null
++++ b/test/carb.r
+@@ -0,0 +1 @@
++/*
* Permit this Carbon application to launch on OS X
*
* Copyright © 1997-2002 Metrowerks Corporation. All Rights Reserved.
*
* Questions and comments to:
* <mailto:support at metrowerks.com>
* <http://www.metrowerks.com/>
*/
/*----------------------------carb ¥ Carbon on OS X launch information --------------------------*/
type 'carb' {
};
resource 'carb'(0) {
};
+\ No newline at end of file
+diff --git a/test/testexpat.c b/test/testexpat.c
+new file mode 100755
+index 0000000..e8bca82
+--- /dev/null
++++ b/test/testexpat.c
+@@ -0,0 +1,87 @@
++/* This is simple demonstration of how to use expat. This program
++reads an XML document from standard input and writes a line with the
++name of each element to standard output indenting child elements by
++one tab stop more than their parent element.
++
++Copied from elements.c 98/08/31 AD to open specified file rather than stdin
++and added a CharacterDataHandler
++*/
++
++#include <stdio.h>
++#include "xmlparse.h"
++
++void startElement(void *userData, const char *name, const char **atts)
++{
++ int i;
++ int *depthPtr = userData;
++ for (i = 0; i < *depthPtr; i++)
++ putchar('\t');
++ puts(name);
++ *depthPtr += 1;
++}
++
++void endElement(void *userData, const char *name)
++{
++ int *depthPtr = userData;
++ *depthPtr -= 1;
++}
++
++
++void charData(void *userData, const XML_Char *s, int len)
++{
++/* write indent level stored in userData */
++ int i;
++ int *depthPtr = userData;
++
++ if (len==0)
++ return; // lots of extra calls?
++
++ for (i = 0; i < *depthPtr; i++)
++ putchar('\t');
++
++/* write out the user data bracketed by ()*/
++ putchar('(');
++ fwrite(s, len, 1, stdout);
++ puts(")");
++}
++
++
++int main()
++{
++ char filename[80];
++ FILE* xmlFile;
++ char buf[BUFSIZ];
++ for (;;) {
++ XML_Parser parser;
++ int done;
++ int depth = 0;
++
++ puts("\n\nXML test: enter filename");
++ gets(filename);
++ if (strlen(filename)==0)
++ break;
++
++ xmlFile = fopen(filename, "r");
++ if (!xmlFile)
++ break;
++
++ parser = XML_ParserCreate(NULL);
++ XML_SetUserData(parser, &depth);
++ XML_SetElementHandler(parser, startElement, endElement);
++ XML_SetCharacterDataHandler(parser, charData);
++ do {
++ size_t len = fread(buf, 1, sizeof(buf), xmlFile /*stdin*/);
++ done = len < sizeof(buf);
++ if (!XML_Parse(parser, buf, len, done)) {
++ fprintf(stderr,
++ "%s at line %d\n",
++ XML_ErrorString(XML_GetErrorCode(parser)),
++ XML_GetCurrentLineNumber(parser));
++ return 1;
++ }
++ } while (!done);
++ XML_ParserFree(parser);
++/* return 0; */
++ }
++ puts("\nfinished!");
++}
+\ No newline at end of file
+diff --git a/test/testexpatpp.cpp b/test/testexpatpp.cpp
+new file mode 100755
+index 0000000..30af4ff
+--- /dev/null
++++ b/test/testexpatpp.cpp
+@@ -0,0 +1,103 @@
++/* This is simple demonstration of how to use expat. This program
++reads an XML document from standard input and writes a line with the
++name of each element to standard output indenting child elements by
++one tab stop more than their parent element.
++
++Copied from elements.c 98/08/31 AD to open specified file rather than stdin
++and added a CharacterDataHandler
++*/
++
++#include <stdio.h>
++#include "expatpp.h"
++#include <string.h>
++
++class myParser : public expatpp {
++public:
++ myParser() : mDepth(0) {};
++
++ virtual void startElement(const XML_Char *name, const XML_Char **atts);
++ virtual void endElement(const XML_Char* name);
++ virtual void charData(const XML_Char *s, int len);
++
++private:
++ void WriteIndent();
++ int mDepth;
++};
++
++
++void
++myParser::WriteIndent()
++{
++ for (int i = 0; i < mDepth; i++)
++ putchar('\t');
++}
++
++
++void
++myParser::startElement(const XML_Char* name, const XML_Char** atts)
++{
++ WriteIndent();
++ puts(name);
++ if (atts) { /* write list of attributes indented below element */
++ int i;
++ for (i=0; atts[i]; i++) {
++ WriteIndent();
++ putchar('-'); putchar(' ');
++ puts(atts[i]);
++ }
++ }
++ mDepth++;
++}
++
++
++void
++myParser::endElement(const XML_Char*)
++{
++ mDepth--;
++}
++
++
++void
++myParser::charData(const XML_Char *s, int len)
++{
++ const int leadingSpace = skipWhiteSpace(s);
++ if (len==0 || len==leadingSpace)
++ return; // called with whitespace between elements
++
++ WriteIndent();
++
++/* write out the user data bracketed by ()*/
++ putchar('(');
++ fwrite(s, len, 1, stdout);
++ puts(")");
++}
++
++
++int main()
++{
++ myParser parser;
++ char filename[80];
++ FILE* xmlFile;
++ for (;;) {
++ int depth = 0;
++
++ puts("\n\nXML test: enter filename");
++ gets(filename);
++ if (strlen(filename)==0)
++ break;
++
++ xmlFile = fopen(filename, "r");
++ if (!xmlFile)
++ break;
++
++ if (!parser.parseFile(xmlFile)) {
++ fprintf(stderr,
++ "%s at line %d\n",
++ XML_ErrorString(parser.XML_GetErrorCode()),
++ parser.XML_GetCurrentLineNumber()
++ );
++ return 1;
++ }
++ } // loop asking for and parsing files
++ puts("\nfinished!");
++}
+diff --git a/test/testexpatpp2.cpp b/test/testexpatpp2.cpp
+new file mode 100755
+index 0000000..120a8d7
+--- /dev/null
++++ b/test/testexpatpp2.cpp
+@@ -0,0 +1,226 @@
++/**
++\file testexpatpp2.cpp
++Uses OOFILE XML classes to help write an XML file to the name you specify
++then parses it back into a data structure. This shows the simple persistence
++you would use to store an XML-based preferences file.
++*/
++
++#include <stdio.h>
++#include "expatpp.h"
++#include <string.h>
++#ifndef H_OOFXML
++ #include "oofxml.h"
++#endif
++
++/**
++Simple data class with public members so it can be updated
++by parser.
++
++writes itself as XML file like
++<?xml version="1.0" standalone="no" ?>
++<simpleData>
++ <name>Andy Dent</name>
++ <isProgrammer/>
++ <age>37</age>
++</simpleData>
++*/
++
++
++// -------------------------------------------------------
++// s i m p l e D a t a
++// -------------------------------------------------------
++class simpleData {
++public:
++ simpleData(const char* inName=0, int inAge=0, bool inProg=false);
++
++ static void writeSampleXML(FILE* xmlFile);
++ void writeXML(FILE* xmlFile);
++ void dumpData();
++
++ oofString mName;
++ int mAge;
++ bool mIsProgrammer;
++};
++
++
++simpleData::simpleData(const char* inName, int inAge, bool inProg) :
++ mName(inName),
++ mAge(inAge),
++ mIsProgrammer(inProg)
++{
++}
++
++
++void
++simpleData::writeXML(FILE* xmlFile)
++{
++ oofXMLwriter theXML;
++ theXML.startElement("simpleData");
++ theXML.addSimpleElement("name", mName);
++ theXML.addSimpleElement("age", mAge);
++ if (mIsProgrammer)
++ theXML.addEmptyElement("isProgrammer");
++ theXML.endElement();
++
++ assert(theXML.topLevelClosed());
++
++ fputs(theXML.generatedXML(), xmlFile);
++ fseek(xmlFile, 0, SEEK_SET); // reset for reading
++}
++
++
++void
++simpleData::dumpData()
++{
++ printf("simpleData\n");
++ printf(" name=%s\n", mName.chars());
++ printf(" age=%d\n", mAge);
++ if (mIsProgrammer)
++ printf(" is Programmer\n");
++ else
++ printf(" is NOT Programmer\n");
++}
++
++
++void
++simpleData::writeSampleXML(FILE* xmlFile)
++{
++ simpleData theSample("Andy Dent", 37, true);
++ theSample.writeXML(xmlFile);
++}
++
++
++// -------------------------------------------------------
++// s d P a r s e r
++// -------------------------------------------------------
++class sdParser : public expatpp {
++public:
++ sdParser(simpleData&);
++
++ virtual void startElement(const XML_Char *name, const XML_Char **atts);
++ virtual void endElement(const XML_Char* name);
++ virtual void charData(const XML_Char *s, int len);
++
++private:
++ enum elementStateT {eNone, eInName, eInAge};
++ elementStateT mState;
++ simpleData& mData;
++};
++
++
++sdParser::sdParser(simpleData& inData) :
++ mState(eNone),
++ mData(inData)
++{}
++
++
++/**
++Either change state or set bool indicating hit empty element
++*/
++void
++sdParser::startElement(const XML_Char* name, const XML_Char** /*atts*/)
++{
++ if(strcmp(name,"name")==0){
++ // ignore the attributes
++ assert(mState==eNone); // enforce the structure we expect
++ mState = eInName;
++ }
++ else if(strcmp(name,"age")==0){
++ assert(mState==eNone); // enforce the structure we expect
++ mState = eInAge;
++ }
++ else if(strcmp(name,"isProgrammer")==0) {
++ mData.mIsProgrammer = true;
++ mState = eNone;
++ }
++}
++
++
++void
++sdParser::endElement(const XML_Char*)
++{
++ mState = eNone;
++}
++
++
++/**
++Based on state - read name or age.
++If you are developing to a rigid XML format it is a really good idea to start
++with a parser that has assertions for unknowns like this one because it will quickly
++help you identify problems with the data being written. Flexible XML formats make it hard
++to decide if bugs are in the writer or reader.
++*/
++void
++sdParser::charData(const XML_Char *s, int len)
++{
++ if (emptyCharData(s, len))
++ return;
++
++ switch(mState) {
++ case eInName :
++ mData.mName.setChars(s, len);
++ break;
++
++ case eInAge :
++ {
++ int i;
++ std::sscanf(s,"%d", &i);
++ mData.mAge = i;
++ }
++ break;
++
++ default : {
++ assert(mState==eNone); // more flexible parser would ignore unknown states
++ }
++ };
++}
++
++
++// -------------------------------------------------------
++// m a i n
++// -------------------------------------------------------
++/**
++sample showing parsing of file in loop reading minimal sized buffer
++to cut down on overhead.
++*/
++int main()
++{
++ simpleData theData;
++ sdParser parser(theData);
++ char filename[80];
++ FILE* xmlFile;
++ char buf[BUFSIZ];
++
++ int done;
++ int depth = 0;
++
++ puts("\n\nXML test: enter filename to write");
++ gets(filename);
++ if (strlen(filename)==0)
++ return 0;
++
++ xmlFile = fopen(filename, "wb+");
++ if (!xmlFile)
++ return 0;
++
++ puts("sample data in original empty state!");
++ theData.dumpData();
++
++ simpleData::writeSampleXML(xmlFile);
++
++// read back thefile
++ if (!parser.parseFile(xmlFile)) {
++ fprintf(stderr,
++ "%s at line %d\n",
++ XML_ErrorString(parser.XML_GetErrorCode()),
++ parser.XML_GetCurrentLineNumber()
++ );
++ return 1;
++ }
++
++ puts("\n\nsample data after reading back!\n");
++ theData.dumpData();
++
++ puts("\nfinished!");
++}
++
+diff --git a/test/testexpatpp3.cpp b/test/testexpatpp3.cpp
+new file mode 100644
+index 0000000..bbc9efb
+--- /dev/null
++++ b/test/testexpatpp3.cpp
+@@ -0,0 +1,188 @@
++/*
++ \file testexpatpp3.cpp
++ Demonstrates use of nesting parsers and parsing attributes
++ Structure of topParser is similar to myParser in testexpatpp.cpp
++
++ \invoking nested parsers with attributes
++ An important point when writing a nested parser is that the element
++ used to invoke the parser, eg: <settings>, is "consumed" by the parent parser.
++ That's fine if you have an element-oriented architecture like oofRep.
++
++ If you expect to have important attributes on the starting element for your
++ sub-parser then use a handleAtts() approach as shown below.
++
++ If the ONLY thing in your sub-parser is handling attributes and it will never
++ be invoked with nested elements then consider not bothering making it a sub-parser
++ at all and just make it a method of the current parent parser.
++
++ \par expected output
++\verbatim
++BEEPX.MSG
++- channel
++- 1
++- msgno
++- 1
++ ignored
++settingsParser::ctor
++ ComPort='1'
++ DataSource='device'
++ RecordFile='off'
++ WindowingStyle='hanning'
++ Points='256'
++
++
++settingsParser::ctor
++
++
++ settingsParser::startElement
++ anAtt='Andy'
++ anotherAtt='woz here'
++
++
++
++finished!
++\endverbatim
++
++*/
++
++#include <stdio.h>
++#include "expatpp.h"
++#include <string.h>
++
++/// sample with a nested element with many attributes
++const char kSample[] =
++ "<BEEPX.MSG channel='1' msgno='1'>"
++ "<ignored />"
++ "<settings \n" // note this is a top-level settings object with attributes
++ "ComPort='1'\n"
++ "DataSource='device'\n"
++ "RecordFile='off'\n"
++ "WindowingStyle='hanning'\n"
++ "Points='256'\n"
++ " />"
++ "<settings>"
++ "<anElementWithinSettings anAtt='Andy' anotherAtt='woz here' />"
++ "</settings>"
++ "</BEEPX.MSG>"
++;
++
++class topParser : public expatppNesting {
++public:
++ topParser() : mDepth(0) {};
++
++ virtual void startElement(const XML_Char *name, const XML_Char **atts);
++ virtual void endElement(const XML_Char* name);
++ virtual void charData(const XML_Char *s, int len);
++
++private:
++ void WriteIndent();
++ int mDepth;
++};
++
++
++class settingsParser : public expatppNesting {
++public:
++ settingsParser(expatppNesting* parent, const XML_Char **atts);
++ virtual void startElement(const XML_Char* name, const XML_Char** atts);
++
++private:
++ void handleAtts(const XML_Char** atts);
++};
++
++
++void
++topParser::WriteIndent()
++{
++ for (int i = 0; i < mDepth; i++)
++ putchar('\t');
++}
++
++
++void
++topParser::startElement(const char* name, const char** atts)
++{
++ if(strcmp(name,"settings")==0)
++ new settingsParser(this, atts); // transfer control to settings parser
++ else {
++ WriteIndent();
++ puts(name);
++ if (atts) { /* write list of attributes indented below element */
++ int i;
++ for (i=0; atts[i]; i++) {
++ WriteIndent();
++ putchar('-'); putchar(' ');
++ puts(atts[i]);
++ }
++ }
++ mDepth++;
++ }
++}
++
++
++void
++topParser::endElement(const char*)
++{
++ mDepth--;
++}
++
++
++void
++topParser::charData(const XML_Char *s, int len)
++{
++ const int leadingSpace = skipWhiteSpace(s);
++ if (len==0 || len==leadingSpace)
++ return; // called with whitespace between elements
++
++ WriteIndent();
++
++/* write out the user data bracketed by ()*/
++ putchar('(');
++ fwrite(s, len, 1, stdout);
++ puts(")");
++}
++
++
++settingsParser::settingsParser(expatppNesting* parent, const XML_Char **atts) :
++ expatppNesting(parent)
++{
++ printf("settingsParser::ctor\n");
++ handleAtts(atts);
++ printf("\n\n");
++}
++
++
++void
++settingsParser::startElement(const XML_Char* name, const XML_Char** atts)
++{
++ printf(" settingsParser::startElement\n");
++ handleAtts(atts);
++ printf("\n\n");
++}
++
++
++void
++settingsParser::handleAtts(const XML_Char** atts)
++{
++ for (int i=0; atts[i]!=0; i++) {
++ printf(" %s='%s'\n", atts[i], atts[++i]);
++ }
++}
++
++
++
++int main()
++{
++ topParser parser;
++ char filename[80];
++ int depth = 0;
++
++ if (!parser.parseString(kSample)) {
++ fprintf(stderr,
++ "%s at line %d\n",
++ XML_ErrorString(parser.XML_GetErrorCode()),
++ parser.XML_GetCurrentLineNumber()
++ );
++ return 1;
++ }
++ puts("\nfinished!");
++}
+--
+1.7.11.7
+
diff --git a/0006-Build-testexpatpp1.patch b/0006-Build-testexpatpp1.patch
new file mode 100644
index 0000000..be540c9
--- /dev/null
+++ b/0006-Build-testexpatpp1.patch
@@ -0,0 +1,28 @@
+From 04b532e0b1969f932e48db0b374fb73de74fc480 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:31:18 +0200
+Subject: [PATCH 06/15] Build testexpatpp1
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ test/CMakeLists.txt | 7 +++++++
+ 1 file changed, 7 insertions(+)
+ create mode 100644 test/CMakeLists.txt
+
+diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
+new file mode 100644
+index 0000000..9d12cc6
+--- /dev/null
++++ b/test/CMakeLists.txt
+@@ -0,0 +1,7 @@
++
++include_directories (${expatpp_SOURCE_DIR}/lib)
++link_directories (${expatpp_BINARY_DIR}/lib ${EXPAT_INCLUDE_DIR})
++
++add_executable (testexpatpp1 testexpatpp.cpp)
++
++target_link_libraries (testexpatpp1 expatpp)
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0007-Fix-subdir-command.patch b/0007-Fix-subdir-command.patch
new file mode 100644
index 0000000..c075c05
--- /dev/null
+++ b/0007-Fix-subdir-command.patch
@@ -0,0 +1,27 @@
+From a63f47dd1d16f94b21e4d4a1f8da6db976a6d80f Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:31:36 +0200
+Subject: [PATCH 07/15] Fix subdir command
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 8db8529..88e5f5e 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -2,5 +2,5 @@ project(expatpp)
+
+ find_package(EXPAT REQUIRED)
+
+-add_dir(lib)
+-add_dir(test)
+\ No newline at end of file
++add_subdirectory(lib)
++add_subdirectory(test)
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0008-Added-cPack.patch b/0008-Added-cPack.patch
new file mode 100644
index 0000000..17725e3
--- /dev/null
+++ b/0008-Added-cPack.patch
@@ -0,0 +1,39 @@
+From f54be89661bf62682f500facaa2e814940914072 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:50:40 +0200
+Subject: [PATCH 08/15] Added cPack
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 88e5f5e..9c95a61 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,6 +1,19 @@
++
++cmake_minimum_required(VERSION 2.6)
++
+ project(expatpp)
+
++
+ find_package(EXPAT REQUIRED)
+
+ add_subdirectory(lib)
+-add_subdirectory(test)
+\ No newline at end of file
++add_subdirectory(test)
++
++SET(CPACK_GENERATOR "RPM")
++SET(CPACK_RPM_PACKAGE_SUMMARY "A tiniy object oriented wrapper around expat library")
++SET(CPACK_RPM_PACKAGE_NAME "expatpp")
++SET(CPACK_RPM_PACKAGE_VERSION 0.6)
++SET(CPACK_RPM_PACKAGE_RELEASE 1)
++SET(CPACK_RPM_PACKAGE_LICENSE "Mozilla")
++
++INCLUDE(CPack)
+--
+1.7.11.7
+
diff --git a/0009-Install-library.patch b/0009-Install-library.patch
new file mode 100644
index 0000000..f41bc29
--- /dev/null
+++ b/0009-Install-library.patch
@@ -0,0 +1,25 @@
+From f8d17bb995244c62583b781c961534997f50074e Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 16:55:43 +0200
+Subject: [PATCH 09/15] Install library
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ lib/CMakeLists.txt | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+index ed70f58..1418031 100644
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -1,3 +1,4 @@
+
+ add_library(expatpp SHARED expatpp.cpp)
+-target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+\ No newline at end of file
++target_link_libraries(expatpp ${EXPAT_LIBRARIES})
++INSTALL_TARGETS(/lib expatpp)
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0010-Use-lib-or-lib64-automatically.patch b/0010-Use-lib-or-lib64-automatically.patch
new file mode 100644
index 0000000..a0f5323
--- /dev/null
+++ b/0010-Use-lib-or-lib64-automatically.patch
@@ -0,0 +1,25 @@
+From 63885e92f129f7f513ed1ea15230141aa8ac88dc Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 17:02:33 +0200
+Subject: [PATCH 10/15] Use lib or lib64 automatically
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ lib/CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+index 1418031..171601f 100644
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -1,4 +1,4 @@
+
+ add_library(expatpp SHARED expatpp.cpp)
+ target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+-INSTALL_TARGETS(/lib expatpp)
+\ No newline at end of file
++INSTALL_TARGETS(/${LIB_INSTALL_DIR} expatpp)
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0011-added-soname-info.patch b/0011-added-soname-info.patch
new file mode 100644
index 0000000..f2d7975
--- /dev/null
+++ b/0011-added-soname-info.patch
@@ -0,0 +1,58 @@
+From 49d35d3007b2e7431a2d7d923293f6a182983a68 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 17:08:14 +0200
+Subject: [PATCH 11/15] added soname info
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 19 +++++++++++--------
+ lib/CMakeLists.txt | 1 +
+ 2 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 9c95a61..a4bc49c 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -3,17 +3,20 @@ cmake_minimum_required(VERSION 2.6)
+
+ project(expatpp)
+
+-
+ find_package(EXPAT REQUIRED)
+
++SET(EXPATPP_MAJOR_VERSION 0)
++SET(EXPATPP_MINOR_VERSION 6)
++SET(EXPATPP_BUILD_VERSION 0)
++SET(EXPATPP_VERSION
++ "${EXPATPP_MAJOR_VERSION}.${EXPATPP_MINOR_VERSION}.${EXPATPP_BUILD_VERSION}")
++SET(EXPATPP_LIBRARY_PROPERTIES ${EXPATPP_LIBRARY_PROPERTIES}
++ VERSION "${EXPATPP_VERSION}"
++ SOVERSION "${EXPATPP_API_VERSION}"
++)
++
++
+ add_subdirectory(lib)
+ add_subdirectory(test)
+
+-SET(CPACK_GENERATOR "RPM")
+-SET(CPACK_RPM_PACKAGE_SUMMARY "A tiniy object oriented wrapper around expat library")
+-SET(CPACK_RPM_PACKAGE_NAME "expatpp")
+-SET(CPACK_RPM_PACKAGE_VERSION 0.6)
+-SET(CPACK_RPM_PACKAGE_RELEASE 1)
+-SET(CPACK_RPM_PACKAGE_LICENSE "Mozilla")
+-
+ INCLUDE(CPack)
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+index 171601f..352687d 100644
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -1,4 +1,5 @@
+
+ add_library(expatpp SHARED expatpp.cpp)
+ target_link_libraries(expatpp ${EXPAT_LIBRARIES})
++SET_TARGET_PROPERTIES(expatpp PROPERTIES ${EXPATPP_LIBRARY_PROPERTIES})
+ INSTALL_TARGETS(/${LIB_INSTALL_DIR} expatpp)
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0012-Fixed-missing-api-version.patch b/0012-Fixed-missing-api-version.patch
new file mode 100644
index 0000000..849f1a9
--- /dev/null
+++ b/0012-Fixed-missing-api-version.patch
@@ -0,0 +1,26 @@
+From 4592e0eb8fb12d39d0eed91d821651e1583b534b Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 17:10:42 +0200
+Subject: [PATCH 12/15] Fixed missing api version
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ CMakeLists.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index a4bc49c..971fea4 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -10,6 +10,8 @@ SET(EXPATPP_MINOR_VERSION 6)
+ SET(EXPATPP_BUILD_VERSION 0)
+ SET(EXPATPP_VERSION
+ "${EXPATPP_MAJOR_VERSION}.${EXPATPP_MINOR_VERSION}.${EXPATPP_BUILD_VERSION}")
++SET(EXPATPP_API_VERSION
++ "${EXPATPP_MAJOR_VERSION}.${EXPATPP_MINOR_VERSION}")
+ SET(EXPATPP_LIBRARY_PROPERTIES ${EXPATPP_LIBRARY_PROPERTIES}
+ VERSION "${EXPATPP_VERSION}"
+ SOVERSION "${EXPATPP_API_VERSION}"
+--
+1.7.11.7
+
diff --git a/0013-Install-header-file.patch b/0013-Install-header-file.patch
new file mode 100644
index 0000000..3968600
--- /dev/null
+++ b/0013-Install-header-file.patch
@@ -0,0 +1,26 @@
+From afc798609cb851d460662def2cff458f265f4655 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Thu, 18 Oct 2012 17:14:25 +0200
+Subject: [PATCH 13/15] Install header file
+
+Signed-off-by: Mario Ceresa <mrceresa at gmail.com>
+---
+ lib/CMakeLists.txt | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+index 352687d..76bc538 100644
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -2,4 +2,5 @@
+ add_library(expatpp SHARED expatpp.cpp)
+ target_link_libraries(expatpp ${EXPAT_LIBRARIES})
+ SET_TARGET_PROPERTIES(expatpp PROPERTIES ${EXPATPP_LIBRARY_PROPERTIES})
+-INSTALL_TARGETS(/${LIB_INSTALL_DIR} expatpp)
+\ No newline at end of file
++INSTALL_TARGETS(/${LIB_INSTALL_DIR} expatpp)
++INSTALL (FILES expatpp.h DESTINATION include)
+\ No newline at end of file
+--
+1.7.11.7
+
diff --git a/0014-Removed-windows-static-lib-header.patch b/0014-Removed-windows-static-lib-header.patch
new file mode 100644
index 0000000..a03d611
--- /dev/null
+++ b/0014-Removed-windows-static-lib-header.patch
@@ -0,0 +1,39 @@
+From 86635c3fd0d640edfa6cb5ed1feb9df8c0602cc9 Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Fri, 19 Oct 2012 10:08:07 +0200
+Subject: [PATCH 14/15] Removed windows static lib header
+
+---
+ expatpplib.h | 20 --------------------
+ 1 file changed, 20 deletions(-)
+ delete mode 100755 expatpplib.h
+
+diff --git a/expatpplib.h b/expatpplib.h
+deleted file mode 100755
+index e920813..0000000
+--- a/expatpplib.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-#ifndef H_EXPATPPLIB
+-#define H_EXPATPPLIB
+-
+-/**
+- \file expatpplib.h
+- ensure expat definitions setup correctly before including expatpp.h
+- so client projects don't have lots of hidden settings
+-*/
+-#ifdef WIN32
+- #define XML_STATIC // we are using a static lib build, not expat.dll
+- #define COMPILED_FROM_DSP
+- #define _LIB
+-#endif
+-
+-#include "expatpp.h"
+-
+-
+-
+-
+-#endif // H_EXPATPPLIB
+--
+1.7.11.7
+
diff --git a/0015-Reworked-documentation.patch b/0015-Reworked-documentation.patch
new file mode 100644
index 0000000..30fb1f8
--- /dev/null
+++ b/0015-Reworked-documentation.patch
@@ -0,0 +1,897 @@
+From 356887cdce167bb5ad37773195d4caa57c04c9cb Mon Sep 17 00:00:00 2001
+From: Mario Ceresa <mrceresa at gmail.com>
+Date: Fri, 19 Oct 2012 10:11:30 +0200
+Subject: [PATCH 15/15] Reworked documentation
+
+---
+ CHANGELOG | 359 ++++++++++++++++++++++++++++++++++++++++++
+ EXTEND | 31 ++++
+ TODO | 29 ++++
+ expatpp Code Change Diary.txt | 359 ------------------------------------------
+ expatpp Prog Docs.txt | 31 ----
+ expatpp TODO.txt | 29 ----
+ 6 files changed, 419 insertions(+), 419 deletions(-)
+ create mode 100755 CHANGELOG
+ create mode 100755 EXTEND
+ create mode 100755 TODO
+ delete mode 100755 expatpp Code Change Diary.txt
+ delete mode 100755 expatpp Prog Docs.txt
+ delete mode 100755 expatpp TODO.txt
+
+diff --git a/CHANGELOG b/CHANGELOG
+new file mode 100755
+index 0000000..5e2479c
+--- /dev/null
++++ b/CHANGELOG
+@@ -0,0 +1,359 @@
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++98/09/02
++
++FILE xpatpp.h
++CLASS xpatt
++- added overrideable callbacks:
++ processingInstruction
++ defaultHandler
++ unparsedEntityDecl
++ notationDecl
++
++-added interface functions for callbacks:
++ processingInstructionCallback
++ defaultHandlerCallback
++ unparsedEntityDeclCallback
++ notationDeclCallback
++
++- added inlines for these interface functions
++
++FILE xpatpp.cpp
++CLASS xpattp
++Method xpattp
++- added calls to
++ XML_SetProcessingInstructionHandler
++ XML_SetDefaultHandler
++ XML_SetUnparsedEntityDeclHandler
++ XML_SetNotationDeclHandler
++
++
++- added empty implementations of the overrideable callbacks
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++99/03/10 AD
++renamed xpatpp to expatpp in filenames and classes.
++updated xpcw project to compile with CodeWarrior Pro4
++and add PPC target to 68K.
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++99/05/03 AD
++UPDATE FOR LATEST EXPAT RELEASE
++
++FILE expatpp.cpp
++CLASS expattp
++Method expattp
++- added call to XML_SetNotStandaloneHandler
++- added call to XML_SetNamespaceDeclHandler
++
++Methods added
++ - virtual notStandaloneHandler returning 0
++ - Empty virtuals startNamespace & endNamespace
++
++
++FILE expatpp.h
++CLASS expatpp
++- added inline notStandaloneHandlerCallback
++- added inline
++
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++99/05/05-09 AD
++ADD NESTED PARSER SUBCLASS
++
++CLASS expatppNesting
++- added subclass of expatpp
++- mDepth, mParent members added
++
++Method ctor
++ - init mDepth(0)
++
++Method ctor(expatppNesting*)
++ - added to nest a parser (pointer to parent)
++
++Method nestedStartElement, nestedEndElement
++ - added callbacks to inc/dec mDepth
++
++
++CLASS expatpp
++Method dtor
++ - made virtual
++
++Method ctor
++ - add optional param to control creation of parser
++ so can nest parsers and continue to use existing
++ XML parser
++
++Method emptyCharData
++ - added to contain common logic I keep putting at top
++ of overridden charData methods
++
++Method all callbacks
++ - made non-inline as I realised they will NOT be used
++ inline, being supplied as function addresses, so no
++ point having them declared as inline
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2002/12/28-30 AD
++CONVERT TO EXPAT 1.95.5
++
++CLASS expatpp
++- made all virtual overrideables protected - should only be invoked through
++ callback interfaces.
++- Added overrideable empty handlers
++ attlistDecl
++ comment
++ elementDecl
++ endCdataSection
++ endDoctypeDecl
++ entityDecl
++ skippedEntity
++ startCdataSection
++ startDoctypeDecl
++ xmlDecl
++
++
++- Added callback interfaces
++ attlistDeclCallback
++ commentCallback
++ elementDeclCallback
++ endCdataSectionCallback
++ endDoctypeDeclCallback
++ entityDeclCallback
++ skippedEntityCallback
++ startCdataSectionCallback
++ startDoctypeDeclCallback
++ xmlDeclCallback
++
++
++Method ctor
++ - added calls to set handlers for
++ XML_SetAttlistDeclHandler
++ XML_SetCdataSectionHandler
++ XML_SetCommentHandler
++ XML_SetDoctypeDeclHandler
++ XML_SetElementDeclHandler
++ XML_SetEntityDeclHandler
++ XML_SetSkippedEntityHandler
++ XML_SetXmlDeclHandler
++
++Method XML_Parse
++ - changed return type from plain XMLPARSEAPI to XMLPARSEAPI(enum XML_Status)
++
++Method XML_GetErrorCode
++ - changed return type from plain XMLPARSEAPI to XMLPARSEAPI(enum XML_Error)
++
++Method XML_GetCurrentLineNumber
++ - changed return type from plain XMLPARSEAPI to XMLPARSEAPI(int)
++
++Method parseFile(FILE*)
++ - added to simplify loop to read files
++
++CLASS expatppNesting
++Method nestedStartElementCallback
++ - change cast ((expatpp*)userData) to nestedParser-> which is
++ an earlier cast (expatppNesting*)userData so it can correctly invoke
++ through the inheritance chain (and avoid compile error)
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2002/12/30 AD
++ADAPT PROJECTS TO COMPILE NEW 1.95.6-COMPATIBLE VERSION ON WIN32
++
++PROJECT expatpp.dsp
++Static targets (the only ones originally)
++- removed all expat files
++- added files so get new relative path to location in expat/lib
++- changed preprocessor additional include dirs to point via relative ref to expat/lib
++ instead of fixed paths that assumed under \oofile
++- Preprocessor definitions
++ - removed XMLTOKAPI, XMLPARSEAPI
++ - added COMPILED_FROM_DSP, _LIB
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/03-11 AD
++ABLE TO USE ON POCKETPC (ALSO BETTER WITH UNICODE)
++
++FILE expatpp.cpp
++- conditional on UNDER_CE being defined (requirement in user project)
++ - #include <windows.h>
++ - #include <dbgapi.h>
++ - #define assert ASSERT
++ - #include <string.h> vs <string>
++ - use namespace std
++
++- define BUFSIZ as 4096 if not defined already
++
++- conditional on XML_UNICODE
++ - define tcscmp so don't have to include Windows headers to get
++
++
++CLASS expatpp
++Method skipWhiteSpace
++ - use XML_Char for params and locals instead of char
++
++Method getAttribute
++ - use XML_Char for params and locals instead of char
++
++Method getIntegerAttribute
++ - use XML_Char for params and locals instead of char
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/17 AD
++CLEANUP HANDLING NESTING PARSER AS ROOT
++making it safe to pass in null parser
++
++
++CLASS expatppNesting
++Method ctor()
++ - moved different init logic into other ctor
++
++Method ctor(expatppNesting*)
++ - allow for null param
++ - default is null param
++
++
++Method nestedStartElementCallback
++ - added assert user data non null
++
++Method nestedEndElementCallback
++ - just quietly exit if null user data (see comments)
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/18 AD
++ROLL IN CHRIS NEWCOMBE'S IDEAS ABOUT PARENTS OWNING CHILD PARSERS
++
++CLASS expatppNesting
++- mSelfDeleting added
++- mOwnedChild added
++
++Method ctor()
++ - init mOwnedChild(0)
++ - init mSelfDeleting(true)
++ - move some logic to RegisterWithParentXMLParser()
++ - call AdoptChild
++
++Method copy ctor
++ - added private to avoid pointer problems
++
++Method operator=
++ - added private to avoid pointer problems
++
++Method ParentWillDelete
++ - added
++
++Method OwnedChildOrphansItself
++ - added
++
++Method returnToParent
++ - conditional on mSelfDeleting, delete this (was unconditional
++ - add conditional call to OwnedChildOrphansItself
++
++Method RegisterWithParentXMLParser
++ - added
++
++Method AdoptChild
++ - added to allow child parsers to set our mOwnedChild flag
++ if not set (Chris had direct member access)
++
++
++CLASS expatpp
++Method ReleaseParser
++ - added to wrap XML_ParserFree
++
++Method dtor
++ - call ReleaseParser instead of XML_ParserFree
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/18 AD
++ALLOW FOR REPEATED PARSING
++
++CLASS expatpp
++- mHaveParsed added
++
++Method ctor
++ - init mHaveParsed(false)
++
++Method ResetParser
++ - added
++
++Method parseFile
++ - call ResetParser()
++
++Method parseString
++ - call ResetParser()
++
++Method XML_Parse
++ - set mHaveParsed
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/18 AD
++ALLOW (POTENTIALLY) COMPILATION WITH OLD EXPAT 1.2
++to be tested
++
++
++CLASS expatpp
++Method ctor
++ - wrap the extra XML_Set... calls in #ifndef EXPATPP_COMPATIBLE_EXPAT12
++
++FILE expatpp.h
++#ifdef EXPATPP_COMPATIBLE_EXPAT12
++ #include "xmlparse.h" vs expat.h
++
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/20 AD
++ADD MORE FLEXIBILITY IN SUBCLASSING FOR ERRORS AND CLEANUP
++
++
++CLASS expatpp
++Method ResetParser
++ - made virtual
++
++Method SetHandlers
++ - made virtual
++
++Method ParserFree
++ - made virtual
++
++Method CheckFinalStatus
++ - added empty virtual
++
++Method XMLParse
++ - call CheckFinalStatus to give subclass chance to log error
++ - made non-inline
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/20 AD
++PREVENT WINDOWS LINKER ERRORS
++
++Remove the XMLPARSEAPI wrapper around return type for
++- XML_Parse
++- parseFile
++- parseString
++- XML_GetErrorCode
++- XML_GetCurrentLineNumber
++
++
++-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
++2003/01/24 AD
++DEBUGGING NEW NESTING STYLE
++
++CLASS expatppNesting
++Method DeleteChild
++ - added
++
++Method dtor
++ - invoke DeleteChild
++
++
+diff --git a/EXTEND b/EXTEND
+new file mode 100755
+index 0000000..f0981e5
+--- /dev/null
++++ b/EXTEND
+@@ -0,0 +1,31 @@
++expatpp Prog Docs.txt
++
++How to add new handlers to expatpp when they are added to expat.
++-----------------------------------------------------------------
++
++Look in expat.h for a Set*Handler method like
++XMLPARSEAPI(void)
++XML_SetXmlDeclHandler(XML_Parser parser,
++ XML_XmlDeclHandler xmldecl);
++
++
++You will normally have a matching function like
++typedef void (*XML_XmlDeclHandler) (void *userData,
++ const XML_Char *version,
++ const XML_Char *encoding,
++ int standalone);
++
++We add a virtual method of expatpp to match XML_XmlDeclHandler and a static function
++with the same signature XML_XmlDeclHandlerCallback
++
++The XML_SetXmlDeclHandler will need to be invoked in the expatpp ctor, passing in
++xmlDeclHandlerCallback as the handler function.
++
++
++
++Using with PocketPC
++-------------------
++Make sure _POCKETPC is defined in your project.
++It has only been tested by including the files into the PPC project, rather than
++attempting to build a library or DLL, so you also need to define COMPILED_FROM_DSP
++and XML_STATIC, as you do in any project which uses the expat files directly.
+diff --git a/TODO b/TODO
+new file mode 100755
+index 0000000..f7f7445
+--- /dev/null
++++ b/TODO
+@@ -0,0 +1,29 @@
++expatpp TODO.txt
++
++As of 2002/12/30 having completed revisions to make it compatible with expat 1.95.6
++
++Add Makefile to match project changes so can build on Unix.
++
++Contact BC project author and get him to do revision.
++
++Update Visual C++ project to build DLL and Unicode versions like expat.
++
++Add test targets to VC project.
++
++ADD UNIT TESTS FOR EXPATPP
++- start subparser
++- start subparser with desired info in attributes of starting element
++- consider all new methods
++- missing data
++ - missing expected char content
++- how handle parser crash
++- add reset and test
++
++
++
++
++OTHER TO DO
++
++Static function calling XML_ParserReset.
++
++Static top-level functions providing parsing loop like example.
+diff --git a/expatpp Code Change Diary.txt b/expatpp Code Change Diary.txt
+deleted file mode 100755
+index 5e2479c..0000000
+--- a/expatpp Code Change Diary.txt
++++ /dev/null
+@@ -1,359 +0,0 @@
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-98/09/02
+-
+-FILE xpatpp.h
+-CLASS xpatt
+-- added overrideable callbacks:
+- processingInstruction
+- defaultHandler
+- unparsedEntityDecl
+- notationDecl
+-
+--added interface functions for callbacks:
+- processingInstructionCallback
+- defaultHandlerCallback
+- unparsedEntityDeclCallback
+- notationDeclCallback
+-
+-- added inlines for these interface functions
+-
+-FILE xpatpp.cpp
+-CLASS xpattp
+-Method xpattp
+-- added calls to
+- XML_SetProcessingInstructionHandler
+- XML_SetDefaultHandler
+- XML_SetUnparsedEntityDeclHandler
+- XML_SetNotationDeclHandler
+-
+-
+-- added empty implementations of the overrideable callbacks
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-99/03/10 AD
+-renamed xpatpp to expatpp in filenames and classes.
+-updated xpcw project to compile with CodeWarrior Pro4
+-and add PPC target to 68K.
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-99/05/03 AD
+-UPDATE FOR LATEST EXPAT RELEASE
+-
+-FILE expatpp.cpp
+-CLASS expattp
+-Method expattp
+-- added call to XML_SetNotStandaloneHandler
+-- added call to XML_SetNamespaceDeclHandler
+-
+-Methods added
+- - virtual notStandaloneHandler returning 0
+- - Empty virtuals startNamespace & endNamespace
+-
+-
+-FILE expatpp.h
+-CLASS expatpp
+-- added inline notStandaloneHandlerCallback
+-- added inline
+-
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-99/05/05-09 AD
+-ADD NESTED PARSER SUBCLASS
+-
+-CLASS expatppNesting
+-- added subclass of expatpp
+-- mDepth, mParent members added
+-
+-Method ctor
+- - init mDepth(0)
+-
+-Method ctor(expatppNesting*)
+- - added to nest a parser (pointer to parent)
+-
+-Method nestedStartElement, nestedEndElement
+- - added callbacks to inc/dec mDepth
+-
+-
+-CLASS expatpp
+-Method dtor
+- - made virtual
+-
+-Method ctor
+- - add optional param to control creation of parser
+- so can nest parsers and continue to use existing
+- XML parser
+-
+-Method emptyCharData
+- - added to contain common logic I keep putting at top
+- of overridden charData methods
+-
+-Method all callbacks
+- - made non-inline as I realised they will NOT be used
+- inline, being supplied as function addresses, so no
+- point having them declared as inline
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2002/12/28-30 AD
+-CONVERT TO EXPAT 1.95.5
+-
+-CLASS expatpp
+-- made all virtual overrideables protected - should only be invoked through
+- callback interfaces.
+-- Added overrideable empty handlers
+- attlistDecl
+- comment
+- elementDecl
+- endCdataSection
+- endDoctypeDecl
+- entityDecl
+- skippedEntity
+- startCdataSection
+- startDoctypeDecl
+- xmlDecl
+-
+-
+-- Added callback interfaces
+- attlistDeclCallback
+- commentCallback
+- elementDeclCallback
+- endCdataSectionCallback
+- endDoctypeDeclCallback
+- entityDeclCallback
+- skippedEntityCallback
+- startCdataSectionCallback
+- startDoctypeDeclCallback
+- xmlDeclCallback
+-
+-
+-Method ctor
+- - added calls to set handlers for
+- XML_SetAttlistDeclHandler
+- XML_SetCdataSectionHandler
+- XML_SetCommentHandler
+- XML_SetDoctypeDeclHandler
+- XML_SetElementDeclHandler
+- XML_SetEntityDeclHandler
+- XML_SetSkippedEntityHandler
+- XML_SetXmlDeclHandler
+-
+-Method XML_Parse
+- - changed return type from plain XMLPARSEAPI to XMLPARSEAPI(enum XML_Status)
+-
+-Method XML_GetErrorCode
+- - changed return type from plain XMLPARSEAPI to XMLPARSEAPI(enum XML_Error)
+-
+-Method XML_GetCurrentLineNumber
+- - changed return type from plain XMLPARSEAPI to XMLPARSEAPI(int)
+-
+-Method parseFile(FILE*)
+- - added to simplify loop to read files
+-
+-CLASS expatppNesting
+-Method nestedStartElementCallback
+- - change cast ((expatpp*)userData) to nestedParser-> which is
+- an earlier cast (expatppNesting*)userData so it can correctly invoke
+- through the inheritance chain (and avoid compile error)
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2002/12/30 AD
+-ADAPT PROJECTS TO COMPILE NEW 1.95.6-COMPATIBLE VERSION ON WIN32
+-
+-PROJECT expatpp.dsp
+-Static targets (the only ones originally)
+-- removed all expat files
+-- added files so get new relative path to location in expat/lib
+-- changed preprocessor additional include dirs to point via relative ref to expat/lib
+- instead of fixed paths that assumed under \oofile
+-- Preprocessor definitions
+- - removed XMLTOKAPI, XMLPARSEAPI
+- - added COMPILED_FROM_DSP, _LIB
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/03-11 AD
+-ABLE TO USE ON POCKETPC (ALSO BETTER WITH UNICODE)
+-
+-FILE expatpp.cpp
+-- conditional on UNDER_CE being defined (requirement in user project)
+- - #include <windows.h>
+- - #include <dbgapi.h>
+- - #define assert ASSERT
+- - #include <string.h> vs <string>
+- - use namespace std
+-
+-- define BUFSIZ as 4096 if not defined already
+-
+-- conditional on XML_UNICODE
+- - define tcscmp so don't have to include Windows headers to get
+-
+-
+-CLASS expatpp
+-Method skipWhiteSpace
+- - use XML_Char for params and locals instead of char
+-
+-Method getAttribute
+- - use XML_Char for params and locals instead of char
+-
+-Method getIntegerAttribute
+- - use XML_Char for params and locals instead of char
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/17 AD
+-CLEANUP HANDLING NESTING PARSER AS ROOT
+-making it safe to pass in null parser
+-
+-
+-CLASS expatppNesting
+-Method ctor()
+- - moved different init logic into other ctor
+-
+-Method ctor(expatppNesting*)
+- - allow for null param
+- - default is null param
+-
+-
+-Method nestedStartElementCallback
+- - added assert user data non null
+-
+-Method nestedEndElementCallback
+- - just quietly exit if null user data (see comments)
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/18 AD
+-ROLL IN CHRIS NEWCOMBE'S IDEAS ABOUT PARENTS OWNING CHILD PARSERS
+-
+-CLASS expatppNesting
+-- mSelfDeleting added
+-- mOwnedChild added
+-
+-Method ctor()
+- - init mOwnedChild(0)
+- - init mSelfDeleting(true)
+- - move some logic to RegisterWithParentXMLParser()
+- - call AdoptChild
+-
+-Method copy ctor
+- - added private to avoid pointer problems
+-
+-Method operator=
+- - added private to avoid pointer problems
+-
+-Method ParentWillDelete
+- - added
+-
+-Method OwnedChildOrphansItself
+- - added
+-
+-Method returnToParent
+- - conditional on mSelfDeleting, delete this (was unconditional
+- - add conditional call to OwnedChildOrphansItself
+-
+-Method RegisterWithParentXMLParser
+- - added
+-
+-Method AdoptChild
+- - added to allow child parsers to set our mOwnedChild flag
+- if not set (Chris had direct member access)
+-
+-
+-CLASS expatpp
+-Method ReleaseParser
+- - added to wrap XML_ParserFree
+-
+-Method dtor
+- - call ReleaseParser instead of XML_ParserFree
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/18 AD
+-ALLOW FOR REPEATED PARSING
+-
+-CLASS expatpp
+-- mHaveParsed added
+-
+-Method ctor
+- - init mHaveParsed(false)
+-
+-Method ResetParser
+- - added
+-
+-Method parseFile
+- - call ResetParser()
+-
+-Method parseString
+- - call ResetParser()
+-
+-Method XML_Parse
+- - set mHaveParsed
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/18 AD
+-ALLOW (POTENTIALLY) COMPILATION WITH OLD EXPAT 1.2
+-to be tested
+-
+-
+-CLASS expatpp
+-Method ctor
+- - wrap the extra XML_Set... calls in #ifndef EXPATPP_COMPATIBLE_EXPAT12
+-
+-FILE expatpp.h
+-#ifdef EXPATPP_COMPATIBLE_EXPAT12
+- #include "xmlparse.h" vs expat.h
+-
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/20 AD
+-ADD MORE FLEXIBILITY IN SUBCLASSING FOR ERRORS AND CLEANUP
+-
+-
+-CLASS expatpp
+-Method ResetParser
+- - made virtual
+-
+-Method SetHandlers
+- - made virtual
+-
+-Method ParserFree
+- - made virtual
+-
+-Method CheckFinalStatus
+- - added empty virtual
+-
+-Method XMLParse
+- - call CheckFinalStatus to give subclass chance to log error
+- - made non-inline
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/20 AD
+-PREVENT WINDOWS LINKER ERRORS
+-
+-Remove the XMLPARSEAPI wrapper around return type for
+-- XML_Parse
+-- parseFile
+-- parseString
+-- XML_GetErrorCode
+-- XML_GetCurrentLineNumber
+-
+-
+--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+-2003/01/24 AD
+-DEBUGGING NEW NESTING STYLE
+-
+-CLASS expatppNesting
+-Method DeleteChild
+- - added
+-
+-Method dtor
+- - invoke DeleteChild
+-
+-
+diff --git a/expatpp Prog Docs.txt b/expatpp Prog Docs.txt
+deleted file mode 100755
+index f0981e5..0000000
+--- a/expatpp Prog Docs.txt
++++ /dev/null
+@@ -1,31 +0,0 @@
+-expatpp Prog Docs.txt
+-
+-How to add new handlers to expatpp when they are added to expat.
+------------------------------------------------------------------
+-
+-Look in expat.h for a Set*Handler method like
+-XMLPARSEAPI(void)
+-XML_SetXmlDeclHandler(XML_Parser parser,
+- XML_XmlDeclHandler xmldecl);
+-
+-
+-You will normally have a matching function like
+-typedef void (*XML_XmlDeclHandler) (void *userData,
+- const XML_Char *version,
+- const XML_Char *encoding,
+- int standalone);
+-
+-We add a virtual method of expatpp to match XML_XmlDeclHandler and a static function
+-with the same signature XML_XmlDeclHandlerCallback
+-
+-The XML_SetXmlDeclHandler will need to be invoked in the expatpp ctor, passing in
+-xmlDeclHandlerCallback as the handler function.
+-
+-
+-
+-Using with PocketPC
+--------------------
+-Make sure _POCKETPC is defined in your project.
+-It has only been tested by including the files into the PPC project, rather than
+-attempting to build a library or DLL, so you also need to define COMPILED_FROM_DSP
+-and XML_STATIC, as you do in any project which uses the expat files directly.
+diff --git a/expatpp TODO.txt b/expatpp TODO.txt
+deleted file mode 100755
+index f7f7445..0000000
+--- a/expatpp TODO.txt
++++ /dev/null
+@@ -1,29 +0,0 @@
+-expatpp TODO.txt
+-
+-As of 2002/12/30 having completed revisions to make it compatible with expat 1.95.6
+-
+-Add Makefile to match project changes so can build on Unix.
+-
+-Contact BC project author and get him to do revision.
+-
+-Update Visual C++ project to build DLL and Unicode versions like expat.
+-
+-Add test targets to VC project.
+-
+-ADD UNIT TESTS FOR EXPATPP
+-- start subparser
+-- start subparser with desired info in attributes of starting element
+-- consider all new methods
+-- missing data
+- - missing expected char content
+-- how handle parser crash
+-- add reset and test
+-
+-
+-
+-
+-OTHER TO DO
+-
+-Static function calling XML_ParserReset.
+-
+-Static top-level functions providing parsing loop like example.
+--
+1.7.11.7
+
diff --git a/expatpp.spec b/expatpp.spec
new file mode 100644
index 0000000..a40f833
--- /dev/null
+++ b/expatpp.spec
@@ -0,0 +1,111 @@
+Name: expatpp
+Version: 0
+Release: 1.20121019gitd8c1bf8%{?dist}
+Summary: C++ layer for expat
+Group: Development/Libraries
+License: MPLv1.1
+URL: http://sourceforge.net/projects/expatpp/
+# svn export -r 6 https://expatpp.svn.sourceforge.net/svnroot/expatpp/trunk/src_pp/ expatpp
+# tar cjf expatpp.tar.bz2 expatpp
+Source0: expatpp.tar.bz2
+Patch1: 0001-Added-CMake-config-file.patch
+Patch2: 0002-Fix-case-of-required-arg.patch
+Patch3: 0003-Include-string-header.patch
+Patch4: 0004-Converted-to-lib-standalone-program-layout.patch
+Patch5: 0005-Added-test-code.patch
+Patch6: 0006-Build-testexpatpp1.patch
+Patch7: 0007-Fix-subdir-command.patch
+Patch8: 0008-Added-cPack.patch
+Patch9: 0009-Install-library.patch
+Patch10: 0010-Use-lib-or-lib64-automatically.patch
+Patch11: 0011-added-soname-info.patch
+Patch12: 0012-Fixed-missing-api-version.patch
+Patch13: 0013-Install-header-file.patch
+Patch14: 0014-Removed-windows-static-lib-header.patch
+Patch15: 0015-Reworked-documentation.patch
+
+Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildRequires: cmake
+BuildRequires: expat-devel
+
+%description
+Expatpp is a simple C++ layer to make using the open source expat XML parsing
+library vastly easier for complex schemas. It has been used widely in industry
+including the Valve Steam project.
+
+%package devel
+Summary: Headers and development libraries for expatpp
+Group: Development/Libraries
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+
+You should install this package if you would like to
+develop code based on expatpp.
+
+%prep
+%setup -q -n expatpp
+
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+
+
+%build
+%cmake -DCMAKE_VERBOSE_MAKEFILE=ON \
+ -DBUILD_SHARED_LIBS:BOOL=ON \
+ -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" .
+
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%check
+ctest .
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%doc CHANGELOG EXTEND TODO
+%{_libdir}/*.so.*
+
+%files devel
+%{_includedir}/%{name}.h
+%{_libdir}/*.so
+
+
+%changelog
+* Sun Oct 28 2012 Mario Ceresa mrceresa fedoraproject org expatpp 0-1.20121019gitd8c1bf8%{?dist}
+- Included revision in svn export directive
+- Fixed tab/spaces issue
+- Fixed revision tag
+- Shorted Source tag
+
+
+
+* Fri Oct 19 2012 Mario Ceresa mrceresa fedoraproject org expatpp 0.6-20121019gitd8c1bf8%{?dist}
+- Added patches and fixed release tag
+- Fixed license and doc files
+
+* Thu Oct 18 2012 Mario Ceresa mrceresa fedoraproject org expatpp 0.6-1%{?dist}
+- Initial SPEC
diff --git a/sources b/sources
index e69de29..882f5ca 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+dcc7c0c0a02801cc0cbd233b7c000281 expatpp.tar.bz2
More information about the scm-commits
mailing list