| 276 | */ |
| 277 | |
| 278 | ConfigFile::LineType ConfigFile::parseLine(const char* fileName, const String& inputPar, Parameter& par) |
| 279 | { |
| 280 | int inString = 0; |
| 281 | String::size_type valStart = 0; |
| 282 | String::size_type eol = String::npos; |
| 283 | String input = inputPar; |
| 284 | bool hasSub = false; |
| 285 | const char* include = "include"; |
| 286 | const unsigned incLen = static_cast<unsigned>(strlen(include)); |
| 287 | |
| 288 | for (String::size_type n = 0; n < input.length(); ++n) |
| 289 | { |
| 290 | switch (input[n]) |
| 291 | { |
| 292 | case '"': |
| 293 | if (par.name.isEmpty()) // quoted string to the left of = doesn't make sense |
| 294 | return LINE_BAD; |
| 295 | if (inString >= 2) // one more quote after quoted string doesn't make sense |
| 296 | return LINE_BAD; |
| 297 | inString++; |
| 298 | break; |
| 299 | |
| 300 | case '=': |
| 301 | if (par.name.isEmpty()) |
| 302 | { |
| 303 | par.name = input.substr(0, n).ToNoCaseString(); |
| 304 | par.name.rtrim(" \t\r"); |
| 305 | if (par.name.isEmpty()) // not good - no key |
| 306 | return LINE_BAD; |
| 307 | valStart = n + 1; |
| 308 | par.hasValue = true; |
| 309 | } |
| 310 | else if (inString >= 2) // Something after the end of line |
| 311 | return LINE_BAD; |
| 312 | break; |
| 313 | |
| 314 | case '#': |
| 315 | if (flags & NO_COMMENTS) |
| 316 | { |
| 317 | if (inString >= 2) // Something after the end of line |
| 318 | return LINE_BAD; |
| 319 | break; |
| 320 | } |
| 321 | if (inString != 1) |
| 322 | { |
| 323 | eol = n; |
| 324 | n = input.length(); // skip the rest of symbols |
| 325 | } |
| 326 | break; |
| 327 | |
| 328 | case ' ': |
| 329 | case '\t': |
| 330 | if (n == incLen && par.name.isEmpty()) |
| 331 | { |
| 332 | KeyType inc = input.substr(0, n).ToNoCaseString(); |
| 333 | if (inc == include) |
| 334 | { |
| 335 | par.value = input.substr(n); |