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