2005-12-10 08:04:31 +01:00
|
|
|
// notes:
|
|
|
|
// - file is called lib_errors.h because 0ad has another errors.cpp and
|
|
|
|
// the MS linker isn't smart enough to deal with object files
|
|
|
|
// of the same name but in different paths.
|
|
|
|
// - the first part of this file is a normal header; the second contains
|
|
|
|
// X macros and is only active if ERR is defined (i.e. someone is
|
|
|
|
// including this header for the purpose of using them).
|
|
|
|
|
|
|
|
#ifndef ERRORS_H__
|
|
|
|
#define ERRORS_H__
|
|
|
|
|
|
|
|
// limits on the errors defined above (used by error_description_r)
|
|
|
|
#define ERR_MIN 100000
|
|
|
|
#define ERR_MAX 110000
|
|
|
|
|
|
|
|
// define error codes.
|
|
|
|
enum LibError {
|
|
|
|
#define ERR(err, id, str) id = err,
|
|
|
|
#include "lib_errors.h"
|
|
|
|
// necessary because the enum would otherwise end with a comma
|
|
|
|
// (which is often tolerated but not standards compliant).
|
|
|
|
// note: we cannot rely on this being the last value (in case the
|
|
|
|
// ERR x-macros aren't arranged in order), so don't use as such.
|
|
|
|
LIB_ERROR_DUMMY
|
|
|
|
};
|
|
|
|
|
2005-12-17 23:00:54 +01:00
|
|
|
// 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
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-12-10 08:04:31 +01:00
|
|
|
|
|
|
|
// generate textual description of an error code.
|
|
|
|
// stores up to <max_chars> in the given buffer.
|
2005-12-12 20:19:30 +01:00
|
|
|
// if error is unknown/invalid, the string will be something like
|
2005-12-10 08:04:31 +01:00
|
|
|
// "Unknown error (65536, 0x10000)".
|
2005-12-12 20:19:30 +01:00
|
|
|
extern void error_description_r(LibError err, char* buf, size_t max_chars);
|
2005-12-10 08:04:31 +01:00
|
|
|
|
2005-12-11 23:23:55 +01:00
|
|
|
|
|
|
|
// return the LibError equivalent of errno, or ERR_FAIL if there's no equal.
|
|
|
|
// only call after a POSIX function indicates failure.
|
|
|
|
extern LibError LibError_from_errno();
|
|
|
|
|
|
|
|
// 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
|
|
|
|
// make sure we do not return any stale errors.
|
|
|
|
extern LibError LibError_from_posix(int ret);
|
|
|
|
|
2005-12-12 20:19:30 +01:00
|
|
|
// 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);
|
|
|
|
|
2005-12-11 23:23:55 +01:00
|
|
|
|
|
|
|
// 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)
|
2005-12-12 20:19:30 +01:00
|
|
|
// 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.
|
2005-12-11 23:23:55 +01:00
|
|
|
|
|
|
|
// if expression evaluates to a negative i64, warn user and return the number.
|
|
|
|
#if OS_WIN
|
|
|
|
#define CHECK_ERR(expression)\
|
|
|
|
STMT(\
|
2005-12-12 20:19:30 +01:00
|
|
|
i64 err64 = (i64)(expression);\
|
|
|
|
if(err64 < 0)\
|
2005-12-11 23:23:55 +01:00
|
|
|
{\
|
2005-12-12 20:19:30 +01:00
|
|
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
|
|
|
DEBUG_WARN_ERR(err);\
|
|
|
|
return err;\
|
2005-12-11 23:23:55 +01:00
|
|
|
}\
|
|
|
|
)
|
|
|
|
#else
|
|
|
|
#define CHECK_ERR(expression)\
|
|
|
|
STMT(\
|
2005-12-12 20:19:30 +01:00
|
|
|
i64 err64 = (i64)(expression);\
|
|
|
|
if(err64 < 0)\
|
2005-12-11 23:23:55 +01:00
|
|
|
{\
|
2005-12-12 20:19:30 +01:00
|
|
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
|
|
|
DEBUG_WARN_ERR(err);\
|
|
|
|
return (LibError)(err & UINT_MAX);\
|
2005-12-11 23:23:55 +01:00
|
|
|
}\
|
|
|
|
)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// just pass on errors without any kind of annoying warning
|
|
|
|
// (useful for functions that can legitimately fail, e.g. vfs_exists).
|
|
|
|
#define RETURN_ERR(expression)\
|
|
|
|
STMT(\
|
2005-12-12 20:19:30 +01:00
|
|
|
i64 err64 = (i64)(expression);\
|
|
|
|
if(err64 < 0)\
|
|
|
|
{\
|
|
|
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
|
|
|
return err;\
|
|
|
|
}\
|
2005-12-11 23:23:55 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// return an error and warn about it (replaces debug_warn+return)
|
|
|
|
#define WARN_RETURN(err)\
|
|
|
|
STMT(\
|
|
|
|
DEBUG_WARN_ERR(err);\
|
|
|
|
return err;\
|
|
|
|
)
|
|
|
|
|
|
|
|
// if expression evaluates to a negative i64, warn user and throw the number.
|
|
|
|
#define THROW_ERR(expression)\
|
|
|
|
STMT(\
|
2005-12-12 20:19:30 +01:00
|
|
|
i64 err64 = (i64)(expression);\
|
|
|
|
if(err64 < 0)\
|
2005-12-11 23:23:55 +01:00
|
|
|
{\
|
2005-12-12 20:19:30 +01:00
|
|
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
|
|
|
DEBUG_WARN_ERR(err);\
|
|
|
|
throw err;\
|
2005-12-11 23:23:55 +01:00
|
|
|
}\
|
|
|
|
)
|
|
|
|
|
|
|
|
// if expression evaluates to a negative i64, warn user and just return
|
|
|
|
// (useful for void functions that must bail and complain)
|
|
|
|
#define WARN_ERR_RETURN(expression)\
|
|
|
|
STMT(\
|
2005-12-12 20:19:30 +01:00
|
|
|
i64 err64 = (i64)(expression);\
|
|
|
|
if(err64 < 0)\
|
2005-12-11 23:23:55 +01:00
|
|
|
{\
|
2005-12-12 20:19:30 +01:00
|
|
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
|
|
|
DEBUG_WARN_ERR(err);\
|
2005-12-11 23:23:55 +01:00
|
|
|
return;\
|
|
|
|
}\
|
|
|
|
)
|
|
|
|
|
|
|
|
// if expression evaluates to a negative i64, warn user
|
|
|
|
// (this is similar to debug_assert but also works in release mode)
|
|
|
|
#define WARN_ERR(expression)\
|
|
|
|
STMT(\
|
2005-12-12 20:19:30 +01:00
|
|
|
i64 err64 = (i64)(expression);\
|
|
|
|
if(err64 < 0)\
|
|
|
|
{\
|
|
|
|
LibError err = (LibError)(err64 & UINT_MAX);\
|
|
|
|
DEBUG_WARN_ERR(err);\
|
|
|
|
}\
|
2005-12-11 23:23:55 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if ok evaluates to false or FALSE, warn user and return -1.
|
|
|
|
#define WARN_RETURN_IF_FALSE(ok)\
|
|
|
|
STMT(\
|
|
|
|
if(!(ok))\
|
|
|
|
{\
|
|
|
|
debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\
|
|
|
|
"feel free to ignore or suppress this warning.");\
|
2005-12-12 20:19:30 +01:00
|
|
|
return ERR_FAIL;\
|
2005-12-11 23:23:55 +01:00
|
|
|
}\
|
|
|
|
)
|
|
|
|
|
|
|
|
// if ok evaluates to false or FALSE, return -1.
|
|
|
|
#define RETURN_IF_FALSE(ok)\
|
|
|
|
STMT(\
|
|
|
|
if(!(ok))\
|
2005-12-12 20:19:30 +01:00
|
|
|
return ERR_FAIL;\
|
2005-12-11 23:23:55 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// if ok evaluates to false or FALSE, warn user.
|
|
|
|
#define WARN_IF_FALSE(ok)\
|
|
|
|
STMT(\
|
|
|
|
if(!(ok))\
|
|
|
|
debug_warn("FYI: WARN_IF_FALSE reports that a function failed."\
|
|
|
|
"feel free to ignore or suppress this warning.");\
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2005-12-10 08:04:31 +01:00
|
|
|
#endif // #ifndef ERRORS_H__
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#ifdef ERR
|
2005-11-19 23:59:16 +01:00
|
|
|
|
2005-11-19 19:12:16 +01:00
|
|
|
// 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).
|
|
|
|
|
2005-12-11 23:23:55 +01:00
|
|
|
// ERR_OK doesn't really need a string, but must be part of enum LibError
|
|
|
|
// due to compiler checks. (and calling error_description_r(0) should
|
|
|
|
// never happen, but we set the text accordingly..)
|
|
|
|
ERR(0, ERR_OK, "(but return value was 0 which indicates success)")
|
|
|
|
ERR(-1, ERR_FAIL, "Function failed (no details available)")
|
|
|
|
|
2006-03-01 23:31:11 +01:00
|
|
|
// note: these values are > 100 to allow multiplexing them with
|
|
|
|
// coroutine return values, which return completion percentage.
|
|
|
|
ERR(101, INFO_CB_CONTINUE, "1 (not an error)")
|
2005-12-11 23:23:55 +01:00
|
|
|
// these are all basically the same thing
|
2006-03-01 23:31:11 +01:00
|
|
|
ERR(102, INFO_CANNOT_HANDLE, "2 (not an error)")
|
|
|
|
ERR(103, INFO_NO_REPLACE, "3 (not an error)")
|
|
|
|
ERR(104, INFO_SKIPPED, "4 (not an error)")
|
|
|
|
ERR(105, INFO_ALL_COMPLETE, "5 (not an error)")
|
|
|
|
ERR(106, INFO_ALREADY_PRESENT, "6 (not an error)")
|
2005-12-11 23:23:55 +01:00
|
|
|
|
|
|
|
ERR(-100000, ERR_LOGIC, "Logic error in code")
|
|
|
|
ERR(-100060, ERR_TIMED_OUT, "Timed out")
|
|
|
|
|
|
|
|
// these are for cases where we just want a distinct value to display and
|
|
|
|
// a symbolic name + string would be overkill (e.g. the various
|
|
|
|
// test cases in a validate() call). they are shared between multiple
|
|
|
|
// functions; when something fails, the stack trace will show in which
|
|
|
|
// one it was => these errors are unambiguous.
|
|
|
|
// there are 3 tiers - 1..9 are used in most functions, 11..19 are
|
|
|
|
// used in a function that calls another validator and 21..29 are
|
|
|
|
// for for functions that call 2 other validators (this avoids
|
|
|
|
// ambiguity as to which error actually happened where)
|
|
|
|
ERR(-100101, ERR_1, "Case 1")
|
|
|
|
ERR(-100102, ERR_2, "Case 2")
|
|
|
|
ERR(-100103, ERR_3, "Case 3")
|
|
|
|
ERR(-100104, ERR_4, "Case 4")
|
|
|
|
ERR(-100105, ERR_5, "Case 5")
|
|
|
|
ERR(-100106, ERR_6, "Case 6")
|
|
|
|
ERR(-100107, ERR_7, "Case 7")
|
|
|
|
ERR(-100108, ERR_8, "Case 8")
|
|
|
|
ERR(-100109, ERR_9, "Case 9")
|
|
|
|
ERR(-100111, ERR_11, "Case 11")
|
|
|
|
ERR(-100112, ERR_12, "Case 12")
|
|
|
|
ERR(-100113, ERR_13, "Case 13")
|
|
|
|
ERR(-100114, ERR_14, "Case 14")
|
|
|
|
ERR(-100115, ERR_15, "Case 15")
|
|
|
|
ERR(-100116, ERR_16, "Case 16")
|
|
|
|
ERR(-100117, ERR_17, "Case 17")
|
|
|
|
ERR(-100118, ERR_18, "Case 18")
|
|
|
|
ERR(-100119, ERR_19, "Case 19")
|
|
|
|
ERR(-100121, ERR_21, "Case 21")
|
|
|
|
ERR(-100122, ERR_22, "Case 22")
|
|
|
|
ERR(-100123, ERR_23, "Case 23")
|
|
|
|
ERR(-100124, ERR_24, "Case 24")
|
|
|
|
ERR(-100125, ERR_25, "Case 25")
|
|
|
|
ERR(-100126, ERR_26, "Case 26")
|
|
|
|
ERR(-100127, ERR_27, "Case 27")
|
|
|
|
ERR(-100128, ERR_28, "Case 28")
|
|
|
|
ERR(-100129, ERR_29, "Case 29")
|
|
|
|
|
2005-11-19 19:12:16 +01:00
|
|
|
// function arguments
|
2005-12-11 23:23:55 +01:00
|
|
|
ERR(-100220, ERR_INVALID_PARAM, "Invalid function argument")
|
|
|
|
ERR(-100221, ERR_INVALID_HANDLE, "Invalid Handle (argument)")
|
|
|
|
ERR(-100222, ERR_BUF_SIZE, "Buffer argument too small")
|
2005-11-19 19:12:16 +01:00
|
|
|
|
|
|
|
// system limitations
|
2005-12-11 23:23:55 +01:00
|
|
|
ERR(-100240, ERR_NO_MEM, "Not enough memory")
|
|
|
|
ERR(-100241, ERR_AGAIN, "Try again later")
|
|
|
|
ERR(-100242, ERR_LIMIT, "Fixed limit exceeded")
|
|
|
|
ERR(-100243, ERR_NO_SYS, "OS doesn't provide a required API")
|
|
|
|
ERR(-100244, ERR_NOT_IMPLEMENTED, "Feature currently not implemented")
|
|
|
|
ERR(-100245, ERR_NOT_SUPPORTED, "Feature isn't and won't be supported")
|
2005-11-19 19:12:16 +01:00
|
|
|
|
|
|
|
// file + vfs
|
2005-12-11 23:23:55 +01:00
|
|
|
ERR(-100300, ERR_FILE_NOT_FOUND, "VFile not found")
|
|
|
|
ERR(-100301, ERR_PATH_NOT_FOUND, "VDir not found")
|
|
|
|
ERR(-100302, ERR_PATH_LENGTH, "Path exceeds VFS_MAX_PATH characters")
|
|
|
|
ERR(-100303, ERR_PATH_INVALID, "Path is invalid")
|
|
|
|
ERR(-100310, ERR_DIR_END, "End of directory reached (no more files)")
|
|
|
|
ERR(-100320, ERR_NOT_FILE, "Not a file")
|
|
|
|
ERR(-100321, ERR_NOT_DIR, "Not a directory")
|
|
|
|
ERR(-100330, ERR_FILE_ACCESS, "Insufficient access rights to open file")
|
|
|
|
ERR(-100331, ERR_IO, "Error during IO")
|
|
|
|
ERR(-100332, ERR_EOF, "Reading beyond end of file")
|
2006-01-23 08:59:20 +01:00
|
|
|
ERR(-100340, ERR_UNKNOWN_CMETHOD, "Unknown/unsupported compression method")
|
|
|
|
ERR(-100341, ERR_IS_COMPRESSED, "Invalid operation for a compressed file")
|
|
|
|
ERR(-100350, ERR_ALREADY_MOUNTED, "Directory (tree) already mounted")
|
|
|
|
ERR(-100351, ERR_INVALID_MOUNT_TYPE, "Invalid mount type (memory corruption?)")
|
|
|
|
ERR(-100360, ERR_NOT_IN_CACHE, "[Internal] Entry not found in cache")
|
2006-03-07 06:44:34 +01:00
|
|
|
ERR(-100370, ERR_TRACE_EMPTY, "No valid entries in trace")
|
2005-11-19 19:12:16 +01:00
|
|
|
|
|
|
|
// 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")
|
2005-12-11 23:23:55 +01:00
|
|
|
ERR(-100507, ERR_TEX_CODEC_CANNOT_HANDLE, "Texture codec cannot handle the given format")
|
2005-11-19 19:12:16 +01:00
|
|
|
|
2005-12-11 23:23:55 +01:00
|
|
|
// CPU
|
2005-11-19 19:12:16 +01:00
|
|
|
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")
|
|
|
|
|
2005-12-11 23:23:55 +01:00
|
|
|
// debug symbol engine
|
|
|
|
ERR(-100800, ERR_SYM_NO_STACK_FRAMES_FOUND, "No stack frames found")
|
|
|
|
ERR(-100801, ERR_SYM_UNRETRIEVABLE_STATIC, "Value unretrievable (stored in external module)")
|
|
|
|
ERR(-100802, ERR_SYM_UNRETRIEVABLE_REG, "Value unretrievable (stored in register)")
|
|
|
|
ERR(-100803, ERR_SYM_TYPE_INFO_UNAVAILABLE, "Error getting type_info")
|
|
|
|
// .. this limit is to prevent infinite recursion.
|
|
|
|
ERR(-100804, ERR_SYM_NESTING_LIMIT, "Symbol nesting too deep or infinite recursion")
|
|
|
|
// .. this limit is to prevent large symbols (e.g. arrays or linked lists) from
|
|
|
|
// hogging all stack trace buffer space.
|
|
|
|
ERR(-100805, ERR_SYM_SINGLE_SYMBOL_LIMIT, "Symbol has produced too much output")
|
|
|
|
ERR(-100806, ERR_SYM_INTERNAL_ERROR, "Exception raised while processing a symbol")
|
|
|
|
ERR(-100807, ERR_SYM_UNSUPPORTED, "Symbol type not (fully) supported")
|
|
|
|
// .. one of the dump_sym* functions decided not to output anything at
|
|
|
|
// all (e.g. for member functions in UDTs - we don't want those).
|
|
|
|
// therefore, skip any post-symbol formatting (e.g. ",") as well.
|
|
|
|
ERR(-100808, ERR_SYM_SUPPRESS_OUTPUT, "Symbol was suppressed")
|
|
|
|
ERR(-100809, ERR_SYM_CHILD_NOT_FOUND, "Symbol does not have the given child")
|
|
|
|
|
|
|
|
// STL debug
|
|
|
|
ERR(-100900, ERR_STL_CNT_UNKNOWN, "Unknown STL container type_name")
|
|
|
|
// .. likely causes: not yet initialized or memory corruption.
|
|
|
|
ERR(-100901, ERR_STL_CNT_INVALID, "Container type is known but contents are invalid")
|
|
|
|
|
2005-11-19 19:12:16 +01:00
|
|
|
#undef ERR
|
|
|
|
#endif // #ifdef ERR
|