[mod.std.mumps] Proposal: changes to the Error Trap Task Group Proposal

hokey@plus5.UUCP (10/07/86)

There are several deficiencies in the proposed mechanism for handling
error traps.  It would be nice of these problems were handled before
a proposal was accepted by the MDC.

I perceive two mechanisms for specifying and error trap, and three mechanisms
for handling a trap.

When specifying a trap, one might want the new trap to be "remembered"
regardless of subsequent changes in the DO/XECUTE stack.  For example, one
might want to "DO INIT", where INIT specifies the error trap.  This trap
should *not* be cleared when the INIT subroutine returns!

Conversely, when entering a "new" program, one would not want any error traps
to be used after the current program passed control back to the invoker.  It
would seem "NEW $ETRAP" is in order.

Once an error condition occurs, there are three different ways a programmer
might want to trap the condition.

The first mechanism is to process the error one level at a time.  This is
especially useful when the NEW command has been used to "alter" the
environment, or when the execution path was determined by run-time data.

In the second mechanism, the programmer would want to "pop" all stack levels
back to where the error trap was explicitly set.  This is, I believe, the
mechanism used by DSM on the Vax.

The third mechanism is the one used, I believe, on some PDP-11 implementations.
Here, the stack is popped clean before the error trap is invoked.

We should be able to support as many of these mechanisms as possible.

For example, one should be able to have a program which wants remembered
traps, and the stack cleaned upon receipt of an error trap.  Should this
package call one which wants stacked traps, this behavior should be permitted.

The addition of three special variable should be sufficient to handle these
issues.

$EMODE is permitted to take two values: [NO]REMEMBER.  If $EMODE is NOREMEMBER,
a $ETRAP is "popped" whenever the DO/XECUTE stack is "shorter" than it was when
the $ETRAP was instantiated.  If $EMODE is REMEMBER, a $ETRAP is valid until
changed.

$STACKLEVEL is incremented with each new DO/XECUTE level, decremented as each
level is "popped".

The behavior of $ESTACK is determined by the value of $EMODE.  If $EMODE is
REMEMBER, the value of $ESTACK is incremented with each new DO/XECUTE level,
decremented as each level is "popped", and reset to zero whenever $ETRAP is
set.  If $EMODE is NOREMEMBER, $ESTACK is zero at a DO/XECUTE level where the
$ETRAP should be invoked, and one otherwise.

One would also have to permit "NEW $ETRAP".

Therefore:

    If one wanted to invoke error trapping on a "clean" stack, one would
    SET $EMODE=NOREMEMBER and begin the error trap utility with QUIT:$ESTACK .

    If one wanted to invoke error processing only at those levels where $ETRAP
    was explicitly set, one would SET $EMODE=REMEMBER and begin the error trap
    utility with QUIT:$ESTACK .

    If one wanted to catch all errors, one just traps errors.

The $STACKLEVEL special variable provides a way to uniquely "store" information
about an arbitrary execution level.

My next perceived shortcoming is with the method of declaring an error trap.
Rather than SET $ETRAP=<labelref> , I would rather SET $ETRAP=<mumps code> .
In this way, one could "control" the invocation of an error trap without
actually loading the error trap routine.  Additionally, it provides one
with the *possibility* of handling and analyzing certain errors without
concern over the ability to load the error trap utility.  Under this scheme,
the three cases described above become:

	SET $EMODE="NOREMEMBER",$ETRAP="QUIT:$ESTACK  G labelref"

	SET $EMODE="REMEMBER",$ETRAP="QUIT:$ESTACK  G labelref"

	SET $ETRAP="G labelref"

The full functionality of this mechanism is best realized when $ECODE is
changed as follows.

	$ECODE holds information about the last error condition encountered
	by the job.  The first colon piece of $EC contains comma-delimited
	strings which describe the error condition.  The first character of
	these strings is M, I, or U, for MDC- Implementor- or User-specified
	error conditions, respectively.

For example, assume the MDC decides certain error conditions are generally
classified into I/O errors, and defines the sequence "MIO" to handle these
conditions.  An arbitrary implementor might decide to add additional
information.  Thus, if a device were to go offline, $ECODE might contain the
string:

	,MIO,IIO,IOFFLINE,:Line Printer 6 offline:

Note the leading and trailing comma characters in the first colon piece.  This
format makes it very easy to determine the presence of an error code by using
the "contains" operator.

Hokey