6 #include "CTextParsers.h"
8 CTextParsers g_TextParse;
10 static int g_ini_chartable1[255] = {0};
11 static int g_ws_chartable[255] = {0};
13 CTextParsers::CTextParsers()
15 g_ini_chartable1['_'] = 1;
16 g_ini_chartable1['-'] = 1;
17 g_ini_chartable1[','] = 1;
18 g_ini_chartable1['+'] = 1;
19 g_ini_chartable1['.'] = 1;
20 g_ini_chartable1['$'] = 1;
21 g_ini_chartable1['?'] = 1;
22 g_ini_chartable1['/'] = 1;
23 g_ws_chartable['\n'] = 1;
24 g_ws_chartable['\v'] = 1;
25 g_ws_chartable['\r'] = 1;
26 g_ws_chartable['\t'] = 1;
27 g_ws_chartable['\f'] = 1;
28 g_ws_chartable[' '] = 1;
31 unsigned int CTextParsers::GetUTF8CharBytes(const char *stream)
33 return _GetUTF8CharBytes(stream);
36 bool CTextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc_listener, unsigned int *line, unsigned int *col, bool strict)
38 /* This beast is a lot more rigorous than our INI friend. */
43 bool CTextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
45 FILE *fp = fopen(file, "rt");
46 unsigned int curline = 0;
69 if (fgets(buffer, sizeof(buffer), fp) == NULL)
74 //:TODO: this will only run once, so find a nice way to move it out of the while loop
75 /* If this is the first line, check the first three bytes for BOM */
77 buffer[0] == (char)0xEF &&
78 buffer[1] == (char)0xBB &&
79 buffer[2] == (char)0xBF)
81 /* We have a UTF-8 marked file... skip these bytes */
87 /***************************************************
88 * We preprocess the string before parsing tokens! *
89 ***************************************************/
91 /* First strip beginning whitespace */
92 while (*ptr != '\0' && g_ws_chartable[*ptr] != 0)
104 /* Now search for comment characters */
107 for (size_t i=0; i<len; i++,ptr++)
122 /* Terminate the string here */
142 /* Lastly, strip ending whitespace off */
143 for (size_t i=len-1; i>=0 && i<len; i--)
145 if (g_ws_chartable[ptr[i]])
159 if (!ini_listener->ReadINI_RawLine(ptr, &curtok))
166 bool invalid_tokens = false;
167 bool got_bracket = false;
168 bool extra_tokens = false;
173 for (size_t i=1; i<len; i++)
180 if (mbtowc(&wc, &ptr[i], len-i) != -1)
182 alnum = (iswalnum(wc) != 0);
183 i += _GetUTF8CharBytes(&ptr[i]) - 1;
186 alnum = (isalnum(c) != 0) || (g_ini_chartable1[c] != 0);
190 /* First check - is this a bracket? */
195 /* If this isn't the last character... */
204 /* n...No! Continue copying. */
205 invalid_tokens = true;
210 /* Tell the handler */
211 if (!ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok))
217 char *val_ptr = NULL;
219 size_t first_space = 0;
220 bool invalid_tokens = false;
221 bool equal_token = false;
226 for (size_t i=0; i<len; i++)
230 /* is this an invalid char? */
233 if (mbtowc(&wc, &ptr[i], len-i) != -1)
235 alnum = (iswalnum(wc) != 0);
236 i += _GetUTF8CharBytes(&ptr[i]) - 1;
239 alnum = (isalnum(c) != 0) || (g_ini_chartable1[c] != 0);
244 if (g_ws_chartable[c])
246 /* if it's a space, keep track of the first occurring space */
254 /* if it's an equal sign, we're done with the key */
257 /* remove excess whitespace */
258 key_ptr[first_space] = '\0';
260 /* remove the equal sign */
263 if (ptr[++i] != '\0')
265 /* If this isn't the end, set next pointer */
271 /* Mark that we got something invalid! */
272 invalid_tokens = true;
279 /* Now we need to parse the value, if any */
282 /* eat up spaces! there shouldn't be any h*/
283 while ((*val_ptr != '\0') && g_ws_chartable[*val_ptr] != 0)
287 if (*val_ptr == '\0')
292 /* Do we have an initial quote? If so, the parsing rules change! */
293 if (*val_ptr == '"' && *val_ptr != '\0')
295 len = strlen(val_ptr);
296 if (val_ptr[len-1] == '"')
299 val_ptr[--len] = '\0';
307 curtok = val_ptr - buffer;
308 if (!ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok))