The following example shows an example of condition handling for
PL/I.
*PROCESS MACRO;
/*Module/File Name: IBMDIVZ
/*********************************************************************/
/* */
/* PL/I Condition Handling Functions: */
/* : Establish ZERODIVIDE ON-unit */
/* : GO TO out of ZERODIVIDE ON-unit */
/* : PL/I Normal return from ZERODIVIDE ON-unit */
/* : Revert ZERODIVIDE ON-unit */
/* : PL/I System action on ZERODIVIDE condition */
/* */
/* 1. This example establishes a ZERODIVIDE ON-unit. */
/* 2. A subprogram, sdivide, is called and causes a ZERODIVIDE */
/* condition to occur. */
/* 3. The ZERODIVIDE ON-unit is entered. A GOTO out of the ON-unit */
/* is processed. The program resumes at the label */
/* "after_1st_zerodivide". */
/* 4. A new ZERODIVIDE ON-unit is established and it overrides the */
/* current established ZERODIVIDE ON-unit. */
/* 5. The subroutine sdivide is called a second time. */
/* 6. The newly established ZERODIVIDE ON-unit is entered. A GOTO */
/* is not executed, and the program resumes at the location */
/* following the instruction that caused the condition. This */
/* is the PL/I normal return action for the ZERODIVIDE condition. */
/* 7. The established ZERODIVIDE ON-unit is canceled by executing */
/* the REVERT ZERODIVIDE statement. */
/* 8. Sdivide is called a third time. Because there is no */
/* ZERODIVIDE ON-unit established, the PL/I implicit action */
/* is executed. Namely, the ERROR condition is raised and the */
/* program is terminated. */
/** */
/*********************************************************************/
CEPLCND: Proc Options(Main);
%INCLUDE CEEIBMAW;
%INCLUDE CEEIBMCT;
dcl in_zdiv_ou1 char (1), in_zdiv_ou2 char(1),fell_thru char(1);
in_zdiv_ou1 = 'N';
in_zdiv_ou2 = 'N';
fell_thru = 'N';
/****************************************************************/
/* A ZERODIVIDE ON-unit is established when control reaches the */
/* ON statement. */
/****************************************************************/
on zerodivide begin;
in_zdiv_ou1 = 'Y';
go to after_1st_zerodivide;
end;
/****************************************************************/
/* The first call to sdivide will result in the ZERODIVIDE */
/* condition being raised. The preceding established ON-unit */
/* gets control. Due to a GO TO out of the ON-unit, execution */
/* resumes immediately at label after_1st_zerodivide. This is */
/* verified by checking that the flow of control did not resume */
/* at the instruction following the ZERODIVIDE condition. */
/****************************************************************/
call sdivide;after_1st_zerodivide:
if (fell_thru = 'Y') then do;
put skip list ('Error in flow of control after'
|| ' the first call to sdivide. ');
end;
/****************************************************************/
/* A new ZERODIVIDE ON-unit is established when control */
/* reaches the following ON ZERODIVIDE statement. */
/****************************************************************/
on zerodivide begin;
in_zdiv_ou2 = 'Y';
end;
/****************************************************************/
/* Subroutine sdivide is called a second time to raise the */
/* ZERODIVIDE condition. Control enters the established */
/* ZERODIVIDE ON-unit. On exit from the preceding zerodivide */
/* ON-unit, control returns to the instruction following the */
/* divide by zero in subroutine SDIVIDE. A check is made to */
/* detect if control flowed to the instruction following the */
/* one that caused the zerodivide condition to be raised. */
/****************************************************************/
call sdivide;
if (fell_thru = 'N') then do;
put skip list
('Error in flow of control after second call to cepldiv. ');
end;
/****************************************************************/
/* The ZERODIVIDE ON-unit is canceled by action of the */
/* REVERT statement. */
/****************************************************************/
revert zerodivide;
if (in_zdiv_ou1 = 'N' | in_zdiv_ou2 = 'N') then
put skip list ('Error in flow of control to ON-units');
else do;
put skip list ('The PL/I condition handling example'
|| ' will terminate with PL/I message IBM0301');
/*************************************************************/
/* Sdivide is called for the third and final time. Because */
/* there are no established ON-units, the implicit action */
/* for ZERODIVIDE takes place. */
/*************************************************************/
call sdivide;
put skip list ('Error in flow of control after third'
|| ' call to sdivide. ');
end;
/*******************************************************************/
/* The sdivide subroutine causes a ZERODIVIDE condition. */
/*******************************************************************/
sdivide: proc;
dcl int fixed bin (15,0);
dcl int_2 fixed bin (15,0) init(5);
dcl int_3 fixed bin (15,0) init(0);
int = int_2 / int_3;
fell_thru = 'Y';
end sdivide;
End ceplcnd;