lib error codes moved to errors.h and made X macros. this allows adding a corresponding text message, which is now output by debug_warn_err.
vfs_path, tex, tex_codec: small tweaks to error-related code. This was SVN commit r3158.
This commit is contained in:
parent
5c9501830c
commit
59f9e37930
@ -571,7 +571,8 @@ ErrorReaction debug_warn_err(int err, 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"Function call failed at %hs:%d (%hs): return value was %d", base_name, line, func, err);
|
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 display_error(buf, DE_ALLOW_SUPPRESS|DE_MANUAL_BREAK, skip, context, base_name, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
source/lib/errors.cpp
Normal file
75
source/lib/errors.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "errors.h"
|
||||||
|
#include "sysdep/sysdep.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h> // abs
|
||||||
|
|
||||||
|
|
||||||
|
static const char* lib_error_description(int err)
|
||||||
|
{
|
||||||
|
// not in our range
|
||||||
|
if(!(ERR_MIN <= abs(err) && abs(err) < ERR_MAX))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch(err)
|
||||||
|
{
|
||||||
|
#define ERR(err, id, str) case id: return str;
|
||||||
|
#include "errors.h"
|
||||||
|
default: return "Unknown lib error";
|
||||||
|
}
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void error_description_r(int err, char* buf, size_t max_chars)
|
||||||
|
{
|
||||||
|
// lib error
|
||||||
|
const char* str = lib_error_description(err);
|
||||||
|
if(str)
|
||||||
|
{
|
||||||
|
// <err> was one of our error codes (chosen so as not to conflict
|
||||||
|
// with any others), so we're done.
|
||||||
|
strcpy_s(buf, max_chars, str);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* error_description(int err)
|
||||||
|
{
|
||||||
|
static char buf[200];
|
||||||
|
error_description_r(err, buf, ARRAY_SIZE(buf));
|
||||||
|
return buf;
|
||||||
|
}
|
70
source/lib/errors.h
Normal file
70
source/lib/errors.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// X macros: error code, symbolic name in code, user-visible string.
|
||||||
|
// error code is usually negative; positive denotes warnings.
|
||||||
|
// its absolute value must be within [ERR_MIN, ERR_MAX).
|
||||||
|
#ifdef ERR
|
||||||
|
|
||||||
|
// function arguments
|
||||||
|
ERR(-100000, ERR_INVALID_PARAM, "Invalid function argument")
|
||||||
|
ERR(-100001, ERR_INVALID_HANDLE, "Invalid Handle (argument)")
|
||||||
|
ERR(-100002, ERR_BUF_SIZE, "Buffer argument too small")
|
||||||
|
|
||||||
|
// system limitations
|
||||||
|
ERR(-100020, ERR_NO_MEM, "Not enough memory")
|
||||||
|
ERR(-100021, ERR_AGAIN, "Try again later")
|
||||||
|
ERR(-100022, ERR_LIMIT, "Fixed limit exceeded")
|
||||||
|
ERR(-100023, ERR_NO_SYS, "OS doesn't provide a required API")
|
||||||
|
ERR(-100024, ERR_NOT_IMPLEMENTED, "Feature currently not implemented")
|
||||||
|
ERR(-100025, ERR_NOT_SUPPORTED, "Feature isn't and won't be supported")
|
||||||
|
|
||||||
|
ERR(-1060, ERR_TIMED_OUT, "Timed out")
|
||||||
|
|
||||||
|
// file + vfs
|
||||||
|
ERR(-100200, ERR_FILE_NOT_FOUND, "VFile not found")
|
||||||
|
ERR(-100201, ERR_PATH_NOT_FOUND, "VDir not found")
|
||||||
|
ERR(-100202, ERR_PATH_LENGTH, "Path exceeds VFS_MAX_PATH characters")
|
||||||
|
ERR(-100203, ERR_PATH_INVALID, "Path is invalid")
|
||||||
|
ERR(-100210, ERR_DIR_END, "End of directory reached (no more files)")
|
||||||
|
ERR(-100220, ERR_NOT_FILE, "Not a file")
|
||||||
|
ERR(-100230, ERR_FILE_ACCESS, "Insufficient access rights to open file")
|
||||||
|
ERR(-100231, ERR_IO, "Error during IO")
|
||||||
|
ERR(-100232, ERR_EOF, "Reading beyond end of file")
|
||||||
|
|
||||||
|
// file format
|
||||||
|
ERR(-100400, ERR_UNKNOWN_FORMAT, "Unknown file format")
|
||||||
|
ERR(-100401, ERR_INCOMPLETE_HEADER, "File header not completely read")
|
||||||
|
ERR(-100402, ERR_CORRUPTED, "File data is corrupted")
|
||||||
|
|
||||||
|
// texture
|
||||||
|
ERR(-100500, ERR_TEX_FMT_INVALID, "Invalid/unsupported texture format")
|
||||||
|
ERR(-100501, ERR_TEX_INVALID_COLOR_TYPE, "Invalid color type")
|
||||||
|
ERR(-100502, ERR_TEX_NOT_8BIT_PRECISION, "Not 8-bit channel precision")
|
||||||
|
ERR(-100503, ERR_TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. right-to-left")
|
||||||
|
ERR(-100504, ERR_TEX_COMPRESSED, "Unsupported texture compression")
|
||||||
|
ERR(+100505, WARN_TEX_INVALID_DATA, "Warning: invalid texel data encountered")
|
||||||
|
ERR(-100506, ERR_TEX_INVALID_SIZE, "Texture size is incorrect")
|
||||||
|
|
||||||
|
ERR(-100600, ERR_CPU_FEATURE_MISSING, "This CPU doesn't support a required feature")
|
||||||
|
|
||||||
|
// shaders
|
||||||
|
ERR(-100700, ERR_SHDR_CREATE, "Shader creation failed")
|
||||||
|
ERR(-100701, ERR_SHDR_COMPILE, "Shader compile failed")
|
||||||
|
ERR(-100702, ERR_SHDR_NO_SHADER, "Invalid shader reference")
|
||||||
|
ERR(-100703, ERR_SHDR_LINK, "Shader linking failed")
|
||||||
|
ERR(-100704, ERR_SHDR_NO_PROGRAM, "Invalid shader program reference")
|
||||||
|
|
||||||
|
#undef ERR
|
||||||
|
#endif // #ifdef ERR
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef ERRORS_H__
|
||||||
|
#define ERRORS_H__
|
||||||
|
|
||||||
|
#define ERR_MIN 100000
|
||||||
|
#define ERR_MAX 110000
|
||||||
|
|
||||||
|
extern const char* error_description(int err);
|
||||||
|
extern void error_description_r(int err, char* buf, size_t max_chars);
|
||||||
|
|
||||||
|
#endif // #ifndef ERRORS_H__
|
@ -59,6 +59,10 @@ scope
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "lib/types.h"
|
#include "lib/types.h"
|
||||||
|
|
||||||
|
// define error codes
|
||||||
|
#define ERR(err, id, str) const int id = err;
|
||||||
|
#include "lib/errors.h"
|
||||||
|
|
||||||
#include "sysdep/sysdep.h"
|
#include "sysdep/sysdep.h"
|
||||||
#include "sysdep/cpu.h" // CAS
|
#include "sysdep/cpu.h" // CAS
|
||||||
|
|
||||||
@ -231,70 +235,6 @@ STMT(\
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
enum LibError
|
|
||||||
{
|
|
||||||
// function arguments
|
|
||||||
ERR_INVALID_PARAM = -1000,
|
|
||||||
ERR_INVALID_HANDLE = -1001,
|
|
||||||
ERR_BUF_SIZE = -1002,
|
|
||||||
|
|
||||||
// system limitations
|
|
||||||
// .. out of memory
|
|
||||||
ERR_NO_MEM = -1020,
|
|
||||||
// .. try again later
|
|
||||||
ERR_AGAIN = -1021,
|
|
||||||
// .. fixed limit exceeded
|
|
||||||
ERR_LIMIT = -1022,
|
|
||||||
// .. the OS doesn't provide an API we need
|
|
||||||
ERR_NO_SYS = -1023,
|
|
||||||
// .. feature not currently implemented (will probably change)
|
|
||||||
ERR_NOT_IMPLEMENTED = -1024,
|
|
||||||
// .. feature won't be supported
|
|
||||||
ERR_NOT_SUPPORTED = -1025,
|
|
||||||
|
|
||||||
ERR_TIMED_OUT = -1060,
|
|
||||||
|
|
||||||
// file + vfs
|
|
||||||
ERR_FILE_NOT_FOUND = -1200,
|
|
||||||
ERR_PATH_NOT_FOUND = -1201,
|
|
||||||
ERR_PATH_LENGTH = -1202,
|
|
||||||
ERR_PATH_INVALID = -1203,
|
|
||||||
ERR_DIR_END = -1210,
|
|
||||||
ERR_NOT_FILE = -1220,
|
|
||||||
ERR_FILE_ACCESS = -1230,
|
|
||||||
ERR_IO = -1231,
|
|
||||||
ERR_EOF = -1232,
|
|
||||||
|
|
||||||
// file format
|
|
||||||
ERR_UNKNOWN_FORMAT = -1400,
|
|
||||||
ERR_INCOMPLETE_HEADER = -1401,
|
|
||||||
// .. data (e.g. in file) is obviously incorrect
|
|
||||||
ERR_CORRUPTED = -1402,
|
|
||||||
|
|
||||||
// texture
|
|
||||||
ERR_TEX_FMT_INVALID = -1500,
|
|
||||||
ERR_TEX_INVALID_COLOR_TYPE = -1501,
|
|
||||||
ERR_TEX_NOT_8BIT_PRECISION = -1502,
|
|
||||||
ERR_TEX_INVALID_LAYOUT = -1503,
|
|
||||||
ERR_TEX_COMPRESSED = -1504,
|
|
||||||
WARN_TEX_INVALID_DATA = +1505,
|
|
||||||
ERR_TEX_INVALID_SIZE = -1506,
|
|
||||||
ERR_TEX_HEADER_NOT_COMPLETE = -1507,
|
|
||||||
|
|
||||||
ERR_CPU_FEATURE_MISSING = -1600,
|
|
||||||
|
|
||||||
// shaders
|
|
||||||
ERR_SHDR_CREATE = -1700,
|
|
||||||
ERR_SHDR_COMPILE = -1701,
|
|
||||||
ERR_SHDR_NO_SHADER = -1702,
|
|
||||||
ERR_SHDR_LINK = -1703,
|
|
||||||
ERR_SHDR_NO_PROGRAM = -1704,
|
|
||||||
|
|
||||||
ERR_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a, b) (((a) < (b))? (a) : (b))
|
#define MIN(a, b) (((a) < (b))? (a) : (b))
|
||||||
|
@ -31,7 +31,6 @@ int path_validate(const uint line, const char* path)
|
|||||||
size_t path_len = 0; // counted as we go; checked against max.
|
size_t path_len = 0; // counted as we go; checked against max.
|
||||||
|
|
||||||
const char* msg = 0; // error occurred <==> != 0
|
const char* msg = 0; // error occurred <==> != 0
|
||||||
int err = -1; // what we pass to caller
|
|
||||||
|
|
||||||
int c = 0, last_c; // used for ./ detection
|
int c = 0, last_c; // used for ./ detection
|
||||||
|
|
||||||
@ -78,12 +77,10 @@ int path_validate(const uint line, const char* path)
|
|||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// failed somewhere - err is the error code,
|
|
||||||
// or -1 if not set specifically above.
|
|
||||||
fail:
|
fail:
|
||||||
debug_printf("%s called from line %d failed: %s (error code %d)\n", __func__, line, msg, err);
|
debug_printf("%s called from line %d failed: %s\n", __func__, line, msg);
|
||||||
debug_warn("failed");
|
debug_warn("failed");
|
||||||
return err;
|
return -1;
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -416,10 +416,10 @@ static int tex_load_impl(void* file_, size_t file_size, Tex* t)
|
|||||||
// make sure the entire header has been read
|
// make sure the entire header has been read
|
||||||
const size_t min_hdr_size = c->hdr_size(0);
|
const size_t min_hdr_size = c->hdr_size(0);
|
||||||
if(file_size < min_hdr_size)
|
if(file_size < min_hdr_size)
|
||||||
return ERR_TEX_HEADER_NOT_COMPLETE;
|
return ERR_INCOMPLETE_HEADER;
|
||||||
const size_t hdr_size = c->hdr_size(file);
|
const size_t hdr_size = c->hdr_size(file);
|
||||||
if(file_size < hdr_size)
|
if(file_size < hdr_size)
|
||||||
return ERR_TEX_HEADER_NOT_COMPLETE;
|
return ERR_INCOMPLETE_HEADER;
|
||||||
t->ofs = hdr_size;
|
t->ofs = hdr_size;
|
||||||
|
|
||||||
DynArray da;
|
DynArray da;
|
||||||
|
@ -48,7 +48,7 @@ int tex_codec_for_header(const u8* file, size_t file_size, const TexCodecVTbl**
|
|||||||
{
|
{
|
||||||
// we guarantee at least 4 bytes for is_hdr to look at
|
// we guarantee at least 4 bytes for is_hdr to look at
|
||||||
if(file_size < 4)
|
if(file_size < 4)
|
||||||
return ERR_TEX_HEADER_NOT_COMPLETE;
|
return ERR_INCOMPLETE_HEADER;
|
||||||
|
|
||||||
for(*c = codecs; *c; *c = (*c)->next)
|
for(*c = codecs; *c; *c = (*c)->next)
|
||||||
{
|
{
|
||||||
|
@ -212,6 +212,8 @@ extern int sys_cursor_free(void* cursor);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern int sys_error_description_r(int err, char* buf, size_t max_chars);
|
||||||
|
|
||||||
extern int get_executable_name(char* n_path, size_t buf_size);
|
extern int get_executable_name(char* n_path, size_t buf_size);
|
||||||
|
|
||||||
// return filename of the module which contains address <addr>,
|
// return filename of the module which contains address <addr>,
|
||||||
|
@ -37,7 +37,6 @@ char win_sys_dir[MAX_PATH+1];
|
|||||||
char win_exe_dir[MAX_PATH+1];
|
char win_exe_dir[MAX_PATH+1];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// we need to know the app's main window for the error dialog, so that
|
// we need to know the app's main window for the error dialog, so that
|
||||||
// it is modal and actually stops the app. if it keeps running while
|
// it is modal and actually stops the app. if it keeps running while
|
||||||
// we're reporting an error, it'll probably crash and take down the
|
// we're reporting an error, it'll probably crash and take down the
|
||||||
@ -634,6 +633,27 @@ int sys_cursor_free(void* cursor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
int sys_error_description_r(int err, char* buf, size_t max_chars)
|
||||||
|
{
|
||||||
|
// not in our range (Win32 error numbers are positive)
|
||||||
|
if(err < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const LPCVOID source = 0; // ignored (we're not using FROM_HMODULE etc.)
|
||||||
|
const DWORD lang_id = 0; // look for neutral, then current locale
|
||||||
|
va_list* args = 0; // we don't care about "inserts"
|
||||||
|
DWORD ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, source, (DWORD)err,
|
||||||
|
lang_id, buf, (DWORD)max_chars, args);
|
||||||
|
if(!ret)
|
||||||
|
return -1;
|
||||||
|
debug_assert(ret < max_chars); // ret = #chars output
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// module init and shutdown mechanism
|
// module init and shutdown mechanism
|
||||||
|
Loading…
Reference in New Issue
Block a user