From 3f0f7fa08bea272fa61b0fde5d7783aa44b1ff25 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Sat, 28 Jun 2008 00:02:54 +0000 Subject: [PATCH] Improved support for parsing integers in the XML parser. Bug fixes. svn-id: r32818 --- common/xmlparser.h | 47 +++++++++++++++++++++++++++++++++++++++- gui/InterfaceManager.cpp | 2 +- gui/ThemeDefaultXML.cpp | 2 +- gui/ThemeParser.cpp | 10 ++++----- gui/ThemeParser.h | 19 ---------------- 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/common/xmlparser.h b/common/xmlparser.h index 4c8e1b986f8..c3cdbc3e028 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -55,7 +55,7 @@ public: return _stream; } - const char operator [](int idx) { + char operator [](int idx) { assert(_stream && idx >= 0); if (_pos + 1 != idx) @@ -287,6 +287,51 @@ protected: return isspace(_text[_pos]) != 0 || _text[_pos] == '>'; } + /** + * Parses the values inside an integer key. + * The count parameter specifies the number of values inside + * the key, which are expected to be separated with commas. + * + * Sample usage: + * parseIntegerKey("255, 255, 255", 3, &red, &green, &blue); + * [will parse each field into its own integer] + * + * parseIntegerKey("1234", 1, &number); + * [will parse the single number into the variable] + * + * @param key String containing the integers to be parsed. + * @param count Number of comma-separated ints in the string. + * @param ... Integer variables to store the parsed ints, passed + * by reference. + * @returns True if the parsing succeeded. + */ + virtual bool parseIntegerKey(const char *key, int count, ...) { + char *parseEnd = 0; + int *num_ptr; + + va_list args; + va_start(args, count); + + while (count--) { + while (isspace(*key)) + key++; + + num_ptr = va_arg(args, int*); + *num_ptr = strtol(key, &parseEnd, 10); + + while (isspace(*parseEnd)) + parseEnd++; + + if (count && *parseEnd++ != ',') + return false; + + key = parseEnd; + } + + va_end(args); + return (*parseEnd == 0); + } + int _pos; /** Current position on the XML buffer. */ XMLStream _text; /** Buffer with the text being parsed */ Common::String _fileName; diff --git a/gui/InterfaceManager.cpp b/gui/InterfaceManager.cpp index cbaf1bbf5b7..7a779df5937 100644 --- a/gui/InterfaceManager.cpp +++ b/gui/InterfaceManager.cpp @@ -137,7 +137,7 @@ bool InterfaceManager::loadTheme(Common::String themeName) { warning("Could not parse custom theme '%s'.\nFalling back to default theme", themeName.c_str()); if (!loadDefaultXML()) // if we can't load the embeded theme, this is a complete failure - error("Could not load default embeded theme."); + error("Could not load default embeded theme"); } for (int i = 0; i < kDrawDataMAX; ++i) { diff --git a/gui/ThemeDefaultXML.cpp b/gui/ThemeDefaultXML.cpp index 0d9faf07681..cd571e680eb 100644 --- a/gui/ThemeDefaultXML.cpp +++ b/gui/ThemeDefaultXML.cpp @@ -51,7 +51,7 @@ bool InterfaceManager::loadDefaultXML() { "" "" - "" + "" "" "" diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 671a4a543eb..8dc02297b71 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -175,7 +175,7 @@ bool ThemeParser::parserCallback_color() { int red, green, blue; - if (sscanf(colorNode->values["rgb"].c_str(), "%d, %d, %d", &red, &green, &blue) != 3 || + if (parseIntegerKey(colorNode->values["rgb"].c_str(), 3, &red, &green, &blue) == false || red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) return parserError("Error when parsing RGB values for palette color '%s'", name.c_str());\ @@ -263,7 +263,7 @@ bool ThemeParser::parserCallback_DRAWDATA() { } bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawstep, bool functionSpecific) { - int red, green, blue, w, h; + int red, green, blue, w, h, x; Common::String val; /** @@ -278,10 +278,10 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst */ #define __PARSER_ASSIGN_INT(struct_name, key_name, force) \ if (stepNode->values.contains(key_name)) { \ - if (!validateKeyInt(stepNode->values[key_name].c_str()))\ + if (!parseIntegerKey(stepNode->values[key_name].c_str(), 1, &x)) \ return parserError("Error when parsing key value for '%s'.", key_name); \ \ - drawstep->struct_name = atoi(stepNode->values[key_name].c_str()); \ + drawstep->struct_name = x; \ } else if (force) { \ return parserError("Missing necessary key '%s'.", key_name); \ } @@ -304,7 +304,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst red = _palette[val].r; \ green = _palette[val].g; \ blue = _palette[val].b; \ - } else if (sscanf(val.c_str(), "%d, %d, %d", &red, &green, &blue) != 3 || \ + } else if (parseIntegerKey(val.c_str(), 3, &red, &green, &blue) == false || \ red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) \ return parserError("Error when parsing color struct '%s'", val.c_str());\ \ diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 2a7e0999d5a..55f39d8a44f 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -325,25 +325,6 @@ protected: bool parserCallback_renderInfo(); bool parserCallback_layoutInfo(); bool parserCallback_defaultSet(); - - - bool validateKeyIntSigned(const char *key) { - if (!isdigit(*key) && *key != '+' && *key != '-') - return false; - - return validateKeyInt(key + 1); - } - - bool validateKeyInt(const char *key) { - if (*key == 0) - return false; - - while (*key) - if (!isdigit(*key++)) - return false; - - return true; - } Graphics::DrawStep *newDrawStep(); Graphics::DrawStep *defaultDrawStep();