Annotation of embedaddon/expat/xmlwf/xmlwf.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>