summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/expat/xmlwf/xmlwf.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/expat/xmlwf/xmlwf.c')
-rw-r--r--3rdparty/expat/xmlwf/xmlwf.c688
1 files changed, 479 insertions, 209 deletions
diff --git a/3rdparty/expat/xmlwf/xmlwf.c b/3rdparty/expat/xmlwf/xmlwf.c
index c4090b0e406..5121fa1028e 100644
--- a/3rdparty/expat/xmlwf/xmlwf.c
+++ b/3rdparty/expat/xmlwf/xmlwf.c
@@ -1,7 +1,36 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -9,25 +38,39 @@
#include "expat.h"
#include "codepage.h"
+#include "internal.h" /* for UNUSED_P only */
#include "xmlfile.h"
#include "xmltchar.h"
#ifdef _MSC_VER
-#include <crtdbg.h>
+# include <crtdbg.h>
#endif
-#if defined(__amigaos__) && defined(__USE_INLINE__)
-#include <proto/expat.h>
+#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. */
#define NSSEP T('\001')
static void XMLCALL
-characterData(void *userData, const XML_Char *s, int len)
-{
- FILE *fp = (FILE *)userData;
+characterData(void *userData, const XML_Char *s, int len) {
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
for (; len > 0; --len, ++s) {
switch (*s) {
case T('&'):
@@ -61,10 +104,10 @@ characterData(void *userData, const XML_Char *s, int len)
}
static void
-attributeValue(FILE *fp, const XML_Char *s)
-{
+attributeValue(FILE *fp, const XML_Char *s) {
puttc(T('='), fp);
puttc(T('"'), fp);
+ assert(s);
for (;;) {
switch (*s) {
case 0:
@@ -112,17 +155,15 @@ attributeValue(FILE *fp, const XML_Char *s)
is equivalent to lexicographically comparing based on the character number. */
static int
-attcmp(const void *att1, const void *att2)
-{
+attcmp(const void *att1, const void *att2) {
return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2);
}
static void XMLCALL
-startElement(void *userData, const XML_Char *name, const XML_Char **atts)
-{
+startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
int nAtts;
const XML_Char **p;
- FILE *fp = (FILE *)userData;
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
puttc(T('<'), fp);
fputts(name, fp);
@@ -142,9 +183,8 @@ startElement(void *userData, const XML_Char *name, const XML_Char **atts)
}
static void XMLCALL
-endElement(void *userData, const XML_Char *name)
-{
- FILE *fp = (FILE *)userData;
+endElement(void *userData, const XML_Char *name) {
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
puttc(T('<'), fp);
puttc(T('/'), fp);
fputts(name, fp);
@@ -152,8 +192,7 @@ endElement(void *userData, const XML_Char *name)
}
static int
-nsattcmp(const void *p1, const void *p2)
-{
+nsattcmp(const void *p1, const void *p2) {
const XML_Char *att1 = *(const XML_Char **)p1;
const XML_Char *att2 = *(const XML_Char **)p2;
int sep1 = (tcsrchr(att1, NSSEP) != 0);
@@ -164,12 +203,11 @@ nsattcmp(const void *p1, const void *p2)
}
static void XMLCALL
-startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
-{
+startElementNS(void *userData, const XML_Char *name, const XML_Char **atts) {
int nAtts;
int nsi;
const XML_Char **p;
- FILE *fp = (FILE *)userData;
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
const XML_Char *sep;
puttc(T('<'), fp);
@@ -180,8 +218,7 @@ startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
fputts(T(" xmlns:n1"), fp);
attributeValue(fp, name);
nsi = 2;
- }
- else {
+ } else {
fputts(name, fp);
nsi = 1;
}
@@ -199,8 +236,7 @@ startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
if (sep) {
ftprintf(fp, T("n%d:"), nsi);
fputts(sep + 1, fp);
- }
- else
+ } else
fputts(name, fp);
attributeValue(fp, *atts);
if (sep) {
@@ -213,9 +249,8 @@ startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
}
static void XMLCALL
-endElementNS(void *userData, const XML_Char *name)
-{
- FILE *fp = (FILE *)userData;
+endElementNS(void *userData, const XML_Char *name) {
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
const XML_Char *sep;
puttc(T('<'), fp);
puttc(T('/'), fp);
@@ -223,8 +258,7 @@ endElementNS(void *userData, const XML_Char *name)
if (sep) {
fputts(T("n1:"), fp);
fputts(sep + 1, fp);
- }
- else
+ } else
fputts(name, fp);
puttc(T('>'), fp);
}
@@ -233,9 +267,8 @@ endElementNS(void *userData, const XML_Char *name)
static void XMLCALL
processingInstruction(void *userData, const XML_Char *target,
- const XML_Char *data)
-{
- FILE *fp = (FILE *)userData;
+ const XML_Char *data) {
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
puttc(T('<'), fp);
puttc(T('?'), fp);
fputts(target, fp);
@@ -245,112 +278,302 @@ processingInstruction(void *userData, const XML_Char *target,
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 *sysid, const XML_Char *publid,
+ int has_internal_subset) {
+ XmlwfUserData *data = (XmlwfUserData *)userData;
+ UNUSED_P(sysid);
+ UNUSED_P(publid);
+ UNUSED_P(has_internal_subset);
+ 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 *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";
+
+ UNUSED_P(base);
+ 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 */
static void XMLCALL
-defaultCharacterData(void *userData, const XML_Char *s, int len)
-{
- XML_DefaultCurrent((XML_Parser) userData);
+defaultCharacterData(void *userData, const XML_Char *s, int len) {
+ UNUSED_P(s);
+ UNUSED_P(len);
+ XML_DefaultCurrent((XML_Parser)userData);
}
static void XMLCALL
defaultStartElement(void *userData, const XML_Char *name,
- const XML_Char **atts)
-{
- XML_DefaultCurrent((XML_Parser) userData);
+ const XML_Char **atts) {
+ UNUSED_P(name);
+ UNUSED_P(atts);
+ XML_DefaultCurrent((XML_Parser)userData);
}
static void XMLCALL
-defaultEndElement(void *userData, const XML_Char *name)
-{
- XML_DefaultCurrent((XML_Parser) userData);
+defaultEndElement(void *userData, const XML_Char *name) {
+ UNUSED_P(name);
+ XML_DefaultCurrent((XML_Parser)userData);
}
static void XMLCALL
defaultProcessingInstruction(void *userData, const XML_Char *target,
- const XML_Char *data)
-{
- XML_DefaultCurrent((XML_Parser) userData);
+ const XML_Char *data) {
+ UNUSED_P(target);
+ UNUSED_P(data);
+ XML_DefaultCurrent((XML_Parser)userData);
}
static void XMLCALL
-nopCharacterData(void *userData, const XML_Char *s, int len)
-{
+nopCharacterData(void *userData, const XML_Char *s, int len) {
+ UNUSED_P(userData);
+ UNUSED_P(s);
+ UNUSED_P(len);
}
static void XMLCALL
-nopStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
-{
+nopStartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
+ UNUSED_P(userData);
+ UNUSED_P(name);
+ UNUSED_P(atts);
}
static void XMLCALL
-nopEndElement(void *userData, const XML_Char *name)
-{
+nopEndElement(void *userData, const XML_Char *name) {
+ UNUSED_P(userData);
+ UNUSED_P(name);
}
static void XMLCALL
nopProcessingInstruction(void *userData, const XML_Char *target,
- const XML_Char *data)
-{
+ const XML_Char *data) {
+ UNUSED_P(userData);
+ UNUSED_P(target);
+ UNUSED_P(data);
}
static void XMLCALL
-markup(void *userData, const XML_Char *s, int len)
-{
- FILE *fp = (FILE *)XML_GetUserData((XML_Parser) userData);
+markup(void *userData, const XML_Char *s, int len) {
+ FILE *fp = ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp;
for (; len > 0; --len, ++s)
puttc(*s, fp);
}
static void
-metaLocation(XML_Parser parser)
-{
+metaLocation(XML_Parser parser) {
const XML_Char *uri = XML_GetBase(parser);
+ FILE *fp = ((XmlwfUserData *)XML_GetUserData(parser))->fp;
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\""),
- XML_GetCurrentByteIndex(parser),
- XML_GetCurrentByteCount(parser),
+ 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_GetCurrentByteCount(parser),
XML_GetCurrentLineNumber(parser),
XML_GetCurrentColumnNumber(parser));
}
static void
-metaStartDocument(void *userData)
-{
- fputts(T("<document>\n"), (FILE *)XML_GetUserData((XML_Parser) userData));
+metaStartDocument(void *userData) {
+ fputts(T("<document>\n"),
+ ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp);
}
static void
-metaEndDocument(void *userData)
-{
- fputts(T("</document>\n"), (FILE *)XML_GetUserData((XML_Parser) userData));
+metaEndDocument(void *userData) {
+ fputts(T("</document>\n"),
+ ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp);
}
static void XMLCALL
-metaStartElement(void *userData, const XML_Char *name,
- const XML_Char **atts)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaStartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
const XML_Char **specifiedAttsEnd
- = atts + XML_GetSpecifiedAttributeCount(parser);
+ = atts + XML_GetSpecifiedAttributeCount(parser);
const XML_Char **idAttPtr;
int idAttIndex = XML_GetIdAttributeIndex(parser);
if (idAttIndex < 0)
idAttPtr = 0;
else
idAttPtr = atts + idAttIndex;
-
+
ftprintf(fp, T("<starttag name=\"%s\""), name);
metaLocation(parser);
if (*atts) {
fputts(T(">\n"), fp);
do {
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)
fputts(T("\" defaulted=\"yes\"/>\n"), fp);
else if (atts == idAttPtr)
@@ -359,16 +582,15 @@ metaStartElement(void *userData, const XML_Char *name,
fputts(T("\"/>\n"), fp);
} while (*(atts += 2));
fputts(T("</starttag>\n"), fp);
- }
- else
+ } else
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaEndElement(void *userData, const XML_Char *name)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaEndElement(void *userData, const XML_Char *name) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
ftprintf(fp, T("<endtag name=\"%s\""), name);
metaLocation(parser);
fputts(T("/>\n"), fp);
@@ -376,145 +598,139 @@ metaEndElement(void *userData, const XML_Char *name)
static void XMLCALL
metaProcessingInstruction(void *userData, const XML_Char *target,
- const XML_Char *data)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+ const XML_Char *data) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = usrData->fp;
ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
- characterData(fp, data, (int)tcslen(data));
+ characterData(usrData, data, (int)tcslen(data));
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaComment(void *userData, const XML_Char *data)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaComment(void *userData, const XML_Char *data) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = usrData->fp;
fputts(T("<comment data=\""), fp);
- characterData(fp, data, (int)tcslen(data));
+ characterData(usrData, data, (int)tcslen(data));
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaStartCdataSection(void *userData)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaStartCdataSection(void *userData) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
fputts(T("<startcdata"), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaEndCdataSection(void *userData)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaEndCdataSection(void *userData) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
fputts(T("<endcdata"), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaCharacterData(void *userData, const XML_Char *s, int len)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaCharacterData(void *userData, const XML_Char *s, int len) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
fputts(T("<chars str=\""), fp);
- characterData(fp, s, len);
+ characterData(data, s, len);
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaStartDoctypeDecl(void *userData,
- const XML_Char *doctypeName,
- const XML_Char *sysid,
- const XML_Char *pubid,
- int has_internal_subset)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaStartDoctypeDecl(void *userData, const XML_Char *doctypeName,
+ const XML_Char *sysid, const XML_Char *pubid,
+ int has_internal_subset) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ UNUSED_P(sysid);
+ UNUSED_P(pubid);
+ UNUSED_P(has_internal_subset);
ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaEndDoctypeDecl(void *userData)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaEndDoctypeDecl(void *userData) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
fputts(T("<enddoctype"), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaNotationDecl(void *userData,
- const XML_Char *notationName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaNotationDecl(void *userData, const XML_Char *notationName,
+ const XML_Char *base, const XML_Char *systemId,
+ const XML_Char *publicId) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ UNUSED_P(base);
ftprintf(fp, T("<notation name=\"%s\""), notationName);
if (publicId)
ftprintf(fp, T(" public=\"%s\""), publicId);
if (systemId) {
fputts(T(" system=\""), fp);
- characterData(fp, systemId, (int)tcslen(systemId));
+ characterData(data, systemId, (int)tcslen(systemId));
puttc(T('"'), fp);
}
metaLocation(parser);
fputts(T("/>\n"), fp);
}
-
static void XMLCALL
-metaEntityDecl(void *userData,
- const XML_Char *entityName,
- int is_param,
- const XML_Char *value,
- int value_length,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaEntityDecl(void *userData, const XML_Char *entityName, int is_param,
+ const XML_Char *value, int value_length, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId,
+ const XML_Char *notationName) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ UNUSED_P(is_param);
+ UNUSED_P(base);
if (value) {
ftprintf(fp, T("<entity name=\"%s\""), entityName);
metaLocation(parser);
puttc(T('>'), fp);
- characterData(fp, value, value_length);
+ characterData(data, value, value_length);
fputts(T("</entity/>\n"), fp);
- }
- else if (notationName) {
+ } else if (notationName) {
ftprintf(fp, T("<entity name=\"%s\""), entityName);
if (publicId)
ftprintf(fp, T(" public=\"%s\""), publicId);
fputts(T(" system=\""), fp);
- characterData(fp, systemId, (int)tcslen(systemId));
+ characterData(data, systemId, (int)tcslen(systemId));
puttc(T('"'), fp);
ftprintf(fp, T(" notation=\"%s\""), notationName);
metaLocation(parser);
fputts(T("/>\n"), fp);
- }
- else {
+ } else {
ftprintf(fp, T("<entity name=\"%s\""), entityName);
if (publicId)
ftprintf(fp, T(" public=\"%s\""), publicId);
fputts(T(" system=\""), fp);
- characterData(fp, systemId, (int)tcslen(systemId));
+ characterData(data, systemId, (int)tcslen(systemId));
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
@@ -522,95 +738,91 @@ metaEntityDecl(void *userData,
}
static void XMLCALL
-metaStartNamespaceDecl(void *userData,
- const XML_Char *prefix,
- const XML_Char *uri)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
+metaStartNamespaceDecl(void *userData, const XML_Char *prefix,
+ const XML_Char *uri) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
fputts(T("<startns"), fp);
if (prefix)
ftprintf(fp, T(" prefix=\"%s\""), prefix);
if (uri) {
fputts(T(" ns=\""), fp);
- characterData(fp, uri, (int)tcslen(uri));
+ characterData(data, uri, (int)tcslen(uri));
fputts(T("\"/>\n"), fp);
- }
- else
+ } else
fputts(T("/>\n"), fp);
}
static void XMLCALL
-metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
-{
- XML_Parser parser = (XML_Parser) userData;
- FILE *fp = (FILE *)XML_GetUserData(parser);
- if (!prefix)
+metaEndNamespaceDecl(void *userData, const XML_Char *prefix) {
+ XML_Parser parser = (XML_Parser)userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ if (! prefix)
fputts(T("<endns/>\n"), fp);
else
ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
}
static int XMLCALL
-unknownEncodingConvert(void *data, const char *p)
-{
+unknownEncodingConvert(void *data, const char *p) {
return codepageConvert(*(int *)data, p);
}
static int XMLCALL
-unknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info)
-{
+unknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info) {
int cp;
static const XML_Char prefixL[] = T("windows-");
static const XML_Char prefixU[] = T("WINDOWS-");
int i;
+ UNUSED_P(userData);
for (i = 0; prefixU[i]; i++)
if (name[i] != prefixU[i] && name[i] != prefixL[i])
return 0;
-
+
cp = 0;
for (; name[i]; i++) {
static const XML_Char digits[] = T("0123456789");
const XML_Char *s = tcschr(digits, name[i]);
- if (!s)
+ if (! s)
return 0;
cp *= 10;
cp += (int)(s - digits);
if (cp >= 0x10000)
return 0;
}
- if (!codepageMap(cp, info->map))
+ if (! codepageMap(cp, info->map))
return 0;
info->convert = unknownEncodingConvert;
/* We could just cast the code page integer to a void *,
and avoid the use of release. */
info->release = free;
info->data = malloc(sizeof(int));
- if (!info->data)
+ if (! info->data)
return 0;
*(int *)info->data = cp;
return 1;
}
static int XMLCALL
-notStandalone(void *userData)
-{
+notStandalone(void *userData) {
+ UNUSED_P(userData);
return 0;
}
static void
-showVersion(XML_Char *prog)
-{
+showVersion(XML_Char *prog) {
XML_Char *s = prog;
XML_Char ch;
const XML_Feature *features = XML_GetFeatureList();
while ((ch = *s) != 0) {
if (ch == '/'
-#if (defined(WIN32) || defined(__WATCOMC__))
+#if defined(_WIN32)
|| ch == '\\'
#endif
- )
+ )
prog = s + 1;
++s;
}
@@ -631,16 +843,56 @@ showVersion(XML_Char *prog)
}
static void
-usage(const XML_Char *prog, int rc)
-{
- ftprintf(stderr,
- T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [file ...]\n"), prog);
+usage(const XML_Char *prog, int rc) {
+ ftprintf(
+ stderr,
+ /* Generated with:
+ * $ xmlwf/xmlwf_helpgen.sh
+ */
+ /* clang-format off */
+ T("usage: %s [-s] [-n] [-p] [-x] [-e ENCODING] [-w] [-r] [-d DIRECTORY]\n")
+ T(" [-c | -m | -t] [-N]\n")
+ T(" [FILE [FILE ...]]\n")
+ T("\n")
+ T("xmlwf - Determines if an XML document is well-formed\n")
+ T("\n")
+ T("positional arguments:\n")
+ T(" FILE file to process (default: STDIN)\n")
+ T("\n")
+ T("input control arguments:\n")
+ T(" -s print an error if the document is not [s]tandalone\n")
+ T(" -n enable [n]amespace processing\n")
+ T(" -p enable processing external DTDs and [p]arameter entities\n")
+ T(" -x enable processing of e[x]ternal entities\n")
+ T(" -e ENCODING override any in-document [e]ncoding declaration\n")
+ T(" -w enable support for [W]indows code pages\n")
+ T(" -r disable memory-mapping and use normal file [r]ead IO calls instead\n")
+ T("\n")
+ T("output control arguments:\n")
+ T(" -d DIRECTORY output [d]estination directory\n")
+ T(" -c write a [c]opy of input XML, not canonical XML\n")
+ T(" -m write [m]eta XML, not canonical XML\n")
+ T(" -t write no XML output for [t]iming of plain parsing\n")
+ T(" -N enable adding doctype and [n]otation declarations\n")
+ T("\n")
+ T("info arguments:\n")
+ T(" -h show this [h]elp message and exit\n")
+ T(" -v show program's [v]ersion number and exit\n")
+ T("\n")
+ T("xmlwf of libexpat is software libre, licensed under the MIT license.\n")
+ T("Please report bugs at https://github.com/libexpat/libexpat/issues. Thank you!\n")
+ , /* clang-format on */
+ prog);
exit(rc);
}
+#if defined(__MINGW32__) && defined(XML_UNICODE)
+/* Silence warning about missing prototype */
+int wmain(int argc, XML_Char **argv);
+#endif
+
int
-tmain(int argc, XML_Char **argv)
-{
+tmain(int argc, XML_Char **argv) {
int i, j;
const XML_Char *outputDir = NULL;
const XML_Char *encoding = NULL;
@@ -649,12 +901,14 @@ tmain(int argc, XML_Char **argv)
int outputType = 0;
int useNamespaces = 0;
int requireStandalone = 0;
- enum XML_ParamEntityParsing paramEntityParsing =
- XML_PARAM_ENTITY_PARSING_NEVER;
+ int requiresNotations = 0;
+ enum XML_ParamEntityParsing paramEntityParsing
+ = XML_PARAM_ENTITY_PARSING_NEVER;
int useStdin = 0;
+ XmlwfUserData userData = {NULL, NULL, NULL};
#ifdef _MSC_VER
- _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
i = 1;
@@ -706,13 +960,16 @@ tmain(int argc, XML_Char **argv)
outputType = 't';
j++;
break;
+ case T('N'):
+ requiresNotations = 1;
+ j++;
+ break;
case T('d'):
if (argv[i][j + 1] == T('\0')) {
if (++i == argc)
usage(argv[0], 2);
outputDir = argv[i];
- }
- else
+ } else
outputDir = argv[i] + j + 1;
i++;
j = 0;
@@ -722,8 +979,7 @@ tmain(int argc, XML_Char **argv)
if (++i == argc)
usage(argv[0], 2);
encoding = argv[i];
- }
- else
+ } else
encoding = argv[i] + j + 1;
i++;
j = 0;
@@ -751,7 +1007,6 @@ tmain(int argc, XML_Char **argv)
i--;
}
for (; i < argc; i++) {
- FILE *fp = 0;
XML_Char *outName = 0;
int result;
XML_Parser parser;
@@ -759,6 +1014,12 @@ tmain(int argc, XML_Char **argv)
parser = XML_ParserCreateNS(encoding, NSSEP);
else
parser = XML_ParserCreate(encoding);
+
+ if (! parser) {
+ tperror(T("Could not instantiate parser"));
+ exit(1);
+ }
+
if (requireStandalone)
XML_SetNotStandaloneHandler(parser, notStandalone);
XML_SetParamEntityParsing(parser, paramEntityParsing);
@@ -769,18 +1030,17 @@ tmain(int argc, XML_Char **argv)
XML_SetElementHandler(parser, nopStartElement, nopEndElement);
XML_SetCharacterDataHandler(parser, nopCharacterData);
XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction);
- }
- else if (outputDir) {
- const XML_Char * delim = T("/");
+ } else if (outputDir) {
+ const XML_Char *delim = T("/");
const XML_Char *file = useStdin ? T("STDIN") : argv[i];
- if (!useStdin) {
+ if (! useStdin) {
/* Jump after last (back)slash */
- const XML_Char * lastDelim = tcsrchr(file, delim[0]);
+ const XML_Char *lastDelim = tcsrchr(file, delim[0]);
if (lastDelim)
file = lastDelim + 1;
-#if (defined(WIN32) || defined(__WATCOMC__))
+#if defined(_WIN32)
else {
- const XML_Char * winDelim = T("\\");
+ const XML_Char *winDelim = T("\\");
lastDelim = tcsrchr(file, winDelim[0]);
if (lastDelim) {
file = lastDelim + 1;
@@ -790,20 +1050,24 @@ tmain(int argc, XML_Char **argv)
#endif
}
outName = (XML_Char *)malloc((tcslen(outputDir) + tcslen(file) + 2)
- * sizeof(XML_Char));
+ * sizeof(XML_Char));
+ if (! outName) {
+ tperror(T("Could not allocate memory"));
+ exit(1);
+ }
tcscpy(outName, outputDir);
tcscat(outName, delim);
tcscat(outName, file);
- fp = tfopen(outName, T("wb"));
- if (!fp) {
+ userData.fp = tfopen(outName, T("wb"));
+ if (! userData.fp) {
tperror(outName);
- exit(1);
+ exit(3);
}
- setvbuf(fp, NULL, _IOFBF, 16384);
+ setvbuf(userData.fp, NULL, _IOFBF, 16384);
#ifdef XML_UNICODE
- puttc(0xFEFF, fp);
+ puttc(0xFEFF, userData.fp);
#endif
- XML_SetUserData(parser, fp);
+ XML_SetUserData(parser, &userData);
switch (outputType) {
case 'm':
XML_UseParserAsHandlerArg(parser);
@@ -837,6 +1101,10 @@ tmain(int argc, XML_Char **argv)
XML_SetCharacterDataHandler(parser, characterData);
#ifndef W3C14N
XML_SetProcessingInstructionHandler(parser, processingInstruction);
+ if (requiresNotations) {
+ XML_SetDoctypeDeclHandler(parser, startDoctypeDecl, endDoctypeDecl);
+ XML_SetNotationDeclHandler(parser, notationDecl);
+ }
#endif /* not W3C14N */
break;
}
@@ -847,14 +1115,16 @@ tmain(int argc, XML_Char **argv)
if (outputDir) {
if (outputType == 'm')
metaEndDocument(parser);
- fclose(fp);
- if (!result) {
+ fclose(userData.fp);
+ if (! result) {
tremove(outName);
- exit(2);
}
free(outName);
}
XML_ParserFree(parser);
+ if (! result) {
+ exit(2);
+ }
}
return 0;
}