Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

747 lines
18 KiB

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