diff options
Diffstat (limited to '3rdparty/expat/xmlwf/xmlwf.c')
-rw-r--r-- | 3rdparty/expat/xmlwf/xmlwf.c | 688 |
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; } |