1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
12 #include "internal.h" /* for UNUSED_P only */
20 #if defined(__amigaos__) && defined(__USE_INLINE__)
21 #include <proto/expat.h>
24 /* This ensures proper sorting. */
26 #define NSSEP T('\001')
29 characterData(void *userData, const XML_Char *s, int len)
31 FILE *fp = (FILE *)userData;
32 for (; len > 0; --len, ++s) {
35 fputts(T("&"), fp);
38 fputts(T("<"), fp);
41 fputts(T(">"), fp);
45 fputts(T("
"), fp);
49 fputts(T("""), fp);
54 ftprintf(fp, T("&#%d;"), *s);
65 attributeValue(FILE *fp, const XML_Char *s)
76 fputts(T("&"), fp);
79 fputts(T("<"), fp);
82 fputts(T("""), fp);
86 fputts(T("	"), fp);
89 fputts(T("
"), fp);
92 fputts(T("
"), fp);
96 fputts(T(">"), fp);
101 ftprintf(fp, T("&#%d;"), *s);
112 /* Lexicographically comparing UTF-8 encoded attribute values,
113 is equivalent to lexicographically comparing based on the character number. */
116 attcmp(const void *att1, const void *att2)
118 return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2);
122 startElement(void *userData, const XML_Char *name, const XML_Char **atts)
126 FILE *fp = (FILE *)userData;
133 nAtts = (int)((p - atts) >> 1);
135 qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp);
139 attributeValue(fp, *atts);
146 endElement(void *userData, const XML_Char *name)
148 FILE *fp = (FILE *)userData;
156 nsattcmp(const void *p1, const void *p2)
158 const XML_Char *att1 = *(const XML_Char **)p1;
159 const XML_Char *att2 = *(const XML_Char **)p2;
160 int sep1 = (tcsrchr(att1, NSSEP) != 0);
161 int sep2 = (tcsrchr(att1, NSSEP) != 0);
164 return tcscmp(att1, att2);
168 startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
173 FILE *fp = (FILE *)userData;
177 sep = tcsrchr(name, NSSEP);
179 fputts(T("n1:"), fp);
181 fputts(T(" xmlns:n1"), fp);
182 attributeValue(fp, name);
193 nAtts = (int)((p - atts) >> 1);
195 qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp);
198 sep = tcsrchr(name, NSSEP);
201 ftprintf(fp, T("n%d:"), nsi);
206 attributeValue(fp, *atts);
208 ftprintf(fp, T(" xmlns:n%d"), nsi++);
209 attributeValue(fp, name);
217 endElementNS(void *userData, const XML_Char *name)
219 FILE *fp = (FILE *)userData;
223 sep = tcsrchr(name, NSSEP);
225 fputts(T("n1:"), fp);
236 processingInstruction(void *userData, const XML_Char *target,
237 const XML_Char *data)
239 FILE *fp = (FILE *)userData;
249 #endif /* not W3C14N */
252 defaultCharacterData(void *userData, const XML_Char *UNUSED_P(s), int UNUSED_P(len))
254 XML_DefaultCurrent((XML_Parser) userData);
258 defaultStartElement(void *userData, const XML_Char *UNUSED_P(name),
259 const XML_Char **UNUSED_P(atts))
261 XML_DefaultCurrent((XML_Parser) userData);
265 defaultEndElement(void *userData, const XML_Char *UNUSED_P(name))
267 XML_DefaultCurrent((XML_Parser) userData);
271 defaultProcessingInstruction(void *userData, const XML_Char *UNUSED_P(target),
272 const XML_Char *UNUSED_P(data))
274 XML_DefaultCurrent((XML_Parser) userData);
278 nopCharacterData(void *UNUSED_P(userData), const XML_Char *UNUSED_P(s), int UNUSED_P(len))
283 nopStartElement(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
288 nopEndElement(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name))
293 nopProcessingInstruction(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target),
294 const XML_Char *UNUSED_P(data))
299 markup(void *userData, const XML_Char *s, int len)
301 FILE *fp = (FILE *)XML_GetUserData((XML_Parser) userData);
302 for (; len > 0; --len, ++s)
307 metaLocation(XML_Parser parser)
309 const XML_Char *uri = XML_GetBase(parser);
311 ftprintf((FILE *)XML_GetUserData(parser), T(" uri=\"%s\""), uri);
312 ftprintf((FILE *)XML_GetUserData(parser),
313 T(" byte=\"%" XML_FMT_INT_MOD "d\" nbytes=\"%d\" \
314 line=\"%" XML_FMT_INT_MOD "u\" col=\"%" XML_FMT_INT_MOD "u\""),
315 XML_GetCurrentByteIndex(parser),
316 XML_GetCurrentByteCount(parser),
317 XML_GetCurrentLineNumber(parser),
318 XML_GetCurrentColumnNumber(parser));
322 metaStartDocument(void *userData)
324 fputts(T("<document>\n"), (FILE *)XML_GetUserData((XML_Parser) userData));
328 metaEndDocument(void *userData)
330 fputts(T("</document>\n"), (FILE *)XML_GetUserData((XML_Parser) userData));
334 metaStartElement(void *userData, const XML_Char *name,
335 const XML_Char **atts)
337 XML_Parser parser = (XML_Parser) userData;
338 FILE *fp = (FILE *)XML_GetUserData(parser);
339 const XML_Char **specifiedAttsEnd
340 = atts + XML_GetSpecifiedAttributeCount(parser);
341 const XML_Char **idAttPtr;
342 int idAttIndex = XML_GetIdAttributeIndex(parser);
346 idAttPtr = atts + idAttIndex;
348 ftprintf(fp, T("<starttag name=\"%s\""), name);
349 metaLocation(parser);
351 fputts(T(">\n"), fp);
353 ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
354 characterData(fp, atts[1], (int)tcslen(atts[1]));
355 if (atts >= specifiedAttsEnd)
356 fputts(T("\" defaulted=\"yes\"/>\n"), fp);
357 else if (atts == idAttPtr)
358 fputts(T("\" id=\"yes\"/>\n"), fp);
360 fputts(T("\"/>\n"), fp);
361 } while (*(atts += 2));
362 fputts(T("</starttag>\n"), fp);
365 fputts(T("/>\n"), fp);
369 metaEndElement(void *userData, const XML_Char *name)
371 XML_Parser parser = (XML_Parser) userData;
372 FILE *fp = (FILE *)XML_GetUserData(parser);
373 ftprintf(fp, T("<endtag name=\"%s\""), name);
374 metaLocation(parser);
375 fputts(T("/>\n"), fp);
379 metaProcessingInstruction(void *userData, const XML_Char *target,
380 const XML_Char *data)
382 XML_Parser parser = (XML_Parser) userData;
383 FILE *fp = (FILE *)XML_GetUserData(parser);
384 ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
385 characterData(fp, data, (int)tcslen(data));
387 metaLocation(parser);
388 fputts(T("/>\n"), fp);
392 metaComment(void *userData, const XML_Char *data)
394 XML_Parser parser = (XML_Parser) userData;
395 FILE *fp = (FILE *)XML_GetUserData(parser);
396 fputts(T("<comment data=\""), fp);
397 characterData(fp, data, (int)tcslen(data));
399 metaLocation(parser);
400 fputts(T("/>\n"), fp);
404 metaStartCdataSection(void *userData)
406 XML_Parser parser = (XML_Parser) userData;
407 FILE *fp = (FILE *)XML_GetUserData(parser);
408 fputts(T("<startcdata"), fp);
409 metaLocation(parser);
410 fputts(T("/>\n"), fp);
414 metaEndCdataSection(void *userData)
416 XML_Parser parser = (XML_Parser) userData;
417 FILE *fp = (FILE *)XML_GetUserData(parser);
418 fputts(T("<endcdata"), fp);
419 metaLocation(parser);
420 fputts(T("/>\n"), fp);
424 metaCharacterData(void *userData, const XML_Char *s, int len)
426 XML_Parser parser = (XML_Parser) userData;
427 FILE *fp = (FILE *)XML_GetUserData(parser);
428 fputts(T("<chars str=\""), fp);
429 characterData(fp, s, len);
431 metaLocation(parser);
432 fputts(T("/>\n"), fp);
436 metaStartDoctypeDecl(void *userData,
437 const XML_Char *doctypeName,
438 const XML_Char *UNUSED_P(sysid),
439 const XML_Char *UNUSED_P(pubid),
440 int UNUSED_P(has_internal_subset))
442 XML_Parser parser = (XML_Parser) userData;
443 FILE *fp = (FILE *)XML_GetUserData(parser);
444 ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
445 metaLocation(parser);
446 fputts(T("/>\n"), fp);
450 metaEndDoctypeDecl(void *userData)
452 XML_Parser parser = (XML_Parser) userData;
453 FILE *fp = (FILE *)XML_GetUserData(parser);
454 fputts(T("<enddoctype"), fp);
455 metaLocation(parser);
456 fputts(T("/>\n"), fp);
460 metaNotationDecl(void *userData,
461 const XML_Char *notationName,
462 const XML_Char *UNUSED_P(base),
463 const XML_Char *systemId,
464 const XML_Char *publicId)
466 XML_Parser parser = (XML_Parser) userData;
467 FILE *fp = (FILE *)XML_GetUserData(parser);
468 ftprintf(fp, T("<notation name=\"%s\""), notationName);
470 ftprintf(fp, T(" public=\"%s\""), publicId);
472 fputts(T(" system=\""), fp);
473 characterData(fp, systemId, (int)tcslen(systemId));
476 metaLocation(parser);
477 fputts(T("/>\n"), fp);
482 metaEntityDecl(void *userData,
483 const XML_Char *entityName,
484 int UNUSED_P(is_param),
485 const XML_Char *value,
487 const XML_Char *UNUSED_P(base),
488 const XML_Char *systemId,
489 const XML_Char *publicId,
490 const XML_Char *notationName)
492 XML_Parser parser = (XML_Parser) userData;
493 FILE *fp = (FILE *)XML_GetUserData(parser);
496 ftprintf(fp, T("<entity name=\"%s\""), entityName);
497 metaLocation(parser);
499 characterData(fp, value, value_length);
500 fputts(T("</entity/>\n"), fp);
502 else if (notationName) {
503 ftprintf(fp, T("<entity name=\"%s\""), entityName);
505 ftprintf(fp, T(" public=\"%s\""), publicId);
506 fputts(T(" system=\""), fp);
507 characterData(fp, systemId, (int)tcslen(systemId));
509 ftprintf(fp, T(" notation=\"%s\""), notationName);
510 metaLocation(parser);
511 fputts(T("/>\n"), fp);
514 ftprintf(fp, T("<entity name=\"%s\""), entityName);
516 ftprintf(fp, T(" public=\"%s\""), publicId);
517 fputts(T(" system=\""), fp);
518 characterData(fp, systemId, (int)tcslen(systemId));
520 metaLocation(parser);
521 fputts(T("/>\n"), fp);
526 metaStartNamespaceDecl(void *userData,
527 const XML_Char *prefix,
530 XML_Parser parser = (XML_Parser) userData;
531 FILE *fp = (FILE *)XML_GetUserData(parser);
532 fputts(T("<startns"), fp);
534 ftprintf(fp, T(" prefix=\"%s\""), prefix);
536 fputts(T(" ns=\""), fp);
537 characterData(fp, uri, (int)tcslen(uri));
538 fputts(T("\"/>\n"), fp);
541 fputts(T("/>\n"), fp);
545 metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
547 XML_Parser parser = (XML_Parser) userData;
548 FILE *fp = (FILE *)XML_GetUserData(parser);
550 fputts(T("<endns/>\n"), fp);
552 ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
556 unknownEncodingConvert(void *data, const char *p)
558 return codepageConvert(*(int *)data, p);
562 unknownEncoding(void *UNUSED_P(userData), const XML_Char *name, XML_Encoding *info)
565 static const XML_Char prefixL[] = T("windows-");
566 static const XML_Char prefixU[] = T("WINDOWS-");
569 for (i = 0; prefixU[i]; i++)
570 if (name[i] != prefixU[i] && name[i] != prefixL[i])
574 for (; name[i]; i++) {
575 static const XML_Char digits[] = T("0123456789");
576 const XML_Char *s = tcschr(digits, name[i]);
580 cp += (int)(s - digits);
584 if (!codepageMap(cp, info->map))
586 info->convert = unknownEncodingConvert;
587 /* We could just cast the code page integer to a void *,
588 and avoid the use of release. */
589 info->release = free;
590 info->data = malloc(sizeof(int));
593 *(int *)info->data = cp;
598 notStandalone(void *UNUSED_P(userData))
604 showVersion(XML_Char *prog)
608 const XML_Feature *features = XML_GetFeatureList();
609 while ((ch = *s) != 0) {
611 #if (defined(WIN32) || defined(__WATCOMC__))
618 ftprintf(stdout, T("%s using %s\n"), prog, XML_ExpatVersion());
619 if (features != NULL && features[0].feature != XML_FEATURE_END) {
621 ftprintf(stdout, T("%s"), features[0].name);
622 if (features[0].value)
623 ftprintf(stdout, T("=%ld"), features[0].value);
624 while (features[i].feature != XML_FEATURE_END) {
625 ftprintf(stdout, T(", %s"), features[i].name);
626 if (features[i].value)
627 ftprintf(stdout, T("=%ld"), features[i].value);
630 ftprintf(stdout, T("\n"));
635 usage(const XML_Char *prog, int rc)
638 T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [file ...]\n"), prog);
643 tmain(int argc, XML_Char **argv)
646 const XML_Char *outputDir = NULL;
647 const XML_Char *encoding = NULL;
648 unsigned processFlags = XML_MAP_FILE;
649 int windowsCodePages = 0;
651 int useNamespaces = 0;
652 int requireStandalone = 0;
653 enum XML_ParamEntityParsing paramEntityParsing =
654 XML_PARAM_ENTITY_PARSING_NEVER;
658 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
665 if (argv[i][0] != T('-'))
667 if (argv[i][1] == T('-') && argv[i][2] == T('\0')) {
673 switch (argv[i][j]) {
675 processFlags &= ~XML_MAP_FILE;
679 requireStandalone = 1;
687 paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS;
690 processFlags |= XML_EXTERNAL_ENTITIES;
694 windowsCodePages = 1;
711 if (argv[i][j + 1] == T('\0')) {
717 outputDir = argv[i] + j + 1;
722 if (argv[i][j + 1] == T('\0')) {
728 encoding = argv[i] + j + 1;
736 showVersion(argv[0]);
751 processFlags &= ~XML_MAP_FILE;
754 for (; i < argc; i++) {
756 XML_Char *outName = 0;
760 parser = XML_ParserCreateNS(encoding, NSSEP);
762 parser = XML_ParserCreate(encoding);
765 tperror("Could not instantiate parser");
769 if (requireStandalone)
770 XML_SetNotStandaloneHandler(parser, notStandalone);
771 XML_SetParamEntityParsing(parser, paramEntityParsing);
772 if (outputType == 't') {
773 /* This is for doing timings; this gives a more realistic estimate of
776 XML_SetElementHandler(parser, nopStartElement, nopEndElement);
777 XML_SetCharacterDataHandler(parser, nopCharacterData);
778 XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction);
780 else if (outputDir) {
781 const XML_Char * delim = T("/");
782 const XML_Char *file = useStdin ? T("STDIN") : argv[i];
784 /* Jump after last (back)slash */
785 const XML_Char * lastDelim = tcsrchr(file, delim[0]);
787 file = lastDelim + 1;
788 #if (defined(WIN32) || defined(__WATCOMC__))
790 const XML_Char * winDelim = T("\\");
791 lastDelim = tcsrchr(file, winDelim[0]);
793 file = lastDelim + 1;
799 outName = (XML_Char *)malloc((tcslen(outputDir) + tcslen(file) + 2)
801 tcscpy(outName, outputDir);
802 tcscat(outName, delim);
803 tcscat(outName, file);
804 fp = tfopen(outName, T("wb"));
809 setvbuf(fp, NULL, _IOFBF, 16384);
813 XML_SetUserData(parser, fp);
814 switch (outputType) {
816 XML_UseParserAsHandlerArg(parser);
817 XML_SetElementHandler(parser, metaStartElement, metaEndElement);
818 XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction);
819 XML_SetCommentHandler(parser, metaComment);
820 XML_SetCdataSectionHandler(parser, metaStartCdataSection,
821 metaEndCdataSection);
822 XML_SetCharacterDataHandler(parser, metaCharacterData);
823 XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl,
825 XML_SetEntityDeclHandler(parser, metaEntityDecl);
826 XML_SetNotationDeclHandler(parser, metaNotationDecl);
827 XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl,
828 metaEndNamespaceDecl);
829 metaStartDocument(parser);
832 XML_UseParserAsHandlerArg(parser);
833 XML_SetDefaultHandler(parser, markup);
834 XML_SetElementHandler(parser, defaultStartElement, defaultEndElement);
835 XML_SetCharacterDataHandler(parser, defaultCharacterData);
836 XML_SetProcessingInstructionHandler(parser,
837 defaultProcessingInstruction);
841 XML_SetElementHandler(parser, startElementNS, endElementNS);
843 XML_SetElementHandler(parser, startElement, endElement);
844 XML_SetCharacterDataHandler(parser, characterData);
846 XML_SetProcessingInstructionHandler(parser, processingInstruction);
847 #endif /* not W3C14N */
851 if (windowsCodePages)
852 XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0);
853 result = XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags);
855 if (outputType == 'm')
856 metaEndDocument(parser);
864 XML_ParserFree(parser);