aboutsummaryrefslogtreecommitdiff
path: root/common/xmlparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/xmlparser.cpp')
-rw-r--r--common/xmlparser.cpp85
1 files changed, 69 insertions, 16 deletions
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index 7728d90d48..de10269cdb 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -36,35 +36,86 @@ using namespace Graphics;
void XMLParser::debug_testEval() {
static const char *debugConfigText =
- "</* lol this is just a moronic test */drawdata id = \"background_default\" cache = true>\n"
- "<drawstep func = \"roundedsq\" fill = \"gradient\" gradient_start = \"255, 255, 128\" gradient_end = \"128, 128, 128\" size = \"auto\"/>\n"
+ "</* lol this is just a moronic test */drawdata id = \"mainmenu_bg\" cache = true>\n"
+ "<drawstep| func = \"roundedsq\" fill = \"gradient\" gradient_start = \"255, 255, 128\" gradient_end = \"128, 128, 128\" size = \"auto\"/>\n"
"//<drawstep func = \"roundedsq\" fill = \"none\" color = /*\"0, 0, 0\"*/\"0, 1, 2\" size = \"auto\"/>\n"
"</ drawdata>/* lol this is just a simple test*/\n";
_text = strdup(debugConfigText);
+ _fileName = strdup("test_parse.xml");
Common::String test = "12, 125, 125";
- printf("\n\nRegex result: %s.\n\n", test.regexMatch("^[d]*,[d]*,[d]*$", true) ? "Success." : "Fail");
-
parse();
}
-void XMLParser::parserError(const char *error_string) {
+void XMLParser::parserError(const char *error_string, ...) {
_state = kParserError;
- printf("PARSER ERROR: %s\n", error_string);
+
+ int pos = _pos;
+ int line_count = 1;
+ int line_start = -1;
+ int line_width = 1;
+
+ do {
+ if (_text[pos] == '\n' || _text[pos] == '\r') {
+ line_count++;
+
+ if (line_start == -1)
+ line_start = pos;
+ }
+ } while (pos-- > 0);
+
+ line_start = MAX(line_start, _pos - 80);
+
+ do {
+ if (_text[line_start + line_width] == '\n' || _text[line_start + line_width] == '\r')
+ break;
+ } while (_text[line_start + line_width++]);
+
+ line_width = MIN(line_width, 80);
+
+ char linestr[81];
+ strncpy(linestr, &_text[line_start] + 1, line_width );
+ linestr[line_width - 1] = 0;
+
+ printf(" File <%s>, line %d:\n", _fileName, line_count);
+
+ printf("%s\n", linestr);
+ for (int i = 1; i < _pos - line_start; ++i)
+ printf(" ");
+
+ printf("^\n");
+ printf("Parser error: ");
+
+ va_list args;
+ va_start(args, error_string);
+ vprintf(error_string, args);
+ va_end(args);
+
+ printf("\n");
}
-void XMLParser::parseActiveKey(bool closed) {
- if (keyCallback(_activeKey.top()->name) == false) {
- parserError("Unhandled value inside key.");
- return;
+bool XMLParser::parseActiveKey(bool closed) {
+ bool ignore = false;
+
+ // check if any of the parents must be ignored.
+ // if a parent is ignored, all children are too.
+ for (int i = _activeKey.size() - 1; i >= 0; --i) {
+ if (_activeKey[i]->ignore)
+ ignore = true;
+ }
+
+ if (ignore == false && keyCallback(_activeKey.top()->name) == false) {
+ return false;
}
if (closed) {
delete _activeKey.pop();
}
+
+ return true;
}
bool XMLParser::parseKeyValue(Common::String keyName) {
@@ -115,7 +166,7 @@ bool XMLParser::parse() {
switch (_state) {
case kParserNeedKey:
if (_text[_pos++] != '<') {
- parserError("Expecting key start.");
+ parserError("Parser expecting key start.");
break;
}
@@ -144,6 +195,7 @@ bool XMLParser::parse() {
} else {
ParserNode *node = new ParserNode;
node->name = _token;
+ node->ignore = false;
_activeKey.push(node);
}
@@ -166,9 +218,10 @@ bool XMLParser::parse() {
selfClosure = (_text[_pos] == '/');
if ((selfClosure && _text[_pos + 1] == '>') || _text[_pos] == '>') {
- parseActiveKey(selfClosure);
- _pos += selfClosure ? 2 : 1;
- _state = kParserNeedKey;
+ if (parseActiveKey(selfClosure)) {
+ _pos += selfClosure ? 2 : 1;
+ _state = kParserNeedKey;
+ }
break;
}
@@ -181,7 +234,7 @@ bool XMLParser::parse() {
case kParserNeedPropertyOperator:
if (_text[_pos++] != '=')
- parserError("Unexpected character after key name.");
+ parserError("Syntax error after key name.");
else
_state = kParserNeedPropertyValue;
@@ -189,7 +242,7 @@ bool XMLParser::parse() {
case kParserNeedPropertyValue:
if (!parseKeyValue(_token))
- parserError("Unable to parse key value.");
+ parserError("Invalid key value.");
else
_state = kParserNeedPropertyName;