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