- 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
This commit is contained in:
parent
8caa7d3f8b
commit
f0e63a49e3
3 changed files with 124 additions and 46 deletions
|
@ -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++]);
|
||||
printf(" File <%s>, line %d:\n", _fileName, lineCount);
|
||||
|
||||
line_width = MIN(line_width, 80);
|
||||
printf("%s%s%s\n",
|
||||
lineStr[0] == '<' ? "" : "...",
|
||||
lineStr[strlen(lineStr) - 1] == '>' ? "" : "...",
|
||||
lineStr);
|
||||
|
||||
char linestr[81];
|
||||
strncpy(linestr, &_text[line_start] + 1, line_width );
|
||||
linestr[line_width - 1] = 0;
|
||||
|
||||
printf(" File <%s>, line %d:\n", _fileName, line_count);
|
||||
|
||||
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");
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) \
|
||||
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.");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue