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