1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
19 /* This ensures proper sorting. */
21 #define NSSEP T('\001')
24 characterData(void *userData
, const XML_Char
*s
, int len
)
27 for (; len
> 0; --len
, ++s
) {
30 fputts(T("&"), fp
);
33 fputts(T("<"), fp
);
36 fputts(T(">"), fp
);
40 fputts(T("
"), fp
);
44 fputts(T("""), fp
);
49 ftprintf(fp
, T("&#%d;"), *s
);
60 attributeValue(FILE *fp
, const XML_Char
*s
)
71 fputts(T("&"), fp
);
74 fputts(T("<"), fp
);
77 fputts(T("""), fp
);
81 fputts(T("	"), fp
);
84 fputts(T("
"), fp
);
87 fputts(T("
"), fp
);
91 fputts(T(">"), fp
);
96 ftprintf(fp
, T("&#%d;"), *s
);
107 /* Lexicographically comparing UTF-8 encoded attribute values,
108 is equivalent to lexicographically comparing based on the character number. */
111 attcmp(const void *att1
, const void *att2
)
113 return tcscmp(*(const XML_Char
**)att1
, *(const XML_Char
**)att2
);
117 startElement(void *userData
, const XML_Char
*name
, const XML_Char
**atts
)
128 nAtts
= (p
- atts
) >> 1;
130 qsort((void *)atts
, nAtts
, sizeof(XML_Char
*) * 2, attcmp
);
134 attributeValue(fp
, *atts
);
141 endElement(void *userData
, const XML_Char
*name
)
151 nsattcmp(const void *p1
, const void *p2
)
153 const XML_Char
*att1
= *(const XML_Char
**)p1
;
154 const XML_Char
*att2
= *(const XML_Char
**)p2
;
155 int sep1
= (tcsrchr(att1
, NSSEP
) != 0);
156 int sep2
= (tcsrchr(att1
, NSSEP
) != 0);
159 return tcscmp(att1
, att2
);
163 startElementNS(void *userData
, const XML_Char
*name
, const XML_Char
**atts
)
172 sep
= tcsrchr(name
, NSSEP
);
174 fputts(T("n1:"), fp
);
176 fputts(T(" xmlns:n1"), fp
);
177 attributeValue(fp
, name
);
188 nAtts
= (p
- atts
) >> 1;
190 qsort((void *)atts
, nAtts
, sizeof(XML_Char
*) * 2, nsattcmp
);
193 sep
= tcsrchr(name
, NSSEP
);
196 ftprintf(fp
, T("n%d:"), nsi
);
201 attributeValue(fp
, *atts
);
203 ftprintf(fp
, T(" xmlns:n%d"), nsi
++);
204 attributeValue(fp
, name
);
212 endElementNS(void *userData
, const XML_Char
*name
)
218 sep
= tcsrchr(name
, NSSEP
);
220 fputts(T("n1:"), fp
);
231 processingInstruction(void *userData
, const XML_Char
*target
,
232 const XML_Char
*data
)
244 #endif /* not W3C14N */
247 defaultCharacterData(void *userData
, const XML_Char
*s
, int len
)
249 XML_DefaultCurrent((XML_Parser
) userData
);
253 defaultStartElement(void *userData
, const XML_Char
*name
,
254 const XML_Char
**atts
)
256 XML_DefaultCurrent((XML_Parser
) userData
);
260 defaultEndElement(void *userData
, const XML_Char
*name
)
262 XML_DefaultCurrent((XML_Parser
) userData
);
266 defaultProcessingInstruction(void *userData
, const XML_Char
*target
,
267 const XML_Char
*data
)
269 XML_DefaultCurrent((XML_Parser
) userData
);
273 nopCharacterData(void *userData
, const XML_Char
*s
, int len
)
278 nopStartElement(void *userData
, const XML_Char
*name
, const XML_Char
**atts
)
283 nopEndElement(void *userData
, const XML_Char
*name
)
288 nopProcessingInstruction(void *userData
, const XML_Char
*target
,
289 const XML_Char
*data
)
294 markup(void *userData
, const XML_Char
*s
, int len
)
296 FILE *fp
= XML_GetUserData((XML_Parser
) userData
);
297 for (; len
> 0; --len
, ++s
)
302 metaLocation(XML_Parser parser
)
304 const XML_Char
*uri
= XML_GetBase(parser
);
306 ftprintf(XML_GetUserData(parser
), T(" uri=\"%s\""), uri
);
307 ftprintf(XML_GetUserData(parser
),
308 T(" byte=\"%ld\" nbytes=\"%d\" line=\"%d\" col=\"%d\""),
309 XML_GetCurrentByteIndex(parser
),
310 XML_GetCurrentByteCount(parser
),
311 XML_GetCurrentLineNumber(parser
),
312 XML_GetCurrentColumnNumber(parser
));
316 metaStartDocument(void *userData
)
318 fputts(T("<document>\n"), XML_GetUserData((XML_Parser
) userData
));
322 metaEndDocument(void *userData
)
324 fputts(T("</document>\n"), XML_GetUserData((XML_Parser
) userData
));
328 metaStartElement(void *userData
, const XML_Char
*name
,
329 const XML_Char
**atts
)
331 XML_Parser parser
= (XML_Parser
) userData
;
332 FILE *fp
= XML_GetUserData(parser
);
333 const XML_Char
**specifiedAttsEnd
334 = atts
+ XML_GetSpecifiedAttributeCount(parser
);
335 const XML_Char
**idAttPtr
;
336 int idAttIndex
= XML_GetIdAttributeIndex(parser
);
340 idAttPtr
= atts
+ idAttIndex
;
342 ftprintf(fp
, T("<starttag name=\"%s\""), name
);
343 metaLocation(parser
);
345 fputts(T(">\n"), fp
);
347 ftprintf(fp
, T("<attribute name=\"%s\" value=\""), atts
[0]);
348 characterData(fp
, atts
[1], tcslen(atts
[1]));
349 if (atts
>= specifiedAttsEnd
)
350 fputts(T("\" defaulted=\"yes\"/>\n"), fp
);
351 else if (atts
== idAttPtr
)
352 fputts(T("\" id=\"yes\"/>\n"), fp
);
354 fputts(T("\"/>\n"), fp
);
355 } while (*(atts
+= 2));
356 fputts(T("</starttag>\n"), fp
);
359 fputts(T("/>\n"), fp
);
363 metaEndElement(void *userData
, const XML_Char
*name
)
365 XML_Parser parser
= (XML_Parser
) userData
;
366 FILE *fp
= XML_GetUserData(parser
);
367 ftprintf(fp
, T("<endtag name=\"%s\""), name
);
368 metaLocation(parser
);
369 fputts(T("/>\n"), fp
);
373 metaProcessingInstruction(void *userData
, const XML_Char
*target
,
374 const XML_Char
*data
)
376 XML_Parser parser
= (XML_Parser
) userData
;
377 FILE *fp
= XML_GetUserData(parser
);
378 ftprintf(fp
, T("<pi target=\"%s\" data=\""), target
);
379 characterData(fp
, data
, tcslen(data
));
381 metaLocation(parser
);
382 fputts(T("/>\n"), fp
);
386 metaComment(void *userData
, const XML_Char
*data
)
388 XML_Parser parser
= (XML_Parser
) userData
;
389 FILE *fp
= XML_GetUserData(parser
);
390 fputts(T("<comment data=\""), fp
);
391 characterData(fp
, data
, tcslen(data
));
393 metaLocation(parser
);
394 fputts(T("/>\n"), fp
);
398 metaStartCdataSection(void *userData
)
400 XML_Parser parser
= (XML_Parser
) userData
;
401 FILE *fp
= XML_GetUserData(parser
);
402 fputts(T("<startcdata"), fp
);
403 metaLocation(parser
);
404 fputts(T("/>\n"), fp
);
408 metaEndCdataSection(void *userData
)
410 XML_Parser parser
= (XML_Parser
) userData
;
411 FILE *fp
= XML_GetUserData(parser
);
412 fputts(T("<endcdata"), fp
);
413 metaLocation(parser
);
414 fputts(T("/>\n"), fp
);
418 metaCharacterData(void *userData
, const XML_Char
*s
, int len
)
420 XML_Parser parser
= (XML_Parser
) userData
;
421 FILE *fp
= XML_GetUserData(parser
);
422 fputts(T("<chars str=\""), fp
);
423 characterData(fp
, s
, len
);
425 metaLocation(parser
);
426 fputts(T("/>\n"), fp
);
430 metaStartDoctypeDecl(void *userData
,
431 const XML_Char
*doctypeName
,
432 const XML_Char
*sysid
,
433 const XML_Char
*pubid
,
434 int has_internal_subset
)
436 XML_Parser parser
= (XML_Parser
) userData
;
437 FILE *fp
= XML_GetUserData(parser
);
438 ftprintf(fp
, T("<startdoctype name=\"%s\""), doctypeName
);
439 metaLocation(parser
);
440 fputts(T("/>\n"), fp
);
444 metaEndDoctypeDecl(void *userData
)
446 XML_Parser parser
= (XML_Parser
) userData
;
447 FILE *fp
= XML_GetUserData(parser
);
448 fputts(T("<enddoctype"), fp
);
449 metaLocation(parser
);
450 fputts(T("/>\n"), fp
);
454 metaNotationDecl(void *userData
,
455 const XML_Char
*notationName
,
456 const XML_Char
*base
,
457 const XML_Char
*systemId
,
458 const XML_Char
*publicId
)
460 XML_Parser parser
= (XML_Parser
) userData
;
461 FILE *fp
= XML_GetUserData(parser
);
462 ftprintf(fp
, T("<notation name=\"%s\""), notationName
);
464 ftprintf(fp
, T(" public=\"%s\""), publicId
);
466 fputts(T(" system=\""), fp
);
467 characterData(fp
, systemId
, tcslen(systemId
));
470 metaLocation(parser
);
471 fputts(T("/>\n"), fp
);
476 metaEntityDecl(void *userData
,
477 const XML_Char
*entityName
,
479 const XML_Char
*value
,
481 const XML_Char
*base
,
482 const XML_Char
*systemId
,
483 const XML_Char
*publicId
,
484 const XML_Char
*notationName
)
486 XML_Parser parser
= (XML_Parser
) userData
;
487 FILE *fp
= XML_GetUserData(parser
);
490 ftprintf(fp
, T("<entity name=\"%s\""), entityName
);
491 metaLocation(parser
);
493 characterData(fp
, value
, value_length
);
494 fputts(T("</entity/>\n"), fp
);
496 else if (notationName
) {
497 ftprintf(fp
, T("<entity name=\"%s\""), entityName
);
499 ftprintf(fp
, T(" public=\"%s\""), publicId
);
500 fputts(T(" system=\""), fp
);
501 characterData(fp
, systemId
, tcslen(systemId
));
503 ftprintf(fp
, T(" notation=\"%s\""), notationName
);
504 metaLocation(parser
);
505 fputts(T("/>\n"), fp
);
508 ftprintf(fp
, T("<entity name=\"%s\""), entityName
);
510 ftprintf(fp
, T(" public=\"%s\""), publicId
);
511 fputts(T(" system=\""), fp
);
512 characterData(fp
, systemId
, tcslen(systemId
));
514 metaLocation(parser
);
515 fputts(T("/>\n"), fp
);
520 metaStartNamespaceDecl(void *userData
,
521 const XML_Char
*prefix
,
524 XML_Parser parser
= (XML_Parser
) userData
;
525 FILE *fp
= XML_GetUserData(parser
);
526 fputts(T("<startns"), fp
);
528 ftprintf(fp
, T(" prefix=\"%s\""), prefix
);
530 fputts(T(" ns=\""), fp
);
531 characterData(fp
, uri
, tcslen(uri
));
532 fputts(T("\"/>\n"), fp
);
535 fputts(T("/>\n"), fp
);
539 metaEndNamespaceDecl(void *userData
, const XML_Char
*prefix
)
541 XML_Parser parser
= (XML_Parser
) userData
;
542 FILE *fp
= XML_GetUserData(parser
);
544 fputts(T("<endns/>\n"), fp
);
546 ftprintf(fp
, T("<endns prefix=\"%s\"/>\n"), prefix
);
550 unknownEncodingConvert(void *data
, const char *p
)
552 return codepageConvert(*(int *)data
, p
);
556 unknownEncoding(void *userData
, const XML_Char
*name
, XML_Encoding
*info
)
559 static const XML_Char prefixL
[] = T("windows-");
560 static const XML_Char prefixU
[] = T("WINDOWS-");
563 for (i
= 0; prefixU
[i
]; i
++)
564 if (name
[i
] != prefixU
[i
] && name
[i
] != prefixL
[i
])
568 for (; name
[i
]; i
++) {
569 static const XML_Char digits
[] = T("0123456789");
570 const XML_Char
*s
= tcschr(digits
, name
[i
]);
578 if (!codepageMap(cp
, info
->map
))
580 info
->convert
= unknownEncodingConvert
;
581 /* We could just cast the code page integer to a void *,
582 and avoid the use of release. */
583 info
->release
= free
;
584 info
->data
= malloc(sizeof(int));
587 *(int *)info
->data
= cp
;
592 notStandalone(void *userData
)
598 showVersion(XML_Char
*prog
)
602 const XML_Feature
*features
= XML_GetFeatureList();
603 while ((ch
= *s
) != 0) {
612 ftprintf(stdout
, T("%s using %s\n"), prog
, XML_ExpatVersion());
613 if (features
!= NULL
&& features
[0].feature
!= XML_FEATURE_END
) {
615 ftprintf(stdout
, T("%s"), features
[0].name
);
616 if (features
[0].value
)
617 ftprintf(stdout
, T("=%ld"), features
[0].value
);
618 while (features
[i
].feature
!= XML_FEATURE_END
) {
619 ftprintf(stdout
, T(", %s"), features
[i
].name
);
620 if (features
[i
].value
)
621 ftprintf(stdout
, T("=%ld"), features
[i
].value
);
624 ftprintf(stdout
, T("\n"));
629 usage(const XML_Char
*prog
, int rc
)
632 T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] "
633 "[-e encoding] file ...\n"), prog
);
638 tmain(int argc
, XML_Char
**argv
)
641 const XML_Char
*outputDir
= NULL
;
642 const XML_Char
*encoding
= NULL
;
643 unsigned processFlags
= XML_MAP_FILE
;
644 int windowsCodePages
= 0;
646 int useNamespaces
= 0;
647 int requireStandalone
= 0;
648 int paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
652 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF
|_CRTDBG_LEAK_CHECK_DF
);
659 if (argv
[i
][0] != T('-'))
661 if (argv
[i
][1] == T('-') && argv
[i
][2] == T('\0')) {
667 switch (argv
[i
][j
]) {
669 processFlags
&= ~XML_MAP_FILE
;
673 requireStandalone
= 1;
681 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_ALWAYS
;
684 processFlags
|= XML_EXTERNAL_ENTITIES
;
688 windowsCodePages
= 1;
705 if (argv
[i
][j
+ 1] == T('\0')) {
711 outputDir
= argv
[i
] + j
+ 1;
716 if (argv
[i
][j
+ 1] == T('\0')) {
722 encoding
= argv
[i
] + j
+ 1;
730 showVersion(argv
[0]);
745 processFlags
&= ~XML_MAP_FILE
;
748 for (; i
< argc
; i
++) {
750 XML_Char
*outName
= 0;
754 parser
= XML_ParserCreateNS(encoding
, NSSEP
);
756 parser
= XML_ParserCreate(encoding
);
757 if (requireStandalone
)
758 XML_SetNotStandaloneHandler(parser
, notStandalone
);
759 XML_SetParamEntityParsing(parser
, paramEntityParsing
);
760 if (outputType
== 't') {
761 /* This is for doing timings; this gives a more realistic estimate of
764 XML_SetElementHandler(parser
, nopStartElement
, nopEndElement
);
765 XML_SetCharacterDataHandler(parser
, nopCharacterData
);
766 XML_SetProcessingInstructionHandler(parser
, nopProcessingInstruction
);
768 else if (outputDir
) {
769 const XML_Char
*file
= useStdin
? T("STDIN") : argv
[i
];
770 if (tcsrchr(file
, T('/')))
771 file
= tcsrchr(file
, T('/')) + 1;
773 if (tcsrchr(file
, T('\\')))
774 file
= tcsrchr(file
, T('\\')) + 1;
776 outName
= malloc((tcslen(outputDir
) + tcslen(file
) + 2)
778 tcscpy(outName
, outputDir
);
779 tcscat(outName
, T("/"));
780 tcscat(outName
, file
);
781 fp
= tfopen(outName
, T("wb"));
786 setvbuf(fp
, NULL
, _IOFBF
, 16384);
790 XML_SetUserData(parser
, fp
);
791 switch (outputType
) {
793 XML_UseParserAsHandlerArg(parser
);
794 XML_SetElementHandler(parser
, metaStartElement
, metaEndElement
);
795 XML_SetProcessingInstructionHandler(parser
, metaProcessingInstruction
);
796 XML_SetCommentHandler(parser
, metaComment
);
797 XML_SetCdataSectionHandler(parser
, metaStartCdataSection
,
798 metaEndCdataSection
);
799 XML_SetCharacterDataHandler(parser
, metaCharacterData
);
800 XML_SetDoctypeDeclHandler(parser
, metaStartDoctypeDecl
,
802 XML_SetEntityDeclHandler(parser
, metaEntityDecl
);
803 XML_SetNotationDeclHandler(parser
, metaNotationDecl
);
804 XML_SetNamespaceDeclHandler(parser
, metaStartNamespaceDecl
,
805 metaEndNamespaceDecl
);
806 metaStartDocument(parser
);
809 XML_UseParserAsHandlerArg(parser
);
810 XML_SetDefaultHandler(parser
, markup
);
811 XML_SetElementHandler(parser
, defaultStartElement
, defaultEndElement
);
812 XML_SetCharacterDataHandler(parser
, defaultCharacterData
);
813 XML_SetProcessingInstructionHandler(parser
,
814 defaultProcessingInstruction
);
818 XML_SetElementHandler(parser
, startElementNS
, endElementNS
);
820 XML_SetElementHandler(parser
, startElement
, endElement
);
821 XML_SetCharacterDataHandler(parser
, characterData
);
823 XML_SetProcessingInstructionHandler(parser
, processingInstruction
);
824 #endif /* not W3C14N */
828 if (windowsCodePages
)
829 XML_SetUnknownEncodingHandler(parser
, unknownEncoding
, 0);
830 result
= XML_ProcessFile(parser
, useStdin
? NULL
: argv
[i
], processFlags
);
832 if (outputType
== 'm')
833 metaEndDocument(parser
);
839 XML_ParserFree(parser
);