|
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 #ifdef AMIGA_SHARED_LIB |
|
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 = (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 = (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], 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, 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, 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, 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, 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, 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, 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 += 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 #ifdef WIN32 |
|
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 #ifdef AMIGA_SHARED_LIB |
|
643 int |
|
644 amiga_main(int argc, char *argv[]) |
|
645 #else |
|
646 int |
|
647 tmain(int argc, XML_Char **argv) |
|
648 #endif |
|
649 { |
|
650 int i, j; |
|
651 const XML_Char *outputDir = NULL; |
|
652 const XML_Char *encoding = NULL; |
|
653 unsigned processFlags = XML_MAP_FILE; |
|
654 int windowsCodePages = 0; |
|
655 int outputType = 0; |
|
656 int useNamespaces = 0; |
|
657 int requireStandalone = 0; |
|
658 enum XML_ParamEntityParsing paramEntityParsing = |
|
659 XML_PARAM_ENTITY_PARSING_NEVER; |
|
660 int useStdin = 0; |
|
661 |
|
662 #ifdef _MSC_VER |
|
663 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); |
|
664 #endif |
|
665 |
|
666 i = 1; |
|
667 j = 0; |
|
668 while (i < argc) { |
|
669 if (j == 0) { |
|
670 if (argv[i][0] != T('-')) |
|
671 break; |
|
672 if (argv[i][1] == T('-') && argv[i][2] == T('\0')) { |
|
673 i++; |
|
674 break; |
|
675 } |
|
676 j++; |
|
677 } |
|
678 switch (argv[i][j]) { |
|
679 case T('r'): |
|
680 processFlags &= ~XML_MAP_FILE; |
|
681 j++; |
|
682 break; |
|
683 case T('s'): |
|
684 requireStandalone = 1; |
|
685 j++; |
|
686 break; |
|
687 case T('n'): |
|
688 useNamespaces = 1; |
|
689 j++; |
|
690 break; |
|
691 case T('p'): |
|
692 paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS; |
|
693 /* fall through */ |
|
694 case T('x'): |
|
695 processFlags |= XML_EXTERNAL_ENTITIES; |
|
696 j++; |
|
697 break; |
|
698 case T('w'): |
|
699 windowsCodePages = 1; |
|
700 j++; |
|
701 break; |
|
702 case T('m'): |
|
703 outputType = 'm'; |
|
704 j++; |
|
705 break; |
|
706 case T('c'): |
|
707 outputType = 'c'; |
|
708 useNamespaces = 0; |
|
709 j++; |
|
710 break; |
|
711 case T('t'): |
|
712 outputType = 't'; |
|
713 j++; |
|
714 break; |
|
715 case T('d'): |
|
716 if (argv[i][j + 1] == T('\0')) { |
|
717 if (++i == argc) |
|
718 usage(argv[0], 2); |
|
719 outputDir = argv[i]; |
|
720 } |
|
721 else |
|
722 outputDir = argv[i] + j + 1; |
|
723 i++; |
|
724 j = 0; |
|
725 break; |
|
726 case T('e'): |
|
727 if (argv[i][j + 1] == T('\0')) { |
|
728 if (++i == argc) |
|
729 usage(argv[0], 2); |
|
730 encoding = argv[i]; |
|
731 } |
|
732 else |
|
733 encoding = argv[i] + j + 1; |
|
734 i++; |
|
735 j = 0; |
|
736 break; |
|
737 case T('h'): |
|
738 usage(argv[0], 0); |
|
739 return 0; |
|
740 case T('v'): |
|
741 showVersion(argv[0]); |
|
742 return 0; |
|
743 case T('\0'): |
|
744 if (j > 1) { |
|
745 i++; |
|
746 j = 0; |
|
747 break; |
|
748 } |
|
749 /* fall through */ |
|
750 default: |
|
751 usage(argv[0], 2); |
|
752 } |
|
753 } |
|
754 if (i == argc) { |
|
755 useStdin = 1; |
|
756 processFlags &= ~XML_MAP_FILE; |
|
757 i--; |
|
758 } |
|
759 for (; i < argc; i++) { |
|
760 FILE *fp = 0; |
|
761 XML_Char *outName = 0; |
|
762 int result; |
|
763 XML_Parser parser; |
|
764 if (useNamespaces) |
|
765 parser = XML_ParserCreateNS(encoding, NSSEP); |
|
766 else |
|
767 parser = XML_ParserCreate(encoding); |
|
768 if (requireStandalone) |
|
769 XML_SetNotStandaloneHandler(parser, notStandalone); |
|
770 XML_SetParamEntityParsing(parser, paramEntityParsing); |
|
771 if (outputType == 't') { |
|
772 /* This is for doing timings; this gives a more realistic estimate of |
|
773 the parsing time. */ |
|
774 outputDir = 0; |
|
775 XML_SetElementHandler(parser, nopStartElement, nopEndElement); |
|
776 XML_SetCharacterDataHandler(parser, nopCharacterData); |
|
777 XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction); |
|
778 } |
|
779 else if (outputDir) { |
|
780 const XML_Char *file = useStdin ? T("STDIN") : argv[i]; |
|
781 if (tcsrchr(file, T('/'))) |
|
782 file = tcsrchr(file, T('/')) + 1; |
|
783 #ifdef WIN32 |
|
784 if (tcsrchr(file, T('\\'))) |
|
785 file = tcsrchr(file, T('\\')) + 1; |
|
786 #endif |
|
787 outName = (XML_Char *)malloc((tcslen(outputDir) + tcslen(file) + 2) |
|
788 * sizeof(XML_Char)); |
|
789 tcscpy(outName, outputDir); |
|
790 tcscat(outName, T("/")); |
|
791 tcscat(outName, file); |
|
792 fp = tfopen(outName, T("wb")); |
|
793 if (!fp) { |
|
794 tperror(outName); |
|
795 exit(1); |
|
796 } |
|
797 setvbuf(fp, NULL, _IOFBF, 16384); |
|
798 #ifdef XML_UNICODE |
|
799 puttc(0xFEFF, fp); |
|
800 #endif |
|
801 XML_SetUserData(parser, fp); |
|
802 switch (outputType) { |
|
803 case 'm': |
|
804 XML_UseParserAsHandlerArg(parser); |
|
805 XML_SetElementHandler(parser, metaStartElement, metaEndElement); |
|
806 XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction); |
|
807 XML_SetCommentHandler(parser, metaComment); |
|
808 XML_SetCdataSectionHandler(parser, metaStartCdataSection, |
|
809 metaEndCdataSection); |
|
810 XML_SetCharacterDataHandler(parser, metaCharacterData); |
|
811 XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl, |
|
812 metaEndDoctypeDecl); |
|
813 XML_SetEntityDeclHandler(parser, metaEntityDecl); |
|
814 XML_SetNotationDeclHandler(parser, metaNotationDecl); |
|
815 XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl, |
|
816 metaEndNamespaceDecl); |
|
817 metaStartDocument(parser); |
|
818 break; |
|
819 case 'c': |
|
820 XML_UseParserAsHandlerArg(parser); |
|
821 XML_SetDefaultHandler(parser, markup); |
|
822 XML_SetElementHandler(parser, defaultStartElement, defaultEndElement); |
|
823 XML_SetCharacterDataHandler(parser, defaultCharacterData); |
|
824 XML_SetProcessingInstructionHandler(parser, |
|
825 defaultProcessingInstruction); |
|
826 break; |
|
827 default: |
|
828 if (useNamespaces) |
|
829 XML_SetElementHandler(parser, startElementNS, endElementNS); |
|
830 else |
|
831 XML_SetElementHandler(parser, startElement, endElement); |
|
832 XML_SetCharacterDataHandler(parser, characterData); |
|
833 #ifndef W3C14N |
|
834 XML_SetProcessingInstructionHandler(parser, processingInstruction); |
|
835 #endif /* not W3C14N */ |
|
836 break; |
|
837 } |
|
838 } |
|
839 if (windowsCodePages) |
|
840 XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0); |
|
841 result = XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags); |
|
842 if (outputDir) { |
|
843 if (outputType == 'm') |
|
844 metaEndDocument(parser); |
|
845 fclose(fp); |
|
846 if (!result) |
|
847 tremove(outName); |
|
848 free(outName); |
|
849 } |
|
850 XML_ParserFree(parser); |
|
851 } |
|
852 return 0; |
|
853 } |