RESET/SETEXIT - non-local goto.

Alternate Entry Name: .RESET/.SETEX

Usage:

B:
   status = setexit( [signature] );
   ...
   reset( [signature] );
/* C users use "setjmp" and "longjmp" */

Where:

signature
is some constant with which to associate the call. If "signature" is not given, it defaults to zero.
status
is zero if SETEXIT is called directly and -1 if it is called indirectly through a RESET.

Description:

SETEXIT and RESET are intended for situations in which it is necessary to "pop out" of many levels of nesting when an error occurs, yet inconvenient to let an error status be percolated back through all the calling functions.

SETEXIT causes current state information to be saved and placed on a pushdown stack associated with "signature". When called directly, SETEXIT returns zero.

A call to RESET causes the topmost state information on the stack associated with "signature" to be removed from the stack and restored so that the program is in a previous state. It then arranges things so that the program appears to return from the SETEXIT that saved the state, but with a status of -1.

If there is no information for a given signature, RESET returns directly. It also returns directly if returning through the SETEXIT would result in going down in the level of nesting, rather than up. That is, you can't call a routine which does a SETEXIT and then RESET back into it when it returns.

Normally, it should be considered a fatal error if RESET returns directly.

The fact that SETEXIT returns zero if called directly and -1 when called via a RESET allows you to use a construct such as

if( setexit() ){
      /* error handling routine */
      }
/* normal processing */

If it is desired to have SETEXIT restack the state after each RESET, the following construct is suggested.

while( setexit() ){
      /* error handling code */
}
/* normal processing */

If a function in which SETEXIT is called returns, the state saved for that SETEXIT is released, so it will be less easy to do an inappropriate RESET.

Copyright © 1996, Thinkage Ltd.