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