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

Glynn Clements glynn at gclements.plus.com
Mon Apr 23 08:08:54 EDT 2012


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