Previous | Contents | Index |
The STOP statement terminates execution of a program, regardless of the current block activation.
The format of the STOP statement is:
STOP; |
The STOP statement signals the FINISH condition, and closes all open
files. If the main procedure has the RETURNS attribute, no return value
is obtainable.
8.9 Null Statement
The null statement performs no action. Its format is:
; |
The null statement usually serves as the target statement of a THEN or ELSE clause in an IF statement, as the target of a WHEN or OTHERWISE clause in a SELECT statement, or as an action in an ON-unit. The following examples illustrate these uses.
IF A < B THEN GOTO COMPUTE; ELSE ; |
In this example, no action takes place if A is greater than or equal to B; execution continues at the statement following ELSE ;. A construction of this type may be necessary when IF statements are nested (see Section 8.4.1).
SELECT; WHEN (condition A,B,C) GOTO FILE_READ; WHEN (condition D,E) GOTO UPDATE; OTHERWISE; END; |
In this example, control is passed to the next executable statement after END if conditions A, B, C, D, and E are not true.
ON ENDPAGE(SYSPRINT); |
In this example, no action takes place upon execution of the ON-unit; the I/O operation that caused the ENDPAGE condition continues.
The null statement can also be used to declare two labels for the same executable statement, as in the following example:
LABEL1: ; LABEL2: statement ... |
A PL/I condition is any occurrence that causes the interruption of a program and a signal. When a condition is signaled, PL/I initiates a search for a user-written program unit called an ON-unit to handle the condition.
An ON condition is any one of several named conditions whose occurrence during the execution of a program interrupts the program. When a condition occurs or is signaled, a statement or sequence of statements, called an ON-unit, is executed. The SYSTEM option can be specified in the ON statement, causing the default system condition handling to be executed.
The following list of condition handling topics are discussed in subsequent sections.
The ON statement defines the action to be taken when a specific condition or conditions are signaled during the execution of a program. The ON statement is an executable statement. It must be executed before the statement that signals the specified condition.
The format of the ON statement is:
condition-name,...
The name or names of the specific conditions for which an ON-unit or the SYSTEM option is specified. There is a keyword name associated with each condition. Successive keyword names must be separated by commas. The conditions are summarized in Table 8-1; each condition is described in an individual entry in this manual.SNAP
This option invokes the debugger and causes a traceback of all active routines to be displayed when the condition is raised. If you use the SNAP option, you should specify the /DEBUG qualifier on both the PLI command and the LINK command in order to have all the debugger symbol table information accessible.If you want to run a program containing the SNAP option in a batch job and cause the program to resume execution after any display of traceback information, you can define DBG$INIT to point to a debug initialization file that contains the following line:
WHILE PC ^= 0 DO(GO)on-unit
The action to be taken when the specified condition or conditions are signaled. An ON-unit can be:
- Any single, unlabeled statement except DECLARE, DO, END, ENTRY, FORMAT, IF, ON, PROCEDURE, RETURN, or SELECT.
- An unlabeled begin block.
- A null statement (a semicolon alone), which causes program execution to continue as if the condition had been handled.
Only the most recent ON-unit established for a given condition can be active. If two successive ON statements are executed for the same condition, the second ON statement nullifies the first.
If no ON-unit is established for a particular condition, the condition ERROR is signaled. If no ON-unit is established for ERROR condition, the default system ON-unit is executed. See Section 8.10.5.
SYSTEM
This option invokes the default system condition handling for the specified condition, overriding any existing ON-unit for the condition. See Section 8.10.6.
The SIGNAL statement causes a specified condition to be signaled, which causes the system to search for and execute an ON-unit to handle the condition. See Section 8.10.8.
The format of the SIGNAL statement is:
SIGNAL condition-name; |
condition-name
The name of the condition to be signaled. It must be one of the keywords listed in Table 8-1. Each of these conditions is described in its own section.
Most conditions occur as a result of a hardware trap or fault, or as a
result of signaling by PL/I run-time procedures. You can use the SIGNAL
statement within a program as a general-purpose communication
technique. In particular, the VAXCONDITION and CONDITION conditions let
you signal unique user-defined condition values.
8.10.3 REVERT Statement
The REVERT statement cancels an ON-unit established for a specified condition or conditions in the current block only.
The format of the REVERT statement is as follows:
REVERT condition-name,...; |
condition-name,...
The keyword name or names associated with the condition or conditions for which the ON-unit is to be reverted. Successive names must be separated by commas. The valid condition names are the same as for the ON statement.
If no ON-unit is established for a specified condition for the current block, the REVERT statement has no effect.
The REVERT statement does not cancel all ON-units that may be active at the same time it is executed (see Section 8.10.8), only a handler in the current block. If you want to temporarily block activation of all user-written ON-units for a condition, define an ON-unit with the SYSTEM option for the given condition.
An ON-unit can be re-established after execution of a REVERT statement by subsequently executing an ON statement.
The REVERT statement has no effect on an ON-unit established for the ANYCONDITION condition unless the statement explicitly references the ANYCONDITION condition. For example:
REVERT ANYCONDITION; |
Therefore, a statement such as the following has no effect on an ON-unit established for the ANYCONDITION condition:
REVERT ZERODIVIDE; |
The next example shows this more clearly:
PROGRAM: PROCEDURE OPTIONS(MAIN); DECLARE A FIXED; DECLARE B FIXED INITIAL (5); DECLARE C FIXED INITIAL (0); ON ANYCONDITION BEGIN; PUT SKIP LIST ('Handled condition = ',ONCODE()); END; REVERT ZERODIVIDE; A = B / C; /* Signal divzero */ ON ZERODIVIDE BEGIN; PUT SKIP LIST ('Handled ZERODIVIDE'); END; A = B / C; /* Signal divzero */ REVERT ZERODIVIDE; A = B / C; /* Signal divzero */ ON ZERODIVIDE BEGIN; PUT SKIP LIST ('Handled ZERODIVIDE'); END; REVERT ANYCONDITION; A = B / C; /* Signal divzero */ REVERT ZERODIVIDE; A = B / C; /* Signal divzero */ END PROGRAM; |
When you run the program, the following conditions result:
Handled condition = 1156 Handled ZERODIVIDE Handled condition = 1156 Handled ZERODIVIDE PL/I ERROR condition. |
Most, but not all, ON conditions are associated with errors. The types of conditions for which you can establish ON-units are grouped in the following categories.
Table 8-1 summarizes ON conditions. Each condition is described individually in the sections that follow.
Condition Name | Function |
---|---|
ANYCONDITION | Handles any condition not specifically handled by another ON-unit |
AREA | Handles a condition that occurs during an operation on an area |
CONDITION | Handles programmer-defined conditions |
CONVERSION | Handles data conversion errors |
ENDFILE | Handles end-of-file for a specified file |
ENDPAGE | Handles end-of-page for a specified file with PRINT attribute |
ERROR | Handles miscellaneous error conditions and conditions for which no specific ON-unit exists |
FINISH | Handles program exit when the main procedure executes a RETURN statement, when any block executes a STOP statement, or when the program exits due to an error that is not handled by an ON-unit |
FIXEDOVERFLOW | Handles fixed-point decimal and integer overflow exception conditions |
KEY | Handles any error involving the key during keyed access to a specified file |
OVERFLOW | Handles floating-point overflow exception conditions |
STORAGE | Handles a condition that occurs during allocation of a controlled variable or a based variable other than in an area |
STRINGRANGE | Handles out-of-bound substring references |
SUBSCRIPTRANGE | Handles out-of-bound array references |
UNDEFINEDFILE | Handles any errors in opening a specified file |
UNDERFLOW (VAX only) | Handles floating-point underflow exception conditions |
VAXCONDITION | Handles operating system or programmer-specified condition values |
ZERODIVIDE | Handles divide-by-zero exception conditions |
The ANYCONDITION keyword can be specified in an ON, REVERT, or SIGNAL statement. It designates an ON-unit established for all signaled conditions that are not handled by specific ON-units.
The ANYCONDITION keyword is not defined in the PL/I language. It is provided specifically for use in the OpenVMS operating system environment. For detailed information on OpenVMS condition handling, see the Kednos PL/I for OpenVMS Systems User Manual.
8.10.4.2 AREA Condition Name
The AREA condition is raised when various operations fail in relation
to areas. For example, it is raised if the extent of an area is not
large enough to contain the variable or variables allocated to it, or
if the area is incorrectly formatted.
For more information see the Kednos PL/I for OpenVMS Systems User Manual.
8.10.4.3 CONDITION Condition Name
The CONDITION condition name is used for ON-units to handle programmer-defined conditions. The value returned by the ONCODE built-in function is PLI$_CONDITION. There is no way to distinguish between multiple programmer-defined conditions if they are specified in the same ON statement.
The format of the CONDITION condition name is:
CONDITION (cond-name) |
cond-name
A name declared with the CONDITION attribute.
The CONVERSION condition name can be specified in an ON, SIGNAL, or REVERT statement to designate a CONVERSION condition or ON-unit.
PL/I signals the CONVERSION condition when the source character data in a conversion to bit-string or arithmetic data contains characters that are not valid in the specified context. In particular, the CONVERSION condition is raised when a character string is being converted and one of the following conditions is true:
The CONVERSION condition can be raised either by a non-I/O conversion, such as an explicit conversion using a built-in function or an implicit conversion generated by the compiler, or by an I/O conversion in a GET statement. For example, A = BIT('1014') would cause the CONVERSION condition to be raised, because 4 is not a valid binary digit. Likewise, a GET statement with an arithmetic target would also cause the CONVERSION condition to be raised if the characters '12K45' appeared in the input field, because 'K' is not a valid numeric character.
You can use the ONSOURCE and ONCHAR built-in functions and pseudovariables inside an ON CONVERSION ON-unit. The ONSOURCE built-in function returns the source string that caused the CONVERSION condition to be raised. The ONCHAR built-in function returns the specific character that caused the conversion to fail. You can use the ONSOURCE pseudovariable to change the value of the conversion. Likewise, you can use the ONCHAR pseudovariable to modify only the single character in error.
If the CONVERSION condition was raised during a conversion required by the GET statement, the ONFILE built-in function returns the name of the file constant inside the CONVERSION ON-unit. If the CONVERSION condition was not raised during a conversion required by the GET statement, the ONFILE built-in function returns a null string.
A normal return from a CONVERSION condition will cause the conversion to be reattempted if the ONSOURCE or ONCHAR pseudovariables have had values assigned to them. If the ONSOURCE value has not been modified, the ERROR condition is raised instead.
For example:
/* * Sample program that displays a 'quick-fix' CONVERSION * ON-unit. At the end of this program, TARGET1 contains * the value 14015, and TARGET2 contains the value '11100'B. * Note that SOURCE1 and SOURCE2 are not modified. */ MAIN: PROCEDURE OPTIONS(MAIN); DCL SOURCE1 CHARACTER(5) VARYING INITIAL('14$15'); DCL SOURCE2 CHARACTER(5) VARYING INITIAL('11q00'); DCL TARGET1 FIXED BINARY(31); DCL TARGET2 BIT(5) ALIGNED; /* * Sample 'quick-fix' CONVERSION ON-unit that replaces * erroneous lowercase q's with 1's, and all other * erroneous characters with 0's. */ ON CONVERSION BEGIN; PUT SKIP EDIT('"',ONSOURCE(),'" "',ONCHAR(),'"')((5)A); IF ONCHAR() = 'q' THEN ONCHAR() = '1'; ELSE ONCHAR() = '0'; END; /* ON */ /* * Note that the CONVERSION condition is raised for all * 3 of the following statements. */ TARGET1 = SOURCE1; TARGET1 = SOURCE1; TARGET2 = SOURCE2; PUT SKIP(2) EDIT(SOURCE1,SOURCE2)(A,X,A); PUT SKIP EDIT(TARGET1,TARGET2)(F(8),X,B(5)); END MAIN; |
The output from this program is:
"14$15" "$" "14$15" "$" "11q00" "q" 14$15 11q00 14015 11100 |
The target of the conversion is undefined when the CONVERSION condition is raised.
The retry attempted on a normal return is for the single field that was in error. Attempts to assign a string containing, for example, a comma list of values will not be used for successive data items in a GET statement.
The actual value modified by the ONSOURCE and ONCHAR pseudovariables is
a temporary value that is discarded once the conversion is complete, or
the control flow cannot return to the point of the error. This means
that invalid data stored in a character string variable will cause the
CONVERSION condition to be raised each time the value is converted, not
just the first time the conversion is attempted, regardless of
modifications to the ONSOURCE and ONCHAR pseudovariables inside the
CONVERSION ON-unit.
8.10.4.5 ENDFILE Condition Name
The ENDFILE condition name can be specified in an ON, SIGNAL, or REVERT statement to designate an end-of-file condition or ON-unit for a specific file.
PL/I signals the ENDFILE condition when a GET or READ statement attempts an input operation on a file or device after the last data item has been input.
The format of the ENDFILE condition name is:
ENDFILE (file-reference) |
file-reference
The name of a file constant or file variable for which the ENDFILE ON-unit is established. If the name of a file variable is specified, the variable must be resolved to the name of a file constant when the condition is signaled.
An ENDFILE ON-unit can be established for any input file. For any particular file, the meaning of the end-of-file condition depends on the type of device. For example, end-of-file is signaled for a terminal device when the Ctrl/Z character is read.
For a stream file, an end-of-file condition is signaled whenever a GET statement attempts to access an empty file or attempts to access a file whose last input field has been read.
For a record file, an end-of-file condition is signaled when a READ statement is executed with the file at the end-of-file position or when a read is attempted beyond the last record in the file. For example:
ON ENDFILE (RECEIPTS) EOF = '1'B; EOF = '0'B; OPEN FILE (RECEIPTS) RECORD SEQUENTIAL; READ FILE (RECEIPTS) INTO (RECORD); DO WHILE (^EOF); . . . READ FILE (RECEIPTS) INTO (RECORD); END; |
In this example, the ON statement establishes the default action to be taken when the last record in the input file has been processed: the flag EOF is set to '1'B.
An ON-unit established to handle end-of-file conditions can reference the ONFILE built-in function to determine the name of the file constant for which the condition was signaled.
If the ON-unit for the ENDFILE condition does not transfer control elsewhere in the program, control returns to the statement following the GET or READ statement that caused the condition to be signaled.
When the ENDFILE condition is signaled, it remains in effect until the file is closed. Subsequent GET or READ statements for the file cause the ENDFILE condition to be signaled repeatedly.
Previous | Next | Contents | Index |