aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/main.cpp3
-rw-r--r--gui/ThemeParser.cpp119
-rw-r--r--gui/ThemeParser.h17
3 files changed, 124 insertions, 15 deletions
diff --git a/base/main.cpp b/base/main.cpp
index 45e0aef728..d0da338e2a 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -43,6 +43,7 @@
#include "gui/newgui.h"
#include "gui/message.h"
#include "gui/InterfaceManager.h"
+#include "gui/ThemeParser.h"
#if defined(_WIN32_WCE)
#include "backends/platform/wince/CELauncherDialog.h"
@@ -70,6 +71,8 @@ static bool launcherDialog(OSystem &system) {
#if 1
+ GUI::ThemeParser parser;
+ parser.debug_testEval();
g_InterfaceManager.runGUI();
return true;
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index 26745ac5a6..73086e942c 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -26,6 +26,8 @@
#include "common/util.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
#include "gui/ThemeParser.h"
@@ -46,39 +48,104 @@ inline bool isValidNameChar(char c) {
c != '<' && c != '>' && c != '=';
}
+void ThemeParser::debug_testEval() {
+ static const char *debug_config_text =
+ "<drawdata id = \"background_default\" cache = true>"
+ "<draw func = \"roundedsq\" /*/fill = \"gradient\" gradient_start = \"255, 255, 128\" gradient_end = \"128, 128, 128\" size = \"auto\"/>"
+ "/*<draw func = \"roundedsq\" fill = \"none\" color = \"0, 0, 0\" size = \"auto\"/>*/"
+ "</drawdata>/* lol this is just a simple test*/";
+
+ _text = strdup(debug_config_text);
+ parseDrawData();
+}
+
+
void ThemeParser::parserError(const char *error_string) {
_state = kParserError;
+ printf("PARSER ERROR: %s\n", error_string);
+}
+
+void ThemeParser::parseActiveKey(bool closed) {
+ printf("Parsed key %s.\n", _activeKey.top().c_str());
+
+ for (Common::StringMap::const_iterator t = _keyValues.begin(); t != _keyValues.end(); ++t)
+ printf(" Key %s = %s\n", t->_key.c_str(), t->_value.c_str());
+
+ if (closed)
+ _activeKey.pop();
+
+ _keyValues.clear();
+}
+
+void ThemeParser::parseKeyValue(Common::String &key_name) {
+ assert(_text[_pos++] == '=');
+
+ while (isspace(_text[_pos]))
+ _pos++;
+
+ Common::String data;
+
+ if (_text[_pos] == '"') {
+ data += _text[_pos++];
+
+ while (_text[_pos] != '"')
+ data += _text[_pos++];
+
+ data += _text[_pos++];
+ } else {
+ while (isValidNameChar(_text[_pos]))
+ data += _text[_pos++];
+ }
+
+ _keyValues[key_name] = data;
}
bool ThemeParser::parseDrawData() {
_state = kParserNeedKey;
+ _pos = 0;
+ _keyValues.clear();
- while (_text[_pos++]) {
-
+ while (_text[_pos]) {
while (isspace(_text[_pos]))
_pos++;
// comment handling: skip everything between /* and */
- if (_text[_pos] == '/') {
- if (_text[++_pos] != '*') {
- parserError("Malformed comment string.");
- return false;
+ if (_text[_pos] == '/' && _text[_pos + 1] == '*') {
+ _pos += 2;
+ while (_text[_pos++]) {
+ if (_text[_pos - 2] == '*' && _text[_pos - 1] == '/')
+ break;
}
-
- _pos++;
-
- while (_text[_pos] != '*' && _text[_pos + 1] != '/')
- _pos++;
+ continue;
}
switch (_state) {
case kParserNeedKey:
- if (_text[_pos] != '<') {
+ if (_text[_pos++] != '<') {
parserError("Expecting key start.");
return false;
}
+ if (_text[_pos] == '/') {
+ _pos++;
+ _token.clear();
+ while (isValidNameChar(_text[_pos]))
+ _token += _text[_pos++];
+
+ if (_token == _activeKey.top()) {
+ _activeKey.pop();
+
+ while (isspace(_text[_pos]) || _text[_pos] == '>')
+ _pos++;
+
+ break;
+ } else {
+ parserError("Unexpected closure.");
+ return false;
+ }
+ }
+
_state = kParserKeyNeedName;
break;
@@ -87,16 +154,38 @@ bool ThemeParser::parseDrawData() {
while (isValidNameChar(_text[_pos]))
_token += _text[_pos++];
- if (!isspace(_text[_pos])) {
+ if (!isspace(_text[_pos]) && _text[_pos] != '>') {
parserError("Invalid character in token name.");
return false;
}
_state = kParserKeyNeedToken;
+ _activeKey.push(_token);
break;
case kParserKeyNeedToken:
_token.clear();
+
+ if ((_text[_pos] == '/' && _text[_pos + 1] == '>') || _text[_pos] == '>') {
+ bool closed = _text[_pos] == '/';
+ parseActiveKey(closed);
+ _pos += closed ? 2 : 1;
+ _state = kParserNeedKey;
+ break;
+ }
+
+ while (isValidNameChar(_text[_pos]))
+ _token += _text[_pos++];
+
+ while (isspace(_text[_pos]))
+ _pos++;
+
+ if (_text[_pos] != '=') {
+ parserError("Unexpected character after key name.");
+ return false;
+ }
+
+ parseKeyValue(_token);
break;
default:
@@ -104,6 +193,10 @@ bool ThemeParser::parseDrawData() {
}
}
+ if (_state != kParserNeedKey || !_activeKey.empty()) {
+ parserError("Unexpected end of file.");
+ }
+
return true;
}
diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h
index c43088c36e..527d911620 100644
--- a/gui/ThemeParser.h
+++ b/gui/ThemeParser.h
@@ -30,10 +30,15 @@
#include "graphics/surface.h"
#include "common/system.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/stack.h"
+
namespace GUI {
class ThemeParser {
+public:
ThemeParser() {}
~ThemeParser() {}
@@ -43,11 +48,16 @@ class ThemeParser {
kParserKeyNeedSubkey,
kParserNeedKey,
kParserInComment,
- kParserError
+ kParserError,
+ kParserSuccess
};
bool parseDrawData();
+ void parseKeyValue(Common::String &key_name);
+ void parseActiveKey(bool closed);
void parserError(const char *error_string);
+
+ void debug_testEval();
protected:
int _pos;
@@ -57,8 +67,11 @@ protected:
Common::String _error;
Common::String _token;
+
+ Common::FixedStack<Common::String, 5> _activeKey;
+ Common::StringMap _keyValues;
};
}
-#endif \ No newline at end of file
+#endif