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

Tanoku at users.sourceforge.net Tanoku at users.sourceforge.net
Thu Jun 19 01:49:47 CEST 2008


Revision: 32734
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32734&view=rev
Author:   Tanoku
Date:     2008-06-18 16:49:47 -0700 (Wed, 18 Jun 2008)

Log Message:
-----------
Split ThemeParser into XMLParser and ThemeParser as child class to have a common XML Parser.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-gui/common/module.mk
    scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj
    scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeParser.h

Added Paths:
-----------
    scummvm/branches/gsoc2008-gui/common/xmlparser.cpp
    scummvm/branches/gsoc2008-gui/common/xmlparser.h

Modified: scummvm/branches/gsoc2008-gui/common/module.mk
===================================================================
--- scummvm/branches/gsoc2008-gui/common/module.mk	2008-06-18 21:02:52 UTC (rev 32733)
+++ scummvm/branches/gsoc2008-gui/common/module.mk	2008-06-18 23:49:47 UTC (rev 32734)
@@ -16,6 +16,7 @@
 	system.o \
 	unarj.o \
 	unzip.o \
+	xmlparser.o \
 	zlib.o
 
 # Include common rules

Added: scummvm/branches/gsoc2008-gui/common/xmlparser.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/common/xmlparser.cpp	                        (rev 0)
+++ scummvm/branches/gsoc2008-gui/common/xmlparser.cpp	2008-06-18 23:49:47 UTC (rev 32734)
@@ -0,0 +1,216 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/util.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/xmlparser.h"
+
+namespace Common {
+
+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"
+		"//<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);
+
+	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) {
+	_state = kParserError;
+	printf("PARSER ERROR: %s\n", error_string);
+}
+
+void XMLParser::parseActiveKey(bool closed) {
+	if (keyCallback(_activeKey.top()->name) == false) {
+		parserError("Unhandled value inside key.");
+		return;
+	}
+	
+	if (closed) {
+		delete _activeKey.pop();
+	}
+}
+
+bool XMLParser::parseKeyValue(Common::String keyName) {
+	assert(_activeKey.empty() == false);
+
+	if (_activeKey.top()->values.contains(keyName))
+		return false;
+
+	_token.clear();
+	char stringStart;
+
+	if (_text[_pos] == '"' || _text[_pos] == '\'') {
+		stringStart = _text[_pos++];
+
+		while (_text[_pos] && _text[_pos] != stringStart)
+			_token += _text[_pos++];
+
+		if (_text[_pos++] == 0)
+			return false;
+
+	} else if (!parseToken()) {
+		return false;
+	}
+
+	_activeKey.top()->values[keyName] = _token;
+	return true;
+}
+
+bool XMLParser::parse() {
+
+	bool activeClosure = false;
+	bool selfClosure = false;
+
+	_state = kParserNeedKey;
+	_pos = 0;
+	_activeKey.clear();
+	
+	while (_text[_pos]) {
+		if (_state == kParserError)
+			break;
+
+		if (skipSpaces())
+			continue;
+
+		if (skipComments())
+			continue;
+
+		switch (_state) {
+			case kParserNeedKey:
+				if (_text[_pos++] != '<') {
+					parserError("Expecting key start.");
+					break;
+				}
+
+				if (_text[_pos] == 0) {
+					parserError("Unexpected end of file.");
+					break;
+				}
+
+				if (_text[_pos] == '/' && _text[_pos + 1] != '*') {
+					_pos++;
+					activeClosure = true;
+				}
+
+				_state = kParserNeedKeyName;
+				break;
+
+			case kParserNeedKeyName:
+				if (!parseToken()) {
+					parserError("Invalid key name.");
+					break;
+				}
+
+				if (activeClosure) {
+					if (_activeKey.empty() || _token != _activeKey.top()->name)
+						parserError("Unexpected closure.");
+				} else {
+					ParserNode *node = new ParserNode;
+					node->name = _token;
+					_activeKey.push(node);
+				}
+
+				_state = kParserNeedPropertyName;
+				break;
+
+			case kParserNeedPropertyName:
+				if (activeClosure) {
+					activeClosure = false;
+					delete _activeKey.pop();
+
+					if (_text[_pos++] != '>')
+						parserError("Invalid syntax in key closure.");
+					else 
+						_state = kParserNeedKey;
+
+					break;
+				}
+
+				selfClosure = (_text[_pos] == '/');
+
+				if ((selfClosure && _text[_pos + 1] == '>') || _text[_pos] == '>') {
+					parseActiveKey(selfClosure);
+					_pos += selfClosure ? 2 : 1;
+					_state = kParserNeedKey;
+					break;
+				}
+
+				if (!parseToken()) 
+					parserError("Error when parsing key value.");
+				else 
+					_state = kParserNeedPropertyOperator;
+
+				break;
+
+			case kParserNeedPropertyOperator:
+				if (_text[_pos++] != '=') 
+					parserError("Unexpected character after key name.");
+				else  
+					_state = kParserNeedPropertyValue;
+
+				break;
+
+			case kParserNeedPropertyValue:
+				if (!parseKeyValue(_token)) 
+					parserError("Unable to parse key value.");
+				else 
+					_state = kParserNeedPropertyName;
+
+				break;
+
+			default:
+				break;
+		}
+	}
+
+	if (_state == kParserError) {
+		return false;
+	}
+
+	if (_state != kParserNeedKey || !_activeKey.empty()) {
+		parserError("Unexpected end of file.");
+		return false;
+	}
+
+	return true;
+}
+
+}
+


Property changes on: scummvm/branches/gsoc2008-gui/common/xmlparser.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/branches/gsoc2008-gui/common/xmlparser.h
===================================================================
--- scummvm/branches/gsoc2008-gui/common/xmlparser.h	                        (rev 0)
+++ scummvm/branches/gsoc2008-gui/common/xmlparser.h	2008-06-18 23:49:47 UTC (rev 32734)
@@ -0,0 +1,208 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef XML_PARSER_H
+#define XML_PARSER_H
+
+#include "common/scummsys.h"
+#include "graphics/surface.h"
+#include "common/system.h"
+#include "common/xmlparser.h"
+
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/stack.h"
+
+namespace Common {
+
+/**
+ * The base XMLParser class implements generic functionality for parsing
+ * XML-like files.
+ *
+ * In order to use it, it must be inherited with a child class that implements
+ * the XMLParser::keyCallback() function.
+ *
+ * @see XMLParser::keyCallback()
+ */
+class XMLParser {
+	/** Maximum depth for nested keys that the parser supports */
+	static const int kParserMaxDepth = 4;
+
+public:
+	/**
+	 * Parser constructor.
+	 */
+	XMLParser() {}
+
+	virtual ~XMLParser() {}
+
+	/** Active state for the parser */
+	enum ParserState {
+		kParserNeedKey,
+		kParserNeedKeyName,
+
+		kParserNeedPropertyName,
+		kParserNeedPropertyOperator,
+		kParserNeedPropertyValue,
+
+		kParserError
+	};
+
+	/** Struct representing a parsed node */
+	struct ParserNode {
+		Common::String name;
+		Common::StringMap values;
+	};
+
+	virtual bool parse();
+	void debug_testEval();
+
+	/**
+	 * Returns the active node being parsed (the one on top of
+	 * the node stack).
+	 */
+	ParserNode *activeNode() {
+		if (!_activeKey.empty())
+			return _activeKey.top();
+
+		return 0;
+	}
+
+protected:
+	/**
+	 * The keycallback function must be overloaded by inheriting classes
+	 * to implement parser-specific functions.
+	 *
+	 * This function is called everytime a key has successfully been parsed.
+	 * The keyName parameter contains the name of the key that has just been
+	 * parsed; this same key is still on top of the Node Stack.
+	 *
+	 * Access the node stack to view this key's properties and its parents.
+	 * Remember to leave the node stack _UNCHANGED_ in your own function. Removal
+	 * of closed keys is done automatically.
+	 *
+	 * Return true if the key was properly handled. False otherwise.
+	 * See the sample implementation in GUI::ThemeParser.
+	 */
+	virtual bool keyCallback(Common::String keyName) {
+		return false;
+	}
+
+	/**
+	 * Parses the value of a given key. There's no reason to overload this.
+	 */
+	virtual bool parseKeyValue(Common::String keyName);
+
+	/**
+	 * Called once a key has been parsed. It handles the closing/cleanup of the
+	 * node stack and calls the keyCallback.
+	 * There's no reason to overload this.
+	 */
+	virtual void parseActiveKey(bool closed);
+
+	/**
+	 * Prints an error message when parsing fails and stops the parser.
+	 * TODO: More descriptive error messages.
+	 */
+	virtual void parserError(const char *errorString);
+
+	/**
+	 * Skips spaces/whitelines etc. Returns true if any spaces were skipped.
+	 * Overload this if you want to make your parser depend on newlines or
+	 * whatever.
+	 */
+	virtual bool skipSpaces() {
+		if (!isspace(_text[_pos]))
+			return false;
+
+		while (_text[_pos] && isspace(_text[_pos]))
+			_pos++;
+
+		return true;
+	}
+
+	/**
+	 * Skips comment blocks and comment lines.
+	 * Returns true if any comments were skipped.
+	 * Overload this if you want to disable comments on your XML syntax
+	 * or to change the commenting syntax.
+	 */
+	virtual bool skipComments() {
+		if (_text[_pos] == '/' && _text[_pos + 1] == '*') {
+			_pos += 2;
+			while (_text[_pos++]) {
+				if (_text[_pos - 2] == '*' && _text[_pos - 1] == '/')
+					break;
+				if (_text[_pos] == 0)
+					parserError("Comment has no closure.");
+			}
+			return true;
+		}
+
+		if (_text[_pos] == '/' && _text[_pos + 1] == '/') {
+			_pos += 2;
+			while (_text[_pos] && _text[_pos] != '\n')
+				_pos++;
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Check if a given character can be part of a KEY or VALUE name.
+	 * Overload this if you want to support keys with strange characters
+	 * in their name.
+	 */
+	virtual bool isValidNameChar(char c) {
+		return isalnum(c) || c == '_';
+	}
+
+	/**
+	 * Parses a the first textual token found.
+	 * There's no reason to overload this.
+	 */
+	virtual bool parseToken() {
+		_token.clear();
+		while (isValidNameChar(_text[_pos]))
+			_token += _text[_pos++];
+
+		return isspace(_text[_pos]) != 0 || _text[_pos] == '>';
+	}
+
+	int _pos; /** Current position on the XML buffer. */
+	char *_text; /** Buffer with the text being parsed */
+
+	ParserState _state; /** Internal state of the parser */
+
+	Common::String _error; /** Current error message */
+	Common::String _token; /** Current text token */
+
+	Common::FixedStack<ParserNode*, kParserMaxDepth> _activeKey; /** Node stack of the parsed keys */
+};
+
+}
+
+#endif


Property changes on: scummvm/branches/gsoc2008-gui/common/xmlparser.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj
===================================================================
--- scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj	2008-06-18 21:02:52 UTC (rev 32733)
+++ scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj	2008-06-18 23:49:47 UTC (rev 32734)
@@ -454,6 +454,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\common\xmlparser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\xmlparser.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\common\zlib.cpp"
 				>
 			</File>
@@ -1223,10 +1231,24 @@
 			<File
 				RelativePath="..\..\gui\ThemeParser.cpp"
 				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
 			</File>
 			<File
 				RelativePath="..\..\gui\ThemeParser.h"
 				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
 			</File>
 			<File
 				RelativePath="..\..\gui\widget.cpp"

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp	2008-06-18 21:02:52 UTC (rev 32733)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp	2008-06-18 23:49:47 UTC (rev 32734)
@@ -28,46 +28,30 @@
 #include "common/events.h"
 #include "common/hashmap.h"
 #include "common/hash-str.h"
+#include "common/xmlparser.h"
 
 #include "gui/InterfaceManager.h"
 #include "gui/ThemeParser.h"
 #include "graphics/VectorRenderer.h"
 
-/**
-
-<drawdata = "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>
-
-*/
-
 namespace GUI {
 
 using namespace Graphics;
+using namespace Common;
 
-void ThemeParser::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"
-		"//<drawstep func = \"roundedsq\" fill = \"none\" color = /*\"0, 0, 0\"*/\"0, 1, 2\" size = \"auto\"/>\n"
-		"</ drawdata>/* lol this is just a simple test*/\n";
+ThemeParser::ThemeParser() : XMLParser() {
+	_callbacks["drawstep"] = &ThemeParser::parserCallback_DRAWSTEP;
+	_callbacks["drawdata"] = &ThemeParser::parserCallback_DRAWDATA;
+}
 
-	_text = strdup(debugConfigText);
+bool ThemeParser::keyCallback(Common::String keyName) {
+	// automatically handle with a function from the hash table.
+	if (!_callbacks.contains(_activeKey.top()->name))
+		return false;
 
-	Common::String test = "12,  125, 125";
-
-	printf("\n\nRegex result: %s.\n\n", test.regexMatch("^[d]*,[d]*,[d]*$", true) ? "Success." : "Fail");
-
-	parse();
+	return (this->*(_callbacks[_activeKey.top()->name]))();
 }
-	
 
-void ThemeParser::parserError(const char *error_string) {
-	_state = kParserError;
-	printf("PARSER ERROR: %s\n", error_string);
-}
-
 Graphics::DrawStep *ThemeParser::newDrawStep() {
 
 	Graphics::DrawStep *step = new DrawStep;
@@ -88,7 +72,7 @@
 	return step;
 }
 
-void ThemeParser::parserCallback_DRAWSTEP() {
+bool ThemeParser::parserCallback_DRAWSTEP() {
 	ParserNode *stepNode = _activeKey.pop();
 	ParserNode *drawdataNode = _activeKey.pop();
 
@@ -104,7 +88,7 @@
 		parserError("Invalid drawing function in draw step.");
 		_activeKey.push(drawdataNode);
 		_activeKey.push(stepNode);
-		return;
+		return false;
 	}	
 
 	drawstep->drawingCall = _drawFunctions[functionName];
@@ -121,173 +105,12 @@
 
 	_activeKey.push(drawdataNode);
 	_activeKey.push(stepNode);
-}
 
-void ThemeParser::parserCallback_DRAWDATA() {
-	printf("Drawdata callback!\n");
-}
-
-void ThemeParser::parseActiveKey(bool closed) {
-	printf("Parsed key %s.\n", _activeKey.top()->name.c_str());
-
-	if (!_callbacks.contains(_activeKey.top()->name)) {
-		parserError("Unhandled value inside key.");
-		return;
-	}
-
-	// Don't you just love C++ syntax? Water clear.
-	(this->*(_callbacks[_activeKey.top()->name]))();
-
-//	for (Common::StringMap::const_iterator t = _activeKey.top()->values.begin(); t != _activeKey.top()->values.end(); ++t)
-//		printf("    Key %s = %s\n", t->_key.c_str(), t->_value.c_str());
-
-	if (closed) {
-		delete _activeKey.pop();
-	}
-}
-
-bool ThemeParser::parseKeyValue(Common::String keyName) {
-	assert(_activeKey.empty() == false);
-
-	if (_activeKey.top()->values.contains(keyName))
-		return false;
-
-	_token.clear();
-	char stringStart;
-
-	if (_text[_pos] == '"' || _text[_pos] == '\'') {
-		stringStart = _text[_pos++];
-
-		while (_text[_pos] && _text[_pos] != stringStart)
-			_token += _text[_pos++];
-
-		if (_text[_pos++] == 0)
-			return false;
-
-	} else if (!parseToken()) {
-		return false;
-	}
-
-	_activeKey.top()->values[keyName] = _token;
 	return true;
 }
 
-bool ThemeParser::parse() {
-
-	bool activeClosure = false;
-	bool selfClosure = false;
-
-	_state = kParserNeedKey;
-	_pos = 0;
-	_activeKey.clear();
-	
-	while (_text[_pos]) {
-		if (_state == kParserError)
-			break;
-
-		if (skipSpaces())
-			continue;
-
-		if (skipComments())
-			continue;
-
-		switch (_state) {
-			case kParserNeedKey:
-				if (_text[_pos++] != '<') {
-					parserError("Expecting key start.");
-					break;
-				}
-
-				if (_text[_pos] == 0) {
-					parserError("Unexpected end of file.");
-					break;
-				}
-
-				if (_text[_pos] == '/' && _text[_pos + 1] != '*') {
-					_pos++;
-					activeClosure = true;
-				}
-
-				_state = kParserNeedKeyName;
-				break;
-
-			case kParserNeedKeyName:
-				if (!parseToken()) {
-					parserError("Invalid key name.");
-					break;
-				}
-
-				if (activeClosure) {
-					if (_activeKey.empty() || _token != _activeKey.top()->name)
-						parserError("Unexpected closure.");
-				} else {
-					ParserNode *node = new ParserNode;
-					node->name = _token;
-					_activeKey.push(node);
-				}
-
-				_state = kParserNeedPropertyName;
-				break;
-
-			case kParserNeedPropertyName:
-				if (activeClosure) {
-					activeClosure = false;
-					delete _activeKey.pop();
-
-					if (_text[_pos++] != '>')
-						parserError("Invalid syntax in key closure.");
-					else 
-						_state = kParserNeedKey;
-
-					break;
-				}
-
-				selfClosure = (_text[_pos] == '/');
-
-				if ((selfClosure && _text[_pos + 1] == '>') || _text[_pos] == '>') {
-					parseActiveKey(selfClosure);
-					_pos += selfClosure ? 2 : 1;
-					_state = kParserNeedKey;
-					break;
-				}
-
-				if (!parseToken()) 
-					parserError("Error when parsing key value.");
-				else 
-					_state = kParserNeedPropertyOperator;
-
-				break;
-
-			case kParserNeedPropertyOperator:
-				if (_text[_pos++] != '=') 
-					parserError("Unexpected character after key name.");
-				else  
-					_state = kParserNeedPropertyValue;
-
-				break;
-
-			case kParserNeedPropertyValue:
-				if (!parseKeyValue(_token)) 
-					parserError("Unable to parse key value.");
-				else 
-					_state = kParserNeedPropertyName;
-
-				break;
-
-			default:
-				break;
-		}
-	}
-
-	if (_state == kParserError) {
-		return false;
-	}
-
-	if (_state != kParserNeedKey || !_activeKey.empty()) {
-		parserError("Unexpected end of file.");
-		return false;
-	}
-
+bool ThemeParser::parserCallback_DRAWDATA() {
+	printf("Drawdata callback!\n");
 	return true;
 }
 

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeParser.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeParser.h	2008-06-18 21:02:52 UTC (rev 32733)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeParser.h	2008-06-18 23:49:47 UTC (rev 32734)
@@ -33,6 +33,7 @@
 #include "common/hashmap.h"
 #include "common/hash-str.h"
 #include "common/stack.h"
+#include "common/xmlparser.h"
 
 #include "graphics/VectorRenderer.h"
 
@@ -305,106 +306,25 @@
 namespace GUI {
 
 using namespace Graphics;
+using namespace Common;
 
-class ThemeParser {
-
-	static const int kParserMaxDepth = 4;
-	typedef void (ThemeParser::*ParserCallback)();
+class ThemeParser : public XMLParser {
 	typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const DrawStep &);
+	typedef bool (ThemeParser::*ParserCallback)();
 
 public:
-	ThemeParser() {
-		_callbacks["drawdata"] = &ThemeParser::parserCallback_DRAWDATA;
-		_callbacks["drawstep"] = &ThemeParser::parserCallback_DRAWSTEP;
-	}
+	ThemeParser();
 
-	~ThemeParser() {}
-
-	enum ParserState {
-		kParserNeedKey,
-		kParserNeedKeyName,
-
-		kParserNeedPropertyName,
-		kParserNeedPropertyOperator,
-		kParserNeedPropertyValue,
-
-		kParserError
-	};
-
-	bool parse();
-	void debug_testEval();
-	
 protected:
-	void parserCallback_DRAWSTEP();
-	void parserCallback_DRAWDATA();
+	bool keyCallback(Common::String keyName);
 
-	bool parseKeyValue(Common::String keyName);
-	void parseActiveKey(bool closed);
-	void parserError(const char *errorString);
+	bool parserCallback_DRAWSTEP();
+	bool parserCallback_DRAWDATA();
 
 	Graphics::DrawStep *newDrawStep();
 
-	inline bool skipSpaces() {
-		if (!isspace(_text[_pos]))
-			return false;
-
-		while (_text[_pos] && isspace(_text[_pos]))
-			_pos++;
-
-		return true;
-	}
-
-	inline bool skipComments() {
-		if (_text[_pos] == '/' && _text[_pos + 1] == '*') {
-			_pos += 2;
-			while (_text[_pos++]) {
-				if (_text[_pos - 2] == '*' && _text[_pos - 1] == '/')
-					break;
-				if (_text[_pos] == 0)
-					parserError("Comment has no closure.");
-			}
-			return true;
-		}
-
-		if (_text[_pos] == '/' && _text[_pos + 1] == '/') {
-			_pos += 2;
-			while (_text[_pos] && _text[_pos] != '\n')
-				_pos++;
-			return true;
-		}
-
-		return false;
-	}
-
-	inline bool isValidNameChar(char c) {
-		return isalnum(c) || c == '_';
-	}
-
-	inline bool parseToken() {
-		_token.clear();
-		while (isValidNameChar(_text[_pos]))
-			_token += _text[_pos++];
-
-		return isspace(_text[_pos]) != 0 || _text[_pos] == '>';
-	}
-
-	int _pos;
-	char *_text;
-
-	ParserState _state;
-
-	Common::String _error;
-	Common::String _token;
-
-	struct ParserNode {
-		Common::String name;
-		Common::StringMap values;
-	};
-
-	Common::FixedStack<ParserNode*, kParserMaxDepth> _activeKey;
-
-	Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _callbacks;
 	Common::HashMap<Common::String, DrawingFunctionCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _drawFunctions;
+	Common::HashMap<Common::String, ParserCallback, 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