Document revision date: 19 July 1999 | |
Previous | Contents | Index |
A block of code starting with ON_ERROR and ending with ENDON_ERROR defines the actions that are to be taken when a procedure fails to execute successfully. Such a block of code is called an error handler. An error handler is an optional part of a DECTPU procedure or program. An error handler traps WARNING and ERROR status values. (See SET (INFORMATIONAL) and SET (SUCCESS) in the DEC Text Processing Utility Reference Manual for information on handling informational and success status values.)
It is good programming practice to put an error handler in all but the simplest procedures. However, if you omit the error handler, DECTPU's default error handling behavior is as follows:
In a procedure, the error handler must be placed at the beginning of a procedure---after the procedure parameter list, the LOCAL or CONSTANT declarations, if present, and before the body of the procedure. In a program, the ON_ERROR language statements must be placed after all the global declarations (PROCEDURE, CONSTANT, and VARIABLE) and before any executable statements. Error statements can contain any DECTPU language statements except other ON_ERROR statements.
There are three DECTPU lexical elements that are useful in an error handler: ERROR, ERROR_LINE, and ERROR_TEXT.
ERROR returns a keyword for the error or warning. The DEC Text Processing Utility Reference Manual includes information on the possible error and warning keywords that each built-in procedure can return.
ERROR_LINE returns the line number at which the error or warning occurs. If a procedure was compiled from a buffer or range, ERROR_LINE returns the line number within the buffer. (This may be different from the line number within the procedure.) If the procedure was compiled from a string, ERROR_LINE returns 1.
ERROR_TEXT returns the text of the error or warning, exactly as DECTPU would display it in the message buffer, with all parameters filled in.
After the execution of an error statement, you can choose where to resume execution of a program. The options are the following:
If you do not specify ABORT or RETURN, the default is to continue executing the program from the point at which the error occurred.
DECTPU provides two forms of error handler: procedural and case style.
4.9.4.15 Procedural Error Handlers
If a WARNING status is trapped by an ON_ERROR statement, the warning message is suppressed. However, if an ERROR status is trapped, the message is displayed. With the ON_ERROR trap, you can do additional error handling after the DECTPU message is displayed.
ON_ERROR statement_1; statement_2; . . . statement_n; ENDON_ERROR; |
Example 4-10 shows error statements at the beginning of a procedure. These statements return control to the caller if the input on the command line of an interface is not correct. Any warning or error status returned by a statement in the body of the procedure causes the error statements to be executed.
Example 4-10 Procedure That Uses the ON_ERROR Statement |
---|
! ! Gold 7 emulation (command line processing) ! PROCEDURE command_line LOCAL line_read, X; ON_ERROR MESSAGE ("Unrecognized command: " + line_read); RETURN; ENDON_ERROR; ! ! Get the command(s) to execute ! line_read := READ_LINE ("DECTPU Statement: "); ! get line from user ! ! compile them ! IF line_read <> "" THEN X := COMPILE (line_read); ELSE RETURN ENDIF; ! ! execute ! IF X <> 0 THEN EXECUTE (X); ENDIF; ENDPROCEDURE; |
The effects of a procedural error handler are as follows:
If an error or warning is generated during execution of a procedural error handler, DECTPU behaves as follows:
Case-style error handlers provide a number of advantages over procedural error handlers. With case-style error handlers, you can do the following:
ON_ERROR [condition_1]: statement_1;... [condition_2]: statement_2;...
. . .
[condition_n]: statement_n; ENDON_ERROR;
You can use the [OTHERWISE] selector alone in an error handler as a shortcut. For example, the following two error handlers have the same effect:
! This error handler uses [OTHERWISE] alone as a shortcut. ON_ERROR [OTHERWISE] : ; ENDON_ERROR ! This error handler has the same effect as using ! [OTHERWISE] alone. ON_ERROR [OTHERWISE] : LEARN_ABORT; RETURN (FALSE); ENDON_ERROR; |
Example 4-11 from the EVE editor shows a procedure with a case-style error handler.
Example 4-11 Procedure with a Case-Style Error Handler |
---|
PROCEDURE eve$learn_abort ON_ERROR [TPU$_CONTROLC]: MESSAGE (ERROR_TEXT); RETURN (LEARN_ABORT); ENDON_ERROR; IF LEARN_ABORT THEN eve$message (EVE$_LEARNABORT); RETURN (TRUE); ELSE RETURN (FALSE); ENDIF; ENDPROCEDURE; |
If a program or procedure has a case-style error handler, DECTPU handles errors and warnings as follows:
special_error_symbol := 0; LEARN_ABORT; RETURN (FALSE); |
special_error_symbol := 0; LEARN_ABORT; RETURN (FALSE); |
special_error_symbol := 0; LEARN_ABORT; RETURN (FALSE); |
If an error or warning is generated during execution of a case-style error handler, DECTPU behaves as follows:
special_error_symbol := 0; LEARN_ABORT; RETURN (FALSE); |
special_error_symbol := 0; LEARN_ABORT; RETURN (FALSE); |
In a procedure with a case-style error handler, an ABORT statement
produces the same effect as the sequence Ctrl/C, with one exception: an
ABORT statement in the TPU$_CONTROLC clause of a case-style error
handler does not reinvoke the TPU$_CONTROLC clause, as is the case when
Ctrl/C is pressed while TPU$_CONTROLC is executing. Instead, an ABORT
statement causes DECTPU to exit from the error handler and look for a
TPU$_CONTROLC selector in the procedures or program (if any) in which
the current procedure is nested. If DECTPU does not find a
TPU$_CONTROLC selector in the containing procedures or program, DECTPU
places the message associated with TPU$_CONTROLC in the message buffer.
4.9.4.17 Ctrl/C Handling
The ability to trap a Ctrl/C in your DECTPU program is both powerful
and dangerous. When you press Ctrl/C, you usually want the application
that is running to prompt for a new command. The ability to trap the
Ctrl/C is intended to allow a procedure to clean up and exit gracefully.
4.9.4.18 RETURN Statement
The RETURN statement causes a return to the procedure that called the current procedure or program. The return is to the statement that follows the statement that called the current procedure or program. You can specify an expression after the RETURN statement and the value of this expression is passed to the calling procedure.
RETURN expression; |
The expression is optional; if it is missing, DECTPU supplies a 0. Also, the RETURN statement itself is optional. That is, if DECTPU reaches the endprocedure of a procedure before encountering a RETURN statement, it will return 0.
Example 4-12 shows a sample procedure in which a value is returned to the calling procedure.
Example 4-12 Procedure That Returns a Value |
---|
PROCEDURE user_get_shift_key LOCAL key_to_shift; ! Keyword for key pressed after shift key SET (SHIFT_KEY, LAST_KEY); key_to_shift := KEY_NAME (READ_KEY, SHIFT_KEY); RETURN key_to_shift; ENDPROCEDURE; |
In addition to using RETURN to pass a value, you can use a 1 (true) or a 0 (false) with the RETURN statement to indicate the status of a procedure. Example 4-13 shows this usage of the RETURN statement.
Example 4-13 Procedure That Returns a Status |
---|
PROCEDURE user_at_end_of_line ! This procedure returns a 1 (true) if user is at the end of a ! line, or a 0 (false) if the current character is not at the ! end of a line ON_ERROR ! Suppress warning message RETURN (1); ENDON_ERROR; IF CURRENT_OFFSET = LENGTH (CURRENT_LINE) THEN RETURN (1); ELSE RETURN (0); ENDIF; ENDPROCEDURE; |
You can use the RETURN statement in the ON_ERROR section of a procedure to specify a return to the calling procedure if an error occurs in the current procedure. Example 4-14 uses the RETURN statement in an ON_ERROR section.
Example 4-14 Using RETURN in an ON_ERROR Section |
---|
! Attach to the parent process. Used when EVE is spawned ! from DCL and run in a subprocess ("kept DECTPU"). The ! ATTACH command can be used for more flexible process control. PROCEDURE eve_attach ON_ERROR IF ERROR = TPU$_NOPARENT THEN MESSAGE ("Not running DECTPU in a subprocess"); RETURN; ENDIF; ENDON_ERROR; ATTACH; ENDPROCEDURE; |
The ABORT statement stops any executing procedures and causes DECTPU to wait for the next keystroke. ABORT is commonly used in error handlers. For additional information on using ABORT in error handlers, see Section 4.9.4.14.
ABORT |
Example 4-15 shows a simple error handler that contains an ABORT statement.
Example 4-15 Simple Error Handler |
---|
ON_ERROR MESSAGE ("Aborting procedure because of error."); ABORT; ENDON_ERROR; |
This section describes the following DECTPU language declarations:
With the EQUIVALENCE declaration, you can create synonyms. Equivalences work only when both real_name and synonym_name are defined at the same time. You cannot save a section file that contains real_name and then later use that section file to extend code that uses an EQUIVALENCE of the saved name. To avoid problems, include all EQUIVALENCE declarations in the same compilation unit where real_name is defined.
The equivalences can reside in different compilation units, but you must use all of the compilation units when building the section file from scratch. If you use a base section file that you extend interactively, you cannot make equivalences to procedures or variables defined in the base section file.
EQUIVALENCE synonym_name1 = real_name1, synonym_name2 = real_name2,
...;
Elements of the EQUIVALENCE Statement
real_name
A user-defined global variable or procedure name. If real_name is undefined, DECTPU defines it as an ambiguous name. This ambiguous name can become a variable or procedure later.synonym_name
A name to be defined as a synonym for the real_name.
With the LOCAL declaration, you can identify certain variables as local variables rather than global variables. All variables are considered to be global variables unless you explicitly use the LOCAL declaration to identify them as local variables. The LOCAL declaration in a procedure is optional. It must be specified after the PROCEDURE statement and before any ON_ERROR statement. LOCAL declarations and CONSTANT declarations can be intermixed.
The maximum number of local variables you can declare in a procedure is 255. Local variables are initialized to 0.
LOCAL variable-name [[,...]]; |
Local variables may also be declared in unbound code. Such variables are accessible only within that unbound code.
Unbound code can occur in the following places:
The following example shows a complete compilation unit. This unit contains a module named mmm that, in turn, contains a procedure bat and some initialization code mmm_module_init, a procedure bar defined outside the module, and some unbound code at the end of the file. In each of these sections of code, a local variable X is defined. The variable is displayed using the MESSAGE built-in procedure.
MODULE mmm IDENT "mmm" PROCEDURE bat; ! Declare procedure "bat" in module "mmm" LOCAL X; ! "X" is local to procedure "bat" X := "Within procedure bat, within module mmm"; MESSAGE (X); ENDPROCEDURE; ! End procedure "bat" LOCAL X; ! "X" is local to ! procedure "mmm_module_init" X := "Starting or ending the module init code"; MESSAGE (X); bat; MESSAGE (X); ENDMODULE; ! End module "mmm" PROCEDURE bar ! Declare procedure "bar" LOCAL X; ! "X" is local to procedure "bar" X := "In procedure bar, which is outside all modules"; MESSAGE (X); ENDPROCEDURE; ! End procedure "bar" LOCAL X; ! "X" is local to the unbound code... X := "Starting or ending the unbound, non-init code"; MESSAGE (X); mmm_module_init; bat; bar; MESSAGE (X); EXIT; |
If this code is included in TEMP.TPU, the following command demonstrates the scope of the various local variables:
$ EDIT/TPU/NOSECTION/NOINITIALIZE/NODISPLAY/COMMAND=temp.tpu Starting or ending the unbound, non-init code Starting or ending the module init code Within procedure bat, within module mmm Starting or ending the module init code Within procedure bat, within module mmm In procedure bar, which is outside all modules Starting or ending the unbound, non-init code |
Previous | Next | Contents | Index |
privacy and legal statement | ||
6018PRO_009.HTML |