diff options
author | Max Horn | 2009-01-30 01:17:12 +0000 |
---|---|---|
committer | Max Horn | 2009-01-30 01:17:12 +0000 |
commit | 1d097d9791b99b78790d68133a4ecf07057a28e6 (patch) | |
tree | e776990e7cba117cf3e7560b75fddb3706aad18b | |
parent | 42b26e0f56752646f7396fbfdea2cf9bba3063ab (diff) | |
download | scummvm-rg350-1d097d9791b99b78790d68133a4ecf07057a28e6.tar.gz scummvm-rg350-1d097d9791b99b78790d68133a4ecf07057a28e6.tar.bz2 scummvm-rg350-1d097d9791b99b78790d68133a4ecf07057a28e6.zip |
Moved debug() etc. and special debug flag handling code to common/debug.*; also some tweaks to the code
svn-id: r36134
-rw-r--r-- | common/debug.cpp | 229 | ||||
-rw-r--r-- | common/debug.h | 154 | ||||
-rw-r--r-- | common/module.mk | 1 | ||||
-rw-r--r-- | common/util.cpp | 229 | ||||
-rw-r--r-- | common/util.h | 95 |
5 files changed, 429 insertions, 279 deletions
diff --git a/common/debug.cpp b/common/debug.cpp new file mode 100644 index 0000000000..6c8d94a829 --- /dev/null +++ b/common/debug.cpp @@ -0,0 +1,229 @@ +/* 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/debug.h" +#include "common/util.h" + +#include "engines/engine.h" + +#include <stdarg.h> // For va_list etc. + + +#ifdef __PLAYSTATION2__ + // for those replaced fopen/fread/etc functions + typedef unsigned long uint64; + typedef signed long int64; + #include "backends/platform/ps2/fileio.h" + + #define fprintf ps2_fprintf + #define fputs(str, file) ps2_fputs(str, file) + #define fflush(a) ps2_fflush(a) +#endif + +#ifdef __DS__ + #include "backends/fs/ds/ds-fs.h" + + void std_fprintf(FILE* handle, const char* fmt, ...); + void std_fflush(FILE* handle); + + #define fprintf(file, fmt, ...) do { char str[128]; sprintf(str, fmt, ##__VA_ARGS__); DS::std_fwrite(str, strlen(str), 1, file); } while(0) + #define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file) + #define fflush(file) DS::std_fflush(file) +#endif + + +namespace Common { + +namespace { + +DebugLevelContainer gDebugLevels; +uint32 gDebugLevelsEnabled = 0; + +struct DebugLevelSort { + bool operator()(const EngineDebugLevel &l, const EngineDebugLevel &r) { + return (l.option.compareToIgnoreCase(r.option) < 0); + } +}; + +struct DebugLevelSearch { + const String &_option; + + DebugLevelSearch(const String &option) : _option(option) {} + + bool operator()(const EngineDebugLevel &l) { + return _option.equalsIgnoreCase(l.option); + } +}; + +} + +bool addSpecialDebugLevel(uint32 level, const String &option, const String &description) { + DebugLevelContainer::iterator i = find_if(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSearch(option)); + + if (i != gDebugLevels.end()) { + warning("Declared engine debug level '%s' again", option.c_str()); + *i = EngineDebugLevel(level, option, description); + } else { + gDebugLevels.push_back(EngineDebugLevel(level, option, description)); + sort(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSort()); + } + + return true; +} + +void clearAllSpecialDebugLevels() { + gDebugLevelsEnabled = 0; + gDebugLevels.clear(); +} + +bool enableSpecialDebugLevel(const String &option) { + DebugLevelContainer::iterator i = find_if(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSearch(option)); + + if (i != gDebugLevels.end()) { + gDebugLevelsEnabled |= i->level; + i->enabled = true; + + return true; + } else { + return false; + } +} + +void enableSpecialDebugLevelList(const String &option) { + StringTokenizer tokenizer(option, " ,"); + String token; + + while (!tokenizer.empty()) { + token = tokenizer.nextToken(); + if (!enableSpecialDebugLevel(token)) + warning("Engine does not support debug level '%s'", token.c_str()); + } +} + +bool disableSpecialDebugLevel(const String &option) { + DebugLevelContainer::iterator i = find_if(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSearch(option)); + + if (i != gDebugLevels.end()) { + gDebugLevelsEnabled &= ~i->level; + i->enabled = false; + + return true; + } else { + return false; + } +} + +const DebugLevelContainer &listSpecialDebugLevels() { + return gDebugLevels; +} + +uint32 getEnabledSpecialDebugLevels() { + return gDebugLevelsEnabled; +} + +} // End of namespace Common + + +int gDebugLevel = -1; + +#ifndef DISABLE_TEXT_CONSOLE + +static void debugHelper(const char *s, va_list va, bool caret = true) { + char in_buf[STRINGBUFLEN]; + char buf[STRINGBUFLEN]; + vsnprintf(in_buf, STRINGBUFLEN, s, va); + + // Next, give the active engine (if any) a chance to augment the message, + // but only if not used from debugN. + if (g_engine && caret) { + g_engine->errorString(in_buf, buf, STRINGBUFLEN); + } else { + strncpy(buf, in_buf, STRINGBUFLEN); + } + buf[STRINGBUFLEN-1] = '\0'; + + if (caret) { + buf[STRINGBUFLEN-2] = '\0'; + strcat(buf, "\n"); + } + + fputs(buf, stdout); + +#if defined( USE_WINDBG ) +#if defined( _WIN32_WCE ) + TCHAR buf_unicode[1024]; + MultiByteToWideChar(CP_ACP, 0, buf, strlen(buf) + 1, buf_unicode, sizeof(buf_unicode)); + OutputDebugString(buf_unicode); +#else + OutputDebugString(buf); +#endif +#endif + + fflush(stdout); +} + +void debug(const char *s, ...) { + va_list va; + + va_start(va, s); + debugHelper(s, va); + va_end(va); +} + +void debug(int level, const char *s, ...) { + va_list va; + + if (level > gDebugLevel) + return; + + va_start(va, s); + debugHelper(s, va); + va_end(va); + +} + +void debugN(int level, const char *s, ...) { + va_list va; + + if (level > gDebugLevel) + return; + + va_start(va, s); + debugHelper(s, va, false); + va_end(va); +} + +void debugC(int level, uint32 engine_level, const char *s, ...) { + va_list va; + + if (gDebugLevel != 11) + if (level > gDebugLevel || !(Common::gDebugLevelsEnabled & engine_level)) + return; + + va_start(va, s); + debugHelper(s, va); + va_end(va); +} + +#endif diff --git a/common/debug.h b/common/debug.h new file mode 100644 index 0000000000..d446a53d0e --- /dev/null +++ b/common/debug.h @@ -0,0 +1,154 @@ +/* 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 COMMON_DEBUG_H +#define COMMON_DEBUG_H + +#include "common/scummsys.h" +#include "common/list.h" +#include "common/str.h" + + +namespace Common { + + +struct EngineDebugLevel { + EngineDebugLevel() : option(""), description(""), level(0), enabled(false) {} + EngineDebugLevel(uint32 l, const String &o, const String &d) + : option(o), description(d), level(l), enabled(false) {} + + String option; + String description; + + uint32 level; + bool enabled; +}; + +/** + * Adds a engine debug level. + * @param level the level flag (should be OR-able i.e. first one should be 1 than 2,4,...) + * @param option the option name which is used in the debugger/on the command line to enable + * this special debug level, the option will be compared case !insentiv! later + * @param description the description which shows up in the debugger + * @return true on success false on failure + */ +bool addSpecialDebugLevel(uint32 level, const String &option, const String &description); + +/** + * Resets all engine debug levels + */ +void clearAllSpecialDebugLevels(); + +/** + * Enables a engine debug level + * @param option the option which should be enabled + * @return true on success false on failure + */ +bool enableSpecialDebugLevel(const String &option); + +// only used for parsing the levels from the commandline +void enableSpecialDebugLevelList(const String &option); + +/** + * Disables a engine debug level + * @param option the option to disable + * @return true on success false on failure + */ +bool disableSpecialDebugLevel(const String &option); + +typedef List<EngineDebugLevel> DebugLevelContainer; + +/** + * Lists all debug levels + * @return returns a arry with all debug levels + */ +const DebugLevelContainer &listSpecialDebugLevels(); + +/** + * Return the active debug flag mask (i.e. all active debug flags ORed + * together into a single uint32). + */ +uint32 getEnabledSpecialDebugLevels(); + + +} // End of namespace Common + + +#ifdef DISABLE_TEXT_CONSOLE + +inline void debug(const char *s, ...) {} +inline void debug(int level, const char *s, ...) {} +inline void debugN(int level, const char *s, ...) {} +inline void debugC(int level, uint32 engine_level, const char *s, ...) {} + + +#else + + +/** + * Print a debug message to the text console (stderr). + * Automatically appends a newline. + */ +void debug(const char *s, ...) GCC_PRINTF(1, 2); + +/** + * Print a debug message to the text console (stderr), but only if + * the specified level does not exceed the value of gDebugLevel. + * As a rule of thumb, the more important the message, the lower the level. + * Automatically appends a newline. + */ +void debug(int level, const char *s, ...) GCC_PRINTF(2, 3); + +/** + * Print a debug message to the text console (stderr), but only if + * the specified level does not exceed the value of gDebugLevel. + * As a rule of thumb, the more important the message, the lower the level. + * Does not append a newline. + */ +void debugN(int level, const char *s, ...) GCC_PRINTF(2, 3); + +/** + * Print a debug message to the text console (stderr), but only if + * the specified level does not exceed the value of gDebugLevel OR + * if the specified special debug level is active. + * As a rule of thumb, the more important the message, the lower the level. + * Automatically appends a newline. + * + * @see enableSpecialDebugLevel + */ +void debugC(int level, uint32 engine_level, const char *s, ...) GCC_PRINTF(3, 4); + + +#endif + +/** + * The debug level. Initially set to -1, indicating that no debug output + * should be shown. Positive values usually imply an increasing number of + * debug output shall be generated, the higher the value, the more verbose the + * information (although the exact semantics are up to the engines). + */ +extern int gDebugLevel; + + +#endif diff --git a/common/module.mk b/common/module.mk index 6d8a71cd23..bdf9590962 100644 --- a/common/module.mk +++ b/common/module.mk @@ -4,6 +4,7 @@ MODULE_OBJS := \ archive.o \ config-file.o \ config-manager.o \ + debug.o \ file.o \ fs.o \ hashmap.o \ diff --git a/common/util.cpp b/common/util.cpp index a1a6568579..2fca568a1b 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -22,10 +22,10 @@ * $Id$ */ -#include "engines/engine.h" #include "common/util.h" #include "common/system.h" #include "gui/debugger.h" +#include "engines/engine.h" #include <stdarg.h> // For va_list etc. @@ -41,24 +41,18 @@ extern bool isSmartphone(void); #include "backends/platform/ps2/fileio.h" #define fprintf ps2_fprintf + #define fputs(str, file) ps2_fputs(str, file) #define fflush(a) ps2_fflush(a) #endif #ifdef __DS__ #include "backends/fs/ds/ds-fs.h" - #undef stderr - #undef stdout - #undef stdin - - #define stdout ((DS::fileHandle*) -1) - #define stderr ((DS::fileHandle*) -2) - #define stdin ((DS::fileHandle*) -3) - void std_fprintf(FILE* handle, const char* fmt, ...); void std_fflush(FILE* handle); - #define fprintf(file, fmt, ...) { char str[128]; sprintf(str, fmt, ##__VA_ARGS__); DS::std_fwrite(str, strlen(str), 1, file); } + #define fprintf(file, fmt, ...) do { char str[128]; sprintf(str, fmt, ##__VA_ARGS__); DS::std_fwrite(str, strlen(str), 1, file); } while(0) + #define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file) #define fflush(file) DS::std_fflush(file) #endif @@ -146,6 +140,22 @@ void hexdump(const byte * data, int len, int bytesPerLine) { printf("|\n"); } +String tag2string(uint32 tag) { + char str[5]; + str[0] = (char)(tag >> 24); + str[1] = (char)(tag >> 16); + str[2] = (char)(tag >> 8); + str[3] = (char)tag; + str[4] = '\0'; + // Replace non-printable chars by dot + for (int i = 0; i < 4; ++i) { + if (!isprint(str[i])) + str[i] = '.'; + } + return Common::String(str); +} + + #pragma mark - @@ -360,194 +370,13 @@ const char *getRenderModeDescription(RenderMode id) { return 0; } -#pragma mark - - -namespace { - -DebugLevelContainer gDebugLevels; -uint32 gDebugLevelsEnabled = 0; - -struct DebugLevelSort { - bool operator()(const EngineDebugLevel &l, const EngineDebugLevel &r) { - return (l.option.compareToIgnoreCase(r.option) < 0); - } -}; - -struct DebugLevelSearch { - const String &_option; - - DebugLevelSearch(const String &option) : _option(option) {} - - bool operator()(const EngineDebugLevel &l) { - return _option.equalsIgnoreCase(l.option); - } -}; - -} - -bool addSpecialDebugLevel(uint32 level, const String &option, const String &description) { - DebugLevelContainer::iterator i = find_if(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSearch(option)); - - if (i != gDebugLevels.end()) { - warning("Declared engine debug level '%s' again", option.c_str()); - *i = EngineDebugLevel(level, option, description); - } else { - gDebugLevels.push_back(EngineDebugLevel(level, option, description)); - sort(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSort()); - } - - return true; -} - -void clearAllSpecialDebugLevels() { - gDebugLevelsEnabled = 0; - gDebugLevels.clear(); -} - -bool enableSpecialDebugLevel(const String &option) { - DebugLevelContainer::iterator i = find_if(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSearch(option)); - - if (i != gDebugLevels.end()) { - gDebugLevelsEnabled |= i->level; - i->enabled = true; - - return true; - } else { - return false; - } -} - -void enableSpecialDebugLevelList(const String &option) { - StringTokenizer tokenizer(option, " ,"); - String token; - - while (!tokenizer.empty()) { - token = tokenizer.nextToken(); - if (!enableSpecialDebugLevel(token)) - warning("Engine does not support debug level '%s'", token.c_str()); - } -} - -bool disableSpecialDebugLevel(const String &option) { - DebugLevelContainer::iterator i = find_if(gDebugLevels.begin(), gDebugLevels.end(), DebugLevelSearch(option)); - - if (i != gDebugLevels.end()) { - gDebugLevelsEnabled &= ~i->level; - i->enabled = false; - - return true; - } else { - return false; - } -} - -const DebugLevelContainer &listSpecialDebugLevels() { - return gDebugLevels; -} - -uint32 getEnabledSpecialDebugLevels() { - return gDebugLevelsEnabled; -} - } // End of namespace Common -/** - * The debug level. Initially set to -1, indicating that no debug output - * should be shown. Positive values usually imply an increasing number of - * debug output shall be generated, the higher the value, the more verbose the - * information (although the exact semantics are up to the engines). - */ -int gDebugLevel = -1; - #ifndef DISABLE_TEXT_CONSOLE -static void debugHelper(const char *in_buf, bool caret = true) { - char buf[STRINGBUFLEN]; - - // Next, give the active engine (if any) a chance to augment the message - if (g_engine) { - g_engine->errorString(in_buf, buf, STRINGBUFLEN); - } else { - strncpy(buf, in_buf, STRINGBUFLEN); - } - buf[STRINGBUFLEN-2] = '\0'; - buf[STRINGBUFLEN-1] = '\0'; - - if (caret) - strcat(buf, "\n"); - - fprintf(stdout, "%s", buf); // FIXME: Use fputs instead - -#if defined( USE_WINDBG ) -#if defined( _WIN32_WCE ) - TCHAR buf_unicode[1024]; - MultiByteToWideChar(CP_ACP, 0, buf, strlen(buf) + 1, buf_unicode, sizeof(buf_unicode)); - OutputDebugString(buf_unicode); -#else - OutputDebugString(buf); -#endif -#endif - - fflush(stdout); -} - -void debug(int level, const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; - - if (level > gDebugLevel) - return; - - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); - - debugHelper(buf); -} - -void debugN(int level, const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; - - if (level > gDebugLevel) - return; - - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); - - debugHelper(buf, false); -} - -void debug(const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; - - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); - - debugHelper(buf); -} - -void debugC(int level, uint32 engine_level, const char *s, ...) { - char buf[STRINGBUFLEN]; - va_list va; - - if (gDebugLevel != 11) - if (level > gDebugLevel || !(Common::gDebugLevelsEnabled & engine_level)) - return; - - va_start(va, s); - vsnprintf(buf, STRINGBUFLEN, s, va); - va_end(va); - - debugHelper(buf); -} - void warning(const char *s, ...) { char buf[STRINGBUFLEN]; va_list va; @@ -590,12 +419,16 @@ void NORETURN error(const char *s, ...) { g_engine->errorString(buf_input, buf_output, STRINGBUFLEN); } else { strncpy(buf_output, buf_input, STRINGBUFLEN); - buf_output[STRINGBUFLEN-1] = '\0'; } + buf_output[STRINGBUFLEN-3] = '\0'; + buf_output[STRINGBUFLEN-2] = '\0'; + buf_output[STRINGBUFLEN-1] = '\0'; + strcat(buf_output, "!\n"); + // Print the error message to stderr - fprintf(stderr, "%s!\n", buf_output); + fputs(buf_output, stderr); // Unless this error -originated- within the debugger itself, we // now invoke the debugger, if available / supported. @@ -642,13 +475,3 @@ void NORETURN error(const char *s, ...) { exit(1); } - -Common::String tag2string(uint32 tag) { - char str[5]; - str[0] = (char)(tag >> 24); - str[1] = (char)(tag >> 16); - str[2] = (char)(tag >> 8); - str[3] = (char)tag; - str[4] = '\0'; - return Common::String(str); -} diff --git a/common/util.h b/common/util.h index b1189e156f..65d288d6f0 100644 --- a/common/util.h +++ b/common/util.h @@ -27,7 +27,7 @@ #include "common/scummsys.h" #include "common/str.h" -#include "common/list.h" +#include "common/debug.h" #ifdef MIN #undef MIN @@ -50,6 +50,7 @@ template<typename T> inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; } #define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) + namespace Common { /** @@ -87,6 +88,18 @@ private: */ extern void hexdump(const byte * data, int len, int bytesPerLine = 16); + +/** + * Take a 32 bit value and turn it into a four character string, where each of + * the four bytes is turned into one character. Most significant byte is printed + * first. + */ +String tag2string(uint32 tag); +#define tag2str(x) Common::tag2string(x).c_str() + + + + /** * Simple random number generator. Although it is definitely not suitable for * cryptographic purposes, it serves our purposes just fine. @@ -243,65 +256,6 @@ extern const char *getRenderModeCode(RenderMode id); extern const char *getRenderModeDescription(RenderMode id); -struct EngineDebugLevel { - EngineDebugLevel() : option(""), description(""), level(0), enabled(false) {} - EngineDebugLevel(uint32 l, const String &o, const String &d) - : option(o), description(d), level(l), enabled(false) {} - - String option; - String description; - - uint32 level; - bool enabled; -}; - -/** - * Adds a engine debug level. - * @param level the level flag (should be OR-able i.e. first one should be 1 than 2,4,...) - * @param option the option name which is used in the debugger/on the command line to enable - * this special debug level, the option will be compared case !insentiv! later - * @param description the description which shows up in the debugger - * @return true on success false on failure - */ -bool addSpecialDebugLevel(uint32 level, const String &option, const String &description); - -/** - * Resets all engine debug levels - */ -void clearAllSpecialDebugLevels(); - -/** - * Enables a engine debug level - * @param option the option which should be enabled - * @return true on success false on failure - */ -bool enableSpecialDebugLevel(const String &option); - -// only used for parsing the levels from the commandline -void enableSpecialDebugLevelList(const String &option); - -/** - * Disables a engine debug level - * @param option the option to disable - * @return true on success false on failure - */ -bool disableSpecialDebugLevel(const String &option); - -typedef List<EngineDebugLevel> DebugLevelContainer; - -/** - * Lists all debug levels - * @return returns a arry with all debug levels - */ -const DebugLevelContainer &listSpecialDebugLevels(); - -/** - * Return the active debug flag mask (i.e. all active debug flags ORed - * together into a single uint32). - */ -uint32 getEnabledSpecialDebugLevels(); - - } // End of namespace Common @@ -317,26 +271,15 @@ inline int printf(const char *s, ...) { return 0; } inline void warning(const char *s, ...) {} -inline void debug(int level, const char *s, ...) {} -inline void debug(const char *s, ...) {} -inline void debugN(int level, const char *s, ...) {} -inline void debugC(int level, uint32 engine_level, const char *s, ...) {} - #else +/** + * Print a warning message to the text console (stdout). + * Automatically prepends the text "WARNING: " and appends + * an exclamation mark and a newline. + */ void warning(const char *s, ...) GCC_PRINTF(1, 2); -void debug(int level, const char *s, ...) GCC_PRINTF(2, 3); -void debug(const char *s, ...) GCC_PRINTF(1, 2); -void debugN(int level, const char *s, ...) GCC_PRINTF(2, 3); -void debugC(int level, uint32 engine_level, const char *s, ...) GCC_PRINTF(3, 4); - #endif -extern int gDebugLevel; - -Common::String tag2string(uint32 tag); -#define tag2str(x) tag2string(x).c_str() - - #endif |