changed copyright years in source files
[fegdk.git] / core / code / system / parser.cpp
blob1b55ac76618f25273e7a38a8c58c2f9fdc48c020
1 #include "f_parser.h"
3 namespace fe {
5 void charParser::errMode (int mode) {
6 mErrMode = mode;
9 charParser::charParser (
10 #ifndef FE_NO_FILESYSTEM
11 fileSystem *fs, const char *buffer, bool stdio, int size
12 #else
13 const char *buffer, int size
14 #endif
17 #ifndef FE_NO_FILESYSTEM
18 mpFileSystem = fs;
19 #else
20 bool stdio = true;
21 #endif
22 mErrMode = 1;
23 mpBuffer = NULL;
24 mpScript = NULL;
25 mBufferSize = 0;
26 mbTokenReady = false;
27 mbSTDIO = stdio;
28 mpToken = mToken;
29 if (size == -1)
31 strncpy (mFileName, buffer, PARSER_MAXFNAME);
33 else
35 mpBuffer = mpScript = (char*)buffer;
36 mBufferSize = size;
37 mpEnd = mpBuffer + size;
38 mLine = 0;
42 charParser::~charParser ()
44 if (mbSTDIO && mpFileSTDIO) {
45 fclose (mpFileSTDIO);
46 mpFileSTDIO = NULL;
48 #ifndef FE_NO_FILESYSTEM
49 else if (!mbSTDIO && mpFile) {
50 mpFile->close ();
51 mpFile = NULL;
53 #endif
56 int charParser::readNextChunk (void) {
57 if (!mpBuffer) {
58 mpBuffer = mBuffer;
59 if (mbSTDIO) {
60 mpFileSTDIO = fopen (mFileName, "rb");
61 if (!mpFileSTDIO) {
62 sys_printf ("ERROR: failed to open file %s\n", mFileName);
63 if (mErrMode) error ();
64 return FILE_NOT_FOUND;
66 fseek (mpFileSTDIO, 0, SEEK_END);
67 mFileLeft = ftell (mpFileSTDIO);
68 rewind (mpFileSTDIO);
69 mpScript = mpBuffer;
70 mpEnd = mpBuffer + mBufferSize;
71 mLine = 0;
73 else {
74 #ifndef FE_NO_FILESYSTEM
75 mpFile = mpFileSystem->openFile (mFileName);
76 if (!mpFile) {
77 sys_printf ("ERROR: failed to open file %s\n", mFileName);
78 if (mErrMode) error ();
79 return FILE_NOT_FOUND;
81 mFileLeft = mpFile->getSize ();
82 mpScript = mpBuffer;
83 mpEnd = mpBuffer + mBufferSize;
84 mLine = 0;
85 #else
86 sys_printf ("ERROR: fe::filesystem is not available in this build\n");
87 if (mErrMode) error ();
88 return FEATURE_NOT_INCLUDED;
89 #endif
92 if (mpScript != mpBuffer) {
93 mpScript = mpBuffer;
95 int sz = min (mFileLeft, PARSER_BUFSIZE);
96 if (mbSTDIO) {
97 if (fread (mpScript, sz, 1, mpFileSTDIO) != 1) {
98 sys_printf ("ERROR: failed to read from file %s\n", mFileName);
99 if (mErrMode) error ();
100 return READ_ERROR;
103 else {
104 if (mpFile->read (mpScript, sz) != sz) {
105 sys_printf ("ERROR: failed to read from file %s\n", mFileName);
106 if (mErrMode) error ();
107 return READ_ERROR;
110 mpEnd = mpScript + sz;
111 mFileLeft -= sz;
112 return 0;
115 int charParser::checkEOF (void) {
116 if (mpScript == mpEnd) {
117 if (mFileLeft) {
118 // read next chunk
119 int res = readNextChunk ();
120 if (res)
121 return res;
123 else {
124 if (mErrMode) error ();
125 return END_OF_FILE;
128 return 0;
131 int charParser::getToken (void)
133 int res;
134 if (!mpScript) {
135 // load data
136 res = readNextChunk ();
137 if (res)
138 return res;
140 if (mbTokenReady)
142 mbTokenReady = false;
143 return 0;
146 if (checkEOF ()) return END_OF_FILE;
148 // skip spaces
149 for (;;)
151 while (mpScript < mpEnd && *mpScript <= 32)
153 if (*mpScript++ == '\n') {
154 mLine++;
156 if (checkEOF ()) return END_OF_FILE;
159 // # comments
160 if (*mpScript == '#')
162 while (mpScript < mpEnd && *mpScript++ != '\n') {
163 if (checkEOF ()) return END_OF_FILE;
165 mLine++;
166 continue;
168 break;
171 mpToken = mToken;
173 if (*mpScript == '"')
175 // quoted token
176 mpScript++;
177 if (checkEOF ()) return END_OF_FILE;
178 while (*mpScript != '"')
180 if (mpToken - mToken == PARSER_MAXTOKEN)
182 *mpToken = 0;
183 sys_printf ("ERROR: token too large in file %s line %i, token: %s\n", mFileName, mLine, mToken);
184 if (mErrMode) exit(-1);
185 return TOKEN_TOO_LARGE;
187 *mpToken++ = *mpScript++;
188 if (checkEOF ()) return END_OF_FILE;
190 mpScript++;
192 else
194 // separator
195 if (*mpScript == '{'
196 || *mpScript == '}'
197 || *mpScript == '['
198 || *mpScript == ']'
199 || *mpScript == '('
200 || *mpScript == ')'
201 || *mpScript == '<'
202 || *mpScript == '>'
203 || *mpScript == ';'
204 || *mpScript == '+'
207 *mpToken++ = *mpScript++;
209 else
210 // regular mToken
211 while (*mpScript > 32
212 && *mpScript != '{'
213 && *mpScript != '}'
214 && *mpScript != '['
215 && *mpScript != ']'
216 && *mpScript != '('
217 && *mpScript != ')'
218 && *mpScript != '<'
219 && *mpScript != '>'
220 && *mpScript != ';'
221 && *mpScript != '+'
224 if (mpToken - mToken == PARSER_MAXTOKEN)
226 *mpToken = 0;
227 sys_printf ("ERROR: token too large in file %s line %i\n", mFileName, mLine);
228 if (mErrMode) exit(-1);
229 return TOKEN_TOO_LARGE;
231 *mpToken++ = *mpScript++;
232 if (checkEOF ())
233 break; // reached EOF while reading token, this is not an error
236 *mpToken = 0;
237 return 0;
240 void charParser::unGetToken ()
242 mbTokenReady = true;
245 bool charParser::hasToken ()
247 int oldLine;
249 bool r;
251 oldLine = mLine;
253 r = getToken ();
255 if (!r)
256 return false;
258 unGetToken ();
260 if (oldLine == mLine)
261 return true;
263 return false;
266 int charParser::matchToken (const char *match)
268 int res;
269 res = getToken ();
270 if (res)
271 return res;
273 const char *p1, *p2;
274 p1 = mToken;
275 p2 = match;
276 while (*p1 && *p2) {
277 if (*p1 != *p2)
279 sys_printf ("WARNING: unmatched token %s (expected %s) in file %s line %d\n", mToken, match, mFileName, mLine);
280 if (mErrMode) exit(-1);
281 return TOKEN_MISMATCH;
283 p1++;
284 p2++;
286 return 0;
289 void charParser::nextLine (void)
291 int line = mLine;
292 while (line == mLine)
293 getToken ();
294 unGetToken ();
297 void charParser::ignoreBlock (const cStr &opentag, const cStr &closetag)
299 int opens = 1;
300 while (opens)
302 getToken ();
303 if (!cmptoken (opentag))
304 opens++;
305 else if (!cmptoken (closetag))
306 opens--;
310 void charParser::getBlockContents (const cStr &opentag, const cStr &closetag, cStr &block)
312 int opens = 1;
313 int ln = -1;
314 block = "";
315 while (opens)
317 bool add = true;
318 getToken ();
319 if (!cmptoken (opentag))
321 opens++;
323 else if (!cmptoken (closetag))
325 if (--opens == 0)
326 add = false;
328 if (mLine != ln)
330 ln = mLine;
331 block += "\r\n";
333 else
334 block += " ";
335 if (add)
336 block += token ();
340 const char *charParser::token (void) const
342 return mToken;
345 bool charParser::cmptoken (const char *s) const
347 return strcmp (s, mToken) ? true : false;
350 bool charParser::isEOL (void)
352 if (checkEOF ()) return true;
353 while (*mpScript <= 32)
355 if (*mpScript == '\n')
356 return true;
357 mpScript++;
358 if (checkEOF ()) return true;
360 return false;
363 void charParser::unexpectedEof (void)
365 sys_printf ("ERROR: unexpected end of file %s, line %d\n", mFileName, mLine);
368 void charParser::generalSyntaxError (void)
370 sys_printf ("ERROR: syntax error in file %s, line %d\n", mFileName, mLine);
373 void charParser::error (void) {
374 sys_printf ("ERROR: error loading file %s at line %d\n", mFileName, mLine);
375 sys_exit (-1);