diff options
author | Vicent Marti | 2008-06-25 11:34:58 +0000 |
---|---|---|
committer | Vicent Marti | 2008-06-25 11:34:58 +0000 |
commit | f0e63a49e38d635d70869f6eb1cda42c684fee8b (patch) | |
tree | cdeb964d63841a2c59baed3d3e024267b630c734 | |
parent | 8caa7d3f8b1146fafc6dff6de4f801eb2e8b61ae (diff) | |
download | scummvm-rg350-f0e63a49e38d635d70869f6eb1cda42c684fee8b.tar.gz scummvm-rg350-f0e63a49e38d635d70869f6eb1cda42c684fee8b.tar.bz2 scummvm-rg350-f0e63a49e38d635d70869f6eb1cda42c684fee8b.zip |
- Reverted getHostPlatformString() from util.cpp (Yeah, Max was right)
- XMLParser now supports streams!
- Added remaining key values for DrawStep parsing.
- XMLParser parserError() bugfixes.
svn-id: r32782
-rw-r--r-- | common/xmlparser.cpp | 51 | ||||
-rw-r--r-- | common/xmlparser.h | 42 | ||||
-rw-r--r-- | gui/ThemeParser.cpp | 77 |
3 files changed, 124 insertions, 46 deletions
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp index de10269cdb..4c2c4b58f1 100644 --- a/common/xmlparser.cpp +++ b/common/xmlparser.cpp @@ -36,12 +36,13 @@ using namespace Graphics; void XMLParser::debug_testEval() { static const char *debugConfigText = - "</* lol this is just a moronic test */drawdata id = \"mainmenu_bg\" 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"; + "</* lol this is just assa moronic test */drawdata id = \"mainmenu_bg\" cache = true>\n" + "<drawstep func = \"roundedsq\" fill = \"none\" color = \"0, 1, 2\" size = \"auto\" />\n" + "<drawstep func = \"roundedsqXD\" fill = \"none\" color = \"0, 1, 2\" size = \"auto\"/>\n" + "</ drawdata>/* lol this is just a simple test*/\n" + "I loled"; - _text = strdup(debugConfigText); + _text.fillFromMem(strdup(debugConfigText)); _fileName = strdup("test_parse.xml"); Common::String test = "12, 125, 125"; @@ -50,48 +51,42 @@ void XMLParser::debug_testEval() { } -void XMLParser::parserError(const char *error_string, ...) { +void XMLParser::parserError(const char *errorString, ...) { _state = kParserError; int pos = _pos; - int line_count = 1; - int line_start = -1; - int line_width = 1; + int lineCount = 1; + int lineStart = -1; do { if (_text[pos] == '\n' || _text[pos] == '\r') { - line_count++; + lineCount++; - if (line_start == -1) - line_start = pos; + if (lineStart == -1) + lineStart = MAX(pos + 1, _pos - 60); } } while (pos-- > 0); - line_start = MAX(line_start, _pos - 80); + char lineStr[70]; + _text.stream()->seek(lineStart, SEEK_SET); + _text.stream()->readLine(lineStr, 70); - do { - if (_text[line_start + line_width] == '\n' || _text[line_start + line_width] == '\r') - break; - } while (_text[line_start + line_width++]); - - line_width = MIN(line_width, 80); - - char linestr[81]; - strncpy(linestr, &_text[line_start] + 1, line_width ); - linestr[line_width - 1] = 0; + printf(" File <%s>, line %d:\n", _fileName, lineCount); - printf(" File <%s>, line %d:\n", _fileName, line_count); + printf("%s%s%s\n", + lineStr[0] == '<' ? "" : "...", + lineStr[strlen(lineStr) - 1] == '>' ? "" : "...", + lineStr); - printf("%s\n", linestr); - for (int i = 1; i < _pos - line_start; ++i) + for (int i = 0; i < _pos - lineStart + 3; ++i) printf(" "); printf("^\n"); printf("Parser error: "); va_list args; - va_start(args, error_string); - vprintf(error_string, args); + va_start(args, errorString); + vprintf(errorString, args); va_end(args); printf("\n"); diff --git a/common/xmlparser.h b/common/xmlparser.h index c7f7218857..d7d929cb9a 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -30,6 +30,7 @@ #include "graphics/surface.h" #include "common/system.h" #include "common/xmlparser.h" +#include "common/stream.h" #include "common/hashmap.h" #include "common/hash-str.h" @@ -37,6 +38,43 @@ namespace Common { +class XMLStream { +protected: + SeekableReadStream *_stream; + int _pos; + +public: + XMLStream() : _stream(0), _pos(0) {} + + ~XMLStream() { + delete _stream; + } + + SeekableReadStream *stream() { + return _stream; + } + + const char operator [](int idx) { + assert(_stream && idx >= 0); + + if (_pos + 1 != idx) + _stream->seek(idx, SEEK_SET); + + _pos = idx; + + return _stream->readSByte(); + } + + void fillFromMem(const char *buffer, bool dispose = false) { + delete _stream; + _stream = new MemoryReadStream((const byte*)buffer, strlen(buffer), dispose); + } + + void fillFromFile(const char *filename) { + + } +}; + /** * The base XMLParser class implements generic functionality for parsing * XML-like files. @@ -132,7 +170,7 @@ protected: /** * Prints an error message when parsing fails and stops the parser. */ - virtual void parserError(const char *errorString, ...); + virtual void parserError(const char *errorString, ...) GCC_PRINTF(1, 2); /** * Skips spaces/whitelines etc. Returns true if any spaces were skipped. @@ -199,7 +237,7 @@ protected: } int _pos; /** Current position on the XML buffer. */ - char *_text; /** Buffer with the text being parsed */ + XMLStream _text; /** Buffer with the text being parsed */ char *_fileName; ParserState _state; /** Internal state of the parser */ diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index afc623c3d8..26701fd96a 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -55,8 +55,10 @@ ThemeParser::ThemeParser() : XMLParser() { bool ThemeParser::keyCallback(Common::String keyName) { // automatically handle with a function from the hash table. - if (!_callbacks.contains(_activeKey.top()->name)) + if (!_callbacks.contains(_activeKey.top()->name)) { + parserError("%s is not a valid key name.", keyName.c_str()); return false; + } return (this->*(_callbacks[_activeKey.top()->name]))(); } @@ -72,7 +74,7 @@ Graphics::DrawStep *ThemeParser::newDrawStep() { step->extraData = 0; step->factor = 1; - step->fillArea = false; + step->fillArea = true; step->fillMode = Graphics::VectorRenderer::kFillDisabled; step->scale = (1 << 16); step->shadow = 0; @@ -104,7 +106,7 @@ bool ThemeParser::parserCallback_DRAWSTEP() { drawstep->drawingCall = _drawFunctions[functionName]; - uint32 red, green, blue; + uint32 red, green, blue, w, h; /** * Helper macro to sanitize and assign an integer value from a key @@ -114,13 +116,18 @@ bool ThemeParser::parserCallback_DRAWSTEP() { * assigned. * @param key_name Name as STRING of the key identifier as it appears in the * theme description format. + * @param force Sets if the key is optional or necessary. */ -#define __PARSER_ASSIGN_INT(struct_name, key_name) \ +#define __PARSER_ASSIGN_INT(struct_name, key_name, force) \ if (stepNode->values.contains(key_name)) { \ - if (!validateKeyInt(stepNode->values[key_name].c_str())) \ + if (!validateKeyInt(stepNode->values[key_name].c_str())) {\ + parserError("Error when parsing key value for '%s'.", key_name); \ return false; \ - \ + } \ drawstep->struct_name = atoi(stepNode->values[key_name].c_str()); \ + } else if (force) { \ + parserError("Missing necessary key '%s'.", key_name); \ + return false; \ } /** @@ -136,17 +143,20 @@ bool ThemeParser::parserCallback_DRAWSTEP() { */ #define __PARSER_ASSIGN_RGB(struct_name, key_name) \ if (stepNode->values.contains(key_name)) { \ - if (sscanf(stepNode->values[key_name].c_str(), "%d, %d, %d", &red, &green, &blue) != 3) \ - return false; \ - \ + if (sscanf(stepNode->values[key_name].c_str(), "%d, %d, %d", &red, &green, &blue) != 3 || \ + red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) {\ + parserError("Error when parsing color struct '%s'", stepNode->values[key_name].c_str());\ + return false; \ + }\ drawstep->struct_name.r = red; \ drawstep->struct_name.g = green; \ drawstep->struct_name.b = blue; \ + drawstep->struct_name.set = true; \ } - __PARSER_ASSIGN_INT(stroke, "stroke"); - __PARSER_ASSIGN_INT(shadow, "shadow"); - __PARSER_ASSIGN_INT(factor, "gradient_factor"); + __PARSER_ASSIGN_INT(stroke, "stroke", false); + __PARSER_ASSIGN_INT(shadow, "shadow", false); + __PARSER_ASSIGN_INT(factor, "gradient_factor", false); __PARSER_ASSIGN_RGB(fgColor, "fg_color"); __PARSER_ASSIGN_RGB(bgColor, "bg_color"); @@ -154,11 +164,43 @@ bool ThemeParser::parserCallback_DRAWSTEP() { __PARSER_ASSIGN_RGB(gradColor2, "gradient_end"); if (functionName == "roundedsq" || functionName == "circle") { - __PARSER_ASSIGN_INT(radius, "radius"); + __PARSER_ASSIGN_INT(radius, "radius", true) } if (functionName == "bevelsq") { - __PARSER_ASSIGN_INT(extraData, "bevel"); + __PARSER_ASSIGN_INT(extraData, "bevel", true); + } + + if (functionName == "triangle") { + + } + + if (stepNode->values.contains("size")) { + if (stepNode->values["size"] == "auto") { + drawstep->fillArea = true; + } else if (sscanf(stepNode->values["size"].c_str(), "%d, %d", &w, &h) == 2) { + drawstep->fillArea = false; + drawstep->w = w; + drawstep->h = h; + } else { + parserError("Invalid value in 'size' subkey: Valid options are 'auto' or 'X, X' to define width and height."); + return false; + } + } + + if (stepNode->values.contains("fill")) { + if (stepNode->values["fill"] == "none") + drawstep->fillMode = VectorRenderer::kFillDisabled; + else if (stepNode->values["fill"] == "foreground") + drawstep->fillMode = VectorRenderer::kFillForeground; + else if (stepNode->values["fill"] == "background") + drawstep->fillMode = VectorRenderer::kFillBackground; + else if (stepNode->values["fill"] == "gradient") + drawstep->fillMode = VectorRenderer::kFillGradient; + else { + parserError("'%s' is not a valid fill mode for a shape.", stepNode->values["fill"].c_str()); + return false; + } } #undef __PARSER_ASSIGN_INT @@ -188,12 +230,15 @@ bool ThemeParser::parserCallback_DRAWDATA() { cached = true; } - if (drawdataNode->values.contains("platform")) { + // Both Max and Johannes suggest using a non-platform specfic approach based on available + // resources and active resolution. getHostPlatformString() has been removed, so fix this. + +/* if (drawdataNode->values.contains("platform")) { if (drawdataNode->values["platform"].compareToIgnoreCase(Common::getHostPlatformString()) != 0) { drawdataNode->ignore = true; return true; } - } + }*/ if (g_InterfaceManager.addDrawData(id, cached) == false) { parserError("Repeated DrawData: Only one set of Drawing Data for a widget may be specified on each platform."); |