xref: /freebsd/contrib/expat/xmlwf/xmlwf.c (revision f0a75d274af375d15b97b830966b99a02b7db911)
1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2    See the file COPYING for copying permission.
3 */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stddef.h>
8 #include <string.h>
9 
10 #include "expat.h"
11 #include "codepage.h"
12 #include "xmlfile.h"
13 #include "xmltchar.h"
14 
15 #ifdef _MSC_VER
16 #include <crtdbg.h>
17 #endif
18 
19 /* This ensures proper sorting. */
20 
21 #define NSSEP T('\001')
22 
23 static void
24 characterData(void *userData, const XML_Char *s, int len)
25 {
26   FILE *fp = userData;
27   for (; len > 0; --len, ++s) {
28     switch (*s) {
29     case T('&'):
30       fputts(T("&amp;"), fp);
31       break;
32     case T('<'):
33       fputts(T("&lt;"), fp);
34       break;
35     case T('>'):
36       fputts(T("&gt;"), fp);
37       break;
38 #ifdef W3C14N
39     case 13:
40       fputts(T("&#xD;"), fp);
41       break;
42 #else
43     case T('"'):
44       fputts(T("&quot;"), fp);
45       break;
46     case 9:
47     case 10:
48     case 13:
49       ftprintf(fp, T("&#%d;"), *s);
50       break;
51 #endif
52     default:
53       puttc(*s, fp);
54       break;
55     }
56   }
57 }
58 
59 static void
60 attributeValue(FILE *fp, const XML_Char *s)
61 {
62   puttc(T('='), fp);
63   puttc(T('"'), fp);
64   for (;;) {
65     switch (*s) {
66     case 0:
67     case NSSEP:
68       puttc(T('"'), fp);
69       return;
70     case T('&'):
71       fputts(T("&amp;"), fp);
72       break;
73     case T('<'):
74       fputts(T("&lt;"), fp);
75       break;
76     case T('"'):
77       fputts(T("&quot;"), fp);
78       break;
79 #ifdef W3C14N
80     case 9:
81       fputts(T("&#x9;"), fp);
82       break;
83     case 10:
84       fputts(T("&#xA;"), fp);
85       break;
86     case 13:
87       fputts(T("&#xD;"), fp);
88       break;
89 #else
90     case T('>'):
91       fputts(T("&gt;"), fp);
92       break;
93     case 9:
94     case 10:
95     case 13:
96       ftprintf(fp, T("&#%d;"), *s);
97       break;
98 #endif
99     default:
100       puttc(*s, fp);
101       break;
102     }
103     s++;
104   }
105 }
106 
107 /* Lexicographically comparing UTF-8 encoded attribute values,
108 is equivalent to lexicographically comparing based on the character number. */
109 
110 static int
111 attcmp(const void *att1, const void *att2)
112 {
113   return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2);
114 }
115 
116 static void
117 startElement(void *userData, const XML_Char *name, const XML_Char **atts)
118 {
119   int nAtts;
120   const XML_Char **p;
121   FILE *fp = userData;
122   puttc(T('<'), fp);
123   fputts(name, fp);
124 
125   p = atts;
126   while (*p)
127     ++p;
128   nAtts = (p - atts) >> 1;
129   if (nAtts > 1)
130     qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp);
131   while (*atts) {
132     puttc(T(' '), fp);
133     fputts(*atts++, fp);
134     attributeValue(fp, *atts);
135     atts++;
136   }
137   puttc(T('>'), fp);
138 }
139 
140 static void
141 endElement(void *userData, const XML_Char *name)
142 {
143   FILE *fp = userData;
144   puttc(T('<'), fp);
145   puttc(T('/'), fp);
146   fputts(name, fp);
147   puttc(T('>'), fp);
148 }
149 
150 static int
151 nsattcmp(const void *p1, const void *p2)
152 {
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);
157   if (sep1 != sep2)
158     return sep1 - sep2;
159   return tcscmp(att1, att2);
160 }
161 
162 static void
163 startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
164 {
165   int nAtts;
166   int nsi;
167   const XML_Char **p;
168   FILE *fp = userData;
169   const XML_Char *sep;
170   puttc(T('<'), fp);
171 
172   sep = tcsrchr(name, NSSEP);
173   if (sep) {
174     fputts(T("n1:"), fp);
175     fputts(sep + 1, fp);
176     fputts(T(" xmlns:n1"), fp);
177     attributeValue(fp, name);
178     nsi = 2;
179   }
180   else {
181     fputts(name, fp);
182     nsi = 1;
183   }
184 
185   p = atts;
186   while (*p)
187     ++p;
188   nAtts = (p - atts) >> 1;
189   if (nAtts > 1)
190     qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp);
191   while (*atts) {
192     name = *atts++;
193     sep = tcsrchr(name, NSSEP);
194     puttc(T(' '), fp);
195     if (sep) {
196       ftprintf(fp, T("n%d:"), nsi);
197       fputts(sep + 1, fp);
198     }
199     else
200       fputts(name, fp);
201     attributeValue(fp, *atts);
202     if (sep) {
203       ftprintf(fp, T(" xmlns:n%d"), nsi++);
204       attributeValue(fp, name);
205     }
206     atts++;
207   }
208   puttc(T('>'), fp);
209 }
210 
211 static void
212 endElementNS(void *userData, const XML_Char *name)
213 {
214   FILE *fp = userData;
215   const XML_Char *sep;
216   puttc(T('<'), fp);
217   puttc(T('/'), fp);
218   sep = tcsrchr(name, NSSEP);
219   if (sep) {
220     fputts(T("n1:"), fp);
221     fputts(sep + 1, fp);
222   }
223   else
224     fputts(name, fp);
225   puttc(T('>'), fp);
226 }
227 
228 #ifndef W3C14N
229 
230 static void
231 processingInstruction(void *userData, const XML_Char *target,
232                       const XML_Char *data)
233 {
234   FILE *fp = userData;
235   puttc(T('<'), fp);
236   puttc(T('?'), fp);
237   fputts(target, fp);
238   puttc(T(' '), fp);
239   fputts(data, fp);
240   puttc(T('?'), fp);
241   puttc(T('>'), fp);
242 }
243 
244 #endif /* not W3C14N */
245 
246 static void
247 defaultCharacterData(void *userData, const XML_Char *s, int len)
248 {
249   XML_DefaultCurrent((XML_Parser) userData);
250 }
251 
252 static void
253 defaultStartElement(void *userData, const XML_Char *name,
254                     const XML_Char **atts)
255 {
256   XML_DefaultCurrent((XML_Parser) userData);
257 }
258 
259 static void
260 defaultEndElement(void *userData, const XML_Char *name)
261 {
262   XML_DefaultCurrent((XML_Parser) userData);
263 }
264 
265 static void
266 defaultProcessingInstruction(void *userData, const XML_Char *target,
267                              const XML_Char *data)
268 {
269   XML_DefaultCurrent((XML_Parser) userData);
270 }
271 
272 static void
273 nopCharacterData(void *userData, const XML_Char *s, int len)
274 {
275 }
276 
277 static void
278 nopStartElement(void *userData, const XML_Char *name, const XML_Char **atts)
279 {
280 }
281 
282 static void
283 nopEndElement(void *userData, const XML_Char *name)
284 {
285 }
286 
287 static void
288 nopProcessingInstruction(void *userData, const XML_Char *target,
289                          const XML_Char *data)
290 {
291 }
292 
293 static void
294 markup(void *userData, const XML_Char *s, int len)
295 {
296   FILE *fp = XML_GetUserData((XML_Parser) userData);
297   for (; len > 0; --len, ++s)
298     puttc(*s, fp);
299 }
300 
301 static void
302 metaLocation(XML_Parser parser)
303 {
304   const XML_Char *uri = XML_GetBase(parser);
305   if (uri)
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));
313 }
314 
315 static void
316 metaStartDocument(void *userData)
317 {
318   fputts(T("<document>\n"), XML_GetUserData((XML_Parser) userData));
319 }
320 
321 static void
322 metaEndDocument(void *userData)
323 {
324   fputts(T("</document>\n"), XML_GetUserData((XML_Parser) userData));
325 }
326 
327 static void
328 metaStartElement(void *userData, const XML_Char *name,
329                  const XML_Char **atts)
330 {
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);
337   if (idAttIndex < 0)
338     idAttPtr = 0;
339   else
340     idAttPtr = atts + idAttIndex;
341 
342   ftprintf(fp, T("<starttag name=\"%s\""), name);
343   metaLocation(parser);
344   if (*atts) {
345     fputts(T(">\n"), fp);
346     do {
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);
353       else
354         fputts(T("\"/>\n"), fp);
355     } while (*(atts += 2));
356     fputts(T("</starttag>\n"), fp);
357   }
358   else
359     fputts(T("/>\n"), fp);
360 }
361 
362 static void
363 metaEndElement(void *userData, const XML_Char *name)
364 {
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);
370 }
371 
372 static void
373 metaProcessingInstruction(void *userData, const XML_Char *target,
374                           const XML_Char *data)
375 {
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));
380   puttc(T('"'), fp);
381   metaLocation(parser);
382   fputts(T("/>\n"), fp);
383 }
384 
385 static void
386 metaComment(void *userData, const XML_Char *data)
387 {
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));
392   puttc(T('"'), fp);
393   metaLocation(parser);
394   fputts(T("/>\n"), fp);
395 }
396 
397 static void
398 metaStartCdataSection(void *userData)
399 {
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);
405 }
406 
407 static void
408 metaEndCdataSection(void *userData)
409 {
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);
415 }
416 
417 static void
418 metaCharacterData(void *userData, const XML_Char *s, int len)
419 {
420   XML_Parser parser = (XML_Parser) userData;
421   FILE *fp = XML_GetUserData(parser);
422   fputts(T("<chars str=\""), fp);
423   characterData(fp, s, len);
424   puttc(T('"'), fp);
425   metaLocation(parser);
426   fputts(T("/>\n"), fp);
427 }
428 
429 static void
430 metaStartDoctypeDecl(void *userData,
431                      const XML_Char *doctypeName,
432                      const XML_Char *sysid,
433                      const XML_Char *pubid,
434                      int has_internal_subset)
435 {
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);
441 }
442 
443 static void
444 metaEndDoctypeDecl(void *userData)
445 {
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);
451 }
452 
453 static void
454 metaNotationDecl(void *userData,
455                  const XML_Char *notationName,
456                  const XML_Char *base,
457                  const XML_Char *systemId,
458                  const XML_Char *publicId)
459 {
460   XML_Parser parser = (XML_Parser) userData;
461   FILE *fp = XML_GetUserData(parser);
462   ftprintf(fp, T("<notation name=\"%s\""), notationName);
463   if (publicId)
464     ftprintf(fp, T(" public=\"%s\""), publicId);
465   if (systemId) {
466     fputts(T(" system=\""), fp);
467     characterData(fp, systemId, tcslen(systemId));
468     puttc(T('"'), fp);
469   }
470   metaLocation(parser);
471   fputts(T("/>\n"), fp);
472 }
473 
474 
475 static void
476 metaEntityDecl(void *userData,
477                const XML_Char *entityName,
478                int  is_param,
479                const XML_Char *value,
480                int  value_length,
481                const XML_Char *base,
482                const XML_Char *systemId,
483                const XML_Char *publicId,
484                const XML_Char *notationName)
485 {
486   XML_Parser parser = (XML_Parser) userData;
487   FILE *fp = XML_GetUserData(parser);
488 
489   if (value) {
490     ftprintf(fp, T("<entity name=\"%s\""), entityName);
491     metaLocation(parser);
492     puttc(T('>'), fp);
493     characterData(fp, value, value_length);
494     fputts(T("</entity/>\n"), fp);
495   }
496   else if (notationName) {
497     ftprintf(fp, T("<entity name=\"%s\""), entityName);
498     if (publicId)
499       ftprintf(fp, T(" public=\"%s\""), publicId);
500     fputts(T(" system=\""), fp);
501     characterData(fp, systemId, tcslen(systemId));
502     puttc(T('"'), fp);
503     ftprintf(fp, T(" notation=\"%s\""), notationName);
504     metaLocation(parser);
505     fputts(T("/>\n"), fp);
506   }
507   else {
508     ftprintf(fp, T("<entity name=\"%s\""), entityName);
509     if (publicId)
510       ftprintf(fp, T(" public=\"%s\""), publicId);
511     fputts(T(" system=\""), fp);
512     characterData(fp, systemId, tcslen(systemId));
513     puttc(T('"'), fp);
514     metaLocation(parser);
515     fputts(T("/>\n"), fp);
516   }
517 }
518 
519 static void
520 metaStartNamespaceDecl(void *userData,
521                        const XML_Char *prefix,
522                        const XML_Char *uri)
523 {
524   XML_Parser parser = (XML_Parser) userData;
525   FILE *fp = XML_GetUserData(parser);
526   fputts(T("<startns"), fp);
527   if (prefix)
528     ftprintf(fp, T(" prefix=\"%s\""), prefix);
529   if (uri) {
530     fputts(T(" ns=\""), fp);
531     characterData(fp, uri, tcslen(uri));
532     fputts(T("\"/>\n"), fp);
533   }
534   else
535     fputts(T("/>\n"), fp);
536 }
537 
538 static void
539 metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
540 {
541   XML_Parser parser = (XML_Parser) userData;
542   FILE *fp = XML_GetUserData(parser);
543   if (!prefix)
544     fputts(T("<endns/>\n"), fp);
545   else
546     ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
547 }
548 
549 static int
550 unknownEncodingConvert(void *data, const char *p)
551 {
552   return codepageConvert(*(int *)data, p);
553 }
554 
555 static int
556 unknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info)
557 {
558   int cp;
559   static const XML_Char prefixL[] = T("windows-");
560   static const XML_Char prefixU[] = T("WINDOWS-");
561   int i;
562 
563   for (i = 0; prefixU[i]; i++)
564     if (name[i] != prefixU[i] && name[i] != prefixL[i])
565       return 0;
566 
567   cp = 0;
568   for (; name[i]; i++) {
569     static const XML_Char digits[] = T("0123456789");
570     const XML_Char *s = tcschr(digits, name[i]);
571     if (!s)
572       return 0;
573     cp *= 10;
574     cp += s - digits;
575     if (cp >= 0x10000)
576       return 0;
577   }
578   if (!codepageMap(cp, info->map))
579     return 0;
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));
585   if (!info->data)
586     return 0;
587   *(int *)info->data = cp;
588   return 1;
589 }
590 
591 static int
592 notStandalone(void *userData)
593 {
594   return 0;
595 }
596 
597 static void
598 showVersion(XML_Char *prog)
599 {
600   XML_Char *s = prog;
601   XML_Char ch;
602   const XML_Feature *features = XML_GetFeatureList();
603   while ((ch = *s) != 0) {
604     if (ch == '/'
605 #ifdef WIN32
606         || ch == '\\'
607 #endif
608         )
609       prog = s + 1;
610     ++s;
611   }
612   ftprintf(stdout, T("%s using %s\n"), prog, XML_ExpatVersion());
613   if (features != NULL && features[0].feature != XML_FEATURE_END) {
614     int i = 1;
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);
622       ++i;
623     }
624     ftprintf(stdout, T("\n"));
625   }
626 }
627 
628 static void
629 usage(const XML_Char *prog, int rc)
630 {
631   ftprintf(stderr,
632            T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] "
633              "[-e encoding] file ...\n"), prog);
634   exit(rc);
635 }
636 
637 int
638 tmain(int argc, XML_Char **argv)
639 {
640   int i, j;
641   const XML_Char *outputDir = NULL;
642   const XML_Char *encoding = NULL;
643   unsigned processFlags = XML_MAP_FILE;
644   int windowsCodePages = 0;
645   int outputType = 0;
646   int useNamespaces = 0;
647   int requireStandalone = 0;
648   int paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
649   int useStdin = 0;
650 
651 #ifdef _MSC_VER
652   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
653 #endif
654 
655   i = 1;
656   j = 0;
657   while (i < argc) {
658     if (j == 0) {
659       if (argv[i][0] != T('-'))
660         break;
661       if (argv[i][1] == T('-') && argv[i][2] == T('\0')) {
662         i++;
663         break;
664       }
665       j++;
666     }
667     switch (argv[i][j]) {
668     case T('r'):
669       processFlags &= ~XML_MAP_FILE;
670       j++;
671       break;
672     case T('s'):
673       requireStandalone = 1;
674       j++;
675       break;
676     case T('n'):
677       useNamespaces = 1;
678       j++;
679       break;
680     case T('p'):
681       paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS;
682       /* fall through */
683     case T('x'):
684       processFlags |= XML_EXTERNAL_ENTITIES;
685       j++;
686       break;
687     case T('w'):
688       windowsCodePages = 1;
689       j++;
690       break;
691     case T('m'):
692       outputType = 'm';
693       j++;
694       break;
695     case T('c'):
696       outputType = 'c';
697       useNamespaces = 0;
698       j++;
699       break;
700     case T('t'):
701       outputType = 't';
702       j++;
703       break;
704     case T('d'):
705       if (argv[i][j + 1] == T('\0')) {
706         if (++i == argc)
707           usage(argv[0], 2);
708         outputDir = argv[i];
709       }
710       else
711         outputDir = argv[i] + j + 1;
712       i++;
713       j = 0;
714       break;
715     case T('e'):
716       if (argv[i][j + 1] == T('\0')) {
717         if (++i == argc)
718           usage(argv[0], 2);
719         encoding = argv[i];
720       }
721       else
722         encoding = argv[i] + j + 1;
723       i++;
724       j = 0;
725       break;
726     case T('h'):
727       usage(argv[0], 0);
728       return 0;
729     case T('v'):
730       showVersion(argv[0]);
731       return 0;
732     case T('\0'):
733       if (j > 1) {
734         i++;
735         j = 0;
736         break;
737       }
738       /* fall through */
739     default:
740       usage(argv[0], 2);
741     }
742   }
743   if (i == argc) {
744     useStdin = 1;
745     processFlags &= ~XML_MAP_FILE;
746     i--;
747   }
748   for (; i < argc; i++) {
749     FILE *fp = 0;
750     XML_Char *outName = 0;
751     int result;
752     XML_Parser parser;
753     if (useNamespaces)
754       parser = XML_ParserCreateNS(encoding, NSSEP);
755     else
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
762          the parsing time. */
763       outputDir = 0;
764       XML_SetElementHandler(parser, nopStartElement, nopEndElement);
765       XML_SetCharacterDataHandler(parser, nopCharacterData);
766       XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction);
767     }
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;
772 #ifdef WIN32
773       if (tcsrchr(file, T('\\')))
774         file = tcsrchr(file, T('\\')) + 1;
775 #endif
776       outName = malloc((tcslen(outputDir) + tcslen(file) + 2)
777                        * sizeof(XML_Char));
778       tcscpy(outName, outputDir);
779       tcscat(outName, T("/"));
780       tcscat(outName, file);
781       fp = tfopen(outName, T("wb"));
782       if (!fp) {
783         tperror(outName);
784         exit(1);
785       }
786       setvbuf(fp, NULL, _IOFBF, 16384);
787 #ifdef XML_UNICODE
788       puttc(0xFEFF, fp);
789 #endif
790       XML_SetUserData(parser, fp);
791       switch (outputType) {
792       case 'm':
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,
801                                   metaEndDoctypeDecl);
802         XML_SetEntityDeclHandler(parser, metaEntityDecl);
803         XML_SetNotationDeclHandler(parser, metaNotationDecl);
804         XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl,
805                                     metaEndNamespaceDecl);
806         metaStartDocument(parser);
807         break;
808       case 'c':
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);
815         break;
816       default:
817         if (useNamespaces)
818           XML_SetElementHandler(parser, startElementNS, endElementNS);
819         else
820           XML_SetElementHandler(parser, startElement, endElement);
821         XML_SetCharacterDataHandler(parser, characterData);
822 #ifndef W3C14N
823         XML_SetProcessingInstructionHandler(parser, processingInstruction);
824 #endif /* not W3C14N */
825         break;
826       }
827     }
828     if (windowsCodePages)
829       XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0);
830     result = XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags);
831     if (outputDir) {
832       if (outputType == 'm')
833         metaEndDocument(parser);
834       fclose(fp);
835       if (!result)
836         tremove(outName);
837       free(outName);
838     }
839     XML_ParserFree(parser);
840   }
841   return 0;
842 }
843