PORTABLE EXCEPTIONS IN C
by Bernhard Tschirren


TRY CONSTRUCT
try..catch Catches thrown exceptions.
try...finally Executes a piece of code even if an exception was thrown.

try...catch
prototype:
try
  {
  [...]
  }
catch(exception)
  {
  case (exception->code)
    {
    case EXCEPTION_1:
      [...]
      break;

    [...]

    default:
      rethrow();
    }
  }
end_catch;
          
description: If the code in the try block (between try and catch) throws an exception, the program instantly jumps to the catch block (between catch and end_catch). Here, the switch() statement filters out specific exceptions that we are interrested in. All the other exceptions are handed to the outer try block using rethrow(). NOTE: It is very important that all unapplicable exceptions are rethrown, otherwise they are considered "handled"!
see also: throw
rethrow
try...finally

try...finally
prototype:
try
  {
  [...]
  }
finally
  {
  [...]
  }
end_finally;
          
description: If the code in the try block (between try and finally) throws an exception, the program instantly jumps to the finally block (between finally and end_finally). If no exceptions are thrown, the finally block is still executed. In other words, the finally block is guaranteed to be executed regardless of any exceptions thrown in the try block. This is usually used for resource deallocation. NOTE: Any exception thrown in the try block is handed over to the outer try..catch block after executing the finally block.
see also: throw
exception_thrown
try...catch


FUNCTIONS
exceptions_init Initialises the exception library.
exceptions_done Finalises the exception library.
add_signal_exception Causes the specified signal to throw an exception whenever it occurs.
remove_signal_exception Stops the specified signal from throwing an exception.
new_exception Returns a pointer to an exception suitable to pass into throw().
throw Throws the given exception.
rethrow Rethrows the current exception.
exception_thrown Returns 1 (TRUE) if an exception was thrown, otherwise it returns 0 (FALSE).
default_catch A default exception handler which can be used in the catch block.

exceptions_init
prototype: void exceptions_init(int *argc, char **argv[]);
description: Initialises the exception library. It should be the first function an application calls. This function also registers signal to exception conversions using add_signal_exception(). All signals that would usually cause the program to exit are converted to exceptions. This function MAY modify the program arguments in the future!
see also: exceptions_done
add_signal_exception

exceptions_done
prototype: void exceptions_done(void);
description: Finalises the exception library. This should be the last thing called by the application. If HAVE_ATEXIT is defined, this function is called automatically whenever the program terminates prematurely (eg: by a call to exit()).
see also: exceptions_init
HAVE_ATEXIT

add_signal_exception
prototype: void add_signal_exception(int sig);
description: Causes the specified signal (sig) to throw an exception whenever it occurs. NOTE: The exception thrown will have a code equal to SIGNAL_EXCEPTION(sig).
see also: remove_signal_exception
SIGNAL_EXCEPTION

remove_signal_exception
prototype: void remove_signal_exception(int sig);
description: Stops the specified signal (sig) from throwing an exception. If you want to add your own signal handlers, you must call this function to disable the relevant signal to exception conversions.
see also: add_signal_exception

new_exception
prototype: EXCEPTION *new_exception(int code, const void *data, const char *format, ...);
description: Returns a pointer to an exception suitable to pass into throw(). The (code) specifies the exception code. (data) can point to anything - it is not used by this exception library, however it is there if the programmer wishes to pass additional information to the exception handler. The format parameter works just like printf(). NOTE: This function always returns a pointer to the same memory address, therefore you cannot perform multiple calls to new_exception() thinking that it will allocate memory for each exception.
see also: throw
USER_EXCEPTION
SIGNAL_EXCEPTION
ERRNO_EXCEPTION

throw
prototype: void throw(EXCEPTION *exception);
description: Throws the given exception. The process is restored to the state stored in the current try context, then the "finally" or "catch" block is executed.
see also: new_exception
try...

rethrow
prototype: void rethrow(void);
description: Rethrows the current exception. In essence, this passes the exception to the "outer" try block. This function is obviously only valid once an exception has occurred - inside the "catch" part of the try block.
see also: throw
try...catch

exception_thrown
prototype: int exception_thrown(void);
description: Returns 1 (TRUE) if an exception was thrown, otherwise it returns 0 (FALSE). This function is only valid inside the "finally" part of a try block.
see also: throw
try...finally

default_catch
prototype: void default_catch(EXCEPTION *exception);
description: A default exception handler which can be used in the "catch" block. It simply prints the exception details to stderr. It does NOT exit the program, nor does it rethrow() the exception.
see also: try...catch
rethrow


MACROS
USER_EXCEPTION Converts any positive integer into an exception code.
SIGNAL_EXCEPTION Converts a signal number into an exception code.
ERRNO_EXCEPTION Converts an errno number into an exception code.

USER_EXCEPTION
prototype: #define USER_EXCEPTION(num)
description: Converts any positive integer into an exception code.
see also: SIGNAL_EXCEPTION
ERRNO_EXCEPTION

SIGNAL_EXCEPTION
prototype: #define SIGNAL_EXCEPTION(sig)
description: Converts a signal number into an exception code.
see also: USER_EXCEPTION
ERRNO_EXCEPTION

ERRNO_EXCEPTION
prototype: #define ERRNO_EXCEPTION(errno)
description: Converts an errno number into an exception code.
see also: USER_EXCEPTION
SIGNAL_EXCEPTION