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