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