[Scummvm-cvs-logs] SF.net SVN: scummvm: [32690] scummvm/branches/gsoc2008-gui/gui

Tanoku at users.sourceforge.net Tanoku at users.sourceforge.net
Fri Jun 13 11:24:41 CEST 2008


Revision: 32690
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32690&view=rev
Author:   Tanoku
Date:     2008-06-13 02:24:41 -0700 (Fri, 13 Jun 2008)

Log Message:
-----------
Parser update. Variable depth.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeParser.h

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp	2008-06-13 08:37:03 UTC (rev 32689)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp	2008-06-13 09:24:41 UTC (rev 32690)
@@ -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,21 +63,43 @@
 	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 @@
 			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 @@
 			case kParserNeedKey:
 				if (_text[_pos++] != '<') {
 					parserError("Expecting key start.");
-					return false;
+					break;
 				}
 
 				if (_text[_pos] == '/') {
@@ -133,8 +157,9 @@
 					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 @@
 						break;
 					} else {
 						parserError("Unexpected closure.");
-						return false;
+						break;
 					}
 				}
 
+				_keyValues.push(Common::StringMap());
 				_state = kParserKeyNeedName;
 				break;
 
@@ -156,7 +182,7 @@
 
 				if (!isspace(_text[_pos]) && _text[_pos] != '>') {
 					parserError("Invalid character in token name.");
-					return false;
+					break;
 				}
 
 				_state = kParserKeyNeedToken;
@@ -182,17 +208,21 @@
 
 				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.");
 	}

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeParser.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeParser.h	2008-06-13 08:37:03 UTC (rev 32689)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeParser.h	2008-06-13 09:24:41 UTC (rev 32690)
@@ -38,8 +38,15 @@
 
 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 @@
 		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 @@
 	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;
 };
 
 }


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list