%
%  The Regina Rexx Interpreter
%  Copyright (C) 1992-1994  Anders Christensen <anders@pvv.unit.no>
%


\chapter{Conditions}
\label{ch:conditions}


\begin{it}
In this chapter, the {\rexx} concept of ``conditions'' is described.
Conditions allow the programmer to handle abnormal control flow, and
enable him to assign special pieces of {\rexx} code to be executed in
case of certain incidences.
\begin{itemize}
\item
   In the first section the concept of conditions is explained.

\item
   Then, there is a description of how a standard condition in {\rexx}
   would work, if it existed.

\item
   In the third section, all the existing conditions in {\rexx} are
   presented, and the differences compared to the standard condition
   described in the previous section are listed.

\item
   The fourth sections contains a collections of random notes on the
   conditions in {\rexx}.

\item
   The last section describes differences, extensions and peculiarities
   in {\regina} on the of subject conditions, and the lists specific
   behavior.
\end{itemize}
\end{it}


\section{What are Conditions}

In this section, the concept of ``conditions'' are explained: What
they are, how they work, and what they mean in programming.



\subsection{What Do We Need Conditions for?}



\subsection{Terminology}

First, let's look at the terminology used in this chapter. If you
don't get a thorough understanding of these terms, you will probably not
understand much of what is said in the rest of this chapter.

\begin{description}
\item[Incident:]
   A situation, external or internal to the interpreter, which it is
   required to respond to in certain predefined manners. The
   interpreter recognizes incidents of several different types. The
   incident will often have a character of ``suddenness'', and will
   also be independent of the normal control flow.

\item[Event:] 
   Data Structure describing one incident, used as a descriptor
   to the incident itself.

\item[Condition:]
   Names the {\rexx} concept that is equivalent to the incident.

\item[Raise a Condition:]
   The action of transforming the information about an incident into
   an event. This is done after the interpreter senses the condition.
   Also includes deciding whether to ignore or produce an event.

\item[Handle a Condition:]
   The act of executing some predefined actions as a response to the
   event generated when a condition was raised. 

\item[(Condition) Trap:]
   Data Structure containing information about how to handle a
   condition.

\item[(Trap) State:]
   Part of the condition trap.

\item[(Condition) Handler:]
   Part of the condition trap, which points to a piece of {\rexx} code
   which is to be used to handle the condition.

\item[(Trap) Method:]
   Part of the condition trap, which defined how the condition handler
   is to be invoked to handle the condition.

\item[Trigger a Trap:]
   The action of invoking a condition handler by the method specified
   by the trap method, in order to handle a condition.

\item[Trap a Condition:]
   Short of trigger a trap for a particular condition. 

\item[Current Trapped Condition:]
   The condition currently being handled. This is the same as the most
   recent trapped condition on this or higher procedure level. 

\item[(Pending) Event Queue:]
   Data Structure storing zero or more events in a specific order.
   There are only one event queue. The event queue contains events of
   all condition types, which have been raised, but not yet handled.

\item[Default-Action:]
   The predefined default way of handling a condition, taken if the
   trap state for the condition raised is {\tt OFF}.

\item[Delay-Action:]
   The predefined default action taken when a condition is raised, and
   the trap state is {\tt DELAY}.
\end{description}




\section{The Mythical Standard Condition}

{\rexx} Language Level 4.00 has six different conditions. However, each
of these is a special case of a mythical, non-existing, standard
condition. In order to better understand the real conditions, we start
by explaining how a standard condition work.

In the examples below, we will call our non-existing standard
condition {\tt MYTH}. Note that these examples will not be executable
on any {\rexx} implementation.






\subsection{Information Regarding Conditions (data structures)}

There are mainly five conceptual data structures involved in
conditions.

\begin{description}
\item[Event queue.]
   There is one interpreter-wide queue of pending conditions. Raising a
   condition is identical to adding information about the condition to
   this queue (FIFO).  The order of the queue is the same order in
   which the conditions are to be handled.

   Every entry in the queue of pending conditions contains some
   information about the event: the line number of the {\rexx} script
   when the condition was raised, a descriptive text and the condition
   type. 

\item[Default-Action.]
   To each, there exists information about the default-action to take
   if this condition is raised but the trap is in state {\tt OFF}.
   This is called the ``default-action''. The standard default-action
   is to ignore the condition, while some conditions may abort the
   execution.

\item[Delay-Action.]
   Each condition will also have delay-action, which tells what to do
   if the condition is raised when condition trap is in state {\tt
   DELAY}. The standard delay-action is to queue the condition in the
   queue of pending conditions, while some conditions may ignore it.

\item[Condition traps.]
   For each condition there is a trap which contains three pieces of
   status information: the state; the handler; and the method. The
   state can be {\tt ON}, {\tt OFF} or {\tt DELAY}.

   The handler names the {\rexx} label in the start of the {\rexx}
   code to handle the event. The method can be either {\tt SIGNAL} or
   {\tt CALL}, and denotes the method in which the condition is to be
   handled. If the state is {\tt OFF}, then neither handler nor method
   is defined.

\item[Current Trapped Condition.]
   This is the most recently handled condition, and is set whenever a
   trap is triggered. It contains information about method, which
   condition, and a context-dependent description. In fact, the
   information in the current trapped condition is the same
   information that was originally put into the pending event queue.
\end{description}

Note that the event queue is a data structure connected to the
interpreter itself. You operate on the same event queue, independent
of subroutines, even external ones. On the other hand, the condition
traps and the current trapped condition are data structures connected
to each single routine. When a new routine is called, it will get its
own condition traps and a current trapped condition. For internal
routines, the initial values will be the same values as those of the
caller. For external routines, the values are the defaults.

The initial value for the event queue is to be empty.  The
default-action and the delay-action are static information, and will
always retain their values during execution. The initial values for
the condition traps are that they are all in state {\tt OFF}. The
initial value for the current trapped condition is that all information
is set to the nullstring to signalize that no condition is currently
being trapped.




\subsection{How to Set up a Condition Trap}

How do you set the information in a condition trap? You do it with a
{\tt SIGNAL} or {\tt CALL} clause, with the {\tt ON} or {\tt OFF}
subkeyword. Remember that a condition trap contain three pieces of
information? Here are the rules for how to set them:
\begin{itemize}
\item
   To set the trap method, use either {\tt SIGNAL} or {\tt CALL} as
   keyword.

\item
   To set state to {\tt ON} or {\tt OFF}, use the appropriate
   subkeyword in the clause. Note that there is no clause or function
   in {\rexx}, capable of setting the state of a trap to {\tt DELAY}.

\item
   To set the condition handler, append the term ``{\tt NAME {\it
   handler}}'' to the command. Note that this term is only legal if
   you are setting the state to {\tt ON}; you can not specify a
   handler when setting the state to {\tt OFF}.
\end{itemize}

The trap is said to be ``enabled'' when the state is either {\tt ON}
or {\tt DELAY}, and ``disabled'' when the state is {\tt OFF}.  Note
that neither the event queue, nor the current trapped condition can be
set explicitly by {\rexx} clauses.  They can only be set as a result
of incidents, when raising and trapping conditions.

It sounds very theoretical, doesn't it?  Look at the
following examples, which sets the trap {\tt MYTH}:

\begin{quote}
   {\tt /* 1 */ SIGNAL ON MYTH NAME TRAP\_IT}\\
   {\tt /* 2 */ SIGNAL OFF MYTH}\\
   {\tt /* 3 */ CALL ON MYTH NAME MYTH\_TRAP}\\
   {\tt /* 4 */ CALL ON MYTH}\\
   {\tt /* 5 */ CALL OFF MYTH}
\end{quote}

Line 1 sets state to {\tt ON}, method to {\tt SIGNAL} and handler to
{\tt TRAP\_IT}. Line 2 sets state to {\tt OFF}, handler and method
becomes undefined. Line 3 sets state to {\tt ON}, method to {\tt
CALL}, and handler to {\tt MYTH\_TRAP}. Line 4 sets state to {\tt ON},
method to {\tt CALL} and handler to {\tt MYTH} (the default). Line 5
sets state to {\tt OFF}, handler and method become undefined.

Why should method and handler become undefined when the trap in in
state {\tt OFF}? For two reasons: firstly, these values are not used
when the trap is in state {\tt OFF}; and secondly, when you set the
trap to state {\tt ON}, they are redefined. So it really does not
matter what they are in state {\tt OFF}.

What happens to this information when you call a subroutine? All
information about traps are inherited by the subroutine, provided that
it is an internal routine. External routines do not inherit any
information about traps, but use the default values. Note that the
inheritance is done by copying, so any changes done in the subroutine
(internal or external), will only have effect until the routine
returns.



\subsection{How to Raise a Condition}

How do you raise a condition? Well, there are really no explicit way
in {\rexx} to do that. The conditions are raised when an incident
occurs.  What sort of situations that is, depends on the context. There
are in general three types of incidents, classified by the origin of
the event:
\begin{itemize}
\item
   Internal origin. The incident is only dependent on the behavior of
   the {\rexx} script. The {\tt SYNTAX} condition is of this type.

\item
   External origin. The {\rexx} script and the interpreter has really
   no control over when this incident. It happens completely
   independent of the control of the {\rexx} script or interpreter.
   The {\tt HALT} condition is of this type.

\item
   Mixed origin. The incident is of external origin, but the situation
   that created the incident, was an action by the {\rexx} script or
   the interpreter. The {\tt ERROR} condition is of this type: the
   incident is a command returning error, but it can only occur when
   the interpreter is executing commands.
\end{itemize}

For conditions trapped by method {\tt CALL}, standard {\rexx} requires
an implementation to at least check for incidents and raise condition
at clause boundaries. (But it is allowed to do so elsewhere too;
although the actual triggering must only be performed at clause
boundaries.)  Consequently, you must be prepared that in some
implementations, conditions trappable by method {\tt CALL} might only
be raised (and the trap triggered) at clause boundaries, even if they
are currently trapped by method {\tt SIGNAL}.

The six standard conditions will be raised as result of various
situations, read the section describing each one of them for more
information.

\begin{figure}[htb]
\begin{center}
\begin{verbatim}
  +-----------+     +-----------+       /---------\       +-----------+
  | Incident  |     | Condition |      /   Trap    \ Off  | Default   |
  |    occurs | --> | is raised | -->  \   State   / ---> |    action |
  +-----------+     +-----------+     / \---------/       +-----------+
                                     /       |
                                    /On      |Delay
                                   /         |
                                  /          v
                    +-----------+/      /---------\       +-----------+
                    | Queue     |  Yes /DelayAction\  No  | Ignore    |
                    |  an event | <--- \ is queue? / ---> |     event |
                    +-----------+       \---------/       +-----------+
                          |
                          v
                     /---------\
                    / Method is \
                    \   CALL?   /
                     \---------/
                    /           \
                   /No        Yes\
                  /               \                        /---------\
                 /                 \                      /           \
         +-----------+         +-----------+              \  Decision /
         | Set state |         | Set state |               \---------/
         |    OFF    |         |   DELAY   |
         +-----------+         +-----------+              +-----------+
         | Trigger   |         |           |              |           |
         |     trap  |         |   Return  |              |  Action   |
         +-----------+         +-----------+              +-----------+
\end{verbatim}
\caption{The triggering of a condition}
\end{center}
\end{figure}

When an incident occurs and the condition is raised, the interpreter
will check the state of the condition trap for that particular
condition at the current procedure level.

\begin{itemize}
\item
   If the trap state is {\tt OFF}, the default-action of the condition
   is taken immediately. The ``standard'' default-action is to ignore
   the condition.

\item
   If the trap state is {\tt DELAY}, the action will depend on the
   delay-action of that condition. The standard delay-action is to
   ignore, then nothing further is done. If the delay-action is to
   queue, the interpreter continues as if the state was {\tt ON}.

\item 
   If the state of the trap is {\tt ON}, an event is generated which
   describes the incident, and it is queued in the pending event
   queue. The further action will depend on the method of trapping.

   If the method is {\tt CALL}, the state of the trap will be set to
   {\tt DELAY}. Then the normal execution is resumed.  The idea is
   that the interpreter will check the event queue later (at a clause
   boundary), and trigger the appropriate trap, if it finds any events
   in the event queue.

   Else, if method of trapping is {\tt SIGNAL}, then the action taken
   is this: First set the trap to state {\tt OFF}, then terminate
   clause the interpreter was executing at this procedure level. Then
   it explicitly trigger the condition trap.
\end{itemize}

This process has be shown in fig.~{\thefigure}. It shows how an
incident makes the interpreter raise a condition, and that the state
of the condition trap determines what to do next. The possible
outcomes of this process are: to take the default-action; to ignore if
delay-action is not to queue; to just queue and the continue
execution; or to queue and trigger the trap.




\subsection{How to Trigger a Condition Trap}

What are the situations where a condition trap might be triggered?  It
depends on the method currently set in the condition trap.

If the method is {\tt SIGNAL}, then the interpreter will explicitly
trigger the relevant trap when it has raised the condition after
having sensed the incident. Note that only the particular trap in
question will be triggered in this case; other traps will not be
triggered, even if the pending event queue is non-empty.

In addition, the interpreter will at each clause boundary check
for any pending events in the event queue. If
the queue is non-empty, the interpreter will not immediately
execute the next normal statement, but it will handle the condition(s)
first. This procedure is repeated until there are no more 
events queued. Only then will the interpreter advance to execute
the next normal statement. 

Note that the {\rexx} standard does not require the pending events to
be handled in any particular order, although the model shown in this
documentation it will be in the order in which the conditions were
raised.  Consequently, if one clause generates several events that
raise conditions before or at the next clause boundary, and these
conditions are trapped by method {\tt CALL}. Then, the order on which
the various traps are triggered is implementations-dependent.  But the
order in which the different instances of the same condition is
handled, is the same as the order of the condition indicator queue.




\subsection{Trapping by Method {\tt SIGNAL}}

Assume that a condition is being trapped by method {\tt SIGNAL}, that
the state is {\tt ON} and the handler is {\tt MYTH\_TRAP}. The
following {\rexx} clause will setup the trap correctly:
\begin{quote}
   {\tt SIGNAL ON MYTH NAME MYTH\_TRAP}
\end{quote}

Now, suppose the {\tt MYTH} incident occurs. The interpreter will sense
it, queue an event, set the trap state to {\tt OFF} and then
explicitly trigger the trap, since the method is {\tt SIGNAL}. What
happens when the trap is triggered?

\begin{itemize}
\item
   It collects the first event from the queue of pending events. The
   information is removed from the queue.

\item
   The current trapped condition is set to the information removed
   from the pending event queue.

\item
   Then, the interpreter simulates a {\tt SIGNAL} clause to the
   label named by trap handler of the trap for the condition in
   question. 

   As all {\tt SIGNAL} clauses, this will have the side-effects of
   setting the {\tt SIGL} special variable, and terminating all active
   loops at the current procedure level.
\end{itemize}

That's it for method {\tt SIGNAL}. If you want to continue trapping
condition {\tt MYTH}, you have to execute a new {\tt SIGNAL ON MYTH}
clause to set the state of the trap to {\tt ON}. But no matter how
quick you reset the trap, you will always have a short period where it
is in state {\tt OFF}. This means that you can not in general use the
method {\tt SIGNAL} if you really want to be sure that you don't loose
any {\tt MYTH} events, unless you have some control over when {\tt
MYTH} condition may arise.

Also note that since the statement being executed is terminated; all
active loops on the current procedure level are terminated; and the
only indication where the error occurred is the line number (the line
may contain several clauses), then it is in general impossible to pick
up the normal execution after a condition trapped by {\tt SIGNAL}.
Therefore, this method is best suited for a ``graceful death'' type of
traps. If the trap is triggered, you want to terminate what you were
doing, and pick up the execution at an earlier stage, e.g.~the
previous procedure level.



\subsection{Trapping by Method {\tt CALL}}

Assume that the condition {\tt MYTH} is being trapped by method {\tt
CALL}, that the state is {\tt ON} and the handler is {\tt MYTH\_HANDLER}.
The following {\rexx} clause will setup the trap correctly:
\begin{quote}
   {\tt CALL ON MYTH NAME MYTH\_HANDLER}
\end{quote}

Now, suppose that the {\tt MYTH} incident occurs. When the interpreter
senses that, it will raise the {\tt MYTH} condition. Since the trap
state is {\tt ON} and the trap method is {\tt CALL}, it will create an
event and queue it in the pending event queue and set the trap state
to {\tt DELAY}. Then it continues the normal execution. The trap is
not triggered before the interpreter encounters the next clause
boundary. What happens then?
\begin{itemize}
\item
   At the every clause boundaries, the interpreter check for any
   pending events in the event queue.  If one is found, it is handled.
   This action is done repeatedly, until the event queue is empty.

\item
   It will simulate a normal function call to the label named by the
   trap handler. As with any {\tt CALL} clause, this will set the
   special variable {\tt SIGL} to the line of from which the call was
   made. This is done prior to the call. Note that this is the current
   line at the time when the condition was raised, not when it was
   triggered.  All other actions normally performed when calling a
   subroutine are done.  Note that the arguments to the subroutine are
   set to empty.

\item
   However, just before execution of the routine starts, it will
   remove the first event in the pending event queue, the information
   is instead put into the current trapped condition. Note that the
   current trapped condition is information that is saved across
   subroutine calls. It is set {\bf after} the condition handler is
   called, and will be local to the condition handler (and functions
   called by the condition handler). To the ``caller'' (i.e.~the
   procedure level active when the trap was triggered), it will seem
   as if the current trapped condition was never changed.

\item
   Then the condition handler finishes execution, and returns by
   executing the {\tt RETURN} clause. Any expression given as argument
   to {\tt RETURN} will be ignored, i.e.~the special variable {\tt
   RESULT} will not be set upon return from a condition handler.

\item
   At the return from the condition handler, the current trapped
   condition and the setup of all traps are restored, as with a normal
   return from subroutine.  As a special case, the state of the trap
   just triggered, will not be put back into {\tt DELAY} state, but is
   set to state {\tt ON}.

\item
   Afterwards (and before the next normal clause), the interpreter
   will again check for more events in the event queue, and it will
   not continue on the {\rexx} script before the queue is empty.
\end{itemize}

During the triggering of a trap by method {\tt CALL} at a clause
boundary, the state of the trap is not normally changed, it will
continue to be {\tt DELAY}, as was set when the condition was raised.
It will continue to be in state {\tt DELAY} until return from the
condition handler, at which the state of the trap in the caller will
be changed to {\tt ON}. If, during the execution of the condition
trap, the state of the condition being trapped is set, that change
will only last until the return from the condition handler.

Since new conditions are generally delayed when an condition handler
is executing, new conditions are queued up for execution. If the trap
state is changed to {\tt ON}, the pending event queue will be
processed as named at the next clause boundary. If the state is
changed to {\tt OFF}, the default action of the conditions will be
taken at the next clause boundary.



\subsection{The Current Trapped Condition}
\label{sect:CTS}

The interpreter maintains a data structure called the current trapped
condition. It contains information relating the the most recent
condition trapped on this or higher procedure level. The current
trapped condition is normally inherited by subroutines and functions,
and restored after return from these.

\begin{itemize}
\item
   When trapped by method {\tt SIGNAL} the current trapped condition
   of the current procedure level is set to information describing
   the condition trapped.

\item
   When trapped by method {\tt CALL}, the current trapped condition at
   the procedure level which the trap occurred at, is not changed.
   Instead, the current trapped condition in the condition handler is
   set to information describing the condition.
\end{itemize}

The information stored in the current trapped condition can be
retrieved by the builtin function {\tt CONDITION()}. The syntax format
of this function is:
\begin{quote}
   {\tt CONDITION({\it option})}
\end{quote}
where {\it option} is an option string of which only the first
character matters.  The valid options are: {\tt Condition~name}, {\tt
Description}, {\tt Instruction} and {\tt State}. These will return:
the name of the current trapped condition; the descriptive text; the
method; and the current state of the condition, respectively. The
default {\it option} is {\tt Instruction}. See the documentation
on the builtin functions. See also the description of each condition
below. 

Note that the {\tt State} option do not return the state at the time
when the condition was raised or the trap was triggered. It returns
the current state of the trap, and may change during execution.  The
other information in the current trapped condition may only change
when a new condition is trapped or at treturn from subroutines.




\section{The Real Conditions}

We have now described how the standard condition and condition trap
works in {\rexx}. Let's look at the six conditions defined which do
exist.  Note that none of these behaves exactly as the standard
condition.


\subsection{The {\tt SYNTAX} condition}

The {\tt SYNTAX} condition is of internal origin, and is raised when
any syntax or runtime error is discovered by the {\rexx} interpreter.
It might be any of the situations that would normally lead to the
abortion of the program and the report of a {\rexx} error message,
except error message number~4 ({\it Program interrupted}), which is
handled by the {\tt HALT} condition.

There are several differences between this condition and the standard
condition:
\begin{itemize}
\item
   It is not possible to trap this condition with the method {\tt
   CALL}, only method {\tt SIGNAL}. The reason for this is partly that
   method {\tt CALL} tries to continue execution until next boundary
   before triggering the trap. That might not be possible with syntax
   or runtime errors.

\item
   When this condition is trapped, the special variable {\tt RC} is
   set to the {\rexx} error number of the syntax or runtime error that
   caused the condition. This is done just before the setting of the
   special variable {\tt SIGL}.

\item
   The default action of this condition if the trap state is {\tt
   OFF}, is to abort the program with a traceback and error message.

\item
   There is not delay-action for condition {\tt SYNTAX}, since it can
   not be trapped by method {\tt CALL}, and consequently never can get
   into state {\tt DELAY}.
\end{itemize}

The descriptive text returned by {\tt CONDITION()} when called with
the {\tt Description} option for condition {\tt SYNTAX}, is
implementation dependent, and may also be a nullstring. Consult the
im\-ple\-menta\-tion-specific documentation for more information.



\subsection{The {\tt HALT} condition}

The {\tt HALT} condition of external origin, which is raised as a
result of an action from the user, normally a combination of keys
which tries to abort the program. Which combination of keys will vary
between operating systems. Some systems might also simulate this event
by other means than key combinations. Consult system for more
information.

The differences between {\tt HALT} and the standard condition are:
\begin{itemize}
\item
   The default-action for the {\tt HALT} condition is to abort
   execution, as though a {\rexx} runtime error error number~4 ({\it
   Program interrupted}) had been reported. But note that {\tt SYNTAX}
   will never be raised if {\tt HALT} is not trapped.

\item
   The delay-action of this condition is to ignore, not queue.
\end{itemize}

The standard allows the interpreter to limit the search for situations
that would set the {\tt HALT} condition, to clause boundaries. As a
result, the response time from pressing the key combination to
actually raising the condition or triggering the trap may vary, even
if {\tt HALT} is trapped by method {\tt SIGNAL}. If a clause for some
reason has blocked execution, and never finish, you may not be able to
break the program.

The descriptive text returned by {\tt CONDITION()} when called with
the {\tt Description} option for condition {\tt HALT}, is
implementation dependent, and may also be a nullstring. In general, it
will describe the way in which the interpreter was attempted halted,
in particular if there are more than one way to do raise a {\tt HALT}
condition. Consult the implementation documentation for more
information.




\subsection{The {\tt ERROR} condition}

The {\tt ERROR} is a condition of mixed origin, it is raised when a
command returns a return value which indicates error during execution.
Often, commands return a numeric value, and a particular value is
considered to mean success. Then, other values might raise the {\tt
ERROR} condition.

Differences between {\tt ERROR} and the standard condition:
\begin{itemize}
\item
   The delay action of {\tt ERROR} is to ignore, not to queue.

\item
   The special variable {\tt RC} is always set before this condition
   is raised. So even if it is trapped by method {\tt SIGNAL}, you can
   rely on {\tt RC} to be set to the return value of the command. 
\end{itemize}

Unfortunately, there is no universal standard on return values. As
stated, they are often numeric, but some operating system use
non-numeric return values. For those which do use numeric values,
there are no standard telling which values and ranges are considered
errors and which are considered success. In fact, the interpretation
of the value might differ between commands within the same operating
system.

Therefore, it is up to the {\rexx} implementation to define which
values and ranges that are considered errors. You must expect that
this information can differ between implementations as well as between
different environments within one implementation.

The descriptive text returned by {\tt CONDITION()} when called with
the {\tt Description} option for condition {\tt ERROR}, is the command
which caused the error. Note that this is the command as the
environment saw it, not as it was entered in the {\rexx} script source
code.



\subsection{The {\tt FAILURE} condition}

The {\tt FAILURE} is a condition of mixed origin, it is raised when a
command returns a return value which indicates failure during
execution, abnormal termination, or when it was impossible to execute
a command.  It is a subset of the {\tt ERROR} condition, and if it is
in state {\tt OFF}, then the {\tt ERROR} condition will be raised
instead. But note that an implementation is free to consider all
return codes from commands as {\tt ERROR}s, and none as {\tt
FAILURES}. In that case, the only situation where a {\tt FAILURE}
would occur, is when it is impossible to execute a command.

Differences between {\tt FAILURE} and the standard condition:
\begin{itemize}
\item
   The delay action of {\tt FAILURE} is to ignore, not to queue.

\item
   The special variable {\tt RC} is always set before this condition
   is raised. So even if it is trapped by method {\tt SIGNAL}, you can
   rely on {\tt RC} to be set to the return value of the command, or
   the return code that signalize that the command was impossible to
   execute.
\end{itemize}

As for {\tt ERROR}, there is no standard the defines which return
values are failures and which are errors. Consult the system and
implementation independent documentation for more information.

The descriptive text returned by {\tt CONDITION()} when called with
the {\tt Description} option for condition {\tt FAILURE}, is the
command which caused the error. Note that this is the command as the
environment saw it, not as it was entered in the {\rexx} script source code.




\subsection{The {\tt NOVALUE} condition}

The {\tt NOVALUE} condition is of internal origin. It is raised in
some circumstances if the value of an unset symbol (which is not a
constant symbol) is requested. Normally, this would return the default
value of the symbol. It is considered bad programming practice not to
initialize variables, and setting the {\tt NOVALUE} condition is one
method of finding the parts of your program that uses this programming
practice.

Note however, there are only three instances where this condition may
be raised: that is when the value of an unset (non-constant) symbol is
used requested: in an expression; after the {\tt VAR} subkeyword in a
{\tt PARSE} clause; and as an indirect reference in either a template,
a {\tt DROP} or a {\tt PROCEDURE} clause. In particular, this
condition is not raised if the {\tt VALUE()} or {\tt SYMBOL()} builtin
functions refer to an unset symbol.

Differences between {\tt NOVALUE} and the standard condtition are:
\begin{itemize}
\item
   It may only be trapped by method {\tt SIGNAL}, never method {\tt
   CALL}. This requirement might seem somewhat strange, but the idea
   is that since an implementation is only forced to check for
   conditions trapped by method {\tt CALL} at clause boundaries,
   incidences that may occur at any point within clauses (like {\tt
   NOVALUE}) can only be trapped by method {\tt SIGNAL}. (However,
   condition {\tt NOTREADY} can occur within a clause, and may be
   trapped by method {\tt CALL} so this does not seem to be absolute
   consistent.)

\item
   There is not delay-action for condition {\tt NOVALUE}, since it can
   not be trapped by method {\tt CALL}, and consequently never can get
   into state {\tt DELAY}.
\end{itemize}

The descriptive text returned by calling {\tt CONDITION()} with the
{\tt Description} option, is the derived (i.e.~tail has be substituted
if possible) name of the variable that caused the condition to be
raised.



\subsection{The {\tt NOTREADY} condition}

The condition {\tt NOTREADY} is a condition of mixed origin. It is
raised as a result of problems with stream I/O. Exactly what causes
it, may vary between implementations, but some of the more probable
causes are: waiting for more I/O on transient streams; access to
streams not allowed; I/O operation would block if attempted; etc. See
the chapter on stream I/O for more information.

Differences between {\tt NOTREADY} and the standard condition are:
\begin{itemize}
\item
   It will be ignored rather than queued if condition trap is in state
   {\tt DELAY}.

\item 
   This condition differs from the rest in that it can be raised
   during execution of a clause, but can still be trapped by method
   {\tt CALL}.
\end{itemize}

The descriptive text returned by {\tt CONDITION()} when called with
the {\tt Description} option for condition {\tt NOTREADY}, is the name
of the stream which caused the problem. This is probably the same
string that you used as the first parameter to the functions that
operates on stream I/O. For the default streams (default input and
output stream), the string returned by {\tt CONDITION()} will be
nullstrings.

Note that if the {\tt NOTREADY} trap is in state {\tt DELAY}, then all
I/O for files which has tried to raise {\tt NOTREADY} within the
current clause will be simulated as if operation had succeeded.


\section{Further Notes on Conditions}

\subsection{Conditions under Language Level 3.50}

The concept of conditions was very much expanded from {\rexx} language
level 3.50 to level 4.00. Many of the central features in conditions
are new in level 4.00, these include:

\begin{itemize}
\item
   The {\tt CALL} method is new, previously only the {\tt SIGNAL}
   method was available, which made it rather difficult to resume
   execution after a problem. As a part of this, the {\tt DELAY} state
   has been added too.

\item
   The condition {\tt NOTREADY} has been added, to allow better
   control over problems involving stream I/O.

\item
   The builtin function {\tt CONDITION()} has been added, to allow
   extraction of information about the current trapped condition.
\end{itemize}


\subsection{Pitfalls when Using Condition Traps}

There are several pitfalls when using conditions:

\begin{itemize}
\item
   Remember that some information are saved across the functions. Both
   the current trapped condition and the settings of the traps.
   Consequently, you can not set a trap in a procedure level from a
   lower level. (I.e.~calling a subroutine to set a trap is will not
   work.)

\item
   Remember that {\tt SIGL} is set when trapped by method {\tt CALL}.
   This means that whenever a condition might be trapped by {\tt
   CALL}, the {\tt SIGL} will be set to a new value. Consequently,
   never trust the contents of the {\tt SIGL} variable for more than
   one clause at a time. This is very frustrating, but at least it
   will not happen often. When it do happen, though, you will probably
   have a hard time debugging it. 

\item
   Also remember that if you use the {\tt PROCEDURE} clause in a
   condition handler called by method {\tt CALL}, remember to {\tt
   EXPOSE} the special variables {\tt SIGL} if you want to use it
   inside the condition handler. Else it will be shadowed by the {\tt
   PROCEDURE}.
\end{itemize}



\subsection{The Correctness of this Description}

In this description of conditions in {\rexx}, I have gone further in
the description of how conditions work, their internal data structures,
the order in which things are executed etc, than the standard does.  I
have tried to interpret the set of distinct statements that is the
documentation on condition, and design a complete and consistent
system describing how such conditions work.  I have done this to try
to clarify an area of {\rexx} which at first glance is very difficult
and sometimes unintuitive.

I hope that the liberties I have taken have helped describe conditions
in {\rexx}. I do not feel that the adding of details that I have done
in any way change how conditions work, but at least I owe the reader
to list which concepts that are genuine {\rexx}, and which have been
filled in by me to make the picture more complete. These are not a
part of the standard {\rexx}.
\begin{itemize}
\item
   {\rexx} does not have anything called a standard condition. There
   just ``are'' a set of conditions having different attributes and
   values. Sometimes there are default values to some of the
   attributes, but still the are no default condition.

\item
   The terms ``event'' and ``incident'' are not used. Instead the term
   ``condition'' is somewhat overloaded to mean several things,
   depending on the situation. I have found it advantageous to use
   different terms for each of these concepts.

\item
   Standard {\rexx} does not have condition queue, although a
   structure of such a kind is needed to handled the queuing of
   pending conditions when the trap state is {\tt DELAY}. 

\item
   The values default-action and delay-action are really non-existing
   in the Standard {\rexx} documentation. I made them up to make the
   system more easy to explain.

\item
   The two-step process of first raising the flag, and then (possibly
   at a later stage) triggering the trap, is not really a {\rexx}
   concept. Originally, {\rexx} seems to allow implementations to
   select certain places of the interpreter where events are sought
   for. All standard conditions that can be called by method {\tt
   CALL}, can be implemented by checking only at clause boundaries. 

   Consequently, a {\rexx} implementation can choose to trigger the
   trap immediately after a condition are raised (since conditions are
   only raised immediately before the trap would trigger anyway). This
   is also the common way used in language level 3.50, when only
   method {\tt SIGNAL} was implemented. 

   Unfortunately, the introduction of the state {\tt DELAY} forces the
   interpreter to keep a queue of pending conditions, so there is
   nothing to gain on insisting that raising should happen immediately
   before triggering. And the picture is even more mudded when the
   {\tt NOTREADY} condition is introduced. Since it explicitly allows
   raising of condition to be done during the clause, even though the
   triggering of the trap must happen (if method is {\tt CALL}) at the
   end of the clause. 
\end{itemize}

I really hope that these changes has made the concept of conditions
easier to understand, not harder. Please feel free to flame me for any
of these which you don't think is representative for {\rexx}.



\section{Conditions in Regina}

Here comes documentation that are specific for the {\regina}
implementation of {\rexx}.



\subsection{How to Raise the {\tt HALT} condition}

The implementation connect the {\tt HALT} condition to an external
event, which might be the pressing of certain key combination. The
common conventions of the operating system will dictate what that
combination of keystrokes is.

Below is a list, which describes how to invoke an event that will
raise the {\tt HALT} condition under various the operating systems
which {\regina} runs under.

\begin{itemize}
\item
   Under various variants of the {\bf Unix} operating system, the {\tt
   HALT} event it connected to the signal ``interrupt'' ({\tt
   SIGINT}). Often this signal is bound to special keystrokes.
   Depending on your version of Unix, this might be {\sc ctrl}-{\sc c}
   (mostly BSD-variants) or the {\sc del} key (mostly System V).  It
   is also possible to send this signal from the command line, in
   general using the program {\tt kill(1)}; or from program, in
   general using the call {\tt signal(3)}.  Refer to your Unix
   documentation for more information.

\item
   Under {\bf VAX/VMS}, the keysequence {\sc ctrl}-{\sc c} is used to
   raise the {\tt HALT} condition in the interpreter.
\end{itemize}



\subsection{Extended builtin functions}

{\regina} has a few extra builtin functions that are added to support
the debugging of the interpreter. Under some circumstances, these
might also be useful when debugging {\rexx} scripts. Note that these
functions are not a part of standard {\rexx} and should never be used
when portability is required. The functions are:
\begin{description}
\item[{\tt RAISE\_COND({\it condition})}]\hfill\\
   is used to explicitly raise a {\it condition} during execution of a
   {\rexx} script. The interpreter will accept the execution of this
   function as an event, just as if the event had occurred. Returns
   the nullstring.

\item[{\tt COND\_INFO([{\it condition}])}]\hfill\\
   is a function that will return information about the current
   settings of the condition indicator for {\it condition}, including
   the state of the flag, and the contents of the pending queue. If
   called without a parameter, it will return a {\sc space}-separated
   list of those conditions which have non-empty pending condition
   queue.

\item[{\tt TRAP\_INFO([{\it condition}])}]\hfill\\
   is a functions that returns the status information about a trigger
   at the current procedure level.  The info returned will be the
   state, the method and the condition handler. If called without a
   parameter, a {\sc space}-separated list of condition enabled (state
   {\tt ON} or {\tt DELAY}) at the current procedure level, is
   returned.
\end{description}

These functions are described in detail elsewhere. Note that these
functions will only be available if the interpreter was compiled with
the certain preprocessor flag set. If the code was included in the
compilation, the availability of these function will still be
dependent on the selection of extensions with the clause {\tt
OPTIONS}, where the extension {\tt DBG\_FUNCS} should be chosen. See
chapter on extensions for more information.



\subsection{Extra Condition in {\regina}}

{\regina} has some other extra conditions. These conditions are:

\begin{itemize}
\item
   A condition {\tt DEBUG}, that is very similar to the condition {\tt
   HALT}. The condition is raised as a result of an event of external
   origin, generally a special combination of keystrokes is pressed.

   The default-action of this condition is to set the trace mode to
   {\tt Normal} and interactive. Consequently, the user will generally
   get into interactive tracing at the next clause boundary. This way,
   the user may be able to stop the program during execution, and
   perform debugging.

   The delay-action of this condition is to ignore it.

   On Unix machines, this is the signal {\tt QUIT} ({\tt SIGQUIT}),
   which is normally bound the the {\sc ctrl}-{\tt \verb+\+} key.
   Just like condition {\tt HALT}, this might also be simulated from
   the command line, or from other programs. Consult the Unix
   documentation for more information. On VAX/VMS machines, this event
   is normally bound to the {\sc ctrl}-{\sc y} key.

   This extended condition will only be available if the extension
   {\tt COND\_DEBUG} has been chosen.
\end{itemize}

Whether or not the conditions listed here are available, may also
depend on whether particular preprocessor flag was set during
compilation. For more information, see the chapter on extensions.



\subsection{Various Other Existing Extensions}


Here is a list of other current extensions in {\regina}. See chapter
on extensions for more information.

\begin{itemize}
\item
   {\regina} allows the condition {\tt NOVALUE} to be trapped by
   method {\tt CALL}, which is not allowed according to the standard.
   This extension will only be available if the extension {\tt
   CALL\_ON\_NOVALUE} has been chosen, and the code was compiled with
   certain preprocessor flags set.

   If {\tt NOVALUE} is being trapped by method {\tt CALL}, the current
   clause will be completed as if {\tt NOVALUE} was not trapped at
   all, returning the default value for an unset symbol as variable
   value.
\end{itemize}



\section{Possible Future extensions}

Here is a list of possible future extensions to {\rexx} which has not
been implemented into {\regina}. Some of these exist in other
implementations of {\rexx}, and some of them are just suggestions or
ideas thrown around by various people. 

\begin{itemize}
\item
   Another extension could have been included, but have been left out
   so far. It is the delay-action, which in standard {\rexx} can be
   either to ignore or to queue. There is at least one other action
   that make sense: to replace. That is, when a trap is in state {\tt
   DELAY}, and a new condition has been raised, the pending queue is
   emptied, before the new condition is queued. That way, the new
   condition will effectively replace any conditions already in the
   queue. 

   If there are several new conditions raised while the condition
   handler is executing (and the trap state is {\tt DELAY}), only the
   very last of them is remembered.

\item
   It should be possible to set the state for a trap to {\tt DELAY},
   so that any new instances of the condition is handles by the
   delay-action. As a special case, the {\tt SYNTAX} condition trap
   might not be set in state {\tt DELAY}
\end{itemize}


