diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/forbidden.h | 49 | ||||
-rw-r--r-- | common/macresman.cpp | 31 | ||||
-rw-r--r-- | common/str.cpp | 54 | ||||
-rw-r--r-- | common/system.cpp | 98 | ||||
-rw-r--r-- | common/system.h | 209 | ||||
-rw-r--r-- | common/xmlparser.cpp | 23 | ||||
-rw-r--r-- | common/xmlparser.h | 2 |
7 files changed, 346 insertions, 120 deletions
diff --git a/common/forbidden.h b/common/forbidden.h index c551110d0e..9cba19cf5e 100644 --- a/common/forbidden.h +++ b/common/forbidden.h @@ -34,6 +34,9 @@ * Backend files may #define FORBIDDEN_SYMBOL_ALLOW_ALL if they * have to access functions like fopen, fread etc. * Regular code, esp. code in engines/, should never do that. + * To ease transition, though, we allow re-enabling selected symbols + * in frontend code. However, this should only be used as a temporary + * measure. Especially new code should avoid this at all costs. */ #ifndef FORBIDDEN_SYMBOL_ALLOW_ALL @@ -51,7 +54,7 @@ * the compiler will hopefully print along with its own error message), * we try to make clear what is causing the error. */ -#define FORBIDDEN_SYMBOL_REPLACEMENT FORBIDDEN SYMBOL !%* +#define FORBIDDEN_SYMBOL_REPLACEMENT FORBIDDEN_look_at_common_forbidden_h_for_more_info SYMBOL !%* #ifndef FORBIDDEN_SYMBOL_EXCEPTION_printf @@ -79,6 +82,21 @@ #define FILE FORBIDDEN_SYMBOL_REPLACEMENT #endif +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_stdin +#undef stdin +#define stdin FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_stdout +#undef stdout +#define stdout FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_stderr +#undef stderr +#define stderr FORBIDDEN_SYMBOL_REPLACEMENT +#endif + #ifndef FORBIDDEN_SYMBOL_EXCEPTION_fopen #undef fopen #define fopen(a,b) FORBIDDEN_SYMBOL_REPLACEMENT @@ -124,22 +142,41 @@ #define fputc(a,b) FORBIDDEN_SYMBOL_REPLACEMENT #endif +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_fgets +#undef fgets +#define fgets(a,b,c) FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_fputs +#undef fputs +#define fputs(a,b) FORBIDDEN_SYMBOL_REPLACEMENT +#endif #ifndef FORBIDDEN_SYMBOL_EXCEPTION_getc #undef getc #define getc(a) FORBIDDEN_SYMBOL_REPLACEMENT #endif -#ifndef FORBIDDEN_SYMBOL_EXCEPTION_getchar -#undef getchar -#define getchar() FORBIDDEN_SYMBOL_REPLACEMENT -#endif - #ifndef FORBIDDEN_SYMBOL_EXCEPTION_putc #undef putc #define putc(a,b) FORBIDDEN_SYMBOL_REPLACEMENT #endif +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_gets +#undef gets +#define gets(a) FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_puts +#undef puts +#define puts(a) FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_getchar +#undef getchar +#define getchar() FORBIDDEN_SYMBOL_REPLACEMENT +#endif + #ifndef FORBIDDEN_SYMBOL_EXCEPTION_putchar #undef putchar #define putchar(a) FORBIDDEN_SYMBOL_REPLACEMENT diff --git a/common/macresman.cpp b/common/macresman.cpp index 70c6e0a7ce..c1cab8b96a 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -32,7 +32,6 @@ #ifdef MACOSX #include "common/config-manager.h" -#include "backends/fs/stdiostream.h" #endif namespace Common { @@ -108,14 +107,17 @@ bool MacResManager::open(String filename) { #ifdef MACOSX // Check the actual fork on a Mac computer String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc"; - SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false); + FSNode resFsNode = FSNode(fullPath); + if (resFsNode.exists()) { + SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();; - if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { - _baseFileName = filename; - return true; - } + if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { + _baseFileName = filename; + return true; + } - delete macResForkRawStream; + delete macResForkRawStream; + } #endif File *file = new File(); @@ -168,14 +170,17 @@ bool MacResManager::open(FSNode path, String filename) { #ifdef MACOSX // Check the actual fork on a Mac computer String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc"; - SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false); + FSNode resFsNode = FSNode(fullPath); + if (resFsNode.exists()) { + SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();; - if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { - _baseFileName = filename; - return true; - } + if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { + _baseFileName = filename; + return true; + } - delete macResForkRawStream; + delete macResForkRawStream; + } #endif // First, let's try to see if the Mac converted name exists diff --git a/common/str.cpp b/common/str.cpp index 740e7b6a06..223188bdd6 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -19,11 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "common/str.h" #include "common/hash-str.h" -#include "common/util.h" - +#include "common/list.h" #include "common/memorypool.h" +#include "common/str.h" +#include "common/util.h" #include <stdarg.h> @@ -256,7 +256,7 @@ String &String::operator=(char c) { String &String::operator+=(const char *str) { if (_str <= str && str <= _str + _size) - return operator+=(Common::String(str)); + return operator+=(String(str)); int len = strlen(str); if (len > 0) { @@ -270,7 +270,7 @@ String &String::operator+=(const char *str) { String &String::operator+=(const String &str) { if (&str == this) - return operator+=(Common::String(str)); + return operator+=(String(str)); int len = str._size; if (len > 0) { @@ -612,7 +612,7 @@ char *trim(char *t) { return rtrim(ltrim(t)); } -Common::String lastPathComponent(const Common::String &path, const char sep) { +String lastPathComponent(const String &path, const char sep) { const char *str = path.c_str(); const char *last = str + path.size(); @@ -622,7 +622,7 @@ Common::String lastPathComponent(const Common::String &path, const char sep) { // Path consisted of only slashes -> return empty string if (last == str) - return Common::String(); + return String(); // Now scan the whole component const char *first = last - 1; @@ -632,24 +632,26 @@ Common::String lastPathComponent(const Common::String &path, const char sep) { if (*first == sep) first++; - return Common::String(first, last); + return String(first, last); } -Common::String normalizePath(const Common::String &path, const char sep) { +String normalizePath(const String &path, const char sep) { if (path.empty()) return path; const char *cur = path.c_str(); - Common::String result; + String result; // If there is a leading slash, preserve that: if (*cur == sep) { result += sep; + // Skip over multiple leading slashes, so "//" equals "/" while (*cur == sep) ++cur; } - // Scan till the end of the String + // Scan for path components till the end of the String + List<String> comps; while (*cur != 0) { const char *start = cur; @@ -657,18 +659,16 @@ Common::String normalizePath(const Common::String &path, const char sep) { while (*cur != sep && *cur != 0) cur++; - const Common::String component(start, cur); - - // Skip empty components and dot components, add all others - if (!component.empty() && component != ".") { - // Add a separator before the component, unless the result - // string already ends with one (which happens only if the - // path *starts* with a separator). - if (!result.empty() && result.lastChar() != sep) - result += sep; + const String component(start, cur); - // Add the component - result += component; + if (component.empty() || component == ".") { + // Skip empty components and dot components + } else if (!comps.empty() && component == ".." && comps.back() != "..") { + // If stack is non-empty and top is not "..", remove top + comps.pop_back(); + } else { + // Add the component to the stack + comps.push_back(component); } // Skip over separator chars @@ -676,6 +676,14 @@ Common::String normalizePath(const Common::String &path, const char sep) { cur++; } + // Finally, assemble all components back into a path + while (!comps.empty()) { + result += comps.front(); + comps.pop_front(); + if (!comps.empty()) + result += sep; + } + return result; } @@ -749,7 +757,7 @@ String tag2string(uint32 tag) { if (!isprint((unsigned char)str[i])) str[i] = '.'; } - return Common::String(str); + return String(str); } size_t strlcpy(char *dst, const char *src, size_t size) { diff --git a/common/system.cpp b/common/system.cpp index 1f2f8cc6d5..fae7a3ef34 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -20,34 +20,71 @@ * */ -// Disable symbol overrides so that we can use system headers. -// FIXME: Necessary for the PS2 port, should get rid of this eventually. -#define FORBIDDEN_SYMBOL_ALLOW_ALL +#define FORBIDDEN_SYMBOL_EXCEPTION_exit +#define FORBIDDEN_SYMBOL_EXCEPTION_FILE +#define FORBIDDEN_SYMBOL_EXCEPTION_fputs +#define FORBIDDEN_SYMBOL_EXCEPTION_fflush +#define FORBIDDEN_SYMBOL_EXCEPTION_stdout +#define FORBIDDEN_SYMBOL_EXCEPTION_stderr #include "common/system.h" +#include "common/events.h" +#include "common/fs.h" +#include "common/savefile.h" #include "common/str.h" +#include "common/textconsole.h" -#ifdef __PLAYSTATION2__ - // for those replaced fopen/fread/etc functions - #include "backends/platform/ps2/fileio.h" - - #define fputs(str, file) ps2_fputs(str, file) - #define fflush(a) ps2_fflush(a) -#endif - -#ifdef __DS__ - #include "backends/fs/ds/ds-fs.h" - - #define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file) - #define fflush(file) DS::std_fflush(file) -#endif +#include "backends/audiocd/default/default-audiocd.h" +#include "backends/fs/fs-factory.h" +#include "backends/timer/default/default-timer.h" OSystem *g_system = 0; OSystem::OSystem() { + _audiocdManager = 0; + _eventManager = 0; + _timerManager = 0; + _savefileManager = 0; + _fsFactory = 0; } OSystem::~OSystem() { + delete _audiocdManager; + _audiocdManager = 0; + + delete _eventManager; + _eventManager = 0; + + delete _timerManager; + _timerManager = 0; + + delete _savefileManager; + _savefileManager = 0; + + delete _fsFactory; + _fsFactory = 0; +} + +void OSystem::initBackend() { + // Verify all managers has been set + if (!_audiocdManager) + error("Backend failed to instantiate audio CD manager"); + if (!_eventManager) + error("Backend failed to instantiate event manager"); + if (!_timerManager) + error("Backend failed to instantiate timer manager"); + + // TODO: We currently don't check _savefileManager, because at least + // on the Nintendo DS, it is possible that none is set. That should + // probably be treated as "saving is not possible". Or else the NDS + // port needs to be changed to always set a _savefileManager +// if (!_savefileManager) +// error("Backend failed to instantiate savefile manager"); + + // TODO: We currently don't check _fsFactory because not all ports + // set it. +// if (!_fsFactory) +// error("Backend failed to instantiate fs factory"); } bool OSystem::setGraphicsMode(const char *name) { @@ -76,16 +113,41 @@ void OSystem::fatalError() { exit(1); } +FilesystemFactory *OSystem::getFilesystemFactory() { + assert(_fsFactory); + return _fsFactory; +} + +Common::SeekableReadStream *OSystem::createConfigReadStream() { + Common::FSNode file(getDefaultConfigFileName()); + return file.createReadStream(); +} + +Common::WriteStream *OSystem::createConfigWriteStream() { +#ifdef __DC__ + return 0; +#else + Common::FSNode file(getDefaultConfigFileName()); + return file.createWriteStream(); +#endif +} + +Common::String OSystem::getDefaultConfigFileName() { + return "scummvm.ini"; +} + void OSystem::logMessage(LogMessageType::Type type, const char *message) { +#if !defined(__PLAYSTATION2__) && !defined(__DS__) FILE *output = 0; - if (type == LogMessageType::kDebug) + if (type == LogMessageType::kInfo || type == LogMessageType::kDebug) output = stdout; else output = stderr; fputs(message, output); fflush(output); +#endif } Common::String OSystem::getSystemLanguage() const { diff --git a/common/system.h b/common/system.h index b584739b77..d26bc593aa 100644 --- a/common/system.h +++ b/common/system.h @@ -73,6 +73,7 @@ struct TimeDate { namespace LogMessageType { enum Type { + kInfo, kError, kWarning, kDebug @@ -95,6 +96,72 @@ protected: OSystem(); virtual ~OSystem(); +protected: + /** + * @name Module slots + * + * For backend authors only, the following pointers (= "slots) to various + * subsystem managers / factories / etc. can and should be set to + * a suitable instance of the respective type. + * + * For some of the slots, a default instance is set if your backend + * does not do so. For details, please look at the documentation of + * each slot. + * + * A backend may setup slot values in its initBackend() method, + * its constructor or somewhere in between. But it must a slot's value + * no later than in its initBackend() implementation, because + * OSystem::initBackend() will create any default instances if + * none has been set yet (and for other slots, will verify that + * one has been set; if not, an error may be generated). + */ + //@{ + + /** + * No default value is provided for _audiocdManager by OSystem. + * However, BaseBackend::initBackend() does set a default value + * if none has been set before. + * + * @note _audiocdManager is deleted by the OSystem destructor. + */ + AudioCDManager *_audiocdManager; + + /** + * No default value is provided for _eventManager by OSystem. + * However, BaseBackend::initBackend() does set a default value + * if none has been set before. + * + * @note _eventManager is deleted by the OSystem destructor. + */ + Common::EventManager *_eventManager; + + /** + * No default value is provided for _timerManager by OSystem. + * + * @note _timerManager is deleted by the OSystem destructor. + */ + Common::TimerManager *_timerManager; + + /** + * No default value is provided for _savefileManager by OSystem. + * + * @note _savefileManager is deleted by the OSystem destructor. + */ + Common::SaveFileManager *_savefileManager; + + /** + * No default value is provided for _fsFactory by OSystem. + * + * Note that _fsFactory is typically required very early on, + * so it usually should be set in the backends constructor or shortly + * thereafter, and before initBackend() is called. + * + * @note _fsFactory is deleted by the OSystem destructor. + */ + FilesystemFactory *_fsFactory; + + //@} + public: /** @@ -105,7 +172,7 @@ public: * parent class. They should do so near the end of their own * implementation. */ - virtual void initBackend() { } + virtual void initBackend(); /** * Allows the backend to perform engine specific init. @@ -128,11 +195,19 @@ public: * - fullscreen mode * - aspect ration correction * - a virtual keyboard for text entry (on PDAs) + * + * One has to distinguish between the *availability* of a feature, + * which can be checked using hasFeature(), and its *state*. + * For example, the SDL backend *has* the kFeatureFullscreenMode, + * so hasFeature returns true for it. On the other hand, + * fullscreen mode may be active or not; this can be determined + * by checking the state via getFeatureState(). Finally, to + * switch between fullscreen and windowed mode, use setFeatureState(). */ enum Feature { /** - * If your backend supports both a windowed and a fullscreen mode, - * then this feature flag can be used to switch between the two. + * If supported, this feature flag can be used to switch between + * windowed and fullscreen mode. */ kFeatureFullscreenMode, @@ -144,10 +219,10 @@ public: * pixels). When the backend support this, then games running at * 320x200 pixels should be scaled up to 320x240 pixels. For all other * resolutions, ignore this feature flag. - * @note You can find utility functions in common/scaler.h which can - * be used to implement aspect ratio correction. In particular, + * @note Backend implementors can find utility functions in common/scaler.h + * which can be used to implement aspect ratio correction. In * stretch200To240() can stretch a rect, including (very fast) - * interpolation, and works in-place. + * particular, interpolation, and works in-place. */ kFeatureAspectRatioCorrection, @@ -159,43 +234,58 @@ public: kFeatureVirtualKeyboard, /** - * This flag determines whether or not the cursor can have its own palette. + * Backends supporting this feature allow specifying a custom palette + * for the cursor. The custom palette is used if the feature state + * is set to true by the client code via setFeatureState(). + * * It is currently used only by some Macintosh versions of Humongous - * Entertainment games. If the backend doesn't implement this feature then - * the engine switches to b/w versions of cursors. + * Entertainment games. If the backend doesn't implement this feature + * then the engine switches to b/w versions of cursors. * The GUI also relies on this feature for mouse cursors. - * - * To enable the cursor palette call "disableCursorPalette" with false. - * @see disableCursorPalette */ - kFeatureCursorHasPalette, + kFeatureCursorPalette, /** - * Set to true if the overlay pixel format has an alpha channel. - * This should only be set if it offers at least 3-4 bits of accuracy, - * as opposed to a single alpha bit. + * A backend have this feature if its overlay pixel format has an alpha + * channel which offers at least 3-4 bits of accuracy (as opposed to + * just a single alpha bit). + * + * This feature has no associated state. */ kFeatureOverlaySupportsAlpha, /** - * Set to true to iconify the window. + * Client code can set the state of this feature to true in order to + * iconify the application window. */ kFeatureIconifyWindow, /** - * This feature, set to true, is a hint toward the backend to disable all - * key filtering/mapping, in cases where it would be beneficial to do so. - * As an example case, this is used in the agi engine's predictive dialog. + * Setting the state of this feature to true tells the backend to disable + * all key filtering/mapping, in cases where it would be beneficial to do so. + * As an example case, this is used in the AGI engine's predictive dialog. * When the dialog is displayed this feature is set so that backends with * phone-like keypad temporarily unmap all user actions which leads to * comfortable word entry. Conversely, when the dialog exits the feature * is set to false. + * + * TODO: The word 'beneficial' above is very unclear. Beneficial to + * whom and for what??? Just giving an example is not enough. + * * TODO: Fingolfin suggests that the way the feature is used can be * generalized in this sense: Have a keyboard mapping feature, which the * engine queries for to assign keys to actions ("Here's my default key * map for these actions, what do you want them set to?"). */ - kFeatureDisableKeyFiltering + kFeatureDisableKeyFiltering, + + /** + * The presence of this feature indicates whether the displayLogFile() + * call is supported. + * + * This feature has no associated state. + */ + kFeatureDisplayLogFile }; /** @@ -367,7 +457,7 @@ public: * reset the scale to x1 so the screen will not be too big when starting * the game. */ - virtual void resetGraphicsScale() = 0; + virtual void resetGraphicsScale() {} #ifdef USE_RGB_COLOR /** @@ -770,25 +860,13 @@ public: * The palette entries from 'start' till (start+num-1) will be replaced - so * a full palette update is accomplished via start=0, num=256. * - * Backends which implement it should have kFeatureCursorHasPalette flag set + * Backends which implement it should have kFeatureCursorPalette flag set * * @see setPalette - * @see kFeatureCursorHasPalette + * @see kFeatureCursorPalette */ virtual void setCursorPalette(const byte *colors, uint start, uint num) {} - /** - * Disable or enable cursor palette. - * - * Backends which implement it should have kFeatureCursorHasPalette flag set - * - * @param disable True to disable, false to enable. - * - * @see setPalette - * @see kFeatureCursorHasPalette - */ - virtual void disableCursorPalette(bool disable) {} - //@} @@ -813,13 +891,17 @@ public: * Return the timer manager singleton. For more information, refer * to the TimerManager documentation. */ - virtual Common::TimerManager *getTimerManager() = 0; + inline Common::TimerManager *getTimerManager() { + return _timerManager; + } /** * Return the event manager singleton. For more information, refer * to the EventManager documentation. */ - virtual Common::EventManager *getEventManager() = 0; + inline Common::EventManager *getEventManager() { + return _eventManager; + } /** * Register hardware keys with keymapper @@ -909,7 +991,9 @@ public: * Return the audio cd manager. For more information, refer to the * AudioCDManager documentation. */ - virtual AudioCDManager *getAudioCDManager() = 0; + inline AudioCDManager *getAudioCDManager() { + return _audiocdManager; + } //@} @@ -943,7 +1027,8 @@ public: * rectangle over the regular screen content; or in a message box beneath * it; etc.). * - * Currently, only pure ASCII messages can be expected to show correctly. + * The message is expected to be provided in the current TranslationManager + * charset. * * @note There is a default implementation in BaseBackend which uses a * TimedMessageDialog to display the message. Hence implementing @@ -958,14 +1043,16 @@ public: * and other modifiable persistent game data. For more information, * refer to the SaveFileManager documentation. */ - virtual Common::SaveFileManager *getSavefileManager() = 0; + inline Common::SaveFileManager *getSavefileManager() { + return _savefileManager; + } /** * Returns the FilesystemFactory object, depending on the current architecture. * * @return the FSNode factory for the current architecture */ - virtual FilesystemFactory *getFilesystemFactory() = 0; + virtual FilesystemFactory *getFilesystemFactory(); /** * Add system specific Common::Archive objects to the given SearchSet. @@ -984,7 +1071,7 @@ public: * ReadStream instance. It is the callers responsiblity to delete * the stream after use. */ - virtual Common::SeekableReadStream *createConfigReadStream() = 0; + virtual Common::SeekableReadStream *createConfigReadStream(); /** * Open the default config file for writing, by returning a suitable @@ -993,7 +1080,14 @@ public: * * May return 0 to indicate that writing to config file is not possible. */ - virtual Common::WriteStream *createConfigWriteStream() = 0; + virtual Common::WriteStream *createConfigWriteStream(); + + /** + * Get the default file name (or even path) where the user configuration + * of ScummVM will be saved. + * Note that not all ports may use this. + */ + virtual Common::String getDefaultConfigFileName(); /** * Logs a given message. @@ -1010,6 +1104,33 @@ public: virtual void logMessage(LogMessageType::Type type, const char *message); /** + * Open the log file in a way that allows the user to review it, + * and possibly email it (or parts of it) to the ScummVM team, + * e.g. as part of a bug report. + * + * On a desktop operating system, this would typically launch + * some kind of (external) text editor / viewer. + * On a phone, it might also cause a context switch to another + * application. Finally, on some ports, it might not be supported + * at all, and so do nothing. + * + * The kFeatureDisplayLogFile feature flag can be used to + * test whether this call has been implemented by the active + * backend. + * + * @return true if all seems to have gone fine, false if an error occurred + * + * @note An error could mean that the log file did not exist, + * or the editor could not launch. However, a return value of true does + * not guarantee that the user actually will see the log file. + * + * @note It is up to the backend to ensure that the system is in a state + * that allows the user to actually see the displayed log files. This + * might for example require leaving fullscreen mode. + */ + virtual bool displayLogFile() { return false; } + + /** * Returns the locale of the system. * * This returns the currently set up locale of the system, on which diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp index 9bd052fb3d..5217c4e82c 100644 --- a/common/xmlparser.cpp +++ b/common/xmlparser.cpp @@ -22,9 +22,7 @@ // FIXME: Avoid using fprintf #define FORBIDDEN_SYMBOL_EXCEPTION_fprintf - -// FIXME: Avoid using vfprintf -#define FORBIDDEN_SYMBOL_EXCEPTION_vfprintf +#define FORBIDDEN_SYMBOL_EXCEPTION_stderr #include "common/xmlparser.h" @@ -83,7 +81,7 @@ void XMLParser::close() { _stream = 0; } -bool XMLParser::parserError(const char *errorString, ...) { +bool XMLParser::parserError(const Common::String &errStr) { _state = kParserError; const int startPosition = _stream->pos(); @@ -134,12 +132,7 @@ bool XMLParser::parserError(const char *errorString, ...) { fprintf(stderr, "%c", _stream->readByte()); fprintf(stderr, "\n\nParser error: "); - - va_list args; - va_start(args, errorString); - vfprintf(stderr, errorString, args); - va_end(args); - + fprintf(stderr, "%s", errStr.c_str()); fprintf(stderr, "\n\n"); return false; @@ -181,16 +174,16 @@ bool XMLParser::parseActiveKey(bool closed) { for (List<XMLKeyLayout::XMLKeyProperty>::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) { if (i->required && !localMap.contains(i->name)) - return parserError("Missing required property '%s' inside key '%s'", i->name.c_str(), key->name.c_str()); + return parserError("Missing required property '" + i->name + "' inside key '" + key->name + "'"); else if (localMap.contains(i->name)) keyCount--; } if (keyCount > 0) - return parserError("Unhandled property inside key '%s'.", key->name.c_str()); + return parserError("Unhandled property inside key '" + key->name + "'."); } else { - return parserError("Unexpected key in the active scope ('%s').", key->name.c_str()); + return parserError("Unexpected key in the active scope ('" + key->name + "')."); } // check if any of the parents must be ignored. @@ -205,7 +198,7 @@ bool XMLParser::parseActiveKey(bool closed) { // when keyCallback() fails, a parserError() must be set. // We set it manually in that case. if (_state != kParserError) - parserError("Unhandled exception when parsing '%s' key.", key->name.c_str()); + parserError("Unhandled exception when parsing '" + key->name + "' key."); return false; } @@ -395,7 +388,7 @@ bool XMLParser::parse() { case kParserNeedPropertyName: if (activeClosure) { if (!closeKey()) { - parserError("Missing data when closing key '%s'.", _activeKey.top()->name.c_str()); + parserError("Missing data when closing key '" + _activeKey.top()->name + "'."); break; } diff --git a/common/xmlparser.h b/common/xmlparser.h index 84fca294a0..7923e43a37 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -274,7 +274,7 @@ protected: * Parser error always returns "false" so we can pass the return value * directly and break down the parsing. */ - bool parserError(const char *errorString, ...) GCC_PRINTF(2, 3); + bool parserError(const Common::String &errStr); /** * Skips spaces/whitelines etc. |