xml/xmlexpatparser/src/expat-1.95.5/xmlwf/xmlwf.c
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     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("&amp;"), fp);
       
    31       break;
       
    32     case T('<'):
       
    33       fputts(T("&lt;"), fp);
       
    34       break;
       
    35     case T('>'):
       
    36       fputts(T("&gt;"), fp);
       
    37       break;
       
    38 #ifdef W3C14N
       
    39     case 13:
       
    40       fputts(T("&#xD;"), fp);
       
    41       break;
       
    42 #else
       
    43     case T('"'):
       
    44       fputts(T("&quot;"), 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("&amp;"), fp);
       
    72       break;
       
    73     case T('<'):
       
    74       fputts(T("&lt;"), fp);
       
    75       break;
       
    76     case T('"'):
       
    77       fputts(T("&quot;"), fp);
       
    78       break;
       
    79 #ifdef W3C14N
       
    80     case 9:
       
    81       fputts(T("&#x9;"), fp);
       
    82       break;
       
    83     case 10:
       
    84       fputts(T("&#xA;"), fp);
       
    85       break;
       
    86     case 13:
       
    87       fputts(T("&#xD;"), fp);
       
    88       break;
       
    89 #else
       
    90     case T('>'):
       
    91       fputts(T("&gt;"), 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 }