|
@@ -30,6 +30,7 @@
|
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <stddef.h>
|
|
@@ -42,9 +43,28 @@
|
|
#include "xmltchar.h"
|
|
#include "xmltchar.h"
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
#ifdef _MSC_VER
|
|
-#include <crtdbg.h>
|
|
|
|
|
|
+# include <crtdbg.h>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef XML_UNICODE
|
|
|
|
+# include <wchar.h>
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+/* Structures for handler user data */
|
|
|
|
+typedef struct NotationList {
|
|
|
|
+ struct NotationList *next;
|
|
|
|
+ const XML_Char *notationName;
|
|
|
|
+ const XML_Char *systemId;
|
|
|
|
+ const XML_Char *publicId;
|
|
|
|
+} NotationList;
|
|
|
|
+
|
|
|
|
+typedef struct xmlwfUserData {
|
|
|
|
+ FILE *fp;
|
|
|
|
+ NotationList *notationListHead;
|
|
|
|
+ const XML_Char *currentDoctypeName;
|
|
|
|
+} XmlwfUserData;
|
|
|
|
+
|
|
|
|
+
|
|
/* This ensures proper sorting. */
|
|
/* This ensures proper sorting. */
|
|
|
|
|
|
#define NSSEP T('\001')
|
|
#define NSSEP T('\001')
|
|
@@ -52,7 +72,7 @@
|
|
static void XMLCALL
|
|
static void XMLCALL
|
|
characterData(void *userData, const XML_Char *s, int len)
|
|
characterData(void *userData, const XML_Char *s, int len)
|
|
{
|
|
{
|
|
- FILE *fp = (FILE *)userData;
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
|
|
for (; len > 0; --len, ++s) {
|
|
for (; len > 0; --len, ++s) {
|
|
switch (*s) {
|
|
switch (*s) {
|
|
case T('&'):
|
|
case T('&'):
|
|
@@ -90,6 +110,7 @@ attributeValue(FILE *fp, const XML_Char *s)
|
|
{
|
|
{
|
|
puttc(T('='), fp);
|
|
puttc(T('='), fp);
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
|
|
+ assert(s);
|
|
for (;;) {
|
|
for (;;) {
|
|
switch (*s) {
|
|
switch (*s) {
|
|
case 0:
|
|
case 0:
|
|
@@ -147,7 +168,7 @@ startElement(void *userData, const XML_Char *name, const XML_Char **atts)
|
|
{
|
|
{
|
|
int nAtts;
|
|
int nAtts;
|
|
const XML_Char **p;
|
|
const XML_Char **p;
|
|
- FILE *fp = (FILE *)userData;
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
|
|
puttc(T('<'), fp);
|
|
puttc(T('<'), fp);
|
|
fputts(name, fp);
|
|
fputts(name, fp);
|
|
|
|
|
|
@@ -169,7 +190,7 @@ startElement(void *userData, const XML_Char *name, const XML_Char **atts)
|
|
static void XMLCALL
|
|
static void XMLCALL
|
|
endElement(void *userData, const XML_Char *name)
|
|
endElement(void *userData, const XML_Char *name)
|
|
{
|
|
{
|
|
- FILE *fp = (FILE *)userData;
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
|
|
puttc(T('<'), fp);
|
|
puttc(T('<'), fp);
|
|
puttc(T('/'), fp);
|
|
puttc(T('/'), fp);
|
|
fputts(name, fp);
|
|
fputts(name, fp);
|
|
@@ -194,7 +215,7 @@ startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
|
|
int nAtts;
|
|
int nAtts;
|
|
int nsi;
|
|
int nsi;
|
|
const XML_Char **p;
|
|
const XML_Char **p;
|
|
- FILE *fp = (FILE *)userData;
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
|
|
const XML_Char *sep;
|
|
const XML_Char *sep;
|
|
puttc(T('<'), fp);
|
|
puttc(T('<'), fp);
|
|
|
|
|
|
@@ -240,7 +261,7 @@ startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
|
|
static void XMLCALL
|
|
static void XMLCALL
|
|
endElementNS(void *userData, const XML_Char *name)
|
|
endElementNS(void *userData, const XML_Char *name)
|
|
{
|
|
{
|
|
- FILE *fp = (FILE *)userData;
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
|
|
const XML_Char *sep;
|
|
const XML_Char *sep;
|
|
puttc(T('<'), fp);
|
|
puttc(T('<'), fp);
|
|
puttc(T('/'), fp);
|
|
puttc(T('/'), fp);
|
|
@@ -260,7 +281,7 @@ static void XMLCALL
|
|
processingInstruction(void *userData, const XML_Char *target,
|
|
processingInstruction(void *userData, const XML_Char *target,
|
|
const XML_Char *data)
|
|
const XML_Char *data)
|
|
{
|
|
{
|
|
- FILE *fp = (FILE *)userData;
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
|
|
puttc(T('<'), fp);
|
|
puttc(T('<'), fp);
|
|
puttc(T('?'), fp);
|
|
puttc(T('?'), fp);
|
|
fputts(target, fp);
|
|
fputts(target, fp);
|
|
@@ -270,6 +291,200 @@ processingInstruction(void *userData, const XML_Char *target,
|
|
puttc(T('>'), fp);
|
|
puttc(T('>'), fp);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+static XML_Char *xcsdup(const XML_Char *s)
|
|
|
|
+{
|
|
|
|
+ XML_Char *result;
|
|
|
|
+ int count = 0;
|
|
|
|
+ int numBytes;
|
|
|
|
+
|
|
|
|
+ /* Get the length of the string, including terminator */
|
|
|
|
+ while (s[count++] != 0) {
|
|
|
|
+ /* Do nothing */
|
|
|
|
+ }
|
|
|
|
+ numBytes = count * sizeof(XML_Char);
|
|
|
|
+ result = malloc(numBytes);
|
|
|
|
+ if (result == NULL)
|
|
|
|
+ return NULL;
|
|
|
|
+ memcpy(result, s, numBytes);
|
|
|
|
+ return result;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void XMLCALL
|
|
|
|
+startDoctypeDecl(void *userData,
|
|
|
|
+ const XML_Char *doctypeName,
|
|
|
|
+ const XML_Char *UNUSED_P(sysid),
|
|
|
|
+ const XML_Char *UNUSED_P(publid),
|
|
|
|
+ int UNUSED_P(has_internal_subset))
|
|
|
|
+{
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)userData;
|
|
|
|
+ data->currentDoctypeName = xcsdup(doctypeName);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+freeNotations(XmlwfUserData *data)
|
|
|
|
+{
|
|
|
|
+ NotationList *notationListHead = data->notationListHead;
|
|
|
|
+
|
|
|
|
+ while (notationListHead != NULL) {
|
|
|
|
+ NotationList *next = notationListHead->next;
|
|
|
|
+ free((void *)notationListHead->notationName);
|
|
|
|
+ free((void *)notationListHead->systemId);
|
|
|
|
+ free((void *)notationListHead->publicId);
|
|
|
|
+ free(notationListHead);
|
|
|
|
+ notationListHead = next;
|
|
|
|
+ }
|
|
|
|
+ data->notationListHead = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int xcscmp(const XML_Char *xs, const XML_Char *xt)
|
|
|
|
+{
|
|
|
|
+ while (*xs != 0 && *xt != 0) {
|
|
|
|
+ if (*xs < *xt)
|
|
|
|
+ return -1;
|
|
|
|
+ if (*xs > *xt)
|
|
|
|
+ return 1;
|
|
|
|
+ xs++;
|
|
|
|
+ xt++;
|
|
|
|
+ }
|
|
|
|
+ if (*xs < *xt)
|
|
|
|
+ return -1;
|
|
|
|
+ if (*xs > *xt)
|
|
|
|
+ return 1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+notationCmp(const void *a, const void *b)
|
|
|
|
+{
|
|
|
|
+ const NotationList * const n1 = *(NotationList **)a;
|
|
|
|
+ const NotationList * const n2 = *(NotationList **)b;
|
|
|
|
+
|
|
|
|
+ return xcscmp(n1->notationName, n2->notationName);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void XMLCALL
|
|
|
|
+endDoctypeDecl(void *userData)
|
|
|
|
+{
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)userData;
|
|
|
|
+ NotationList **notations;
|
|
|
|
+ int notationCount = 0;
|
|
|
|
+ NotationList *p;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ /* How many notations do we have? */
|
|
|
|
+ for (p = data->notationListHead; p != NULL; p = p->next)
|
|
|
|
+ notationCount++;
|
|
|
|
+ if (notationCount == 0) {
|
|
|
|
+ /* Nothing to report */
|
|
|
|
+ free((void *)data->currentDoctypeName);
|
|
|
|
+ data->currentDoctypeName = NULL;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ notations = malloc(notationCount * sizeof(NotationList *));
|
|
|
|
+ if (notations == NULL) {
|
|
|
|
+ fprintf(stderr, "Unable to sort notations");
|
|
|
|
+ freeNotations(data);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (p = data->notationListHead, i = 0;
|
|
|
|
+ i < notationCount;
|
|
|
|
+ p = p->next, i++) {
|
|
|
|
+ notations[i] = p;
|
|
|
|
+ }
|
|
|
|
+ qsort(notations, notationCount, sizeof(NotationList *), notationCmp);
|
|
|
|
+
|
|
|
|
+ /* Output the DOCTYPE header */
|
|
|
|
+ fputts(T("<!DOCTYPE "), data->fp);
|
|
|
|
+ fputts(data->currentDoctypeName, data->fp);
|
|
|
|
+ fputts(T(" [\n"), data->fp);
|
|
|
|
+
|
|
|
|
+ /* Now the NOTATIONs */
|
|
|
|
+ for (i = 0; i < notationCount; i++) {
|
|
|
|
+ fputts(T("<!NOTATION "), data->fp);
|
|
|
|
+ fputts(notations[i]->notationName, data->fp);
|
|
|
|
+ if (notations[i]->publicId != NULL) {
|
|
|
|
+ fputts(T(" PUBLIC '"), data->fp);
|
|
|
|
+ fputts(notations[i]->publicId, data->fp);
|
|
|
|
+ puttc(T('\''), data->fp);
|
|
|
|
+ if (notations[i]->systemId != NULL) {
|
|
|
|
+ puttc(T(' '), data->fp);
|
|
|
|
+ puttc(T('\''), data->fp);
|
|
|
|
+ fputts(notations[i]->systemId, data->fp);
|
|
|
|
+ puttc(T('\''), data->fp);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (notations[i]->systemId != NULL) {
|
|
|
|
+ fputts(T(" SYSTEM '"), data->fp);
|
|
|
|
+ fputts(notations[i]->systemId, data->fp);
|
|
|
|
+ puttc(T('\''), data->fp);
|
|
|
|
+ }
|
|
|
|
+ puttc(T('>'), data->fp);
|
|
|
|
+ puttc(T('\n'), data->fp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Finally end the DOCTYPE */
|
|
|
|
+ fputts(T("]>\n"), data->fp);
|
|
|
|
+
|
|
|
|
+ free(notations);
|
|
|
|
+ freeNotations(data);
|
|
|
|
+ free((void *)data->currentDoctypeName);
|
|
|
|
+ data->currentDoctypeName = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void XMLCALL
|
|
|
|
+notationDecl(void *userData,
|
|
|
|
+ const XML_Char *notationName,
|
|
|
|
+ const XML_Char *UNUSED_P(base),
|
|
|
|
+ const XML_Char *systemId,
|
|
|
|
+ const XML_Char *publicId)
|
|
|
|
+{
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)userData;
|
|
|
|
+ NotationList *entry = malloc(sizeof(NotationList));
|
|
|
|
+ const char *errorMessage = "Unable to store NOTATION for output\n";
|
|
|
|
+
|
|
|
|
+ if (entry == NULL) {
|
|
|
|
+ fputs(errorMessage, stderr);
|
|
|
|
+ return; /* Nothing we can really do about this */
|
|
|
|
+ }
|
|
|
|
+ entry->notationName = xcsdup(notationName);
|
|
|
|
+ if (entry->notationName == NULL) {
|
|
|
|
+ fputs(errorMessage, stderr);
|
|
|
|
+ free(entry);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (systemId != NULL) {
|
|
|
|
+ entry->systemId = xcsdup(systemId);
|
|
|
|
+ if (entry->systemId == NULL) {
|
|
|
|
+ fputs(errorMessage, stderr);
|
|
|
|
+ free((void *)entry->notationName);
|
|
|
|
+ free(entry);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ entry->systemId = NULL;
|
|
|
|
+ }
|
|
|
|
+ if (publicId != NULL) {
|
|
|
|
+ entry->publicId = xcsdup(publicId);
|
|
|
|
+ if (entry->publicId == NULL) {
|
|
|
|
+ fputs(errorMessage, stderr);
|
|
|
|
+ free((void *)entry->systemId); /* Safe if it's NULL */
|
|
|
|
+ free((void *)entry->notationName);
|
|
|
|
+ free(entry);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ entry->publicId = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ entry->next = data->notationListHead;
|
|
|
|
+ data->notationListHead = entry;
|
|
|
|
+}
|
|
|
|
+
|
|
#endif /* not W3C14N */
|
|
#endif /* not W3C14N */
|
|
|
|
|
|
static void XMLCALL
|
|
static void XMLCALL
|
|
@@ -322,7 +537,7 @@ nopProcessingInstruction(void *UNUSED_P(userData), const XML_Char *UNUSED_P(targ
|
|
static void XMLCALL
|
|
static void XMLCALL
|
|
markup(void *userData, const XML_Char *s, int len)
|
|
markup(void *userData, const XML_Char *s, int len)
|
|
{
|
|
{
|
|
- FILE *fp = (FILE *)XML_GetUserData((XML_Parser) userData);
|
|
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)XML_GetUserData((XML_Parser) userData))->fp;
|
|
for (; len > 0; --len, ++s)
|
|
for (; len > 0; --len, ++s)
|
|
puttc(*s, fp);
|
|
puttc(*s, fp);
|
|
}
|
|
}
|
|
@@ -331,11 +546,14 @@ static void
|
|
metaLocation(XML_Parser parser)
|
|
metaLocation(XML_Parser parser)
|
|
{
|
|
{
|
|
const XML_Char *uri = XML_GetBase(parser);
|
|
const XML_Char *uri = XML_GetBase(parser);
|
|
|
|
+ FILE *fp = ((XmlwfUserData *)XML_GetUserData(parser))->fp;
|
|
if (uri)
|
|
if (uri)
|
|
- ftprintf((FILE *)XML_GetUserData(parser), T(" uri=\"%s\""), uri);
|
|
|
|
- ftprintf((FILE *)XML_GetUserData(parser),
|
|
|
|
- T(" byte=\"%" XML_FMT_INT_MOD "d\" nbytes=\"%d\" \
|
|
|
|
- line=\"%" XML_FMT_INT_MOD "u\" col=\"%" XML_FMT_INT_MOD "u\""),
|
|
|
|
|
|
+ ftprintf(fp, T(" uri=\"%s\""), uri);
|
|
|
|
+ ftprintf(fp,
|
|
|
|
+ T(" byte=\"%") T(XML_FMT_INT_MOD) T("d\"")
|
|
|
|
+ T(" nbytes=\"%d\"")
|
|
|
|
+ T(" line=\"%") T(XML_FMT_INT_MOD) T("u\"")
|
|
|
|
+ T(" col=\"%") T(XML_FMT_INT_MOD) T("u\""),
|
|
XML_GetCurrentByteIndex(parser),
|
|
XML_GetCurrentByteIndex(parser),
|
|
XML_GetCurrentByteCount(parser),
|
|
XML_GetCurrentByteCount(parser),
|
|
XML_GetCurrentLineNumber(parser),
|
|
XML_GetCurrentLineNumber(parser),
|
|
@@ -345,13 +563,15 @@ metaLocation(XML_Parser parser)
|
|
static void
|
|
static void
|
|
metaStartDocument(void *userData)
|
|
metaStartDocument(void *userData)
|
|
{
|
|
{
|
|
- fputts(T("<document>\n"), (FILE *)XML_GetUserData((XML_Parser) userData));
|
|
|
|
|
|
+ fputts(T("<document>\n"),
|
|
|
|
+ ((XmlwfUserData *)XML_GetUserData((XML_Parser) userData))->fp);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
static void
|
|
metaEndDocument(void *userData)
|
|
metaEndDocument(void *userData)
|
|
{
|
|
{
|
|
- fputts(T("</document>\n"), (FILE *)XML_GetUserData((XML_Parser) userData));
|
|
|
|
|
|
+ fputts(T("</document>\n"),
|
|
|
|
+ ((XmlwfUserData *)XML_GetUserData((XML_Parser) userData))->fp);
|
|
}
|
|
}
|
|
|
|
|
|
static void XMLCALL
|
|
static void XMLCALL
|
|
@@ -359,7 +579,8 @@ metaStartElement(void *userData, const XML_Char *name,
|
|
const XML_Char **atts)
|
|
const XML_Char **atts)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
const XML_Char **specifiedAttsEnd
|
|
const XML_Char **specifiedAttsEnd
|
|
= atts + XML_GetSpecifiedAttributeCount(parser);
|
|
= atts + XML_GetSpecifiedAttributeCount(parser);
|
|
const XML_Char **idAttPtr;
|
|
const XML_Char **idAttPtr;
|
|
@@ -368,14 +589,14 @@ metaStartElement(void *userData, const XML_Char *name,
|
|
idAttPtr = 0;
|
|
idAttPtr = 0;
|
|
else
|
|
else
|
|
idAttPtr = atts + idAttIndex;
|
|
idAttPtr = atts + idAttIndex;
|
|
-
|
|
|
|
|
|
+
|
|
ftprintf(fp, T("<starttag name=\"%s\""), name);
|
|
ftprintf(fp, T("<starttag name=\"%s\""), name);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
if (*atts) {
|
|
if (*atts) {
|
|
fputts(T(">\n"), fp);
|
|
fputts(T(">\n"), fp);
|
|
do {
|
|
do {
|
|
ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
|
|
ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
|
|
- characterData(fp, atts[1], (int)tcslen(atts[1]));
|
|
|
|
|
|
+ characterData(data, atts[1], (int)tcslen(atts[1]));
|
|
if (atts >= specifiedAttsEnd)
|
|
if (atts >= specifiedAttsEnd)
|
|
fputts(T("\" defaulted=\"yes\"/>\n"), fp);
|
|
fputts(T("\" defaulted=\"yes\"/>\n"), fp);
|
|
else if (atts == idAttPtr)
|
|
else if (atts == idAttPtr)
|
|
@@ -393,7 +614,8 @@ static void XMLCALL
|
|
metaEndElement(void *userData, const XML_Char *name)
|
|
metaEndElement(void *userData, const XML_Char *name)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
ftprintf(fp, T("<endtag name=\"%s\""), name);
|
|
ftprintf(fp, T("<endtag name=\"%s\""), name);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -404,9 +626,10 @@ metaProcessingInstruction(void *userData, const XML_Char *target,
|
|
const XML_Char *data)
|
|
const XML_Char *data)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = usrData->fp;
|
|
ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
|
|
ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
|
|
- characterData(fp, data, (int)tcslen(data));
|
|
|
|
|
|
+ characterData(usrData, data, (int)tcslen(data));
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -416,9 +639,10 @@ static void XMLCALL
|
|
metaComment(void *userData, const XML_Char *data)
|
|
metaComment(void *userData, const XML_Char *data)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = usrData->fp;
|
|
fputts(T("<comment data=\""), fp);
|
|
fputts(T("<comment data=\""), fp);
|
|
- characterData(fp, data, (int)tcslen(data));
|
|
|
|
|
|
+ characterData(usrData, data, (int)tcslen(data));
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -428,7 +652,8 @@ static void XMLCALL
|
|
metaStartCdataSection(void *userData)
|
|
metaStartCdataSection(void *userData)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
fputts(T("<startcdata"), fp);
|
|
fputts(T("<startcdata"), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -438,7 +663,8 @@ static void XMLCALL
|
|
metaEndCdataSection(void *userData)
|
|
metaEndCdataSection(void *userData)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
fputts(T("<endcdata"), fp);
|
|
fputts(T("<endcdata"), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -448,9 +674,10 @@ static void XMLCALL
|
|
metaCharacterData(void *userData, const XML_Char *s, int len)
|
|
metaCharacterData(void *userData, const XML_Char *s, int len)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
fputts(T("<chars str=\""), fp);
|
|
fputts(T("<chars str=\""), fp);
|
|
- characterData(fp, s, len);
|
|
|
|
|
|
+ characterData(data, s, len);
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -464,7 +691,8 @@ metaStartDoctypeDecl(void *userData,
|
|
int UNUSED_P(has_internal_subset))
|
|
int UNUSED_P(has_internal_subset))
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
|
|
ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -474,7 +702,8 @@ static void XMLCALL
|
|
metaEndDoctypeDecl(void *userData)
|
|
metaEndDoctypeDecl(void *userData)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
fputts(T("<enddoctype"), fp);
|
|
fputts(T("<enddoctype"), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -488,13 +717,14 @@ metaNotationDecl(void *userData,
|
|
const XML_Char *publicId)
|
|
const XML_Char *publicId)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
ftprintf(fp, T("<notation name=\"%s\""), notationName);
|
|
ftprintf(fp, T("<notation name=\"%s\""), notationName);
|
|
if (publicId)
|
|
if (publicId)
|
|
ftprintf(fp, T(" public=\"%s\""), publicId);
|
|
ftprintf(fp, T(" public=\"%s\""), publicId);
|
|
if (systemId) {
|
|
if (systemId) {
|
|
fputts(T(" system=\""), fp);
|
|
fputts(T(" system=\""), fp);
|
|
- characterData(fp, systemId, (int)tcslen(systemId));
|
|
|
|
|
|
+ characterData(data, systemId, (int)tcslen(systemId));
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
}
|
|
}
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
@@ -514,13 +744,14 @@ metaEntityDecl(void *userData,
|
|
const XML_Char *notationName)
|
|
const XML_Char *notationName)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
|
|
|
|
if (value) {
|
|
if (value) {
|
|
ftprintf(fp, T("<entity name=\"%s\""), entityName);
|
|
ftprintf(fp, T("<entity name=\"%s\""), entityName);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
puttc(T('>'), fp);
|
|
puttc(T('>'), fp);
|
|
- characterData(fp, value, value_length);
|
|
|
|
|
|
+ characterData(data, value, value_length);
|
|
fputts(T("</entity/>\n"), fp);
|
|
fputts(T("</entity/>\n"), fp);
|
|
}
|
|
}
|
|
else if (notationName) {
|
|
else if (notationName) {
|
|
@@ -528,7 +759,7 @@ metaEntityDecl(void *userData,
|
|
if (publicId)
|
|
if (publicId)
|
|
ftprintf(fp, T(" public=\"%s\""), publicId);
|
|
ftprintf(fp, T(" public=\"%s\""), publicId);
|
|
fputts(T(" system=\""), fp);
|
|
fputts(T(" system=\""), fp);
|
|
- characterData(fp, systemId, (int)tcslen(systemId));
|
|
|
|
|
|
+ characterData(data, systemId, (int)tcslen(systemId));
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
ftprintf(fp, T(" notation=\"%s\""), notationName);
|
|
ftprintf(fp, T(" notation=\"%s\""), notationName);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
@@ -539,7 +770,7 @@ metaEntityDecl(void *userData,
|
|
if (publicId)
|
|
if (publicId)
|
|
ftprintf(fp, T(" public=\"%s\""), publicId);
|
|
ftprintf(fp, T(" public=\"%s\""), publicId);
|
|
fputts(T(" system=\""), fp);
|
|
fputts(T(" system=\""), fp);
|
|
- characterData(fp, systemId, (int)tcslen(systemId));
|
|
|
|
|
|
+ characterData(data, systemId, (int)tcslen(systemId));
|
|
puttc(T('"'), fp);
|
|
puttc(T('"'), fp);
|
|
metaLocation(parser);
|
|
metaLocation(parser);
|
|
fputts(T("/>\n"), fp);
|
|
fputts(T("/>\n"), fp);
|
|
@@ -552,13 +783,14 @@ metaStartNamespaceDecl(void *userData,
|
|
const XML_Char *uri)
|
|
const XML_Char *uri)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
fputts(T("<startns"), fp);
|
|
fputts(T("<startns"), fp);
|
|
if (prefix)
|
|
if (prefix)
|
|
ftprintf(fp, T(" prefix=\"%s\""), prefix);
|
|
ftprintf(fp, T(" prefix=\"%s\""), prefix);
|
|
if (uri) {
|
|
if (uri) {
|
|
fputts(T(" ns=\""), fp);
|
|
fputts(T(" ns=\""), fp);
|
|
- characterData(fp, uri, (int)tcslen(uri));
|
|
|
|
|
|
+ characterData(data, uri, (int)tcslen(uri));
|
|
fputts(T("\"/>\n"), fp);
|
|
fputts(T("\"/>\n"), fp);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -569,7 +801,8 @@ static void XMLCALL
|
|
metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
|
|
metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
|
|
{
|
|
{
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
XML_Parser parser = (XML_Parser) userData;
|
|
- FILE *fp = (FILE *)XML_GetUserData(parser);
|
|
|
|
|
|
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
|
|
|
|
+ FILE *fp = data->fp;
|
|
if (!prefix)
|
|
if (!prefix)
|
|
fputts(T("<endns/>\n"), fp);
|
|
fputts(T("<endns/>\n"), fp);
|
|
else
|
|
else
|
|
@@ -659,10 +892,15 @@ static void
|
|
usage(const XML_Char *prog, int rc)
|
|
usage(const XML_Char *prog, int rc)
|
|
{
|
|
{
|
|
ftprintf(stderr,
|
|
ftprintf(stderr,
|
|
- T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [file ...]\n"), prog);
|
|
|
|
|
|
+ T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [-N] [file ...]\n"), prog);
|
|
exit(rc);
|
|
exit(rc);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(__MINGW32__) && defined(XML_UNICODE)
|
|
|
|
+/* Silence warning about missing prototype */
|
|
|
|
+int wmain(int argc, XML_Char **argv);
|
|
|
|
+#endif
|
|
|
|
+
|
|
int
|
|
int
|
|
tmain(int argc, XML_Char **argv)
|
|
tmain(int argc, XML_Char **argv)
|
|
{
|
|
{
|
|
@@ -674,9 +912,11 @@ tmain(int argc, XML_Char **argv)
|
|
int outputType = 0;
|
|
int outputType = 0;
|
|
int useNamespaces = 0;
|
|
int useNamespaces = 0;
|
|
int requireStandalone = 0;
|
|
int requireStandalone = 0;
|
|
|
|
+ int requiresNotations = 0;
|
|
enum XML_ParamEntityParsing paramEntityParsing =
|
|
enum XML_ParamEntityParsing paramEntityParsing =
|
|
XML_PARAM_ENTITY_PARSING_NEVER;
|
|
XML_PARAM_ENTITY_PARSING_NEVER;
|
|
int useStdin = 0;
|
|
int useStdin = 0;
|
|
|
|
+ XmlwfUserData userData = { NULL, NULL, NULL };
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
#ifdef _MSC_VER
|
|
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
|
|
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
|
|
@@ -731,6 +971,10 @@ tmain(int argc, XML_Char **argv)
|
|
outputType = 't';
|
|
outputType = 't';
|
|
j++;
|
|
j++;
|
|
break;
|
|
break;
|
|
|
|
+ case T('N'):
|
|
|
|
+ requiresNotations = 1;
|
|
|
|
+ j++;
|
|
|
|
+ break;
|
|
case T('d'):
|
|
case T('d'):
|
|
if (argv[i][j + 1] == T('\0')) {
|
|
if (argv[i][j + 1] == T('\0')) {
|
|
if (++i == argc)
|
|
if (++i == argc)
|
|
@@ -776,7 +1020,6 @@ tmain(int argc, XML_Char **argv)
|
|
i--;
|
|
i--;
|
|
}
|
|
}
|
|
for (; i < argc; i++) {
|
|
for (; i < argc; i++) {
|
|
- FILE *fp = 0;
|
|
|
|
XML_Char *outName = 0;
|
|
XML_Char *outName = 0;
|
|
int result;
|
|
int result;
|
|
XML_Parser parser;
|
|
XML_Parser parser;
|
|
@@ -786,7 +1029,7 @@ tmain(int argc, XML_Char **argv)
|
|
parser = XML_ParserCreate(encoding);
|
|
parser = XML_ParserCreate(encoding);
|
|
|
|
|
|
if (! parser) {
|
|
if (! parser) {
|
|
- tperror("Could not instantiate parser");
|
|
|
|
|
|
+ tperror(T("Could not instantiate parser"));
|
|
exit(1);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -825,16 +1068,16 @@ tmain(int argc, XML_Char **argv)
|
|
tcscpy(outName, outputDir);
|
|
tcscpy(outName, outputDir);
|
|
tcscat(outName, delim);
|
|
tcscat(outName, delim);
|
|
tcscat(outName, file);
|
|
tcscat(outName, file);
|
|
- fp = tfopen(outName, T("wb"));
|
|
|
|
- if (!fp) {
|
|
|
|
|
|
+ userData.fp = tfopen(outName, T("wb"));
|
|
|
|
+ if (!userData.fp) {
|
|
tperror(outName);
|
|
tperror(outName);
|
|
exit(1);
|
|
exit(1);
|
|
}
|
|
}
|
|
- setvbuf(fp, NULL, _IOFBF, 16384);
|
|
|
|
|
|
+ setvbuf(userData.fp, NULL, _IOFBF, 16384);
|
|
#ifdef XML_UNICODE
|
|
#ifdef XML_UNICODE
|
|
- puttc(0xFEFF, fp);
|
|
|
|
|
|
+ puttc(0xFEFF, userData.fp);
|
|
#endif
|
|
#endif
|
|
- XML_SetUserData(parser, fp);
|
|
|
|
|
|
+ XML_SetUserData(parser, &userData);
|
|
switch (outputType) {
|
|
switch (outputType) {
|
|
case 'm':
|
|
case 'm':
|
|
XML_UseParserAsHandlerArg(parser);
|
|
XML_UseParserAsHandlerArg(parser);
|
|
@@ -868,6 +1111,10 @@ tmain(int argc, XML_Char **argv)
|
|
XML_SetCharacterDataHandler(parser, characterData);
|
|
XML_SetCharacterDataHandler(parser, characterData);
|
|
#ifndef W3C14N
|
|
#ifndef W3C14N
|
|
XML_SetProcessingInstructionHandler(parser, processingInstruction);
|
|
XML_SetProcessingInstructionHandler(parser, processingInstruction);
|
|
|
|
+ if (requiresNotations) {
|
|
|
|
+ XML_SetDoctypeDeclHandler(parser, startDoctypeDecl, endDoctypeDecl);
|
|
|
|
+ XML_SetNotationDeclHandler(parser, notationDecl);
|
|
|
|
+ }
|
|
#endif /* not W3C14N */
|
|
#endif /* not W3C14N */
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -878,7 +1125,7 @@ tmain(int argc, XML_Char **argv)
|
|
if (outputDir) {
|
|
if (outputDir) {
|
|
if (outputType == 'm')
|
|
if (outputType == 'm')
|
|
metaEndDocument(parser);
|
|
metaEndDocument(parser);
|
|
- fclose(fp);
|
|
|
|
|
|
+ fclose(userData.fp);
|
|
if (!result) {
|
|
if (!result) {
|
|
tremove(outName);
|
|
tremove(outName);
|
|
exit(2);
|
|
exit(2);
|