1
0
forked from 0ad/0ad

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:
janwas 2005-11-19 18:12:16 +00:00
parent 5c9501830c
commit 59f9e37930
9 changed files with 179 additions and 74 deletions

View File

@ -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
View 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
View 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__

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -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)
{ {

View File

@ -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>,

View File

@ -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