1355604Sdelphij/* 2355604Sdelphij __ __ _ 3355604Sdelphij ___\ \/ /_ __ __ _| |_ 4355604Sdelphij / _ \\ /| '_ \ / _` | __| 5355604Sdelphij | __// \| |_) | (_| | |_ 6355604Sdelphij \___/_/\_\ .__/ \__,_|\__| 7355604Sdelphij |_| XML parser 8355604Sdelphij 9355604Sdelphij Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10355604Sdelphij Copyright (c) 2000-2017 Expat development team 11355604Sdelphij Licensed under the MIT license: 12355604Sdelphij 13355604Sdelphij Permission is hereby granted, free of charge, to any person obtaining 14355604Sdelphij a copy of this software and associated documentation files (the 15355604Sdelphij "Software"), to deal in the Software without restriction, including 16355604Sdelphij without limitation the rights to use, copy, modify, merge, publish, 17355604Sdelphij distribute, sublicense, and/or sell copies of the Software, and to permit 18355604Sdelphij persons to whom the Software is furnished to do so, subject to the 19355604Sdelphij following conditions: 20355604Sdelphij 21355604Sdelphij The above copyright notice and this permission notice shall be included 22355604Sdelphij in all copies or substantial portions of the Software. 23355604Sdelphij 24355604Sdelphij THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25355604Sdelphij EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26355604Sdelphij MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27355604Sdelphij NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28355604Sdelphij DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29355604Sdelphij OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30355604Sdelphij USE OR OTHER DEALINGS IN THE SOFTWARE. 31104349Sphk*/ 32104349Sphk 33355604Sdelphij#include <assert.h> 34104349Sphk#include <stdio.h> 35104349Sphk#include <stdlib.h> 36104349Sphk#include <stddef.h> 37104349Sphk#include <string.h> 38104349Sphk 39104349Sphk#include "expat.h" 40104349Sphk#include "codepage.h" 41355604Sdelphij#include "internal.h" /* for UNUSED_P only */ 42104349Sphk#include "xmlfile.h" 43104349Sphk#include "xmltchar.h" 44104349Sphk 45104349Sphk#ifdef _MSC_VER 46355604Sdelphij# include <crtdbg.h> 47104349Sphk#endif 48104349Sphk 49355604Sdelphij#ifdef XML_UNICODE 50355604Sdelphij# include <wchar.h> 51178848Scokane#endif 52178848Scokane 53355604Sdelphij/* Structures for handler user data */ 54355604Sdelphijtypedef struct NotationList { 55355604Sdelphij struct NotationList *next; 56355604Sdelphij const XML_Char *notationName; 57355604Sdelphij const XML_Char *systemId; 58355604Sdelphij const XML_Char *publicId; 59355604Sdelphij} NotationList; 60355604Sdelphij 61355604Sdelphijtypedef struct xmlwfUserData { 62355604Sdelphij FILE *fp; 63355604Sdelphij NotationList *notationListHead; 64355604Sdelphij const XML_Char *currentDoctypeName; 65355604Sdelphij} XmlwfUserData; 66355604Sdelphij 67104349Sphk/* This ensures proper sorting. */ 68104349Sphk 69104349Sphk#define NSSEP T('\001') 70104349Sphk 71178848Scokanestatic void XMLCALL 72355604SdelphijcharacterData(void *userData, const XML_Char *s, int len) { 73355604Sdelphij FILE *fp = ((XmlwfUserData *)userData)->fp; 74104349Sphk for (; len > 0; --len, ++s) { 75104349Sphk switch (*s) { 76104349Sphk case T('&'): 77104349Sphk fputts(T("&"), fp); 78104349Sphk break; 79104349Sphk case T('<'): 80104349Sphk fputts(T("<"), fp); 81104349Sphk break; 82104349Sphk case T('>'): 83104349Sphk fputts(T(">"), fp); 84104349Sphk break; 85104349Sphk#ifdef W3C14N 86104349Sphk case 13: 87104349Sphk fputts(T("
"), fp); 88104349Sphk break; 89104349Sphk#else 90104349Sphk case T('"'): 91104349Sphk fputts(T("""), fp); 92104349Sphk break; 93104349Sphk case 9: 94104349Sphk case 10: 95104349Sphk case 13: 96104349Sphk ftprintf(fp, T("&#%d;"), *s); 97104349Sphk break; 98104349Sphk#endif 99104349Sphk default: 100104349Sphk puttc(*s, fp); 101104349Sphk break; 102104349Sphk } 103104349Sphk } 104104349Sphk} 105104349Sphk 106104349Sphkstatic void 107355604SdelphijattributeValue(FILE *fp, const XML_Char *s) { 108104349Sphk puttc(T('='), fp); 109104349Sphk puttc(T('"'), fp); 110355604Sdelphij assert(s); 111104349Sphk for (;;) { 112104349Sphk switch (*s) { 113104349Sphk case 0: 114104349Sphk case NSSEP: 115104349Sphk puttc(T('"'), fp); 116104349Sphk return; 117104349Sphk case T('&'): 118104349Sphk fputts(T("&"), fp); 119104349Sphk break; 120104349Sphk case T('<'): 121104349Sphk fputts(T("<"), fp); 122104349Sphk break; 123104349Sphk case T('"'): 124104349Sphk fputts(T("""), fp); 125104349Sphk break; 126104349Sphk#ifdef W3C14N 127104349Sphk case 9: 128104349Sphk fputts(T("	"), fp); 129104349Sphk break; 130104349Sphk case 10: 131104349Sphk fputts(T("
"), fp); 132104349Sphk break; 133104349Sphk case 13: 134104349Sphk fputts(T("
"), fp); 135104349Sphk break; 136104349Sphk#else 137104349Sphk case T('>'): 138104349Sphk fputts(T(">"), fp); 139104349Sphk break; 140104349Sphk case 9: 141104349Sphk case 10: 142104349Sphk case 13: 143104349Sphk ftprintf(fp, T("&#%d;"), *s); 144104349Sphk break; 145104349Sphk#endif 146104349Sphk default: 147104349Sphk puttc(*s, fp); 148104349Sphk break; 149104349Sphk } 150104349Sphk s++; 151104349Sphk } 152104349Sphk} 153104349Sphk 154104349Sphk/* Lexicographically comparing UTF-8 encoded attribute values, 155104349Sphkis equivalent to lexicographically comparing based on the character number. */ 156104349Sphk 157104349Sphkstatic int 158355604Sdelphijattcmp(const void *att1, const void *att2) { 159104349Sphk return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2); 160104349Sphk} 161104349Sphk 162178848Scokanestatic void XMLCALL 163355604SdelphijstartElement(void *userData, const XML_Char *name, const XML_Char **atts) { 164104349Sphk int nAtts; 165104349Sphk const XML_Char **p; 166355604Sdelphij FILE *fp = ((XmlwfUserData *)userData)->fp; 167104349Sphk puttc(T('<'), fp); 168104349Sphk fputts(name, fp); 169104349Sphk 170104349Sphk p = atts; 171104349Sphk while (*p) 172104349Sphk ++p; 173178848Scokane nAtts = (int)((p - atts) >> 1); 174104349Sphk if (nAtts > 1) 175104349Sphk qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp); 176104349Sphk while (*atts) { 177104349Sphk puttc(T(' '), fp); 178104349Sphk fputts(*atts++, fp); 179104349Sphk attributeValue(fp, *atts); 180104349Sphk atts++; 181104349Sphk } 182104349Sphk puttc(T('>'), fp); 183104349Sphk} 184104349Sphk 185178848Scokanestatic void XMLCALL 186355604SdelphijendElement(void *userData, const XML_Char *name) { 187355604Sdelphij FILE *fp = ((XmlwfUserData *)userData)->fp; 188104349Sphk puttc(T('<'), fp); 189104349Sphk puttc(T('/'), fp); 190104349Sphk fputts(name, fp); 191104349Sphk puttc(T('>'), fp); 192104349Sphk} 193104349Sphk 194104349Sphkstatic int 195355604Sdelphijnsattcmp(const void *p1, const void *p2) { 196104349Sphk const XML_Char *att1 = *(const XML_Char **)p1; 197104349Sphk const XML_Char *att2 = *(const XML_Char **)p2; 198104349Sphk int sep1 = (tcsrchr(att1, NSSEP) != 0); 199104349Sphk int sep2 = (tcsrchr(att1, NSSEP) != 0); 200104349Sphk if (sep1 != sep2) 201104349Sphk return sep1 - sep2; 202104349Sphk return tcscmp(att1, att2); 203104349Sphk} 204104349Sphk 205178848Scokanestatic void XMLCALL 206355604SdelphijstartElementNS(void *userData, const XML_Char *name, const XML_Char **atts) { 207104349Sphk int nAtts; 208104349Sphk int nsi; 209104349Sphk const XML_Char **p; 210355604Sdelphij FILE *fp = ((XmlwfUserData *)userData)->fp; 211104349Sphk const XML_Char *sep; 212104349Sphk puttc(T('<'), fp); 213104349Sphk 214104349Sphk sep = tcsrchr(name, NSSEP); 215104349Sphk if (sep) { 216104349Sphk fputts(T("n1:"), fp); 217104349Sphk fputts(sep + 1, fp); 218104349Sphk fputts(T(" xmlns:n1"), fp); 219104349Sphk attributeValue(fp, name); 220104349Sphk nsi = 2; 221355604Sdelphij } else { 222104349Sphk fputts(name, fp); 223104349Sphk nsi = 1; 224104349Sphk } 225104349Sphk 226104349Sphk p = atts; 227104349Sphk while (*p) 228104349Sphk ++p; 229178848Scokane nAtts = (int)((p - atts) >> 1); 230104349Sphk if (nAtts > 1) 231104349Sphk qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp); 232104349Sphk while (*atts) { 233104349Sphk name = *atts++; 234104349Sphk sep = tcsrchr(name, NSSEP); 235104349Sphk puttc(T(' '), fp); 236104349Sphk if (sep) { 237104349Sphk ftprintf(fp, T("n%d:"), nsi); 238104349Sphk fputts(sep + 1, fp); 239355604Sdelphij } else 240104349Sphk fputts(name, fp); 241104349Sphk attributeValue(fp, *atts); 242104349Sphk if (sep) { 243104349Sphk ftprintf(fp, T(" xmlns:n%d"), nsi++); 244104349Sphk attributeValue(fp, name); 245104349Sphk } 246104349Sphk atts++; 247104349Sphk } 248104349Sphk puttc(T('>'), fp); 249104349Sphk} 250104349Sphk 251178848Scokanestatic void XMLCALL 252355604SdelphijendElementNS(void *userData, const XML_Char *name) { 253355604Sdelphij FILE *fp = ((XmlwfUserData *)userData)->fp; 254104349Sphk const XML_Char *sep; 255104349Sphk puttc(T('<'), fp); 256104349Sphk puttc(T('/'), fp); 257104349Sphk sep = tcsrchr(name, NSSEP); 258104349Sphk if (sep) { 259104349Sphk fputts(T("n1:"), fp); 260104349Sphk fputts(sep + 1, fp); 261355604Sdelphij } else 262104349Sphk fputts(name, fp); 263104349Sphk puttc(T('>'), fp); 264104349Sphk} 265104349Sphk 266104349Sphk#ifndef W3C14N 267104349Sphk 268178848Scokanestatic void XMLCALL 269104349SphkprocessingInstruction(void *userData, const XML_Char *target, 270355604Sdelphij const XML_Char *data) { 271355604Sdelphij FILE *fp = ((XmlwfUserData *)userData)->fp; 272104349Sphk puttc(T('<'), fp); 273104349Sphk puttc(T('?'), fp); 274104349Sphk fputts(target, fp); 275104349Sphk puttc(T(' '), fp); 276104349Sphk fputts(data, fp); 277104349Sphk puttc(T('?'), fp); 278104349Sphk puttc(T('>'), fp); 279104349Sphk} 280104349Sphk 281355604Sdelphijstatic XML_Char * 282355604Sdelphijxcsdup(const XML_Char *s) { 283355604Sdelphij XML_Char *result; 284355604Sdelphij int count = 0; 285355604Sdelphij int numBytes; 286355604Sdelphij 287355604Sdelphij /* Get the length of the string, including terminator */ 288355604Sdelphij while (s[count++] != 0) { 289355604Sdelphij /* Do nothing */ 290355604Sdelphij } 291355604Sdelphij numBytes = count * sizeof(XML_Char); 292355604Sdelphij result = malloc(numBytes); 293355604Sdelphij if (result == NULL) 294355604Sdelphij return NULL; 295355604Sdelphij memcpy(result, s, numBytes); 296355604Sdelphij return result; 297355604Sdelphij} 298355604Sdelphij 299355604Sdelphijstatic void XMLCALL 300355604SdelphijstartDoctypeDecl(void *userData, const XML_Char *doctypeName, 301355604Sdelphij const XML_Char *sysid, const XML_Char *publid, 302355604Sdelphij int has_internal_subset) { 303355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)userData; 304355604Sdelphij UNUSED_P(sysid); 305355604Sdelphij UNUSED_P(publid); 306355604Sdelphij UNUSED_P(has_internal_subset); 307355604Sdelphij data->currentDoctypeName = xcsdup(doctypeName); 308355604Sdelphij} 309355604Sdelphij 310355604Sdelphijstatic void 311355604SdelphijfreeNotations(XmlwfUserData *data) { 312355604Sdelphij NotationList *notationListHead = data->notationListHead; 313355604Sdelphij 314355604Sdelphij while (notationListHead != NULL) { 315355604Sdelphij NotationList *next = notationListHead->next; 316355604Sdelphij free((void *)notationListHead->notationName); 317355604Sdelphij free((void *)notationListHead->systemId); 318355604Sdelphij free((void *)notationListHead->publicId); 319355604Sdelphij free(notationListHead); 320355604Sdelphij notationListHead = next; 321355604Sdelphij } 322355604Sdelphij data->notationListHead = NULL; 323355604Sdelphij} 324355604Sdelphij 325355604Sdelphijstatic int 326355604Sdelphijxcscmp(const XML_Char *xs, const XML_Char *xt) { 327355604Sdelphij while (*xs != 0 && *xt != 0) { 328355604Sdelphij if (*xs < *xt) 329355604Sdelphij return -1; 330355604Sdelphij if (*xs > *xt) 331355604Sdelphij return 1; 332355604Sdelphij xs++; 333355604Sdelphij xt++; 334355604Sdelphij } 335355604Sdelphij if (*xs < *xt) 336355604Sdelphij return -1; 337355604Sdelphij if (*xs > *xt) 338355604Sdelphij return 1; 339355604Sdelphij return 0; 340355604Sdelphij} 341355604Sdelphij 342355604Sdelphijstatic int 343355604SdelphijnotationCmp(const void *a, const void *b) { 344355604Sdelphij const NotationList *const n1 = *(NotationList **)a; 345355604Sdelphij const NotationList *const n2 = *(NotationList **)b; 346355604Sdelphij 347355604Sdelphij return xcscmp(n1->notationName, n2->notationName); 348355604Sdelphij} 349355604Sdelphij 350355604Sdelphijstatic void XMLCALL 351355604SdelphijendDoctypeDecl(void *userData) { 352355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)userData; 353355604Sdelphij NotationList **notations; 354355604Sdelphij int notationCount = 0; 355355604Sdelphij NotationList *p; 356355604Sdelphij int i; 357355604Sdelphij 358355604Sdelphij /* How many notations do we have? */ 359355604Sdelphij for (p = data->notationListHead; p != NULL; p = p->next) 360355604Sdelphij notationCount++; 361355604Sdelphij if (notationCount == 0) { 362355604Sdelphij /* Nothing to report */ 363355604Sdelphij free((void *)data->currentDoctypeName); 364355604Sdelphij data->currentDoctypeName = NULL; 365355604Sdelphij return; 366355604Sdelphij } 367355604Sdelphij 368355604Sdelphij notations = malloc(notationCount * sizeof(NotationList *)); 369355604Sdelphij if (notations == NULL) { 370355604Sdelphij fprintf(stderr, "Unable to sort notations"); 371355604Sdelphij freeNotations(data); 372355604Sdelphij return; 373355604Sdelphij } 374355604Sdelphij 375355604Sdelphij for (p = data->notationListHead, i = 0; i < notationCount; p = p->next, i++) { 376355604Sdelphij notations[i] = p; 377355604Sdelphij } 378355604Sdelphij qsort(notations, notationCount, sizeof(NotationList *), notationCmp); 379355604Sdelphij 380355604Sdelphij /* Output the DOCTYPE header */ 381355604Sdelphij fputts(T("<!DOCTYPE "), data->fp); 382355604Sdelphij fputts(data->currentDoctypeName, data->fp); 383355604Sdelphij fputts(T(" [\n"), data->fp); 384355604Sdelphij 385355604Sdelphij /* Now the NOTATIONs */ 386355604Sdelphij for (i = 0; i < notationCount; i++) { 387355604Sdelphij fputts(T("<!NOTATION "), data->fp); 388355604Sdelphij fputts(notations[i]->notationName, data->fp); 389355604Sdelphij if (notations[i]->publicId != NULL) { 390355604Sdelphij fputts(T(" PUBLIC '"), data->fp); 391355604Sdelphij fputts(notations[i]->publicId, data->fp); 392355604Sdelphij puttc(T('\''), data->fp); 393355604Sdelphij if (notations[i]->systemId != NULL) { 394355604Sdelphij puttc(T(' '), data->fp); 395355604Sdelphij puttc(T('\''), data->fp); 396355604Sdelphij fputts(notations[i]->systemId, data->fp); 397355604Sdelphij puttc(T('\''), data->fp); 398355604Sdelphij } 399355604Sdelphij } else if (notations[i]->systemId != NULL) { 400355604Sdelphij fputts(T(" SYSTEM '"), data->fp); 401355604Sdelphij fputts(notations[i]->systemId, data->fp); 402355604Sdelphij puttc(T('\''), data->fp); 403355604Sdelphij } 404355604Sdelphij puttc(T('>'), data->fp); 405355604Sdelphij puttc(T('\n'), data->fp); 406355604Sdelphij } 407355604Sdelphij 408355604Sdelphij /* Finally end the DOCTYPE */ 409355604Sdelphij fputts(T("]>\n"), data->fp); 410355604Sdelphij 411355604Sdelphij free(notations); 412355604Sdelphij freeNotations(data); 413355604Sdelphij free((void *)data->currentDoctypeName); 414355604Sdelphij data->currentDoctypeName = NULL; 415355604Sdelphij} 416355604Sdelphij 417355604Sdelphijstatic void XMLCALL 418355604SdelphijnotationDecl(void *userData, const XML_Char *notationName, const XML_Char *base, 419355604Sdelphij const XML_Char *systemId, const XML_Char *publicId) { 420355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)userData; 421355604Sdelphij NotationList *entry = malloc(sizeof(NotationList)); 422355604Sdelphij const char *errorMessage = "Unable to store NOTATION for output\n"; 423355604Sdelphij 424355604Sdelphij UNUSED_P(base); 425355604Sdelphij if (entry == NULL) { 426355604Sdelphij fputs(errorMessage, stderr); 427355604Sdelphij return; /* Nothing we can really do about this */ 428355604Sdelphij } 429355604Sdelphij entry->notationName = xcsdup(notationName); 430355604Sdelphij if (entry->notationName == NULL) { 431355604Sdelphij fputs(errorMessage, stderr); 432355604Sdelphij free(entry); 433355604Sdelphij return; 434355604Sdelphij } 435355604Sdelphij if (systemId != NULL) { 436355604Sdelphij entry->systemId = xcsdup(systemId); 437355604Sdelphij if (entry->systemId == NULL) { 438355604Sdelphij fputs(errorMessage, stderr); 439355604Sdelphij free((void *)entry->notationName); 440355604Sdelphij free(entry); 441355604Sdelphij return; 442355604Sdelphij } 443355604Sdelphij } else { 444355604Sdelphij entry->systemId = NULL; 445355604Sdelphij } 446355604Sdelphij if (publicId != NULL) { 447355604Sdelphij entry->publicId = xcsdup(publicId); 448355604Sdelphij if (entry->publicId == NULL) { 449355604Sdelphij fputs(errorMessage, stderr); 450355604Sdelphij free((void *)entry->systemId); /* Safe if it's NULL */ 451355604Sdelphij free((void *)entry->notationName); 452355604Sdelphij free(entry); 453355604Sdelphij return; 454355604Sdelphij } 455355604Sdelphij } else { 456355604Sdelphij entry->publicId = NULL; 457355604Sdelphij } 458355604Sdelphij 459355604Sdelphij entry->next = data->notationListHead; 460355604Sdelphij data->notationListHead = entry; 461355604Sdelphij} 462355604Sdelphij 463104349Sphk#endif /* not W3C14N */ 464104349Sphk 465178848Scokanestatic void XMLCALL 466355604SdelphijdefaultCharacterData(void *userData, const XML_Char *s, int len) { 467355604Sdelphij UNUSED_P(s); 468355604Sdelphij UNUSED_P(len); 469355604Sdelphij XML_DefaultCurrent((XML_Parser)userData); 470104349Sphk} 471104349Sphk 472178848Scokanestatic void XMLCALL 473355604SdelphijdefaultStartElement(void *userData, const XML_Char *name, 474355604Sdelphij const XML_Char **atts) { 475355604Sdelphij UNUSED_P(name); 476355604Sdelphij UNUSED_P(atts); 477355604Sdelphij XML_DefaultCurrent((XML_Parser)userData); 478104349Sphk} 479104349Sphk 480178848Scokanestatic void XMLCALL 481355604SdelphijdefaultEndElement(void *userData, const XML_Char *name) { 482355604Sdelphij UNUSED_P(name); 483355604Sdelphij XML_DefaultCurrent((XML_Parser)userData); 484104349Sphk} 485104349Sphk 486178848Scokanestatic void XMLCALL 487355604SdelphijdefaultProcessingInstruction(void *userData, const XML_Char *target, 488355604Sdelphij const XML_Char *data) { 489355604Sdelphij UNUSED_P(target); 490355604Sdelphij UNUSED_P(data); 491355604Sdelphij XML_DefaultCurrent((XML_Parser)userData); 492104349Sphk} 493104349Sphk 494178848Scokanestatic void XMLCALL 495355604SdelphijnopCharacterData(void *userData, const XML_Char *s, int len) { 496355604Sdelphij UNUSED_P(userData); 497355604Sdelphij UNUSED_P(s); 498355604Sdelphij UNUSED_P(len); 499104349Sphk} 500104349Sphk 501178848Scokanestatic void XMLCALL 502355604SdelphijnopStartElement(void *userData, const XML_Char *name, const XML_Char **atts) { 503355604Sdelphij UNUSED_P(userData); 504355604Sdelphij UNUSED_P(name); 505355604Sdelphij UNUSED_P(atts); 506104349Sphk} 507104349Sphk 508178848Scokanestatic void XMLCALL 509355604SdelphijnopEndElement(void *userData, const XML_Char *name) { 510355604Sdelphij UNUSED_P(userData); 511355604Sdelphij UNUSED_P(name); 512104349Sphk} 513104349Sphk 514178848Scokanestatic void XMLCALL 515355604SdelphijnopProcessingInstruction(void *userData, const XML_Char *target, 516355604Sdelphij const XML_Char *data) { 517355604Sdelphij UNUSED_P(userData); 518355604Sdelphij UNUSED_P(target); 519355604Sdelphij UNUSED_P(data); 520104349Sphk} 521104349Sphk 522178848Scokanestatic void XMLCALL 523355604Sdelphijmarkup(void *userData, const XML_Char *s, int len) { 524355604Sdelphij FILE *fp = ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp; 525104349Sphk for (; len > 0; --len, ++s) 526104349Sphk puttc(*s, fp); 527104349Sphk} 528104349Sphk 529104349Sphkstatic void 530355604SdelphijmetaLocation(XML_Parser parser) { 531104349Sphk const XML_Char *uri = XML_GetBase(parser); 532355604Sdelphij FILE *fp = ((XmlwfUserData *)XML_GetUserData(parser))->fp; 533104349Sphk if (uri) 534355604Sdelphij ftprintf(fp, T(" uri=\"%s\""), uri); 535355604Sdelphij ftprintf(fp, 536355604Sdelphij T(" byte=\"%") T(XML_FMT_INT_MOD) T("d\"") T(" nbytes=\"%d\"") 537355604Sdelphij T(" line=\"%") T(XML_FMT_INT_MOD) T("u\"") T(" col=\"%") 538355604Sdelphij T(XML_FMT_INT_MOD) T("u\""), 539355604Sdelphij XML_GetCurrentByteIndex(parser), XML_GetCurrentByteCount(parser), 540104349Sphk XML_GetCurrentLineNumber(parser), 541104349Sphk XML_GetCurrentColumnNumber(parser)); 542104349Sphk} 543104349Sphk 544104349Sphkstatic void 545355604SdelphijmetaStartDocument(void *userData) { 546355604Sdelphij fputts(T("<document>\n"), 547355604Sdelphij ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp); 548104349Sphk} 549104349Sphk 550104349Sphkstatic void 551355604SdelphijmetaEndDocument(void *userData) { 552355604Sdelphij fputts(T("</document>\n"), 553355604Sdelphij ((XmlwfUserData *)XML_GetUserData((XML_Parser)userData))->fp); 554104349Sphk} 555104349Sphk 556178848Scokanestatic void XMLCALL 557355604SdelphijmetaStartElement(void *userData, const XML_Char *name, const XML_Char **atts) { 558355604Sdelphij XML_Parser parser = (XML_Parser)userData; 559355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 560355604Sdelphij FILE *fp = data->fp; 561104349Sphk const XML_Char **specifiedAttsEnd 562355604Sdelphij = atts + XML_GetSpecifiedAttributeCount(parser); 563104349Sphk const XML_Char **idAttPtr; 564104349Sphk int idAttIndex = XML_GetIdAttributeIndex(parser); 565104349Sphk if (idAttIndex < 0) 566104349Sphk idAttPtr = 0; 567104349Sphk else 568104349Sphk idAttPtr = atts + idAttIndex; 569355604Sdelphij 570104349Sphk ftprintf(fp, T("<starttag name=\"%s\""), name); 571104349Sphk metaLocation(parser); 572104349Sphk if (*atts) { 573104349Sphk fputts(T(">\n"), fp); 574104349Sphk do { 575104349Sphk ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]); 576355604Sdelphij characterData(data, atts[1], (int)tcslen(atts[1])); 577104349Sphk if (atts >= specifiedAttsEnd) 578104349Sphk fputts(T("\" defaulted=\"yes\"/>\n"), fp); 579104349Sphk else if (atts == idAttPtr) 580104349Sphk fputts(T("\" id=\"yes\"/>\n"), fp); 581104349Sphk else 582104349Sphk fputts(T("\"/>\n"), fp); 583104349Sphk } while (*(atts += 2)); 584104349Sphk fputts(T("</starttag>\n"), fp); 585355604Sdelphij } else 586104349Sphk fputts(T("/>\n"), fp); 587104349Sphk} 588104349Sphk 589178848Scokanestatic void XMLCALL 590355604SdelphijmetaEndElement(void *userData, const XML_Char *name) { 591355604Sdelphij XML_Parser parser = (XML_Parser)userData; 592355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 593355604Sdelphij FILE *fp = data->fp; 594104349Sphk ftprintf(fp, T("<endtag name=\"%s\""), name); 595104349Sphk metaLocation(parser); 596104349Sphk fputts(T("/>\n"), fp); 597104349Sphk} 598104349Sphk 599178848Scokanestatic void XMLCALL 600104349SphkmetaProcessingInstruction(void *userData, const XML_Char *target, 601355604Sdelphij const XML_Char *data) { 602355604Sdelphij XML_Parser parser = (XML_Parser)userData; 603355604Sdelphij XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser); 604355604Sdelphij FILE *fp = usrData->fp; 605104349Sphk ftprintf(fp, T("<pi target=\"%s\" data=\""), target); 606355604Sdelphij characterData(usrData, data, (int)tcslen(data)); 607104349Sphk puttc(T('"'), fp); 608104349Sphk metaLocation(parser); 609104349Sphk fputts(T("/>\n"), fp); 610104349Sphk} 611104349Sphk 612178848Scokanestatic void XMLCALL 613355604SdelphijmetaComment(void *userData, const XML_Char *data) { 614355604Sdelphij XML_Parser parser = (XML_Parser)userData; 615355604Sdelphij XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser); 616355604Sdelphij FILE *fp = usrData->fp; 617104349Sphk fputts(T("<comment data=\""), fp); 618355604Sdelphij characterData(usrData, data, (int)tcslen(data)); 619104349Sphk puttc(T('"'), fp); 620104349Sphk metaLocation(parser); 621104349Sphk fputts(T("/>\n"), fp); 622104349Sphk} 623104349Sphk 624178848Scokanestatic void XMLCALL 625355604SdelphijmetaStartCdataSection(void *userData) { 626355604Sdelphij XML_Parser parser = (XML_Parser)userData; 627355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 628355604Sdelphij FILE *fp = data->fp; 629104349Sphk fputts(T("<startcdata"), fp); 630104349Sphk metaLocation(parser); 631104349Sphk fputts(T("/>\n"), fp); 632104349Sphk} 633104349Sphk 634178848Scokanestatic void XMLCALL 635355604SdelphijmetaEndCdataSection(void *userData) { 636355604Sdelphij XML_Parser parser = (XML_Parser)userData; 637355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 638355604Sdelphij FILE *fp = data->fp; 639104349Sphk fputts(T("<endcdata"), fp); 640104349Sphk metaLocation(parser); 641104349Sphk fputts(T("/>\n"), fp); 642104349Sphk} 643104349Sphk 644178848Scokanestatic void XMLCALL 645355604SdelphijmetaCharacterData(void *userData, const XML_Char *s, int len) { 646355604Sdelphij XML_Parser parser = (XML_Parser)userData; 647355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 648355604Sdelphij FILE *fp = data->fp; 649104349Sphk fputts(T("<chars str=\""), fp); 650355604Sdelphij characterData(data, s, len); 651104349Sphk puttc(T('"'), fp); 652104349Sphk metaLocation(parser); 653104349Sphk fputts(T("/>\n"), fp); 654104349Sphk} 655104349Sphk 656178848Scokanestatic void XMLCALL 657355604SdelphijmetaStartDoctypeDecl(void *userData, const XML_Char *doctypeName, 658355604Sdelphij const XML_Char *sysid, const XML_Char *pubid, 659355604Sdelphij int has_internal_subset) { 660355604Sdelphij XML_Parser parser = (XML_Parser)userData; 661355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 662355604Sdelphij FILE *fp = data->fp; 663355604Sdelphij UNUSED_P(sysid); 664355604Sdelphij UNUSED_P(pubid); 665355604Sdelphij UNUSED_P(has_internal_subset); 666104349Sphk ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName); 667104349Sphk metaLocation(parser); 668104349Sphk fputts(T("/>\n"), fp); 669104349Sphk} 670104349Sphk 671178848Scokanestatic void XMLCALL 672355604SdelphijmetaEndDoctypeDecl(void *userData) { 673355604Sdelphij XML_Parser parser = (XML_Parser)userData; 674355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 675355604Sdelphij FILE *fp = data->fp; 676104349Sphk fputts(T("<enddoctype"), fp); 677104349Sphk metaLocation(parser); 678104349Sphk fputts(T("/>\n"), fp); 679104349Sphk} 680104349Sphk 681178848Scokanestatic void XMLCALL 682355604SdelphijmetaNotationDecl(void *userData, const XML_Char *notationName, 683355604Sdelphij const XML_Char *base, const XML_Char *systemId, 684355604Sdelphij const XML_Char *publicId) { 685355604Sdelphij XML_Parser parser = (XML_Parser)userData; 686355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 687355604Sdelphij FILE *fp = data->fp; 688355604Sdelphij UNUSED_P(base); 689104349Sphk ftprintf(fp, T("<notation name=\"%s\""), notationName); 690104349Sphk if (publicId) 691104349Sphk ftprintf(fp, T(" public=\"%s\""), publicId); 692104349Sphk if (systemId) { 693104349Sphk fputts(T(" system=\""), fp); 694355604Sdelphij characterData(data, systemId, (int)tcslen(systemId)); 695104349Sphk puttc(T('"'), fp); 696104349Sphk } 697104349Sphk metaLocation(parser); 698104349Sphk fputts(T("/>\n"), fp); 699104349Sphk} 700104349Sphk 701178848Scokanestatic void XMLCALL 702355604SdelphijmetaEntityDecl(void *userData, const XML_Char *entityName, int is_param, 703355604Sdelphij const XML_Char *value, int value_length, const XML_Char *base, 704355604Sdelphij const XML_Char *systemId, const XML_Char *publicId, 705355604Sdelphij const XML_Char *notationName) { 706355604Sdelphij XML_Parser parser = (XML_Parser)userData; 707355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 708355604Sdelphij FILE *fp = data->fp; 709104349Sphk 710355604Sdelphij UNUSED_P(is_param); 711355604Sdelphij UNUSED_P(base); 712104349Sphk if (value) { 713104349Sphk ftprintf(fp, T("<entity name=\"%s\""), entityName); 714104349Sphk metaLocation(parser); 715104349Sphk puttc(T('>'), fp); 716355604Sdelphij characterData(data, value, value_length); 717104349Sphk fputts(T("</entity/>\n"), fp); 718355604Sdelphij } else if (notationName) { 719104349Sphk ftprintf(fp, T("<entity name=\"%s\""), entityName); 720104349Sphk if (publicId) 721104349Sphk ftprintf(fp, T(" public=\"%s\""), publicId); 722104349Sphk fputts(T(" system=\""), fp); 723355604Sdelphij characterData(data, systemId, (int)tcslen(systemId)); 724104349Sphk puttc(T('"'), fp); 725104349Sphk ftprintf(fp, T(" notation=\"%s\""), notationName); 726104349Sphk metaLocation(parser); 727104349Sphk fputts(T("/>\n"), fp); 728355604Sdelphij } else { 729104349Sphk ftprintf(fp, T("<entity name=\"%s\""), entityName); 730104349Sphk if (publicId) 731104349Sphk ftprintf(fp, T(" public=\"%s\""), publicId); 732104349Sphk fputts(T(" system=\""), fp); 733355604Sdelphij characterData(data, systemId, (int)tcslen(systemId)); 734104349Sphk puttc(T('"'), fp); 735104349Sphk metaLocation(parser); 736104349Sphk fputts(T("/>\n"), fp); 737104349Sphk } 738104349Sphk} 739104349Sphk 740178848Scokanestatic void XMLCALL 741355604SdelphijmetaStartNamespaceDecl(void *userData, const XML_Char *prefix, 742355604Sdelphij const XML_Char *uri) { 743355604Sdelphij XML_Parser parser = (XML_Parser)userData; 744355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 745355604Sdelphij FILE *fp = data->fp; 746104349Sphk fputts(T("<startns"), fp); 747104349Sphk if (prefix) 748104349Sphk ftprintf(fp, T(" prefix=\"%s\""), prefix); 749104349Sphk if (uri) { 750104349Sphk fputts(T(" ns=\""), fp); 751355604Sdelphij characterData(data, uri, (int)tcslen(uri)); 752104349Sphk fputts(T("\"/>\n"), fp); 753355604Sdelphij } else 754104349Sphk fputts(T("/>\n"), fp); 755104349Sphk} 756104349Sphk 757178848Scokanestatic void XMLCALL 758355604SdelphijmetaEndNamespaceDecl(void *userData, const XML_Char *prefix) { 759355604Sdelphij XML_Parser parser = (XML_Parser)userData; 760355604Sdelphij XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser); 761355604Sdelphij FILE *fp = data->fp; 762355604Sdelphij if (! prefix) 763104349Sphk fputts(T("<endns/>\n"), fp); 764104349Sphk else 765104349Sphk ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix); 766104349Sphk} 767104349Sphk 768178848Scokanestatic int XMLCALL 769355604SdelphijunknownEncodingConvert(void *data, const char *p) { 770104349Sphk return codepageConvert(*(int *)data, p); 771104349Sphk} 772104349Sphk 773178848Scokanestatic int XMLCALL 774355604SdelphijunknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info) { 775104349Sphk int cp; 776104349Sphk static const XML_Char prefixL[] = T("windows-"); 777104349Sphk static const XML_Char prefixU[] = T("WINDOWS-"); 778104349Sphk int i; 779104349Sphk 780355604Sdelphij UNUSED_P(userData); 781104349Sphk for (i = 0; prefixU[i]; i++) 782104349Sphk if (name[i] != prefixU[i] && name[i] != prefixL[i]) 783104349Sphk return 0; 784355604Sdelphij 785104349Sphk cp = 0; 786104349Sphk for (; name[i]; i++) { 787104349Sphk static const XML_Char digits[] = T("0123456789"); 788104349Sphk const XML_Char *s = tcschr(digits, name[i]); 789355604Sdelphij if (! s) 790104349Sphk return 0; 791104349Sphk cp *= 10; 792178848Scokane cp += (int)(s - digits); 793104349Sphk if (cp >= 0x10000) 794104349Sphk return 0; 795104349Sphk } 796355604Sdelphij if (! codepageMap(cp, info->map)) 797104349Sphk return 0; 798104349Sphk info->convert = unknownEncodingConvert; 799104349Sphk /* We could just cast the code page integer to a void *, 800104349Sphk and avoid the use of release. */ 801104349Sphk info->release = free; 802104349Sphk info->data = malloc(sizeof(int)); 803355604Sdelphij if (! info->data) 804104349Sphk return 0; 805104349Sphk *(int *)info->data = cp; 806104349Sphk return 1; 807104349Sphk} 808104349Sphk 809178848Scokanestatic int XMLCALL 810355604SdelphijnotStandalone(void *userData) { 811355604Sdelphij UNUSED_P(userData); 812104349Sphk return 0; 813104349Sphk} 814104349Sphk 815104349Sphkstatic void 816355604SdelphijshowVersion(XML_Char *prog) { 817104349Sphk XML_Char *s = prog; 818104349Sphk XML_Char ch; 819104349Sphk const XML_Feature *features = XML_GetFeatureList(); 820104349Sphk while ((ch = *s) != 0) { 821104349Sphk if (ch == '/' 822355604Sdelphij#if defined(_WIN32) 823104349Sphk || ch == '\\' 824104349Sphk#endif 825355604Sdelphij ) 826104349Sphk prog = s + 1; 827104349Sphk ++s; 828104349Sphk } 829104349Sphk ftprintf(stdout, T("%s using %s\n"), prog, XML_ExpatVersion()); 830104349Sphk if (features != NULL && features[0].feature != XML_FEATURE_END) { 831104349Sphk int i = 1; 832104349Sphk ftprintf(stdout, T("%s"), features[0].name); 833104349Sphk if (features[0].value) 834104349Sphk ftprintf(stdout, T("=%ld"), features[0].value); 835104349Sphk while (features[i].feature != XML_FEATURE_END) { 836104349Sphk ftprintf(stdout, T(", %s"), features[i].name); 837104349Sphk if (features[i].value) 838104349Sphk ftprintf(stdout, T("=%ld"), features[i].value); 839104349Sphk ++i; 840104349Sphk } 841104349Sphk ftprintf(stdout, T("\n")); 842104349Sphk } 843104349Sphk} 844104349Sphk 845104349Sphkstatic void 846355604Sdelphijusage(const XML_Char *prog, int rc) { 847355604Sdelphij ftprintf( 848355604Sdelphij stderr, 849355604Sdelphij /* Generated with: 850355604Sdelphij * $ xmlwf/xmlwf_helpgen.sh 851355604Sdelphij */ 852355604Sdelphij /* clang-format off */ 853355604Sdelphij T("usage: %s [-s] [-n] [-p] [-x] [-e ENCODING] [-w] [-r] [-d DIRECTORY]\n") 854355604Sdelphij T(" [-c | -m | -t] [-N]\n") 855355604Sdelphij T(" [FILE [FILE ...]]\n") 856355604Sdelphij T("\n") 857355604Sdelphij T("xmlwf - Determines if an XML document is well-formed\n") 858355604Sdelphij T("\n") 859355604Sdelphij T("positional arguments:\n") 860355604Sdelphij T(" FILE files to process (default: STDIN)\n") 861355604Sdelphij T("\n") 862355604Sdelphij T("input control arguments:\n") 863355604Sdelphij T(" -s print an error if the document is not [s]tandalone\n") 864355604Sdelphij T(" -n enable [n]amespace processing\n") 865355604Sdelphij T(" -p enable processing external DTDs and [p]arameter entities\n") 866355604Sdelphij T(" -x enable processing of e[x]ternal entities\n") 867355604Sdelphij T(" -e ENCODING override any in-document [e]ncoding declaration\n") 868355604Sdelphij T(" -w enable support for [W]indows code pages\n") 869355604Sdelphij T(" -r disable memory-mapping and use normal file [r]ead IO calls instead\n") 870355604Sdelphij T("\n") 871355604Sdelphij T("output control arguments:\n") 872355604Sdelphij T(" -d DIRECTORY output [d]estination directory\n") 873355604Sdelphij T(" -c write a [c]opy of input XML, not canonical XML\n") 874355604Sdelphij T(" -m write [m]eta XML, not canonical XML\n") 875355604Sdelphij T(" -t write no XML output for [t]iming of plain parsing\n") 876355604Sdelphij T(" -N enable adding doctype and [n]otation declarations\n") 877355604Sdelphij T("\n") 878355604Sdelphij T("info arguments:\n") 879355604Sdelphij T(" -h show this [h]elp message and exit\n") 880355604Sdelphij T(" -v show program's [v]ersion number and exit\n") 881355604Sdelphij T("\n") 882355604Sdelphij T("libexpat is software libre, licensed under the MIT license.\n") 883355604Sdelphij T("Please report bugs at https://github.com/libexpat/libexpat/issues. Thank you!\n") 884355604Sdelphij , /* clang-format on */ 885355604Sdelphij prog); 886104349Sphk exit(rc); 887104349Sphk} 888104349Sphk 889355604Sdelphij#if defined(__MINGW32__) && defined(XML_UNICODE) 890355604Sdelphij/* Silence warning about missing prototype */ 891355604Sdelphijint wmain(int argc, XML_Char **argv); 892355604Sdelphij#endif 893355604Sdelphij 894104349Sphkint 895355604Sdelphijtmain(int argc, XML_Char **argv) { 896104349Sphk int i, j; 897104349Sphk const XML_Char *outputDir = NULL; 898104349Sphk const XML_Char *encoding = NULL; 899104349Sphk unsigned processFlags = XML_MAP_FILE; 900104349Sphk int windowsCodePages = 0; 901104349Sphk int outputType = 0; 902104349Sphk int useNamespaces = 0; 903104349Sphk int requireStandalone = 0; 904355604Sdelphij int requiresNotations = 0; 905355604Sdelphij enum XML_ParamEntityParsing paramEntityParsing 906355604Sdelphij = XML_PARAM_ENTITY_PARSING_NEVER; 907104349Sphk int useStdin = 0; 908355604Sdelphij XmlwfUserData userData = {NULL, NULL, NULL}; 909104349Sphk 910104349Sphk#ifdef _MSC_VER 911355604Sdelphij _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 912104349Sphk#endif 913104349Sphk 914104349Sphk i = 1; 915104349Sphk j = 0; 916104349Sphk while (i < argc) { 917104349Sphk if (j == 0) { 918104349Sphk if (argv[i][0] != T('-')) 919104349Sphk break; 920104349Sphk if (argv[i][1] == T('-') && argv[i][2] == T('\0')) { 921104349Sphk i++; 922104349Sphk break; 923104349Sphk } 924104349Sphk j++; 925104349Sphk } 926104349Sphk switch (argv[i][j]) { 927104349Sphk case T('r'): 928104349Sphk processFlags &= ~XML_MAP_FILE; 929104349Sphk j++; 930104349Sphk break; 931104349Sphk case T('s'): 932104349Sphk requireStandalone = 1; 933104349Sphk j++; 934104349Sphk break; 935104349Sphk case T('n'): 936104349Sphk useNamespaces = 1; 937104349Sphk j++; 938104349Sphk break; 939104349Sphk case T('p'): 940104349Sphk paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS; 941104349Sphk /* fall through */ 942104349Sphk case T('x'): 943104349Sphk processFlags |= XML_EXTERNAL_ENTITIES; 944104349Sphk j++; 945104349Sphk break; 946104349Sphk case T('w'): 947104349Sphk windowsCodePages = 1; 948104349Sphk j++; 949104349Sphk break; 950104349Sphk case T('m'): 951104349Sphk outputType = 'm'; 952104349Sphk j++; 953104349Sphk break; 954104349Sphk case T('c'): 955104349Sphk outputType = 'c'; 956104349Sphk useNamespaces = 0; 957104349Sphk j++; 958104349Sphk break; 959104349Sphk case T('t'): 960104349Sphk outputType = 't'; 961104349Sphk j++; 962104349Sphk break; 963355604Sdelphij case T('N'): 964355604Sdelphij requiresNotations = 1; 965355604Sdelphij j++; 966355604Sdelphij break; 967104349Sphk case T('d'): 968104349Sphk if (argv[i][j + 1] == T('\0')) { 969104349Sphk if (++i == argc) 970104349Sphk usage(argv[0], 2); 971104349Sphk outputDir = argv[i]; 972355604Sdelphij } else 973104349Sphk outputDir = argv[i] + j + 1; 974104349Sphk i++; 975104349Sphk j = 0; 976104349Sphk break; 977104349Sphk case T('e'): 978104349Sphk if (argv[i][j + 1] == T('\0')) { 979104349Sphk if (++i == argc) 980104349Sphk usage(argv[0], 2); 981104349Sphk encoding = argv[i]; 982355604Sdelphij } else 983104349Sphk encoding = argv[i] + j + 1; 984104349Sphk i++; 985104349Sphk j = 0; 986104349Sphk break; 987104349Sphk case T('h'): 988104349Sphk usage(argv[0], 0); 989104349Sphk return 0; 990104349Sphk case T('v'): 991104349Sphk showVersion(argv[0]); 992104349Sphk return 0; 993104349Sphk case T('\0'): 994104349Sphk if (j > 1) { 995104349Sphk i++; 996104349Sphk j = 0; 997104349Sphk break; 998104349Sphk } 999104349Sphk /* fall through */ 1000104349Sphk default: 1001104349Sphk usage(argv[0], 2); 1002104349Sphk } 1003104349Sphk } 1004104349Sphk if (i == argc) { 1005104349Sphk useStdin = 1; 1006104349Sphk processFlags &= ~XML_MAP_FILE; 1007104349Sphk i--; 1008104349Sphk } 1009104349Sphk for (; i < argc; i++) { 1010104349Sphk XML_Char *outName = 0; 1011104349Sphk int result; 1012104349Sphk XML_Parser parser; 1013104349Sphk if (useNamespaces) 1014104349Sphk parser = XML_ParserCreateNS(encoding, NSSEP); 1015104349Sphk else 1016104349Sphk parser = XML_ParserCreate(encoding); 1017302305Sdelphij 1018302305Sdelphij if (! parser) { 1019355604Sdelphij tperror(T("Could not instantiate parser")); 1020302305Sdelphij exit(1); 1021302305Sdelphij } 1022302305Sdelphij 1023104349Sphk if (requireStandalone) 1024104349Sphk XML_SetNotStandaloneHandler(parser, notStandalone); 1025104349Sphk XML_SetParamEntityParsing(parser, paramEntityParsing); 1026104349Sphk if (outputType == 't') { 1027104349Sphk /* This is for doing timings; this gives a more realistic estimate of 1028104349Sphk the parsing time. */ 1029104349Sphk outputDir = 0; 1030104349Sphk XML_SetElementHandler(parser, nopStartElement, nopEndElement); 1031104349Sphk XML_SetCharacterDataHandler(parser, nopCharacterData); 1032104349Sphk XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction); 1033355604Sdelphij } else if (outputDir) { 1034355604Sdelphij const XML_Char *delim = T("/"); 1035104349Sphk const XML_Char *file = useStdin ? T("STDIN") : argv[i]; 1036355604Sdelphij if (! useStdin) { 1037178848Scokane /* Jump after last (back)slash */ 1038355604Sdelphij const XML_Char *lastDelim = tcsrchr(file, delim[0]); 1039178848Scokane if (lastDelim) 1040178848Scokane file = lastDelim + 1; 1041355604Sdelphij#if defined(_WIN32) 1042178848Scokane else { 1043355604Sdelphij const XML_Char *winDelim = T("\\"); 1044178848Scokane lastDelim = tcsrchr(file, winDelim[0]); 1045178848Scokane if (lastDelim) { 1046178848Scokane file = lastDelim + 1; 1047178848Scokane delim = winDelim; 1048178848Scokane } 1049178848Scokane } 1050104349Sphk#endif 1051178848Scokane } 1052178848Scokane outName = (XML_Char *)malloc((tcslen(outputDir) + tcslen(file) + 2) 1053355604Sdelphij * sizeof(XML_Char)); 1054104349Sphk tcscpy(outName, outputDir); 1055178848Scokane tcscat(outName, delim); 1056104349Sphk tcscat(outName, file); 1057355604Sdelphij userData.fp = tfopen(outName, T("wb")); 1058355604Sdelphij if (! userData.fp) { 1059104349Sphk tperror(outName); 1060104349Sphk exit(1); 1061104349Sphk } 1062355604Sdelphij setvbuf(userData.fp, NULL, _IOFBF, 16384); 1063104349Sphk#ifdef XML_UNICODE 1064355604Sdelphij puttc(0xFEFF, userData.fp); 1065104349Sphk#endif 1066355604Sdelphij XML_SetUserData(parser, &userData); 1067104349Sphk switch (outputType) { 1068104349Sphk case 'm': 1069104349Sphk XML_UseParserAsHandlerArg(parser); 1070104349Sphk XML_SetElementHandler(parser, metaStartElement, metaEndElement); 1071104349Sphk XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction); 1072104349Sphk XML_SetCommentHandler(parser, metaComment); 1073104349Sphk XML_SetCdataSectionHandler(parser, metaStartCdataSection, 1074104349Sphk metaEndCdataSection); 1075104349Sphk XML_SetCharacterDataHandler(parser, metaCharacterData); 1076104349Sphk XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl, 1077104349Sphk metaEndDoctypeDecl); 1078104349Sphk XML_SetEntityDeclHandler(parser, metaEntityDecl); 1079104349Sphk XML_SetNotationDeclHandler(parser, metaNotationDecl); 1080104349Sphk XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl, 1081104349Sphk metaEndNamespaceDecl); 1082104349Sphk metaStartDocument(parser); 1083104349Sphk break; 1084104349Sphk case 'c': 1085104349Sphk XML_UseParserAsHandlerArg(parser); 1086104349Sphk XML_SetDefaultHandler(parser, markup); 1087104349Sphk XML_SetElementHandler(parser, defaultStartElement, defaultEndElement); 1088104349Sphk XML_SetCharacterDataHandler(parser, defaultCharacterData); 1089104349Sphk XML_SetProcessingInstructionHandler(parser, 1090104349Sphk defaultProcessingInstruction); 1091104349Sphk break; 1092104349Sphk default: 1093104349Sphk if (useNamespaces) 1094104349Sphk XML_SetElementHandler(parser, startElementNS, endElementNS); 1095104349Sphk else 1096104349Sphk XML_SetElementHandler(parser, startElement, endElement); 1097104349Sphk XML_SetCharacterDataHandler(parser, characterData); 1098104349Sphk#ifndef W3C14N 1099104349Sphk XML_SetProcessingInstructionHandler(parser, processingInstruction); 1100355604Sdelphij if (requiresNotations) { 1101355604Sdelphij XML_SetDoctypeDeclHandler(parser, startDoctypeDecl, endDoctypeDecl); 1102355604Sdelphij XML_SetNotationDeclHandler(parser, notationDecl); 1103355604Sdelphij } 1104104349Sphk#endif /* not W3C14N */ 1105104349Sphk break; 1106104349Sphk } 1107104349Sphk } 1108104349Sphk if (windowsCodePages) 1109104349Sphk XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0); 1110104349Sphk result = XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags); 1111104349Sphk if (outputDir) { 1112104349Sphk if (outputType == 'm') 1113104349Sphk metaEndDocument(parser); 1114355604Sdelphij fclose(userData.fp); 1115355604Sdelphij if (! result) { 1116104349Sphk tremove(outName); 1117247296Sdelphij } 1118104349Sphk free(outName); 1119104349Sphk } 1120104349Sphk XML_ParserFree(parser); 1121355604Sdelphij if (! result) { 1122355604Sdelphij exit(2); 1123355604Sdelphij } 1124104349Sphk } 1125104349Sphk return 0; 1126104349Sphk} 1127