Re: [AD] 4.3 error handling redux |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
- To: Coordination of admins/developers of the game programming library Allegro <alleg-developers@xxxxxxxxxx>
- Subject: Re: [AD] 4.3 error handling redux
- From: Elias Pschernig <elias@xxxxxxxxxx>
- Date: Thu, 27 Jul 2006 10:34:25 +0200
On Tue, 2006-07-25 at 23:40 -0700, Chris wrote:
> Here's another attempt at an error handling API. Since setjmp/longjmp won't
> work, and I can't think of any other method to jump out of a user-defined
> block, I just went with callbacks. It comes with three callbacks,
> AL_ERROR_ABORT (default), AL_ERROR_WARN, and AL_ERROR_IGNORE. The user can
> supply their own handler if they wish, and use the function
> al_error_set_handler (any consensus on function name conventions yet?).
> al_error is used to retrieve the last error code, along with optionally
> grabbing a descriptive string of the problem. Getting the error with that
> function will clear it. al_error_set is exposed because some user error
> handlers and/or addons may want to check the error themselves, before passing
> it back down to user code.
>
> The only thing I'm not sure of is what to do with AL_NO_ERROR. OpenAL defines
> this for itself, but I'm not sure what else to use.
>
> The code...
>
> #include <signal.h>
> #include <stdio.h>
>
> /* public */
> typedef enum {
> AL_NO_ERROR = 0,
> AL_INVALID_PARAM = 1,
> AL_INVALID_OBJECT = 2,
>
> AL_GENERIC_ERROR = 255
> } AL_ERROR_ENUM;
>
> AL_ERROR_ENUM al_error(const char **str);
> void al_error_set(AL_ERROR_ENUM code, const char *str);
> void al_error_set_handler(void (*func)());
>
> void AL_ERROR_ABORT(void);
> void AL_ERROR_WARN(void);
> #define AL_ERROR_IGNORE NULL
>
> /* source only */
> static __thread AL_ERROR_ENUM _al_errcode;
> static __thread const char *_al_errstr;
>
> static __thread void (*_allegro_error)(void) = AL_ERROR_ABORT;
>
>
> void al_error_set_handler(void (*func)(void))
> {
> _allegro_error = func;
> }
>
>
> void AL_ERROR_ABORT(void)
> {
> const char *str;
> AL_ERROR_ENUM code;
>
> code = al_error(&str);
>
> fprintf(stderr, "An error occured!\nCode: %d\nMessage: %s\nAborting\n",
> code, str);
> abort();
> }
>
> void AL_ERROR_WARN(void)
> {
> const char *str;
> AL_ERROR_ENUM code;
>
> code = al_error(&str);
> fprintf(stderr, "An error occured!\nCode: %d\nMessage: %s\n", code, str);
>
> al_error_set(code, str);
> }
>
> void al_error_set(AL_ERROR_ENUM code, const char *str)
> {
> _al_errcode = code;
> if(!str)
> {
> switch(code)
> {
> #define CASE(x) case x: _al_errstr = #x; break
> CASE(AL_NO_ERROR);
> CASE(AL_INVALID_PARAM);
> CASE(AL_INVALID_OBJECT);
> CASE(AL_GENERIC_ERROR);
> #undef CASE
> default:
> _al_errstr = "Unknown error";
> break;
> }
> }
> else
> _al_errstr = str;
>
> if(_allegro_error)
> _allegro_error();
> }
>
> AL_ERROR_ENUM al_error(const char **str)
> {
> AL_ERROR_ENUM ret = _al_errcode;
> if(str)
> *str = _al_errstr;
>
> _al_errcode = AL_NO_ERROR;
> _al_errstr = NULL;
>
> return ret;
> }
>
I like it. Well, some minor things:
AL_ERROR_ABORT is not needed I think. (Is there any place in 4.2 that
would abort the program? Certainly the user should decided that.)
al_error_set should probably accept printf style parameters, it will
make it much easier to have meaningful error messages.
--
Elias Pschernig