/3rdparty/expat-2.0.1/xmlwf/xmlfile.c

https://github.com/neojjang/moai-beta · C · 244 lines · 216 code · 23 blank · 5 comment · 50 complexity · 742102e18fd43a28b8c98c570f9538f0 MD5 · raw file

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