xmlwf.c 21 KB

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