diff --git a/source/lib/debug.cpp b/source/lib/debug.cpp index c353ca109b..cbe6266bbc 100644 --- a/source/lib/debug.cpp +++ b/source/lib/debug.cpp @@ -30,18 +30,16 @@ #endif -AT_STARTUP(\ - error_setDescription(ERR::SYM_NO_STACK_FRAMES_FOUND, "No stack frames found");\ - error_setDescription(ERR::SYM_UNRETRIEVABLE_STATIC, "Value unretrievable (stored in external module)");\ - error_setDescription(ERR::SYM_UNRETRIEVABLE_REG, "Value unretrievable (stored in register)");\ - error_setDescription(ERR::SYM_TYPE_INFO_UNAVAILABLE, "Error getting type_info");\ - error_setDescription(ERR::SYM_INTERNAL_ERROR, "Exception raised while processing a symbol");\ - error_setDescription(ERR::SYM_UNSUPPORTED, "Symbol type not (fully) supported");\ - error_setDescription(ERR::SYM_CHILD_NOT_FOUND, "Symbol does not have the given child");\ - error_setDescription(ERR::SYM_NESTING_LIMIT, "Symbol nesting too deep or infinite recursion");\ - error_setDescription(ERR::SYM_SINGLE_SYMBOL_LIMIT, "Symbol has produced too much output");\ - error_setDescription(INFO::SYM_SUPPRESS_OUTPUT, "Symbol was suppressed");\ -) +ERROR_ASSOCIATE(ERR::SYM_NO_STACK_FRAMES_FOUND, "No stack frames found", -1); +ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE_STATIC, "Value unretrievable (stored in external module)", -1); +ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE_REG, "Value unretrievable (stored in register)", -1); +ERROR_ASSOCIATE(ERR::SYM_TYPE_INFO_UNAVAILABLE, "Error getting type_info", -1); +ERROR_ASSOCIATE(ERR::SYM_INTERNAL_ERROR, "Exception raised while processing a symbol", -1); +ERROR_ASSOCIATE(ERR::SYM_UNSUPPORTED, "Symbol type not (fully) supported", -1); +ERROR_ASSOCIATE(ERR::SYM_CHILD_NOT_FOUND, "Symbol does not have the given child", -1); +ERROR_ASSOCIATE(ERR::SYM_NESTING_LIMIT, "Symbol nesting too deep or infinite recursion", -1); +ERROR_ASSOCIATE(ERR::SYM_SINGLE_SYMBOL_LIMIT, "Symbol has produced too much output", -1); +ERROR_ASSOCIATE(INFO::SYM_SUPPRESS_OUTPUT, "Symbol was suppressed", -1); // needed when writing crashlog diff --git a/source/lib/debug_stl.cpp b/source/lib/debug_stl.cpp index e5e68f9ebe..e2ff35238c 100644 --- a/source/lib/debug_stl.cpp +++ b/source/lib/debug_stl.cpp @@ -19,10 +19,8 @@ #include "regex.h" -AT_STARTUP(\ - error_setDescription(ERR::STL_CNT_UNKNOWN, "Unknown STL container type_name");\ - error_setDescription(ERR::STL_CNT_INVALID, "Container type is known but contents are invalid");\ -) +ERROR_ASSOCIATE(ERR::STL_CNT_UNKNOWN, "Unknown STL container type_name", -1); +ERROR_ASSOCIATE(ERR::STL_CNT_INVALID, "Container type is known but contents are invalid", -1); // used in debug_stl_simplify_name. diff --git a/source/lib/lib_errors.cpp b/source/lib/lib_errors.cpp index e19dd34293..702327850d 100644 --- a/source/lib/lib_errors.cpp +++ b/source/lib/lib_errors.cpp @@ -23,63 +23,50 @@ #include "lib/posix/posix_errno.h" #include "lib/sysdep/sysdep.h" +// linked list (most recent first) +// note: no memory is allocated, all nodes are static instances. +static LibErrorAssociation* associations; -struct LibErrorAssociation +int error_AddAssociation(LibErrorAssociation* lea) { - const char* description_; - int errno_equivalent_; - LibErrorAssociation() - : description_(0), errno_equivalent_(-1) {} + // insert at front of list + lea->next = associations; + associations = lea; - void setDescription(const char* description) + return 0; // stored in dummy variable +} + +static const LibErrorAssociation* AssociationFromLibError(LibError err) +{ + for(const LibErrorAssociation* lea = associations; lea; lea = lea->next) { - debug_assert(description_ == 0); // not already set - description_ = description; + if(lea->err == err) + return lea; } - void setEquivalent(int errno_equivalent) + return 0; +} + +static const LibErrorAssociation* AssociationFromErrno(errno_t errno_equivalent) +{ + for(const LibErrorAssociation* lea = associations; lea; lea = lea->next) { - debug_assert(errno_equivalent_ == -1); // not already set - errno_equivalent_ = errno_equivalent; + if(lea->errno_equivalent == errno_equivalent) + return lea; } -}; -typedef std::map LibErrorAssociations; -// wrapper required because error_set* is called from AT_STARTUP -// (potentially before our static map is constructed) -static LibErrorAssociations& associations() -{ - static LibErrorAssociations associations_; - return associations_; -} - -void error_setDescription(LibError err, const char* description) -{ - associations()[err].setDescription(description); -} - -void error_setEquivalent(LibError err, int errno_equivalent) -{ - associations()[err].setEquivalent(errno_equivalent); + return 0; } -// generate textual description of an error code. -// stores up to in the given buffer. -// if error is unknown/invalid, the string will be something like -// "Unknown error (65536, 0x10000)". char* error_description_r(LibError err, char* buf, size_t max_chars) { // lib error - LibErrorAssociations::iterator it = associations().find(err); - if(it != associations().end()) + const LibErrorAssociation* lea = AssociationFromLibError(err); + if(lea) { - const LibErrorAssociation& a = it->second; - if(a.description_) - { - strcpy_s(buf, max_chars, a.description_); - return buf; - } + strcpy_s(buf, max_chars, lea->description); + return buf; } // unknown @@ -88,33 +75,20 @@ char* 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. -// only call after a POSIX function indicates failure. -// raises a warning (avoids having to on each call site). LibError LibError_from_errno(bool warn_if_failed) { LibError ret = ERR::FAIL; - LibErrorAssociations::iterator it; - for(it = associations().begin(); it != associations().end(); ++it) - { - const LibErrorAssociation& a = it->second; - if(a.errno_equivalent_ == errno) - { - ret = it->first; - break; - } - } + const LibErrorAssociation* lea = AssociationFromErrno(errno); + if(lea) + ret = lea->err; if(warn_if_failed) DEBUG_WARN_ERR(ret); return ret; } -// 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. + LibError LibError_from_posix(int ret, bool warn_if_failed) { debug_assert(ret == 0 || ret == -1); @@ -128,13 +102,9 @@ LibError LibError_from_posix(int ret, bool warn_if_failed) // does not assign to errno (this simplifies code by allowing direct return) static int return_errno_from_LibError(LibError err) { - LibErrorAssociations::iterator it = associations().find(err); - if(it != associations().end()) - { - const LibErrorAssociation& a = it->second; - if(a.errno_equivalent_ != -1) - return a.errno_equivalent_; - } + const LibErrorAssociation* lea = AssociationFromLibError(err); + if(lea && lea->errno_equivalent != -1) + return lea->errno_equivalent; // 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 @@ -142,11 +112,6 @@ static int return_errno_from_LibError(LibError err) return EPERM; } - -// set errno to the equivalent of . 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); @@ -155,64 +120,55 @@ void LibError_set_errno(LibError err) //----------------------------------------------------------------------------- -AT_STARTUP(\ - /* INFO::OK doesn't really need a string because calling error_description_r(0) should never happen, but go the safe route. */\ - error_setDescription(INFO::OK, "(but return value was 0 which indicates success)");\ - error_setDescription(ERR::FAIL, "Function failed (no details available)");\ - \ - error_setDescription(INFO::CB_CONTINUE, "Continue (not an error)");\ - error_setDescription(INFO::SKIPPED, "Skipped (not an error)");\ - error_setDescription(INFO::CANNOT_HANDLE, "Cannot handle (not an error)");\ - error_setDescription(INFO::ALL_COMPLETE, "All complete (not an error)");\ - error_setDescription(INFO::ALREADY_EXISTS, "Already exists (not an error)");\ - \ - error_setDescription(ERR::LOGIC, "Logic error in code");\ - error_setDescription(ERR::TIMED_OUT, "Timed out");\ - error_setDescription(ERR::REENTERED, "Single-call function was reentered");\ - error_setDescription(ERR::CORRUPTED, "File/memory data is corrupted");\ - \ - error_setDescription(ERR::INVALID_PARAM, "Invalid function argument");\ - error_setDescription(ERR::INVALID_HANDLE, "Invalid Handle (argument)");\ - error_setDescription(ERR::BUF_SIZE, "Buffer argument too small");\ - error_setDescription(ERR::AGAIN, "Try again later");\ - error_setDescription(ERR::LIMIT, "Fixed limit exceeded");\ - error_setDescription(ERR::NO_SYS, "OS doesn't provide a required API");\ - error_setDescription(ERR::NOT_IMPLEMENTED, "Feature currently not implemented");\ - error_setDescription(ERR::NOT_SUPPORTED, "Feature isn't and won't be supported");\ - error_setDescription(ERR::NO_MEM, "Not enough memory");\ - \ - error_setDescription(ERR::_1, "Case 1");\ - error_setDescription(ERR::_2, "Case 2");\ - error_setDescription(ERR::_3, "Case 3");\ - error_setDescription(ERR::_4, "Case 4");\ - error_setDescription(ERR::_5, "Case 5");\ - error_setDescription(ERR::_6, "Case 6");\ - error_setDescription(ERR::_7, "Case 7");\ - error_setDescription(ERR::_8, "Case 8");\ - error_setDescription(ERR::_9, "Case 9");\ - error_setDescription(ERR::_11, "Case 11");\ - error_setDescription(ERR::_12, "Case 12");\ - error_setDescription(ERR::_13, "Case 13");\ - error_setDescription(ERR::_14, "Case 14");\ - error_setDescription(ERR::_15, "Case 15");\ - error_setDescription(ERR::_16, "Case 16");\ - error_setDescription(ERR::_17, "Case 17");\ - error_setDescription(ERR::_18, "Case 18");\ - error_setDescription(ERR::_19, "Case 19");\ - error_setDescription(ERR::_21, "Case 21");\ - error_setDescription(ERR::_22, "Case 22");\ - error_setDescription(ERR::_23, "Case 23");\ - error_setDescription(ERR::_24, "Case 24");\ - error_setDescription(ERR::_25, "Case 25");\ - error_setDescription(ERR::_26, "Case 26");\ - error_setDescription(ERR::_27, "Case 27");\ - error_setDescription(ERR::_28, "Case 28");\ - error_setDescription(ERR::_29, "Case 29");\ -) +// INFO::OK doesn't really need a string because calling error_description_r(0) should never happen, but go the safe route. +ERROR_ASSOCIATE(INFO::OK, "(but return value was 0 which indicates success)", -1); +ERROR_ASSOCIATE(ERR::FAIL, "Function failed (no details available)", -1); +ERROR_ASSOCIATE(INFO::CB_CONTINUE, "Continue (not an error)", -1); +ERROR_ASSOCIATE(INFO::SKIPPED, "Skipped (not an error)", -1); +ERROR_ASSOCIATE(INFO::CANNOT_HANDLE, "Cannot handle (not an error)", -1); +ERROR_ASSOCIATE(INFO::ALL_COMPLETE, "All complete (not an error)", -1); +ERROR_ASSOCIATE(INFO::ALREADY_EXISTS, "Already exists (not an error)", -1); -AT_STARTUP(\ - error_setEquivalent(ERR::NO_MEM, ENOMEM);\ - error_setEquivalent(ERR::INVALID_PARAM, EINVAL);\ - error_setEquivalent(ERR::NOT_IMPLEMENTED, ENOSYS);\ -) +ERROR_ASSOCIATE(ERR::LOGIC, "Logic error in code", -1); +ERROR_ASSOCIATE(ERR::TIMED_OUT, "Timed out", -1); +ERROR_ASSOCIATE(ERR::REENTERED, "Single-call function was reentered", -1); +ERROR_ASSOCIATE(ERR::CORRUPTED, "File/memory data is corrupted", -1); + +ERROR_ASSOCIATE(ERR::INVALID_PARAM, "Invalid function argument", EINVAL); +ERROR_ASSOCIATE(ERR::INVALID_HANDLE, "Invalid Handle (argument)", -1); +ERROR_ASSOCIATE(ERR::BUF_SIZE, "Buffer argument too small", -1); +ERROR_ASSOCIATE(ERR::AGAIN, "Try again later", -1); +ERROR_ASSOCIATE(ERR::LIMIT, "Fixed limit exceeded", -1); +ERROR_ASSOCIATE(ERR::NO_SYS, "OS doesn't provide a required API", -1); +ERROR_ASSOCIATE(ERR::NOT_IMPLEMENTED, "Feature currently not implemented", ENOSYS); +ERROR_ASSOCIATE(ERR::NOT_SUPPORTED, "Feature isn't and won't be supported", -1); +ERROR_ASSOCIATE(ERR::NO_MEM, "Not enough memory", ENOMEM); + +ERROR_ASSOCIATE(ERR::_1, "Case 1", -1); +ERROR_ASSOCIATE(ERR::_2, "Case 2", -1); +ERROR_ASSOCIATE(ERR::_3, "Case 3", -1); +ERROR_ASSOCIATE(ERR::_4, "Case 4", -1); +ERROR_ASSOCIATE(ERR::_5, "Case 5", -1); +ERROR_ASSOCIATE(ERR::_6, "Case 6", -1); +ERROR_ASSOCIATE(ERR::_7, "Case 7", -1); +ERROR_ASSOCIATE(ERR::_8, "Case 8", -1); +ERROR_ASSOCIATE(ERR::_9, "Case 9", -1); +ERROR_ASSOCIATE(ERR::_11, "Case 11", -1); +ERROR_ASSOCIATE(ERR::_12, "Case 12", -1); +ERROR_ASSOCIATE(ERR::_13, "Case 13", -1); +ERROR_ASSOCIATE(ERR::_14, "Case 14", -1); +ERROR_ASSOCIATE(ERR::_15, "Case 15", -1); +ERROR_ASSOCIATE(ERR::_16, "Case 16", -1); +ERROR_ASSOCIATE(ERR::_17, "Case 17", -1); +ERROR_ASSOCIATE(ERR::_18, "Case 18", -1); +ERROR_ASSOCIATE(ERR::_19, "Case 19", -1); +ERROR_ASSOCIATE(ERR::_21, "Case 21", -1); +ERROR_ASSOCIATE(ERR::_22, "Case 22", -1); +ERROR_ASSOCIATE(ERR::_23, "Case 23", -1); +ERROR_ASSOCIATE(ERR::_24, "Case 24", -1); +ERROR_ASSOCIATE(ERR::_25, "Case 25", -1); +ERROR_ASSOCIATE(ERR::_26, "Case 26", -1); +ERROR_ASSOCIATE(ERR::_27, "Case 27", -1); +ERROR_ASSOCIATE(ERR::_28, "Case 28", -1); +ERROR_ASSOCIATE(ERR::_29, "Case 29", -1); diff --git a/source/lib/lib_errors.h b/source/lib/lib_errors.h index cb2a218165..b69af935af 100644 --- a/source/lib/lib_errors.h +++ b/source/lib/lib_errors.h @@ -143,15 +143,34 @@ Notes: // Lint's 'strong type' checking can be used to find errors. typedef long LibError; +// opaque - do not access its fields! +// note: must be defined here because clients instantiate them; +// fields cannot be made private due to POD requirement. +struct LibErrorAssociation +{ + LibError err; + + // must remain valid until end of program. + const char* description; + + // POSIX errno, or -1 + int errno_equivalent; + + LibErrorAssociation* next; +}; /** - * associate textual description with an error code. - * - * @param err LibError to be associate with. if it already has a - * description, a warning will be generated. - * @param description string. Must remain valid until end of program. + * associate a LibError with a description and errno equivalent. + * @return dummy integer to allow calling via static initializer. **/ -extern void error_setDescription(LibError err, const char* description); +extern int error_AddAssociation(LibErrorAssociation*); + +// associate a LibError with a description and errno equivalent. +// Invoke this at file or function scope. +#define ERROR_ASSOCIATE(err, description, errno_equivalent)\ + static LibErrorAssociation UID__ = { err, description, errno_equivalent };\ + static int UID2__ = error_AddAssociation(&UID__); + /** * generate textual description of an error code. @@ -165,24 +184,12 @@ extern void error_setDescription(LibError err, const char* description); **/ extern char* error_description_r(LibError err, char* buf, size_t max_chars); - //----------------------------------------------------------------------------- // conversion to/from other error code definitions. // note: other conversion routines (e.g. to/from Win32) are implemented in // the corresponding modules to keep this header portable. - -/** - * associate POSIX errno with an error code. - * - * @param err LibError to be associate with. if it already has a - * equivalent, a warning will be generated. - * @param errno (as defined by POSIX) - **/ -extern void error_setEquivalent(LibError err, int errno_); - - /** * translate errno to LibError. * diff --git a/source/lib/mmgr.cpp b/source/lib/mmgr.cpp index 2e8e3dbda4..d9ee363269 100644 --- a/source/lib/mmgr.cpp +++ b/source/lib/mmgr.cpp @@ -11,10 +11,8 @@ #include "precompiled.h" -AT_STARTUP(\ - error_setDescription(ERR::MEM_ALLOC_NOT_FOUND, "Not a valid allocated address");\ - error_setDescription(ERR::MEM_OVERWRITTEN, "Wrote to memory outside valid allocation");\ -) +ERROR_ASSOCIATE(ERR::MEM_ALLOC_NOT_FOUND, "Not a valid allocated address", -1); +ERROR_ASSOCIATE(ERR::MEM_OVERWRITTEN, "Wrote to memory outside valid allocation", -1); // for easy removal in release builds, so that we don't cause any overhead. diff --git a/source/lib/module_init.cpp b/source/lib/module_init.cpp index bfead376e4..1a53bc54b2 100644 --- a/source/lib/module_init.cpp +++ b/source/lib/module_init.cpp @@ -37,10 +37,7 @@ bool ModuleShouldInitialize(volatile ModuleInitState* pInitState) retry: ModuleInitState latchedInitState = *pInitState; if(latchedInitState == MODULE_ERROR) - { - debug_warn("attempting to init after error"); return false; - } if(!cpu_CAS(pInitState, latchedInitState, latchedInitState+1)) goto retry; return false; diff --git a/source/lib/path_util.cpp b/source/lib/path_util.cpp index 94230ddacc..ee14985f0e 100644 --- a/source/lib/path_util.cpp +++ b/source/lib/path_util.cpp @@ -15,16 +15,12 @@ #include -AT_STARTUP(\ - error_setDescription(ERR::PATH_LENGTH, "Path exceeds PATH_MAX characters");\ - error_setDescription(ERR::PATH_EMPTY, "Path is an empty string");\ - error_setDescription(ERR::PATH_NOT_RELATIVE, "Path is not relative");\ - error_setDescription(ERR::PATH_NON_PORTABLE, "Path contains OS-specific dir separator");\ - error_setDescription(ERR::PATH_NON_CANONICAL, "Path contains unsupported .. or ./");\ - error_setDescription(ERR::PATH_COMPONENT_SEPARATOR, "Path component contains dir separator");\ - \ - error_setEquivalent(ERR::PATH_LENGTH, ENAMETOOLONG);\ -) +ERROR_ASSOCIATE(ERR::PATH_LENGTH, "Path exceeds PATH_MAX characters", ENAMETOOLONG, -1); +ERROR_ASSOCIATE(ERR::PATH_EMPTY, "Path is an empty string", -1); +ERROR_ASSOCIATE(ERR::PATH_NOT_RELATIVE, "Path is not relative", -1); +ERROR_ASSOCIATE(ERR::PATH_NON_PORTABLE, "Path contains OS-specific dir separator", -1); +ERROR_ASSOCIATE(ERR::PATH_NON_CANONICAL, "Path contains unsupported .. or ./", -1); +ERROR_ASSOCIATE(ERR::PATH_COMPONENT_SEPARATOR, "Path component contains dir separator", -1); bool path_is_dir_sep(char c) diff --git a/source/lib/res/file/archive.cpp b/source/lib/res/file/archive.cpp index b97d681aff..57bb088dc8 100644 --- a/source/lib/res/file/archive.cpp +++ b/source/lib/res/file/archive.cpp @@ -34,9 +34,7 @@ // - file mapping -AT_STARTUP(\ - error_setDescription(ERR::IS_COMPRESSED, "Invalid operation for a compressed file");\ -) +ERROR_ASSOCIATE(ERR::IS_COMPRESSED, "Invalid operation for a compressed file", -1); /////////////////////////////////////////////////////////////////////////////// diff --git a/source/lib/res/file/compression.cpp b/source/lib/res/file/compression.cpp index 4c0026d0b1..78b1edee72 100644 --- a/source/lib/res/file/compression.cpp +++ b/source/lib/res/file/compression.cpp @@ -20,9 +20,7 @@ #include "file_io.h" // IO_EOF -AT_STARTUP(\ - error_setDescription(ERR::COMPRESSION_UNKNOWN_METHOD, "Unknown/unsupported compression method");\ -) +ERROR_ASSOCIATE(ERR::COMPRESSION_UNKNOWN_METHOD, "Unknown/unsupported compression method", -1); // provision for removing all ZLib code (all inflate calls will fail). diff --git a/source/lib/res/file/file.cpp b/source/lib/res/file/file.cpp index 6420ba2310..4f9b0c861e 100644 --- a/source/lib/res/file/file.cpp +++ b/source/lib/res/file/file.cpp @@ -26,13 +26,9 @@ #include "file_internal.h" -AT_STARTUP(\ - error_setDescription(ERR::FILE_ACCESS, "Insufficient access rights to open file");\ - error_setDescription(ERR::DIR_END, "End of directory reached (no more files)");\ - error_setDescription(ERR::FILE_NOT_MAPPED, "File was not mapped");\ - \ - error_setEquivalent(ERR::FILE_ACCESS, EACCES);\ -) +ERROR_ASSOCIATE(ERR::FILE_ACCESS, "Insufficient access rights to open file", EACCES); +ERROR_ASSOCIATE(ERR::DIR_END, "End of directory reached (no more files)", -1); +ERROR_ASSOCIATE(ERR::FILE_NOT_MAPPED, "File was not mapped", -1); // rationale for aio, instead of only using mmap: // - parallelism: instead of just waiting for the transfer to complete, diff --git a/source/lib/res/file/file_io.cpp b/source/lib/res/file/file_io.cpp index b92f011d92..5829ae63e9 100644 --- a/source/lib/res/file/file_io.cpp +++ b/source/lib/res/file/file_io.cpp @@ -20,12 +20,8 @@ #include "file_internal.h" -AT_STARTUP(\ - error_setDescription(ERR::IO, "Error during IO");\ - error_setDescription(ERR::IO_EOF, "Reading beyond end of file");\ - \ - error_setEquivalent(ERR::IO, EIO);\ -) +ERROR_ASSOCIATE(ERR::IO, "Error during IO", EIO); +ERROR_ASSOCIATE(ERR::IO_EOF, "Reading beyond end of file", -1); //----------------------------------------------------------------------------- diff --git a/source/lib/res/file/path.cpp b/source/lib/res/file/path.cpp index 04bbbaca38..8518a773da 100644 --- a/source/lib/res/file/path.cpp +++ b/source/lib/res/file/path.cpp @@ -22,9 +22,7 @@ #include "file_internal.h" -AT_STARTUP(\ - error_setDescription(ERR::ROOT_DIR_ALREADY_SET, "Attempting to set FS root dir more than once");\ -) +ERROR_ASSOCIATE(ERR::ROOT_DIR_ALREADY_SET, "Attempting to set FS root dir more than once", -1); // path types: diff --git a/source/lib/res/file/trace.cpp b/source/lib/res/file/trace.cpp index 7d1a8e0e36..6e0d74961f 100644 --- a/source/lib/res/file/trace.cpp +++ b/source/lib/res/file/trace.cpp @@ -18,9 +18,7 @@ #include "file_internal.h" -AT_STARTUP(\ - error_setDescription(ERR::TRACE_EMPTY, "No valid entries in trace");\ -) +ERROR_ASSOCIATE(ERR::TRACE_EMPTY, "No valid entries in trace"); static uintptr_t trace_initialized; // set via CAS diff --git a/source/lib/res/file/vfs_tree.cpp b/source/lib/res/file/vfs_tree.cpp index 846a0daa6e..d6c6d06342 100644 --- a/source/lib/res/file/vfs_tree.cpp +++ b/source/lib/res/file/vfs_tree.cpp @@ -23,12 +23,8 @@ #include "file_internal.h" -AT_STARTUP(\ - error_setDescription(ERR::TNODE_NOT_FOUND, "File/directory not found");\ - error_setDescription(ERR::TNODE_WRONG_TYPE, "Using a directory as file or vice versa");\ - \ - error_setEquivalent(ERR::TNODE_NOT_FOUND, ENOENT);\ -) +ERROR_ASSOCIATE(ERR::TNODE_NOT_FOUND, "File/directory not found", ENOENT); +ERROR_ASSOCIATE(ERR::TNODE_WRONG_TYPE, "Using a directory as file or vice versa", -1); // we add/cancel directory watches from the VFS mount code for convenience - diff --git a/source/lib/res/graphics/ogl_shader.cpp b/source/lib/res/graphics/ogl_shader.cpp index db95dfa3d1..dbd9b73415 100644 --- a/source/lib/res/graphics/ogl_shader.cpp +++ b/source/lib/res/graphics/ogl_shader.cpp @@ -19,13 +19,11 @@ #define LOG_CATEGORY "shaders" -AT_STARTUP(\ - error_setDescription(ERR::SHDR_CREATE, "Shader creation failed");\ - error_setDescription(ERR::SHDR_COMPILE, "Shader compile failed");\ - error_setDescription(ERR::SHDR_NO_SHADER, "Invalid shader reference");\ - error_setDescription(ERR::SHDR_LINK, "Shader linking failed");\ - error_setDescription(ERR::SHDR_NO_PROGRAM, "Invalid shader program reference");\ -) +ERROR_ASSOCIATE(ERR::SHDR_CREATE, "Shader creation failed"); +ERROR_ASSOCIATE(ERR::SHDR_COMPILE, "Shader compile failed"); +ERROR_ASSOCIATE(ERR::SHDR_NO_SHADER, "Invalid shader reference"); +ERROR_ASSOCIATE(ERR::SHDR_LINK, "Shader linking failed"); +ERROR_ASSOCIATE(ERR::SHDR_NO_PROGRAM, "Invalid shader program reference"); // Convert a shader object type into a descriptive string. diff --git a/source/lib/res/graphics/tex.cpp b/source/lib/res/graphics/tex.cpp index a7de7f1f82..6c61b72f48 100644 --- a/source/lib/res/graphics/tex.cpp +++ b/source/lib/res/graphics/tex.cpp @@ -22,16 +22,14 @@ #include "tex_codec.h" -AT_STARTUP(\ - error_setDescription(ERR::TEX_FMT_INVALID, "Invalid/unsupported texture format");\ - error_setDescription(ERR::TEX_INVALID_COLOR_TYPE, "Invalid color type");\ - error_setDescription(ERR::TEX_NOT_8BIT_PRECISION, "Not 8-bit channel precision");\ - error_setDescription(ERR::TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. right-to-left");\ - error_setDescription(ERR::TEX_COMPRESSED, "Unsupported texture compression");\ - error_setDescription(WARN::TEX_INVALID_DATA, "Warning: invalid texel data encountered");\ - error_setDescription(ERR::TEX_INVALID_SIZE, "Texture size is incorrect");\ - error_setDescription(INFO::TEX_CODEC_CANNOT_HANDLE, "Texture codec cannot handle the given format");\ -) +ERROR_ASSOCIATE(ERR::TEX_FMT_INVALID, "Invalid/unsupported texture format"); +ERROR_ASSOCIATE(ERR::TEX_INVALID_COLOR_TYPE, "Invalid color type"); +ERROR_ASSOCIATE(ERR::TEX_NOT_8BIT_PRECISION, "Not 8-bit channel precision"); +ERROR_ASSOCIATE(ERR::TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. right-to-left"); +ERROR_ASSOCIATE(ERR::TEX_COMPRESSED, "Unsupported texture compression"); +ERROR_ASSOCIATE(WARN::TEX_INVALID_DATA, "Warning: invalid texel data encountered"); +ERROR_ASSOCIATE(ERR::TEX_INVALID_SIZE, "Texture size is incorrect"); +ERROR_ASSOCIATE(INFO::TEX_CODEC_CANNOT_HANDLE, "Texture codec cannot handle the given format"); //----------------------------------------------------------------------------- diff --git a/source/lib/res/res.cpp b/source/lib/res/res.cpp index b64732fb34..d153ceec9d 100644 --- a/source/lib/res/res.cpp +++ b/source/lib/res/res.cpp @@ -12,7 +12,5 @@ #include "res.h" -AT_STARTUP(\ - error_setDescription(ERR::RES_UNKNOWN_FORMAT, "Unknown file format");\ - error_setDescription(ERR::RES_INCOMPLETE_HEADER, "File header not completely read");\ -) +ERROR_ASSOCIATE(ERR::RES_UNKNOWN_FORMAT, "Unknown file format", -1); +ERROR_ASSOCIATE(ERR::RES_INCOMPLETE_HEADER, "File header not completely read", -1); diff --git a/source/lib/secure_crt.cpp b/source/lib/secure_crt.cpp index 75e7aed537..982a451d9e 100644 --- a/source/lib/secure_crt.cpp +++ b/source/lib/secure_crt.cpp @@ -19,9 +19,7 @@ // we were included from wsecure_crt.cpp; skip all stuff that // must only be done once. #ifndef WSECURE_CRT -AT_STARTUP(\ - error_setDescription(ERR::STRING_NOT_TERMINATED, "Invalid string (no 0 terminator found in buffer)")\ -) +ERROR_ASSOCIATE(ERR::STRING_NOT_TERMINATED, "Invalid string (no 0 terminator found in buffer)", -1); #endif diff --git a/source/lib/sysdep/cpu.cpp b/source/lib/sysdep/cpu.cpp index 7ea7c00237..c7fbd2bc91 100644 --- a/source/lib/sysdep/cpu.cpp +++ b/source/lib/sysdep/cpu.cpp @@ -26,12 +26,10 @@ #endif -AT_STARTUP(\ - error_setDescription(ERR::CPU_FEATURE_MISSING, "This CPU doesn't support a required feature");\ - error_setDescription(ERR::CPU_UNKNOWN_OPCODE, "Disassembly failed");\ - error_setDescription(ERR::CPU_UNKNOWN_VENDOR, "CPU vendor unknown");\ - error_setDescription(ERR::CPU_RESTRICTED_AFFINITY, "Cannot set desired CPU affinity");\ -) +ERROR_ASSOCIATE(ERR::CPU_FEATURE_MISSING, "This CPU doesn't support a required feature", -1); +ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_OPCODE, "Disassembly failed", -1); +ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_VENDOR, "CPU vendor unknown", -1); +ERROR_ASSOCIATE(ERR::CPU_RESTRICTED_AFFINITY, "Cannot set desired CPU affinity", -1); //----------------------------------------------------------------------------- diff --git a/source/lib/sysdep/win/delay_load.cpp b/source/lib/sysdep/win/delay_load.cpp index 2618fe8b12..b0211569c0 100644 --- a/source/lib/sysdep/win/delay_load.cpp +++ b/source/lib/sysdep/win/delay_load.cpp @@ -267,24 +267,6 @@ FLoadedAtPreferredAddress(PIMAGE_NT_HEADERS pinh, HMODULE hmod) { } -// Do the InterlockedExchange magic -// -#if CPU_IA32 - -#undef InterlockedExchangePointer -#define InterlockedExchangePointer(Target, Value) \ - (PVOID)(uintptr_t)InterlockedExchange((PLONG)(Target), (LONG)(uintptr_t)(Value)) - - -#if MSC_VERSION >= 1300 -typedef __w64 unsigned long *PULONG_PTR; -#else -typedef unsigned long *PULONG_PTR; -#endif - - -#endif - extern "C" FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd, FARPROC* ppfnIATEntry) { // Set up some data we use for the hook procs but also useful for diff --git a/source/lib/sysdep/win/mahaf.cpp b/source/lib/sysdep/win/mahaf.cpp index 43b9e4e6c1..44e19659e9 100644 --- a/source/lib/sysdep/win/mahaf.cpp +++ b/source/lib/sysdep/win/mahaf.cpp @@ -177,10 +177,19 @@ static void UninstallDriver() if(!hService) return; - BOOL ok; + // stop service SERVICE_STATUS serviceStatus; - ok = ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus); - WARN_IF_FALSE(ok); + if(!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) + { + // if the problem wasn't that the service is already stopped, + // something actually went wrong. + const DWORD err = GetLastError(); + if(err != ERROR_SERVICE_NOT_ACTIVE && err != ERROR_SERVICE_CANNOT_ACCEPT_CTRL) + debug_assert(0); + } + + // delete service + BOOL ok; ok = DeleteService(hService); WARN_IF_FALSE(ok); ok = CloseServiceHandle(hService); diff --git a/source/lib/sysdep/win/win.h b/source/lib/sysdep/win/win.h index db0802a3c1..aea6aa1491 100644 --- a/source/lib/sysdep/win/win.h +++ b/source/lib/sysdep/win/win.h @@ -99,6 +99,12 @@ typedef unsigned __int64 DWORDLONG; typedef DWORD ULONG_PTR; +#if MSC_VERSION >= 1300 +typedef __w64 unsigned long* PULONG_PTR; +#else +typedef unsigned long* PULONG_PTR; +#endif + typedef struct _MEMORYSTATUSEX { DWORD dwLength; @@ -317,4 +323,13 @@ enum DataKind DataIsConstant }; + + + +#if CPU_IA32 +// the official version causes pointer truncation warnings. +# undef InterlockedExchangePointer +# define InterlockedExchangePointer(Target, Value) (PVOID)(uintptr_t)InterlockedExchange((PLONG)(Target), (LONG)(uintptr_t)(Value)) +#endif + #endif // #ifndef INCLUDED_WIN diff --git a/source/lib/timer.h b/source/lib/timer.h index 964e0c260c..3de30ed417 100644 --- a/source/lib/timer.h +++ b/source/lib/timer.h @@ -97,7 +97,7 @@ typedef Timer::unit TimerUnit; // convenience // opaque - do not access its fields! // note: must be defined here because clients instantiate them; -// fields cannot be made private due to C compatibility requirement. +// fields cannot be made private due to POD requirement. struct TimerClient { TimerUnit sum; // total bill