[GRASS-dev] Emitting a Python exception instead of calling exit in GRASS

Sören Gebbert soerengebbert at googlemail.com
Tue Apr 24 04:42:45 EDT 2012


Hi Glynn,
many thanks for your feedback.
I seems that i still have no idea how the stack/heap works ... but i
am willingly to learn.
Anyway, i would like to continue this discussion using the trac ticket
system [1].
My suggestion is to generate wrapper functions around fatal error
effected library functions automatically.

Best regards
Soeren

[1] http://trac.osgeo.org/grass/ticket/1646

2012/4/23 Glynn Clements <glynn at gclements.plus.com>:
>
> Sören Gebbert wrote:
>
>> while thinking about a high level Python interface based on the low
>> level ctypes interface a question raised in my mind:
>>
>> Is it possible to raise a Python exception instead of calling exit in
>> case of a fatal error when using ctypes wrapped GRASS library
>> functions? So the calling module can gently exit, closing open
>> database connections and so on?
>
> Yes, but you would have to wrap each function individually.
>
>> In the vtk-grass-bridge i am using setjmp/longjmp to shut down the
>> calling module gently in case of a fatall error. Does anybody know how
>> to do something similar with exceptions in the ctypes interface?
>> Something like a TRY/EXCEPT implementation in libgis using
>> setjmp/longjmp?
>
> You can't separate the "try" from its body. The best you can do at a
> library level is to provide a wrapper, e.g.:
>
>        static jmp_buf jbuf;
>
>        static void error_handler(void *arg)
>        {
>            longjmp(jbuf, 1);
>        }
>
>        int call_with_catch(void (*func)(void *), void *arg)
>        {
>            if (setjmp(jbuf) == 0) {
>                G_add_error_handler(error_handler, NULL);
>                (*func)(arg);
>                G_remove_error_handler(error_handler, NULL);
>                return 0;
>            }
>            else {
>                G_remove_error_handler(error_handler, NULL);
>                return -1;
>            }
>        }
>
>> Untested and maybe wrong Example:
>
>> int TRY(){
>>     return !setjmp(stack_buffer);
>> }
>
> You can't wrap setjmp within another function; the jmp_buf becomes
> invalid once you return from the function in which setjmp was
> "called". Also, setjmp() may only be used in specific contexts (7.13):
>
>       [#4] An invocation of the setjmp macro shall appear only  in
>       one of the following contexts:
>
>         -- the  entire  controlling  expression  of a selection or
>            iteration statement;
>
>         -- one operand of a relational or equality  operator  with
>            the  other operand an integer constant expression, with
>            the resulting expression being the  entire  controlling
>            expression of a selection or iteration statement;
>
>         -- the  operand  of  a unary ! operator with the resulting
>            expression being the entire controlling expression of a
>            selection or iteration statement; or
>
>         -- the   entire  expression  of  an  expression  statement
>            (possibly cast to void).
>
>       [#5] If the invocation appears in  any  other  context,  the
>       behavior is undefined.
>
> --
> Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list