Re: [AD] 4.3 error handling redux

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


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





Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/