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

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);
        !           852:       if (!result)
        !           853:         tremove(outName);
        !           854:       free(outName);
        !           855:     }
        !           856:     XML_ParserFree(parser);
        !           857:   }
        !           858:   return 0;
        !           859: }

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