home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _d190e23da0f49588d3d26b28b6f62d72 < prev    next >
Encoding:
Text File  |  2004-06-01  |  5.6 KB  |  232 lines

  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. }
  232.