xml/xmlexpatparser/src/expat-1.95.5/xmlwf/xmlfile.c
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
       
     2    See the file COPYING for copying permission.
       
     3 */
       
     4 
       
     5 #include <stdio.h>
       
     6 #include <stdlib.h>
       
     7 #include <stddef.h>
       
     8 #include <string.h>
       
     9 #include <fcntl.h>
       
    10 #ifdef COMPILED_FROM_DSP
       
    11 #include "winconfig.h"
       
    12 #else
       
    13 #include "expat_config.h"
       
    14 #endif
       
    15 #include "expat.h"
       
    16 #include "xmlfile.h"
       
    17 #include "xmltchar.h"
       
    18 #include "filemap.h"
       
    19 
       
    20 #ifdef _MSC_VER
       
    21 #include <io.h>
       
    22 #endif
       
    23 
       
    24 #ifdef HAVE_UNISTD_H
       
    25 #include <unistd.h>
       
    26 #endif
       
    27 
       
    28 #ifndef O_BINARY
       
    29 #ifdef _O_BINARY
       
    30 #define O_BINARY _O_BINARY
       
    31 #else
       
    32 #define O_BINARY 0
       
    33 #endif
       
    34 #endif
       
    35 
       
    36 #ifdef _DEBUG
       
    37 #define READ_SIZE 16
       
    38 #else
       
    39 #define READ_SIZE (1024*8)
       
    40 #endif
       
    41 
       
    42 
       
    43 typedef struct {
       
    44   XML_Parser parser;
       
    45   int *retPtr;
       
    46 } PROCESS_ARGS;
       
    47 
       
    48 static void
       
    49 reportError(XML_Parser parser, const XML_Char *filename)
       
    50 {
       
    51   int code = XML_GetErrorCode(parser);
       
    52   const XML_Char *message = XML_ErrorString(code);
       
    53   if (message)
       
    54     ftprintf(stdout, T("%s:%d:%d: %s\n"),
       
    55              filename,
       
    56              XML_GetErrorLineNumber(parser),
       
    57              XML_GetErrorColumnNumber(parser),
       
    58              message);
       
    59   else
       
    60     ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code);
       
    61 }
       
    62 
       
    63 static void
       
    64 processFile(const void *data, size_t size,
       
    65             const XML_Char *filename, void *args)
       
    66 {
       
    67   XML_Parser parser = ((PROCESS_ARGS *)args)->parser;
       
    68   int *retPtr = ((PROCESS_ARGS *)args)->retPtr;
       
    69   if (XML_Parse(parser, data, size, 1) == XML_STATUS_ERROR) {
       
    70     reportError(parser, filename);
       
    71     *retPtr = 0;
       
    72   }
       
    73   else
       
    74     *retPtr = 1;
       
    75 }
       
    76 
       
    77 #ifdef WIN32
       
    78 
       
    79 static int
       
    80 isAsciiLetter(XML_Char c)
       
    81 {
       
    82   return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z'));
       
    83 }
       
    84 
       
    85 #endif /* WIN32 */
       
    86 
       
    87 static const XML_Char *
       
    88 resolveSystemId(const XML_Char *base, const XML_Char *systemId,
       
    89                 XML_Char **toFree)
       
    90 {
       
    91   XML_Char *s;
       
    92   *toFree = 0;
       
    93   if (!base
       
    94       || *systemId == T('/')
       
    95 #ifdef WIN32
       
    96       || *systemId == T('\\')
       
    97       || (isAsciiLetter(systemId[0]) && systemId[1] == T(':'))
       
    98 #endif
       
    99      )
       
   100     return systemId;
       
   101   *toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)
       
   102                                * sizeof(XML_Char));
       
   103   if (!*toFree)
       
   104     return systemId;
       
   105   tcscpy(*toFree, base);
       
   106   s = *toFree;
       
   107   if (tcsrchr(s, T('/')))
       
   108     s = tcsrchr(s, T('/')) + 1;
       
   109 #ifdef WIN32
       
   110   if (tcsrchr(s, T('\\')))
       
   111     s = tcsrchr(s, T('\\')) + 1;
       
   112 #endif
       
   113   tcscpy(s, systemId);
       
   114   return *toFree;
       
   115 }
       
   116 
       
   117 static int
       
   118 externalEntityRefFilemap(XML_Parser parser,
       
   119                          const XML_Char *context,
       
   120                          const XML_Char *base,
       
   121                          const XML_Char *systemId,
       
   122                          const XML_Char *publicId)
       
   123 {
       
   124   int result;
       
   125   XML_Char *s;
       
   126   const XML_Char *filename;
       
   127   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
       
   128   PROCESS_ARGS args;
       
   129   args.retPtr = &result;
       
   130   args.parser = entParser;
       
   131   filename = resolveSystemId(base, systemId, &s);
       
   132   XML_SetBase(entParser, filename);
       
   133   if (!filemap(filename, processFile, &args))
       
   134     result = 0;
       
   135   free(s);
       
   136   XML_ParserFree(entParser);
       
   137   return result;
       
   138 }
       
   139 
       
   140 static int
       
   141 processStream(const XML_Char *filename, XML_Parser parser)
       
   142 {
       
   143   /* passing NULL for filename means read intput from stdin */
       
   144   int fd = 0;   /* 0 is the fileno for stdin */
       
   145 
       
   146   if (filename != NULL) {
       
   147     fd = topen(filename, O_BINARY|O_RDONLY);
       
   148     if (fd < 0) {
       
   149       tperror(filename);
       
   150       return 0;
       
   151     }
       
   152   }
       
   153   for (;;) {
       
   154     int nread;
       
   155     char *buf = XML_GetBuffer(parser, READ_SIZE);
       
   156     if (!buf) {
       
   157       if (filename != NULL)
       
   158         close(fd);
       
   159       ftprintf(stderr, T("%s: out of memory\n"),
       
   160                filename != NULL ? filename : "xmlwf");
       
   161       return 0;
       
   162     }
       
   163     nread = read(fd, buf, READ_SIZE);
       
   164     if (nread < 0) {
       
   165       tperror(filename != NULL ? filename : "STDIN");
       
   166       if (filename != NULL)
       
   167         close(fd);
       
   168       return 0;
       
   169     }
       
   170     if (XML_ParseBuffer(parser, nread, nread == 0) == XML_STATUS_ERROR) {
       
   171       reportError(parser, filename != NULL ? filename : "STDIN");
       
   172       if (filename != NULL)
       
   173         close(fd);
       
   174       return 0;
       
   175     }
       
   176     if (nread == 0) {
       
   177       if (filename != NULL)
       
   178         close(fd);
       
   179       break;;
       
   180     }
       
   181   }
       
   182   return 1;
       
   183 }
       
   184 
       
   185 static int
       
   186 externalEntityRefStream(XML_Parser parser,
       
   187                         const XML_Char *context,
       
   188                         const XML_Char *base,
       
   189                         const XML_Char *systemId,
       
   190                         const XML_Char *publicId)
       
   191 {
       
   192   XML_Char *s;
       
   193   const XML_Char *filename;
       
   194   int ret;
       
   195   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
       
   196   filename = resolveSystemId(base, systemId, &s);
       
   197   XML_SetBase(entParser, filename);
       
   198   ret = processStream(filename, entParser);
       
   199   free(s);
       
   200   XML_ParserFree(entParser);
       
   201   return ret;
       
   202 }
       
   203 
       
   204 int
       
   205 XML_ProcessFile(XML_Parser parser,
       
   206                 const XML_Char *filename,
       
   207                 unsigned flags)
       
   208 {
       
   209   int result;
       
   210 
       
   211   if (!XML_SetBase(parser, filename)) {
       
   212     ftprintf(stderr, T("%s: out of memory"), filename);
       
   213     exit(1);
       
   214   }
       
   215 
       
   216   if (flags & XML_EXTERNAL_ENTITIES)
       
   217       XML_SetExternalEntityRefHandler(parser,
       
   218                                       (flags & XML_MAP_FILE)
       
   219                                       ? externalEntityRefFilemap
       
   220                                       : externalEntityRefStream);
       
   221   if (flags & XML_MAP_FILE) {
       
   222     PROCESS_ARGS args;
       
   223     args.retPtr = &result;
       
   224     args.parser = parser;
       
   225     if (!filemap(filename, processFile, &args))
       
   226       result = 0;
       
   227   }
       
   228   else
       
   229     result = processStream(filename, parser);
       
   230   return result;
       
   231 }