1
1
forked from 0ad/0ad

- display_msg and display_error -> debug prefix since in debug header

- debug_warn_err now takes LibError
- lib_error.cpp: revise error code -> string (only support liberror
now); add function to set errno from LibError
- unifont, CFont: parameter made a simple wchar_t from const wchar_t&
- mmap now sets errno
- Loader and VfsUtil function now return LibError as well
- Profile.cpp, ProfileViewer.cpp: fix int/uint/size_t warnings
- Renderer.cpp: fix cannot-generate-assignment-operator warning

This was SVN commit r3235.
This commit is contained in:
janwas 2005-12-12 19:19:30 +00:00
parent 8d3df809bb
commit 6e82e33ccf
24 changed files with 295 additions and 251 deletions

View File

@ -30,6 +30,7 @@
#include "self_test.h" #include "self_test.h"
#include "app_hooks.h" #include "app_hooks.h"
// needed when writing crashlog // needed when writing crashlog
static const size_t LOG_CHARS = 16384; static const size_t LOG_CHARS = 16384;
wchar_t debug_log[LOG_CHARS]; wchar_t debug_log[LOG_CHARS];
@ -436,14 +437,26 @@ const char* debug_get_symbol_string(void* symbol, const char* name, const char*
} }
//-----------------------------------------------------------------------------
// output
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ErrorReaction display_error(const wchar_t* description, int flags, // translates and displays the given strings in a dialog.
uint skip, void* context, const char* file, int line) // this is typically only used when debug_display_error has failed or
// is unavailable because that function is much more capable.
// implemented via sys_display_msgw; see documentation there.
void debug_display_msgw(const wchar_t* caption, const wchar_t* msg)
{
sys_display_msgw(ah_translate(caption), ah_translate(msg));
}
// display the error dialog. shows <description> along with a stack trace.
// context and skip are as with debug_dump_stack.
// flags: see DisplayErrorFlags. file and line indicate where the error
// occurred and are typically passed as __FILE__, __LINE__.
ErrorReaction debug_display_error(const wchar_t* description,
int flags, uint skip, void* context, const char* file, int line)
{ {
if(!file || file[0] == '\0') if(!file || file[0] == '\0')
file = "unknown"; file = "unknown";
@ -495,7 +508,7 @@ ErrorReaction display_error(const wchar_t* description, int flags,
ErrorReaction er = sys_display_error(text, flags); ErrorReaction er = sys_display_error(text, flags);
// note: debug_break-ing here to make sure the app doesn't continue // note: debug_break-ing here to make sure the app doesn't continue
// running is no longer necessary. display_error now determines our // running is no longer necessary. debug_display_error now determines our
// window handle and is modal. // window handle and is modal.
// handle "break" request unless the caller wants to (doing so here // handle "break" request unless the caller wants to (doing so here
@ -528,8 +541,8 @@ ErrorReaction display_error(const wchar_t* description, int flags,
// notify the user that an assertion failed; displays a stack trace with // notify the user that an assertion failed; displays a stack trace with
// local variables. // local variables.
ErrorReaction debug_assert_failed(const char* file, int line, ErrorReaction debug_assert_failed(const char* expr,
const char* func, const char* expr) const char* file, int line, const char* func)
{ {
// for edge cases in some functions, warnings (=asserts) are raised in // for edge cases in some functions, warnings (=asserts) are raised in
// addition to returning an error code. self-tests deliberately trigger // addition to returning an error code. self-tests deliberately trigger
@ -548,12 +561,12 @@ ErrorReaction debug_assert_failed(const char* file, int line,
uint skip = 1; void* context = 0; uint skip = 1; void* context = 0;
wchar_t buf[400]; wchar_t buf[400];
swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed at %hs:%d (%hs): \"%hs\"", base_name, line, func, expr); swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed at %hs:%d (%hs): \"%hs\"", base_name, line, func, expr);
return display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line); return debug_display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip,context, base_name,line);
} }
ErrorReaction debug_warn_err(int err, const char* file, int line, ErrorReaction debug_warn_err(LibError err,
const char* func) const char* file, int line, const char* func)
{ {
// for edge cases in some functions, warnings (=asserts) are raised in // for edge cases in some functions, warnings (=asserts) are raised in
// addition to returning an error code. self-tests deliberately trigger // addition to returning an error code. self-tests deliberately trigger
@ -573,7 +586,7 @@ ErrorReaction debug_warn_err(int err, const char* file, int line,
wchar_t buf[400]; wchar_t buf[400];
char err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf)); char err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf));
swprintf(buf, ARRAY_SIZE(buf), L"Function call failed at %hs:%d (%hs): return value was %d (%hs)", base_name, line, func, err, err_buf); swprintf(buf, ARRAY_SIZE(buf), L"Function call failed at %hs:%d (%hs): return value was %d (%hs)", base_name, line, func, err, err_buf);
return display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line); return debug_display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip,context, base_name,line);
} }

View File

@ -19,7 +19,6 @@
#define DEBUG_H_INCLUDED #define DEBUG_H_INCLUDED
#include "lib.h" // STMT #include "lib.h" // STMT
#include "sysdep/sysdep.h" // ErrorReaction
#if OS_WIN #if OS_WIN
# include "sysdep/win/wdbg.h" # include "sysdep/win/wdbg.h"
#else #else
@ -73,7 +72,7 @@ even if debug information is present and assert dialogs are useless.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// check heap integrity (independently of mmgr). // check heap integrity (independently of mmgr).
// errors are reported by the CRT or via display_error. // errors are reported by the CRT or via debug_display_error.
extern void debug_heap_check(void); extern void debug_heap_check(void);
enum DebugHeapChecks enum DebugHeapChecks
@ -122,7 +121,7 @@ STMT(\
static unsigned char suppress__ = 0x55;\ static unsigned char suppress__ = 0x55;\
if(suppress__ == 0x55 && !(expr))\ if(suppress__ == 0x55 && !(expr))\
{\ {\
switch(debug_assert_failed(__FILE__, __LINE__, __func__, #expr))\ switch(debug_assert_failed(#expr, __FILE__, __LINE__, __func__))\
{\ {\
case ER_SUPPRESS:\ case ER_SUPPRESS:\
suppress__ = 0xAA;\ suppress__ = 0xAA;\
@ -137,9 +136,6 @@ STMT(\
}\ }\
) )
// called when an assertion has failed; notifies the user via display_error.
extern enum ErrorReaction debug_assert_failed(const char* file, int line,
const char* func, const char* assert_expr);
// show a dialog to make sure unexpected states in the program are noticed. // show a dialog to make sure unexpected states in the program are noticed.
// this is less error-prone than "debug_assert(0 && "text");" and avoids // this is less error-prone than "debug_assert(0 && "text");" and avoids
@ -150,6 +146,9 @@ extern enum ErrorReaction debug_assert_failed(const char* file, int line,
#define debug_warn(str) debug_assert((str) && 0) #define debug_warn(str) debug_assert((str) && 0)
// if (LibError)err indicates an function failed, display the error dialog.
// used by CHECK_ERR et al., which wrap function calls and automatically
// warn user and return to caller.
#define DEBUG_WARN_ERR(err)\ #define DEBUG_WARN_ERR(err)\
STMT(\ STMT(\
static unsigned char suppress__ = 0x55;\ static unsigned char suppress__ = 0x55;\
@ -170,8 +169,15 @@ STMT(\
}\ }\
) )
extern enum ErrorReaction debug_warn_err(int err, const char* file, int line,
const char* func); // called when an assertion has failed; notifies the user via debug_display_error.
extern enum ErrorReaction debug_assert_failed(const char* assert_expr,
const char* file, int line, const char* func);
// called when a lib function wrapped in DEBUG_WARN_ERR failed;
// notifies the user via debug_display_error.
extern enum ErrorReaction debug_warn_err(LibError err,
const char* file, int line, const char* func);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -185,12 +191,61 @@ extern void debug_printf(const char* fmt, ...);
extern void debug_wprintf(const wchar_t* fmt, ...); extern void debug_wprintf(const wchar_t* fmt, ...);
extern ErrorReaction display_error(const wchar_t* description, int flags, // translates and displays the given strings in a dialog.
uint skip, void* context, const char* file, int line); // this is typically only used when debug_display_error has failed or
// is unavailable because that function is much more capable.
// implemented via sys_display_msgw; see documentation there.
extern void debug_display_msgw(const wchar_t* caption, const wchar_t* msg);
// choices offered by the shared error dialog
enum ErrorReaction
{
// ignore, continue as if nothing happened.
// note: don't start at 0 because that is interpreted as a
// DialogBoxParam failure.
ER_CONTINUE = 1,
// ignore and do not report again.
// only returned if DE_ALLOW_SUPPRESS was passed.
// note: non-persistent; only applicable during this program run.
ER_SUPPRESS,
// trigger breakpoint, i.e. enter debugger.
// only returned if DE_MANUAL_BREAK was passed; otherwise,
// debug_display_error will trigger a breakpoint itself.
ER_BREAK,
// exit the program immediately.
// never returned; debug_display_error exits immediately.
ER_EXIT
};
enum DisplayErrorFlags
{
// allow the suppress button (requires calling via macro that
// maintains a 'suppress' bool; see debug_assert)
DE_ALLOW_SUPPRESS = 1,
// disallow the continue button. used e.g. if an exception is fatal.
DE_NO_CONTINUE = 2,
// do not trigger a breakpoint inside debug_display_error; caller
// will take care of this if ER_BREAK is returned. this is so that the
// debugger can jump directly into the offending function.
DE_MANUAL_BREAK = 4
};
// display the error dialog. shows <description> along with a stack trace.
// context and skip are as with debug_dump_stack.
// flags: see DisplayErrorFlags. file and line indicate where the error
// occurred and are typically passed as __FILE__, __LINE__.
extern ErrorReaction debug_display_error(const wchar_t* description,
int flags, uint skip, void* context, const char* file, int line);
// convenience version, in case the advanced parameters aren't needed. // convenience version, in case the advanced parameters aren't needed.
// done this way instead of with default values so that it also works in C. // macro instead of providing overload/default values for C compatibility.
#define DISPLAY_ERROR(text) display_error(text, 0, 0, 0, __FILE__, __LINE__) #define DISPLAY_ERROR(text) debug_display_error(text, 0, 0,0, __FILE__,__LINE__)
// //

View File

@ -31,14 +31,6 @@
#endif #endif
// translates the given strings and passes them on to sys_display_msgw
// (see documentation there).
void display_msgw(const wchar_t* caption, const wchar_t* msg)
{
sys_display_msgw(ah_translate(caption), ah_translate(msg));
}
// FNV1-A hash - good for strings. // FNV1-A hash - good for strings.
// if len = 0 (default), treat buf as a C-string; // if len = 0 (default), treat buf as a C-string;
// otherwise, hash <len> bytes of buf. // otherwise, hash <len> bytes of buf.

View File

@ -208,10 +208,6 @@ const size_t GiB = 1ul << 30;
#endif #endif
// translates the given strings and passes them on to sys_display_msgw
// (see documentation there).
extern void display_msgw(const wchar_t* caption, const wchar_t* msg);
#define BIT(n) (1ul << (n)) #define BIT(n) (1ul << (n))

View File

@ -11,17 +11,18 @@
#include <stdlib.h> // abs #include <stdlib.h> // abs
static const char* lib_error_description(int err) static const char* LibError_description(LibError err)
{ {
// not in our range // not in our range
if(!(ERR_MIN <= abs(err) && abs(err) < ERR_MAX)) const int ierr = abs((int)err);
if(!(ERR_MIN <= ierr && ierr < ERR_MAX))
return 0; return 0;
switch(err) switch(err)
{ {
#define ERR(err, id, str) case id: return str; #define ERR(err, id, str) case id: return str;
#include "lib_errors.h" #include "lib_errors.h"
default: return "Unknown lib error"; default: return "Unknown error";
} }
UNREACHABLE; UNREACHABLE;
} }
@ -29,13 +30,12 @@ static const char* lib_error_description(int err)
// generate textual description of an error code. // generate textual description of an error code.
// stores up to <max_chars> in the given buffer. // stores up to <max_chars> in the given buffer.
// <err> can be one of the above error codes, POSIX ENOENT etc., or // if error is unknown/invalid, the string will be something like
// an OS-specific errors. if unknown, the string will be something like
// "Unknown error (65536, 0x10000)". // "Unknown error (65536, 0x10000)".
void error_description_r(int err, char* buf, size_t max_chars) void error_description_r(LibError err, char* buf, size_t max_chars)
{ {
// lib error // lib error
const char* str = lib_error_description(err); const char* str = LibError_description(err);
if(str) if(str)
{ {
// <err> was one of our error codes (chosen so as not to conflict // <err> was one of our error codes (chosen so as not to conflict
@ -44,34 +44,7 @@ void error_description_r(int err, char* buf, size_t max_chars)
return; return;
} }
// Win32 GetLastError and errno both define values in [0,100).
// what we'll do is always try the OS-specific translation,
// add libc's interpretation if <err> is a valid errno, and
// output "Unknown" if none of the above succeeds.
const bool should_display_libc_err = (0 <= err && err < sys_nerr);
bool have_output = false;
// OS-specific error
if(sys_error_description_r(err, buf, max_chars) == 0) // success
{
have_output = true;
// add a separator text before libc description
if(should_display_libc_err)
strcat_s(buf, max_chars, "; libc err=");
}
// libc error
if(should_display_libc_err)
{
strcat_s(buf, max_chars, strerror(err));
// note: we are sure to get meaningful output (not just "unknown")
// because err < sys_nerr.
have_output = true;
}
// fallback // fallback
if(!have_output)
snprintf(buf, max_chars, "Unknown error (%d, 0x%X)", err, err); snprintf(buf, max_chars, "Unknown error (%d, 0x%X)", err, err);
} }
@ -83,30 +56,21 @@ LibError LibError_from_errno()
{ {
switch(errno) switch(errno)
{ {
case ENOMEM: case ENOMEM: return ERR_NO_MEM;
return ERR_NO_MEM;
case EINVAL: case EINVAL: return ERR_INVALID_PARAM;
return ERR_INVALID_PARAM; case ENOSYS: return ERR_NOT_IMPLEMENTED;
case ENOSYS:
return ERR_NOT_IMPLEMENTED;
case ENOENT: case ENOENT: return ERR_PATH_NOT_FOUND;
return ERR_PATH_NOT_FOUND; case EACCES: return ERR_FILE_ACCESS;
case EACCES: case EIO: return ERR_IO;
return ERR_FILE_ACCESS; case ENAMETOOLONG: return ERR_PATH_LENGTH;
case EIO:
return ERR_IO;
case ENAMETOOLONG:
return ERR_PATH_LENGTH;
default: default: return ERR_FAIL;
return ERR_FAIL;
} }
UNREACHABLE; UNREACHABLE;
} }
// translate the return value of any POSIX function into LibError. // translate the return value of any POSIX function into LibError.
// ret is typically to -1 to indicate error and 0 on success. // ret is typically to -1 to indicate error and 0 on success.
// you should set errno to 0 before calling the POSIX function to // you should set errno to 0 before calling the POSIX function to
@ -116,3 +80,36 @@ LibError LibError_from_posix(int ret)
debug_assert(ret == 0 || ret == -1); debug_assert(ret == 0 || ret == -1);
return (ret == 0)? ERR_OK : LibError_from_errno(); return (ret == 0)? ERR_OK : LibError_from_errno();
} }
// return the errno.h equivalent of <err>.
// does not assign to errno (this simplifies code by allowing direct return)
static int return_errno_from_LibError(LibError err)
{
switch(err)
{
case ERR_NO_MEM: return ENOMEM;
case ERR_INVALID_PARAM: return EINVAL;
case ERR_NOT_IMPLEMENTED: return ENOSYS;
case ERR_PATH_NOT_FOUND: return ENOENT;
case ERR_FILE_ACCESS: return EACCES;
case ERR_IO: return EIO;
case ERR_PATH_LENGTH: return ENAMETOOLONG;
// somewhat of a quandary: the set of errnos in wposix.h doesn't
// have an "unknown error". we pick EPERM because we don't expect
// that to come up often otherwise.
default: return EPERM;
}
}
// set errno to the equivalent of <err>. used in wposix - underlying
// functions return LibError but must be translated to errno at
// e.g. the mmap interface level. higher-level code that calls mmap will
// in turn convert back to LibError.
void LibError_set_errno(LibError err)
{
errno = return_errno_from_LibError(err);
}

View File

@ -27,10 +27,9 @@ enum LibError {
// generate textual description of an error code. // generate textual description of an error code.
// stores up to <max_chars> in the given buffer. // stores up to <max_chars> in the given buffer.
// <err> can be one of the above error codes, POSIX ENOENT etc., or // if error is unknown/invalid, the string will be something like
// an OS-specific errors. if unknown, the string will be something like
// "Unknown error (65536, 0x10000)". // "Unknown error (65536, 0x10000)".
extern void error_description_r(int err, char* buf, size_t max_chars); extern void error_description_r(LibError err, char* buf, size_t max_chars);
// return the LibError equivalent of errno, or ERR_FAIL if there's no equal. // return the LibError equivalent of errno, or ERR_FAIL if there's no equal.
@ -43,35 +42,43 @@ extern LibError LibError_from_errno();
// make sure we do not return any stale errors. // make sure we do not return any stale errors.
extern LibError LibError_from_posix(int ret); extern LibError LibError_from_posix(int ret);
// set errno to the equivalent of <err>. used in wposix - underlying
// functions return LibError but must be translated to errno at
// e.g. the mmap interface level. higher-level code that calls mmap will
// in turn convert back to LibError.
extern void LibError_set_errno(LibError err);
// be careful here. the given expression (e.g. variable or // be careful here. the given expression (e.g. variable or
// function return value) may be a Handle (=i64), so it needs to be // function return value) may be a Handle (=i64), so it needs to be
// stored and compared as such. (very large but legitimate Handle values // stored and compared as such. (very large but legitimate Handle values
// casted to int can end up negative) // casted to int can end up negative)
// all functions using this return int (instead of i64) for efficiency and // all functions using this return LibError (instead of i64) for
// simplicity. if the input was negative, it is an error code and is // efficiency and simplicity. if the input was negative, it is an
// therefore known to fit; we still mask with UINT_MAX to avoid // error code and is therefore known to fit; we still mask with
// VC cast-to-smaller-type warnings. // UINT_MAX to avoid VC cast-to-smaller-type warnings.
// if expression evaluates to a negative i64, warn user and return the number. // if expression evaluates to a negative i64, warn user and return the number.
#if OS_WIN #if OS_WIN
#define CHECK_ERR(expression)\ #define CHECK_ERR(expression)\
STMT(\ STMT(\
i64 err__ = (i64)(expression);\ i64 err64 = (i64)(expression);\
if(err__ < 0)\ if(err64 < 0)\
{\ {\
DEBUG_WARN_ERR(err__);\ LibError err = (LibError)(err64 & UINT_MAX);\
return (LibError)(err__ & UINT_MAX);\ DEBUG_WARN_ERR(err);\
return err;\
}\ }\
) )
#else #else
#define CHECK_ERR(expression)\ #define CHECK_ERR(expression)\
STMT(\ STMT(\
i64 err__ = (i64)(expression);\ i64 err64 = (i64)(expression);\
if(err__ < 0)\ if(err64 < 0)\
{\ {\
DEBUG_WARN_ERR(err__);\ LibError err = (LibError)(err64 & UINT_MAX);\
return (LibError)(err__ & UINT_MAX);\ DEBUG_WARN_ERR(err);\
return (LibError)(err & UINT_MAX);\
}\ }\
) )
#endif #endif
@ -80,9 +87,12 @@ STMT(\
// (useful for functions that can legitimately fail, e.g. vfs_exists). // (useful for functions that can legitimately fail, e.g. vfs_exists).
#define RETURN_ERR(expression)\ #define RETURN_ERR(expression)\
STMT(\ STMT(\
i64 err__ = (i64)(expression);\ i64 err64 = (i64)(expression);\
if(err__ < 0)\ if(err64 < 0)\
return (LibError)(err__ & UINT_MAX);\ {\
LibError err = (LibError)(err64 & UINT_MAX);\
return err;\
}\
) )
// return an error and warn about it (replaces debug_warn+return) // return an error and warn about it (replaces debug_warn+return)
@ -95,11 +105,12 @@ STMT(\
// if expression evaluates to a negative i64, warn user and throw the number. // if expression evaluates to a negative i64, warn user and throw the number.
#define THROW_ERR(expression)\ #define THROW_ERR(expression)\
STMT(\ STMT(\
i64 err__ = (i64)(expression);\ i64 err64 = (i64)(expression);\
if(err__ < 0)\ if(err64 < 0)\
{\ {\
DEBUG_WARN_ERR(err__);\ LibError err = (LibError)(err64 & UINT_MAX);\
throw (LibError)(err__ & UINT_MAX);\ DEBUG_WARN_ERR(err);\
throw err;\
}\ }\
) )
@ -107,10 +118,11 @@ STMT(\
// (useful for void functions that must bail and complain) // (useful for void functions that must bail and complain)
#define WARN_ERR_RETURN(expression)\ #define WARN_ERR_RETURN(expression)\
STMT(\ STMT(\
i64 err__ = (i64)(expression);\ i64 err64 = (i64)(expression);\
if(err__ < 0)\ if(err64 < 0)\
{\ {\
DEBUG_WARN_ERR(err__);\ LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return;\ return;\
}\ }\
) )
@ -119,9 +131,12 @@ STMT(\
// (this is similar to debug_assert but also works in release mode) // (this is similar to debug_assert but also works in release mode)
#define WARN_ERR(expression)\ #define WARN_ERR(expression)\
STMT(\ STMT(\
i64 err__ = (i64)(expression);\ i64 err64 = (i64)(expression);\
if(err__ < 0)\ if(err64 < 0)\
DEBUG_WARN_ERR(err__);\ {\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
}\
) )
@ -133,7 +148,7 @@ STMT(\
{\ {\
debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\ debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\
"feel free to ignore or suppress this warning.");\ "feel free to ignore or suppress this warning.");\
return -1;\ return ERR_FAIL;\
}\ }\
) )
@ -141,7 +156,7 @@ STMT(\
#define RETURN_IF_FALSE(ok)\ #define RETURN_IF_FALSE(ok)\
STMT(\ STMT(\
if(!(ok))\ if(!(ok))\
return -1;\ return ERR_FAIL;\
) )
// if ok evaluates to false or FALSE, warn user. // if ok evaluates to false or FALSE, warn user.
@ -174,6 +189,8 @@ ERR(1, INFO_CB_CONTINUE , "1 (not an error)")
ERR(2, INFO_CANNOT_HANDLE, "2 (not an error)") ERR(2, INFO_CANNOT_HANDLE, "2 (not an error)")
ERR(3, INFO_NO_REPLACE , "3 (not an error)") ERR(3, INFO_NO_REPLACE , "3 (not an error)")
ERR(4, INFO_SKIPPED , "4 (not an error)") ERR(4, INFO_SKIPPED , "4 (not an error)")
//
ERR(5, INFO_ALL_COMPLETE, "5 (not an error)")
ERR(-100000, ERR_LOGIC, "Logic error in code") ERR(-100000, ERR_LOGIC, "Logic error in code")
ERR(-100060, ERR_TIMED_OUT, "Timed out") ERR(-100060, ERR_TIMED_OUT, "Timed out")

View File

@ -27,7 +27,7 @@ typedef std::map<wchar_t, unsigned short> glyphmap_id;
// Store the size separately, because it's used separately // Store the size separately, because it's used separately
typedef std::map<wchar_t, int> glyphmap_size; typedef std::map<wchar_t, int> glyphmap_size;
glyphmap_id* BoundGlyphs = NULL; static glyphmap_id* BoundGlyphs = NULL;
struct UniFont struct UniFont
{ {

View File

@ -17,6 +17,7 @@
#include "ia32.h" #include "ia32.h"
#endif #endif
// pass "omit frame pointer" setting on to the compiler // pass "omit frame pointer" setting on to the compiler
#if MSC_VERSION #if MSC_VERSION
# if CONFIG_OMIT_FP # if CONFIG_OMIT_FP
@ -129,40 +130,13 @@ extern void* alloca(size_t size);
// raise a message box with the given text or (depending on platform) // raise a message box with the given text or (depending on platform)
// otherwise inform the user. // otherwise inform the user.
// called from debug_display_msgw.
extern void sys_display_msg(const char* caption, const char* msg); extern void sys_display_msg(const char* caption, const char* msg);
extern void sys_display_msgw(const wchar_t* caption, const wchar_t* msg); extern void sys_display_msgw(const wchar_t* caption, const wchar_t* msg);
// choices offered by the shared error dialog // show the error dialog. flags: see DisplayErrorFlags.
enum ErrorReaction // called from debug_display_error.
{ enum ErrorReaction;
// ignore, continue as if nothing happened.
ER_CONTINUE = 1,
// note: don't start at 0 because that is interpreted as a
// DialogBoxParam failure.
// ignore and do not report again.
// only returned if DE_ALLOW_SUPPRESS was passed.
ER_SUPPRESS,
// note: non-persistent; only applicable during this program run.
// trigger breakpoint, i.e. enter debugger.
// only returned if DE_MANUAL_BREAK was passed; otherwise,
// display_error will trigger a breakpoint itself.
ER_BREAK,
// exit the program immediately.
// never returned; display_error exits immediately.
ER_EXIT
};
enum SysDisplayErrorFlags
{
DE_ALLOW_SUPPRESS = 1,
DE_NO_CONTINUE = 2,
DE_MANUAL_BREAK = 4
};
// internal use only (used by display_error)
extern ErrorReaction sys_display_error(const wchar_t* text, int flags); extern ErrorReaction sys_display_error(const wchar_t* text, int flags);

View File

@ -102,7 +102,7 @@ void wdbg_set_thread_name(const char* name)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// check heap integrity (independently of mmgr). // check heap integrity (independently of mmgr).
// errors are reported by the CRT or via display_error. // errors are reported by the CRT or via debug_display_error.
void debug_heap_check() void debug_heap_check()
{ {
int ret; int ret;
@ -616,7 +616,7 @@ static const wchar_t* get_exception_locus(const EXCEPTION_POINTERS* ep)
// no problems with wdbg_exception_filter's "%[^:]" format string. // no problems with wdbg_exception_filter's "%[^:]" format string.
// note: keep formatting in sync with wdbg_exception_filter, which // note: keep formatting in sync with wdbg_exception_filter, which
// extracts file/line for use with display_error. // extracts file/line for use with debug_display_error.
static wchar_t locus[256]; static wchar_t locus[256];
swprintf(locus, ARRAY_SIZE(locus), L"%hs (%hs:%d)", func_name, file, line); swprintf(locus, ARRAY_SIZE(locus), L"%hs (%hs:%d)", func_name, file, line);
return locus; return locus;
@ -709,7 +709,7 @@ LONG WINAPI wdbg_exception_filter(EXCEPTION_POINTERS* ep)
int flags = 0; int flags = 0;
if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
flags = DE_NO_CONTINUE; flags = DE_NO_CONTINUE;
ErrorReaction er = display_error(buf, flags, 1, ep->ContextRecord, file, line); ErrorReaction er = debug_display_error(buf, flags, 1,ep->ContextRecord, file,line);
debug_assert(er > 0); debug_assert(er > 0);
wdbg_write_minidump(ep); wdbg_write_minidump(ep);

View File

@ -579,8 +579,6 @@ int poll(struct pollfd /* fds */[], int /* nfds */, int /* timeout */)
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// convert POSIX PROT_* flags to their Win32 PAGE_* enumeration equivalents. // convert POSIX PROT_* flags to their Win32 PAGE_* enumeration equivalents.
// used by mprotect. // used by mprotect.
static DWORD win32_prot(int prot) static DWORD win32_prot(int prot)
@ -637,25 +635,22 @@ static LibError mmap_mem(void* start, size_t len, int prot, int flags, int fd, v
// see explanation at MAP_NORESERVE definition. // see explanation at MAP_NORESERVE definition.
bool want_commit = (prot != PROT_NONE && !(flags & MAP_NORESERVE)); bool want_commit = (prot != PROT_NONE && !(flags & MAP_NORESERVE));
// decommit a given area (leaves its address space reserved)
if(!want_commit && start != 0 && flags & MAP_FIXED) if(!want_commit && start != 0 && flags & MAP_FIXED)
{ {
MEMORY_BASIC_INFORMATION mbi; MEMORY_BASIC_INFORMATION mbi;
BOOL ok = VirtualQuery(start, &mbi, len); WARN_RETURN_IF_FALSE(VirtualQuery(start, &mbi, len));
debug_assert(ok); // todo4 if(mbi.State == MEM_COMMIT)
DWORD state = mbi.State;
if(state == MEM_COMMIT)
{ {
ok = VirtualFree(start, len, MEM_DECOMMIT); WARN_IF_FALSE(VirtualFree(start, len, MEM_DECOMMIT));
debug_assert(ok);
*pp = 0; *pp = 0;
return ERR_OK; return ERR_OK;
} }
} }
DWORD op = want_commit? MEM_COMMIT : MEM_RESERVE; DWORD flAllocationType = want_commit? MEM_COMMIT : MEM_RESERVE;
DWORD flProtect = win32_prot(prot); DWORD flProtect = win32_prot(prot);
void* p = VirtualAlloc(start, len, op, flProtect); void* p = VirtualAlloc(start, len, flAllocationType, flProtect);
if(!p) if(!p)
return ERR_NO_MEM; return ERR_NO_MEM;
*pp = p; *pp = p;
@ -759,6 +754,7 @@ void* mmap(void* start, size_t len, int prot, int flags, int fd, off_t ofs)
if(err < 0) if(err < 0)
{ {
WARN_ERR(err); WARN_ERR(err);
LibError_set_errno(err);
return MAP_FAILED; return MAP_FAILED;
} }

View File

@ -333,7 +333,7 @@ ErrorReaction sys_display_error(const wchar_t* text, int flags)
// failed; warn user and make sure we return an ErrorReaction. // failed; warn user and make sure we return an ErrorReaction.
if(ret == 0 || ret == -1) if(ret == 0 || ret == -1)
{ {
display_msgw(L"Error", L"Unable to display detailed error dialog."); debug_display_msgw(L"Error", L"Unable to display detailed error dialog.");
return ER_CONTINUE; return ER_CONTINUE;
} }
return (ErrorReaction)ret; return (ErrorReaction)ret;

View File

@ -95,18 +95,18 @@ static int ProgressiveLoad()
{ {
wchar_t description[100]; wchar_t description[100];
int progress_percent; int progress_percent;
int ret = LDR_ProgressiveLoad(10e-3, description, ARRAY_SIZE(description), &progress_percent); LibError ret = LDR_ProgressiveLoad(10e-3, description, ARRAY_SIZE(description), &progress_percent);
switch(ret) switch(ret)
{ {
// no load active => no-op (skip code below) // no load active => no-op (skip code below)
case 0: case ERR_OK:
return 0; return 0;
// current task didn't complete. we only care about this insofar as the // current task didn't complete. we only care about this insofar as the
// load process is therefore not yet finished. // load process is therefore not yet finished.
case ERR_TIMED_OUT: case ERR_TIMED_OUT:
break; break;
// just finished loading // just finished loading
case LDR_ALL_FINISHED: case INFO_ALL_COMPLETE:
g_Game->ReallyStartGame(); g_Game->ReallyStartGame();
wcscpy_s(description, ARRAY_SIZE(description), L"Game is starting.."); wcscpy_s(description, ARRAY_SIZE(description), L"Game is starting..");
// LDR_ProgressiveLoad returns L""; set to valid text to // LDR_ProgressiveLoad returns L""; set to valid text to

View File

@ -64,7 +64,7 @@ int CFont::GetHeight()
return unifont_height(h); return unifont_height(h);
} }
int CFont::GetCharacterWidth(const wchar_t& c) int CFont::GetCharacterWidth(wchar_t c)
{ {
return unifont_character_width(h, c); return unifont_character_width(h, c);
} }

View File

@ -31,7 +31,7 @@ public:
void Bind(); void Bind();
int GetLineSpacing(); int GetLineSpacing();
int GetHeight(); int GetHeight();
int GetCharacterWidth(const wchar_t& c); int GetCharacterWidth(wchar_t c);
void CalculateStringSize(const CStrW& string, int& w, int& h); void CalculateStringSize(const CStrW& string, int& w, int& h);
private: private:

View File

@ -522,8 +522,7 @@ static void InitVfs(const char* argv0)
// rationale for data/ being root: untrusted scripts must not be // rationale for data/ being root: untrusted scripts must not be
// allowed to overwrite critical game (or worse, OS) files. // allowed to overwrite critical game (or worse, OS) files.
// the VFS prevents any accesses to files above this directory. // the VFS prevents any accesses to files above this directory.
int err = file_set_root_dir(argv0, "../data"); WARN_ERR(file_set_root_dir(argv0, "../data"));
WARN_ERR(err);
vfs_init(); vfs_init();
vfs_mount("", "mods/official", VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_WATCH); vfs_mount("", "mods/official", VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_WATCH);

View File

@ -84,14 +84,14 @@ struct DurationAdder: public std::binary_function<double, const LoadRequest&, do
// this routine is provided so we can prevent 2 simultaneous load operations, // this routine is provided so we can prevent 2 simultaneous load operations,
// which is bogus. that can happen by clicking the load button quickly, // which is bogus. that can happen by clicking the load button quickly,
// or issuing via console while already loading. // or issuing via console while already loading.
int LDR_BeginRegistering() LibError LDR_BeginRegistering()
{ {
if(state != IDLE) if(state != IDLE)
return -1; return ERR_LOGIC;
state = REGISTERING; state = REGISTERING;
load_requests.clear(); load_requests.clear();
return 0; return ERR_OK;
} }
@ -103,7 +103,7 @@ int LDR_BeginRegistering()
// <estimated_duration_ms>: used to calculate progress, and when checking // <estimated_duration_ms>: used to calculate progress, and when checking
// whether there is enough of the time budget left to process this task // whether there is enough of the time budget left to process this task
// (reduces timeslice overruns, making the main loop more responsive). // (reduces timeslice overruns, making the main loop more responsive).
int LDR_Register(LoadFunc func, void* param, const wchar_t* description, LibError LDR_Register(LoadFunc func, void* param, const wchar_t* description,
int estimated_duration_ms) int estimated_duration_ms)
{ {
if(state != REGISTERING) if(state != REGISTERING)
@ -111,21 +111,21 @@ int LDR_Register(LoadFunc func, void* param, const wchar_t* description,
debug_warn("not called between LDR_(Begin|End)Register - why?!"); debug_warn("not called between LDR_(Begin|End)Register - why?!");
// warn here instead of relying on the caller to CHECK_ERR because // warn here instead of relying on the caller to CHECK_ERR because
// there will be lots of call sites spread around. // there will be lots of call sites spread around.
return -1; return ERR_LOGIC;
} }
const LoadRequest lr(func, param, description, estimated_duration_ms); const LoadRequest lr(func, param, description, estimated_duration_ms);
load_requests.push_back(lr); load_requests.push_back(lr);
return 0; return ERR_OK;
} }
// call when finished registering tasks; subsequent calls to // call when finished registering tasks; subsequent calls to
// LDR_ProgressiveLoad will then work off the queued entries. // LDR_ProgressiveLoad will then work off the queued entries.
int LDR_EndRegistering() LibError LDR_EndRegistering()
{ {
if(state != REGISTERING) if(state != REGISTERING)
return -1; return ERR_LOGIC;
if(load_requests.empty()) if(load_requests.empty())
debug_warn("no LoadRequests queued"); debug_warn("no LoadRequests queued");
@ -134,25 +134,25 @@ int LDR_EndRegistering()
estimated_duration_tally = 0.0; estimated_duration_tally = 0.0;
task_elapsed_time = 0.0; task_elapsed_time = 0.0;
total_estimated_duration = std::accumulate(load_requests.begin(), load_requests.end(), 0.0, DurationAdder()); total_estimated_duration = std::accumulate(load_requests.begin(), load_requests.end(), 0.0, DurationAdder());
return 0; return ERR_OK;
} }
// immediately cancel this load; no further tasks will be processed. // immediately cancel this load; no further tasks will be processed.
// used to abort loading upon user request or failure. // used to abort loading upon user request or failure.
// note: no special notification will be returned by LDR_ProgressiveLoad. // note: no special notification will be returned by LDR_ProgressiveLoad.
int LDR_Cancel() LibError LDR_Cancel()
{ {
// note: calling during registering doesn't make sense - that // note: calling during registering doesn't make sense - that
// should be an atomic sequence of begin, register [..], end. // should be an atomic sequence of begin, register [..], end.
if(state != LOADING) if(state != LOADING)
return -1; return ERR_LOGIC;
state = IDLE; state = IDLE;
// the queue doesn't need to be emptied now; that'll happen during the // the queue doesn't need to be emptied now; that'll happen during the
// next LDR_StartRegistering. for now, it is sufficient to set the // next LDR_StartRegistering. for now, it is sufficient to set the
// state, so that LDR_ProgressiveLoad is a no-op. // state, so that LDR_ProgressiveLoad is a no-op.
return 0; return ERR_OK;
} }
@ -186,7 +186,7 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
// ("" if finished) and the current progress value. // ("" if finished) and the current progress value.
// //
// return semantics: // return semantics:
// - if the final load task just completed, return LDR_ALL_FINISHED. // - if the final load task just completed, return INFO_ALL_COMPLETE.
// - if loading is in progress but didn't finish, return ERR_TIMED_OUT. // - if loading is in progress but didn't finish, return ERR_TIMED_OUT.
// - if not currently loading (no-op), return 0. // - if not currently loading (no-op), return 0.
// - any other value indicates a failure; the request has been de-queued. // - any other value indicates a failure; the request has been de-queued.
@ -196,10 +196,10 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
// persistent, we can't just store a pointer. returning a pointer to // persistent, we can't just store a pointer. returning a pointer to
// our copy of the description doesn't work either, since it's freed when // our copy of the description doesn't work either, since it's freed when
// the request is de-queued. that leaves writing into caller's buffer. // the request is de-queued. that leaves writing into caller's buffer.
int LDR_ProgressiveLoad(double time_budget, wchar_t* description, LibError LDR_ProgressiveLoad(double time_budget, wchar_t* description,
size_t max_chars, int* progress_percent) size_t max_chars, int* progress_percent)
{ {
int ret; // single exit; this is returned LibError ret; // single exit; this is returned
double progress = 0.0; // used to set progress_percent double progress = 0.0; // used to set progress_percent
double time_left = time_budget; double time_left = time_budget;
@ -217,7 +217,7 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
// we're called unconditionally from the main loop, so this isn't // we're called unconditionally from the main loop, so this isn't
// an error; there is just nothing to do. // an error; there is just nothing to do.
if(state != LOADING) if(state != LOADING)
return 0; return ERR_OK;
while(!load_requests.empty()) while(!load_requests.empty())
{ {
@ -232,13 +232,13 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
// call this task's function and bill elapsed time. // call this task's function and bill elapsed time.
const double t0 = get_time(); const double t0 = get_time();
ret = lr.func(lr.param, time_left); int status = lr.func(lr.param, time_left);
const double elapsed_time = get_time() - t0; const double elapsed_time = get_time() - t0;
time_left -= elapsed_time; time_left -= elapsed_time;
task_elapsed_time += elapsed_time; task_elapsed_time += elapsed_time;
// either finished entirely, or failed => remove from queue. // either finished entirely, or failed => remove from queue.
if(ret == 0 || ret < 0) if(status <= 0)
{ {
debug_printf("LOADER| completed %ls in %g ms; estimate was %g ms\n", lr.description.c_str(), task_elapsed_time*1e3, estimated_duration*1e3); debug_printf("LOADER| completed %ls in %g ms; estimate was %g ms\n", lr.description.c_str(), task_elapsed_time*1e3, estimated_duration*1e3);
task_elapsed_time = 0.0; task_elapsed_time = 0.0;
@ -254,32 +254,37 @@ int LDR_ProgressiveLoad(double time_budget, wchar_t* description,
// function interrupted itself; add its estimated progress. // function interrupted itself; add its estimated progress.
// note: monotonicity is guaranteed since we never add more than // note: monotonicity is guaranteed since we never add more than
// its estimated_duration_ms. // its estimated_duration_ms.
if(ret > 0) if(status > 0)
{ {
ret = MIN(ret, 100); // clamp in case estimate is too high status = MIN(status, 100); // clamp in case estimate is too high
current_estimate += estimated_duration * ret/100.0; current_estimate += estimated_duration * status/100.0;
} }
progress = current_estimate / total_estimated_duration; progress = current_estimate / total_estimated_duration;
} }
// translate return value // do we need to continue?
// (function interrupted itself; need to return ERR_TIMED_OUT) // .. function interrupted itself, i.e. timed out; abort.
if(ret > 0) if(status > 0)
{
ret = ERR_TIMED_OUT; ret = ERR_TIMED_OUT;
// failed or timed out => abort immediately; loading will
// continue when we're called in the next iteration of the main loop.
// rationale: bail immediately instead of remembering the first error
// that came up, so that we report can all errors that happen.
if(ret != 0)
goto done; goto done;
// else: continue and process next queued task. }
// .. failed; abort. loading will continue when we're called in
// the next iteration of the main loop.
// rationale: bail immediately instead of remembering the first
// error that came up so we report can all errors that happen.
else if(status < 0)
{
ret = (LibError)status;
goto done;
}
// .. succeeded; continue and process next queued task.
} }
// queue is empty, we just finished. // queue is empty, we just finished.
state = IDLE; state = IDLE;
ret = LDR_ALL_FINISHED; ret = INFO_ALL_COMPLETE;
// set output params (there are several return points above) // set output params (there are several return points above)
@ -302,7 +307,7 @@ done:
// immediately process all queued load requests. // immediately process all queued load requests.
// returns 0 on success or a negative error code. // returns 0 on success or a negative error code.
int LDR_NonprogressiveLoad() LibError LDR_NonprogressiveLoad()
{ {
const double time_budget = 100.0; const double time_budget = 100.0;
// large enough so that individual functions won't time out // large enough so that individual functions won't time out
@ -312,15 +317,14 @@ int LDR_NonprogressiveLoad()
for(;;) for(;;)
{ {
int ret = LDR_ProgressiveLoad(time_budget, description, ARRAY_SIZE(description), &progress_percent); LibError ret = LDR_ProgressiveLoad(time_budget, description, ARRAY_SIZE(description), &progress_percent);
switch(ret) switch(ret)
{ {
case 0: case ERR_OK:
debug_warn("No load in progress"); debug_warn("No load in progress");
return 0; // success return ERR_OK;
case LDR_ALL_FINISHED: case INFO_ALL_COMPLETE:
return 0; // success return ERR_OK;
case ERR_TIMED_OUT: case ERR_TIMED_OUT:
break; // continue loading break; // continue loading
default: default:

View File

@ -87,7 +87,7 @@ registering member functions, which would otherwise be messy.
// this routine is provided so we can prevent 2 simultaneous load operations, // this routine is provided so we can prevent 2 simultaneous load operations,
// which is bogus. that can happen by clicking the load button quickly, // which is bogus. that can happen by clicking the load button quickly,
// or issuing via console while already loading. // or issuing via console while already loading.
extern int LDR_BeginRegistering(); extern LibError LDR_BeginRegistering();
// callback function of a task; performs the actual work. // callback function of a task; performs the actual work.
@ -111,23 +111,21 @@ typedef int (*LoadFunc)(void* param, double time_left);
// <estimated_duration_ms>: used to calculate progress, and when checking // <estimated_duration_ms>: used to calculate progress, and when checking
// whether there is enough of the time budget left to process this task // whether there is enough of the time budget left to process this task
// (reduces timeslice overruns, making the main loop more responsive). // (reduces timeslice overruns, making the main loop more responsive).
extern int LDR_Register(LoadFunc func, void* param, const wchar_t* description, extern LibError LDR_Register(LoadFunc func, void* param, const wchar_t* description,
int estimated_duration_ms); int estimated_duration_ms);
// call when finished registering tasks; subsequent calls to // call when finished registering tasks; subsequent calls to
// LDR_ProgressiveLoad will then work off the queued entries. // LDR_ProgressiveLoad will then work off the queued entries.
extern int LDR_EndRegistering(); extern LibError LDR_EndRegistering();
// immediately cancel this load; no further tasks will be processed. // immediately cancel this load; no further tasks will be processed.
// used to abort loading upon user request or failure. // used to abort loading upon user request or failure.
// note: no special notification will be returned by LDR_ProgressiveLoad. // note: no special notification will be returned by LDR_ProgressiveLoad.
extern int LDR_Cancel(); extern LibError LDR_Cancel();
const int LDR_ALL_FINISHED = 1;
// process as many of the queued tasks as possible within <time_budget> [s]. // process as many of the queued tasks as possible within <time_budget> [s].
// if a task is lengthy, the budget may be exceeded. call from the main loop. // if a task is lengthy, the budget may be exceeded. call from the main loop.
// //
@ -135,7 +133,7 @@ const int LDR_ALL_FINISHED = 1;
// ("" if finished) and the current progress value. // ("" if finished) and the current progress value.
// //
// return semantics: // return semantics:
// - if the final load task just completed, return LDR_ALL_FINISHED. // - if the final load task just completed, return INFO_ALL_COMPLETE.
// - if loading is in progress but didn't finish, return ERR_TIMED_OUT. // - if loading is in progress but didn't finish, return ERR_TIMED_OUT.
// - if not currently loading (no-op), return 0. // - if not currently loading (no-op), return 0.
// - any other value indicates a failure; the request has been de-queued. // - any other value indicates a failure; the request has been de-queued.
@ -145,12 +143,12 @@ const int LDR_ALL_FINISHED = 1;
// persistent, we can't just store a pointer. returning a pointer to // persistent, we can't just store a pointer. returning a pointer to
// our copy of the description doesn't work either, since it's freed when // our copy of the description doesn't work either, since it's freed when
// the request is de-queued. that leaves writing into caller's buffer. // the request is de-queued. that leaves writing into caller's buffer.
extern int LDR_ProgressiveLoad(double time_budget, wchar_t* next_description, extern LibError LDR_ProgressiveLoad(double time_budget, wchar_t* next_description,
size_t max_chars, int* progress_percent); size_t max_chars, int* progress_percent);
// immediately process all queued load requests. // immediately process all queued load requests.
// returns 0 on success or a negative error code. // returns 0 on success or a negative error code.
extern int LDR_NonprogressiveLoad(); extern LibError LDR_NonprogressiveLoad();
// boilerplate check-if-timed-out and return-progress-percent code. // boilerplate check-if-timed-out and return-progress-percent code.

View File

@ -33,12 +33,12 @@ public:
// Implementation of AbstractProfileTable interface // Implementation of AbstractProfileTable interface
virtual CStr GetName(); virtual CStr GetName();
virtual CStr GetTitle(); virtual CStr GetTitle();
virtual uint GetNumberRows(); virtual size_t GetNumberRows();
virtual const std::vector<ProfileColumn>& GetColumns(); virtual const std::vector<ProfileColumn>& GetColumns();
virtual CStr GetCellText(uint row, uint col); virtual CStr GetCellText(size_t row, size_t col);
virtual AbstractProfileTable* GetChild(uint row); virtual AbstractProfileTable* GetChild(size_t row);
virtual bool IsHighlightRow(uint row); virtual bool IsHighlightRow(size_t row);
private: private:
/** /**
@ -97,7 +97,7 @@ CStr CProfileNodeTable::GetTitle()
} }
// Total number of children // Total number of children
uint CProfileNodeTable::GetNumberRows() size_t CProfileNodeTable::GetNumberRows()
{ {
return node->GetChildren()->size() + node->GetScriptChildren()->size() + 1; return node->GetChildren()->size() + node->GetScriptChildren()->size() + 1;
} }
@ -109,11 +109,11 @@ const std::vector<ProfileColumn>& CProfileNodeTable::GetColumns()
} }
// Retrieve cell text // Retrieve cell text
CStr CProfileNodeTable::GetCellText(uint row, uint col) CStr CProfileNodeTable::GetCellText(size_t row, size_t col)
{ {
CProfileNode* child; CProfileNode* child;
uint nrchildren = node->GetChildren()->size(); size_t nrchildren = node->GetChildren()->size();
uint nrscriptchildren = node->GetScriptChildren()->size(); size_t nrscriptchildren = node->GetScriptChildren()->size();
char buf[256]; char buf[256];
if (row < nrchildren) if (row < nrchildren)
@ -177,11 +177,11 @@ CStr CProfileNodeTable::GetCellText(uint row, uint col)
} }
// Return a pointer to the child table if the child node is expandable // Return a pointer to the child table if the child node is expandable
AbstractProfileTable* CProfileNodeTable::GetChild(uint row) AbstractProfileTable* CProfileNodeTable::GetChild(size_t row)
{ {
CProfileNode* child; CProfileNode* child;
uint nrchildren = node->GetChildren()->size(); size_t nrchildren = node->GetChildren()->size();
uint nrscriptchildren = node->GetScriptChildren()->size(); size_t nrscriptchildren = node->GetScriptChildren()->size();
if (row < nrchildren) if (row < nrchildren)
child = (*node->GetChildren())[row]; child = (*node->GetChildren())[row];
@ -197,10 +197,10 @@ AbstractProfileTable* CProfileNodeTable::GetChild(uint row)
} }
// Highlight all script nodes // Highlight all script nodes
bool CProfileNodeTable::IsHighlightRow(uint row) bool CProfileNodeTable::IsHighlightRow(size_t row)
{ {
uint nrchildren = node->GetChildren()->size(); size_t nrchildren = node->GetChildren()->size();
uint nrscriptchildren = node->GetScriptChildren()->size(); size_t nrscriptchildren = node->GetScriptChildren()->size();
return (row >= nrchildren && row < (nrchildren + nrscriptchildren)); return (row >= nrchildren && row < (nrchildren + nrscriptchildren));
} }

View File

@ -85,9 +85,9 @@ void CProfileViewerInternals::NavigateTree(int id)
else else
{ {
AbstractProfileTable* table = path[path.size() - 1]; AbstractProfileTable* table = path[path.size() - 1];
int numrows = table->GetNumberRows(); size_t numrows = table->GetNumberRows();
for(int row = 0; row < numrows; ++row) for(size_t row = 0; row < numrows; ++row)
{ {
AbstractProfileTable* child = table->GetChild(row); AbstractProfileTable* child = table->GetChild(row);
@ -132,17 +132,17 @@ void CProfileViewer::RenderProfile()
AbstractProfileTable* table = m->path[m->path.size() - 1]; AbstractProfileTable* table = m->path[m->path.size() - 1];
const std::vector<ProfileColumn>& columns = table->GetColumns(); const std::vector<ProfileColumn>& columns = table->GetColumns();
uint numrows = table->GetNumberRows(); size_t numrows = table->GetNumberRows();
// Render background // Render background
int estimate_height; uint estimate_height;
int estimate_width; uint estimate_width;
estimate_width = 50; estimate_width = 50;
for(uint i = 0; i < columns.size(); ++i) for(uint i = 0; i < columns.size(); ++i)
estimate_width += columns[i].width; estimate_width += columns[i].width;
estimate_height = 3 + numrows; estimate_height = 3 + (uint)numrows;
if (m->path.size() > 1) if (m->path.size() > 1)
estimate_height += 2; estimate_height += 2;
estimate_height = 20*estimate_height; estimate_height = 20*estimate_height;

View File

@ -70,7 +70,7 @@ public:
* *
* @return Number of rows in this table. * @return Number of rows in this table.
*/ */
virtual uint GetNumberRows() = 0; virtual size_t GetNumberRows() = 0;
/** /**
* GetColumnDescriptions * GetColumnDescriptions
@ -87,7 +87,7 @@ public:
* *
* @return Text to be displayed in the given cell. * @return Text to be displayed in the given cell.
*/ */
virtual CStr GetCellText(uint row, uint col) = 0; virtual CStr GetCellText(size_t row, size_t col) = 0;
/** /**
* GetChild: Return a row's child table if the child is expandable. * GetChild: Return a row's child table if the child is expandable.
@ -97,7 +97,7 @@ public:
* @return Pointer to the child table if the given row has one. * @return Pointer to the child table if the given row has one.
* Otherwise, return 0. * Otherwise, return 0.
*/ */
virtual AbstractProfileTable* GetChild(uint row) = 0; virtual AbstractProfileTable* GetChild(size_t row) = 0;
/** /**
* IsHighlightRow * IsHighlightRow
@ -106,7 +106,7 @@ public:
* *
* @return true if the row should be highlighted in a special color. * @return true if the row should be highlighted in a special color.
*/ */
virtual bool IsHighlightRow(uint row) { UNUSED2(row); return false; } virtual bool IsHighlightRow(size_t row) { UNUSED2(row); return false; }
}; };

View File

@ -47,7 +47,7 @@ bool VFSUtil::FindFiles (const CStr& dirname, const char* filter, FileList& file
// also returned. // also returned.
// //
// note: EnumDirEntsCB path and ent are only valid during the callback. // note: EnumDirEntsCB path and ent are only valid during the callback.
int VFSUtil::EnumDirEnts(const CStr start_path, int flags, const char* user_filter, LibError VFSUtil::EnumDirEnts(const CStr start_path, int flags, const char* user_filter,
EnumDirEntsCB cb, void* context) EnumDirEntsCB cb, void* context)
{ {
debug_assert((flags & ~(RECURSIVE)) == 0); debug_assert((flags & ~(RECURSIVE)) == 0);
@ -119,5 +119,5 @@ int VFSUtil::EnumDirEnts(const CStr start_path, int flags, const char* user_filt
} }
while(!dir_queue.empty()); while(!dir_queue.empty());
return 0; return ERR_OK;
} }

View File

@ -29,7 +29,7 @@ enum EnumDirEntsFlags
// call <cb> for each entry matching <user_filter> (see vfs_next_dirent) in // call <cb> for each entry matching <user_filter> (see vfs_next_dirent) in
// directory <path>; if flags & RECURSIVE, entries in subdirectories are // directory <path>; if flags & RECURSIVE, entries in subdirectories are
// also returned. // also returned.
extern int EnumDirEnts(const CStr path, int flags, const char* filter, extern LibError EnumDirEnts(const CStr path, int flags, const char* filter,
EnumDirEntsCB cb, void* context); EnumDirEntsCB cb, void* context);
}; // namespace VFSUtil }; // namespace VFSUtil

View File

@ -97,6 +97,9 @@ private:
// Must be last to count number of rows // Must be last to count number of rows
NumberRows NumberRows
}; };
// no copy ctor because some members are const
CRendererStatsTable& operator=(const CRendererStatsTable&);
}; };
// Construction // Construction