xmlwf.c 17 KB

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