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