When a condition trap is currently enabled (ON) and the specified
condition occurs, instead of the usual flow of control, a CALL trapname or SIGNAL trapname instruction is processed automatically.
You can specify the trapname after the NAME subkeyword of
the CALL ON or SIGNAL ON instruction. If you do not specify a trapname, the name of the condition itself (ERROR, FAILURE, HALT, NOTREADY,
NOVALUE, or SYNTAX) is used.
For example, the instruction call on error enables the
condition trap for the ERROR condition. If the condition occurred,
then a call to the routine identified by the name ERROR is made. The
instruction call on error name commanderror would enable
the trap and call the routine COMMANDERROR if the condition occurred.
The sequence of events, after a condition has been trapped, varies
depending on whether a SIGNAL or CALL is processed:
- If the action taken is a SIGNAL, execution of the current instruction
ceases immediately, the condition is disabled (set to OFF), and the
SIGNAL takes place in exactly the same way as usual (see page SIGNAL).
If any new occurrence of the
condition is to be trapped, a new CALL ON or SIGNAL ON instruction
for the condition is required to re-enable it when the label is reached.
For example, if SIGNAL ON SYNTAX is enabled when a SYNTAX condition
occurs, then, if the SIGNAL ON SYNTAX label name is not found, a usual
syntax error termination occurs.
- If the action taken is a CALL (which can occur only at a clause
boundary), the CALL is made in the usual way (see page CALL) except that the call does not affect
the special variable RESULT. If the routine should RETURN any data,
then the returned character string is ignored.
Because these conditions
(ERROR, FAILURE, and HALT) can arise during execution of an INTERPRET
instruction, execution of the INTERPRET may be interrupted and later
resumed if CALL ON was used.
As the condition is raised, and
before the CALL is made, the condition trap is put into a delayed
state. This state persists until the RETURN from the CALL, or until
an explicit CALL (or SIGNAL) ON (or OFF) is made for the condition.
This delayed state prevents a premature condition trap at the start
of the routine called to process a condition trap. When a condition
trap is in the delayed state it remains enabled, but if the condition
is raised again, it is either ignored (for ERROR, FAILURE, or NOTREADY)
or (for the other conditions) any action (including the updating of
the condition information) is delayed until one of the following events
occurs:
- A CALL ON or SIGNAL ON, for the delayed condition, is processed.
In this case a CALL or SIGNAL takes place immediately after the new
CALL ON or SIGNAL ON instruction has been processed.
- A CALL OFF or SIGNAL OFF, for the delayed condition, is processed.
In this case the condition trap is disabled and the default action
for the condition occurs at the end of the CALL OFF or SIGNAL OFF
instruction.
- A RETURN is made from the subroutine. In this case the condition
trap is no longer delayed and the subroutine is called again immediately.
On RETURN from the CALL, the original flow of execution
is resumed (that is, the flow is not affected by the CALL).
Note: - You must be extra careful when you write a syntax trap routine.
Where possible, put the routine near the beginning of the program.
This is necessary because the trap routine label might not be found
if there are certain scanning errors, such as a missing ending comment.
Also, the trap routine should not contain any statements that might
cause more of the program in error to be scanned. Examples of this
are calls to built-in functions with no quotation marks around the
name. If the built-in function name is in uppercase and is enclosed
in quotation marks, REXX goes directly to the function, rather than
searching for an internal label.
- In all cases, the condition is raised immediately upon detection.
If SIGNAL ON traps the condition, the current instruction is ended,
if necessary. Therefore, the instruction during which an event occurs
may be only partly processed. For example, if SYNTAX is raised during
the evaluation of the expression in an assignment, the assignment
does not take place. Note that the CALL for ERROR, FAILURE, HALT,
and NOTREADY traps can occur only at clause boundaries. If these conditions
arise in the middle of an INTERPRET instruction, execution of INTERPRET
may be interrupted and later resumed. Similarly, other instructions,
for example, DO or SELECT, may be temporarily interrupted by a CALL
at a clause boundary.
- The state (ON, OFF, or DELAY, and any trapname)
of each condition trap is saved on entry to a subroutine and is then
restored on RETURN. This means that CALL ON, CALL OFF, SIGNAL ON,
and SIGNAL OFF can be used in a subroutine without affecting the conditions
set up by the caller. See the CALL instruction (page CALL) for details of other information that
is saved during a subroutine call.
- The state of condition traps is not affected when an external
routine is called by a CALL, even if the external routine is a REXX
program. On entry to any REXX program, all condition traps have an
initial setting of OFF.
- While user input is processed during interactive tracing, all
condition traps are temporarily set OFF. This prevents any unexpected
transfer of control—for example, should the user accidentally
use an uninitialized variable while SIGNAL ON NOVALUE is active. For
the same reason, a syntax error during interactive tracing does not
cause exit from the program but is trapped specially and then ignored
after a message is given.
- The system interface detects certain execution errors either before
execution of the program starts or after the program has ended. SIGNAL
ON SYNTAX cannot trap these errors.
Note that a
label is a clause consisting
of a single symbol followed by a colon. Any number of successive clauses
can be labels; therefore, multiple labels are allowed before another
type of clause.