1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/CTextParsers.cpp Mon Nov 06 10:57:37 2006 +0000
1.3 @@ -0,0 +1,286 @@
1.4 +#include <stdio.h>
1.5 +#include <ctype.h>
1.6 +#include <string.h>
1.7 +#include "CTextParsers.h"
1.8 +
1.9 +CTextParsers g_TextParse;
1.10 +
1.11 +static int g_ini_chartable1[255] = {0};
1.12 +
1.13 +CTextParsers::CTextParsers()
1.14 +{
1.15 + g_ini_chartable1['_'] = 1;
1.16 + g_ini_chartable1['-'] = 1;
1.17 + g_ini_chartable1[','] = 1;
1.18 + g_ini_chartable1['+'] = 1;
1.19 + g_ini_chartable1['.'] = 1;
1.20 + g_ini_chartable1['$'] = 1;
1.21 + g_ini_chartable1['?'] = 1;
1.22 + g_ini_chartable1['/'] = 1;
1.23 +}
1.24 +
1.25 +bool CTextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc_listener, unsigned int *line, unsigned int *col)
1.26 +{
1.27 + /* :TODO: Implement this */
1.28 + if (line)
1.29 + {
1.30 + *line = 0;
1.31 + }
1.32 +
1.33 + return false;
1.34 +}
1.35 +
1.36 +bool CTextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
1.37 +{
1.38 + FILE *fp = fopen(file, "rt");
1.39 + unsigned int curline = 0;
1.40 + unsigned int curtok;
1.41 + size_t len;
1.42 +
1.43 + if (!fp)
1.44 + {
1.45 + if (line)
1.46 + {
1.47 + *line = 0;
1.48 + }
1.49 +
1.50 + return false;
1.51 + }
1.52 +
1.53 + char buffer[2048];
1.54 + char *ptr, *save_ptr;
1.55 + bool in_quote;
1.56 + while (!feof(fp))
1.57 + {
1.58 + curline++;
1.59 + curtok = 0;
1.60 + buffer[0] = '\0';
1.61 + if (fgets(buffer, sizeof(buffer), fp) == NULL)
1.62 + {
1.63 + break;
1.64 + }
1.65 +
1.66 + /* Preprocess the string before anything */
1.67 + ptr = buffer;
1.68 +
1.69 + /* First strip beginning whitespace */
1.70 + while ((*ptr != '\0') && isspace(*ptr))
1.71 + {
1.72 + ptr++;
1.73 + }
1.74 +
1.75 + len = strlen(ptr);
1.76 +
1.77 + if (!len)
1.78 + {
1.79 + continue;
1.80 + }
1.81 +
1.82 + /* Now search for comment characters */
1.83 + in_quote = false;
1.84 + save_ptr = ptr;
1.85 + for (size_t i=0; i<len; i++,ptr++)
1.86 + {
1.87 + if (!in_quote)
1.88 + {
1.89 + switch (*ptr)
1.90 + {
1.91 + case '"':
1.92 + {
1.93 + in_quote = true;
1.94 + break;
1.95 + }
1.96 + case ';':
1.97 + {
1.98 + /* Stop the loop */
1.99 + len = i;
1.100 + /* Terminate the string here */
1.101 + *ptr = '\0';
1.102 + break;
1.103 + }
1.104 + }
1.105 + } else {
1.106 + if (*ptr == '"')
1.107 + {
1.108 + in_quote = false;
1.109 + }
1.110 + }
1.111 + }
1.112 +
1.113 + if (!len)
1.114 + {
1.115 + continue;
1.116 + }
1.117 +
1.118 + ptr = save_ptr;
1.119 +
1.120 + /* Lastly, strip ending whitespace off */
1.121 + for (size_t i=len-1; i>=0 && i<len; i--)
1.122 + {
1.123 + if (isspace(ptr[i]))
1.124 + {
1.125 + ptr[i] = '\0';
1.126 + len--;
1.127 + } else {
1.128 + break;
1.129 + }
1.130 + }
1.131 +
1.132 + if (!len)
1.133 + {
1.134 + continue;
1.135 + }
1.136 +
1.137 + if (!ini_listener->ReadINI_RawLine(ptr, &curtok))
1.138 + {
1.139 + goto event_failed;
1.140 + }
1.141 +
1.142 + if (*ptr == '[')
1.143 + {
1.144 + bool invalid_tokens = false;
1.145 + bool got_bracket = false;
1.146 + bool extra_tokens = false;
1.147 + char c;
1.148 +
1.149 + for (size_t i=1; i<len; i++)
1.150 + {
1.151 + c = ptr[i];
1.152 + if (!isalnum(c) && !g_ini_chartable1[c])
1.153 + {
1.154 + /* First check - is this a bracket? */
1.155 + if (c == ']')
1.156 + {
1.157 + /* Yes! */
1.158 + got_bracket = true;
1.159 + /* If this isn't the last character... */
1.160 + if (i != len - 1)
1.161 + {
1.162 + extra_tokens = true;
1.163 + }
1.164 + /* terminate */
1.165 + ptr[i] = '\0';
1.166 + break;
1.167 + } else {
1.168 + /* n...No! Continue copying. */
1.169 + invalid_tokens = true;
1.170 + }
1.171 + }
1.172 + }
1.173 +
1.174 + /* Tell the handler */
1.175 + if (!ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok))
1.176 + {
1.177 + goto event_failed;
1.178 + }
1.179 + } else {
1.180 + char *key_ptr = ptr;
1.181 + char *val_ptr = NULL;
1.182 + char c;
1.183 + size_t first_space = 0;
1.184 + bool invalid_tokens = false;
1.185 + bool equal_token = false;
1.186 + bool quotes = false;
1.187 +
1.188 + for (size_t i=0; i<len; i++)
1.189 + {
1.190 + c = ptr[i];
1.191 + /* is this an invalid char? */
1.192 + if (!isalnum(c) && !g_ini_chartable1[c])
1.193 + {
1.194 + if (isspace(c))
1.195 + {
1.196 + /* if it's a space, keep track of the last space */
1.197 + if (!first_space)
1.198 + {
1.199 + first_space = i;
1.200 + }
1.201 + } else {
1.202 + if (c == '=')
1.203 + {
1.204 + /* if it's an equal sign, we're done with the key */
1.205 + if (first_space)
1.206 + {
1.207 + /* remove excess whitespace */
1.208 + key_ptr[first_space] = '\0';
1.209 + } else {
1.210 + /* remove the equal sign */
1.211 + key_ptr[i] = '\0';
1.212 + }
1.213 + if (ptr[++i] != '\0')
1.214 + {
1.215 + /* If this isn't the end, set next pointer */
1.216 + val_ptr = &ptr[i];
1.217 + }
1.218 + equal_token = true;
1.219 + break;
1.220 + } else {
1.221 + /* Mark that we got something invalid! */
1.222 + invalid_tokens = true;
1.223 + first_space = 0;
1.224 + }
1.225 + }
1.226 + }
1.227 + }
1.228 +
1.229 + /* Now we need to parse the value, if any */
1.230 + if (val_ptr)
1.231 + {
1.232 + /* eat up spaces! there shouldn't be any h*/
1.233 + while ((*val_ptr != '\0') && isspace(*val_ptr))
1.234 + {
1.235 + val_ptr++;
1.236 + }
1.237 + if (*val_ptr == '\0')
1.238 + {
1.239 + val_ptr = NULL;
1.240 + goto skip_value;
1.241 + }
1.242 + /* Do we have an initial quote? If so, the parsing rules change! */
1.243 + if (*val_ptr == '"' && *val_ptr != '\0')
1.244 + {
1.245 + len = strlen(val_ptr);
1.246 + if (val_ptr[len-1] == '"')
1.247 + {
1.248 + /* Strip quotes! */
1.249 + val_ptr[--len] = '\0';
1.250 + val_ptr++;
1.251 + quotes = true;
1.252 + }
1.253 + }
1.254 + }
1.255 +skip_value:
1.256 + /* We're done! */
1.257 + curtok = val_ptr - buffer;
1.258 + if (!ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok))
1.259 + {
1.260 + curtok = 0;
1.261 + goto event_failed;
1.262 + }
1.263 + }
1.264 + }
1.265 +
1.266 + if (line)
1.267 + {
1.268 + *line = curline;
1.269 + }
1.270 +
1.271 + fclose(fp);
1.272 +
1.273 + return true;
1.274 +
1.275 +event_failed:
1.276 + if (line)
1.277 + {
1.278 + *line = curline;
1.279 + }
1.280 +
1.281 + if (col)
1.282 + {
1.283 + *col = curtok;
1.284 + }
1.285 +
1.286 + fclose(fp);
1.287 +
1.288 + return false;
1.289 +}