#include <define.h> #include <error_ctx.h> typedef VOID *error_ctx; error_ctx DEFAULT_ERROR_CTX; /* error_ctx==0 results in default error explanation */ /* str==0 causes error_explain_error to do nothing */ int error_explain_error(ctx, err, str) error_ctx ctx; /* IN, may be 0 */ int err; /* IN */ char str[ERROR_MESSAGE_LENGTH]; /* OUT, may be 0 */ /* error_ctx==0 causes error_log_error to do nothing */ int error_log_error(ctx, err) error_ctx ctx; /* IN, may be 0 */ int err; /* IN */ /* error_ctx==0 causes error_log_printf to do nothing */ int error_log_printf(ctx, err, format /* , ... */ ) error_ctx ctx; /* IN, may be 0 */ int module_num; /* IN */ char *format; /* IN, may be 0 */ /* ... */ /* IN */ /* call with ERROR_MODULE(error_num) to disable/enable logging for a * specific module */ int error_disable_module_error_logging(module_num) int module_num; /* IN */ int error_enable_module_error_logging(module_num) int module_num; /* IN */ /* write_func==0 prevents logging */ /* write_func() returns the number of bytes written, or -1 for error */ int create_error_ctx(ctx, log) error_ctx *ctx; /* IN */ int (*write_func) PROTO_LIST((VOID *write_handle, char *buf, int nbyte)), /* IN, may be 0 */ VOID *write_handle /* IN */ int delete_error_ctx(ctx) error_ctx *ctx; /* IN */ int modify_error_ctx(ctx, modify, /* , ... */ ) PROTO_LIST(( error_ctx ctx, /* IN */ int modify, /* IN */ /* ... */ /* IN */ #define ERROR_CTX_MODIFY_ALL_LOGGING_DISABLED 0 /* int bool */ int query_error_ctx(ctx, query, /* , ... */ ) PROTO_LIST(( error_ctx ctx, /* IN */ int query, /* IN */ /* ... */ /* OUT */ #define ERROR_CTX_QUERY_ALL_LOGGING_DISABLED 0 /* int *bool */ #define ERROR_CTX_DEFAULT_ALL_LOGGING_DISABLED 0
error_ctx
is an abstraction used for reporting errors. The mechanism is used to convert return values
to textual error descriptions, to log these descriptions, and to provide global contextual error state in a
multithreaded environment. In the event that the default error_ctx
,
DEFAULT_ERROR_CTX
, is not used, each thread is
expected to use a unique error_ctx
. create_error_ctx()
creates the error_ctx. An error_ctx
is not usable prior to a call to
create_error_ctx()
.
delete_error_ctx()
deletes the error_ctx. An error_ctx
is no longer usable following a call to
delete_error_ctx()
.
error_explain_error()
converts a numeric return value to a textual error description.
error_log_error()
logs a textual description of an error code to the output stream associated with
the provided error_ctx
. A default error_ctx
, called DEFAULT_ERROR_CTX
, can be used to log
errors to stderr.
error_log_printf()
can be used to log arbitrary textual descriptions to the output stream associated with
the provided error_ctx
. A default error_ctx
, called DEFAULT_ERROR_CTX
, can be used to log
errors to stderr.
modify_error_ctx
and query_error_ctx
is
used to modify the behavior of an error_ctx
. The following
options are available:
Two macros, ERROR_MODULE()
and ERROR_NUMBER()
convert between a numeric return value and
values representing the module that generated the error and the module-specific error number.
error_explain_error()
, passing in a 0 error_ctx
is equivalent to passing in the default
error_ctx
(DEFAULT_ERROR_CTX
), the result being that no additional contextual information is
provided to the error-reporting routine. Passing in a 0 str
parameter causes
error_explain_error()
to do nothing. For error_log_error()
, passing in a 0 error_ctx
causes it to do nothing.
For error_log_printf()
, passing in a 0 error_ctx
or format
causes it to do nothing.
For create_error_ctx()
, passing in a 0 log
parameter disables logging for that error_ctx
.
create_error_ctx()
and delete_error_ctx()
return NO_ERROR
. On failure,
create_error_ctx()
returns ERROR_ERR_BAD_PARAMETER
or ERROR_ERR_NO_MEMORY
. On
failure, CACHE_delete()
returns ERROR_ERR_BAD_PARAMETER
. The error handling routines error_explain_error()
, error_log_error()
, and
error_reset_error()
always return NO_ERROR
, independent of their error status, in order to
prevent errors from generating additional errors.
See Return Values for descriptions of individual error codes.
simple_example() { int status; /* numeric return value */ int module; /* the module in which the error occured */ status = some_setref_function(); if (status != NO_ERROR) { module = ERROR_MODULE(status); /* print arbitrary data to the log */ error_log_printf(DEFAULT_ERROR_CTX, module, "Something bad happened"); /* log the error */ error_log_error(DEFAULT_ERROR_CTX, status); } /* ... */ } another_simple_example() { int status; /* numeric return value */ UCHAR str[ERROR_MESSAGE_LENGTH]; status = some_setref_function(); if (status != NO_ERROR) { /* obtain an explaination of the error */ error_explain_error(DEFAULT_ERROR_CTX, status, str); /* display the explanation */ printf("error message: %s\n", str); } /* ... */ } int write_log(write_handle, buf, nbyte) VOID *write_handle; char *buf; int nbyte; { return fwrite(buf, 1, nbyte, (FILE*)write_handle); } complex_example() { error_ctx ectx; /* per-thread error_ctx */ int status; /* numeric return value */ FILE *log; /* thread-specific error log */ log = fopen(thread_error_log(), "a"); assert(log != 0); status = create_error_ctx(&ectx, write_log, (VOID*)log); assert(status == NO_ERROR); status = some_setref_function(); if (status != NO_ERROR) { /* log the error */ error_log_error(ectx, status); /* display error information to the user */ fprintf(stderr,"error number %d in module %d\n", ERROR_NUMER(status), ERROR_MODULE(status)); } /* ... */ }