[GRASS-dev] lib fn to convert int color number to RGB values?

Glynn Clements glynn at gclements.plus.com
Thu Jan 31 05:00:12 EST 2008


Ivan Shmakov wrote:

>  >> As lib fns, the one G_fatal_error() would need to change to
>  >> G_warning().  Or is it better to be silent and rely on the module
>  >> programmer to check the fn's return code?
> 
>  > If it's conceivable that the module will continue in the event of an
>  > error, the function should just return a status code.
> 
>  > If it's likely that the module is just going to call G_fatal_error()
>  > anyhow, the library function may as well call it itself, thereby
>  > providing a "infallible" interface (i.e. the function never fails; it
>  > either succeeds, or the process is no longer running so the failure
>  > is moot).
> 
> [...]
> 
>  > The former is only an advantage if there's a situation where a module
>  > doesn't just call G_fatal_error() when an invalid colour
>  > occurs. Given that invalid user input is usually a fatal error, I
>  > can't immediately think of a situation where you might get an invalid
>  > colour string without it resulting in a fatal error.
> 
> 	Did you consider the use of the function from within a GUI
> 	application?  Hardly calling exit () on incorrect input from the
> 	user is a friendly behaviour for a GUI application.

GRASS simply doesn't work in such a context. One more function doesn't
make any difference unless you're going to fix the thousands that
already behave this way.

BTW, we seem to have had this discussion at least once a year for as
long as I have been subscribed to these lists (~7 years).

> 	Actually, I see calling G_fatal_error () from a library function
> 	to imply such a marginal improvement on the caller's side, so
> 	I'd not bother with this issue at all and rather never call a
> 	function implying exit () from the library code (with the
> 	exception for the functions clearly intended to call exit (),
> 	or, may be, for the out-of-memory conditions.)
> 
> 	As an additional benefit, it allows the libraries to be used
> 	from high-level languages (like Python or Scheme.)  Calling exit
> 	() behind the back of the language implementation (or the
> 	interface author) doesn't sound very friendly, too.

If we were writing GRASS from scratch, that would be a reasonable
argument. But we aren't writing GRASS from scratch.

Apart from calling exit() via G_fatal_error()[1], there are some other
obstacles to making the GRASS libraries behave like normal libraries. 
The most significant is the amount of static data which cannot be
multiply instantiated, most of which is initialised at first use and
often cannot be reset or otherwise modified thereafter.

The GRASS libraries are fundamentally designed to be used in
"one-shot" modules. Errors are handled by printing a message then
exiting. Variables are either initialised at startup from the .data
and .bss segments or are initialised upon first use. Memory doesn't
get explicitly de-allocated, as the operating system will do that when
the module terminates.

Making library functions suitable for use in persistent applications
amounts to a complete re-write. If you're interested in taking that
route, please let us know when you've finished.

[1] You can use G_set_error_routine() to install an error handler, but
the handler mustn't return (or else exit() will still get called). The
reason is that code which calls G_fatal_error() doesn't expect it to
return.

Calling G_fatal_error() solves any and all problems without any
further effort from the caller. Normally, this is achieved by calling
exit(), but if you want to supply your own error handler which takes a
different approach to solving any problem which may have occurred, you
are free to do so.

However, the handler must solve all problems itself. You can't just
push the responsibility onto the ~650 different files which call that
function.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list