diff options
| author | Vicent Marti | 2008-06-13 09:24:41 +0000 | 
|---|---|---|
| committer | Vicent Marti | 2008-06-13 09:24:41 +0000 | 
| commit | e0d7301cb04a99927091fdf51cec2d88fb68ad52 (patch) | |
| tree | 346920f21cbe88c66530d3f8763ed32395034cca | |
| parent | ace171e22f98f9f9195447893b12fcf4ea79561c (diff) | |
| download | scummvm-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.cpp | 64 | ||||
| -rw-r--r-- | gui/ThemeParser.h | 21 | 
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;  };  }  | 
