diff -r 85863b89e38b -r a10ba529ae39 src/error.h --- a/src/error.h Sat May 23 00:33:23 2009 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ -#ifndef ERROR_H -#define ERROR_H - -/** - * @file - * - * Error-handling functions - */ -#include -#include - -/** - * The type used for error codes is an explicitly *unsigned* int, meaning that error codes themselves are positive. - * Negative error codes (as signed ints) also exist in some places, and they are just a negative err_t. - */ -typedef unsigned int err_t; - -/** - * Ways to interpret error_info.extra - */ -enum error_extra_types { - /** No extra info */ - ERR_EXTRA_NONE = 0, - - /** libc errno, using strerror() */ - ERR_EXTRA_ERRNO, - - /** libc resolver, using gai_strerror() */ - ERR_EXTRA_GAI, - - /** GnuTLS, using gnutls_strerror() */ - ERR_EXTRA_GNUTLS, - - /** Static error message string */ - ERR_EXTRA_STR, -}; - -/** - * List of defined error codes, organized mostly by function name - */ -enum error_code { - _ERR_INVALID = 0x000000, - - /** stdlib.h functions */ - _ERR_STDLIB = 0x000100, - ERR_CALLOC, - ERR_STRDUP, - ERR_SIGACTION, - ERR_ACCESS_READ, - - /** DNS resolver */ - _ERR_RESOLVER = 0x000200, - ERR_GETADDRINFO, - ERR_GETADDRINFO_EMPTY, - - /** socket/IO errors */ - _ERR_SOCK = 0x000300, - ERR_SOCKET, ///< socket(2) failed - ERR_CONNECT, ///< connect(2) error - either direct or async - ERR_READ, ///< read(2) error - will probably show up as an ERR_WRITE as well - ERR_WRITE, ///< write(2) error - data was unsent, will probably show up as an ERR_READ as well - ERR_WRITE_EOF, ///< write(2) gave EOF - zero bytes written - ERR_FCNTL, ///< fcntl(2) failed - ERR_CLOSE, ///< close(2) failed, some written data was probably not sent - ERR_GETSOCKOPT, ///< getsockopt(2) failed - ERR_OPEN, ///< open(2) failed - ERR_ACCEPT, ///< accept(2) failed - ERR_BIND, ///< bind(2) failed - ERR_LISTEN, ///< listen(2) failed - - /** @see sock_gnutls_error_code */ - _ERR_GNUTLS = 0x000400, - - /** Libevent errors */ - _ERR_LIBEVENT = 0x000500, - ERR_EVENT_NEW, - ERR_EVENT_ADD, - ERR_EVENT_DEL, - - /** Evsql errors */ - _ERR_EVSQL = 0x000600, - ERR_EVSQL_NEW_PQ, - ERR_EVSQL_QUERY_EXEC, - - /** irc_proto errors */ - _ERR_IRC_LINE = 0x000700, - ERR_LINE_TOO_LONG, - ERR_LINE_INVALID_TOKEN, - ERR_INVALID_NM, - ERR_INVALID_NICK_LENGTH, - - /** irc_conn errors */ - _ERR_IRC_CONN = 0x000800, - ERR_IRC_CONN_REGISTER_STATE, - ERR_IRC_CONN_QUIT_STATE, - - /** irc_net errors */ - _ERR_IRC_NET = 0x000900, - ERR_IRC_NET_INFO, - ERR_IRC_NET_STATE, - - /** @see module_error_code */ - _ERR_MODULE = 0x000a00, - - /** config errors */ - _ERR_CONFIG = 0x000b00, - ERR_CONFIG_NAME, ///< unknown option name - ERR_CONFIG_TYPE, ///< invalid value type for parameter - ERR_CONFIG_REQUIRED, ///< missing value for required parameter - ERR_CONFIG_VALUE, ///< invalid value - ERR_CONFIG_PARAMS, ///< invalid number of parameters - - /** lua errors */ - _ERR_LUA = 0x000c00, - ERR_LUA_MEM, - ERR_LUA_SYNTAX, - ERR_LUA_RUN, - ERR_LUA_ERR, - ERR_LUA_FILE, - - /** irc_chan errors */ - _ERR_IRC_CHAN = 0x000d00, - ERR_IRC_CHAN_STATE, - - /** pcre errors */ - _ERR_PCRE = 0x000e00, - ERR_PCRE_COMPILE, ///< pcre_compile: - ERR_PCRE_EXEC, ///< pcre_exec: - - /** str errors */ - _ERR_STR = 0x000f00, - - /** Transport errors */ - _ERR_TRANSPORT = 0x001000, - - /** General errors */ - _ERR_GENERAL = 0xffff00, - ERR_MISC, ///< general error - ERR_CMD_OPT, ///< invalid commandline option - ERR_UNKNOWN, - ERR_DUP_NAME, ///< duplicate name - ERR_EOF, ///< end of file - ERR_MEM, ///< memory allocation error - ERR_NOT_IMPLEMENTED, ///< function not implemented -}; - -/** - * Table of error descriptions - */ -struct error_desc { - /** The flat error code */ - err_t code; - - /** The short name */ - const char *name; - - /** How to interpret .extra */ - enum error_extra_types extra_type; -}; - -/** - * An error code and associated extra infos - */ -struct error_info { - /** - * The base error code. - * - * This is a signed int because we need to be able to manipulate negative errors codes as well. - */ - signed int code; - - union { - /** Additional detail info, usually some third-party error code, as defined by the code's ERR_EXTRA_* */ - int extra; - - /** Additional info, stored as a pointer to a static string (note how dangerous this is) */ - const char *extra_str; - }; -}; - -/** - * The public names - */ -typedef struct error_info error_t; - -/** - * Translate an err_t into a function name. - */ -const char *error_name (err_t code); - -/** - * Look up the error_desc for the given error code - */ -const struct error_desc* error_lookup (err_t code); - -/** - * Maximum length of error messages returned by error_msg (including NUL byte) - */ -#define ERROR_MSG_MAXLEN 1024 - -/** - * Translate an error_info into a message. - * - * This is returned as a pointer into a statically allocated buffer. It is not re-entrant. - */ -const char *error_msg (const error_t *err); - -/** - * Compare the given errors for equivalency - */ -bool error_cmp_eq (const error_t *a, const error_t *b); - -/** No error, evaulates as logical false */ -#define SUCCESS (0) - -/** Evaulates to error_info.code as lvalue */ -#define ERROR_CODE(err_info_ptr) ((err_info_ptr)->code) - -/** Evaulates to error_info.extra as lvalue */ -#define ERROR_EXTRA(err_info_ptr) ((err_info_ptr)->extra) - -/** Set error_info.code to SUCCESS, evaulates as zero */ -#define RESET_ERROR(err_info_ptr) ((err_info_ptr)->code = SUCCESS) - -/** Compare error_info.code != 0 */ -#define IS_ERROR(err_info_ptr) (!!(err_info_ptr)->code) - -/** Compare the err_code/err_extra for an err_info */ -#define MATCH_ERROR(err_info_ptr, err_code, err_extra) ((err_info_ptr)->code == (err_code) && (err_info_ptr)->extra == (err_extra)) - -/** Set error_info.code, but leave err_extra as-is. Evaluates to err_code */ -#define SET_ERROR(err_info_ptr, err_code) ((err_info_ptr)->code = (err_code)) - -/** Set error_info.code/extra. XXX: should evaluate to err_code */ -#define _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) (err_info_ptr)->code = (err_code); (err_info_ptr)->extra = (err_extra) -#define SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); } while (0) - -/** Set error_info.code to err_code, and .extra to errno. XXX: should evaulate to err_code */ -#define _SET_ERROR_ERRNO(err_info_ptr, err_code) _SET_ERROR_EXTRA(err_info_ptr, err_code, errno); -#define SET_ERROR_ERRNO(err_info_ptr, err_code) SET_ERROR_EXTRA(err_info_ptr, err_code, errno); - -/** - * Set error_info.code to err_code, and .extra_str to str. The given string pointer should remain valid while the error - * is being handled down-stack. - */ -#define _SET_ERROR_STR(err_info_ptr, err_code, err_str) (err_info_ptr)->code = (err_code); (err_info_ptr)->extra_str = (err_str) -#define SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); } while(0) - -/** Set error_info from another error_info. Evaluates to the new error_info */ -#define SET_ERROR_INFO(err_info_ptr, from_ptr) (*err_info_ptr = *from_ptr) - -/** Same as above, but also return err_code from func. XXX: use 'return SET_ERROR...' instead */ -#define RETURN_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); return (err_code); } while (0) -#define RETURN_SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); return (err_code); } while (0) -#define RETURN_SET_ERROR_ERRNO(err_info_ptr, err_code) do { _SET_ERROR_ERRNO(err_info_ptr, err_code); return (err_code); } while (0) -#define RETURN_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); return (from_ptr->code); } while (0) -#define RETURN_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); return (err_code); } while (0) - -/** Same as above, but also do a 'goto error' */ -#define JUMP_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); goto error; } while (0) -#define JUMP_SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); goto error; } while (0) -#define JUMP_SET_ERROR_ERRNO(err_info_ptr, err_code) do { _SET_ERROR_ERRNO(err_info_ptr, err_code); goto error; } while (0) -#define JUMP_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); goto error; } while (0) -#define JUMP_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); goto error; } while (0) - -/** - * Macro used to mark code segments that should never be executed (e.g. switch-default), kind of like assert - */ -#include -#define NOT_REACHED(val) abort() - -#endif