1
0
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 "app_hooks.h"
// needed when writing crashlog
static const size_t LOG_CHARS = 16384;
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,
uint skip, void* context, const char* file, int line)
// translates and displays the given strings in a dialog.
// 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')
file = "unknown";
@ -495,7 +508,7 @@ ErrorReaction display_error(const wchar_t* description, int flags,
ErrorReaction er = sys_display_error(text, flags);
// 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.
// 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
// local variables.
ErrorReaction debug_assert_failed(const char* file, int line,
const char* func, const char* expr)
ErrorReaction debug_assert_failed(const char* expr,
const char* file, int line, const char* func)
{
// for edge cases in some functions, warnings (=asserts) are raised in
// 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;
wchar_t buf[400];
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,
const char* func)
ErrorReaction debug_warn_err(LibError err,
const char* file, int line, const char* func)
{
// for edge cases in some functions, warnings (=asserts) are raised in
// 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];
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);
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
#include "lib.h" // STMT
#include "sysdep/sysdep.h" // ErrorReaction
#if OS_WIN
# include "sysdep/win/wdbg.h"
#else
@ -73,7 +72,7 @@ even if debug information is present and assert dialogs are useless.
//-----------------------------------------------------------------------------
// 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);
enum DebugHeapChecks
@ -122,7 +121,7 @@ STMT(\
static unsigned char suppress__ = 0x55;\
if(suppress__ == 0x55 && !(expr))\
{\
switch(debug_assert_failed(__FILE__, __LINE__, __func__, #expr))\
switch(debug_assert_failed(#expr, __FILE__, __LINE__, __func__))\
{\
case ER_SUPPRESS:\
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.
// this is less error-prone than "debug_assert(0 && "text");" and avoids
@ -150,7 +146,10 @@ extern enum ErrorReaction debug_assert_failed(const char* file, int line,
#define debug_warn(str) debug_assert((str) && 0)
#define DEBUG_WARN_ERR(err) \
// 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)\
STMT(\
static unsigned char suppress__ = 0x55;\
if(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 ErrorReaction display_error(const wchar_t* description, int flags,
uint skip, void* context, const char* file, int line);
// translates and displays the given strings in a dialog.
// 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.
// done this way instead of with default values so that it also works in C.
#define DISPLAY_ERROR(text) display_error(text, 0, 0, 0, __FILE__, __LINE__)
// macro instead of providing overload/default values for C compatibility.
#define DISPLAY_ERROR(text) debug_display_error(text, 0, 0,0, __FILE__,__LINE__)
//

View File

@ -31,14 +31,6 @@
#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.
// if len = 0 (default), treat buf as a C-string;
// otherwise, hash <len> bytes of buf.

View File

@ -208,10 +208,6 @@ const size_t GiB = 1ul << 30;
#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))

View File

@ -11,17 +11,18 @@
#include <stdlib.h> // abs
static const char* lib_error_description(int err)
static const char* LibError_description(LibError err)
{
// 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;
switch(err)
{
#define ERR(err, id, str) case id: return str;
#include "lib_errors.h"
default: return "Unknown lib error";
default: return "Unknown error";
}
UNREACHABLE;
}
@ -29,13 +30,12 @@ static const char* lib_error_description(int err)
// generate textual description of an error code.
// stores up to <max_chars> in the given buffer.
// <err> can be one of the above error codes, POSIX ENOENT etc., or
// an OS-specific errors. if unknown, the string will be something like
// if error is unknown/invalid, the string will be something like
// "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
const char* str = lib_error_description(err);
const char* str = LibError_description(err);
if(str)
{
// <err> was one of our error codes (chosen so as not to conflict
@ -44,35 +44,8 @@ void error_description_r(int err, char* buf, size_t max_chars)
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
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)
{
case ENOMEM:
return ERR_NO_MEM;
case ENOMEM: return ERR_NO_MEM;
case EINVAL:
return ERR_INVALID_PARAM;
case ENOSYS:
return ERR_NOT_IMPLEMENTED;
case EINVAL: return ERR_INVALID_PARAM;
case ENOSYS: return ERR_NOT_IMPLEMENTED;
case ENOENT:
return ERR_PATH_NOT_FOUND;
case EACCES:
return ERR_FILE_ACCESS;
case EIO:
return ERR_IO;
case ENAMETOOLONG:
return ERR_PATH_LENGTH;
case ENOENT: return ERR_PATH_NOT_FOUND;
case EACCES: return ERR_FILE_ACCESS;
case EIO: return ERR_IO;
case ENAMETOOLONG: return ERR_PATH_LENGTH;
default:
return ERR_FAIL;
default: return ERR_FAIL;
}
UNREACHABLE;
}
// translate the return value of any POSIX function into LibError.
// ret is typically to -1 to indicate error and 0 on success.
// 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);
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.
// stores up to <max_chars> in the given buffer.
// <err> can be one of the above error codes, POSIX ENOENT etc., or
// an OS-specific errors. if unknown, the string will be something like
// if error is unknown/invalid, the string will be something like
// "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.
@ -43,35 +42,43 @@ extern LibError LibError_from_errno();
// make sure we do not return any stale errors.
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
// function return value) may be a Handle (=i64), so it needs to be
// stored and compared as such. (very large but legitimate Handle values
// casted to int can end up negative)
// all functions using this return int (instead of i64) for efficiency and
// simplicity. if the input was negative, it is an error code and is
// therefore known to fit; we still mask with UINT_MAX to avoid
// VC cast-to-smaller-type warnings.
// all functions using this return LibError (instead of i64) for
// efficiency and simplicity. if the input was negative, it is an
// error code and is therefore known to fit; we still mask with
// UINT_MAX to avoid VC cast-to-smaller-type warnings.
// if expression evaluates to a negative i64, warn user and return the number.
#if OS_WIN
#define CHECK_ERR(expression)\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
DEBUG_WARN_ERR(err__);\
return (LibError)(err__ & UINT_MAX);\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return err;\
}\
)
#else
#define CHECK_ERR(expression)\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
DEBUG_WARN_ERR(err__);\
return (LibError)(err__ & UINT_MAX);\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return (LibError)(err & UINT_MAX);\
}\
)
#endif
@ -80,9 +87,12 @@ STMT(\
// (useful for functions that can legitimately fail, e.g. vfs_exists).
#define RETURN_ERR(expression)\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
return (LibError)(err__ & UINT_MAX);\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
return err;\
}\
)
// 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.
#define THROW_ERR(expression)\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
DEBUG_WARN_ERR(err__);\
throw (LibError)(err__ & UINT_MAX);\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
throw err;\
}\
)
@ -107,10 +118,11 @@ STMT(\
// (useful for void functions that must bail and complain)
#define WARN_ERR_RETURN(expression)\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
DEBUG_WARN_ERR(err__);\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return;\
}\
)
@ -119,9 +131,12 @@ STMT(\
// (this is similar to debug_assert but also works in release mode)
#define WARN_ERR(expression)\
STMT(\
i64 err__ = (i64)(expression);\
if(err__ < 0)\
DEBUG_WARN_ERR(err__);\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
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."\
"feel free to ignore or suppress this warning.");\
return -1;\
return ERR_FAIL;\
}\
)
@ -141,7 +156,7 @@ STMT(\
#define RETURN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
return -1;\
return ERR_FAIL;\
)
// 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(3, INFO_NO_REPLACE , "3 (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(-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
typedef std::map<wchar_t, int> glyphmap_size;
glyphmap_id* BoundGlyphs = NULL;
static glyphmap_id* BoundGlyphs = NULL;
struct UniFont
{

View File

@ -17,6 +17,7 @@
#include "ia32.h"
#endif
// pass "omit frame pointer" setting on to the compiler
#if MSC_VERSION
# 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)
// otherwise inform the user.
// called from debug_display_msgw.
extern void sys_display_msg(const char* caption, const char* msg);
extern void sys_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.
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)
// show the error dialog. flags: see DisplayErrorFlags.
// called from debug_display_error.
enum ErrorReaction;
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).
// 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()
{
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.
// 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];
swprintf(locus, ARRAY_SIZE(locus), L"%hs (%hs:%d)", func_name, file, line);
return locus;
@ -709,7 +709,7 @@ LONG WINAPI wdbg_exception_filter(EXCEPTION_POINTERS* ep)
int flags = 0;
if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
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);
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.
// used by mprotect.
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.
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)
{
MEMORY_BASIC_INFORMATION mbi;
BOOL ok = VirtualQuery(start, &mbi, len);
debug_assert(ok); // todo4
DWORD state = mbi.State;
if(state == MEM_COMMIT)
WARN_RETURN_IF_FALSE(VirtualQuery(start, &mbi, len));
if(mbi.State == MEM_COMMIT)
{
ok = VirtualFree(start, len, MEM_DECOMMIT);
debug_assert(ok);
WARN_IF_FALSE(VirtualFree(start, len, MEM_DECOMMIT));
*pp = 0;
return ERR_OK;
}
}
DWORD op = want_commit? MEM_COMMIT : MEM_RESERVE;
DWORD flAllocationType = want_commit? MEM_COMMIT : MEM_RESERVE;
DWORD flProtect = win32_prot(prot);
void* p = VirtualAlloc(start, len, op, flProtect);
void* p = VirtualAlloc(start, len, flAllocationType, flProtect);
if(!p)
return ERR_NO_MEM;
*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)
{
WARN_ERR(err);
LibError_set_errno(err);
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.
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 (ErrorReaction)ret;

View File

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

View File

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

View File

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

View File

@ -522,8 +522,7 @@ static void InitVfs(const char* argv0)
// rationale for data/ being root: untrusted scripts must not be
// allowed to overwrite critical game (or worse, OS) files.
// the VFS prevents any accesses to files above this directory.
int err = file_set_root_dir(argv0, "../data");
WARN_ERR(err);
WARN_ERR(file_set_root_dir(argv0, "../data"));
vfs_init();
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,
// which is bogus. that can happen by clicking the load button quickly,
// or issuing via console while already loading.
int LDR_BeginRegistering()
LibError LDR_BeginRegistering()
{
if(state != IDLE)
return -1;
return ERR_LOGIC;
state = REGISTERING;
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
// whether there is enough of the time budget left to process this task
// (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)
{
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?!");
// warn here instead of relying on the caller to CHECK_ERR because
// there will be lots of call sites spread around.
return -1;
return ERR_LOGIC;
}
const LoadRequest lr(func, param, description, estimated_duration_ms);
load_requests.push_back(lr);
return 0;
return ERR_OK;
}
// call when finished registering tasks; subsequent calls to
// LDR_ProgressiveLoad will then work off the queued entries.
int LDR_EndRegistering()
LibError LDR_EndRegistering()
{
if(state != REGISTERING)
return -1;
return ERR_LOGIC;
if(load_requests.empty())
debug_warn("no LoadRequests queued");
@ -134,25 +134,25 @@ int LDR_EndRegistering()
estimated_duration_tally = 0.0;
task_elapsed_time = 0.0;
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.
// used to abort loading upon user request or failure.
// 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
// should be an atomic sequence of begin, register [..], end.
if(state != LOADING)
return -1;
return ERR_LOGIC;
state = IDLE;
// 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
// 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.
//
// 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 not currently loading (no-op), return 0.
// - 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
// 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.
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)
{
int ret; // single exit; this is returned
LibError ret; // single exit; this is returned
double progress = 0.0; // used to set progress_percent
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
// an error; there is just nothing to do.
if(state != LOADING)
return 0;
return ERR_OK;
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.
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;
time_left -= elapsed_time;
task_elapsed_time += elapsed_time;
// 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);
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.
// note: monotonicity is guaranteed since we never add more than
// its estimated_duration_ms.
if(ret > 0)
if(status > 0)
{
ret = MIN(ret, 100); // clamp in case estimate is too high
current_estimate += estimated_duration * ret/100.0;
status = MIN(status, 100); // clamp in case estimate is too high
current_estimate += estimated_duration * status/100.0;
}
progress = current_estimate / total_estimated_duration;
}
// translate return value
// (function interrupted itself; need to return ERR_TIMED_OUT)
if(ret > 0)
// do we need to continue?
// .. function interrupted itself, i.e. timed out; abort.
if(status > 0)
{
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;
// 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.
state = IDLE;
ret = LDR_ALL_FINISHED;
ret = INFO_ALL_COMPLETE;
// set output params (there are several return points above)
@ -302,7 +307,7 @@ done:
// immediately process all queued load requests.
// returns 0 on success or a negative error code.
int LDR_NonprogressiveLoad()
LibError LDR_NonprogressiveLoad()
{
const double time_budget = 100.0;
// large enough so that individual functions won't time out
@ -312,15 +317,14 @@ int LDR_NonprogressiveLoad()
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)
{
case 0:
case ERR_OK:
debug_warn("No load in progress");
return 0; // success
case LDR_ALL_FINISHED:
return 0; // success
return ERR_OK;
case INFO_ALL_COMPLETE:
return ERR_OK;
case ERR_TIMED_OUT:
break; // continue loading
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,
// which is bogus. that can happen by clicking the load button quickly,
// or issuing via console while already loading.
extern int LDR_BeginRegistering();
extern LibError LDR_BeginRegistering();
// 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
// whether there is enough of the time budget left to process this task
// (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);
// call when finished registering tasks; subsequent calls to
// 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.
// used to abort loading upon user request or failure.
// 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].
// 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.
//
// 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 not currently loading (no-op), return 0.
// - 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
// 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.
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);
// immediately process all queued load requests.
// 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.

View File

@ -20,7 +20,7 @@
template<class T> struct MemFun_t
{
T* const this_;
int(T::*func)(void);
int (T::*func)(void);
MemFun_t(T* this__, int(T::*func_)(void))
: this_(this__), func(func_) {}
@ -53,7 +53,7 @@ template<class T, class Arg> struct MemFun1_t
{
T* const this_;
Arg arg;
int(T::*func)(Arg);
int (T::*func)(Arg);
MemFun1_t(T* this__, int(T::*func_)(Arg), Arg arg_)
: this_(this__), func(func_), arg(arg_) {}

View File

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

View File

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

View File

@ -70,7 +70,7 @@ public:
*
* @return Number of rows in this table.
*/
virtual uint GetNumberRows() = 0;
virtual size_t GetNumberRows() = 0;
/**
* GetColumnDescriptions
@ -87,7 +87,7 @@ public:
*
* @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.
@ -97,7 +97,7 @@ public:
* @return Pointer to the child table if the given row has one.
* Otherwise, return 0.
*/
virtual AbstractProfileTable* GetChild(uint row) = 0;
virtual AbstractProfileTable* GetChild(size_t row) = 0;
/**
* IsHighlightRow
@ -106,7 +106,7 @@ public:
*
* @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.
//
// 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)
{
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());
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
// directory <path>; if flags & RECURSIVE, entries in subdirectories are
// 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);
}; // namespace VFSUtil

View File

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