aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti2008-06-13 09:24:41 +0000
committerVicent Marti2008-06-13 09:24:41 +0000
commite0d7301cb04a99927091fdf51cec2d88fb68ad52 (patch)
tree346920f21cbe88c66530d3f8763ed32395034cca
parentace171e22f98f9f9195447893b12fcf4ea79561c (diff)
downloadscummvm-rg350-e0d7301cb04a99927091fdf51cec2d88fb68ad52.tar.gz
scummvm-rg350-e0d7301cb04a99927091fdf51cec2d88fb68ad52.tar.bz2
scummvm-rg350-e0d7301cb04a99927091fdf51cec2d88fb68ad52.zip
Parser update. Variable depth.
svn-id: r32690
-rw-r--r--gui/ThemeParser.cpp64
-rw-r--r--gui/ThemeParser.h21
2 files changed, 64 insertions, 21 deletions
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index 73086e942c..c75340ada2 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -43,20 +43,18 @@
namespace GUI {
inline bool isValidNameChar(char c) {
- return !isspace(c) && c != '/' && c != '*' && c != '\\' &&
- c != '|' && c != '"' && c != '\'' && c != ',' &&
- c != '<' && c != '>' && c != '=';
+ return isalnum(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\"/>*/"
+ "<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();
+ parse();
}
@@ -65,20 +63,42 @@ void ThemeParser::parserError(const char *error_string) {
printf("PARSER ERROR: %s\n", error_string);
}
+void ThemeParser::parserCallback_DRAW() {
+ printf("Draw callback!\n");
+}
+
+void ThemeParser::parserCallback_DRAWDATA() {
+ printf("Drawdata callback!\n");
+}
+
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)
+ if (!_callbacks.contains(_activeKey.top())) {
+ parserError("Unhandled value inside key.");
+ return;
+ }
+
+ // Don't you just love C++ syntax? Water clear.
+ (this->*(_callbacks[_activeKey.top()]))();
+
+ for (Common::StringMap::const_iterator t = _keyValues.top().begin(); t != _keyValues.top().end(); ++t)
printf(" Key %s = %s\n", t->_key.c_str(), t->_value.c_str());
- if (closed)
+ if (closed) {
+ _keyValues.pop();
_activeKey.pop();
-
- _keyValues.clear();
+ }
}
void ThemeParser::parseKeyValue(Common::String &key_name) {
assert(_text[_pos++] == '=');
+ assert(_keyValues.empty() == false);
+
+ if (_keyValues.top().contains(key_name)) {
+ parserError("Repeated value inside key.");
+ return;
+ }
while (isspace(_text[_pos]))
_pos++;
@@ -97,16 +117,20 @@ void ThemeParser::parseKeyValue(Common::String &key_name) {
data += _text[_pos++];
}
- _keyValues[key_name] = data;
+ _keyValues.top()[key_name] = data;
}
-bool ThemeParser::parseDrawData() {
+bool ThemeParser::parse() {
_state = kParserNeedKey;
_pos = 0;
_keyValues.clear();
+ _activeKey.clear();
while (_text[_pos]) {
+ if (_state == kParserError)
+ break;
+
while (isspace(_text[_pos]))
_pos++;
@@ -124,7 +148,7 @@ bool ThemeParser::parseDrawData() {
case kParserNeedKey:
if (_text[_pos++] != '<') {
parserError("Expecting key start.");
- return false;
+ break;
}
if (_text[_pos] == '/') {
@@ -133,8 +157,9 @@ bool ThemeParser::parseDrawData() {
while (isValidNameChar(_text[_pos]))
_token += _text[_pos++];
- if (_token == _activeKey.top()) {
+ if (!_activeKey.empty() && _token == _activeKey.top()) {
_activeKey.pop();
+ _keyValues.pop();
while (isspace(_text[_pos]) || _text[_pos] == '>')
_pos++;
@@ -142,10 +167,11 @@ bool ThemeParser::parseDrawData() {
break;
} else {
parserError("Unexpected closure.");
- return false;
+ break;
}
}
+ _keyValues.push(Common::StringMap());
_state = kParserKeyNeedName;
break;
@@ -156,7 +182,7 @@ bool ThemeParser::parseDrawData() {
if (!isspace(_text[_pos]) && _text[_pos] != '>') {
parserError("Invalid character in token name.");
- return false;
+ break;
}
_state = kParserKeyNeedToken;
@@ -182,17 +208,21 @@ bool ThemeParser::parseDrawData() {
if (_text[_pos] != '=') {
parserError("Unexpected character after key name.");
- return false;
+ break;
}
parseKeyValue(_token);
break;
default:
- return false;
+ break;
}
}
+ if (_state == kParserError) {
+ return false;
+ }
+
if (_state != kParserNeedKey || !_activeKey.empty()) {
parserError("Unexpected end of file.");
}
diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h
index 527d911620..22ad50a333 100644
--- a/gui/ThemeParser.h
+++ b/gui/ThemeParser.h
@@ -38,8 +38,15 @@ namespace GUI {
class ThemeParser {
+ static const int PARSER_MAX_DEPTH = 4;
+ typedef void (ThemeParser::*PARSER_CALLBACK)();
+
public:
- ThemeParser() {}
+ ThemeParser() {
+ _callbacks["drawdata"] = &ThemeParser::parserCallback_DRAWDATA;
+ _callbacks["draw"] = &ThemeParser::parserCallback_DRAW;
+ }
+
~ThemeParser() {}
enum ParserState {
@@ -52,14 +59,18 @@ public:
kParserSuccess
};
- bool parseDrawData();
+ bool parse();
void parseKeyValue(Common::String &key_name);
void parseActiveKey(bool closed);
+
void parserError(const char *error_string);
void debug_testEval();
protected:
+ void parserCallback_DRAW();
+ void parserCallback_DRAWDATA();
+
int _pos;
char *_text;
@@ -68,8 +79,10 @@ protected:
Common::String _error;
Common::String _token;
- Common::FixedStack<Common::String, 5> _activeKey;
- Common::StringMap _keyValues;
+ Common::FixedStack<Common::String, PARSER_MAX_DEPTH> _activeKey;
+ Common::FixedStack<Common::StringMap, PARSER_MAX_DEPTH> _keyValues;
+
+ Common::HashMap<Common::String, PARSER_CALLBACK, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _callbacks;
};
}