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