home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _415c26d9d861d32b24ec9d7832b730d1 < prev    next >
Text File  |  2004-06-01  |  21KB  |  843 lines

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