Sunteți pe pagina 1din 161

Udhayas PL/I Material 6/06/2003 Page:- 1 / 161

PL/I
Udhayas PL/I Material 6/06/2003 Page:- 2 / 161
CONTENTS
SECTION NO. TOPIC PAGE
SECTION 1 BASIC STRUCTURE OF PL/I PROGRAMS 3
SECTION 2 COMPILING UNDER MVS 9
SECTION 3 DATA TYPES AND DATA MANIPULATION 13
SECTION 4 PROCEDURES, FUNCTIONS 22
SECTION 5 SUBROUTINES AND FUNCTIONS 36
SECTION 6 CONTROL STATEMENTS 50
SECTION CONDITIONS AND ON UNITS 54
SECTION ! ARRAYS 69
SECTION 9 STRUCTURES AND PICTURES 2
SECTION 10 STORAGE CONTROL !1
SECTION 11 FILE PROCESSING 101
SECTION 11"A STREAM ORIENTED DATA TRANSMISSION 105
SECTION 11"B RECORD I/O 116
SECTION 11"C DEFINING AND USING VSAM DATA SETS 122
SECTION 12 PL/I AND MULTITAS#ING 133
SECTION 12 PREPROCESSOR FACILITIES 140
SECTION 13 STUDENT PRO$ECT %OR# 151
A&&'()*' 155
LIMITS
References :-
1) IBM PL/I for MVS and VM Programming Guide
2) IBM PL/I for MVS and VM Language Reference
3) PL/I Structured Programming ! "oan#$#%ug&es#
Udhayas PL/I Material 6/06/2003 Page:- 3 / 161
SECTION 1 BASIC STRUCTURE OF PL/I PROGRAMS
B+,-. P*/0*+1 S2'33
MYPROG:PROCEDURE OPTONS(MAN);
.
.
/' t&is is a comment '/
.
END MYPROG;
Note:-
1. MYPROG: is a label
2. Comments are encased in /* */
3. OPTONS(MAN) indicates entry point of program and must be indicated only for one
procedure in the program.
4. Columns start at 2 and end at 72.
5. Free form of writing
6. Column 2 to 72 user source code
7. Column 73 to 80 may contain program D or sequence code. t is not checked by the
compiler.
( first sim)*e )rogram
CONPL01: PROC OPTONS(MAN);
DCL BUFFER CHAR(80) NT('HELLO FROM CONSPL01');
PUT SKP LST(BUFFER);
GET LST(BUFFER);
PUT SKP LST(BUFFER);
END CONPL01;
See t&e s!stem for t&e I+L1,L )rocedure and t&e ",L to )re)are and run t&e
ao-e )rogram#
,&aracter Sets
$@#
ABCDEFGHJKLMNOPQRDSTUVWXYZ
0123456789
blank
= Equal / assignment symbol
+ Plus sign
- Minus sign
* Asterisk / multiply symbol
/ Slash / divide symbol
( ) Parenthesis
, Comma
. Point or period
' Single quotation mark or apostrophe
% Percent symbol
; Semicolon
: Colon
NOT symbol
& AND symbol
Udhayas PL/I Material 6/06/2003 Page:- 4 / 161
| OR symbol
> Greater than symbol
< Less than symbol
_ Break (underscore)
? Question mark
A combination of symbols may be used , e.g.
A**3 A power 3
A >= A greater than or equal to 3
'A' || 'B' A concatenated with B
I.+/0I1I+RS
Variable names, Procedure names, Statement Labels, keywords (e.g. PUT, GET),
File names etc.
Consists of 1 to 31 alphabetic characters made up of (A-Z,!,#,$,0-9,_).
First character must be a Alphabet.
E(+143'
MY_LABEL_1
CLENT_NAME
A procedure with OPTONS(MAN) is an external procedure . External procedure names
can be maximum of seven characters only. This is also true of a file name, which
however can go up to eight characters.
S0(0+M+/0 12RM(0
LABEL: KEYWORD STATEMENT OPTONS;
Example
READ_STMT:GET LST(A,B,C);
Free form statement which can contain as many blanks as felt necessary by programmer.
Position 1 reserved for use by O/S.
Position 2 to 72 may contain one or more PL/ statement each separated by ' ; '
GET LST (A,B); GET LST (C,D);
Alternately one statement may be continued across several lines e.g.;
GET LST
(A,B);
Position 73 to 80 may contain sequence number maintained by editor.
PL/I ,2/S0(/0S
Decimal Fixed Point 12.30 , 180, +10.23 , -1.12, 0.03
Decimal Floating Point 0.1234E+2 X.XXXXXE+XX, X.XXXXXE-XX
Exponent range 10**-78 to 10**+75
Character String 'ABCDE'
'ABCD''EF', (2)'ABCD'
Bit String Constant '11011'B, (16)'0'B
Binary Fixed Point 1011B
Binary Floating Point 0.11011011E+48B
Udhayas PL/I Material 6/06/2003 Page:- 5 / 161

LIS0 .IR+,0+. I/2
I/P30
GET LST (A,B,C,D,E); /'Reads from S4SI/ '/
GET FLE(SYSN) LST (A,B,C,D,E); /'e5)*icit form '/
OR
OR
n List Directed /O no record boundaries are considered. tems are either separated by a
blank or a comma
GET LST (A,B) COPY; /' additiona**! co)ies t&e data to S4SPRI/0 '/
Example of nput 12.90,.04E+3,'ABCD','1010'B
Example
DECLARE DATA1 CHAR(12);
GET LST (DATA1);
230P30
PUT LST (50,'ABC',123,127);
PUT LST (23,86,87);
PUT LST (A,5,C*D); /' note use of an e5)ression ,'. '/
PUT PAGE LST ('ABC'); /' (B, )rints in ne5t )age '/
PUT SKP LST(123); /' S6i) one *ine efore )rint '/
PUT SKP(0) LST (123); /' Print 7it&out s)acing '/
PUT SKP(2) LST (123); /' S6i) t7o *ines efore )rint '/
PUT PAGE LNE (10) LST (123); /' S6i) to *ine 18 of ne7 )age and )rint '/
PUT PAGE LST ((100)'-'); /' ne7 )age and 188 das&es '/
100 90 80 70 90
90
70
80
90
100
100,90,80,70,90
1 25 49 3 9 121
50 ABC 123 127 23
86 87
Udhayas PL/I Material 6/06/2003 Page:- 6 / 161
PR2GR(M S0R3,03R+
MNPROC: PROCEDURE OPTONS(MAN);
.
.
CALL SUBPROC_1;
CALL SUBPROC_2;
.
RETURN;
SUBPROC_1: PROCEDURE;
.
.
END SUBPROC_1;
SUBPROC_2: PROCEDURE;
.
.
END SUBPROC_2;
END MNPROC;
E(+143' /5 ,-143' &',6'7 4*/.'7)*'
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL FELD1 FXED DECMAL(7,2);
DCL FELD2 FXED DECMAL(7,2);
GET DATA (FELD1,FELD2);
PUT SKP LST(SUM(FELD1,FELD2));
SUM:PROCEDURE (A,B) RETURNS(FXED DECMAL(7,2));
DCL A FXED DECMAL(7,2);
DCL B FXED DECMAL(7,2);
RETURN (A+B);
END SUM;
END MYPROG;
/*
//GO.SYSN DD *
FELD2=1.23,FELD1=3.45;
/*
//
E(+143' 6/ 7'1/&,6*+6' ,./4' /5 8+*-+93',
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL FELD1 FXED DECMAL(7,2);
DCL FELD2 FXED DECMAL(7,2);
DCL SUM FXED DECMAL(7,2);
GET DATA (FELD1,FELD2);
CALL ADD;
PUT SKP LST(SUM);
Udhayas PL/I Material 6/06/2003 Page:- 7 / 161
PUT SKP DATA;
/: P*/.'7)*' ADD :/
ADD:PROCEDURE;
SUM=A+B;
END ADD;
/: E&7 /5 P*/.'7)*' ADD :/
END MYPROG;
/*
//GO.SYSN DD *
FELD2=1.23,FELD1=3.45;
/*
//
Udhayas PL/I Material 6/06/2003 Page:- 8 / 161
SECTION 2 COMPILING UNDER MVS
S'' 62' C+6+3/0)'7 P*/.'7)*', 9'3/; -& 62' ,<,6'1.
1. EL1C Compile only
2. EL1CL Compile and Link Edit
3. EL1CLG Compile, Link-edit and run
4. EL1CG Compile load and run
DD &+1',
PL.SYSN SOURCE
PL.SYSLB COPY BOOKS
PL.STEPLB LOADLB WHERE COMPLER RESDES
PL.SYSPRNT COMPLATON LSTNG
PL.SYSLN COMPLED OBJECT CODE
PL.SYSUT1 COMPLER WORK FLE
LKED.STEPLB LOADLB WHERE LNKAGE EDTOR RESDES
LKED.SYSLN PRMARY NPUT FOR LNKAGE EDTOR
LKED.SYSLMOD OUTPUT OF LNKAGE EDTOR, THE LOAD MODULE
LKED.SYSN SECONDARY NPUT FOR LNKAGE EDTOR
LKED.SYSLB LNK LBRARY OF PRECOMPLED OBJECT CODE
LKED.SYSUT1 LNKAGE EDTOR WORK FLE
LKED.SYSPRNT LNKAGE EDTOR LSTNG
INVOCATION %IT= INLINE SOURCE
//MYPROG JOB
//STEP1 EXEC EL1CLG,REGON.PL=1M
//PL.SYSLB DD DSN=MY.SOURCE.LB,DSP=SHR
//PL.SYSN DD *
.
Put your source here
.
/*
//
INVOCATION %IT= SOURCE IN A PDS MEMBER
//MYPROG JOB
//STEP1 EXEC EL1CLG,REGON.PL=1M
//PL.SYSLB DD DSN=MY.SOURCE.LB,DSP=SHR
//PL.SYSN DD DSN=MY.SOURCE.LB(PROG1),DSP=SHR
//
E>AMPLE
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL FELD CHAR(20) NT('HELLO WORLD');
PUT LST (FELD);
END MYPROG;
//
E>AMPLE OF SEPARATE COMPILATIONS IN ONE $OB
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
Udhayas PL/I Material 6/06/2003 Page:- 9 / 161
//STEP1 EXEC PROC=EL1C,REGON.PL=1M
//PL.SYSN DD *
SUM: PROCEDURE(A,B) RETURNS(FXED DEC(3));
DCL (A,B) FXED DEC(3);
RETURN(A+B);
END SUM;
/*
//STEP2 EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL SUM ENTRY(FXED DEC(3),FXED DEC(3)) RETURNS(FXED DEC(3));
DCL (A,B) FXED DEC(3);
A=2;B=3;
PUT LST(SUM(A,B));
END MYPROG;
//
E>AMPLE OF SEPARATE COMPILATIONS IN SEPARATE $OBS?PART A)
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1C
//PL.SYSN DD *
SUM: PROCEDURE (A,B);
DCL (A,B) FXED DECMAL(6,2);
DCL RESULT FXED DECMAL(6,2) EXTERNAL;
RESULT=A+B;
END SUM;
/*
//PL.SYSLN DD DSN=USERAA.PLCLASS.OBJ(SUM),DSP=(NEW,KEEP),
// UNT=SYSDA,SPACE=(TRK,(1,,1))
//
?PART B)
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL SUM ENTRY(FXED DECMAL(6,2),FXED DECMAL(6,2));
DCL RESULT FXED DECMAL(6,2) EXTERNAL;
DCL X FXED DECMAL(6,2);
DCL Y FXED DECMAL(6,2);
X=123.45;
Y=111.11;
CALL SUM(X,Y);
PUT SKP EDT('RESULT S:',RESULT)(A,F(6,2));
END MYPROG;
/*
//LKED.SYSLB DD DSN=USERAA.PLCLASS.OBJ(SUM),DSP=OLD
// DD DSN=CEE.SCEELKED,DSP=SHR
//
E>AMPLE OF SEPARATE COMPILATIONS AND CREATION OF A LOAD MODULE
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CL
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL SUM ENTRY(FXED DECMAL(6,2),FXED DECMAL(6,2));
Udhayas PL/I Material 6/06/2003 Page:- 10 / 161
DCL RESULT FXED DECMAL(6,2) EXTERNAL;
DCL X FXED DECMAL(6,2);
DCL Y FXED DECMAL(6,2);
X=123.45;
Y=111.11;
CALL SUM(X,Y);
PUT SKP EDT('RESULT S:',RESULT)(A,F(6,2));
END MYPROG;
/*
//LKED.SYSLB DD DSN=USERAA.PLCLASS.OBJ(SUM),DSP=OLD
// DD DSN=CEE.SCEELKED,DSP=SHR
//LKED.SYSLMOD DD DSN=USERAA.ASMCLASS.LOADLB(PL252),DSP=OLD
//

E>AMPLE OF RUNNING A PREVIOUSLY CREATED LOAD MODULE
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PGM=PL252
//STEPLB DD DSN=USERAA.ASMCLASS.LOADLB,DSP=SHR
//SYSPRNT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//
SOME IMPORTANT COMPILER OPTIONS
ESD | NOESD Listing of external symbol dictionary
FLAG() List all messages
FLAG(W) List all except information messages
FLAG(E) list all except warning and information messages
FLAG(S) list only severe error messages
DECK | NODECK Deck specifies that the object module is written in card image
form onto SYSPCH
[NO]AGGREGATE controls listing of lengths of arrays and structures in program
listing
[NO]ATTRBUTES (FULL | SHORT)
controls listing of all source program identifiers with their
attributes in the program listing. n SHORT un-referenced
identifiers are omitted.
NOT(9not c&aracter9) Defines new NOT character
[NO]GONUMBER controls whether the compiler produces code which will give line
number from the source program to be included in run time
messages
[NO]OBJECT controls whether the compiler produces a object module on
SYSLN
[NO]OPTONS controls whether the compiler prints the options in effect in the
program listing
[NO]SOURCE controls whether the compiler lists the source program in the
program listing.
SYSTEM (MVS|CMS|TSO|CCS..)
Udhayas PL/I Material 6/06/2003 Page:- 11 / 161
Specifies the format in which parameters are passed to the main
PL procedure (this is system dependent)
[NO]XREF(FULL|SHORT) Controls inclusion of cross reference table in the listing
These options can be set in the source by the
%PROCESS option,option,...;
or
*PROCESS option,option,..;
Udhayas PL/I Material 6/06/2003 Page:- 12 / 161
SECTION 3 DATA TYPES AND DATA MANIPULATION
PL/ Data Type BM Data Format Storage Basic Usage
FXED DECMAL Packed Decimal 4 bits / decimal Arithmetic
digit, sign Operations
FXED BNARY Fixed Point Halfword or Arithmetic
Fullword Operations
FLOAT DECMAL Floating Point 32 | 64 | 128 Bits Arithmetic
FLOAT BNARY Operations
PCTURE Zoned Decimal 8 bits per digit Numeric
Character
CHARACTER Character 8 bits per Char Alphabetic
Character
BT Bit One byte min Logical
Data
DECLARE PRCE DECMAL FXED(5,2);
Precision of five digits of which two
are decimal fraction
Scale Attribute
Base attribute
dentifier (variable)
PL/ Keyword
DECLARE PRCE FLOAT DECMAL(6);
PRCE = 3.12345
DECLARE PRCE DECMAL FXED(6,2);
PRCE = 1234.56;
DECLARE PRCE FXED BNARY(15); /' 1: its ; sign it '/
PRCE = 123456;
DECLARE PRCE FXED BNARY(31); /' 31 its ; sign it '/
PRCE = 123456;
DECLARE PRCE FXED BNARY(15,2);/' 1: its ; sign# im)*ied 2 its fraction
1111111111111#11 fraction ma5 #<: decima*'/
MODE ATTRIBUTE
DCL COMPLEX_VAR FLOAT DECMAL (6) COMPLEX;
Both Real and imaginary component have FLOAT DECMAL (6) base Scale and
Precision.
Partial Declarations possible
DCL A DECMAL; /' on*! ase defined '/
/' sca*e and )recision defau*t to 1L2(0 =>) '/
DCL A BNARY /' on*! ase defined '/
/'sca*e and )recision defau*t to 1L2(0=21) '/
DCL A FXED; /' on*! sca*e defined '/
/' ase and )recision defau*t to .+,IM(L =:?8)'/
DCL A FLOAT /' on*! sca*e defined '/
/' ase and )recision defau*t to .+,IM(L =>) '/
Udhayas PL/I Material 6/06/2003 Page:- 13 / 161
Other attributes default to the table below
D'.3+*'7 A66*-9)6', D'5+)36 A66*-9)6',
DECMAL FXED (5,0)
DECMAL FLOAT (6)
BNARY FXED (15,0)
BNARY FLOAT (21)
DECMAL FLOAT (6)
BNARY FLOAT (21)
FXED DECMAL (5,0)
FLOAT DECMAL (6)
None, Variable begins with -N BNARY FXED (15)
None, Variable begins with A-H,O-Z,@,#,$ DECMAL FLOAT (6)
Bit .ata
DCL END_OF_FLE BT(1);
DCL NO BT(1) NT('0'B);
DCL YES BT(1) NT('1'B);
.
.
END_OF_FLE = NO;
ON ENDFLE(SYSN) END_OF_FLE = YES;
DO WHLE( END_OF_FLE);
.
.
END;
,&aracter .ata
DCL CHAR_DATA CHAR(20) NT('ABCDEFGH');
/' Left "ustified and )added on rig&t 7it& *an6s '/
Var!ing attriute
DCL CHAR_DATA CHAR(20) VARYNG;
/' 0&is is a t7o !te *engt& fie*d fo**o7ed '/
/' ! a 28 !te fie*d for data '/
CHAR_DATA = 'MY NAME';
CHAR_DATA =''; /' nu** string '/
DCL BT_DATA BT(8) VARYNG;
.efined attriute
DCL A CHAR(20);
DCL B CHAR(5) DEF A; /' o-er*a! on ( '/
DCL C CHAR(10) DEF A; /' o-er*a! on ( '/
DCL D CHAR(10) DEF C; /' +RR2R @? not a**o7ed '/
Permitted Redifines
Base dentifier Defined tem
Coded Arithmetic variable coded arithmetic variable with same BASE, SCALE,
PRECSON
Character String Character string or Bit String
Bit String Character string or Bit string
Position (ttriute
DCL CHAR_LST CHAR(20);
DCL A CHAR(10) DEFNED CHAR_LST;
Udhayas PL/I Material 6/06/2003 Page:- 14 / 161
/' o-er*a!s first ten )ositions '/
DCL B CHAR(10) DEFNED CHAR_LST POSTON(10);
/' o-er*a!s ne5t 18 )ositions '/
Initia* (ttriute
Use this to initialise variables
DCL A FXED DECMAL (7,2) NTAL(24.50);
DCL B CHAR(10) NT((10)'A');
DCL C BT(2) NT('00'B);
DCL D FXED BNARY(15) NT (0);
same effect can also be achieved by an assignment statement at lower code efficiency.
PL/I .ata (ttriutes
FI>ED DECIMAL ( Also represented as FXED, DECMAL FXED)
Data Format Packed Decimal
Type of Data Coded arithmetic
Default Precision 5 Decimal Digits S99,999
Maximum Precision 15 Decimal digits S999,999,999,999,999
Used for monetary calculations
Example:
DCL A FXED DECMAL (5,2) NT (123.45);
FI>ED BINARY
Data Format Fixed point signed binary (Halfword or Fullword)
Type of Data Coded arithmetic
Default Precision 15 Bits plus sign bit (Decimal 32,767)
Maximum Precision 31 Bits plus sign bit (Decimal 2,147,483,647)
Used for fast computations, usually for integers
Variables beginning -N default to fixed Binary unless explicitly defined otherwise
Can be used for representing fractions, but fractions do not have exact representation
in Binary .
Example:
DCL A FXED BNARY (31) NT(2147483647);
FLOAT DECIMAL (Also represented as DECMAL)
Data Format Floating Point, 32bit, 64 bit or 128 bit representation
Type of data Coded Arithmetic
Default precision 6 Decimal digits
Maximum precision 16 Decimal digits
Range of Exponent 10**-78 to 10**+75
Examples:
DCL A FLOAT DEC(6);
DCL A DEC (6); /' .efau*ts to 1L2(0 '/
DCL A FLOAT DEC(6) NT(6.0E+12);
Note that in storage there is no difference between FLOAT BINARY and FLOAT
DECIMAL data representation The! are both represented as E" D and L for#at f$oating
point data" depending on the precision

BIT
Data Format bit (8 bits per byte)
Type of Data Logical
Default length None
Maximum Length 8000 bits for constants
32767 bits for variables
+5am)*es
DCL FLAGS BT(8) NT('11100001'B);
DCL FLAGS BT(32) NT((32)'0'B);
Udhayas PL/I Material 6/06/2003 Page:- 15 / 161
Note that bit strings are (like character strings ) assigned left to right. f a smaller bit string
is assigned to a larger string, padding with binary zeroes takes place on the vacant right
positions. f the assigned bit string is larger than the receiving field then truncation takes
place on the right.
C=ARACTER
Data Format Character
Type of data Alphanumeric (anything goes)
Default length None
Maximum Length 1000 characters for constants
32767 characters for variables
On assignment data is left aligned and vacant positions on right are padded with spaces.
f the receiving field is smaller, then truncation takes place on the right.
+5am)*e:
DCL A CHAR(20) NT('ABCDEF');
DCL A CHAR(10) NT((10)' ');
DATA DECLARATION
E(43-.-6 D'.3+*+6-/&
The scope of an explicit declaration of a name is that block to which the declaration is
internal, including all contained blocks, except those blocks (and any blocks contained
within them) to which another explicit declaration of the same name is internal.

P: PROC;
DCL A, B;

Q: PROC;
DCL B, C; /' of )roc ) is no7 &idden ! t&is '/
/' a of )roc ) is sti** -isi*e '/
/' c of )roc A is -isi*e '/
R: PROC
DCL C, D /' c of )roc A is no7 &idden ! t&is c'/
/' a of )roc ) is sti** -isi*e '/
/' of )roc A is sti** -isi*e '/
/' d of )roc r is -isi*e '/
END R;
/' no7 c of )roc A is -isi*e '/
/' of )roc A is -isi*e '/
/' a of )roc ) is -isi*e '/
END Q;
/' /o7 B of PR2, P is -isi*e '/
/' ( of PR2, P is -isi*e '/
END P;
DECLARE S6+6'1'&6
The DECLARE statement specifies attributes of a name and its position determines the
scope of the declaration of the name.
DECLARE [*e-e*] name [attriute] , [*e-e*] name [attriute]
F+.6/*-&0 /5 A66*-9)6',
Attributes common to several names can be factored to eliminate repeated specification
of the same attribute.
DECLARE (A,B,C,D) BNARY FXED (31);
Udhayas PL/I Material 6/06/2003 Page:- 16 / 161
DECLARE (E DECMAL(6,5), F CHARACTER(10)) STATC;
DECLARE ((A,B) FXED(10),C FLOAT(5)) EXTERNAL;
I143-.-6 D'.3+*+6-/& /5 N+1',
f a name appears in a program and is not explicitly declared, it is implicitly declared. The
scope of an implicit declaration is determined as if the name were declared in a
DECLARE statement immediately following the PROCEDURE statement of the external
procedure in which the name is used.
mplicit declaration has the same effect as if the name were declared in the external
procedure, even when all the occurrences of the name are internal to a block (called B,
for example) that is contained in the external procedure. Consequently, the name is
known throughout the entire external procedure, except for any blocks in which the name
is explicitly declared. t is as if block B has inherited the declaration from the containing
external procedure.
Some attributes for a name declared implicitly can be determined from the context in
which the name appears. These cases, called contextual declarations, are:
A name that appears in a CALL statement, in a CALL option, or is followed by an
argument list is given the BULTN and NTERNAL attributes.
A name that appears in a FLE or COPY option, or a name that appears in an ON,
SGNAL statement for a condition that requires a file name is given a FLE attribute.
A name that appears in an ON CONDTON or SGNAL CONDTON statement is
given the CONDTON attribute.
A name that appears in the BASED attribute, in a SET option, or on the left-hand side
of a locator qualification symbol is given the PONTER attribute.
A name that appears in an N option, or in the OFFSET attribute, is given the AREA
attribute.
E(+143', /5 ./&6'(6)+3 7'.3+*+6-/& +*'@
READ FLE (PREQ) NTO (Q);
ALLOCATE X N (S);
n these statements, PREQ is given the FLE attribute, and S is given the AREA attribute.
Udhayas PL/I Material 6/06/2003 Page:- 17 / 161
S./4', /5 D'.3+*+6-/&,
P Q Q R R' S
A: PROCEDURE;
DECLARE P, Q;
B: PROCEDURE;
DECLARE Q;
R = Q;
C: BEGN;
DECLARE R;
DO = 1 TO 10;
.
END;
END C;
END B;
D: PROCEDURE;
DECLARE S;
END D;
END A;

P is declared in the block A and known throughout A since it is not re-declared.
Q is declared in block A, and re-declared in block B. The scope of the first declaration
of Q is all of A except B; the scope of the second declaration of Q is block B only.
R is declared in block C, but a reference to R is also made in block B. The reference
to R in block B results in an implicit declaration of R in A, the external procedure.
Therefore, two separate names (R and R`) with different scopes exist. The scope of
the explicitly declared R is block C; the scope of the implicitly declared R is all of A
except block C.
is referred to in block C. This results in an implicit declaration in the external
procedure A. As a result, this declaration applies to all of A, including the contained
procedures B, C, and D.
S is explicitly declared in procedure D an is known only within D.
INTERNAL +&7 E>TERNAL A66*-9)6',
NTERNAL specifies that the name can be known only in the declaring block. Any other
explicit declaration of that name refers to a new object with a different, non overlapping
scope.
A name with the EXTERNAL attribute can be declared more than once, either in different
external procedures or within blocks contained in external procedures. All declarations of
the same name with the EXTERNAL attribute refer to the same data.
EXTERNAL is the default for controlled variables, file constants, entry constants,
Because external declarations for the same name all refer to the same data, they must all
result in the same set of attributes.
L+&0)+0' S4'.-5-'7 D'5+)36,
Udhayas PL/I Material 6/06/2003 Page:- 18 / 161
When a problem-data name has not been declared with a data type or when the
RETURNS option is omitted from a function procedure, the default is coded arithmetic
problem data.
If mode? sca*e? and ase are not s)ecified ! a .+,L(R+ or .+1(3L0 statement?
or ! a R+03R/S o)tion? -aria*es 7it& names eginning 7it& an! of t&e *etters I
t&roug& / are gi-en t&e attriutes R+(L 1IB+. BI/(R4 =1:?8)? and t&ose 7it&
names eginning 7it& an! ot&er a*)&aetic c&aracter are gi-en t&e attriutes
R+(L 1L2(0 .+,IM(L =>)#
A scaling factor in the precision attribute constitutes an explicit declaration of FXED.
If mode? sca*e? or ase is s)ecified ! a .+,L(R+ or .+1(3L0 statement? or ! a
R+03R/S o)tion? t&e remaining attriutes are com)*eted from t&e fo**o7ing *ist of
defau*ts:
0&e defau*t ase is .+,IM(L#
0&e defau*t sca*e is 1L2(0#
0&e defau*t mode is R+(L#
.efau*t )recision is t&en com)*eted from t&e fo**o7ing *ist:
=:?8) for .+,IM(L 1IB+.
=1:?8) for BI/(R4 1IB+.
=>) for .+,IM(L 1L2(0
=21) for BI/(R4 1L2(0
For example the statement:
DCL X BNARY (15)
/' no sca*e s)ecified #gets t&e attriutes R+(L and 1L2(0 '/
DCL X BNARY (15,0)
/' sca*e s)ecified gets t&e attriutes R+(L and 1IB+.# '/
f no parameter descriptor list is given, the default is that the argument attributes match
the parameter attributes.
DEFAULT S6+6'1'&6
The DEFAULT statement specifies data-attribute defaults (when attribute sets are not
complete). Any attributes not applied by the DEFAULT statement for any partially
complete explicit or contextual declarations, and for implicit declarations, are supplied by
language-specified defaults.
Abbreviation: DFT RANGE(letter)
Specifies that the defaults apply to names that begin with the name(s) specified. Letter
can be any letter in the English alphabet.
E(+143'@
RANGE (ABC)
applies to these names:
ABC
ABCD
ABCDE
but not to:
Udhayas PL/I Material 6/06/2003 Page:- 19 / 161
ABD
ACB
AB
A
Hence a single letter in the range-specification applies to all names that start with that
letter.
RANGE (letter : letter)
Specifies that the defaults apply to names with initial letters that either correspond to the
two letters specified, or to any letters between the two in alphabetic sequence.
RANGE(*)
Specifies all names in the scope of the DEFAULT statement.
E(+143'@
DEFAULT RANGE (A:C) VALUE (FXED DEC(10),FLOAT DEC(14),AREA(2000));
DECLARE B FXED DECMAL, C FLOAT DECMAL, A AREA;
These statements are equivalent to:
DECLARE B FXED DECMAL (10), C FLOAT DECMAL(14), A AREA(2000);
E(+143'@
DFT RANGE(:N) FXED BNARY VALUE(FXED BNARY(15));
DFT RANGE(A:H,O:Z) FLOAT DECMAL VALUE(FLOAT DECMAL(6));
D+6+ C/&8'*,-/&,
When mixed data types appear in an arithmetic expression, PL/ causes the following
conversions to take place to make the expression have all tokens of the same data type.
1. f base of the data item differs, DECMAL is converted to BNARY
2. f the scale differs FXED is converted to FLOAT
3. f CHARACTER and BT are involved, then BT is converted to CHARACTER a Bit 1
becoming character 1, a zero becoming character 0.
Va*ues o)erated on ,on-ersion ,omments
DCL A FXED DEC, A is converted scale is different
B FLOAT DEC; to FLOAT FXED -> FLOAT
Y = A + B;
DCL C FXED DEC, C is converted base is different
D FXED BN; to FXED BN DEC -> BN
= C*D;
DCL E FXED DEC, E is converted base and scale are
F FLOAT BN; to FLOAT BN different
R = E/F; FXED -> FLOAT
DECMAL -> BNARY
DCL K CHAR(13), J is converted to BT -> CHARACTER
CHAR(5), CHAR(8)
Udhayas PL/I Material 6/06/2003 Page:- 20 / 161
J BT(8);
K = || J;
(ssignment Statements
DCL A FXED DECMAL(5,2) NT(1.12);
DCL B FXED DECMAL(5,2) NT(2.32);
DCL C FXED DECMAL(5,2);
C = A+B; /' note t&at assignment is t&e C sign '/
A,B,C = 0; /' a** t&ree -aria*es assigned -a*ue 8 '/
C = A*3D /' Rig&t &and side is an e5)ression '/
Note that the assigned term can be a variable or an expression ( of constants /
constants and variables.
(rit&metic 2)erations
** Exponentiation
* Multiplication
/ Division
+ Addition
- Subtraction
Rule 1: Order of resolution in an arithmetic expression is Exponentiation first going right
to left. Next moving from left to right multiplication or division, whichever appears
first. Then addition or subtraction , whichever appears first, moving from left to
right.
Rule 2: f parenthesis are used in an expression, the innermost expression within the
parenthesis is resolved first, in consonance with Rule 1, and the resolution
moves outwards. Example A * (B+C)
/' reso*-e B;, first and mu*ti)*! t&e resu*t ! ( '/
Rule 3: Prefix operators are performed before infix operators
Example A = B**-A
/' /egate ( first# 0&en raise B to t&e )o7er of ( '/
Rule 4: Any expression or element may be raised to a power which can be a negative
value Example A**2, (A+5)**3, A**-B
Rule 5: f two or more operators with the highest priority appear in the same expression,
the order of priority is from right to left
Example -A**2 /' +5)onentiation first? /egation ne5t '/
A**B**C /' +-a*uate B'', first#0&en raise ( to t&e resu*tant
)o7er'/
2)erator Precedence
Le-e* 2)erator
1 prefix +, prefix -, ** ,
2 *, /
3 infix +, infix -
4 ||
5 >=,>,=,<, =,...
6 &
7 |
Udhayas PL/I Material 6/06/2003 Page:- 21 / 161
SECTION 4 PROCEDURES, FUNCTIONS

Bui*t In 1unctions
Declaration required
DCL function-name BULTN;
Example
DCL DATE BULTN;
(rit&metic Bui*t-in 1unctions
ROUND?+*01,+*02A
arg1 is the value to be rounded, can be an element, array element or array name arg2
specifies the digit position where rounding is to occur. f positive, rounding occurs nth
digit to right of decimal point. f zero, rounding occurs at the first digit left of the decimal
point. f negative rounding occurs at n+1 digit to the left of the decimal point.
Example:
DCL X FXED DECMAL(7,4);
DCL Y FXED DECMAL(7,4);
X = 123.7261
Y = ROUND(X,3); /' 4 is 123#<2>8'/
Y = ROUND(X,2); /' 4 is 123#<388'/
Y = ROUND(X,0); /' 4 is 12E#8888'/
Y = ROUND(X,-1); /' 4 is 128#8888'/
MOD?+*01,+*02A
The value returned is the remainder of the division of arg1 by arg2.
COS?+*01A, SIN?+*01A, LOG?+*01A '6.. +*' +8+-3+93'
.ate and 0ime ui*t in functions
DCL DATEVAR CHAR(6);
DCL TMEVAR CHAR(9);
DCL DATE BULTN;
DCL TME BULTN;
DATEVAR = DATE; /' 44MM.. '/
TMEVAR = TME; /' %%MMSS000 '/
String &and*ing functions
SUBSTR?+*01,I,$A
Returns a sub-string from arg1 (character, Bit or Picture attribute)starting at position and
J characters long. Arg1 can be a constant, variable name or an expression. t may also
be specified as a LST item in a GET or PUT statement.
Pseudo-aria*es
s a built in function appearing as a receiving field.
Example:
DCL DATE CHAR(6) NT('980215');
SUBSTR(DATE,1,2)='99'; /' c&ange 44 to FF '/
GET LST (SUBSTR(DATE,3,4)); /' get MM.. from S4SI/ '/
BIT
Converts coded arithmetic data item or Character string to a Bit string
DCL A BT(32);
DCL B FXED BNARY(31);
A = BT(B); /' con-erts into a 31 ; sign it string '/
Udhayas PL/I Material 6/06/2003 Page:- 22 / 161
A = BT(B,15); /' ( contains a it string of *engt& 1: '/
C=AR
Converts a given value to Character form
DCL A FXED DEC(5) NT(175);
DCL B CHAR(5);
B = CHAR(A); /' B contains 91<:9 '/
B = CHAR(A,2); /'B contains 91<9 '/
LENGT=
Returns length of character or Bit string. Useful in finding length of character strings with
the VARYNG attribute.
DCL A CHAR(30) VARYNG;
DCL A_LENGTH FXED BNARY(15);
A = 'ABCDEF';
A_LENGTH = LENGTH(A); /' (GL+/G0% &as a -a*ue of > '/
INDE>
Searches a given string for a specified BT or CHAR sub-string. f found returns the left
most occurrence of the sub-string else returns zero. Arguments can be bit string,
character string, binary coded arithmetic field, decimal picture or array names. f both
arguments are not bit strings, both arguments are converted into character strings, else
the operation is performed on bit strings.
DCL SENTENCE CHAR(40);
SENTENCE = 'THE DOG CHASED THE TAC';
START = NDEX(SENTENCE,'TAC'); /' Locate 90(,9 '/
SUBSTR(SENTENCE,START,3) = 'CAT';/' and ,&ange it to 9,(09 '/
REPEAT
REPEAT(string,n)
Repeats string n times.
DCL SENTENCE CHAR(40);
SENTENCE = (10)'ABCD' /'S+/0+/,+ contains 9(B,.(B,.H#9 '/
SENTENCE = REPEAT('WALLA',2); /' S+/0+/,+ is 9I(LL(I(LL(9 '/
TRANSLATE
TRANSLATE(Source_string, Replacement_string, Position_string)
DCL SOURCE CHARACTER(5);
DCL TARGET CHARACTER(5);
DCL NEW_VALUE CHAR(1);
DCL OLD_VALUE CHAR(1);
SOURCE = '+1234';
NEW_VALUE = ' ';
OLD_VALUE = '+';
TARGET = TRANSLATE(SOURCE,NEW_VALUE,OLD_VALUE);
/' 0(RG+0 is no7 9 123E9 '/
PROGRAM ORGANISATION
Programs
A PL/ program consists of one or more external procedures. Each procedure can
contain other procedures, begin-blocks, or both.
Program (cti-ation
A PL/ program becomes active when a calling program invokes the main procedure.
Udhayas PL/I Material 6/06/2003 Page:- 23 / 161
CONTRL: PROCEDURE OPTONS(MAN);
CALL A;
CALL B;
CALL C;
END CONTRL;
B*oc6s
A block is a delimited sequence of statements that determines the scope of the
declaration of names declared within it, limits the allocation of automatic variables,
and determines the scope of DEFAULT statements.
Two kinds of blocks: 4*/.'7)*' 93/.B, and 9'0-&"93/.B,.
Begin-blocks and procedures can contain declarations that are treated as local
definitions of names.
These declarations are not known outside their own block.
Automatic storage is allocated upon entry to the block where the storage is
declared. The storage is freed upon exit from the block.
B*oc6 (cti-ation
Except for the main procedure, external and internal procedures contained in a
program are activated only when they are invoked by a procedure reference.
Begin-blocks are activated through sequential flow or as ON-units.
.uring B*oc6 (cti-ation@
Expressions for automatic and defined variables are evaluated for dimension
bounds, area sizes, string lengths, and initial values (including iteration factors).
Storage is allocated for automatic variables and initialisation, if specified.
Currently active blocks known to the procedure are identified, so that the correct
generations of automatic storage are accessible, and the correct ON-units can be
entered.
Storage is allocated for any dummy arguments that might be created in this block.
B*oc6 0ermination
A procedure is terminated when control passes back to the invoking block or to
some other active block, by means other than a procedure reference. Similarly, a
begin-block is terminated when control passes to another active block, by means
other than a procedure reference.
.uring *oc6 termination@
The ON-unit environment is re-established as it existed before the block was
activated.
Storage for all automatic variables allocated in the block is released.
Interna* and +5terna* B*oc6s
There can be no overlapping of blocks;
A procedure that is contained within another block is called an internal procedure. A
procedure that is not contained within another block is called an external procedure.
Udhayas PL/I Material 6/06/2003 Page:- 24 / 161
Begin-blocks are always internal;
Udhayas PL/I Material 6/06/2003 Page:- 25 / 161
A: PROCEDURE;
.
.
B: BEGN;
.
.
END B;
.
.
C: PROCEDURE;
.
.
D: BEGN;
.
.
E: PROCEDURE;
.
.
END E;
.
.
END D;
END C;
.
.
END A;
Procedures
A procedure is a sequence of statements delimited by a PROCEDURE statements and a
corresponding END statement.
For example:
NAME: A: PROCEDURE;
.
.
.
END NAME;
The leftmost label of the PROCEDURE statement represents the primary entry point of
the procedure. Optionally, additional labels define secondary entry points. The ENTRY
statement also defines secondary entry points.
B: ENTRY;
PR2,+.3R+ and +/0R4 Statements
A procedure (subroutine or function) can have one or more entry points. The primary
entry point to a procedure is established by the leftmost label of the PROCEDURE
statement. Secondary entry points to a procedure are established by additional labels of
the PROCEDURE statement and by the ENTRY statement.
A: : PROCEDURE (X);
is the sa#e as%
A: PROCEDURE (X);
Udhayas PL/I Material 6/06/2003 Page:- 26 / 161
: ENTRY (X);
When an EXTERNAL ENTRY is declared without a parameter descriptor list, matching
between parameters and arguments does not occur. Therefore, no diagnostic message is
issued if any arguments are specified in a CALL to such an entry point.
'(+143'@
DECLARE X ENTRY EXTERNAL;
CALL X(parameter);
F/*1+6 5/* PROCEDURE ,6+6'1'&6
entr!-constant: PROCEDURE ()arameter? )arameter,.)
RETURNS(attriute) OPTONS (2)tions-*ist)
F/*1+6 5/* ENTRY ,6+6'1'&6
entr!-constant: ENTRY ()arameter? )arameter,.)
RETURNS(attriute) OPTONS (2)tions-*ist)
Im)ortant 2P0I2/S are
BYADDR or BYVALUE
Specify how all parameters defined for this procedure entry are passed. f you specify
BYADDR, parameters are received by address. f you specify BYVALUE, parameters are
received by value. Any change to a parameter that is being passed by value is not
reflected in the argument passed by the caller. BYADDR is the default
BYVALUE can be specified for EXTERNAL PROCEDURE statements, but it cannot be
specified for internal procedures or ENTRY statements. Additionally BYVALUE entry
points can only have scalar arguments and return values that are either PONTER or
REAL FXED BNARY(31,0)
BYADDR is the default.
E(+143'@
EXTR: PROCEDURE(A,B) OPTONS (BYADDR);
DCL (A,B) FLOAT;
MAN The PL/ procedure is the initial procedure of a PL/ program. The operating
system control program invokes it as the first step in the execution of that
program.
COBOL Specifies that the designated entry point is in a COBOL subprogram.

ASSEMBLER specifies that the designated entry point is in an assembler subroutine.
PL/ passes arguments directly to the subroutine, rather than via PL/ control
blocks. Entries with the ASSEMBLER option are subject to the following rules:

They cannot be used as a function reference.
Any number of arguments can be passed in the CALL statement invoking the
entry, from zero up to the number specified by the entry declaration, but
intervening arguments cannot be omitted.
Udhayas PL/I Material 6/06/2003 Page:- 27 / 161
Parameter (ttriutes
Because a parameter has no associated storage within the invoked procedure, it cannot
be declared to have any of the storage attributes STATC, AUTOMATC, BASED, or
DEFNED. However, it can be declared to have the CONTROLLED attribute.
,ontro**ed Parameter Bounds? Lengt&s? and SiJes
The bounds, length, or size of a controlled parameter can be specified in a DECLARE
statement either by asterisks or by element expressions.
MAN: PROCEDURE OPTONS(MAN) ;
DECLARE (A(20), B(30), C(100),
D(100)) CONTROLLED,
NAME CHARACTER (20),
FXED (3,0) ;
DECLARE (SUB1,SUB2) ENTRY;
ALLOCATE A,B;
CALL SUB1(A,B) ;
FREE A,B; /: F*'', A +&7 B +33/.+6'7 -& SUB1 :/
FREE A,B; /: F*'', A +&7 B +33/.+6'7 -& MAIN :/
GET LST (NAME,) ; /:G'6 NAME +&7 I 5*/1 SYSIN :/
CALL SUB2 (C,D,NAME,);
FREE C,D;
END MAN;
SUB1: PROCEDURE (U,V) ;
DCL (U(*), V(*)) CONTROLLED;
ALLOCATE U(30), V(40);
RETURN;
END SUB1;
SUB2: PROCEDURE (X,Y,NAMEA,N);
DECLARE (X(N),Y(N)) CONTROLLED,
NAMEA CHARACTER (*),
N FXED(3,0);
ALLOCATE X,Y;
RETURN;
END SUB2;
When SUB1 is invoked, A and B, which have been allocated as declared, are passed.
The ALLOCATE statement in SUB1 specifies bounds for the arrays; consequently, the
allocated arrays, which are actually a second generation of A and B, have bounds
different from the first generation. f no bounds were specified in the ALLOCATE
statement, the bounds of the first and the new generation are identical.
On return to MAN, the first FREE statement frees the second generation of A and B
(allocated in SUB1), and the second FREE statement frees the first generation (allocated
in MAN).
n SUB2, X and Y are declared with bounds that depend upon the value of N. When X
and Y are allocated, this value determines the bounds of the allocated array.
The asterisk notation for the length of NAMEA indicates that the length is to be picked up
from the argument (NAME).This can be done by the built-in function LENGTH.
P*/.'7)*' A.6-8+6-/&
After the keyword CALL in a CALL statement (as described in "CALL Statement)
Udhayas PL/I Material 6/06/2003 Page:- 28 / 161
After the keyword CALL in the CALL option of the NTAL attribute
E(+143': SET_UP is the name of a procedure that can set the initial values of
elements in TABLE. X and Y are arguments passed to SET_UP.

DECLARE TABLE (20,20) NTAL CALL SET_UP (X,Y);
As a function reference
E&6*< P/-&6,
A: READN: PROCEDURE;
statement-1
statement-2
ERRT: ENTRY;
statement-3
statement-4
statement-5
NEXT: RETR: ENTRY;
statement-6
. . .
END READN;
n the example, A is the primary entry point. A and READN specify the same entry point,
as do NEXT and RETR. However note that depending on the entry point used to invoke
the procedure, the code executed can be different. The procedure can be activated by
any of the following statements:
CALL A;
CALL ERRT;
CALL NEXT;
CALL RETR;
CALL READN;
E&6*< V+*-+93',
DECLARE ENT1 ENTRY VARABLE;
ENT1 = ERRT;
CALL ENT1; /' t&is ca** and t&e ne5t ca** &a-e t&e same effect '/
CALL ERRT; /' t&is ca** and t&e )re-ious &a-e t&e same effect '/
Procedure 0ermination
Normal procedure termination occurs when:
Control reaches a RETURN statement within the procedure. The execution of a
RETURN statement returns control to the point of invocation in the invoking
procedure. f the point of invocation is a CALL statement, execution in the invoking
procedure resumes with the statement following the CALL. f the point of invocation is
one of the other forms of procedure references (that is, a CALL option of the NT
keyword or a function reference), execution of the statement containing the reference
is resumed.
Control reaches the END statement of the procedure. Effectively, this is equivalent to
the execution of a RETURN statement.
Transferring control out of a procedure using a GO TO statement can sometimes result in
the termination of several procedures and/or begin-blocks. Specifically, if the transfer
Udhayas PL/I Material 6/06/2003 Page:- 29 / 161
point specified by the GO TO statement is contained in a block that did not directly
activate the block being terminated, all intervening blocks in the activation sequence are
terminated.
E(+143'@
A: PROCEDURE OPTONS(MAN) ;
statement-1
statement-2
B: BEGN;
statement-b1
statement-b2
CALL C;
statement-b3
END B;
statement-3
statement-4
C: PROCEDURE;
statement-c1
statement-c2
statement-c3
D: BEGN;
statement-d1
statement-d2
GO TO LAB;
statement-d3
END D;
statement-c4
END C;
statement-5
LAB: statement-6
statement-7
END A;
A activates B, which activates C, which activates D. n D, the statement GO TO LAB
transfers control to statement-6 in A. Since this statement is not contained in D, C, or B,
all three blocks are terminated; A remains active. Thus, the transfer of control out of D
results in the termination of intervening blocks B and C as well as the termination of block
D.
.!namic Loading of an +5terna* Procedure
Use FETCH and RELEASE statements
PROGA: PROC OPTONS(MAN);
DCL (C,D) FXED BN(31);
DCL PROGB ENTRY(FXED BN(31),FXED BN(31));
FETCH PROGB;
CALL PROGB(C,D);
RELEASE PROGB;
END PROGA;
E(+143'
//.. JOB
//DYNSTP EXEC PROC=EL1CL,REGON.PL=1M
//PL.SYSN DD *
PROGB : PROC(A,B);
DCL (A,B) FXED BN(31);
Udhayas PL/I Material 6/06/2003 Page:- 30 / 161
PUT LST('A AND B:' ,A,B);
END PROGB;
/*
//PL.SYSLN DD DSN=&&LOADSET,DSP=(NEW,KEEP),.......same parms as
existing SYSLN statement in EL1CL proc
//LKED.OBJMOD DD DSN=&&LOADSET,DSP=(OLD,DELETE)
//LKED.SYSLMOD DD DSN=MYLB.PL.LOADLB,DSP=OLD
//LKED.SYSLN DD *
ENTRY PROGB
NCLUDE OBJMOD
NAME PROGB( R )
/*

",L for com)i*e and *in6 edit main )roc#
//.... JOB
//COMPLEK EXEC EL1CL
//PL.SYSN DD *
PROGA: PROC OPTONS(MAN);
DCL (C,D) FXED BN(31);
DCL PROGB ENTRY(FXED BN(31),FXED BN(31));
C=1;D=2;
FETCH PROGB;
CALL PROGB(C,D);
RELEASE PROGB;
END PROGA;
/*
//LKED.SYSLMOD DD DSN=MYLB.PL.LOADLB(PROGA),DSP=SHR
+5ecuting main )roc
//STEP EXEC PGM=PROGA
//STEPLB DD DSN=MYLB.PL.LOADLB,DSP=SHR
Suroutines
A subroutine is a procedure that is invoked by a CALL statement or CALL option of an
NTAL attribute. t can be either an external or an internal procedure.
Example of nvocation of subroutines that are internal to and external to the invoking
block.
E(+143'
PRMAN: PROCEDURE;
DECLARE NAME CHARACTER (20), TEM BT (5),
OUTSUB ENTRY;
CALL OUTSUB (NAME, TEM);
END PRMAN;
OUTSUB: PROCEDURE (A,B);
DECLARE A CHARACTER (20), B BT (5);
PUT LST (A,B);
END OUTSUB;
E(+143'
A: PROCEDURE;
DECLARE RATE FLOAT (10),
TME FLOAT (5),
DSTANCE FLOAT (15),
Udhayas PL/I Material 6/06/2003 Page:- 31 / 161
MASTER FLE;
CALL READCM (RATE, TME,DSTANCE, MASTER);
READCM: PROCEDURE (W,X,Y,Z) ;
DECLARE W FLOAT (10),
X FLOAT (5),
Y FLOAT (15), Z FLE;
GET FLE (Z) LST (W,X,Y);
Y = W*X;
F Y > 0 THEN
RETURN;
ELSE
PUT LST ('ERROR READCM');
END READCM;
END A;
BUILTIN S)9*/)6-&',
These have entry name that are defined at compile-time and are invoked by a CALL
statement.
F)&.6-/&,
A function is a procedure that is invoked by a function reference in an expression. A
function reference is an entry reference that represents an entry name (a particular entry
point of a procedure) invoked as a function.
A function returns a value, and control, to replace the function reference in the evaluation
of the expression in which the function reference appears. This single value can be of
any data type except entry.
E(+143',
MANP: PROCEDURE;
GET LST (A, B, C, Y);
X = Y**3+SPROD(A,B,C);
.
.
END MANP;
SPROD: PROCEDURE (U,V,W) RETURNS (BN FLOAT (21));
DCL (U,V,W) BN FLOAT (53);
F U > V + W
THEN RETURN (0);
ELSE
RETURN ( U*V*W);
END SPROD;
A,,/.-+6-/& /5 A*0)1'&6, +&7 P+*+1'6'*,
When a function or subroutine is invoked, parameters in the parameter list are associated
, from left to right, with the arguments in the argument list. The number of parameters and
arguments must be the same.
D)11< A*0)1'&6,
A reference to an argument, not its value, is generally passed to a subroutine or function.
This is known as passing arguments by reference. However, this is not always possible
or desirable. Constants, for example, should not be altered by an invoked procedure.
Therefore, the compiler allocates storage (in storage belonging to the invoking
Udhayas PL/I Material 6/06/2003 Page:- 32 / 161
procedure) for some arguments using attributes that agree with the parameter, converts,
and assigns the argument to the allocated storage, and then passes a reference to the
allocated storage. These storage locations are called dummy arguments. Any change to
a parameter for which a dummy argument has been created is reflected only in the value
of the dummy argument and not in the value of the original argument from which it was
constructed.
A dummy argument is created when the original argument is any of the following:
A constant.
An expression with operators, parentheses, or function references.
A variable whose data attributes or alignment attributes are different from the
attributes declared for the parameter. This does not apply to simple parameters when
only bounds, lengths, or size differ and, for the parameter, these are declared with
asterisks.
n the case of arguments and parameters with the PCTURE attribute, a dummy
argument is created unless the picture specifications match exactly, after any
repetition factors are applied.
A controlled string or area (because an ALLOCATE statement could change the
length or extent).
P+,,-&0 +& A*0)1'&6 6/ 62' MAIN P*/.'7)*'
TOM: PROC (PARAM) OPTONS (MAN) ;
DCL PARAM CHAR(100) VARYNG;
When NOEXECOPS is specified, the MAN procedure can have a single parameter
that is a VARYNG CHARACTER string. The parameter is passed as is, and a
descriptor is set up. ("/, if contained in the string, is treated as part of the string).
E(+143'@
MAN: PROC(PARM) OPTONS(MAN NOEXECOPS);
DCL PARM CHAR(n) VARYNG;
Note that the OPTON NOEXECOPS implies that the PARM string is not evaluated
by the run environment of CMS or MVS but passed unchanged to the user program.
Shows a MAN procedure that can be invoked as follows:
// EXEC PGM=MAN, PARM='REPORT,LST'
The PARM contains REPORT,LST and has a length of 11.
When PL/ programs are called from Assembler routines, more than one parameter
can be passed as below:
E(+143'
MAN: PROC(FUNC, P) OPTONS(MAN NOEXECOPS);
DCL FUNC FXED BN(31);
DCL P PONTER;
B'0-&"B3/.B,
A begin-block is a sequence of statements delimited by a BEGN statement and a
corresponding END statement.
Udhayas PL/I Material 6/06/2003 Page:- 33 / 161
Example:
B: BEGN;
statement-1
statement-2
.
.
.
statement-n
END B;
Unlike a procedure, a label is optional for a begin-block.
B'0-&"93/.B A.6-8+6-/&
Begin-blocks are activated through sequential flow or as a unit in an F, ON, WHEN, or
OTHERWSE statement. Control can be transferred to a labelled BEGN statement by
execution of a GO TO statement.
B'0-&"B3/.B T'*1-&+6-/&
A begin-block is terminated when control passes to another active block by some means
other than a procedure reference; that is, when:
Control reaches the END statement for the block. When this occurs, control moves to
the statement physically following the END, except when the block is an ON-unit.
The execution of a GO TO statement within the begin-block (or any block activated
from within that begin-block) transfers control to a point not contained within the block.
A STOP or EXT statement is executed (thereby terminating execution of the current
task and all its sub-tasks).
Control reaches a RETURN statement that transfers control out of the begin-block
(and out of its containing procedure as well).
A procedure within which the begin-block is contained has been attached as a task,
and the attaching block terminates.
A GO TO statement can also terminate other blocks if the transfer point is contained in a
block that did not directly activate the block being terminated. n this case, all intervening
blocks in the activation sequence are terminated.
E&6*< D+6+
Entry data can be an entry constant or the value of an entry variable. An entry constant is
a name written as a label prefix to a PROCEDURE or ENTRY statement, or a name
declared with the ENTRY attribute and not the VARABLE attribute. An entry constant
can be assigned to an entry variable.
E(+143'@
P: PROCEDURE;
DECLARE EV ENTRY VARABLE,
(E1,E2) ENTRY;
EV = E1;
CALL EV;
EV = E2;
CALL EV;
Udhayas PL/I Material 6/06/2003 Page:- 34 / 161
P, E1, and E2 are entry constants. EV is an entry variable.
The following example contains a sub-scripted entry reference:
DECLARE (A,B,C,D,E) ENTRY,
DECLARE F(5) ENTRY VARABLE
NTAL (A,B,C,D,E);
DO = 1 TO 5;
CALL F() (X,Y,Z);
END;
/' t&e fi-e entries (?B?,?.?+? are eac& in-o6ed 7it& )arameters B?4 and K '/
D'.3+*-&0 E&6*< D+6+
nternal entry constants are explicitly declared by the appearance of a label prefix to a
PROCEDURE or ENTRY statement. A parameter-descriptor list (the number of
parameters and their attributes) is obtained from the parameter declarations, if any, and
by defaults.
you must explicitly declare external entry constants. This declaration:
Defines an entry point to an external procedure
optionally specifies a parameter-descriptor list, if any, for the entry point
Optionally specifies the attributes of the value that is returned by the procedure if the
entry is invoked as a function.
E(+143', /5 4+*+1'6'* 7',.*-46/* 3-,6
ENTRY (CHARACTER(10),,,FXED DEC); /' E )arameters '/
ENTRY (*); /' indicates one )arameter '/
ENTRY(FLOAT BNARY, ); /'indicates 2 )arameters '/
ENTRY ( ); /' s)ecifies entr! &as ni* )arms'/
ENTRY; /'Su))resses argument c&ec6s'/
E(+143'
TEST: PROCEDURE (A,B,C,D,E,F);
DECLARE A FXED DECMAL (5),
B FLOAT BNARY (15),
C PONTER,
1 D,
2 P,
2 Q,
3 R FXED DECMAL,
1 E,
2 X,
2 Y,
3 Z,
F(4) CHARACTER (10);
END TEST;
+/0R4 for t&is cou*d e dec*ared as fo**o7s:
Udhayas PL/I Material 6/06/2003 Page:- 35 / 161
DECLARE TEST ENTRY
(DECMAL FXED (5),
BNARY FLOAT (15),
PONTER,
1 ,
2 ,
2 ,
3 DECMAL FXED,
1,
2,
2,
3,
(4) CHARACTER (10));
BUILTIN A66*-9)6'
Specifies that the name is a built-in function name, PSEUDOVARABLE name, or built-in
subroutine name
A: PROCEDURE;
DECLARE SQRT FLOAT BNARY;
X = SQRT; /' )rogrammer dec*ared SLR0 is assigned '/
B: BEGN;
DECLARE SQRT BULTN;
Z = SQRT(P); /' interna* SLR0 function is ca**ed'/
END B;
END A;
GENERIC A66*-9)6' +&7 R'5'*'&.',
A generic name is declared with the GENERC attribute, and specifies a set of entry
references.
E(+143'
DECLARE CALC GENERC
( FXDCAL WHEN (FXED,FXED),
FLOCAL WHEN (FLOAT,FLOAT),
MXED WHEN (FLOAT,FXED));
Z = X+CALC (X,Y);
Depending on the argument attributes, the matching entry point is used. n a similar
manner, an entry point to a procedure can be selected on the basis of the dimension.
E(+143'@
DCL D GENERC ( D1 WHEN ((*)),
D2 WHEN ((*,*))),
A(2),
B(3,5);
CALL D(A); /' entr! .1 '/
CALL D(B); /' entr! .2 '/
RETURN S6+6'1'&6
The RETURN statement terminates execution of the procedure that contains the
RETURN statement.
RETURN (expression);
Udhayas PL/I Material 6/06/2003 Page:- 36 / 161
The RETURN statement with expression is used to terminate a procedure
invoked by a function reference.
SECTION 5 SUBROUTINES AND FUNCTIONS
Suroutines and Procedures
Main Procedures (entry point into program)
Subroutine Procedures
Function Procedures
Procedures can be nested (unlike C and like Pascal)
Arguments can be passed to procedures
Function procedures can return value (like C functions)
Subroutine procedures return value(s) through modification of argument(s) passed
nvoke a procedure via a CALL statement
Example: CALL SUBRT(A,B,C);
Subroutines compiled separately are called EXTERNAL procedures and their name is
limited to seven characters. (Although MVS supports eight, the last position is used by
the PL/ compiler for a suffix to segregate code from one external procedure into more
than one CSECT).
A STOP or EXT routine in a procedure stops or exits the whole run unit.
E(+143'@
MANPR: PROCEDURE OPTONS(MAN);
DCL X FXED DEC(7,2);
DCL Y FXED DEC(7,2);
DCL Z FXED DEC(8,2);
DCL SUBRT ENTRY; /' dec*ares S3BR0 as a )rocedure'/
GET LST (X,Y);
CALL SUBRT(X,Y,Z);
PUT LST('THE SUM S =',Z);
END MANPR;
SUBRT: PROCEDURE(A,B,C);
DCL A FXED DEC(7,2);
DCL B FXED DEC(7,2);
DCL C FXED DEC(8,2);
C = A + B;
END SUBRT;
An argument can be one of the following
Variable
Constant
Expression
Array name
Array expression
Major structure name
Minor structure name
Structure expression
Built in function name
Entry name (can be an Entry Variable or a Label variable)
File name
E(+143'@
CALL SUBRT('ABCD',VAR_1);
CALL SUBRT(VAR_2,SQRT(X)); /' since ui*t in function &as arguments
/' it is in-o6ed efore S3BR0 is ca**ed '/
Udhayas PL/I Material 6/06/2003 Page:- 37 / 161
CALL SUBRT(A,DATE,C); /' .(0+ is /20 ca**ed efore S3BR0 '/
CALL SUBRT(A,(DATE),C); /' .(0+ is ca**ed efore S3BR0 '/
DAY = SUBSTR(DATE,5,2); /' since .(0+ is argument to ca**
to anot&er ui*t in function it IS
in-o6ed efore S3BS0R is ca**ed '/
When a constant is passed as an argument, internally a dummy argument is generated
to handle this argument
E(+143'@ CALL SUBRT(5.7,X);
Note that the dummy argument will have attribute FXED(2,1) whereas in SUBRT the
first argument was FXED(7,2). This can cause error. To avoid this pitfall code as below
E(+143'@
DCL ARG_1 FXED DECMAL(7,2);
ARG_1 = 5.7;
CALL SUBRT(ARG_1,X);
Alternately declare the subroutine procedure as below
E(+143'@
DCL SUBRT ENTRY(FXED DECMAL(7,2),
FXED DECMAL(7,2),
FXED DECMAL(8,2));
Alternately
DCL SUBRT ENTRY(FXED DECMAL(7,2),
FXED DECMAL(7,2) , );
/' note t&e asence of t&ird )arameter ! t&e comma# 0&is is reAuired as
t&e t&ird )arameter &as no -a*ue initia**! '/
A dummy argument is generated under following conditions
f an argument is a constant
f an argument is an expression involving operators
f an argument is an expression in parenthesis
f an argument is a variable whose attributes are different from those the declared for
the parameter in the ENTRY name attribute specification appearing in the invoking
block
f an argument is itself a function reference containing arguments
/ote t&at an! modification made to a )arameter 7&ic& is re)resented ! a dumm!
argument is not ref*ected in t&e origina* )arameter.
1unction Procedures
Return statement is used to terminate a function
RETURN(element-expression);
Example : W = CALC(A,B);
MANPR: PROCEDURE OPTONS(MAN);
DCL CALC ENTRY RETURNS(FXED DEC(7));
DCL SUM FXED DECMAL(7);
DCL A FXED DECMAL(7);
DCL B FXED DECMAL(7);
DCL C FXED DECMAL(7);
Udhayas PL/I Material 6/06/2003 Page:- 38 / 161
GET LST(A,B,C);
SUM = CALC(A,B,C);
PUT LST('SUM S',SUM);
END MANPR;
CALC: PROCEDURE (X,Y,Z) RETURNS(FXED DECMAL(7));
DCL X FXED DECMAL(7);
DCL Y FXED DECMAL(7);
DCL Z FXED DECMAL(7);
RETURN(X+Y+Z);
END CALC;
Sco)e of Identifiers
P1:PROCEDURE;
DCL X CHAR(2);
DCL Y CHAR(2);
DCL Z CHAR(2);
DCL SUM FXED DEC(7);
.
.
CALL P2;
.
.
P2:PROCEDURE;
DCL A CHAR(2);
DCL B CHAR(2);
DCL C CHAR(2);
DCL SUM CHAR(7); /' t&is &ides t&e S3M in P1 '/
X = 'AB'; /' Parameters in outer *oc6 can e accessed '/
#
.
END P2;
END P1;
Note: X,Y and Z are known to P1.However A,B and C are not known to P1
A,B and C come into existence only when P2 is invoked
X,Y,Z,A,B and C are all known to P2.
Inner *oc6s can see out# 2uter *oc6s cannot see in7ards#
Any data item with the EXTERNAL attribute tells the compiler that this variable is known
outside this module and is to be allocated once in the Global data area. However all other
modules which refer to this variable must declare this with same name and attributes and
EXTERNAL attribute.
,*assification of Bui*t In 1unctions
To aid in their description, built-in functions are listed in classes below. The first four
classes are computational built-in functions.
String-handling
Arithmetic
Mathematical
Array-handling
Condition-handling
Storage control
Event
nput / Output
Udhayas PL/I Material 6/06/2003 Page:- 39 / 161
Miscellaneous
S6*-&0"=+&73-&0 B)-36 I& F)&.6-/&,
The string-handling built-in functions simplify the processing of bit and character strings.
They are:
BT HGH MPSTR TRANSLATE
BOOL NDEX REPEAT UNSPEC
CHAR LENGTH STRNG VERFY
GRAPHC LOW SUBSTR
A*-621'6-. B)-36 I& F)&.6-/&,
The arithmetic built-in functions allow you to:
1. Control conversion of base, scale, mode, and precision both directly and during
basic arithmetic operations.
2. Determine properties of arithmetic values. For example, the SGN function indicates
the sign of an arithmetic value.
They are:
ABS DECMAL MAG PRECSON
ADD DVDE MAX REAL
BNARY FXED MN ROUND
CEL FLOAT MOD SGN
COMPLEX FLOOR MULTPLY TRUNC
CONJG
M+62'1+6-.+3 B)-36 I& F)&.6-/&,
The mathematical built-in functions provide mathematical operations. They are:
ACOS COSD LOG SNH
ASN COSH LOG2 SQRT
ATAN ERF LOG10 TAN
ATAND ERFC SN TAND
ATANH EXP SND TANH
All of these functions operate on floating-point values to produce a floating-point result.
A**+<"=+&73-&0 B)-36 I& F)&.6-/&,
The array-handling built-in functions operate on array arguments and return an element
value . They are:
ALL LBOUND
ANY POLY
DM PROD
HBOUND SUM
C/&7-6-/&"=+&73-&0 B)-36 I& F)&.6-/&,
The condition-handling build-in functions allow you to investigate the cause of
enabled conditions. They are:
DATAFELD ONFLE
ONCHAR ONKEY
ONCODE ONLOC
ONCOUNT ONSOURCE
Udhayas PL/I Material 6/06/2003 Page:- 40 / 161
Use of these functions is in context when within the scope of an ON-unit entered for the
condition specific to the built-in function, or within an ON-unit for the ERROR or FNSH
condition when raised as an implicit action. All other uses are out of context.
S6/*+0' C/&6*/3 B)-36 I& F)&.6-/&,
The storage-control built in functions allow you to determine the storage requirements and
location of variables, to assign special values to area and locator variables, to perform
conversion between offset and pointer values, and to obtain the number of generations of
a controlled variable. They are:
ADDR ENTRYADDR PONTERADD
ALLOCATON NULL PONTERVALUE
BNARYVALUE OFFSET STORAGE
CURRENTSTORAGE PONTER SYSNULL
EMPTY
I&4)6 / O)64)6 B)-36 I& F)&.6-/&,
The nput / Output built-in functions allow you to determine the current state of a file.
They are:
COUNT LNENO SAMEKEY
M-,.'33+&'/), B)-36 I& F)&.6-/&,
The built-in functions that do not fit into any of the foregoing classes are:
DATE DATETME PLRETV
TME PLRETC
B)-36 IN S)9*/)6-&',
The PL/ built-in subroutines are the following;
PLCANC PLSRTC
PLCKPT PLSRTA PLSRTD
PLDUMP PLSRTB PLTEST

P,')7/"8+*-+93',
Pseudo-variables represent receiving fields. Except when noted in the description, the
Pseudo-variables :
Can appear on the left of the assignment symbol in an assignment.
Can appear in a data list of a GET statement or in the STRNG option of a PUT
statement.
Can appear as the string name in a KEYTO option.
The Pseudo-variables are:
COMPLETON ONCHAR STATUS
COMPLEX ONSOURCE STRNG
ENTRYADDR PRORTY SUBSTR
MAG REAL UNSPEC
ADDR ?S6/*+0' ./&6*/3A
Udhayas PL/I Material 6/06/2003 Page:- 41 / 161
ADDR returns the pointer value that identifies the generation of x. The syntax for ADDR
is:
ADDR (X) Reference to variable of any data type,
ALL ?A**+<"=+&73-&0A
ALL returns a bit string in which each bit is 1 if the corresponding bit in each element of X
exists and is 1. The length of the result is equal to that of the longest element. The syntax
for ALL is:
ALL (X) /' I&ere B is an (rra! e5)ression '/
f X is not a bit-string array, it is converted to bit string.
ALLOCATION ?S6/*+0' C/&6*/3A
ALLOCATON returns a FXED BNARY (31,0) value specifying the number of
generations that can be accessed in the current task for X. The syntax for ALLOCATON
is:
ALLOCATON (X)
ANY ?A**+<"2+&73-&0A
ANY returns a bit string in which each bit is 1 if the corresponding bit in any element of X
exists and is 1. The length of the result is equal to that of the longest element . The
syntax for ANY is:
ANY (X)
X is an Array expression.
BINARYVALUE ?S6/*+0' C/&6*/3A
BNARYVALUE returns a REAL FXED BN (31,0) value that is the converted value of its
pointer expression, X. The syntax for BNARYVALUE is:
BNARYVALUE (X)
BIT ?S6*-&0A
BT returns the value of X with length specified by Y where Y is FXED BNARY(15)
The syntax is
BT (X, Y)
C=AR ?S6*-&0"=+&73-&0A
CHAR returns the character value of X, with a length specified by Y which is FXED
BNARY(15). The syntax for CHAR is:
CHAR (X, Y)
COUNT ?I&4)6 / O)64)6A
COUNT returns a FXED BNARY (15,0) value specifying the number of data items
transmitted during the last GET or PUT operation on X. The syntax for COUNT is:
COUNT (X)
X is a File-reference. The file must be open and have the STREAM attribute.
Udhayas PL/I Material 6/06/2003 Page:- 42 / 161
CURRENTSTORAGE ?S6/*+0' C/&6*/3A
CURRENTSTORAGE returns a FXED BNARY (31,0) value giving the implementation-
defined storage in bytes, required by X . The syntax for CURRENTSTORAGE is:
CURRENTSTORAGE (X)
DATAFIELD ?C/&7-6-/&"=+&73-&0A
DATAFELD is in context in a NAME condition ON-unit (or any of its dynamic
descendants), and returns a character string whose value is the contents of the field that
raised the condition.
DATAFELD ( )
DATE ?M-,.'33+&'/),A
DATE returns a character string, length 6, in the format YYMMDD. The syntax for DATE
is:
DATE ( )
The returned character string represents:
YY last two digits of the current year
MM Current month
DD Current day
DATETIME ?M-,.'33+&'/),A
DATATME returns a character string, length 17, in the format of
YYYYMMDDHHMMSSTTT. The syntax for DATATME is:
DATETME ( )
The returned character string represents:
YYYY Current year
MM Current month
DD Current day
HH Current hour
MM Current minute
SS Current second
TTT Current millisecond
DECIMAL ?A*-621'6-.A
DECMAL returns the decimal value of X, with a precision specified by P and Q . The
result has the mode and scale of X. The syntax for DECMAL is:
DECMAL (X, P, Q)
DIM ?A**+<"=+&73-&0A
DM returns a FXED BNARY (31,0) value specifying the current extent of the dimension
Y of X . The syntax for DM is:
DM (X, Y)
Udhayas PL/I Material 6/06/2003 Page:- 43 / 161
X Array expression. X must not have less than Y dimensions, and X must
not be an array of structures.
Y Expression specifying a particular dimension of X. f necessary, Y is
converted to a FXED BNARY (31,0) value. Y must be greater than or equal to 1
f the extent of an array dimension exceeds the allowable number for the implementation,
the DM function returns an undefined value.
EMPTY ?S6/*+0' C/&6*/3A
EMPTY returns an area of zero extent. t can be used to free all allocations in an area.
The syntax for EMPTY is:
EMPTY ( )
E(+143'
DECLARE A AREA,
BASED (P);
J BASED (Q);
ALLOCATE N (A), J N (A);
A = EMPTY( );
/'eAui-a*ent to: 1R++ I I/ =()? " I/ =()D'/
ENTRYADDR ?S6/*+0' C/&6*/3A
ENTRYADDR returns a pointer value that is the address of the first executed instruction if
the entry X is invoked . The entry X must be an external entry. The syntax for
ENTRYADDR is:
ENTRYADDR (X)
X Entry reference.
ENTRYADDR ?P,')7/"8+*-+93'A
The ENTRYADDR Pseudo-variable initialises an entry variable X, with the address of the
entry to be invoked. The syntax for ENTRYADDR PSEUDOVARABLE is:
ENTRYADDR (X)
X Entry reference
=BOUND ?A**+<"=+&73-&0A
HBOUND returns a FXED BNARY (31,0) value specifying the current upper bound of
dimension Y of X. The syntax for HBOUND is:
HBOUND (X, Y)
X Array expression. X must not have less than Y dimensions, and X must not be an
array of structures.
Y Expression specifying a particular dimension of X. f necessary Y is converted to a
FXED BNARY (15,0) value. Y must be greater than or equal to 1
INDE> ?S6*-&0"=+&73-&0A
NDEX returns a FXED BNARY (15,0) value indicating the starting position within X of a
sub-string identical to Y. The syntax for NDEX is:
Udhayas PL/I Material 6/06/2003 Page:- 44 / 161
NDEX (X, Y)
X String-expression to be searched.
Y String-expression to be searched for.
if Y does not occur in X, or if either X or Y have zero length, the value zero is returned
f occurs more than once in X, the starting position of the leftmost occurrence is returned.
LBOUND ?A**+<"=+&73-&0 A
LBOUND returns a FXED BNARY (31,0) value specifying the current lower bound of
dimension Y of X. The syntax for LBOUND is:
LBOUND (X, Y)
X Array expression, X must not have less than Y dimensions, and X must
not be an array of structures.
Y Expression specifying the particular dimension of X. f necessary Y is
converted to a FXED BNARY (15,0) value . Y must be greater than or equal to 1
LENGT= ?S6*-&0"=+&73-&0A
LENGTH returns a FXED BNARY (15,0) value specifying the current length of X. The
syntax for LENGTH is:
LENGTH (X)
X String -expression. f X is binary it is converted to bit string; otherwise
any other conversion required is to character string.
LINENO ? I&4)6 / O)64)6A
LNENO returns a FXED BNARY (15,0) value specifying the current line number of X.
The syntax for LNENO is:
LNENO (X)
X File-reference.
The file must be open and have the PRNT attribute.
NULL ?S6/*+0' C/&6*/3A
NULL returns the null pointer value . The null pointer value does not identify any
generation of a variable The null pointer value can be converted to OFFSET by
assignment of the built-in function value to an offset variable. The syntax for NULL is:
NULL ( )
OFFSET ?S6/*+0' C/&6*/3A
OFFSET returns an offset value derived from a pointer reference X and relative to an
area Y. f X is the null pointer value, the null offset value is returned. The syntax for
OFFSET is:
OFFSET (X, Y)
X Pointer reference, which must identify a generation of a based variable
within the area Y, or be the null pointer value.
Y Area reference.
ONC=AR ?C/&7-6-/&"=+&73-&0A
Udhayas PL/I Material 6/06/2003 Page:- 45 / 161
ONCHAR returns a character string of length 1, containing the character that caused
the CONVERSON condition to be raised. t is in context in an ON-unit (or any of its
dynamic descendants) for the CONVERSON condition or for the ERROR or FNSH
condition raised as the implicit action for the CONVERSON condition. The syntax for
ONCHAR is:

ONCHAR ( )
ONC=AR ? P,')7/"8+*-+93' A
The Pseudo-variable sets the current value of the ONCHAR built-in function. The
element value assigned to the pseudo-variable is converted to a character value of length
1. The new character is used when the conversion is re-attempted.
ONCHAR ( )
ONCODE ?C/&7-6-/&"=+&73-&0A
ONCODE returns FXED BNARY (15,0) value that is the condition code. t is in context
in any ON-unit, or any dynamic descendant of an ON-unit.
ONCODE ( )
ONFILE ?C/&7-6-/&"=+&73-&0A
ONFLE returns a character string whose value is the name of the file for which an
input/output or CONVERSON condition is raised.
ONFLE ( )
ONLOC ?C/&7-6-/&"=+&73-&0A
ONLOC returns a character string whose value is the name of the entry-point used for the
current invocation of the procedure in which a condition was raised. t is in context in
any ON-unit, or in any of its dynamic descendants.
ONLOC ( )
ONSOURCE ?C/&7-6-/& " =+&73-&0A
ONSOURCE returns a character string whose value is the contents of the field that was
being processed when the CONVERSON condition was raised. t is in context in an ON-
unit, or any of its dynamic descendants, for the CONVERSON condition or for the
ERROR or FNSH condition raised as the implicit action for the CONVERSON
CONDTON. The syntax for ONSOURCE is:
ONSOURCE ( )
ONSOURCE ?P,')7/"8+*-+93'A
The pseudo-variable sets the current value of the ONSOURCE built-in function. The
element value assigned to the pseudo-variable is converted to a character string and, if
necessary, is padded on the right with blanks or truncated to match the length of the field
that raised the CONVERSON condition. The new string is used when the conversion is
re-attempted.
ONSOURCE ( )
Udhayas PL/I Material 6/06/2003 Page:- 46 / 161
PLIDUMP ?B)-36"-& S)9*/)6-&'A
This built-in subroutine allows you to obtain a formatted dump of selected parts of
storage used by your program. For the syntax of the PLDUMP and other details lookup
Language Environment for MVS and VM Debugging Guide and Run Time Messages.
PLIRETC ?B)-36"-& S)9*/)6-&'A
This built-in subroutine allows you to set a return code that can be examined by the
program or (sub) system that invoked this PL/ program or by another PL/ procedure via
the PLRETV built-in function. The syntax for PLRETC is:
PLRETC (return-code)
Example: CALL PLRETC(16); /' sets return code of 1> '/
PLIRETV ?M-,.'33+&'/),A
PLRETV returns a FXED BNARY (31,0) value that is the PL/ return code. The syntax
for PLRETV is:
PLRETV ( )
The value of the PL/ return code is the most recent value specified by a CALL
PLRETC statement in any task or the value returned by a COBOL or assembler routine
(via Register 15) whose entry point is declared with the option OPTONS(RETCODE), or
zero.
POINTER ?S6/*+0' C/&6*/3)
PONTER returns a pointer value that identifies the generation specified by an offset
reference X, in an area specified by Y. f X is the null offset value, the null pointer value
is returned. The syntax for PONTER is:
PONTER (X, Y)

X Offset reference, which can be the null offset value; if it is not, it must
identify a generation of a based variable.
Y Area reference.
REPEAT ?S6*-&0"=+&73-&0A
REPEAT returns a bit or character string consisting of X concatenated to itself the
number of times specified by Y; that is, there are (Y+1) occurrences of X. The syntax for
REPEAT is:
REPEAT (X, Y)
X Bit or character expression to be repeated. if X is arithmetic, it is
converted to bit string if it is binary, character string if it is decimal.
Y Expression. f necessary, y is converted to a FXED BNARY ( 15,0)
if Y is zero or negative, the string X is returned.
STORAGE ?S6/*+0' C/&6*/3A
STORAGE returns a FXED BNARY (31,0) value giving the implementation - defined
storage, in bytes, allocated to a variable X. The syntax for STORAGE is:
Udhayas PL/I Material 6/06/2003 Page:- 47 / 161
STORAGE ( X )
X A variable of any data type, data organisation, alignment
STRING ?S6*-&0"=+&73-&0A
STRNG returns an element bit or character string that is the concatenation of all the
elements of X. The syntax for STRNG is:
STRNG ( X )
X Aggregate or element reference. Each base element of X must be either
all bit-string, or all character string and/or numeric character, in any
combination. f X is a structure that has padding caused by ALGNED
elements, the padding is not included in the result. f any of the strings in
the aggregate X are of varying length, only the current length, not
including the 2-byte length prefix, is concatenated. if X is an element
variable, the rules for aggregates apply except that there is no
concatenation.
SUBSTR ?S6*-&0"=+&73-&0A
SUBSTR returns a sub-string, specified by Y and Z, of X. The syntax for SUBSTR is:
SUBSTR ( X, Y, Z)
X String-expression from which the sub-string is to be extracted. f X is not
a string, it is converted to a bit string if binary, or a character string if
decimal.
Y Expression that can be converted to a FXED BNARY (15,0) value
specifying the starting position of the sub-string in X.
Z Expression that can be converted to a value specifying the length of the
sub-string in X. f Z is zero, a null string is returned. if Z is omitted, the
sub-string returned is position Y in X to the end of x.
The S0RI/GR(/G+ condition is raised if Z is negative or if the values of Y and Z are
such that the sub-string does not lie entirely within the current length of X; it is not raised
when Y = LENGTH(X)+1 and Z=0 or Z is omitted.
SUBSTR ?P,')7/"8+*-+93'A
The pseudo-variable assigns a string value to a sub-string, specified by Y and Z, of X.
The remainder of X is unchanged. (Assignments to a varying string do not change the
length of the string.) The syntax for SUBSTR pseudo-variable is:
SUBSTR (X,Y,Z) = ...
X String-reference. X must not be a numeric character.
Y Expression that can be converted to a FXED BNARY (15,0) value
specifying the starting position of the sub-string in X.
Z Expression that can be converted to a FXED BNARY (15,0) value
specifying the length of the sub-string in X. f Z is zero, a null string is
returned. f Z is omitted, the sub-string returned is position Y in X to the
end of X. Y and Z can be arrays only if X is an array.
Udhayas PL/I Material 6/06/2003 Page:- 48 / 161
SUM ?A**+<"=+&73-&0A
SUM returns the sum of all the elements in X. The base, mode, and scale of the result
match those of X. The syntax for SUM is:
SUM ( X )
X Array expression. f the elements of x are strings, they are converted to
fixed-point integer values.
SYSNULL ?S6/*+0' C/&6*/3A
SYSNULL returns the system null pointer value. t can be used to initialise static pointer
and offset variables. t also can be assigned or converted to offset variables (like NULL).
The Syntax for SYSNULL is :
SYSNULL ( )
TIME?M-,.'33+&'/),A
TME returns a character string, length 9, in the format of HHMMSSTTT. The syntax for
TME is:
TME ( )
The returned character string represents:
HH Current hour
MM Current minute
SS Current second
TTT Current millisecond
TRASLATE ?S6*-&0"=+&73-&0A
TRANSLATE returns a character string of the same length as X. The Syntax for
TRANSLATE is:
TRANSLATE (X, Y, Z)
X Character expression to be searched for possible translation of its
characters.
Y Character expression containing the translation values of characters.
Z Character expression containing the characters that are to be translated.
f Z is omitted, a string of 256 characters is assumed; it contains one
instance of each EBCDC code arranged in ascending collating
sequence (hexadecimal 00 through FF)
TRANSLATE operates on each character of X as follows. f a character in X is
found in Z, the character in Y that corresponds to that in Z is copied to the result;
otherwise, the character in X is copied directly to the result. if Z contains
duplicates, the leftmost occurrence is used. Y is padded with blanks, or
truncated, on the right to match the length of Z.
Any arithmetic or bit arguments are converted to character.
E(+143'@

DECLARE (W, X) CHAR (3);
Udhayas PL/I Material 6/06/2003 Page:- 49 / 161
X = 'ABC';
W = TRANSLATE (X, 'TAR', 'DAB');
/' I C M(R,N '/
VERIFY ?S6*-&0" =+&73-&0A
VERFY returns a FXED BNARY (15,0) value indicating the leftmost character or bit
position in X that is not in Y. f all the characters or bits in X do appear in Y, a value of
zero is returned. f X is the null string, a value of zero is returned. f X is not the null string
and Y is the null string, a value of one is returned. The syntax for VERFY is:
VERFY (X, Y,)
X String Expression
Y String expression .
f either argument is character or decimal, conversions are performed to produce
character string. Otherwise, if the arguments are bit and binary or both binary, and
conversions are performed to produce bit strings. n the following example, the VERFY
built-in function is used to test whether or not a string is all-numeric:
VERFY (X, '0123456789').
Udhayas PL/I Material 6/06/2003 Page:- 50 / 161
SECTION 6 CONTROL STATEMENTS
Logica* 0esting
Symbols Operations
GE or >= Greater than or equal to
GT or > Greater than
NE or Not equal to
= Equal to
LT or < Less than
LE or <= Less than or equal to
NL or Not less than
NG or Not greater than
F *ogica* e5)ression THEN statement ;
ELSE statement;
F *ogica* e5)ression THEN
DO;
.
.
END;
ELSE
DO;
.
.
END;
/ested I1 statement
F A=B THEN
F A=C THEN
X=1;
ELSE
X=2;
ELSE
X=3;
/u** I1
F A=B THEN F A=B THEN
F A=C THEN F A=C THEN
X=1; X=1;
ELSE; ELSE
ELSE X=3;
X=3;
Se*ect Statement
SELECT (expression which is optional);
WHEN (expression) action 1;
WHEN (expression) action 2;
WHEN (expression) action 3;
OTHERWSE action 3;
END;
E(+143'@
SELECT (CODE)
Udhayas PL/I Material 6/06/2003 Page:- 51 / 161
WHEN (1) DO;
.
.
END;
WHEN (2) CALL SUBRTN;
OTHERWSE CALL NVCODE;
END;
SELECT;
WHEN(CODE<10) DO;
.
.
END;
WHEN (CODE>=10) CALL SUBRTN;
OTHERWSE CALL ERRORTN;
END;
Logica* 2)erators
NOT
& AND
| OR
Note that the | or can be changed by the %PROCESS statement like below
%PROCESS NOT('~'); /' O ecomes t&e not o)erator '/
F A=B & C=D THEN CALL SUBRTN;
Logica* 2)erators in t&e assignment statement
A=B=C; /'If BC, t&en a -a*ue of 1 is assigned to ( e*se 8 is assigned'/
A=B>C; /' If BP, t&en a -a*ue of 1 is assigned to ( e*se 8 is assigned'/
E(+143' /5 .+46)*-&0 PARM, SELECT ,6+6'1'&6 +&7 IF ,6+6'1'&6,
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M,PARM.GO='E'
//PL.SYSN DD *
%PROCESS ATTRBUTES(FULL),XREF(FULL);
MYPROG: PROCEDURE(A) OPTONS(MAN);
DCL A CHAR(20) VARYNG;
PUT SKP EDT('PARM PASSED S=',A)(A);
SELECT(A);
WHEN('A') PUT SKP LST('PARM PASSED A A');
WHEN('B') PUT SKP LST('PARM PASSED A B');
WHEN('C') PUT SKP LST('PARM PASSED A C');
WHEN('D') PUT SKP LST('PARM PASSED A D');
OTHERWSE PUT SKP LST('UNKNOWN CHAR PASSED');
END;
F A = 'A' THEN
PUT SKP LST('CHAR S A');
ELSE
F A='B' THEN
PUT SKP LST('CHAR S B');
ELSE
F A='C' THEN
PUT SKP LST('CHAR S C');
ELSE
Udhayas PL/I Material 6/06/2003 Page:- 52 / 161
F A='D' THEN
PUT SKP LST('CHAR S D');
ELSE
PUT SKP LST('UNKNOWN CHAR');
END MYPROG;
/*
//
.2 L22PS
DO UNTL(expression) /' test is after t&e *oo) od! '/
/' *oo) terminates 7&en t&e condition ecomes true '/
DO WHLE(expression) /' test is efore t&e *oo) od! '/
/' *oo) terminates 7&en t&e condition ecomes fa*se'/
DO UNTL (expression);
.
.
END;
Expression can be a logical expression or a flag variable (BN (1)). A flag variable
with a value of binary one is true. A binary value of zero is false.
Iterati-e .2 *oo)
DO contro*--aria*e = initia* -a*ue TO *imit -a*ue BY modification -a*ue
[WHLE(e5)ression) | UNTL(e5)ression)];
E(+143'@
J=10;
K=5;
L=2;
DO =J TO K BY L;
.
.
END;
E(+143'?,A@
DO =1 TO 100 BY 1; /' .2 IC1 B4 1 02 188 is a*so 2$ '/
DO =100 TO 1 BY -1;
DO =1 BY 1; /'termination condition must e inside t&e *oo)'/
DO =0.1 BY 0.1 TO 1.0;
DO =1 TO 5,10 TO 20, 25 TO 50 BY 2;
DO =1,4,7,22;
DO =1 TO 100 WHLE(X<100);
/' *oo) terminates 7&en I reac&es 188 or PC188'/
Commas separate specifications as below
DO =1 TO 10, 11 BY 0 WHLE(A=B);
/' after I C 1 to 18? continuos *oo)ing at I C 11 ta6es )*ace 7&i*e
(CB# (t t&is time *oo) terminates on*! 7&en ( is not C B '/
Udhayas PL/I Material 6/06/2003 Page:- 53 / 161
DO ='ABC','DEF','GH'
Lea-e statement
The leave statement transfers control from within a DO loop to the statement
following the end statement that delimits the group and terminates the DO group.
E(+143'
A: DO;
.
.
LEAVE; /' transfers contro* to t&e ne5t statement after t&is *oc6'/
.
END;
next statement;
E(+143'
A: DO =1 to 10;
DO J = 1 to 10;
F X(,J)=0 THEN LEAVE A; /' to statement outside grou) ( '/
ELSE..
.
END;
END;
statement after group A.
Udhayas PL/I Material 6/06/2003 Page:- 54 / 161
SECTION CONDITIONS AND ON UNITS
,ondition and 2/-3/I0S
condition occurs
system no
action (null operation) action
Program specified action
n absence of program specified action default system action takes place. ERROR
condition is raised and the program is terminated. Two built-in functions exist, ONCODE
(which returns the error code, binary value, for diagnostic purposes) and ONLOC which
returns the procedure/function name, as a string, where the error occurred. Note that
these built-in functions do not have any arguments and should therefore be declared
before use as below
DCL ONCODE BULTN;
Standard error handling routines can be kept in source form in a source statement library
and included in your program by the statement
%NCLUDE oo6Gname
ON units can be declared to handle specific conditions. Within an ON unit facilities are
provided to get more information on the condition that caused the ON unit to be activated.
Some of these are ONCODE( ), ONSOURCE( ), ONCHAR( ). A normal return from an
ON unit is said to take place when execution returns through END statement. An
abnormal termination is said to occur when we branch out of the ON unit through a
GOTO statement.
ON condition
BEGN;
.
.
END;
E(+143'@
ON ENDFLE(SYSN)
BEGN
.
.
END;
E(+143'@
ON ERROR SYSTEM; /' restores ac6 s!stem action for +RR2R condition'/
ON ERROR
BEGN;
ON ERROR SYSTEM;
PUT DATA; /' out)ut a** -aria*es and -a*ues '/
WHAT
ACTION ?
Udhayas PL/I Material 6/06/2003 Page:- 55 / 161
END;
,ondition %and*ing
C/&7-6-/& P*'5-(',
You can specify whether or not some conditions are enabled or disabled. f a condition is
enabled, the raising of the condition executes an action. f a condition is disabled, the
raising of the conditions does not execute an action.
Enabling and disabling can be specified for the eligible conditions by a condition prefix.
Example:
(SZE): L1 X=(**N);
The conditions that are always enabled unless they are explicitly disabled by condition
prefixes are:
CONVERSON
FXEDOVERFLOW
OVERFLOW
UNDERFLOW
ZERODVDE
Each of the preceding conditions can be disabled by condition prefix specifying the
condition name preceded by NO with intervening blanks. Thus, one of the following in a
condition prefix disables the respective condition:
NOCOVERSON
NOFXEDOVERFLOW
NOOVERFLOW
NOUNDERFLOW
NOZERODVDE
The conditions that are always disabled unless they are enabled by a condition prefix are:
SZE
SUBSCRPTRANGE
STRNGRANGE
STRNGSZE
All other conditions are always enabled and cannot be disabled . These conditions are:
AREA KEY
ATTENTON NAME
CONDTON RECORD
ENDFLE TRANSMT
ENDPAGE UNDEFNEDFLE
ERROR PENDNG
FNSH
S./4' /5 62' C/&7-6-/& P*'5-(
A condition prefix attached to a PROCEDURE or BEGN statement applies to all the
statements up to and including the corresponding END statement. This includes other
PROCEDURE or BEGN statements nested with that block.
The scope of a condition prefix applied to a DO or SELECT statement is limited to
execution of the statement itself; it does not apply to execution of the entire group.
Udhayas PL/I Material 6/06/2003 Page:- 56 / 161
ON S6+6'1'&6
The ON statement establishes the action to be executed for any subsequent raising of
an enabled condition in the scope of the established action.
ON condition [SNAP] [SYSTEM] | on&'nit
SNAP
Specifies that when the enabled condition is raised, a list is printed of all the blocks and
ON-units active in the current task at the time the condition is raised. The action of the
SNAP option precedes the action of the ON-unit.
SYSTEM
Specifies that the implicit action is taken. The implicit action is not the same for every
condition, although for most conditions a message is printed and the ERROR condition is
raised.
on&'nit
Specifies the action to executed when the condition is raised and is enabled. The action
is defined by the statement or statements in the ON-unit itself. The On-unit is not
executed at the time the ON statement is executed; it is executed only when the specified
enabled condition is raised.
nu** on-3nit
The effect of a null statement on-unit is to execute normal return from the condition. Use
of the null on-unit is not the same as disabling, for two reasons:

A null ON-unit can be specified for any condition, but not all conditions can be
disabled.
Disabling a condition, if possible, can save time by avoiding any checking for this
condition. (f a null ON-unit is specified, the system must still check for the raising of
the condition).
The execution of an ON statement establishes an action specification for a condition.
Once this action is established, it remains established throughout that block and
throughout all dynamically descendent blocks until it is overridden by the execution of
another ON statement or a REVERT statement or until termination of the block in which
the ON statement is executed.
E(+143' 5/* REVERT@"
PROC1: PROCEDURE;
ON CONVERSON BEGN;
END;
B: PROC2;
ON CONVERSON BEGN; /' 2-errides 2/ unit in PR2,1 '/
END;
.
.
Udhayas PL/I Material 6/06/2003 Page:- 57 / 161
REVERT CONVERSON; /' /o7 t&e 2/ unit in PR2,1 is ac6 in contro* '/
END PROC2;
END PROC1;
Note: Dynamic descendency refers to the fact that ON-units are inherited from the
calling procedure in all circumstances. Dynamic descendancy is often not known until run
time, since a procedure can be called from anywhere where it is visible.
To prevent an ERROR condition raised in an ERROR ON-unit from executing the same
ERROR ON-unit, thus raising the ERROR condition again and causing a loop, the
following technique can be used:
ON ERROR BEGN;
ON ERROR SYSTEM;
.
.
.
END;
E(+143'
DCL F FLE, G FLE VARABLE;
G =F;
L1: ON ENDFLE (G);
L2: ON ENDFLE (F);
The statements labelled L1 and L2 are equivalent.
E(+143'
DECLARE FV FLE VARABLE,
FC1 FLE,
FC2 FLE;
FV = FC1;
ON ENDFLE (FV) GO TO FN; /' 2/ unit for 1,1 '/
.
.
.
FV =FC2;
READ FLE (FC1) NTO (X1);
READ FLE (FV) NTO (X2);
An ENDFLE condition raised during the first READ statement causes the on-unit to be
entered, since the on-unit refers to file FC1. f the condition is raised in the second READ
statement, however, the on-unit is not entered, since this READ refers to file FC2.
SIGNAL S6+6'1'&6
You can raise a condition by means of the SGNAL statement. This statement can be
used in program testing to verify the action of an ON-unit and to determine whether the
correct action is associated with the condition. The established action is taken unless the
condition is disabled.
f the specified condition is disabled, the SGNAL statement becomes equivalent to a null
statement. The syntax for the SGNAL statement is:
Udhayas PL/I Material 6/06/2003 Page:- 58 / 161
SGNAL Condition;
C3+,,-5-.+6-/& /5 C/&7-6-/&,
The conditions are classified as follows:
Computation conditions-those associated with data handling, expression evaluation,
and computation. The conditions are:
CONVERSON SZE
FXEDOVERFLOW UNDERFLOW
OVERFLOW ZERODVDE
f a computational conditional (except UNDERFLOW) is raised and the condition is
disabled, the program is in error;
nput/output conditions-those conditions associated with input and output.
They are:
ENDFLE ENDPAGE
KEY TRANSMT
UNDEFNEDFLE NAME
RECORD
ENDFLE When end of file is reached
KEY ncorrect KEY for a keyed data set
UNDEFNEDFLE File could not be opened
ENDPAGE End of page on PRNT file
TRANSMT /O error
NAME On GET DATA when incorrect items in input
RECORD Typically when buffer is too small for record
For read. For write of fixed length records it
Can occur if buffer is larger than record size.
Program-checkout conditions-those conditions that facilitate the debugging of a
program. They are
STRNGSZE
STRNGRANGE
SUBSCRPTRANGE
f SUBSCRPTRANGE is raised is disabled, the program is in error. Because this
checking involves a substantial overhead in both storage space and run time, it
usually is used only in programs testing. t is removed for production programs,
because the above are normally disabled conditions.
Miscellaneous conditions, which are:
AREA ERROR
ATTENTON FNSH
CONDTON
AREA C/&7-6-/&
The AREA condition is raised in either of the following circumstances:
When an attempt is made to allocate a based variable within an area that contains
insufficient free storage for the allocation to be made.
When an attempt is made to perform an area assignment, and the target area
contains insufficient storage to accommodate the allocations in the source area.
Udhayas PL/I Material 6/06/2003 Page:- 59 / 161
The syntax for AREA is:
ON AREA BEGN;
.
END;
Result: n both cases the attempted allocation or assignment has no effect.
mplicit Action: A message is printed and the ERROR condition is raised.
Status: AREA is always enabled.
Normal Return
1) f the condition was raised by an allocation and the on-unit is a NULL on-unit the
allocation is not attempted again.
2) f the on-unit is not NULL then the allocation is attempted again provided the
pointer qualifying the reference to the AREA has been changed
3) f the condition was raised by an area assignment or by a SGNAL statement, the
execution continues from the next statement.
CONDITION C/&7-6-/&
The CONDTON condition is raised by a SGNAL statement that specifies the
appropriate name. The name specified in the SGNAL statement determines which
CONDTON condition is to be raised. The syntax for CONDTON is:
ON CONDTON (name)
Abbreviation: COND
The CONDTON condition allows you to establish an ON-unit that is executed whenever
a SGNAL statement is executed specifying CONDTON and that name.
As a debugging aid, this condition can be used to establish an ON-unit whose execution
results in printing information that shows the current status of the program. The On-unit
can be executed from any point in the program through placement of SGNAL statement.
Of course, normal rules of name scope apply;
Following is an example of how the CONDTON condition might be included in a
program:
DCL TEST CONDTON; /* declare the TEST condition */
ON CONDTON (TEST) BEGN; /*Now set up the ON unit */
.
.
.
END;
The begin-block is executed whenever the following statement is executed:
SGNAL CONDTON (TEST);
I#p$icit Action: A message is printed and execution continues with the statement
following SGNAL.
(tat's: CONDTON is always enabled.
Normal Return: Execution continues with the statement following the SGNAL statement.
CONVERSION C/&7-6-/&
The CONVERSON computational condition is raised whenever an invalid conversion is
attempted on character data.
Udhayas PL/I Material 6/06/2003 Page:- 60 / 161
A character other than 0 or 1 exists in character data being converted to bit data.
A character value being converted to a numeric character field, or to coded arithmetic,
contains characters which are not the representation of an optionally signed arithmetic
constant, or an expression to represent a complex constant .
A value being converted to a character pictured item contains characters not allowed
by the picture specification.
The syntax for CONVERSON is;
ON CONVERSON ..
Im)*icit (ction: A message is printed and the ERROR condition is raised.
Status% CONVERSON is enabled throughout the program, except within the scope of a
condition prefix specifying NOCONVERSON.
/orma* Return: f the ONSOURCE or ONCHAR PSEUDOVARABLE is used, the
program retries the conversion on return from the on-unit. f the error is not corrected, the
program loops. f these PSEUDOVARABLES are not used the ERROR condition is
raised.
E(+143'
DCL X BT(4);
X = '10A1'; /' a** c&ars must e 1 or 8 '/

ENDFILE C/&7-6-/&
The ENDFLE input \ output condition can be raised during a GET or READ operation by
an attempt to read past the end of the file specified in the GET or READ statement. t
applies only to SEQUENTAL NPUT, SEQUENTAL UPDATE, and STREAM NPUT
files. The syntax for ENDFLE is:
ON ENDFLE (file-reference) ...
n record-oriented data transmission, ENDFLE is raised whenever an end of file is
encountered during the execution of a READ statement.
n stream-oriented data transmission, ENDFLE is raised during the execution of a GET
statement if an end of file is encountered either before any items in the GET statement
data list have been transmitted or between transmission of two of the data items. f an
end of file is encountered while a data item is being processed, or if it is encountered
while an X format item is being processed, the ERROR condition is raised.
f the file is not closed after ENDFLE is raised, any subsequent GET or READ statement
for that file immediately raises the ENDFLE condition again.
Im)*icit (ction: A message is printed and the ERROR condition is raised.
Status@ The ENDFLE condition is always enabled.
/orma* Return: Execution continues with the statement immediately following the GET
or READ statement that raised this condition. f a file is closed in an on-unit for this
Udhayas PL/I Material 6/06/2003 Page:- 61 / 161
exception, the results of normal return is undefined. Exit in such situations must be by a
GO TO from the on-unit block.
ENDPAGE C/&7-6-/&
The ENDPAGE input/output condition is raised when a PUT statement results in an
attempt to start a new line beyond the limit specified for the current page. This limit can
be specified by the PAGESZE option in an OPEN statement; if PAGESZE has not been
specified, a default limit of 60 is applied. The attempt to exceed the limit can be made
during data transmission (including associated format items, if the PUT statement is edit-
directed), by the LNE option, or by SKP option. ENDPAGE can also be raised by a LNE
option or LNE format item that specified a line number less than the current line number .
The syntax for ENDPAGE is
ON ENDPAGE (file-reference)
ENDPAGE is raised only once per page, except when it is raised by the SGNAL
statement. We can artificially signal this condition with SGNAL ENDPAGE(filename);
The ON-unit can start a new page by execution of a PAGE option or a PAGE format
item, which sets the current line to one.
f the ON-unit does not start a new page, the current line number can increase
indefinitely
Im)*icit (ction: A new page is started. f the condition is signalled, execution is
unaffected and continues with the statement following the SGNAL statement.
Status@ ENDPAGE is always enabled.
/orma* Return: Execution of the PUT statement continues and the data is written on the
current line which may(probably would) have been changed by the ON UNT.
ERROR C/&7-6-/&
The ERROR condition is raised under the following circumstances:
Provides common condition that can be used to check many other conditions
As a result of the implicit action for a condition for which that action is to print an error
message and raise the ERROR condition.
As a result of an error (for which there is no other condition) during program
execution.
As a result of an ABEND
As a result of a SGNAL ERROR statement.
Use ONCODE built-in to distinguish between various circumstances that can raise
ERROR condition
The syntax for ERROR is:
ON ERROR ..
Im)*icit (ction% f the condition is raised in the major task, the FNSH condition is raised
and the task terminates. f the condition is raised in any other task, the program is
terminated.
Status: ERROR is always enabled
/orma* Return : The implicit action is taken.
FINIS= C/&7-6-/&
Udhayas PL/I Material 6/06/2003 Page:- 62 / 161
The FNSH condition is raised during execution of a statement that would terminate the
major task of the PL/ program, that is, by a STOP statement in any task, or an EXT
statement in the major task, or a RETURN or END statement in the MAN procedure of
the program.
/ote: The STOP statement immediately terminates the program including all concurrent
tasks. Before termination the FNSH condition is raised in the task in which the STOP
executes. On normal return from the on-unit all tasks in the program terminate.
The EXT statement immediately terminates the program or the task that contains the
statement and all tasks attached by this task. f executed in a major task, EXT raises the
FNSH condition in that task. On normal return from the on-unit, the task executing the
statement and all of its descendant tasks are terminated. Thus EXT in a major task is
equivalent to a STOP statement.
The condition is also raised by SGNAL FNSH, and as part of the implicit action for the
ERROR condition. The condition is raised in the task in which the statement is executed,
and any ON-unit specified for the condition is executed as part of that task. An abnormal
return from the ON-unit avoids program termination and allows the program to continue.
The syntax for FNSH is:
ON FNSH ..
Im)*icit (ction: No action is taken and processing continues from the point where the
condition was raised.
Status% FNSH is always enabled.
/orma* Return: Execution of the statement is resumed.
FI>EDOVERFLO% C/&7-6-/&
The FXEDOVERFLOW computational condition is raised when the length of the result of
a fixed-point arithmetic operation exceeds the maximum length allowed by the
implementation.
The FXEDOVERFLOW condition differs from the SZE condition in that SZE is raised
when a result exceeds the declared size of a variable, while FXEDOVERFLOW is raised
when a result exceeds the maximum allowed by the computer. The syntax for
FXEDOVERFLOW S
ON FXEDOVERFLOW ...
Resu*t: The result of the invalid fixed-point operation is undefined.
Im)*icit (ction: A message is printed and the ERROR condition is raised.
Status@ FXEDOVERFLOW is enabled throughout the program, except within the scope
of a condition prefix that specifies NOFXEDOVERFLOW.
E(+143'
DCL A FXED DEC(15);
DCL B FXED DEC(15);
DCL C FXED DEC(15);
A=40000000;
Udhayas PL/I Material 6/06/2003 Page:- 63 / 161
B=80000000;
C=A*B; /' fi5ed )oint o-erf*o7 is raised '/
OVERFLO%
Occurs when the magnitude of the result of a floating point operation exceeds 10**75
A=55E71;
B=23E11;
C=A*B; /' 2V+R1L2I condition is raised '/
Resu*t: The value of such an invalid floating point number is undefined
Im)*icit (ction: A message is printed and ERROR is raised.
Status: Enabled throughout the program except within the scope of NOOVERFLOW
/orma* Return: Control returns to the point after the instruction which caused this
condition.

SICE C/&7-6-/&
The SZE computational condition is raised only when high-order (that is, leftmost)
significant binary or decimal digits are lost in an attempted assignment to a variable or an
intermediate result or in an input/output operation. This loss can result from a conversion
involving different data types, different bases, different scales, or different precision. The
size condition is not enabled unless it appears in a condition prefix. The syntax for SZE
is:
ON SZE ...
The SZE condition differs from the FXEDOVERFLOW condition in that, whereas
FXEDOVERFLOW is raised when the size of a calculated fixed-point value exceeds the
maximum allowed by the implementation, SZE is raised when the size of the value being
assigned to a data item exceeds the declared (or default) size of the data item in your
program. SZE can be raised on assignment of a value regardless of whether or not
FXEDOVERFLOW was raised in the calculation of the value.
The declared size is not necessarily the actual precision with which the item is held in
storage, however, the limit for SZE is the declared or default size, not the actual size in
storage. For example, a fixed binary item of precision (20) occupies a FULLWORD in
storage, but SZE is raised if a value whose size exceeds FXED BNARY (20) is
assigned to it.
Because this checking involves a substantial overhead in both storage space and run
time, it usually is used only in program testing. You should remove it for production
programs.
f the SZE condition is raised and it is disabled, the program is in error.
Resu*t@ The result of the assignment is undefined.
Im)*icit (ction% A message is printed and the ERROR condition is raised.
Status% SZE is disabled within the scope of a NOSZE condition prefix and elsewhere
throughout the program, except within the scope of a condition prefix specifying SZE.
E(+143'
DCL X FXED DEC(4);
Udhayas PL/I Material 6/06/2003 Page:- 64 / 161
DCL Y FXED DEC(5) NT(12345);
X = Y; /' siJe condition is raised '/
STRINGRANGE C/&7-6-/&
The STRNGRANGE program-checkout condition is raised whenever the values of the
arguments to a SUBSTR reference fail to comply with the rules described for the
SUBSTR built-in function. t is raised for each such reference. The syntax for
STRNGRANGE is:
ON STRNGRANGE..
Im)*icit (ction: A message is printed and processing continues as described for normal
return.
Status@ STRNGRANGE is disabled by default and within the scope of a
NOSTRNGRANGE condition prefix. t is enabled only within the scope of a
STRNGRANGE condition prefix.
/orma* Return: Depends on various factors. (See PL/ language reference)

E(+143'
DCL NAME CHAR(20);
DCL FRST CHAR(16);
FRST=SUBSTR(NAME,5,20); /' raises t&e string range condition '/
/' S0RI/GR(/G+ is disa*ed ! defau*t# 0o ena*e it code as e*o7'/
(STRNGRANGE):
MANLNE PROCEDURE OPTONS(MAN);
.
.
.
END MANLNE;
STRINGSICE C/&7-6-/&
The STRNGSZE program-checkout condition is raised when you attempt to assign a
string to a target with a shorter maximum length. The syntax for STRNGSZE is:
ON STRNGSZE ..
Resu*t% After the condition action, the truncated string is assigned to its target string. The
right-hand characters, bits or graphics of the source string are truncated so that the target
string can accommodate the source string.
Im)*icit (ction; A message is printed and processing continues.
Status: STRNGSZE is disabled by default and within the scope of a NOSTRNGSZE
condition prefix. t is enabled only within the range of a STRNGSZE condition prefix.
E(+143'
DCL NAME CHAR(20);
DCL FRST CHAR(16);
FRST=NAME; /' raises t&e stringsiJe condition '/
/' 0o ena*e stringsiJe =7&ic& is off ! defau*t) for an assignment statement code '/
/' e*o7 '/
Udhayas PL/I Material 6/06/2003 Page:- 65 / 161
(STRNGSZE):
RECEVE = SUBSTR(FELD_1,5,20);
SUBCRIPTRANGE C/&7-6-/&
The SUBSCRPTRANGE program-checkout condition is raised whenever a subscript is
evaluated and found to lie outside its specified bounds.
ON SUBCRPTRANGE ..
Resu*t% When SUBCRPTRANGE has been raised, the value of the invalid subscript is
undefined, and, hence, the reference is also undefined.
Im)*icit (ction: A message is printed and the ERROR condition is raised.
Status@ SUBSCRPTRANGE is disabled by default and within the scope of a
NOSUBSCRPTRANGE condition prefix. t is enabled only within the scope of a
SUBCRPTRANGE condition prefix.
/orma* Return: Normal return from a SUBSCRPTRANGE ON-unit raises the ERROR
condition .
UNDEFINEDFILE C/&7-6-/&
The UNDEFNEDFLE input/output condition is raised whenever a nonzero return code is
received from the OPEN SVC. f the attempt is made by means of an OPEN statement
that specifies more than one file, the condition is raised after attempts to open all files
specified. The syntax for UNDEFNEDFLE is:
ON UNDEFNEDFLE (file-reference) ...
Im)*icit (ction: A message is printed and the ERROR condition is raised.
Status@ UNDEFNDFLE is always enabled.
/orma* Return: Upon the normal completion of the final ON-unit, control is given to the
statement immediately following the statement that raised the condition.
UNDERFLO%
Occurs when the magnitude of the result of a floating point operation is less
than 10**-78
A=23E-71;
B=3E-9;
C=A*B; /' underf*o7 condition '/
Resu*t: The value of the invalid floating point value is set to 0.
Im)*icit (ction: A message is printed and execution continues from the point at which
the condition was raised
Status: Enabled throughout the program except within the scope of NOUNDERFLOW.
Normal Return: Control returns to the point immediately following the point at which the
condition was raised.
Udhayas PL/I Material 6/06/2003 Page:- 66 / 161
CERODIVIDE C/&7-6-/&
The ZERODVDE computational condition is raised when an attempt is made to divide
by zero. This condition is raised for fixed-point and floating-point division. The compiler
can also raise this condition, instead of fixed overflow, when:
The results of a conversion from decimal to binary exceeds the maximum length
allowed by the implementation.
A fixed, floating-point, or decimal divide exception is detected by the hardware, as, for
example, when using the DVDE built-in function and the quotient exceeds the size
specified for the result.
The syntax for ZERODVDE is:
ON ZERODVDE
f the ZERODVDE condition is raised and it is disabled, the program is in error.
Resu*t: The result of a division by zero is undefined.
mplicit Action: A message is printed and the ERROR condition is raised.
Status@ ZERODVDE is enabled throughout the program, except within the scope of a
condition prefix specifying NOZERODVDE.
/orma* Return: Control returns to the point immediately following the point at which the
condition was raised.
E(+143'
A=15;
B=0;
C=A/B; /' K+R2.IVI.+ condition '/
E(+143' 6/ 7'1/&,6*+6' SICE ./&7-6-/&
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
(SZE):
MYPROG: PROCEDURE OPTONS(MAN);
DCL FELD1 FXED DECMAL(7,2);
DCL FELD2 FXED DECMAL(7,2);
DCL FELD3 FXED DECMAL(10,2);
DCL SUM FXED DECMAL(7,2);
ON SZE BEGN;
PUT SKP LST('SZE ERROR');
END;
FELD3=19999999.99;
FELD1=FELD3;
GET DATA (FELD1,FELD2);
SUM=FELD1+FELD2;
PUT SKP LST(SUM);
GET DATA (FELD1,FELD2);
SUM=FELD1+FELD2;
PUT SKP LST(SUM);
END MYPROG;
/*
//GO.SYSN DD *
FELD2=1.23,FELD1=3.45;
Udhayas PL/I Material 6/06/2003 Page:- 67 / 161
FELD1=99999.99,FELD2=88888.88;
/*
//
Udhayas PL/I Material 6/06/2003 Page:- 68 / 161
E(+143' 6/ 7'1/&,6*+6' 8+*-/), CONDITIONS
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL FELD FXED DEC(5,2);
DCL BUFF CHAR(10);
DCL BUFF1 CHAR(20) NT('ABCDEFGHJKLMNOP');
DCL (J,K) FXED BNARY(15);
DCL A FXED DECMAL(5,2);
DCL MYCONDTON CONDTON;

ON CONVERSON BEGN;
PUT SKP LST('CONVERSON CONDTON RASED');
PUT SKP EDT('CHAR N ERROR S=',ONCHAR( ))(A);
PUT SKP EDT('FELD N ERROR S=',ONSOURCE( ))(A);
PUT SKP LST('ATTEMPTNG REPAR...');
ONCHAR='1';
END;
ON STRNGSZE PUT SKP LST('STRNGSZE CONDTON...');
ON STRNGRANGE PUT SKP LST('STRNGRANGE CONDTON...');
ON ERROR PUT SKP LST('ERROR CONDTON RASED, PROGRAM
ABENDNG..');
ON FNSH PUT SKP LST('FNSH CONDTON RASED.DO CLEANUP');
ON FXEDOVERFLOW PUT SKP LST('FXED OVERFLOW CONDTON
RASED');

ON SZE PUT SKP LST('SZE CONDTON RASED');

ON NAME(SYSN) PUT SKP LST('NAME CONDTON RASED ON SYSN');

ON CONDTON(MYCONDTON) PUT SKP LST('MYCONDTON RASED');

J=1;K=15;
GET EDT (FELD)(F(5,2)); /' raises con-ersion condition '/
PUT EDT(FELD)(F(6,2));
(STRNGSZE):BUFF=SUBSTR(BUFF1,J,K); /' raises stringsiJe cond '/

J=10;K=20;
(STRNGRANGE):BUFF=SUBSTR(BUFF1,J,K);/'raises stringrange cond '/

J=32700;K=32700;J=J*K*J; /' raises fi5ed o-erf*o7 condition '/

J,K=32700;
(SZE):J=J+K; /' raises siJe condition '/

GET SKP DATA(A); /' name condition raised '/

GET SKP DATA(A); /' t&is time data is fine'/

(STRNGSZE):SGNAL STRNGSZE; /' Qust for 6ic6s '/
Udhayas PL/I Material 6/06/2003 Page:- 69 / 161
SGNAL STRNGSZE; /'sorr! 7ont 7or6 &ere '/

SGNAL CONDTON(MYCONDTON);
END MYPROG;
/*
//GO.SYSN DD *
A1200
B=12.34;
A=12.34;
/*
//
Udhayas PL/I Material 6/06/2003 Page:- 70 / 161
SECTION ! ARRAYS
(rra!s
DCL STUD_AVG (365) FXED DEC(4,2);
DCL TABLE(0:11) FXED DEC(5);
DCL GRAPH(-3:3) FXED DEC(5,2);
DCL LST(-2:6) FXED BN(15,0) NT(1,2,4,21,2,3,4,80,90);
DCL TABLE(3,2) FXED DEC(5);
COLUMN 1 COLUMN 2
ROW 1 (1,1) (1,2)
ROW 2 (2,1) (2,2)
ROW 3 (3,1) (3,2)
DCL AXS(-3:3,-4:4) FLOAT DEC(6) NT((63)0);
DCL B(10) FXED DEC(3) NT((7)0,1,2,3);
DCL TABLE(10) CHAR(2) NT((10)(2)'A');
DCL TABLE(10) CHAR(5) NT((10)?1A'EMPTY');
/' note t&e =1) @# It is reAuired @ '/
Access an element as below AXS(-3,-4) /' first e*ement)
Subscripts can be nested as below
DCL X(5) FXED BN(15,0) NT(10,20,30,40,50);
DCL Y(3) FXED BN(15,0) NT(3,2,1);
=3;
Z=X(Y()); /' K is 18 '/
Varia*e arra! ounds
PROC1: PROCEDURE;
DCL A(500) FXED BN(31) NT((500)7);
DCL B FXED BN(31);
CALL MYSUM(A,B);
.
.
.
END PROC1;
MYSUM:PROCEDURE(ARRAY,SUM);
DCL ARRAY(*) FXED BN(31);
DCL SUM FXED BN(31);
DCL LOW FXED BN(31);
DCL HGH FXED BN(31);
DCL NDEX FXED BN(31);
DCL (HBOUND,LBOUND) BULTN;
LOW = LBOUND(ARRAY,1);
/' second )arm is t&e dimension 7e are *oo6ing at'/
HGH = HBOUND(ARRAY,1);
/' L2I and %IG% are no7 t&e ounds of (RR(4'/
SUM=0;
DO NDEX=LOW TO HGH BY 1;
SUM=SUM + ARRAY(NDEX);
END;
END MYSUM;
Udhayas PL/I Material 6/06/2003 Page:- 71 / 161
I/2 o)erations and (rra!s
DCL AMOUNT(20) FXED DECMAL(3);
GET LST AMOUNT; /' (M23/0=1) to (M23/0=28) are in)ut '/
GET LST((TEMP() DO = 1 TO LMT));
GET LST(((A(,J)DO =21 to 5)DO J=3 TO 7));
/' note t&at I is inner .2 =-aries fast)# " is outer .2=-aries s*o7*!)'/
(rra! (ssignment
DCL MONTHS(12) FXED DEC(4,1);
MONTHS = 0; /' inits a** e*ements of M2/0%S to 8 '/
DCL A(10) FXED DEC(6);
DCL B(10) FXED DEC(6);
A=B;
DCL A FXED DEC(6) NT(1,2,3,4,5,6);
A=-A; /' ( is no7 -1?-2?-3?-E?-:?-> '/
A=A*2; /' ( is no7 -2?-E?->?-R?-18?-12 '/
DCL B FXED DEC(6) NT(1,2,3,4,5,6);
A=A+B; /' ( is no7 -1?-2?-3?-E?-:?-> '/
,ross Sections of (rra!s
DCL TABLE(3,4) FXED BNARY(15);
TABLE(*,1) refers to first column of TABLE
TABLE(1,*) refers to first row of TABLE
TABLE(*,3) refers to third column of TABLE
S3BS,RIP0R(/G+ condition
Default state is disabled. To enable do one of the following
(SUBSCRPTRANGE):
MATRX: PROC OPTONS(MAN);
.
END MATRX;
ON SUBSCRPTRANGE
BEGN;
.
.
END;
E(+143' /5 ARRAY ),+0'
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL ARRAY(2,10) FXED DECMAL(2) NT((10)1,(10)2);
PUT DATA (ARRAY);
PUT SKP LST('ARRAY AFTER ARRAY+10..');
ARRAY=ARRAY+10;
PUT SKP;
PUT DATA (ARRAY);
Udhayas PL/I Material 6/06/2003 Page:- 72 / 161
PUT SKP LST('NOW RESTORNG ARRAY...');
ARRAY(1,*)=1;
ARRAY(2,*)=2;
PUT SKP;
PUT DATA(ARRAY);
END MYPROG;
/*
//
E(+143' 6/ 7'1/&,6*+6' ARRAYS
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
MYPROG: PROCEDURE OPTONS(MAN);
DCL FELD_ARRAY(10) FXED DECMAL(7,2) NT(1,2,3,(7)9);
DCL SUM FXED DECMAL(7,2);
CALL ADD(FELD_ARRAY);
PUT SKP LST(SUM);
ADD:PROCEDURE (A);
DCL A(*) FXED DECMAL(7,2);
DCL (HBOUND,LBOUND) BULTN;
DCL NDEX FXED BNARY(15);
DCL UPPER FXED BNARY(15);
DCL LOWER FXED BNARY(15);
SUM=0;
LOWER=LBOUND(A,1);
UPPER=HBOUND(A,1);
DO NDEX=LOWER TO UPPER BY 1;
SUM=SUM+A(NDEX);
END;
END ADD;
END MYPROG;
/*
//
Udhayas PL/I Material 6/06/2003 Page:- 73 / 161
SECTION 9 PICTURES AND STRUCTURES
Pictures
To treat character strings as Arithmetic data
To treat arithmetic quantities as character strings
To edit data ( Zero suppression, Dollar float, +,-,DB,CR and comma decimal
insertion in numeric data) for output to printer
PCTURE 9)icture s)ecification c&aracters9
Picture specification characters are 9,V,$,Z,.,,,DB,CR
DCL A PC '999V99' /' F re)resents a numeric digit '/
DCL B PC '(3)9V(2)9' /' V is t&e im)*ied decima* )oint '/
PIC B<6', ED)-8+3'&6 V+3)' +,,-0&'7 I&6. 8+3)' N/6'
99999 5 DECMAL FXED(5) 12345 12345^
99999V 5 DECMAL FXED(5) 12345 12345^
999V99 5 DECMAL FXED(5,2) 123.45 123^45
999V99 5 DECMAL FXED(5,2) 12345 345^00 1
V99999 5 DECMAL FXED(5,5) 12345 ^00000 2
99999 5 DECMAL FXED(5) 123 00123^
999V99 5 DECMAL FXED(5,2) 123 123^00
9V9 5 DECMAL FXED(2,1) 123.45 3^4 3
999V99 5 DECMAL FXED(5,2) -123.45 123^45 4
S999V99 5 DECMAL FXED(5,2) -123.45 -123^45
-999V99 6 DECMAL FXED(5,2) -123.45 -123^45
-999V99 6 DECMAL FXED(5,2) +123.45 123^45
S999V99 6 DECMAL FXED(5,2) +123.45 +123^45
999V99S 6 DECMAL FXED(5,2) -123.45 123^45-
+999V99 6 DECMAL FXED(5,2) +123.45 +123^45
+999V99 6 DECMAL FXED(5,2) -123.45 123^45
Note:
1:Truncation of most significant digits occurred
2:Truncation of significant digits occurred
3:Truncation on both sides of decimal points occurred
4:Sign is lost as picture clause did not have provision for sign S
Arithmetic Operations on Decimal Picture Data
DCL SUM PC'9999';
DCL A PC'999';
DCL B PC'999';
SUM = A + B;
The compiler generates code to
a)Convert A to Fixed Decimal
b)Convert B to Fixed Decimal format
c) Add A and B
d)Convert the result to character form (PC of SUM)
e)Place the converted result in SUM.
Udhayas PL/I Material 6/06/2003 Page:- 74 / 161
Note that arithmetic operations can be performed on PC fields with editing
characters. However it results in inefficient code.
C 4-.6)*' .2+*+.6'* s used for suppression of leading Zeroes.
PIC V+3)' +,,-0&'7 I&6'*&+3 R'4*','&6+6-/&
ZZZZ9 100 bb100
ZZZZ9 0 bbbb0
ZZZZZ 0 bbbbb
ZZZV99 123 12300
ZZZVZZ 1234 23400
ZZZVZZ .01 bbbb1
ZZZV99 0 bbb00
Z9999 0 b0000
ZZZVZ9 /' in-a*id# If one K a))ears to rig&t of decima*? t&en a** edit
c&ars must K '/
ZZ9ZZ /' In-a*id# (** K9S must e to t&e *eft of t&e F '/
D'.-1+3 P/-&6
This is an insertion character
DCL A PC'999V.99' NT(12.34);
PUT LST(A); /' out)uts 812#3E '/
DCL A PC'999V99' NT(12.34);
PUT LST(A); /' out)uts 8123E '/
The alignment is caused by the V edit character. Decimal point is only output as
an insertion character. See example below to illustrate this:
DCL A PC'999.99V' NT(12.34);
PUT LST(A); /' out)uts 888#12 '/
C/11+
This is an insertion character
DCL A PC'9,999V.99' NT(3512.34);
PUT LST(A); /' out)uts 3?:12#3E '/
DCL A PC'Z,ZZZV.99' NT(3512.34);
PUT LST(A); /' out)uts 3?:12#3E '/
DCL A PC'Z,ZZZV.99' NT(512.34);
PUT LST(A); /' out)uts :12#3E '/
B3+&B
s another insertion character. Use this to generate blanks on the right hand side
of the picture string. f you need blanks on the left, use the Z edit character
DCL A PC'999V99BBB'; /' t&ree *an6s on t&e rig&t'/
DCL B PC'Z,ZZZV.99(7)B'; /' se-en *an6s on t&e rig&t'/
DCL EDTED_DATE PC'99B99B99'; /'insert *an6s et7een
44?MM? and ..'/
S3+,2
s another insertion character
DCL RUN_DATE CHAR(6);
DCL EDTED_RUN_DATE PC'99/99/99';
EDTED_RUN_DATE=RUN_DATE;
Udhayas PL/I Material 6/06/2003 Page:- 75 / 161
D/33+* S-0&
n the Floating form (where there is more than one $ sign) leading zeroes
are suppressed and last leading Zero is replaced with the $ sign. n static
form (only one $ sign) it appears wherever defined in the picture string.
DCL B PC'$999V.99' NT(12.34);
PUT LST(B); /' out)uts S812#3E '/
DCL B PC'$$$$V.99' NT(12.34);
PUT LST(B); /' out)uts S12#3E '/
S-0& .2+*+.6'*, ?S,",EA
The above characters may be also drifting.
DCL A PC'S999' NT(12);
PUT LST(A); /' out)uts ;812 '/
DCL A PC'SSS9' NT(12);
PUT LST(A); /' out)uts ;12 '/
DCL A PC'9999S' NT(1234);
PUT LST(A); /' out)uts 123E; '/
DCL A PC'+99' NT(144); /'error@'/
PUT LST(A); /' out)uts ;EE '/
DCL A PC'999V.99S' NT(-123.45);
PUT LST(A); /' out)uts 123#E:- '/
A,6'*-,B
Usually used as a floating character for protection against forgery
DCL A PC'*****9V.99' NT(104.75);
PUT LST(A); /' out)uts '''18E#<: '/
DCL A PC'*****V.**' NT(104.75);
PUT LST(A); /' out)uts ''18E#<: '/
DCL A PC'*****V.**' NT(.75);
PUT LST(A); /' out)uts '''''#<: '/
CR +&7 DR
DB or CR can be used to indicate negative values. CR or DB can only appear
to the right of all digit positions in the PC clause.
DCL A PC'99V.99CR' NT(-12.75);
PUT LST(A); /' out)uts 12#<:,R '/
DCL A PC'99V.99DB' NT(-12.75);
PUT LST(A); /' out)uts 12#<:.B '/
DCL A PC'99V.99CR' NT(12.75);
PUT LST(A); /* outputs 12.75bb */
C2+*+.6'* S6*-&0 P-.6)*',
These cannot be used for data items which are to participate in computations .
They are made up of A, X, and 9
Built-in functions of SUBSTR, LENGTH, NDEX and VERFY can be used on
these data items.
A specifies characters A to Z or blank
9 specifies a numeric character
X can contain any character
The B and other insertion characters may not be specified in these PC clauses
This type of PC attribute is used primarily for data validation
E(+143'@
Assume we need to ensure that any data item is of the form 1237AB
Udhayas PL/I Material 6/06/2003 Page:- 76 / 161
The first 4 positions are numeric and the last two are alphabetic.
Code the data item which is to receive the above data as PC'9999AA'
DCL A PC'9999AA';
DCL B CHAR(6);
A = B; /' if t&e format of t&e assigned data does not conform to t&e
PI, of t&e recei-ing fie*d? t&e ,2/V+RSI2/ condition
is raised '/
T2' P ,4'.-5-.+6-/& -, +33/;'7 -& -&4)6 +&7 /)64)6 GET +&7 PUT ,6+6'1'&6,
GET FLE(SYSN) EDT(A,B,C,D) (COL(1),P'ZZZ9',P'99V99',P'AA999',P'(5)9');
In)ut -a*ue 1ormat Resu*ting interna* -a*ue
bb15 P'ZZZ9' 0015
1234 P'99V99' 12^34
AB123 P'AA999' AB123
AB123 P'(5)9' con-ersion error @@
DCL ASSETS FXED DECMAL(11,2);
ASSETS = 45326985.76;
PUT EDT(ASSETS) (P'$$$$,$$$,$$$V.99');
/' out)uts SE:?32>?FR:#<> '/
DCL ASSETS FXED DECMAL(11,2);
ASSETS = 2500.00;
PUT EDT(ASSETS) (P'$ZZZ,ZZZ,ZZZV.99');
/' out)uts S2?:88#88 '/
Structures
DCL 1 EMP_ADDRESS,
2 NAME CHAR(20),
2 STREET CHAR(20),
2 CTY CHAR(20),
2 STATE CHAR(20);
READ FLE(NFLE) NTO (EMP_ADDRESS);
Notes:
Level 1 is the Major structure level which does not have attributes. However
other storage qualifiers like BASED(P) are to be specified here.
Any number > 1 can represent lower levels
Attributes and NT are defined only at elementary levels
There is no equivalent to the COBOL FLLER
STRNG(EMP_ADDRESS) concatenates all the elements into one character
string.
STRNG(structure -aria*e) can also be used as a pseudo variable (on the
LHS of an assignment statement.
DCL 1 SALARY_RECORD,
2 NAME,
3 LAST CHAR(10),
3 FRST CHAR(10),
3 MDDLE CHAR(10),
2 EMP_NO FXED DEC(5),
2 HOURS,
3 REGULAR FXED DEC(4),
3 OVERTMEFXED DEC(4),
Udhayas PL/I Material 6/06/2003 Page:- 77 / 161
2 WAGES,
3 REG_PAY FXED DEC(4),
3 OVT_PAY FXED DEC(4);
F+.6/*-&0
E(+143'@
DCL 1 SALARY_RECORD,
2 NAME,
3 (LAST,FRST,MDDLE) CHAR(10),
2 EMP_NO FXED DEC(5),
2 HOURS,
3 (REGULAR,OVERTME) FXED DEC(4),
2 WAGES,
3 (REG_PAY,OVT_PAY) FXED DEC(4);
I&-6-+3 A66*-9)6'
Elementary data items in the structure can have the NT attribute
E(+143'@
DCL 1 SALARY_RECORD,
2 NAME,
3 LAST CHAR(10) NT('JOHNSON'),
2 EMP_NO FXED DEC(5) NT(12345),
2 HOURS,
3 REGULAR FXED DEC(4) NT(100),
2 WAGES,
3 REG_PAY FXED DEC(4) NT(2000);
N+1', ;-62-& + ,6*).6)*'
DCL 1 EMP_REC,
3 REGULAR_PAY PC'999V99',
3 HOURS,
5 REGULAR PC'99',
5 OVERTME PC'99',
3 WAGES,
5 REGULAR PC'99V99',
5 OVERTME PC'99V99';
EMP_REC.REGULAR_PAY = EMP_REC.HOURS.REGULAR *
EMP_REC.WAGES.REGULAR;
REGULAR_PAY = HOURS.REGULAR * WAGES.REGULAR;
/' a*so 2$ if t&e second and t&ird Aua*ifier uniAue*! identif! t&e data item '/
A**+<, -& ,6*).6)*',
DCL 1 NVENTORY_TEM,
2 PART_NO CHAR(8),
2 QTY_N_HAND PC'9999',
2 SALES_HSTORY(12) PC'99999';
NVENTORY_TEM.SALES_HSTORY(1) = 1234;
A**+<, /5 ,6*).6)*',
DCL 1 WEATHER(20),
2 TEMP,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1),
Udhayas PL/I Material 6/06/2003 Page:- 78 / 161
2 VELOCTY,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1),
2 RANFALL,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1);
Refer to structure as WEATHER(n)
Refer to VELOCTY as VELOCTY(n)
Refer to TEMP.HGH as TEMP.HGH(n) /' ca**ed suscri)ted Aua*ified name
'/
L-B' A66*-9)6'
DCL 1 METRO_WEATHER(365),
2 TEMP,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1),
2 VELOCTY,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1),
2 RANFALL,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1);
DCL 1 COUNTRY_WEATHER LKE METRO_WEATHER;
/' effecti-e*! t&e same as t&e definition e*o7'/
DCL 1 COUNTRY_WEATHER,
2 TEMP,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1),
2 VELOCTY,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1),
2 RANFALL,
3 HGH FXED DEC(4,1),
3 LOW FXED DEC(4,1);
Note that the Dimension Attribute is not copied. To effect the dimension also
code as
DCL 1 COUNTRY_WEATHER(365) LKE METRO_WEATHER;
We can use LKE attribute for a minor structure name also.
A,,-0&1'&6,
We can assign one structure to another so long as they have the same minor
structuring and same numer of elementary items. f arrays are contained within,
the bounds must be the same. We can assign Major to minor structures or vice
versa provided the relative structuring, as defined above, is the same.
Note that even if the attributes of the data items are different, conversion takes
place as per rules.
DCL 1 A
2 B FXED DEC(5),
2 C FXED BN(31),
Udhayas PL/I Material 6/06/2003 Page:- 79 / 161
2 D CHAR(20),
2 E FXED BN(15),
2 F FLOAT DEC(5);
DCL 1 AA
2 BB FXED BN(15),
2 CC FXED DEC(5),
2 DD CHAR(10),
2 EE FXED DEC(4),
2 FF FXED DEC(6);
A = AA; /' -a*id assignment# ,on-ersions occur '/
/' eAui-a*ent to '/
/' B C BB '/
/' , C ,, '/
/' . C .. '/
/' + C ++ '/
/' 1 C 11 '/
A,,-0&1'&6 9< &+1'
DCL 1 NPUT,
2 EMP_NAME CHAR(20),
2 EMP_NUMBER CHAR(6),
2 HOURS,
3 REGULAR PC'99',
3 OVERTME PC'99',
2 GROSS_PAY PC'999V99';
DCL 1 OUTPUT,
2 CARRAGE_CNTL CHAR(1),
2 EMP_NUMBER CHAR(6),
2 EMP_NAME CHAR(20),
2 GROSS_PAY PC'999V99';
OUTPUT = NPUT, BY NAME;
Elements of NPUT whose names are identical to those of OUTPUT are moved.
f Major structure contains a minor structure, the minor structure names must match to
move elementary items within the minor structure.
DCL 1 FRST,
2 MNOR_1,
3 A,
3 B,
2 C,
2 D;
DCL 1 SECOND,
2 MNOR_2,
3 A,
3 B,
2 C,
2 D;
FRST = SECOND, BY NAME;
/' ,?. 7i** e mo-ed# %o7e-er ( and B 7i** not as t&eir Minor
Udhayas PL/I Material 6/06/2003 Page:- 80 / 161
structure names are different '/
S.+3+* 6/ S6*).6)*' +,,-0&1'&6
DCL 1 EMP_REC,
2 EMP_NAME CHAR(20),
2 EMP_ADDRESS,
3 STREET CHAR(20),
3 CTY CHAR(20);
EMP_REC = ' '; /' -a*id '/
/' +MPG/(M+ C 9 9D '/
/' S0R++0 C 9 9D '/
/' ,I04 C 9 9D '/
.efining 2-er*a! of a Sca*ar Varia*e on a Structure
E(+143'
DCL 1 EMP_REC,
2 EMP_NAME CHAR(20),
2 EMP_ADDRESS,
3 STREET CHAR(20),
3 CTY CHAR(20);
DCL EMP_DETALS CHAR(60) DEFNED EMP_REC;
EMP_DETALS='';
.efining 2-er*a! of a structure on a structure
E(+143'
DCL 1 SSUES,
2 CODE CHAR(1),
2 QTY PC '9999',
2 JOB_NO CHAR(4),
2 PART_NO CHAR(7),
2 DEPT CHAR(3),
2 FLLER1 CHAR(3);
DCL 1 RECEPTS DEFNED SSUES,
2 CODE CHAR(1),
2 QTY PC '9999',
2 PART_NO CHAR(7),
2 SUPPLER CHAR(6);
READ FLE(NPUT) NTO SSUES;
SELECT (SSUES.CODE);
WHEN ('1') CALL PROCESS_SSUES;
WHEN ('2') CALL PROCESS_RECEPTS;
OTHERWSE CALL CODE_N_ERROR;
END;
Structures in Stream I/2
Structures may also be specified in EDT or LST directed stream /O. The names
may be major or minor structure names.
E(+143'
DCL 1 NVENTORY,
2 PART_NUMBER CHAR(6),
2 QTY_ON_HAND FXED DEC(5),
2 PRCE FXED DEC(5,2);
Udhayas PL/I Material 6/06/2003 Page:- 81 / 161
GET EDT(NVENTORY) (A(6), F(5), F(5,2));

E(+143'
DCL 1 NVENTORY,
2 PART_NUMBER,
3 TYPE CHAR(2),
3 CODE CHAR(3),
2 REORDER_QTY PC '(4)9';
PUT EDT(PART_NUMBER,REORDER_QTY) (A(2),A(3),F(4));
E(+143'
DCL 1 A,
2 B(10),
2 C(10);
PUT EDT(A) (F(12));
Outputs
A.B(1) A.B(2).. A.B(10) A.C(1)..A.C(10)


Udhayas PL/I Material 6/06/2003 Page:- 82 / 161
SECTION 10 STORAGE CONTROL
S6/*+0' C3+,,',
Unless declared otherwise variables will have the storage class AUTOMATC
MAN: PROCEDURE OPTONS(MAN);
DCL 1 STRUCTURE,
2 A FXED DEC (6,2),
2 B CHAR(20);
.
.
P1: PROC;
DCL TABLE(100) CHAR(10);
.
END P1;
P2: PROC;
DCL LST(500) FXED;
.
END P2;
END MAN;

AUTOMATIC Sto!"#
The above is the layout when P1 is called

AUTOMATIC Sto!"#
The above is the layout when P2 is called
Note the overlaying of TABLE and LST which is characteristic of AUTOMATC variables
Automatic variables lifetime is the lifetime of the enclosing block (Either a PROC or
BEGN) Automatic variables make efficient use of storage. The storage for an automatic
variable is allocated on entry into the block by a )ro*ogue and de-allocated on exit from
the block by e)i*ogue. Prologue and Epilogue code is generated by the compiler.
STATC Storage
MAN: PROCEDURE OPTONS(MAN);
DCL 1 STRUCTURE,
2 A FXED DEC (6,2),
2 B CHAR(20);
.
.
P1: PROC;
DCL TABLE(100) CHAR(10) STATC;
END P1;
P2: PROC;
MAIN
MAIN
$1
$1
$2
$2
ST%UCTU%E
ST%UCTU%E
TAB&E
&IST
Udhayas PL/I Material 6/06/2003 Page:- 83 / 161
DCL LST(500) FXED STATC;
.
END P2;
END MAN;

static storage
static storage
automatic storage
The above is the layout when P1 or P2 are called
Note that Static storage is allocated before start of program execution and remains
allocated throughout program execution.
Where you want variables to retain their value from one invocation of the procedure to
another declare them with the static attribute.
Static variables can be initialised just like automatic variables
DCL FLAG BT(1) NT('1'B) STATC;
B+,'7 S6/*+0'
DCL P PONTER;
DCL A(100) FXED DEC(5) BASED(P);
/' first dec*aration of P is not mandator! as second dec*aration
im)*ies t&e nature of P 7&ic& is a -aria*e of t!)e P2I/0+R
/ote t&at storage for ( is /20 a**ocated ! t&e ao-e dec*aration '/

To refer variable A one of the following needs to be done
Assign to P the value returned by an ADDR( ) function
DCL VALUE1 BT(32) BASED(P);
DCL VALUE2 BT(32);
P = ADDR(VALUE2);
Assign to P another pointer which has a valid value
DCL (P,Q) PONTER;
Q = ADDR(AREA);
P = Q;
nitialise P by using it with SET option of a READ or LOCATE /O statement
READ FLE(NPUT) SET(P); /' I/2 read direct to ased -aria*e '/
LOCATE FLE(OUTPUT) SET(Q); /'Based -aria*e ma))ed to out)ut uffer '/
Allocate the variable which P is tied to.
DCL (P,Q) PONTER;
DCL AREA CHAR(100) BASED(P);
ALLOCATE(AREA); /' 1irst generation of (R+( '/
ALLOCATE(AREA) SET(Q); /' Second generation of (R+( '/
AREA = 'ABCD'D /' 1irst generation used '/
MAIN
$1
$2
ST%UCTU%E
TAB&E
&IST
Udhayas PL/I Material 6/06/2003 Page:- 84 / 161
Q->AREA = 'PQRS'; /' Second generation used '/
S-1)3+6-&0 O8'*3+<,
DCL A(100) FXED BN(15);
DCL B(50) FXED BN(15) DEFNED A;
/' traditiona* definition of o-er*a! '/
DCL A(100) FXED BN(15);
DCL B(50) FXED BN(15) BASED(P);
P = ADDR(A); /' a*ternate met&od '/
/' note t&at storage siJe of B must not
e5ceed t&at of ( '/
t is possible to have two variables based on one PONTER.
DCL PTR PONTER;
DCL 1 A,
2 B PC'9999',
2 C FXED DEC (13,2),
2 D CHAR(21);
DCL 1 J BASED(PTR),
2 X FXED BN(15),
2 Y FLOAT DEC(6),
2 Z BT(7);
DCL 1 W BASED(PTR),
2 K FXED BN(15),
2 L FXED BN(15);
PTR = ADDR(A);
When overlay defining a CHAR varying field special considerations exist
DCL FELD CHAR(100) VARYNG;
DCL 1 STRUCTURE BASED(P),
2 LENGTH FXED BN(15,0),
2 DATA CHAR(100);
P = ADDR(FELD);
Note that LENGTH overlays the Half word length field preceding the varying
character field.
U,-&0 POINTERS -& I/O ?L/.+6' 1/7' I/OA
DCL P PONTER;
DCL TAPE FLE NPUT RECORD ENVRONMENT(F BLKSZE (240)
RECSZE(24));
DCL 1 SSUES BASED(P),
2 CODE CHAR(1),
2 QTY PC'(4)9',
2 JOB_# PC'(4)9',
2 PART_# PC'(7)9',
2 DEPT PC'99',
2 UNUSED CHAR(6);
DCL 1 RECEPTS BASED(P),
2 CODE CHAR(1),
2 QTY PC'(4)9',
2 UNUSED CHAR(6),
Udhayas PL/I Material 6/06/2003 Page:- 85 / 161
2 PART_# PC'(7)9',
2 SUPPLER CHAR'(6)9';
READ FLE (TAPE) SET(P);
SELECT (SSUES.CODE);
WHEN ('1') CALL PROCESS_SSUES;
WHEN ('2') CALL PROCESS_RECEPTS;
END;
To output in LOCATE mode:
LOCATE OUT FLE (TAPEOUT) SET(Q); /' 230 is out)ut data area
for 7&ic& )ointer is L '/
Note that the SET parameter is optional. WE could have coded as below
DCL OUT CHAR(80) BASED(Q);
LOCATE OUT FLE (TAPEOUT);
/' ear*ier dec*aration s&ou*d &a-e een .,L 230 ,%(R=R8) B(S+.=L)D'/
C/&6*/33'7 S6/*+0'
DCL A(100) FXED DEC(5) CONTROLLEDF /' ( does not e5ist &ere '/
ALLOCATE A; /' Storage for ( is a**ocated &ere '/
GET LST(A);
TOTAL = SUM(A);
FREE A; /' Storage for ( is de-a**ocated &ere '/
Note that controlled variables after allocation exist until they are explicitly freed. They
are not affected by block boundaries. For arrays the size specification may be deferred
until ALLOCATE
DCL A(*) FXED DEC(5) CONTROLLED;
ALLOCATE A(100);
DCL TABLE(*,*) BN(1) CONTROLLED;
ALLOCATE TABLE(100,100);
Note that a repeat allocation before a free results in a new generation of the variable. The
previous generation is pushed into a stack meant for storing multiple generations of
controlled variables. A free will then cause the previous generation to be popped out of
the stack. Example follows:
DCL BUFF CHAR(100) CONTROLLED;
ALLOCATE BUFF;
BUFF = 'THS S FRST GENERATON OF BUFF';
PUT LST(BUFF); /' t&is is first generation of uff '/
ALLOCATE BUFF;
BUFF = 'THS S SECOND GENERATON OF BUFF';
PUT LST(BUFF); /' t&is is second generation of uff'/
FREE BUFF;
PUT LST(BUFF); /' t&is is first generation of uff '/
FREE BUFF; /' /o B311 in e5istence '/
The ALLOCATON(X) built in function returns a '1'B if the variable X has been allocated.
Else it returns a '0'B. X can be an element variable name, a major structure name or an
unsubscripted array name.

Udhayas PL/I Material 6/06/2003 Page:- 86 / 161
DCL 1 PRODUCT BASED(Q),
2 DESCRPTON CHAR(20),
2 CODE FXED DEC(4);
DCL P PONTER;
ALLOCATE PRODUCT SET(P); /' note t&at L is not c&anged ! t&is '/
P->PRODUCT.DESCRPTON = 'SCREW';
/' PR2.3,0 is referenced ! a *ocator Aua*ifier '/

FREE P->PRODUCT; /' 1R++ t&e storage for t&e -aria*e t&is 7a!'/
DCL NULL BULTN; /' /3LL is a ui*tin function 7&ic& returns a /3LL
)ointer '/
Storage ,ontro*
Allocation for a given variable can take place statically, (before the execution of the
program) or dynamically (during execution). A variable that is allocated statically remains
allocated for the duration of the program. A variable that is allocated dynamically
relinquishes its storage either upon the termination of the block containing that variable or
at your request, depending upon its storage class.
AUTOMATC specifies that storage is allocated upon each entry to the block that
contains the storage declaration. The storage is released when the block is exited.
STATC specifies that storage is allocated when the program is loaded. The storage is
not freed until program execution is completed.
CONTROLLED specifies that you maintain full control over the allocation and freeing
of storage with the ALLOCATE and FREE statements. Multiple allocations of the
same controlled variable in the same task, without intervening freeing, stack
generations of the variable.
BASED, like CONTROLLED, specifies that you maintain full control over storage
allocation and freeing. Multiple allocations are not stacked but are available at any
time. Each allocation can be identified by the value of a locator variable.
The default storage class is AUTOMATC
(utomatic and ased -aria*es can &a-e interna* sco)e on*!.
Static and contro**ed -aria*es can &a-e interna* or e5terna* sco)e#
S6+6-. S6/*+0' +&7 A66*-9)6'
You use static storage when the variable is local to the procedure and the value it
contains must be saved between successive invocations. Variables declared with the
STATC attribute are allocated prior to running a program. They remain allocated until the
program terminates
E(+143'
A: PROC OPTONS(MAN);
.
.
.
B: PROC;
DECLARE X STATC NTERNAL;
Udhayas PL/I Material 6/06/2003 Page:- 87 / 161
.
.
.
END B;
END A;
Although the variable X is allocated throughout the program, it can be referenced only
within procedure B or any block contained in B.
A)6/1+6-. S6/*+0' +&7 A66*-9)6'
Automatic variables are allocated on entry to the block in which they are declared. They
can be reallocated many times during the execution of a program. You control their
allocation by your design of the block structure. The syntax for the AUTOMATC attribute
is:
DCL X FXED BN(31) AUTOMATC;
E(+143'
A: PROC;
.
.
.
CALL B;
B:PROC;
DECLARE (X,Y) AUTO;
.
.
.
END B;
.
.
.
CALL B;
Each time procedure B is invoked, the variables X and Y are allocated storage. when B
terminates the storage is released, and the values they contain are lost.
Array bounds, string lengths, and area sizes for automatic variables can be specified as
expressions.
A:PROC;
DECLARE N FXED BN;
.
.
.
B:PROC;
DECLARE STR CHAR(N);
C/&6*/33'7 S6/*+0' +&7 A66*-9)6'
Variables declared as CONTROLLED are allocated only when they are specified in an
ALLOCATE statement. You have individual control over each controlled variable. a
controlled variable remains allocated until a FREE statement that names the variable is
encountered or until the end of the program in which it is allocated.
Controlled variables are independent of the program block structure.
E(+143'
Udhayas PL/I Material 6/06/2003 Page:- 88 / 161
A: PROC;
DCL X CONTROLLED;
CALL B;
.
.
.
B:PROC;
ALLOCATE X;
.
.
.
END B;
END A;
The variable X can be referred to within the procedure B and that part of the procedure A
that follows execution of the CALL statement.
ALLOCATE S6+6'1'&6 5/* C/&6*/33'7 V+*-+93',
The ALLOCATE statement allocates storage for controlled variables, independent of
procedure block boundaries. The bounds of controlled arrays, the lengths of controlled
strings, and the size of controlled areas, as well as their initial values, can also be
specified at the time the ALLOCATE statement is executed.
f a bound, length, or size is explicitly specified in an ALLOCATE statement, it
overrides that given in the DECLARE statement.
f a bound, length, or size is specified by an asterisk in an ALLOCATE statement, the
bound, length, or size is taken from the current generation.
DCL X (20) FXED BN CTL;
ALLOCATE X; /' t&e u))er ound is ta6en as 28 from t&e .,L statement '/
DCL X(20) CHAR(5) CONTROLLED;
ALLOCATE X(25) CHAR(6);
/' .,L u))er ound and *engt& are o-erridden '/
nitial values are assigned to a variable upon allocation, if it has an NTAL attribute in
either the ALLOCATE statement or DECLARE statement. f an NTAL attribute
appears in both DECLARE and ALLOCATE statements, the NTAL attribute in the
ALLOCATE statement is used.
FREE S6+6'1'&6 5/* C/&6*/33'7 V+*-+93',
The FREE statement frees the storage allocated for controlled variables. The storage can
then be used for other allocations. For controlled variables, the next most recent
allocation in the task is made available, and subsequent references in the task refer to
that allocation.
M)36-43' G'&'*+6-/&, /5 C/&6*/33'7 V+*-+93',
An ALLOCATE statement for a variable for which storage was previously allocated and
not freed pushes down or stacks storage for the variable. This stacking creates a new
generation of data for the variable. The new generation becomes the current generation;
the previous generation cannot be directly accessed until the current generation has
been freed. When storage for this variable is freed, using the FREE statement, storage is
popped up from the stack.
E(+143'
Udhayas PL/I Material 6/06/2003 Page:- 89 / 161
DCL X(10,20) CHAR(5) CTL;
ALLOCATE X;
ALLOCATE X(10,10);
ALLOCATE X(*,*);
The first generation of X has bounds (10,20); the second and third generations have
bounds (10,10). The elements of each generation of X are all character strings of length
5.
The asterisk notation can also be used in a DECLARE statement, but has a different
meaning.
E(+143'
DCL Y CHAR(*) CTL,
N FXED BN;
N=20;
ALLOCATE Y CHAR(N);
ALLOCATE Y;
The length of the character string Y is taken from the previous generation unless it is
specified in an ALLOCATE statement, in which case Y is given the specified length. This
allows you to defer the specification of the string length until the actual allocation of
storage.
C/&6*/33'7 S6*).6)*',
When a structure is controlled, any arrays, strings, or areas it contains can be adjustable.
For this reason, you are allowed to describe the relative structuring in an ALLOCATE
statement.
E(+143'@
DCL 1 A CTL,
2 B(-10:10),
2 C CHAR(*) VARYNG;
ALLOCATE 1 A,
2 B(1:10),
2 C CHAR (5);
FREE A;
E(+143'
DCL 1 A CTL,
2 B(N,M),
2 C CHAR(L) VARYNG;
N = -10;
M = 10;
L = 5;
ALLOC A;
FREE A;
B)-36"-& F)&.6-/&, 5/* C/&6*/33'7 V+*-+93',
The (LL2,(0I2/ ui*t-in function returns a binary value of precision (31,0) indicating
the number of generations that you can access in the current task for a given controlled
variable. Array-handling functions .IM, which determines the extent of a specified
dimension of an array, and LB23/. and %B23/., which determine the lower and
upper bound, respectively, of a specified dimension of a given array. The
Udhayas PL/I Material 6/06/2003 Page:- 90 / 161
,3RR+/0S02R(G+ built-in function return the amount of storage required by a
particular variable. S02R(G+ returns allocated storage for a variable. For strings, the
built-in function L+/G0% returns the current length of the string.
B+,'7 S6/*+0' +&7 A66*-9)6'
A declaration of a based variable is the amount of storage required and its attributes. A
locator value identifies the location of the generation. A based variable can be used to
describe existing data, to obtain storage by means of the ALLOCATE statement, or to
access data in a buffer by means of the LOCATE statement or READ (with SET option)
statement.
DCL X FXED BN BASED(P);
This declares that references to X, except when the reference is explicitly qualified, use
the variable P to locate the storage for X.
n the following example, the arrays A and C refer to the same storage. The elements B
and C (2,1) also refer to the same storage.
DCL A (3,2) CHAR(5) BASED(P),
B CHAR(5) BASED(Q),
C (3,2) CHAR(5);
P = ADDR(C);
Q = ADDR (A(2,1));
Note% )hen a based *ariab$e is o*er$aid in this wa!" no new storage is a$$ocated The
based *ariab$e 'ses the sa#e storage as the *ariab$e on which it is o*er$aid +A+,"-. in
the e/a#p$e.
L/.+6/* D+6+
There are two types of locator data: pointer and offset.
The value of a pointer variable is effectively an address of a location in storage
relative to the start of the virtual address space ( X'00000000').
The value of an offset variable specifies a location relative to the start of an AREA
variable and remains valid when the area is assigned to a different part of storage.
When an offset variable is used in a reference, its value is implicitly converted to a
pointer value.
Explicit conversion of an offset to a pointer value is accomplished using the PONTER
built-in function.
DCL P PONTER, O OFFSET(B), B AREA;
P = PONTER(O,B);
The OFFSET built-in function complements the PONTER built-in function and returns
an offset value derived from a given pointer and area.
L/.+6/* G)+3-5-.+6-/&
Locator qualification is the association of one or more locator references with a based
reference to identify a particular generation of a based variable. This is called a locator-
qualified reference. The composite symbol -> represents qualified by or points to.
E(+143'@
P -> X
X is a based variable and P is a locator variable.
Udhayas PL/I Material 6/06/2003 Page:- 91 / 161
Reference to a based variable can also be implicitly qualified. The locator reference used
to determine the generation of a based variable that is implicitly qualified is the one
declared with the based variable.
E(+143'
DCL X FXED BN BASED(P);
ALLOCATE X;
X= X + 1;
References to X can also be explicitly locator-qualified as follows:
P->X = P->X + 1;
Q = P;
Q->X = Q->X + 1;
Because the locator declared with a based variable can also be based, a chain of locator
qualifiers can be implied.
E(+143'
DECLARE (P(10),Q) PONTER,
R PONTER BASED (Q),
V BASED (P(3)),
W BASED (R);

ALLOCATE R,V,W;
/' a** references e*o7 are -a*id '/
/' P=3) -P V '/
/' V '/
/' L -P R -P I '/
/' R -P I '/
/' I '/
L'8'3, /5 L/.+6/* G)+3-5-.+6-/&
DECLARE X BASED (P),
P PONTER BASED (Q),
Q OFFSET (A);
ALLOCATE P; /' &a-e to do t&is first to ma6e instance of P '/
ALLOCATE X; /' /o7 7e can ma6e an instance of B '/
The references: B? P-PB? and L-PP-PB all represent three levels of locator
qualification and are equivalent ways of referencing X.
POINTER V+*-+93' +&7 A66*-9)6'
A pointer variable is declared contextually if it appears in the declaration of a based
variable, as a locator qualifier, in a BASED attribute, or in the SET option of an
ALLOCATE, LOCATE, or READ statement.
S'66-&0 P/-&6'* V+*-+93',
NULL ( ) returns null pointer value
SYSNULL ( ) returns null pointer value. Use for static pointer and offset variables
PONTERADD(X,Y) . X is a pointer, Y is a FXED BN(31)
PONTERVALUE(X). X is FXED BN(31)
Udhayas PL/I Material 6/06/2003 Page:- 92 / 161
PONTER(X,Y). X is an OFFSET , Y is an AREA, returns a PONTER.
A READ statement with the SET option.
An ALLOCATE statement.
By assignment of the value of another locator variable, or a locator value returned by
a user-defined function.
B)-36"I& F)&.6-/&, 5/* B+,'7 V+*-+93',
The (..R built-in function returns a pointer value that identifies the first byte of a
variable. The +/0R4(..R built-in function returns a pointer value that is the address of
the first executed instruction if the entry were to be invoked.
n general, the value of the NULL built-in function is used whenever a pointer (or offset)
variable does not identify a location in storage. There are many ways a pointer can
acquire the null value:
1. By assignment of the NULL built-in function
2. Assignment of the ENTRYADDR built-in function of a procedure that has not been
fetched
3. Assignment of the value returned by the ADDR built-in function for an unallocated
controlled variable.
4. t can also acquire the system null value by the assignment of the SYSNULL built-in
function.
ALLOCATE S6+6'1'&6 5/* B+,'7 V+*-+93',
The ALLOCATE statement allocates storage for based variables and sets a locator
variable that can be used to identify the location, independent of procedure block
boundaries.
ALLOCATE (based&*ariab$e [, based&*ariab$e,.])
[N ( area&reference)]
[SET ($ocator&reference)]
N :-Specifies the area variable in which the storage is allocated.
SET :- Specifies a locator variable that is set to the location of the storage
allocated. f the SET option is not specified, the declaration of the based
variable must specify a locator variable.
Storage is allocated in an area when the N option is specified or the SET option specifies
an offset variable.
FREE S6+6'1'&6 5/* 9+,'7 8+*-+93',
The FREE statement frees the storage allocated for based and controlled variables.
FREE $ocator&0'a$ifier&1based&*ariab$e [N (area&reference)]
REFER O46-/& ?S'35"D'5-&-&0 D+6+A
A self-defining structure contains information about its own fields, such as the length of a
string. A based structure can be declared to manipulate this data. String lengths, array
bounds, and area sizes can all be defined by variables declared within the structure.
The variable, known as the object of the REFER option, must be a member of the
declared structure.
t must be REAL FXED BNARY(p,0).
Udhayas PL/I Material 6/06/2003 Page:- 93 / 161
E(+143'
DECLARE 1 STR BASED (P)
2 X FXED BNARY,
2 Y (L REFER (X)),
L FXED BNARY NT(1000);
This declaration specifies that the based structure STR consists of an array Y
and an element X. When STR is allocated, the upper bound is set to the current
value of L which is assigned to X . For any other reference to Y, such as a READ
statement that sets P, the bound value is taken from X.
E(+143'
DECLARE 1 STR BASED(P),
2 (M,N),
2 ARR( REFER (M) ,
J REFER(N) ),
2 X;
When this structure is allocated, the values assigned to and J set the bounds of
the two dimensional array ARR
E(+143'
DCL 1 REC BASED (P),
2 N,
2 A(M REFER(N)),
2 M NTAL (100);
ALLOCATE REC;
N = 86;
WRTE FLE (X) FROM (REC);
86 elements of REC are written. t would be an error to attempt to free REC at
this point, since N must be restored to the value it had when allocated (that is,
100). f N is assigned a value greater than 100, an error occurs when the WRTE
statement is encountered.
A*'+ D+6+ +&7 A66*-9)6'
Area Variables describe areas of storage that are reserved for the allocation of based
variables. This reserved storage can be allocated to, and freed from, based variables by
the ALLOCATE and FREE statements. Area variables can have any storage class and
must be aligned.
When a based variable is allocated and an area is not specified, the storage is obtained
from wherever it is available.
You might want to identify the locations of based variables within an area variable relative
to the start of the area variable. Offset variables are provided for this purpose.
A variable is given the AREA attribute contextually by its appearance in the OFFSET
attribute or an N option, or by explicit declaration. The syntax for the AREA attribute is:
AREA [ ( * | expression [ REFER (variable)] ) ]
f expression, or *, is not specified, the default is 1000
Use * for AREA with controlled attribute, or when an AREA is passed as an
argument to a called procedure where the AREA parameter can be declared with
a * so that the size can be picked up from the argument
Udhayas PL/I Material 6/06/2003 Page:- 94 / 161
E(+143', /5 AREA 7'.3+*+6-/&, +*':
DECLARE AREA1 AREA (2000),
AREA2 AREA;
O55,'6 D+6+ +&7 A66*-9)6'
Offset data is used exclusively with area variables. The value of an offset variable
indicates the location of a based variable within an area variable relative to the start of
the area
DCL variable-name OFFSET (area-variable)
S'66-&0 O55,'6 V+*-+93',
The value of an offset variable can be set in any one of the following ways:
By an ALLOCATE statement
By assignment of the value of another locator variable, or a locator value returned by
a user-defined function.
By assignment of the NULL built-in function value
By using the return value from the OFFSET built-in function.
E(+143'@
DCL X BASED(O),
Y BASED(P),
A AREA,
O OFFSET(A);
ALLOCATE X;
ALLOCATE Y N(A);
The storage class of area A and offset O is AUTOMATC by default. The first ALLOCATE
statement is equivalent to:
ALLOCATE X N(A) SET(O);
The second ALLOCATE statement is equivalent to;
ALLOCATE Y N(A) SET(P);
The following example shows how a list can be built in an area variable using offset
variables:
DCL A AREA,
(T,H) OFFSET(A),
1 STR BASED(H),
2 P OFFSET(A),
2 DATA;
ALLOCATE STR ;
T=H;
NEXT: ALLOCATE STR SET (T->P);
T=T->P;
.
.
GO TO NEXT;
Udhayas PL/I Material 6/06/2003 Page:- 95 / 161
T->P = NULL;
READ: T=H;
DO WHLE ( T ~= NULL);
PUT LST (DATA);
T=T->P;
END;
A*'+ A,,-0&1'&6
The value of an area reference can be assigned to one or more area variables by an
assignment statement. Area-to-area assignment has the effect of freeing all allocations in
the target area and then assigning the extent of the source area to the target area, so
that all offsets for the source area are valid for the target area.
E(+143'
DCL X BASED (O(1)),
O(2) OFFSET (A),
(A,B) AREA;
ALLOC X N (A);
X = 1;
ALLOC X N (A) SET (O(2));
O(2)->X = 2;
B = A;
Using the PONTER built-in function, the references PONTER (O(2),B)->X and
O(2)->X represent the same value allocated in areas B and A respectively.
I&4)6 / O)64)6 /5 A*'+,
The area facility allows input and output of complete lists of based variables as one unit,
to and from RECORD files. On output, the area extent, together with the 16 bytes of
control information, is transmitted.
Because the extents of areas can vary, V format or U format records should be used. the
maximum records length required is governed by the area length (area size + 16).
L-,6 P*/.',,-&0
n list processing, a number of based variables with many generations can be included in
a list. Members of the list are linked together by one or more pointers in one member
identifying the location of other members or lists.
DCL 1 STR BASED(H),
2 P PONTER,
2 DATA,
T PONTER;
ALLOCATE STR;
T=H;
NEXT: ALLOCATE STR SET (T->P);
T = T->P;
. .
.
.
GO TO NEXT;
T->P = NULL;
For the above example, the following statements can be used to access each
generation in turn:
Udhayas PL/I Material 6/06/2003 Page:- 96 / 161
DO T = H
WHLE (T =NULL);
. . . .
. . . T -> DATA . . . ;
. . . T = T->P;
END;
DEFINED A66*-9)6'
The DEFNED attribute specifies that the declared variable is associated with some or all
of the storage associated with the designated base variable.
DECLARE variable-name DEFNED reference
Base variable can be EXTERNAL or NTERNAL
The defined variable must be NTERNAL and a level-1 identifier. t cannot be NTAL,
AUTOMATC,BASED, CONTROLLED, STATC.
There are three types of defining: simple, iSUB, and string overlay.
S-143' D'5-&-&0
Simple defining allows you to refer to an element, array, or structure variable by another
name. The defined and base variables can comprise any data type, but they must match,
E(+143',@
DCL A(10,10,10),
X1(2,2,2) DEF A,
X2(10,10) DEF A (*,*,5),
X3 DEF A (L,M,N);
X1 is a three-dimensional array that consists of the first two elements of each
row, column and plane of A. X2 is a two-dimensional array that consists of the
fifth plane of A. X3 is an element that consists of the element identified by the
subscript expressions L,M, and N.
E(+143'
DCL B CHAR(10),
Y CHAR(5) DEF B;
Y is a character string that consists of the first 5 characters of B.
E(+143'
DCL C AREA (500),
Z AREA (500) DEF C;
Z is an area defined on C.
E(+143'
DCL 1 D UNALGNED,
2 E,
2 F,
3 G CHAR(10) VAR,
3 H,
1 S UNALGNED DEF D,
2 T,
2 U,
3 V CHAR(10) VAR,
Udhayas PL/I Material 6/06/2003 Page:- 97 / 161
3 W;
S is a structure defined on D. For simple defining, the organisation of the two
structures must be identical. A reference to T is a reference to E, V to G, and so
on.
-SUB D'5-&-&0
By defining an iSUB, you can create a defined array that consists of designated
elements from a base array.
An iSUB variable is a reference, in the subscript list for the base array, to the ith
dimension of the defined array. The value of ranges from 1 to n, where n is the
number of dimensions in the defined array.
E(+143',@
DCL A (10,10),
X(10) DEFNED (A(1SUB,1SUB));
X is a one-dimensional array that consists of a diagonal of A.
S6*-&0 O8'*3+< D'5-&-&0
E(+143',@
DCL A CHAR (100),
V(10,10) CHAR(1) DEF A;
V is a two-dimensional array that consists of all the elements in the character string A.
E(+143'
DCL B(10) CHAR(1),
W CHAR (10) DEF B;
W is a character string that consists of all the elements in the array B.
POSITION A66*-9)6'
The POSTON attribute can be used only with string-overlay defining and specifies the
bit or character within the base variable at which the defined variable is to begin.
E(+143',@
DCL C (10,10) BT (1),
X BT(40) DEF C POS(20);
X is a bit string that consists of 40 elements of C, starting at the 20th element.
INITIAL A66*-9)6'
The NTAL attribute specifies an initial value or values assigned to a variable at the time
storage is allocated for it. Only one initial value can be specified for an element variable;
more than one can be specified for an array variable. A structure variable can be
initialised only by separate initialisation of its elementary names, whether they are
element or array variables.
The NTAL attribute has two forms. the first specifies an initial constant, expression, or
function reference, whose value is assigned to a variable when storage is allocated to it.
The second form specifies that, through the CALL option, a procedure is invoked to
perform initialisation at allocation. The variable is initialised by assignment during the
Udhayas PL/I Material 6/06/2003 Page:- 98 / 161
execution of the called routine (rather than by this routine being invoked as a function that
returns a value to the point of invocation). The syntax for the NTAL attribute
is:
DCL *ariab$e&na#e attrib'te NTAL ( ite#" ite#,.)
Where item is
initia$&constant 2 reference 2 e/pression 2 +iteration factor. iteration&ite#
)here Initia$ constant is one of the fo$$owing
3 or & Arith#etic constant
bit constant
Character constant
entr! constant
fi$e constant
$abe$ constant

For a variable that is allocated when the program is loaded, that is, a static variable,
which remains allocated throughout execution of the program, any value specified in an
NTAL attribute is assigned only once. (Static storage for fetched procedures is
allocated and initialised each time the procedure is loaded).
For automatic variables, which are allocated at each activation of the declaring block, any
specified initial value is assigned with each allocation.
For based and controlled variables, which are allocated at the execution of ALLOCATE
statements (also LOCATE statements for based variables), any specified initial value is
assigned with each allocation. However, this initialisation of controlled variables can be
overridden in the ALLOCATE statement.
nitial values specified for an array are assigned to successive elements of the array in
row-major order (final subscript varying most rapidly). f too many initial values are
specified, the excess values are ignored; if not enough are specified, the remainder of the
array is not initialised.
Only constant values with no operations, for example, 3 or 'ABC', can be specified in the
NTAL attribute for static variables, except that the NULL built-in function can be used
to initialise a static pointer variable.
E(+143'
DCL C CHAR(3) STATC NT (('A'| | 'BC'))
E(+143'
((2) 'A') is equivalent to ('AA')
((2) ('A')) is equivalent to ('A','A')
((2) (1)'A') is equivalent to ('A','A')
Note that first index is string repetition factor ( (3)'B' is 'BBB'). The outer index is
the iteration factor ( (2)(3)'B' is 'BBB','BBB').
E(+143'
n the following example, when storage is allocated for NAME, the character
constant 'JOHN DOE' (padded on the right to 10 characters) is assigned to it:
DCL NAME CHAR(10) NT('JOHN DOE');
n the following example, when P is allocated, it is initialised to the value 3.1416:
Udhayas PL/I Material 6/06/2003 Page:- 99 / 161
DCL P FXED DEC (5,4) NT (3.1416);
The following example specifies that A is to be initialised with the value of the
expression B*C:
DECLARE A NT ((B*C));
The following examples illustrate the use of a function reference to initialise a
variable:
DECLARE X NT(SQRT(Z));
DECLARE TABLE(100,10) NTAL (( 920(0), (20) ((3)5,9));
First 920 elements are set to zero. Thereafter the pattern 5,5,5,9 is repeated
20 times.
E(+143'
DCL TABLE (20,20) NTAL CALL SET_UP(X,Y);
DCL A(15) CHAR(13) NTAL
( 'JOHN DOE', *,
'RCHARD ROW',
'MARY SMTH');/'on*! 1st? 3rd and Et& e*ements inited'/
DCL B(10,10) DECMAL FXED(5) NT ((25)0,25(1),50(0));
DCL 1 C(8),
2 D NT(0), /' on*! first e*ement Jeroed '/
2 E NT((8)0); /' a** R e*ements Jeroed '/
E(+143' /5 7'1/&,6*+6-/& /5 POINTERS
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
%PROCESS ATTRBUTES(FULL),NOT('~');
MYPROG: PROCEDURE OPTONS(MAN);
DCL 1 LNK BASED(P),
2 DATA CHAR(80),
2 NEXT PONTER;
DCL (HEAD,THS) PONTER;
DCL COUNT FXED DEC(3);
DCL BUFFER CHAR(80);
DCL NULL BULTN;
ALLOCATE LNK SET(HEAD);
COUNT=1;
PUT STRNG(BUFFER) EDT(COUNT,'ABCDEFGHJKLMNOPQRS')(F(3),A);
HEAD->DATA=BUFFER;
THS=HEAD;
DO =1 TO 100 BY 1;
ALLOCATE LNK SET(THS->NEXT);
COUNT=COUNT+1;
PUT STRNG(BUFFER) EDT(COUNT,'ABCDEFGHJKLMNOPQRS')(F(3),A);
THS=THS->NEXT;
THS->DATA=BUFFER;
Udhayas PL/I Material 6/06/2003 Page:- 100 / 161
END;
THS->NEXT=NULL;
THS=HEAD;
DO WHLE(THS ~= NULL);
PUT SKP EDT(THS->DATA)(A);
THS=THS->NEXT;
END;
END MYPROG;
/*
//
E(+143' /5 7'1/&,6*+6-/& /5 CONTROLLED +66*-9)6'
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
%PROCESS ATTRBUTES(FULL),NOT('~');
MYPROG: PROCEDURE OPTONS(MAN);
DCL 1 LNK CONTROLLED,
2 DATA CHAR(80);
DCL COUNT FXED BNARY(15);
DCL BUFFER CHAR(80);
DCL NULL BULTN;
DO =1 TO 100 BY 1;
ALLOCATE LNK;
PUT STRNG(BUFFER) EDT(,'ABCDEFGHJKLMNOPQRS')(F(3),A);
LNK.DATA=BUFFER;
COUNT=COUNT+1;
END;
COUNT=ALLOCATON(LNK);
DO =1 TO COUNT BY 1;
PUT SKP EDT(LNK.DATA)(A);
FREE LNK;
END;
END MYPROG;
/*
//
E(+143' /5 7'1/&,6*+6-/& /5 AREA 6<4' 8+*-+93',
//USERAA1 JOB MSGCLASS=A,NOTFY=USERAA
//MYSTEP EXEC PROC=EL1CLG,REGON.PL=1M
//PL.SYSN DD *
%PROCESS ATTRBUTES(FULL),NOT('~');
MYPROG: PROCEDURE OPTONS(MAN);
DCL MYAREA AREA(2000);
DCL NEWMYAREA AREA(20000);
DCL (HEAD,THS) OFFSET(MYAREA);
DCL 1 LNK BASED(P),
2 DATA CHAR(80),
2 NEXT OFFSET(MYAREA);
DCL COUNT FXED DEC(3);
DCL BUFFER CHAR(80);
DCL NULL BULTN;

ON AREA BEGN;
PUT SKP LST('NSUFFCENT STORAGE N AREA...');
STOP;
Udhayas PL/I Material 6/06/2003 Page:- 101 / 161
END;

ALLOCATE LNK SET(HEAD);
COUNT=1;
PUT STRNG(BUFFER) EDT(COUNT,'ABCDEFGHJKLMNOPQRS')(F(3),A);
HEAD->DATA=BUFFER;
THS=HEAD;
DO =1 TO 100 BY 1;
ALLOCATE LNK SET(THS->NEXT);
COUNT=COUNT+1;
PUT STRNG(BUFFER) EDT(COUNT,'ABCDEFGHJKLMNOPQRS')(F(3),A);
THS=THS->NEXT;
THS->DATA=BUFFER;
END;
THS->NEXT=NULL;
THS=HEAD;
DO WHLE(THS ~= NULL);
PUT SKP EDT(THS->DATA)(A);
THS=THS->NEXT;
END;
PUT SKP LST('NOW READNG FROM NEW AREA..');
NEWMYAREA=MYAREA;
THS=HEAD;
DO WHLE(THS ~= NULL);
PUT SKP EDT(PONTER(THS,NEWMYAREA)->DATA)(A);
THS=PONTER(THS,NEWMYAREA)->NEXT;
END;
END MYPROG;
/*
//
Udhayas PL/I Material 6/06/2003 Page:- 102 / 161
SECTION 11 FILE PROCESSING
TYPES OF TRANSMISSION
StreamData formatting facilities, less efficient, conversion to character form before
output or input. Stream implies that the data of the file is a continuos stream of
data items in character form assigned to variables or from expressions to the
stream
RecordNo data formatting facilities, more efficient, image of data in program buffer
written to media. Record mode implies that the file consists of physically separate
records each of which consist of one or more data items in any form
R'./*7 VS S6*'+1 I/O
ST%EAM I/O
(&IST / EDIT / DATA) %ECO%D
,om)arison et7een t&e t7o forms of I/2
n Stream /O conversions take place in the process of reading the data from
Character to coded form or vice versa. No such conversions take place with record /O
n stream /O less than or more than one physical record may be needed to satisfy a
GET or a PUT. n record /O only one record is output or input at a time for a READ or
WRTE statement.
n Stream /O the programmer knows in advance the format of the data (else it is not
possible to specify the data items or format list). n record /O programmer needs to
know only RECSZE / BLKSZE. Data format need not be known.
n record /O data in any form (coded or character) may be stored. n stream form the
data has to be in character form only.
'ET ()!!(t#*
Co+,#t to
Co-#- !.t)/#t.(
0o/
$o(#** (o-#-
!.t)/#t.( 0o/
Co+,#t (o-#-
!.t)/#t.( 0o/
to ()!!(t# 0o/
$1t ()!!(t#*
%EAD
$o(#** D!t! .+
%#(o- 0o/
A+2
(o+,#*.o+*
)!,# to 3#
-o+# 32 t)#
4o"!//#
W.t#
Udhayas PL/I Material 6/06/2003 Page:- 103 / 161
Record mode /O may be used with any type of data set(QSAM, VSAM KSDS, VSAM
RRDS, VSAM ESDS). Stream /O can be used only on sequential data sets.
TYPES OF DATA SETS SUPPORTED BY PL/I
T<4' /5 7+6+ ,'6 PL/I /*0+&-H+6-/&
Sequential CONSECUTVE
ndexed sequential NDEXED
Direct REGONAL
KSDS,ESDS,RRDS VSAM
FILE INPUT / OUTPUT
0&e Process PL/I statement
Define the File DECLARE fi*ename FLE .
Open the File OPEN FLE(fi*ename);
Process the File READ/WRTE/REWRTE for access by record
GET/PUT for stream access
Close the File CLOSE FLE(fi*ename)
A file used within a PL/ program has a PL/ file name. f you have the following file
declaration in your program:
DCL STOC# FILE STREAM INPUT;
Create a DD statement with a data definition name (DDNAME)

//GO.STOC# DD DSNIPARTS.INSTOC#, . . .
Ensure that the DDNAME of the DD statement that defines the data set is the same as
either the declared PL/ file name, or the character-string value of the expression
specified in the TITLE option of the associated OPEN statement. f the file name is
longer than 8 characters, the default DDNAME is composed of the first 8 characters of
the file name.
OPEN FILE ?DETAILA TITLE?JDETAILIKAF
Corresponding 4CL is
//DETAILI DD DSNAMEIDETAILA, . . .
File Variables are different from file constants as they can be the target of an assignment
statement
DCL PRCES FLE VARABLE, /' PRI,+S is a fi*e -aria*e '/
RPRCE FLE; /' RPRI,+ is a fi*e constant '/
PRCES = RPRCE;
OPEN FLE (PRCES);
The DD statement should associate the data set with the file constant RPRCE, which is
the value of the file variable PRCES, thus:
//RPRCE DD DSNAME= . . .
Use of a file variable also allows you to manipulate a number files at various times by a
single statement. For example:
Udhayas PL/I Material 6/06/2003 Page:- 104 / 161
DECLARE F FLE VARABLE,
A FLE,
B FLE,
C FLE,
.
.
.
DO F=A, B, C;
READ FLE (F). . . ;
.
.
.
ENDF
FILE ATTRIBUTE OF A DATA ITEM
Main attriutes are
GROUP ALTERNATIVES DEFAULT
Usage STREAM | RECORD STREAM
Function NPUT | OUTPUT | UPDATE NPUT
Access SEQUENTAL | DRECT DRECT
Buffering BUFFERED | UNBUFFERED BUFFERED
Scope EXTERNAL | NTERNAL EXTERNAL
/otes on (ttriutes
RECORD Associated verbs OPEN, CLOSE, READ, WRTE,
REWRTE. DELETE
STREAM Associated verbs OPEN, CLOSE, GET, PUT
NPUT nput only
OUTPUT Output only
UPDATE Valid only for RECORD mode. Transmission in either
direction
SEQUENTAL Valid in RECORD MODE only. Records accessed in
physical sequence
DRECT Valid in RECORD MODE only. Records accessed in any
order by KEY. mplies KEYED attribute.
[UN]BUFFERED Record files only. BUFFERED is default for
SEQUENTAL
ENVRONMENT VSAM | REGONAL(1|2|3) | NDEXED |
CONSECUTVE F | FB | V | VB, BLKSZE(N), RECSZE
(N),KEYLENGTH(N)
KEYED Only RECORD files. t means records can be
accessed using one of KEY, KEYTO, KEYFROM of
data transmission statements
In)ut / 2ut)ut Vers
OPEN FLE (fi$e&reference) [STREAM | RECORD] [NPUT | OUTPUT |
UPDATE] [DRECT | SEQUENTAL] [ BUFFERED | UNBUFFERED] [KEYED]
Udhayas PL/I Material 6/06/2003 Page:- 105 / 161
[PRNT] [TTLE (e/pression)] [LNESZE(e/pression)]
[PAGESZ3E(e/pression)]... /'Bot& forms of I/2'/
GET FILE?5-3'"*'5'*'&.'ALLL. /:S6*'+1 I/O:/
PUT FILE?5-3'"*'5'*'&.'ALLL. /:S6*'+1 I/O:/
READ FILE?5-3'"*'5'*'&.'ALL.. /:R'./*7 I/O:/
%RITE FILE?5-3'"*'5'*'&.'ALL /:R'./*7 I/O:/
RE%RITE FILE?5-3'"*'5'*'&.'AL. /:R'./*7 I/O:/
DELETE FILE?5-3'"*'5'*'&.'ALL /:R'./*7 I/O:/
CLOSEFILE ?fi*e-referenceALL /:B/62 5/*1, I/O:/
Udhayas PL/I Material 6/06/2003 Page:- 106 / 161
SECTION 11"A STREAM ORIENTED DATA TRANSMISSION
Data sets with the STREAM attribute are processed by stream-oriented data
transmission, which allows your PL/ program to ignore block and record boundaries and
treat a data set as a continuous stream of data values in character form.
For output, PL/ converts the data items from program variables into character form if
necessary, and builds the stream of characters into records for transmission to the data
set.
For input, PL/ takes records from the data set and separates them into the data items
requested by your program, converting them into the appropriate form for assignment to
program variables.
.efining 1i*es using Stream I/2
DCL filename FLE STREAM
NPUT | {OUTPUT [PRNT]}
ENVRONMENT (options);
options
CONSECUTVE
F | FB | FS | FBS | V |VB | U
RECSZE (record-length)
BLKSZE (block-size)
BUFFERS(n)
.efau*t .efinitions created ! t&e PL/I com)i*er
DCL SYSPRINT FILE STREAM OUTPUT PRINT ENV?V BL#SICE?129AAF
(120 characters of data, 1 ASA character , 4 bytes Block size, 4 Bytes Record size)
DCL SYSIN FILE STREAM INPUT ENV ?F BL#SICE?!0AAF
n your JCL include the following statements to use SYSPRNT and SYSN
//SYSPRINT DD SYSOUTIA
//SYSIN DD :
L
L
/:
Use the GET and PUT verbs for the /O within your program
Sa*ient )oints of Stream I/2
The /O is in a continuos stream and record boundaries are not reflected to the user
program, although they exist at the Physical level.
The /O is in character mode. For example coded arithmetic data is converted to
character (display) mode both ways(From arithmetic mode to character mode on
output and from character mode to coded mode on input).
On input the data items must be in character mode and either BLANK or COMMA
must be used as a separator.
Udhayas PL/I Material 6/06/2003 Page:- 107 / 161
n PUT LST for printer output the data is output in predetermined tab positions
spaced at 21 positions between tabs.
List Directed data Transmission
Data Directed Data Transmission
Edit Directed Data Transmission
Vers
OPEN .. /' see )re-ious section '/
CLOSE. /' see )re-ious section '/
GET FLE(file-reference) data-specification [COPY (SYSPRNT | file-ref)]
[SKP (expression)]
PUT FLE(file-reference) data-specification [PAGE] [LNE(expression)]
[SKP(expression)]
PUT STRNG(char-reference) data-specification /' SPRI/01 of , '/
.ata S)ecifications
LST (data-item, data-item,..)
DATA (data-item, data-item,..)
EDT (data-item, data-item,.) (format-item, format-item,.)
/otes
COPY Specifies that source data stream is written without alteration on the
specified data set
GET FLE(SYSN) DATA(A,B,C) COPY(DPL);
SKP Specifies a new current line (or record ) in the data set;
PUT LST (X,Y,Z) SKP(3);
outputs on SYSPRNT after skipping three lines
PAGE Only for PRNT files. Starts a new page.
LNE Only for PRNT files. Changes line counter value.

E(+143'
DCL NVEN FLE NPUT STREAM ENV(o)tions);
ENV options are BLKSZE, RECSZE etc. Note that this can be omitted if it is
specified in the JCL
Note that Filename is the DD name in the run JCL for this program.
NPUT or OUTPUT attribute can be specified with OPEN statement also. This can be
useful when the same file is opened / closed / opened / closed in one run first with one
mode and then with another.
Default is NPUT unless the file has the PRNT attribute in which case it defaults to
OUTPUT.
E(+143'
DCL NVEN FLE STREAM NPUT ENV(F BLKSZE(80));
Udhayas PL/I Material 6/06/2003 Page:- 108 / 161
Print (ttriute
Use this for printer output.
This will enable options on PUT like PAGE, SKP( ), LNE( ) etc.
This attribute can be used only when STREAM and OUTPUT are other attributes.
This attribute causes first byte of each record of the data set to be reserved for
carriage control character
DCL PRNTR FLE OUTPUT STREAM ENV(F BLKSZE(61));
Note record size is size of print line plus one position
DCL PRNTR FLE OUTPUT STREAM PRNT ENV(F BLKSZE(133));
DCL PRNTBUF CHAR(132);
PUT FLE(PRNTR) LST(PRNTBUF);
Without print attribute the following statements are used
DCL PRNTR FLE OUTPUT STREAM ENV(F BLKSZE(132));
DCL AREA CHAR(130);
PUT FLE(PRNTR) LST(AREA);
Without PRNT attribute PUT encases character strings in quotes. For the quotes two
positions are needed (hence AREA is only 130 chars wide). Also note that the BLKSZE
is only 132 as we do not need a carriage control character.
DCL FXED BNARY(15);
=LNENO(PRNTR) /'returns -a*ue of t&e LI/+/2 counter maintained ! PL/I '/
Stream Files are automatically opened with first GET or PUT.
PAGESZE and LNESZE for PRNT files should be specified only in OPEN statement.
OPEN FLE(PRNTR) PAGESZE(50) LNESZE(120);
Default output is to SYSPRNT with default line size of 120.Override this by
OPEN FLE(SYSPRNT) LNESZE(133);
The TTLE attribute in the OPEN statement is used to specify the DD name
OPEN FLE(DATAN) TTLE(FLEA); /' 1IL+( is t&e .. name'/
Note that FLE attributes can be specified in the JCL, DCL and OPEN statements. They
are merged at OPEN time.
The CLOSE FLE(DATAN); statement is used to close the file. Program end also
automatically closes all files
+dit .irected I/2
Edit Directed /O overcomes some of the limitations of LST directed /O like need for
spaces or commas to separate data (wastage of space) or printing at predetermined
tab positions for printer output.
Edit /O like Stream /O deals only in character data.
Consider the following Data which is intended to be read with LST directed /O
GET LST(EMPNUM,EMPNAME);
Employee Employee
Udhayas PL/I Material 6/06/2003 Page:- 109 / 161
Number Name
12345678,SRNVASKAMATH
Note the comma separating the two data items
For EDT directed /O
GET FLE(fi*ename) EDT(data*ist) (format*ist);
GET EDT(EMPNUM,EMPNAME) (COLUMN(1),F(8),A(15));
Employee Employee
Number Name
12345678SRNVAS KAMATH
Note the absence of blank or comma to separate the two data items
Format identifiers are
A(n) n Alphameric characters
F(m,n) Fixed point with the precision of m,n
X(n) Skip n positions
COLUMN(n) Data starts from column n
Note that in the event of insufficient format identifiers the set of identifiers provided are
used again starting with the first format identifier
GET EDT(A,B,C) (F(4),F(5));
A -> F(4)
B -> F(5)
C -> F(4)
Excess format identifiers are ignored.
The /O continues across record boundaries until all the identifiers have been
read or written
A B
DCL A CHAR(70);
DCL B CHAR(40); Record boundary
GET EDT (A,B) (A(70),A(40));
A B
DCL A CHAR(70);
DCL B CHAR(40); Record boundary
GET EDT (A,B) (COLUMN(1),A(70),COLUMN(1),A(40));
Alternately,
DCL A CHAR(70);
DCL B CHAR(40);
GET EDT (A,B) (A(70),X(10),A(40));
E(+143'@
To read first forty positions of each record
1 70 71 80 1 50
1 70 1 60
Udhayas PL/I Material 6/06/2003 Page:- 110 / 161
DCL FELD_1 CHAR(40);
DO =1 to 10;
GET EDT(FELD_1) (COLUMN(1),A(40));
END;
Data items may be Data aggregates
E(+143'@
DCL TABLE(100) FLOAT DEC(6);
GET EDT(TABLE) (COLUMN(1),F(6,2));
/' note t&at 188 records 7i** e read to satisf! t&is read '/
DCL TABLE(100) FLOAT DEC(6);
GET EDT((TABLE(K) DO K=1 TO 50)) (COLUMN(1),F(6,2));
/' note t&at :8 records 7i** e read to satisf! t&is read '/
DCL TABLE(100) FLOAT DEC(6);
GET EDT(TABLE) (50 F(3),50 F(4));
/' different data formats for eac& of t&e :8 e*ements '/
DCL A CHAR(70);
GET EDT (SUBSTR(A,50,20)) (A(20));
/' read into *ast 28 )ositions of ( '/
PUT EDT ('MY NAME') (A(7));
PUT EDT(A*3,B+C/D) (F(10), F(8,2));
More than one EDT list and FORMAT list may be specified
GET EDT(data *ist) (format *ist) (data *ist) (format *ist) (data *ist) (format *ist)
E(+143'@
PUT EDT (A,B,C) (F(12),F(15,3),A(5))
(D,E,F) (B(10),F(5,2),COLUMN(60),A(7));
/O can be to a string in memory rather than to a FLE
PUT STRNG (FELD_1) EDT (A,B,C) (A(20),A(10),F(3));
GET STRNG (FELD_1) EDT (A,B,C) (A(20),A(10),F(3));
This option can be used to effect CHAR to coded arithmetic or vice versa conversion.
%*-6-&0 ='+7-&0,
PUT EDT('THS S A HEADNG STARTNG N COLUMN 32')
(PAGE,COLUMN(32),A); /'t&e com)i*er ca*cu*ates 7idt& of ('/
PUT EDT(MM,'/',DD,'/',YY) (A,A,A,A,A);
PUT EDT(MM,'/',DD,'/',YY) (5 A);
PUT EDT('EMPLOYEE NO. NAME') (SKP(2),A)
('RATE HOURS DEDUCTON NET PAY') (COL(40),A);
PUT EDT (A,B,C,D,E,F) (PAGE,3(F(5),F(3,1)));
/' format is eAui-a*ent to =1=:)?1=3?1)? 1=:)?1=3?1)? 1=:)?1=3?1))'/
1ormat Identifiers
A(w) Character field of width w
A Character field of width determined by the data item it represents
Udhayas PL/I Material 6/06/2003 Page:- 111 / 161
B(w) Bit field of width w
B Bit field of width determined by the data item it represents
E(w,d) Floating point notation (e.g. 60E+12). W is the total width of the character
representation including decimal point (if any) signs and the designation
E. For example 156.35E+05 , E(10,2), w is 10. The number of significant
digits is d+1 where d digits are the fractional portion. The above value
therefore is output as bb1.56E+07
F(w) Field contains w characters containing a fixed point decimal value.
123 F(3) 123
-123 F(3) SZE error
-123 F(4) -123
123 F(5) bb123
F(w,d) Width of character field is w and d positions are to right of decimal
point.
123.45 F(4,0) b123
123.45 F(6,2) 123.45
123.45 F(7,3) 123.450
123.45 F(6,1) b123.5
123.45 F(5,2) SZE error
123.65 F(4,0) b124
X(w) Skip w characters in input or output
P Picture format characters $ + - Z 9 v / , . B.
Used to edit numeric data in fixed decimal point format.
COLUMN(n) Start from Column n
LNE(n) Skip to line n
PAGE Skip to new page (output only)
SKP On input continue with next record
On output SKP(n) where n=0 suppress line feed, n=1 print on next line,
n = expression where n-1 lines are skipped.
.ata .irected In)ut
Each item in the input is in the form of an assignment statement that specifies both value
and the identity of the variable to which it is to be assigned.
E(+143'@
The input stream could contain
A=12.13,B=570,C='SED',D='1011'B;
GET DATA(A,B,C,D);
GET DATA(B,D,A,C); /' 7ou*d 7or6 Qust as 7e** '/
GET DATA(A,B,C,D,E); /' not an error# + is su)erf*uous and is ignored '/
Udhayas PL/I Material 6/06/2003 Page:- 112 / 161
GET DATA(A,C,D); /'+RR2R@# Identifier in in)ut stream ut not in +0'/
/' t&is raises t&e /(M+ condition 7&ic& can e &and*ed '/
/' ! an 2/ /(M+=S4SI/) '/
GET DATA; /' a** items in stream u) to t&e semico*on are in)ut# %o7e-er
t&e data names must &a-e een defined )rior to t&is )oint '/
The COUNT(filename) returns the data items input during last GET
DCL NFLE FLE NPUT STREAM;
GET FLE(NFLE) DATA;
=COUNT(NFLE);

.ata .irected 2ut)ut
DCL A FXED DEC(5) NT(0);
DCL B FXED DEC(5) NT(0);
DCL C FXED DEC(5) NT(175);
PUT DATA (A,B,C);
Outputs -> A=0 B=0 C=175;
Note that A is in TAB position 1
B is in TAB position 25
C is in TAB position 49
Stream 1i*e ,onditions
ENDFLE End of File has been reached
ENDPAGE On printed output end of a page of output has been completed
TRANSMT nput or Output device did not transmit correctly
RECORD Size of record in the media does not match that declared in the
PL/ program.
SZE Number of significant digits in the coded arithmetic item exceeds
the size declared for the identifier.
nput -> -123
GET EDT (VALUE) (F(3));
CONVERSON The data has embedded characters which are illegal for type of
data item declared
Input
GET EDT(VALUE) (COLUMN(1),F(5));
E(+143' /5 ,6*'+1 I/O
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL FIELD CAR(!") INIT(#ELLO $ORLD#);
PUT LIST (FIELD);
GET LIST (FIELD);
PUT S%IP LIST(FIELD);
PUT S%IP EDIT(FIELD,FIELD) (A(&),X(1),A(1));
END MYPROG;
/*
//GO.SYSIN DD *
#SRINI'AS %AMAT#
1 5
57 98
Udhayas PL/I Material 6/06/2003 Page:- 113 / 161
/*
//
E(+143' /5 ,6*'+1 I/O
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL FIELD1 FIXED DECIMAL((,!);
DCL FIELD! FIXED DECIMAL((,!);
DCL SUM FIXED DECIMAL((,!);
GET LIST (FIELD1,FIELD!);
SUM=FIELD1)FIELD!;
PUT S%IP LIST(SUM);
END MYPROG;
/*
//GO.SYSIN DD *
1!*.+ ,-(.&
/*
//
E(+143' /5 ,6*'+1 I/O
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL FIELD1 FIXED DECIMAL((,!);
DCL FIELD! FIXED DECIMAL((,!);
DCL SUM FIXED DECIMAL((,!);
GET DATA (FIELD1,FIELD!);
SUM=FIELD1)FIELD!;
PUT S%IP LIST(SUM);
END MYPROG;
/*
//GO.SYSIN DD *
FIELD1=1.!* FIELD!=*.+,;
/*
//
More on PRI/0 1i*es and Stream I/2
The operating system allows you to use the first byte of each record for a print control
character. The control characters, which are not printed, cause the printer to skip to a
new line or page. n a PL/ program, with stream /O, the use of a PRNT attribute for a
file provides a convenient means of controlling the layout of printed output from stream-
oriented data transmission. The compiler automatically inserts print control characters in
response to the PAGE, SKP, and LNE options and format items.
You can apply the PRNT attribute to any STREAM OUTPUT file, even if you do not
intend to print the associated data set directly.
,&aracter (ction
Blank Space 1 line before printing
0 Space 2 lines before printing
- Space 3 lines before printing
+ No space before printing
Udhayas PL/I Material 6/06/2003 Page:- 114 / 161
1 Start new page
,ontro**ing Printed Line *engt&
You can limit the length of the printed line produced by a PRNT file either by specifying a
record length in your PL/ program (ENVRONMENT attribute) or in a DD statement, or
by giving a line size in an OPEN statement (LNESZE option). The record length must
include the extra byte for the print control character, that is, it must be 1 byte larger than
the length of the printed line (9 bytes larger for V-format records).The value you specify in
the LNESZE option refers to the number of characters in the printed line; the compiler
adds the print control character.
2-erriding t&e 0a ,ontro* 0a*e
Data-directed and list-directed output to a PRNTFLE are aligned on preset tabulator
positions. The definitions of the fields in the table are as follows.
OFFSET OF TAB COUNT:
Half word binary integer that gives the offset of "Tab count, the field that indicates the
number of tabs to be used.
PAGESZE:
Half word binary integer that defines the default page size. This page size is used for
dump output to the PLDUMP data set as well as for stream output.
LNESZE:
Half word binary integer that defines the default line size.
PAGELENGTH7
Half word binary integer that defines the default page length for printing at a terminal. For
TSO and VM, the value 0 indicates unformatted output8
FI&&E%S7
Three Half word binary integers; reserved for future use.
TAB COUNT7
Half word binary integer that defines the number of tab position entries in the table
(maximum 255), f TAB COUNT=0, any specified tab positions are ignored.
TAB1-TABN:
n half-word binary integers that define the tab positions within the print line. The first
position is numbered 1, and the highest position is numbered 255 The value of each tab
should be greater than that of the tab preceding it in the table; otherwise, it is ignored.
The first data field in the printed output begins at the next available tab position.
You can override the default PL/ tab settings for your program by causing the linkage
editor to resolve an external reference to PLTABS. To cause the reference to be
resolved, supply a table with the name PLTABS, in the format described above. Note
that TAB1 identifies the position of the second item printed on a line; the first item on a
line always starts at the left margin.
DCL 1 PLITABS STATIC EXT,
! ( OFFSET INIT(1+),
PAGESI.E INIT (-"),
LINESI.E INIT (1!"),
PAGELENGT INIT ("),
FILL1 INIT ("),
FILL! INIT ("),
Udhayas PL/I Material 6/06/2003 Page:- 115 / 161
FILL* INIT ("),
NO_OF_TABS INIT (3),
TAB1 INIT (30),
TAB2 INIT(60),
TAB3 INIT(90)) FIXED BIN (1,, ");
E(+143' /5 .2+&0-&0 TAB ,'66-&0,, ./&8'*,-/&,
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL A CAR(-) INIT(#1!*.+,#);
DCL B FIXED DECIMAL(,,!);
DCL C FIXED BINARY(1,);
DCL (D,E) DECIMAL FLOAT(-);
DCL F CAR(-) INIT(#1"#);
DCL 1 PLITABS STATIC EXTERNAL,
! (OFFSET INIT(1+),
PAGESI.E INIT(-"),
LINESI.E INIT(1!"),
PAGELENGT INIT("),
FILL1 INIT("),
FILL! INIT("),
FILL* INIT("),
N"/OF/TABS INIT(*),
TAB1 INIT(1,),
TAB! INIT(*"),
TAB- INIT(+,)) FIXED BIN(1,,");
B=A;C=A;
PUT S%IP LIST(A,B,C);
A=#0!*+.,-#;
B=A;C=A;
PUT S%IP LIST(A,B,C);
D=1.!*+,-E)*;E=1.++E0*;
PUT S%IP LIST(D,E,(D)E));
B=A/F;
PUT S%IP LIST(A,F,B);
END MYPROG;
/*
//
E(+143' /5 .*'+6-&0 + 4*-&6 5-3' V-+ S6*'+1 D+6+ T*+&,1-,,-/&
1PROCESS NOT(#2#);
CARDPRNT: PROC OPTIONS (MAIN);
DCL TABLE FILE STREAM OUTPUT PRINT;
DCL PGNO FIXED DEC(!) INIT(1);
DCL ONCODE BUILTIN;
DCL EOF BIT(1) INIT(#"#B);
DCL CARD CAR(&");
ON ENDFILE(SYSIN) EOF INIT(#1#B);
ON ERROR BEGIN;
ON ERROR SYSTEM;
PUT LIST (#ONCODE = #33 ONCODE);
END;
ON ENDPAGE (TABLE)BEGIN;
PUT FILE (TABLE) PAGE
EDIT (4CARD TO PRINT PGNO= 5,PGNO) (A,F(!));
Udhayas PL/I Material 6/06/2003 Page:- 116 / 161
PGNO = PGNO )1;
END;
OPEN FILE (TABLE) PAGESIZE(52) LINESIZE (80)
SIGNAL ENDPAGE(TABLE);
GET LIST(CARD);
DO $ILE 2EOF;
PUT FILE (TABLE) EDIT(CARD)(A);
GET LIST(CARD);
END;
END CARDPRNT;
Udhayas PL/I Material 6/06/2003 Page:- 117 / 161
SECTION 11"B RECORD I/O
Define Files (DASD, TAPE or CARD)
Declare /O Areas
Use READ and WRTE (instead of GET and PUT)
DCL 5-3'"./&,6+&6 FILE L..+66*-9)6',LL
Vers for Record 2riented .ata 0ransmission on*!
READ FLE(file-reference) [NTO(reference) [ KEY(expression) | KEYTO(reference) ]]
READ FLE(file-reference)
[SET(pointer-reference) [KEY(expression) | KEYTO(reference) ] ]
WRTE FLE (file-reference) FROM(reference)
[KEYFROM(expression) | KEYTO(reference) ]]
DELETE FLE(file-reference) [KEY(expression)]
N/6',
NTO Specifies Data area in form of element or aggregate variable into which
the logical record is read.
FROM Specifies the element or aggregate from which the record is written.
SET Specifies a pointer variable that is set to point to the location in the buffer
into which the record has been moved during the READ operation
KEY Specifies character key that identifies a record for a NDEXED,
REGONAL, VSAM KSDS data set. Can appear only if the FLE has
DRECT attribute or NDEXED or VSAM and KEYED attribute. Can be
used in a R+(. statement for I/P30 or 3P.(0+ fi*e or in a
R+IRI0+ for a .IR+,0 3P.(0+ fi*e.
E(+143'
READ FLE (STOCK) NTO (TEM ) KEY (STKEY );
KEYFROM Specifies a character key that identifies the record in the data set. Can
be used in a IRI0+ statement for S+L3+/0I(L out)ut, or .IR+,0
230P30 or .IR+,0 3P.(0+ in a R+GI2/(L 1IL+. Can also be used
in IRI0+ statement 7it& $+4+. S+L3+/0I(L 3P.(0+ VS(M data
set#
For REGONAL (2) and (3) data sets KEYFROM specifies a recorded
key whose length is specified by the KEYLEN sub-parameter or
KEYLENGTH option.
E(+143'
WRTE FLE(LOANS) FROM (LOANREC) KEYFROM(LOANNO);
KEYTO Specifies the character variable to which the key of a record is assigned.
Variables with PC and STRNG cannot be used. Applies only to KEYED
files of NDEXED, VSAM or REGONAL organisation.
For REGONAL(1) 8 character region number padded or truncated on
left (if required) is moved to the KEYTO field
For REGONAL(2) or (3) the recorded key without the region number
(padded or truncated on left if required) is moved
Udhayas PL/I Material 6/06/2003 Page:- 118 / 161
For VSAM KSDS the recorded key padded or truncated on right (if
required) is moved
For ESDS a 4 character RBA padded or truncated on right (if required
is moved)
For VSAM RRDS a 8 character relative record number padded or
truncated on the left is moved
E(+143'@
DCL INFILE FILE INPUT RECORD EN'(F RECSI.E(&"));
DCL OUTFILE FILE OUTPUT RECORD EN'(F RECSI.E(&"));
DCL DATA/AREA CAR(&");
!" #$%&'() RECORD *+)*,-.$/ *. */ ($,'() I!O "!
OPEN FILE(INFILE),FILE(OUTFILE);
.
READ FILE(INFILE) INTO (DATA/AREA);
$RITE FILE(OUTFILE) FROM(DATA/AREA);
.
.
CLOSE FILE(INFILE),FILE(OUTFILE);
C+**-+0' C/&6*/3 -& RECORD I/O
Append a carriage control character at start of the Record
CC C/7' A.6-/&
blank Space one line before printing
0 Space two lines before printing
- Space three lines before printing
+ Suppress space before printing
1 Skip to channel 1 before printing
2 Skip to channel 2 before printing
.
.
9 Skip to channel 9 before printing
A Skip to channel 10 before printing
.
C Skip to channel 12 before printing
To indicate to PL/ that ASA (American Standards Association) characters are being used
on printer output add the keyword CTLASA / CTL360 to the ENV options of the file
declaration. However note that with CTLASA the carriage movement takes place before
printing. With CTL360 it occurs after the printing.
E(+143'@
DCL DATA_AREA CHAR(80);
DCL PRNT_AREA CHAR(81);
DCL PRNTR FLE OUTPUT RECORD ENV(F RECSZE(81) CTLASA );
PRNT_AREA = '1' || DATA_AREA; /' (S( c&aracter is no7 919 '/
WRTE FLE(OUTFLE) FROM(PRNT_AREA);
,onsecuti-e .ata Sets
Used for both STREAM as well as RECORD oriented /O
Records written in order of presentation (sequentially)
Records can be fetched sequentially only.
Udhayas PL/I Material 6/06/2003 Page:- 119 / 161
Stream oriented o)eration on consecuti-e data sets
Use LST or EDT or DATA directed /O for stream operation
DCL FLE STREAM NPUT|OUTPUT [PRNT] ENVRONMENT(o)tions);
/' 0&is &as een co-ered e5tensi-e*! in an ear*ier section '/
Environment options are
F | FB | V | VB | U
RECSZE(record-length)
BLKSZE(block-size)
T<4' /5 *'./*7 /*0+&-H+6-/& ,)44/*6'7
F Fixed-length, unblocked
FB Fixed-length, blocked
V Variable-length, unblocked
VB Variable-length, blocked
VS Variable-length, unblocked, spanned
VBS Variable-length, blocked, spanned
n a sequential (or CONSECUTVE) data set, records are placed in physical sequence.
An indexed sequential (or NDEXED) data set must reside on a direct-access volume. An
index or set of indexes maintained by the operating system gives the location of certain
principal records. This allows direct retrieval, replacement, addition, and deletion of
records, as well as sequential processing.
A direct (or REGONAL) data set must reside on a direct-access volume. The records
within the data set can be organised in three ways: REGONAL(1), REGONAL(2), and
REGONAL(3); in each case, the data set is divided into regions, each of which contains
one or more records. A key that specifies the region number and, for REGONAL(2) and
REGONAL(3), identify the record, allows direct-access to any record; sequential
processing is also possible.
An example of a typical FLE declaration for a VSAM KSDS is
DCL FLENAME FLE RECORD SEQUENTAL KEYED NPUT
ENV ( VSAM);
+/VIR2/M+/0 o)tion .,B su-)arameter
F | FB | V | VB .. RECFM=F | FB |..
RECSZE LRECL
BLKSZE BLKSZE
CTLASA | CTL360
KEYLENGTH KEYLEN
Udhayas PL/I Material 6/06/2003 Page:- 120 / 161
GEN#EY :
The GENKEY (generic key) option applies only to NDEXED and VSAM key-sequenced
data sets. t enables you to classify keys recorded in a data set and to use a
SEQUENTAL KEYED NPUT or SEQUENTAL KEYED UPDATE file to access records
according to their key classes.
A generic key is a character string that identifies a class of keys; all keys that begin with
the string are members of that class. For example, the recorded keys "ABCD, "ABCE,
and "ABDF are all members of the classes identified by the generic keys "A and "AB,
and the first two are also members of the class "ABC; and the three recorded keys can
be considered to be unique members of the classes "ABCD, "ABCE, and "ABCF,
respectively.
DCL ND FLE RECORD SEQUENTAL KEYED UPDATE
ENV (VSAM GENKEY);
.
.
.
READ FLE(ND) NTO(NFELD) KEY ('ABC');
.
.
.
NEXT: READ FLE (ND) NTO (NFELD);
.
.
.
GO TO NEXT;
#EYLENGT= O46-/&:
Use the KEYLENGTH option to specify the length of the recorded key for KEYED files
where n is the length. You can specify KEYLENGTH for NDEXED or REGONAL(3) files.
f you include the KEYLENGTH option in a VSAM file declaration for checking purposes,
and the key length you specify in the option conflicts with the value defined for the data
set, the UNDEFNEDFLE condition is raised.
DEFINING AND USING CONSECUTIVE DATA SETS
n a data set with consecutive organisation, records are organised solely on the basis of
their successive physical positions; when the data set is created, records are written
consecutively in the order in which they are presented. You can retrieve the records only
in the order in which they were written, or, for RECORD \O only, also in the reverse
order when using the BACKWARDS attribute.
.efining 1i*es 3sing Record I/2
DCL filename FLE RECORD
NPUT | OUTPUT | UPDATE
SEQUENTAL
BUFFERED | UNBUFFERED
ENVRONMENT (options);
Some important ENVRONMENT options applicable to consecutive data sets are:
F | FB | V | VB |...
RECSZE (record-length)
BLKSZE (block-size)
CONSECUTVE | VSAM | RELATVE(n)
Udhayas PL/I Material 6/06/2003 Page:- 121 / 161
CTLASA | CTL360
E>AMPLE OF PRINTING RECORD ORIENTED DATA TRANSMISSION
PRT: PROC OPTIONS(MAIN);
DCL TABLE FILE RECORD INPUT SE6UENTIAL;
DCL PRINTER FILE RECORD OUTPUT SE6L EN'(' BL%SI.E(&7) CTLASA);
DCL LINE CAR(&1) 'AR;
DCL CTLCAR CAR(1) DEFINED LINE;
DCL DATA CAR(&") DEFINED LINE POS(!);
DCL TABLE/EOF BIT(1)INIT(4"5B); !"$'0 01-2 0'( .-31$ "!
DCL TRUE BIT(1) INIT(415B); !" ,'+/.-+. .(4$ "!
DCL FALSE BIT(1) INIT(4"5B); !" ,'+/.-+. 0-1/$ "!
ON ENDFILE(TABLE) TABLE/EOF = TRUE;
OPEN FILE(TABLE), FILE(PRINTER);
READ FILE(TABLE) INTO(DATA); /" 5(*6*+2 ($-) "!
CTLCAR = 415; !" ASA C7AR "!
DO $ILE (TABLE/EOF = FALSE);
$RITE FILE(PRINTER) FROM(LINE);
READ FILE(TABLE) INTO(DATA);
END;
CLOSE FILE(TABLE), FILE(PRINTER);
END PRT;
Udhayas PL/I Material 6/06/2003 Page:- 122 / 161
SECTION 11"C DEFINING AND USING VSAM DATA SETS
Before you execute a program that accesses a VSAM data set, you need to know:
The name of the VSAM data set
The name of the PL/ file
Whether you intend to share the data set with other users
Then you can write the required DD statement to access the data set:
//5-3'&+1' DD DSNAMEI7,&+1',DISPIOLD M S=R
For example, if your file is named PL1FLE, your data set named VSAMDS, and you want
exclusive control of the data set, enter:
// PL1FILE DD DSNAMEIVSAMDS, DISPIOLD
To share your data set, use DSP=SHR.
PL/l provides support for three types of VSAM data sets:
Key-sequenced data sets (KSDS)
Entry-sequenced data sets (ESDS)
Relative record data sets (RRDS).
These correspond roughly to PL/l indexed, consecutive, and regional data set
organisations, respectively. They are all ordered, and they can all have keys associated
with their records. Both sequential and keyed access are possible with all three types.
Although only key-sequenced data set have keys as part of their logical records, keyed
access is also possible for entry-sequenced data sets (using relative-byte addresses) and
relative record data sets (using relative record numbers).
All VSAM data sets are held on direct-access storage devices, and a virtual storage
operating system is required to use them. VSAM does not use the concept of blocking,
records need not be of a fixed length. The data items are arranged in control intervals, in
control areas. A control interval can contain one or more logical records, VSAM data sets
can have two types of indexes-prime and alternate. You can have one or more alternate
indexes on a KSDS or an ESDS.
Any change in a data set that has alternate indexes must be reflected in all the indexes if
they are to remain useful. This activity is known as index upgrade, and is done by VSAM
for any index in index upgrade set of the data set.
Before using a VSAM data set for the first time, you need to define it to the system with
the DEFNE command of Access Method Services, the operation of writing the initial data
into a newly create VSAM data set is referred to as loading.
Use the three different types of data sets according to the following purposes:
Use entry-sequenced data sets for data that you primarily access in the order in which
it was created (or the reverse order).
Udhayas PL/I Material 6/06/2003 Page:- 123 / 161
Use key-sequenced data sets when you normally access records through keys
within the records (for example, a stock-control file where the part number is used
to access a record).
Use relative record data sets for data in which each item has a particular number.
you can access records in all types of VSAM data sets either directly by means of a key,
or sequentially (backward or forward). You can also use a combination of the two ways:
Select a starting point with a key and then read forward or backward from that point.
$e!s for Inde5ed VS(M .ata Sets
Keys for key-sequenced data sets and for entry-sequenced data sets accessed via an
alternate index are part of the logical records recorded on the data set. You define the
length and location of the keys when you create the data set. You can reference the keys
in the KEY, KEYFROM, and KEYTO options
Re*ati-e B!te (ddresses =RB()
Relative byte addresses allow you to use keyed access on an ESDS associated with a
KEY SEQUENTAL file. The RBA, or keys, are character strings of length 4, and their
values are defined by VSAM. You cannot construct or manipulate RBA in PL/l; obtain the
RBA for a record by using the KEYTO option, on a WRTE or on a READ statement.
Subsequently use an RBA in the KEY option of a READ or REWRTE statement.
Re*ati-e Record /umers
Records in an RRDS are identified by a relative record number that starts at 1 and is
incremented by 1 for each succeeding record. Keys used as relative record numbers are
character strings of length 8. Source key you use in the KEY or KEYFROM option must
represent an unsigned integer. f not 8 characters truncated or padded with blanks
(interpreted as Zeros) on the left.
You define a direct VSAM data set by using a file declaration with the following attributes:
DCL filename FLE RECORD
NPUT | OUTPUT | UPDATE
DRECT
[KEYED]
ENVRONMENT (options);
Some of the ENVRONMENT options applicable to VSAM data sets are:
BUFND (n)
BUFN (n)
GENKEY
PASSWORD (password - specification)
VSAM
.efining VS(M data Sets
Use the DEFNE CLUSTER command of Access Method Services to define and
catalogue VSAM data sets. To use the DEFNE command, you need to know:
The name and password of the master catalogue if the master catalogue is password
protected
The name and password of the VSAM private catalogue you are using if you are not
using the master catalogue
Whether VSAM space for your data set is available
Udhayas PL/I Material 6/06/2003 Page:- 124 / 161
The type of VSAM data set you are going to create
The volume on which your data set us to be placed
The average and maximum record size in your data set
The position and length of the key for an indexed data set
The space to be allocated for your data set
How to code the DEFNE command
How to use the Access Method Services program.
When you have the information, you are in a position to code the DEFNE command and
then define and catalogue the data set using Access Method Services.
E>AMPLE OF DEFINING AND LOADING A VSAM ESDS
E>AMPLE OF DEFINING A VSAM ESDS CLUSTER
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//STEP1 EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER 0
(NAME(USERAA.'SAM.ESDS.PLI)0
'OLUMES(TSO""1)0
NONINDEXED 0
RECORDSI.E(&" &")0
TRAC%S(1 1))
/*
//
E>AMPLE OF LOADING A VSAM ESDS
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL FAMFILE FILE SE6UENTIAL OUTPUT EN'('SAM);
DCL IN FILE RECORD INPUT;
DCL STRING CAR(&");
DCL NOTEOF BIT(1) INIT(#1#B);
ON ENDFILE(IN) NOTEOF=#"#B;
READ FILE(IN) INTO(STRING);
DO I=1 BY 1 $ILE(NOTEOF);
PUT FILE(SYSPRINT) S%IP EDIT(STRING)(A);
$RITE FILE(FAMFILE) FROM(STRING);
READ FILE(IN) INTO(STRING);
END;
PUT S%IP EDIT(I01,#RECORDS PROCESSED#)(F(*),A);
END MYPROG;
/*
//GO.FAMFILE DD DSN=USERAA.'SAM.ESDS.PLI,DISP=OLD
//GO.IN DD *
AAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBB
/*
//STEP! EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
PRINT INDATASET(USERAA.'SAM.ESDS.PLI) CAR
Udhayas PL/I Material 6/06/2003 Page:- 125 / 161
/*
//
E>AMPLE OF DUMPING A ESDS
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL FAMFILE FILE SE6UENTIAL INPUT EN'('SAM);
DCL BADFILE FILE SE6UENTIAL INPUT EN'('SAM);
DCL STRING CAR(&");
DCL NOTEOF BIT(1) INIT(#1#B);
ON ENDFILE(FAMFILE) NOTEOF=#"#B;
ON UNDEFINEDFILE(BADFILE) PUT S%IP LIST(# BADFILE NOT
OPENED#);
OPEN FILE(BADFILE);
READ FILE(FAMFILE) INTO(STRING);
DO I=1 BY 1 $ILE(NOTEOF);
PUT S%IP EDIT(#RECORD NO.#,I,STRING)(A,F(*),X(!),A);
READ FILE(FAMFILE) INTO(STRING);
END;
CLOSE FILE(FAMFILE);
END MYPROG;
/*
//GO.FAMFILE DD DSN=USERAA.'SAM.ESDS.PLI,DISP=OLD
//
L/+7-&0 + #SDS /* I&7'('7 ESDS
Open the file for KEYED SEQUENTAL OUTPUT and present the records in
ascending key order, use the KEYFROM option.
f the KSDS already contains some records, and you open the associated file with the
SEQUENTAL and OUTPUT attributes, you can only add records at the end of the
data set.
KEYED SEQUENTAL OUTPUT file is used with a WRTE FROM KEYFROM
statement. The data must be presented in ascending key order.
E>AMPLE OF DEFINING A #SDS USING IDCAMS
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//STEP1 EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER 0
(NAME(USERAA.'SAM.%SDS.PLI)0
'OLUMES(TSO""1)0
INDEXED 0
%EYS(!" ") 0
RECORDSI.E(!* &")0
TRAC%S(* 1))
/*
//
E(+143' /5 3/+7-&0 + VSAM #SDS ,'D)'&6-+33<
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
Udhayas PL/I Material 6/06/2003 Page:- 126 / 161
DCL DIREC FILE RECORD SE6UENTIAL OUTPUT %EYED EN'('SAM);
DCL CARD CAR(&");
DCL NAME CAR(!") DEF CARD POS(1);
DCL NUMBER CAR(*) DEF CARD POS(!1);
DCL OUTREC CAR(!*) DEF CARD POS(1);
DCL NOTEOF BIT(1) INIT(#1#B);
ON ENDFILE(SYSIN) NOTEOF=#"#B;
ON 8E9(DIREC) BEGIN
PUT S8IP EDIT(:DUPLICATE 8E9 IN T7IS INPUT;:,CARD)(A)
END
OPEN FILE(DIREC) OUTPUT
GET FILE(SYSIN) EDIT(CARD)(A(&"));
DO $ILE(NOTEOF);
<RITE FILE(DIREC) FROM(OUTREC) 8E9FROM(NAME)
GET FILE(SYSIN) EDIT(CARD)(A(&"));
END;
CLOSE FILE(DIREC)
END MYPROG;
/*
//GO.DIREC DD DSN=USERAA.'SAM.%SDS.PLI,DISP=OLD
//GO.SYSIN DD *
ACTION,G. 1-!
BA%ER,R. 1,!
BRAMLEY,O.. !+&
/*
//STEP! EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
PRINT INDATASET(USERAA.'SAM.%SDS.PLI) CAR
/*
//
E(+143' /5 *'+7-&0 + VSAM #SDS -& 7-*'.6 1/7'
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
1PROCESS ATTRIBUTES(FULL);
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL DIREC FILE RECORD DIRECT INPUT 8E9ED EN=(=SAM)
DCL CARD CAR(&");
DCL NAME CAR(!") DEF CARD POS(1);
DCL NUMBER CAR(*) DEF CARD POS(!1);
DCL INREC CAR(!*);
DCL NOTEOF BIT(1) INIT(#1#B);
DCL GOOD8E9FLAG BIT(1) INIT(:1:B)
ON ENDFILE(SYSIN) NOTEOF=#"#B;
ON 8E9(DIREC) BEGIN
PUT S8IP EDIT(:IN=ALID 8E9 IN INPUT RECORD>:,CARD)(A)
GOOD8E9FLAG>:0:B
END
OPEN FILE(DIREC)
GET FILE(SYSIN) EDIT(CARD)(A(&"));
DO $ILE(NOTEOF);
READ FILE(DIREC) INTO(INREC) 8E9(NAME);
IF GOOD%EYFLAG TEN PUT S%IP
EDIT(#RECORD IS= #,INREC)(A);
GOOD%EYFLAG=#1#B;
Udhayas PL/I Material 6/06/2003 Page:- 127 / 161
GET FILE(SYSIN) EDIT(CARD)(A(&"));
END;
CLOSE FILE(DIREC)
END MYPROG;
/*
//GO.DIREC DD DSN=USERAA.'SAM.%SDS.PLI,DISP=OLD
//GO.SYSIN DD *
ACTION,G. 1-!
BA%ER,R. 1,!
%AMAT,M.S 777
BRAMLEY,O.. !+&
/*
//
U,-&0 + D-*'.6 F-3' 6/ A..',, + #SDS /* I&7'('7 ESDS
You can open a Direct file that is used to access an indexed VSAM data set with the
NPUT, or OUTPUT attribute.
f you use a DRECT NPUT or DRECT UPDATE file, you can read , write, rewrite, or
delete records in the same way as for as a KEYED SEQUENTAL file.
E>AMPLE OF UPDATING A VSAM #SDS DYNAMICALLY
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
1PROCESS ATTRIBUTES(FULL),NOT(#2#);
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL DIREC FILE RECORD 8E9ED EN=(=SAM)
DCL ONCODE BUILTIN;
DCL OUTREC CAR(!*);
DCL NAME CAR(!") DEF OUTREC POS(1);
DCL NUMBER CAR(*) DEF OUTREC POS(!1);
DCL CODE CAR(1);
DCL EOF BIT(1) INIT(#"#B);
ON ENDFILE(SYSIN) EOF=#1#B;
ON 8E9(DIREC) BEGIN
IF ONCODE>51 T7EN PUT FILE(S9SPRINT) S8IP EDIT
(:NOT FOUND; :,NAME)(A(15),A)
IF ONCODE>52 T7EN PUT FILE(S9SPRINT) S8IP EDIT
(:DUPLICATE; :,NAME)(A(15),A)
END
OPEN FILE(DIREC) DIRECT UPDATE;
GET FILE(SYSIN) EDIT(NAME,NUMBER,CODE)
(COLUMN(1),A(!"),A(*),A(1));
DO $ILE(2EOF);
PUT FILE(SYSPRINT) S%IP
EDIT(# #,NAME,#8#,NUMBER,# #,CODE)
(A(1),A(!"),A(1),A(*),A(1),A(1));
SELECT (CODE)
<7EN (:A:) <RITE FILE(DIREC)
FROM(OUTREC) 8E9FROM(NAME)
<7EN (:C:) RE<RITE FILE(DIREC)
FROM(OUTREC) 8E9(NAME)
<7EN (:D:) DELETE FILE(DIREC) 8E9(NAME)
OTER$ISE PUT FILE(SYSPRINT) S%IP EDIT
(#IN'ALID CODE: #,NAME)(A(1,),A);
END
Udhayas PL/I Material 6/06/2003 Page:- 128 / 161
GET FILE(SYSIN) EDIT(NAME,NUMBER,CODE)
(COLUMN(1),A(!"),A(*),A(1));
END;
CLOSE FILE(DIREC)
PUT FILE(SYSPRINT) PAGE;
OPEN FILE(DIREC) SE?UENTIAL INPUT; !" DUMP T7E FILE "!
EOF=#"#B;
ON ENDFILE(DIREC) EOF=#1#B;
READ FILE(DIREC) INTO(OUTREC);
DO $ILE(2EOF);
PUT FILE(SYSPRINT) S%IP EDIT(OUTREC)(A);
READ FILE(DIREC) INTO(OUTREC);
END;
CLOSE FILE(DIREC)
END MYPROG;
/*
//GO.DIREC DD DSN=USERAA.'SAM.%SDS.PLI,DISP=OLD
//GO.SYSIN DD *
%AMAT,M.S ,"1A
ACTION,G. 1-!D
/*
//
Codes used above are
A Add a new record
C Change the number of an existing name
D Delete a record
VS(M R+L(0IV+ R+,2R. .(0( S+0S
%2'& +& RRDS -, 9'-&0 3/+7'7, you must open the associated file for OUTPUT. Use
either a DRECT or a SEQUENTAL file.
F/* + DIRECT OUTPUT 5-3', each record is placed in the position specified by the
relative record number (or key) in the KEYFORM option of the WRTE statement.
F/* + SEGUENTIAL OUTPUT file, use WRTE statements with or without the KEYFROM
option. f you specify the KEYFROM option, the record is placed in the specified slot; if
you omit it, the record is placed in the slot following the current position.
E>AMPLE OF DEFINING A VSAM RRDS USING IDCAMS
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//STEP1 EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER 0
(NAME(USERAA.'SAM.RRDS.PLI)0
'OLUMES(TSO""1)0
NUMBERED 0
RECORDSI.E(!" !")0
TRAC%S(! !))
/*
//
E>AMPLE OF LOADING A VSAM RRDS SEGUENTIALLY
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
Udhayas PL/I Material 6/06/2003 Page:- 129 / 161
//PLI.SYSIN DD *
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL NOS FILE RECORD OUTPUT DIRECT 8E9ED EN=(=SAM)
DCL CARD CAR(&");
DCL NAME CAR(!") DEF CARD POS(1);
DCL NUMBER CAR(!) DEF CARD POS(!1);
DCL IOFIELD CAR(!");
DCL NOTEOF BIT(1) INIT(#1#B);
ON ENDFILE(SYSIN) NOTEOF=#"#B;
OPEN FILE(NOS) OUTPUT
GET FILE(SYSIN) EDIT(CARD)(A(&"));
DO $ILE(NOTEOF);
PUT FILE(SYSPRINT) S%IP EDIT(CARD)(A);
IOFIELD=NAME;
<RITE FILE(NOS) FROM(IOFIELD) 8E9FROM(NUMBER)
GET FILE(SYSIN) EDIT(CARD)(A(&"));
END;
PUT S%IP LIST(#END OF INPUT0000#);
CLOSE FILE(NOS)
END MYPROG;
/*
//GO.NOS DD DSN=USERAA.'SAM.RRDS.PLI,DISP=OLD
//GO.SYSIN DD *
ACTION,G. 1!
BA%ER,R. 1*
BRAMLEY,O.. !&
/*
//STEP! EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
PRINT INDATASET(USERAA.'SAM.RRDS.PLI) CAR
/*
//
E>AMPLE OF ACCESSING A VSAM RRDS RANDOMLY
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
1PROCESS NOT(#2#);
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL NOS FILE RECORD INPUT DIRECT 8E9ED EN=(=SAM);
DCL ONCODE BUILTIN;
DCL CARD CAR(&");
DCL NAME CAR(!") DEF CARD POS(1);
DCL NUMBER CAR(!) DEF CARD POS(!1);
DCL IOFIELD CAR(!");
DCL NOTEOF BIT(1) INIT(#1#B);
DCL BAD%EY BIT(1);
ON ENDFILE(SYSIN) NOTEOF=#"#B;
OPEN FILE(NOS)
ON 8E9(NOS) BEGIN
PUT S8IP EDIT(:IN=ALID 8E9; :,NUMBER)(A,A)
PUT EDIT(: ONCODE IS; :,ONCODE)(A,F(@))
BAD8E9>:1:B
END
GET FILE(SYSIN) EDIT(CARD)(A(&"));
DO $ILE(NOTEOF);
Udhayas PL/I Material 6/06/2003 Page:- 130 / 161
BAD%EY=#"#B;
READ FILE(NOS) INTO(IOFIELD) 8E9(NUMBER)
IF 2BAD%EY TEN PUT FILE(SYSPRINT)
S%IP EDIT(IOFIELD)(A);
GET FILE(SYSIN) EDIT(CARD)(A(&"));
END;
PUT S%IP LIST(#END OF INPUT0000#);
CLOSE FILE(NOS)
END MYPROG;
/*
//GO.NOS DD DSN=USERAA.'SAM.RRDS.PLI,DISP=OLD
//GO.SYSIN DD *
ACTION,G. 1!
BA%ER,R. 1*
BRAMLEY,O.. !&
%AMAT,M.S. 77
/*
//STEP! EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
PRINT INDATASET(USERAA.'SAM.RRDS.PLI) CAR
/*
//
VS(M (L0+R/(0+ I/.+B+S
Pairing an (*ternate Inde5 Pat& 7it& a 1i*e
When using an alternate index, you simply specify the name of the path in the DSNAME
parameter if the DD statement associating the base data set/alternate index pair with
your PL/l file.
Given a PL/l file called PL1FLE and the alternate index path called PERSALPH, the DD
statement required would be:
//PL1FILE DD DSNAMEIPERSALP=, DISPIOLD
(*ternate Inde5es for $S.S or Inde5ed +S.Ss
Three Access Method Services commands are used as below:
DEFNE ALTERNATENDEX
defines the alternate index as a data set to VSAM.
BLDNDEX
places the pointers to the relevant records in the alternate index.
DEFNE PATH
defines an entity that can be associated with a PL/ file in a DD
statement.
E>AMPLE OF DEFINING A ALTERNATE INDE> FOR A VSAM #SDS FILE
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//STEP1 EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE ALTERNATEINDEX 0
(NAME(USERAA.'SAM.%SDS.ALTINDX.PLI)0
'OLUMES(TSO""1)0
UNI6UE%EY 0
%EYS(* !") 0
RECORDSI.E(!+ +&)0
Udhayas PL/I Material 6/06/2003 Page:- 131 / 161
TRAC%S(+ +)0
RELATE(USERAA.'SAM.%SDS.PLI))
/*
//
EXAMPLE OF THE ALTERNATE INDEX AND DEFINING THE PATH
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//STEP1 EXEC PGM=IDCAMS,REGION=,1!%
//SYSPRINT DD SYSOUT=*
//DD1 DD DSN=USERAA.'SAM.%SDS.PLI,DISP=OLD
//DD! DD DSN=USERAA.'SAM.%SDS.ALTINDX.PLI,DISP=OLD
//SYSIN DD *
BLDINDEX INFILE(DD1) OUTFILE(DD!)
DEFINE PAT0
(NAME(USERAA.'SAM.%SDS.PAT.PLI)0
PATENTRY(USERAA.'SAM.%SDS.ALTINDX.PLI))
/*
//
E>AMPLE OF ACCESSING T=E #SDS FILE SEGUENTIALLY
T=ROUG= T=E ALTERNATE INDE>

//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
1PROCESS ATTRIBUTES(FULL);
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL DIREC FILE RECORD SE?UENTIAL INPUT EN=(=SAM)
DCL INREC CAR(!*);
DCL NOTEOF BIT(1) INIT(#1#B);
OPEN FILE(DIREC)
ON ENDFILE(DIREC) NOTEOF=#"#B;
DO $ILE(NOTEOF);
READ FILE(DIREC) INTO(INREC)
IF NOTEOF TEN PUT S%IP EDIT(#RECORD IS= #,INREC)(A);
END;
CLOSE FILE(DIREC)
END MYPROG;
/*
!!GOADIREC DD DSN>USERAAA=SAMA8SDSAPAT7APLI,DISP>OLD
//
E>AMPLE OF ACCESSING T=E #SDS FILE DYNAMICALLY
T=ROUG= T=E ALTERNATE INDE>
//USERAA1 JOB MSGCLASS=A,NOTIFY=USERAA
//MYSTEP EXEC PROC=IEL1CLG,REGION.PLI=1M
//PLI.SYSIN DD *
1PROCESS ATTRIBUTES(FULL);
MYPROG: PROCEDURE OPTIONS(MAIN);
DCL DIREC FILE RECORD DIRECT INPUT 8E9ED EN=(=SAM)
DCL ONCODE BUILTIN;
DCL CARD CAR(&");
DCL NAME CAR(!") DEF CARD POS(1);
DCL NUMBER CAR(*) DEF CARD POS(!1);
DCL INREC CAR(!*);
Udhayas PL/I Material 6/06/2003 Page:- 132 / 161
DCL NOTEOF BIT(1) INIT(#1#B);
DCL GOOD%EYFLAG BIT(1) INIT(#1#B);
ON ENDFILE(SYSIN) NOTEOF=#"#B;
ON 8E9(DIREC) BEGIN
PUT S8IP EDIT(:IN=ALID 8E9 IN INPUT RECORD>:,CARD)(A)
PUT S8IP EDIT(:ONCODE IS>:,ONCODE)(A,F(8))
GOOD8E9FLAG>:0:B
END
OPEN FILE(DIREC)
GET FILE(SYSIN) EDIT(CARD)(A(&"));
DO $ILE(NOTEOF);
READ FILE(DIREC) INTO(INREC) 8E9(NUMBER)
IF GOOD%EYFLAG TEN PUT S%IP
EDIT(#RECORD IS= #,INREC)(A);
GOOD%EYFLAG=#1#B;
GET FILE(SYSIN) EDIT(CARD)(A(&"));
END;
CLOSE FILE(DIREC)
END MYPROG;
/*
!!GOADIREC DD DSN>USERAAA=SAMA8SDSAPAT7APLI,DISP>OLD
//GO.SYSIN DD *
ACTION,G. 1-!
BA%ER,R. 1,!
%AMAT,M.S 777
BRAMLEY,O.. !+&
/*
//
Udhayas PL/I Material 6/06/2003 Page:- 133 / 161
PL/I A&7 M)36-6+,B-&0
A PL/ program is a set of one or more procedures.
When the multitasking facilities are not used, the execution of a program comprising one or more
procedures constitutes a single task, with a single flow of control.
This execution with a single flow of control is called synchronous.
When multitasking, the invoking procedure does not relinquish control to the invoked procedure.
nstead, an additional flow of control is established so that both procedures run concurrently.
This process is known as attaching a task. The attached task is a subtask of the attaching task.
Any task can attach one or more subtasks. The task that has control at the outset is called the
major task. The execution of such concurrent procedures is called asynchronous.
The execution of these procedures constitutes one or more tasks, each associated with a
different task-variable.
The task-reference used to associate a task variable with a task is used to identify the task. For
example, after

CA&& IN$UT TAS9(A2);
When several procedures are executed asynchronously, it might be necessary for the system to
select its next action from a number of different tasks eligible for execution(not waiting for some
resource or event completion). f more than one such task is found, the task the having highest
priority is despatched. You can allow the system to allocate priorities or you can assign priorities
to your tasks when they are attached.
Provision has been made for one task to await the completion of another task before proceeding.
This process is known as task synchronization. nformation about the state of an operation can
be held by an event-variable. Execution of a WAT statement causes the task to wait for
completion of the operation associated with the event-variable. You can set the value of the
event-variable explicitly, or you can apply the EVENT option to tasks and certain input/output
operations, in which case the value of the event-variable is set as a result of the operation.
n general, the rules associated with the synchronous invocation of procedures apply equally to
the asynchronous attachment of tasks. For example, ON-units established prior to attachment of
a subtask are inherited by the subtask. However, asynchronous operation introduces some extra
considerations, such as the fact that a number of concurrent tasks can independently refer to one
variable.
T+,B D+6+ +&7 A66*-9)6'
You can use task variables to control the relative priorities of tasks. A variable is given the TASK
attribute by its appearance in a TASK option, or by explicit declaration.
A task-variable contains a priority value. This value is a real fixed-point binary value of precision
(15,0). This value can be tested by the PRORTY built-in function and modified by the
pseudovariable. The priority value of the task-variable is undefined unless it is set by one of the
following:

Assignment to the PRORTY pseudovariable
PRORTY option of the CALL statement that creates the task
Udhayas PL/I Material 6/06/2003 Page:- 134 / 161
C*'+6-/& /5 T+,B,
You specify the creation of an individual task by using one or more of the multitasking options of a
CALL statement. After the CALL statement activates a procedure, all synchronously activated
blocks become part of the created task and all attached tasks become subtasks of the created
task. The created task itself is a subtask of the task executing the CALL statement. All
programmer-created tasks are subtasks of the major task.

You must specify the REENTRANT option for procedures that are attached as more than one
task to be executed concurrently. When REENTRANT is specified, the compiler generates code
that is reenterable as far as machine instructions and compiler-created storage are concerned.
However, you must ensure that the logic of your PL/ source code keeps the procedure
reenterable. n particular, you must not overwrite static storage.
CALL S6+6'1'&6
The CALL statement for asynchronous operation has the same syntax as that for synchronous
operation, with the addition of one or more of the multitasking options: TASK, EVENT, or
PRORTY. These options all specify that the invocation of the procedure is a task.
TAS# O46-/&
You can use the task-variable to control the priority of the task. f you do not specify a task-
reference, an unnamed task-variable is allocated and used. The syntax for the TASK option is:

TAS% 9(:;<=0>?@?>?AB?)C
EVENT O46-/&
The event-variable is associated with the completion of the task created by the CALL statement.
Another task can then wait for completion of this task by specifying the event-variable in a WAT
statement of the other task. The syntax for the EVENT option is:

E'ENT (?D?A:0>?@?>?AB?)
When the CALL statement is run, the completion value of the event-variable is set to '0'B (for
incomplete) and the status value to zero (for normal status). The sequence of these two assignments
is uninterruptible, and is completed before control passes to the named entry point.

On termination of the created task, the completion value is set to '1'B. n the case of abnormal
termination, the status value is set to 1 (if it is still zero). The sequence of the two assignments to the
event-variable values is uninterruptible.
PRIORITY O46-/&
When a number of tasks simultaneously require service, the operating system selects tasks based on
their relative priority. A task that has a higher priority value than the others generally receives service
first. Tasks, other than those executing the user's program and those in a wait state, can require
service from the system and can have a higher priority than any of the user's tasks. The syntax for
the PRORTY option is:

PRIORITY (?EF>?<<GHA)
expression s evaluated to a real fixed-point binary value, m, of precision (15,0). The priority of the
created task is then made m relative to the task executing the CALL statement.

f the PRORTY option does not appear, the priority of the attached task is equated to that of the
task-variable referenced in the TASK option, if any, or equated to the priority of the attaching task.
E(+143',
18 CA&& $%OCA TAS9(T1);
Udhayas PL/I Material 6/06/2003 Page:- 135 / 161
28 CA&& $%OCA TAS9(T2) E:ENT(ET2);
58 CA&& $%OCA TAS9(T5) E:ENT(ET5) $%IO%IT;(<2);
68 CA&& $%OCA $%IO%IT;(1);
P*-/*-6< /5 T+,B,
The PRORTY pseudovariable provides a method of setting the priority of a task relative to the
current task. The effect of the statement:

PRORTY(T)=N;
The priority of task T is set to the priority of this task + N. Similarly PRORTY(T) returns the priority
relative to the value of the parent task.
Priorities can be changed after the subtask is running.
C//*7-&+6-/& +&7 S<&.2*/&-H+6-/& /5 T+,B,
The rules for scope of names apply to blocks in the same way whether or not they are invoked as, or
by, subtasks. Thus, data and files can be shared between asynchronously executing tasks. As a
result, a high degree of cooperation is possible between tasks, but this necessitates some
coordination. Additional rules are introduced to deal with sharing of data and files between tasks, and
the WAT statement is provided to allow task synchronization.

An example of task synchronization is:

P1: PROCEDURE;
CALL P! E'ENT(EP!);
CALL P* E'ENT(EP*);
$AIT (EP!);
$AIT (EP*);
END P1;
S2+*-&0 D+6+ B'6;''& T+,B,
Normal rules of scoping apply, but it is your responsibility to ensure that two references to the same
variable cannot be in effect at one time if either reference changes the value of the variable. You can
do so by including an appropriate WAT statement at a suitable point in your source program to force
synchronization of the tasks involved.
S2+*-&0 F-3', B'6;''& T+,B,
A file is shared between a task and its subtask if the file is open at the time the subtask is attached. f
a subtask shares a file with its attaching task, the subtask must not attempt to close the file. A
subtask must not access a shared file while its attaching task is closing the file.

f a file is known to a task and its subtask, and the file was not open when the subtask was attached,
the file is not shared.
T',6-&0 +&7 S'66-&0 E8'&6 V+*-+93',
The COMPLETON built-in function returns the current completion value of the event-reference. This
value is '0'B if the event is incomplete, or '1'B if the event is complete.

The STATUS built-in function returns the current status of the event-reference. This value is nonzero
if the event-variable is abnormal, or zero if it is normal.

Udhayas PL/I Material 6/06/2003 Page:- 136 / 161
The COMPLETON and STATUS pseudovariables can be used to set the two values of an event-
variable. Alternatively, it is possible to assign the values of one event-variable to another in an
assignment statement. By these means, you can mark the stages of a task; and, by using a WAT
statement in one task and using the COMPLETON pseudovariable or an event assignment in
another task, you can synchronize any stage of one task with any stage of another.

You should not attempt to assign a completion value to an event-variable currently associated with an
active task or with an input/output event.
T'*1-&+6-/& /5 T+,B,
A task terminates when one of the following occurs:

Control for the task reaches a RETURN or END statement for the initial procedure of the task.
Control for the task reaches an EXT statement.
Control for the task, or for any other task, reaches a STOP statement.

The block in which the task was attached terminates (either normally or abnormally).
The attaching task itself terminates.
mplicit action for the ERROR condition or the action on normal return from an ERROR ON-unit is
carried out.

Termination is normal only if the first item of the above list applies. n all other cases, termination is
abnormal.

To avoid unintentional abnormal termination of a subtask, an attaching task should always wait for
completion of the subtask in the same block that attached the subtask, before the task itself is
allowed to terminate.

When a task is terminated, the following actions are performed:

1. All input/output events that were initiated in the task and are not yet complete are set complete,
and their status values (if still zero) are set to 1. The results of the input/output operations are not
defined.
2. All files that were opened during the task and are still open are closed. All input/output conditions
are disabled while this action is takes place.
3. All allocations of controlled variables made by the task are freed.
4. All allocations of based variables made by the task are freed, except those it has allocated within
an area allocated by another task (these are freed when the area is freed).
5. All active blocks (including all active subtasks) in the task are terminated.
6. f the EVENT option was specified when the task was attached, the completion value of the
associated event-variable is set to '1'B. f the status value is still zero and termination is
abnormal, the status value is set to 1.
7. All records locked by the task are unlocked.
Udhayas PL/I Material 6/06/2003 Page:- 137 / 161
E>IT S6+6'1'&6
The EXT statement immediately terminates the task that contains the statement and all tasks
attached by this task.

f executed in a major task, EXT raises the FNSH condition in that task. On normal return from the
FNSH ON-unit, the task executing the statement and all of its descendant tasks are terminated.
Thus, EXT executed in a major task is equivalent to a STOP statement. The syntax for the EXT
statement is: EXT;
The completion values of the event variables associated with these tasks are set to '1'B, and their
status values to 1 (unless they are already nonzero).
$CL
IEL1C3
//IEL1CL PROC LNGPRFX=#IEL.'1R1M1#,LIBPRFX=#CEE#,
.
.
//L%ED EXEC PGM=IE$L,PARM=#XREF,LIST#,COND=(7,LT,PLI),REGION=,1!%
//SYSLIB DD DSN=&LIBPRFX..SIBMTASK,DISP=SHR
// DD DSN=ILIBPRFX..SCEEL%ED,DISP=SR
.
.
$CL 5/* OS/PL/I
For a PL/ program, the DD statement SYSLB will normally define the PL/ Library. The subroutines
of the PL/ Library that are needed at link-edit time are stored in three data sets, SYS1.PLBASE (the
base library), SYS1.PLTASK (the multitasking library), and SYS1.SBMBASE (the Common library).
The base library contains all the PL/ Library subroutines required by a nonmultitasking program. The
multitasking library contains subroutines that are peculiar to multitasking, together with multitasking
variants of some of the base library subroutines, and the Common Library subroutines that are
common to PL/ Version 2 Release 2 and C/370.

For link-editing a non-multitasking program, specify only the base library in the SYSLB DD
statement. The following DD statement will usually suffice:

//SYSLIB DD DSN=SYS1.PLIBASE,DISP=SR
// DD DSN=SYS1.SIBMBASE,DISP=SR

For link-editing a multitasking program, specify both the multitasking library and the base library.
When attempting to resolve an external reference, the linkage editor will first search the multitasking
library. f it cannot find the required subroutine, it will then search the base library. To ensure that the
search is carried out in the correct sequence, the DD statements defining the two sections of the
library must be in the correct sequence: multitasking library first, base library second. The following
DD statements will usually suffice:

//SYSLIB DD DSNAME=SYS1.PLITAS%,DISP=SR
// DD DSNAME=SYS1.PLIBASE,DISP=SR
// DD DSNAME=SYS1.SIBMBASE,DISP=SR
S+143'1
MAIN: PROC OPTIONS(MAIN REENTRANT);
DCL (TA1,TX1) TAS%;
DCL (E'1,EX1) E'ENT;
DCL (E1,E!) E'ENT;
COMPLETION(E1)=#1#B;
COMPLETION(E!)=#"#B;
Udhayas PL/I Material 6/06/2003 Page:- 138 / 161
CALL TA TAS%(TA1) E'ENT(E'1);
CALL TX TAS%(TX1) E'ENT(EX1);
$AIT(E'1);$AIT(EX1);
PUT S%IP LIST(#EXITING MAIN#);
TA: PROC;
DO I=1 TO !"";
$AIT(E1);
PUT S%IP LIST(#IN TAS% TA#);
COMPLETION(E1)=#"#B;
COMPLETION(E!)=#1#B;
END;
END;
TX: PROC;
DO J=1 TO !"";
$AIT(E!);
PUT S%IP LIST(#IN TAS% TX#);
COMPLETION(E!)=#"#B;
COMPLETION(E1)=#1#B;
END;
END;
END;
Udhayas PL/I Material 6/06/2003 Page:- 139 / 161
S+143' 2
MAIN: PROC OPTIONS(MAIN REENTRANT);
DCL (TA1,TX1) TAS%;
DCL (E'1,EX1) E'ENT;
DCL (E1,E!) E'ENT STATIC EXTERNAL;
DCL (TA,TX) ENTRY;
COMPLETION(E1)=#1#B;
COMPLETION(E!)=#"#B;
CALL TA TAS%(TA1) E'ENT(E'1);
CALL TX TAS%(TX1) E'ENT(EX1);
$AIT(E'1);$AIT(EX1);
PUT S%IP LIST(#EXITING MAIN#);
END MAIN;
*PROCESS;
TX: PROC;
DCL (E1,E!) E'ENT STATIC EXTERNAL;
DO J=1 TO !"";
$AIT(E!);
PUT S%IP LIST(#IN TAS% TX#);
COMPLETION(E!)=#"#B;
COMPLETION(E1)=#1#B;
END;
END TX;
*PROCESS;
TA: PROC;
DCL (E1,E!) E'ENT STATIC EXTERNAL;
DO I=1 TO !"";
$AIT(E1);
PUT S%IP LIST(#IN TAS% TA#);
COMPLETION(E1)=#"#B;
COMPLETION(E!)=#1#B;
END;
END TA;
Udhayas PL/I Material 6/06/2003 Page:- 140 / 161
P*'4*/.',,/* F+.-3-6-',
The compiler provides a macroprocessor for source program alteration. t is executed prior to
compilation, when you specify the MACRO compile-time option. The preprocessor scans the
preprocessor input and generates preprocessor output. The preprocessor output can serve as
input to the compiler.
Preprocessor statements, except those in preprocessor procedures, begin with a percent symbol
(%). Using a blank to separate the percent symbol from the rest of the statement is optional.

The preprocessor executes preprocessor statements and alters the input text accordingly.
Preprocessor statements can cause alteration of the input text in any of the following ways:

< Any identifier (and an optional argument list) appearing in the input text can be changed to
an arbitrary string of text.
< You can indicate which portions of the input text to copy into the preprocessor output.
< A string of characters residing in a library can be included in the preprocessor input.
Preprocessor Statements: Preprocessor statements are executed when encountered. You can:

Define preprocessor names using the %DECLARE statement.

f a preprocessor variable is not explicitly declared, it is an error and is diagnosed and the variable
given the default attribute of CHARACTER. However, the variable is not activated for
replacement unless it appears in a subsequently executed %ACTVATE statement. The variable
can be referenced in preprocessor statements.

1. Activate an identifier using the %DECLARE or %ACTVATE statement.
2. Deactivate an identifier using the %DEACTVATE statement, thus terminating replacement
activity.
3. Generate a message in the compiler listing using the %NOTE statement.
4. nclude string of characters into the preprocessor input.
5. Cause the preprocessor to continue the scan at a different point in the preprocessor input
using the %GOTO, %F, %null, %DO, or %END statement.
6. Change values of preprocessor variables using the %assignment or %DO statement.

7. Define preprocessor procedures using the %PROCEDURE, %RETURN, and %END
statements. A preprocessor procedure can be invoked by a function reference in a
preprocessor expression, or, if the function procedure name is active, by encountering a
function reference in the preprocessor scan of input text.

nput Text: The input text, after replacement of any active identifiers by new values, is copied into
the preprocessor output.

A.6-8' I7'&6-5-'*,. For an identifier to be replaced by a new value, the identifier must be first
activated for replacement. nitially, an identifier can be activated by its appearance in a
%DECLARE statement. t can be deactivated by executing a %DEACTVATE statement, and it
can be reactivated by executing a %ACTVATE or %DECLARE statement.

Udhayas PL/I Material 6/06/2003 Page:- 141 / 161
An identifier that matches the name of an active preprocessor variable is replaced in the
preprocessor output by the value of the variable.

When an identifier matches the name of an active preprocessor function (either programmer-
written or built-in) the procedure is invoked and the invocation is replaced by the returned value.

dentifiers can be activated with either the RESCAN or the NORESCAN options. f the
NORESCAN option applies, the value is immediately inserted into the preprocessor output. f the
RESCAN option applies, a rescan is made during which the value is tested to determine whether
it, or any part of it, should be replaced by another value. f it cannot be replaced, it is inserted into
the preprocessor output; if it can be replaced, replacement activity continues until no further
replacements can be made. Thus, insertion of a value into the preprocessor output takes place
only after all possible replacements have been made.

The scan terminates when an attempt is made to scan beyond the last character in the
preprocessor input. The preprocessor output is then complete and compilation can begin.
Preprocessor data types are coded arithmetic and string data, and are either:
FXED DECMAL (5,0):- A preprocessor variable declared with the FXED attribute is given the
attributes DECMAL and precision (5,0). Fixed decimal constants must be integers.

CHARACTER varying:- A preprocessor variable declared with the CHARACTER attribute is given
the varying attribute. String repetition factors are not allowed for character constants.
BT There are no preprocessor bit variables. However, bit constants are allowed
P*'4*/.',,/* P*/.'7)*',
Preprocessor procedures are function procedures. A preprocessor procedure is delimited by
%PROCEDURE and %END statements, and contains at least one RETURN statement.

The statements and groups that can be used within a preprocessor procedure are:

1. The preprocessor assignment statement.
2. The preprocessor DECLARE statement.
3. The preprocessor do-group.
4. The preprocessor GO TO statement. (A GO TO statement appearing in a preprocessor
procedure cannot transfer control to a point outside of that procedure.)
5. The preprocessor F statement.
6. The preprocessor null statement.
7. The preprocessor RETURN statement.
8. The preprocessor NOTE statement.
9. The %PAGE, %SKP, %PRNT, and %NOPRNT listing control statements.

10. Preprocessor statements in a preprocessor procedure do not begin with a percent symbol.
11. Preprocessor procedures cannot be nested. A preprocessor ENTRY cannot be in a
preprocessor procedure.
Udhayas PL/I Material 6/06/2003 Page:- 142 / 161
NPROCEDURE S6+6'1'&6
The %PROCEDURE statement is used in conjunction with a %END statement to delimit a
preprocessor procedure. The syntax for the %PROCEDURE statement is:


1?A:>J0A;K?: PROCEDURE 9(F;>;K?:?>, F;>;K?:?>, . .)C
RETURNS(CARACTER 3 FIXED );
Abbreviation: %PROC
For example, a preprocessor procedure headed by:

1FIND:PROC(A,B,C) STATEMENT...;

must be invoked from a preprocessor expression by a reference of the form:
FIND(;>L1,;>L!,;>L*)
The value returned by a preprocessor function procedure to the point of invocation is specified by
the preprocessor-expression in a RETURN statement in the procedure. The syntax of the
preprocessor RETURN statement is:


[label:] RETURN(preprocessor-expression);
preprocessor-expression The value is converted to the RETURNS attribute specified in the
%PROCEDURE statement before it is passed back to the point of invocation.
P*'4*/.',,/* B)-36"I& F)&.6-/&,
A function reference can invoke one of a set of predefined functions called preprocessor built-in
functions. These built-in functions are invoked in the same way that programmer-defined
functions are invoked, except that they must be invoked with the correct number of arguments.

The preprocessor built-in functions are:

COMPILETIME LENGT
COUNTER PARMSET
INDEX SUBSTR

The preprocessor executes a reference to a preprocessor built-in function in input text only if the
built-in function name is active. The built-in functions can be activated by a %DECLARE or
%ACTVATE statement.
COMPILETIME B)-36"I& F)&.6-/&
COMPLETME returns a character string, length 18, in the format of DDbMMMbYYmHH.MM.SS.
The character string contains the date and the time of compilation. The syntax for
COMPLETME is:

COM$I&ETIME
The returned character string represents:

M BN;A=
DD D;J H@ :O? KHA:O
MMM MHA:O GA :O? @H>K JAN, FEB, MAR, ?:B.
YY Y?;>
Udhayas PL/I Material 6/06/2003 Page:- 143 / 161
HP>
MM MGAP:?
SS S?BHAQ

The following example shows how to print the string returned by COMPLETME when your
program is executed:

1DECLARE COMP/TIME CAR;
1COMP/TIME=####33COMPILETIME33####;
PUT EDIT (COMP/TIME) (A);
COUNTER B)-36"I& F)&.6-/&
COUNTER returns a character string, length 5, containing a decimal number. The returned
number is 00001 for the first invocation, and is incremented by one on each successive
invocation. The syntax for COUNTER is:

COUNTER
f COUNTER is invoked more than 99999 times, a diagnostic message is issued and 00000 is
returned. The next invocation is treated as the first.

The COUNTER built-in function can be used to generate unique names, or for counting purposes.
INDE> B)-36"I& F)&.6-/&
NDEX returns a FXED value indicating the starting position within the character expression x of
a substring identical to character expression y. The syntax for NDEX is:


INDEX(E,J)
E CO;>;B:?> ?EF>?<<GHA :H M? <?;>BO?Q

J CO;>;B:?> ?EF>?<<GHA :H M? <?;>BO?Q @H>.


f y does not occur in x, or if either string is null, the value 0 is returned.
LENGT= B)-36"I& F)&.6-/&
LENGTH returns a FXED value specifying the current length of a given character expression x.
The syntax for LENGTH is:


LENGT(E)
E CO;>;B:?> ?EF>?<<GHA. E G< BHAD?>:?Q :H BO;>;B:?>, G@ A?B?<<;>J.
PARMSET B)-36"I& F)&.6-/&
The PARMSET built-in function can be used only within a preprocessor procedure. t is used to
determine whether a specified parameter is set on invocation of the procedure. The syntax for
PARMSET is:


PARMSET(E)
E MP<: M? ; F;>;K?:?> H@ :O? F>?F>HB?<<H> F>HB?QP>?.


Udhayas PL/I Material 6/06/2003 Page:- 144 / 161
PARMSET returns a bit value of '1'B if the parameter x was explicitly set by the function reference
which invoked the procedure, and a bit value of '0'B if it was not--that is, if the corresponding
argument was omitted from the function reference in a preprocessor expression.
SUBSTR B)-36"I& F)&.6-/&
SUBSTR returns a substring of the character expression x. The syntax for SUBSTR is:


SUBSTR(E,J9,RC)

E CO;>;B:?> ?EF>?<<GHA @>HK SOGBO :O? <PM<:>GAL G< ?E:>;B:?Q. E
BHAD?>:< :H BO;>;B:?>, G@ A?B?<<;>J.

J EEF>?<<GHA :O;: B;A M? BHAD?>:?Q :H FIXED, <F?BG@JGAL :O?
<:;>:GAL FH<G:GHA H@ :O? <PM<:>GAL GA E.

R EEF>?<<GHA :O;: B;A M? BHAD?>:?Q :H FIXED, <F?BG@JGAL :O? N?AL:O
H@ :O? <PM<:>GAL GA E. I@ R G< ", ; APNN <:>GAL G< >?:P>A?Q. I@
R G< HKG::?Q, :O? <PM<:>GAL >?:P>A?Q G< FH<G:GHA J GA E :H :O?
?AQ H@ E.
NACTIVATE S6+6'1'&6
A %ACTVATE statement makes an identifier active and eligible for replacement. Any
subsequent encounter of that identifier in the input text while the identifier is active initiates
replacement activity. The syntax for the %ACTVATE statement is:

19N;M?N:C ACTI'ATE GQ?A:G@G?>,RESCAN 3 NORESCAN, . . .
Abbreviation: %ACT

identifier Specifies the name of a preprocessor variable, a preprocessor procedure, or a
preprocessor built-in function.

RESCAN Specifies that when the identifier is scanned by the preprocessor, replacement (as
described below for NORESCAN) and rescanning takes place. RESCAN is the default.

NORESCAN Specifies that when the identifier is encountered by the preprocessor scan, it is
replaced in the preprocessor output by that text which is either the current value of the variable
whose name matches the identifier, or the result of invoking the function whose name matches
the identifier. This text is not rescanned for further replacement.
N+,,-0&1'&6 S6+6'1'&6
A %assignment statement evaluates a preprocessor expression and assigns the result to a
preprocessor variable. The syntax for the %assignment statement is:

19N;M?N:C F>?F>HB?<<H>0D;>G;MN? = F>?F>HB?<<H>0?EF>?<<GHA

NDEACTIVATE S6+6'1'&6
A %DEACTVATE statement makes an identifier inactive. The syntax for the %DEACTVATE
statement is:


19N;M?N:CDEACTI'ATE GQ?A:G@G?>, . . .;
Udhayas PL/I Material 6/06/2003 Page:- 145 / 161
Abbreviation: %DEACT

identifier Specifies the name of either a preprocessor variable, a preprocessor procedure, or a
preprocessor built-in function.

The deactivation of an identifier causes loss of its replacement capability but not its value. Hence, the
reactivation of such an identifier need not be accompanied by the assignment of a replacement value.

The deactivation of an identifier does not prevent it from receiving new values in subsequent
preprocessor statements.
NDECLARE S6+6'1'&6
The %DECLARE statement establishes an identifier as a preprocessor name, specifies attributes of
the name, and establishes the scope of the name.

A %DECLARE statement behaves as a %ACTVATE statement when it is encountered outside a
preprocessor procedure, and activates, with the RESCAN option, all identifiers declared in the
%DECLARE statement. The syntax for the %DECLARE statement is:


19N;M?N:C DECLARE GQ?A:G@G?> FIXED 3 CARACTER 3 ENTRY 3 BUILTIN, . . .;
Abbreviations: %DCL for %DECLARE
CHAR for CHARACTER


identifier Specifies the name of either a preprocessor variable, a preprocessor procedure, or a
preprocessor built-in function.

CHARACTER Specifies that the identifier represents a varying-length character string that has no
maximum length.

FXED A preprocessor variable declared with the attribute FXED is also given the attributes
DECMAL(5,0).

ENTRY An entry declaration can be specified for each preprocessor entry name in the source
program. The declaration activates the entry name.
NDO S6+6'1'&6
The %DO statement, and its corresponding %END statement, delimit a preprocessor do-group, and
can also specify repetitive execution of the do-group. The syntax for the %DO statement is:


Type

19N;M?N:C DO;

Type
19N;M?N:C DO; F>?F>HB?<<H>0QH0<F?BG@GB;:GHA ;

F>?F>HB?<<H>0QH0<F?BG@GB;:GHA:
)00F>?F>HB?<<H>0D;>G;MN? = F>?F>HB?<<H>0?EF1000000000000000000000000000T

T0000000000000000000000000000000000000000000000000000000000000000000000U
Udhayas PL/I Material 6/06/2003 Page:- 146 / 161
)0TO00F>?F>HB?<<H>0?EF!0000000000000000000000000000U
U )0BY00F>?F>HB?<<H>0?EF*0) U
)0BY00F>?F>HB?<<H>0?EF*0000000000000000000000000000)
)0TO00F>?F>HB?<<H>0?EF!0)
NEND S6+6'1'&6
The %END statement is used in conjunction with %DO or %PROCEDURE statements to delimit
preprocessor do-groups or preprocessor procedures. The syntax for the %END statement is:


19N;M?N:C END;
The label following END must be a label of a %PROCEDURE or %DO statement. Multiple closure is
allowed.
NGO TO S6+6'1'&6
The %GO TO statement causes the preprocessor to continue its scan at the specified label. The
syntax for the %GO TO statement is:

19N;M?N:C GO TO ;AH:O?>0N;M?N;
Abbreviation: %GOTO
NIF S6+6'1'&6
The %F statement controls the flow of the scan according to the bit value of a preprocessor
expression. The syntax for the %F statement is:


19N;M?N:C IF F>?F>HB?<<H>0?EF>?<<GHA
1 TEN
F>?F>HB?<<H>0PAG:1
1 ELSE
F>?F>HB?<<H>0PAG:!
preprocessor-expression s evaluated and converted to a bit string (if the conversion cannot be made,
it is an error).

preprocessor-unit s any single preprocessor statement (other than %DECLARE, %PROCEDURE,
%END, or %DO) or a preprocessor do-group.
NNOTE S6+6'1'&6
The %NOTE statement generates a preprocessor diagnostic message of specified text and severity.
The syntax for the %NOTE statement is:


19N;M?N:C NOTE (K?<<;L? 9,BHQ?C );
message A character expression whose value is the required diagnostic message.

code A fixed expression whose value indicates the severity of the message, as follows:

)00000000000000000000000000000)
U CHQ? U S?D?>G:J U
)00000000000000)00000000000000U
U " U I U
)00000000000000)00000000000000U
Udhayas PL/I Material 6/06/2003 Page:- 147 / 161
U + U $ U
)00000000000000)00000000000000U
U & U E U
)00000000000000)00000000000000U
U 1! U S U
)00000000000000)00000000000000U
U 1- U U U
)00000000000000000000000000000)
$CL .2+&0', &''7'7
IEL1CL
//IEL1CL PROC . . .
.
.
//PLI EXEC PGM=IEL1AA,PARM=#OBJECT,NODEC%,MACRO#,REGION=,1!%
.
.
//
E(+143' 1
f the preprocessor input contains:

1DECLARE A CARACTER, B FIXED;
1A = #B)C#;
1B = !;
X = A;

the following is inserted into the preprocessor output:

X = !)C;

The preprocessor statements activate A and B with the default RESCAN, assign the character string
'B+C' to A, and assign the constant 2 to B.
f, in the above example, the preprocessor variable A was activated by this statement:

1ACTI'ATE A NORESCAN;

the preprocessor output would be:

X = B)C;
E(+143' 2
f the preprocessor input contains:

1DECLARE I FIXED, T CARACTER;
1DEACTI'ATE I;
1I = 1,;
1T = #A(I)#;
S = I*T**;
1I = I),;
1ACTI'ATE I;
1DEACTI'ATE T;
R = I*T*!

Udhayas PL/I Material 6/06/2003 Page:- 148 / 161
the preprocessor output would be as follows (replacement blanks are not shown):

S = I*A(I)**;
R = !"*T*!;
E(+143' 3
This example illustrates how preprocessor facilities can be used to speed up the execution of a do-
group, such as:

DO I=1 TO 1";
.(I)=X(I))Y(I);
END;

The following would accomplish the same thing, but without the requirements of incrementing and
testing during execution of the compiled program:

1DECLARE I FIXED;
1DO I = 1 TO 1";
.(I)=X(I))Y(I);
1END;
1DEACTI'ATE I;

The third line is input text and is scanned for replacement activity. The first time that this line is
scanned, has the value 1 and has been activated. Therefore, the following is inserted into the
preprocessor output:

.( 1)=X( 1))Y( 1);

Each 1 is preceded by seven blanks.

For each increment of , up to and including 10, the input text is scanned and each occurrence of is
replaced by its current value. As a result, the following is inserted into the preprocessor output:

.( 1)=X( 1))Y( 1);
.( !)=X( !))Y( !);
.
.
.
.( 1")=X( 1"))Y( 1");

When the value of reaches 11, control falls through to the %DEACTVATE statement.
The complete program is:-
PLIPGM1: PROC OPTIONS(MAIN);
DCL (LBOUND,BOUND) BUILTIN;
DCL X(1") FIXED BIN(*1) INIT((1")1);
DCL Y(1") FIXED BIN(*1) INIT((1")!);
DCL .(1") FIXED BIN(*1) INIT((1")");
1DECLARE I FIXED;
1DO I = 1 TO 1";
.(I)=X(I))Y(I);
1END;
1DEACTI'ATE I;
PUT DATA(.);
DCL 6(1") FIXED BINARY(*1) CTL;
ALLOCATE 6(1"");
Udhayas PL/I Material 6/06/2003 Page:- 149 / 161
ALLOCATE 6(*);
PUT S%IP LIST(LBOUND(6,1),BOUND(6,1));
END PLIPGM1;
E(+143' 4
n the preprocessor input below, VALUE is a preprocessor function procedure that returns a character
string of the form 'arg1(arg2)', where arg1 and arg2 represent the arguments that are passed to the
function:

DECLARE (.(1"), 6) FIXED;
1A=#.#;
1ACTI'ATE A, 'ALUE;
6 = - ) 'ALUE(A,*);
1DECLARE A CARACTER;
1'ALUE: PROC(ARG1,ARG!) RETURNS(CAR);
DCL ARG1 CAR, ARG! FIXED;
RETURN(ARG133#(#33ARG!33#)#);
1END 'ALUE;

When the scan encounters the fourth line, A is active and is thus eligible for replacement. Since
VALUE is also active, the reference to it in the fourth line invokes the preprocessor function procedure
of that name.

However, before the arguments A and 3 are passed to VALUE, A is replaced by its value Z (assigned
to A in a previous assignment statement), and 3 is converted to fixed-point to conform to the attribute
of its corresponding parameter. VALUE then performs a concatenation of these arguments and the
parentheses and returns the concatenated value, that is, the string Z (3), to the point of invocation.
The returned value replaces the function reference and the result is inserted into the preprocessor
output. Thus, the preprocessor output generated is:

DECLARE (.(1"),6) FIXED;
6 = -).( *);
E(+143'
//. . . JOB
//STEP! EXEC IEL1C,PARM.PLI=#MACRO,MDEC%,NOCOMPILE,NOSYNTAX#
.
.
//PLI.SYSIN DD *
/* GI'EN .IP CODE, FINDS CITY */
1DCL USE CAR;
1USE = #FUN# /* FOR SUBROUTINE, 1USE = #SUB# */ ;
1IF USE = #FUN# 1TEN 1DO;
CITYFUN: PROC(.IPIN) RETURNS(CAR(1-)) REORDER; /* FUNCTION */
1END;
1ELSE 1DO;
CITYSUB: PROC(.IPIN, CITYOUT) REORDER; /* SUBROUTINE */
DCL CITYOUT CAR(1-); /* CITY NAME */
1END;
DCL (LBOUND, BOUND) BUILTIN;
DCL .IPIN PIC #77777#; /* .IP CODE */
DCL 1 .IP/CITY(() STATIC, /* .IP CODE 0 CITY NAME TABLE */
! .IP PIC #77777# INIT(
7,1+1, 7,"1+, 7,"*",
7,",1, 7,"(", 7,""&,
"), /* $ILL NOT LOO% AT LAST ONE */
Udhayas PL/I Material 6/06/2003 Page:- 150 / 161
! CITY CAR(1-) INIT(
#SAN JOSE#, #CUPERTINO#, #LOS GATOS#,
#SANTA CLARA#, #SARATOGA#, #CAMPBELL#,
#UN%NO$N CITY#); /* $ILL NOT LOO% AT LAST ONE */
DCL I FIXED BIN(*1);
DO I = LBOUND(.IP,1) TO /* SEARC FOR .IP IN TABLE */
BOUND(.IP,1)01 /* DON#T LOO% AT LAST ELEMENT */
$ILE(.IPIN V= .IP(I));
END;
1IF USE = #FUN# 1TEN 1DO;
RETURN(CITY(I)); /* RETURN CITY NAME */
1END;
1ELSE 1DO;
CITYOUT=CITY(I); /* RETURN CITY NAME */
1END;
END;
Udhayas PL/I Material 6/06/2003 Page:- 151 / 161
SECTION"13 PRO$ECT FOR PL/I
SETTING UP AND GETTING ACGUAINTED %IT= BASICS
Examine and understand the BM supplied procedures I+L1,?I+L1,L?I+L1,LG
Create a P.S with .S/ name userid#PLI.PROCLIB with
.S2RGCP2?LR+,LCR8?BL$SIK+C3288?3/I0CS4S.(?R+,1MC1B?SP(,+C=0R$?=1?1?:))
Create a P.S with .S/ name userid#PLI.OB$ with
.S2RGCP2?LR+,LCR8?BL$SIK+C3288?3/I0CS4S.(?R+,1MC1B?
SP(,+C=0R$?=1?1?:))
Create a P.S with .S/ name userid#PLI.SOURCE with
.S2RGCP2?LR+,LCR8?BL$SIK+C3288?3/I0CS4S.(?R+,1MC1B? SP(,+C=0R$?=1?1?:))
Create a PDS with .S/ name userid#PLI.LOADLIB with
.S2RGCP2?3/I0CS4S.(?R+,1MC3?SP(,+C=0R$?=1?1?:))
Try to prepare the sample program in the first chapter and run it. Examine the compilation,
Linkage and run outputs.
Udhayas PL/I Material 6/06/2003 Page:- 152 / 161
S6)7'&6 P*/O'.6
The project is a VDEO rental system. The system keeps track of its customers via a customer
master file that has all the customer details, including the number of videos outstanding against
that customer. t keeps track of its inventory of videos via the video master file. There is one
record for each media and that record also keeps track of whether it is rented, and if so the date
of rental and the customer number of the customer who has rented that media.
The customer master is a VSAM KSDS indexed on customer number. The video master is
indexed on the video title and a two byte copy number, as multiple copies of the same title can
exist. This file has an alternate index built on the customer number. f we wish to get the videos
against each customer we can fetch the records in the video master file via the alternate index.
The figure below indicates the various functions of the system, implemented by more than one
program.
The record layout for the VDMAST and CUSTMAST files are given below:-
CUSTMAST
DCL "1 CUSTOMER/MASTER/RECORD,
", CM/CUSTOMER/NUMBER CAR((),
", CM/FIRST/NAME CAR(!"),
", CM/LAST/NAME CAR(*"),
", CM/ADDRESS CAR(*"),
", CM/CITY CAR(!"),
", CM/STATE CAR(!),
", CM/.IP/CODE CAR(1"),
", CM/'IDEOS/OUT FIXED BINARY(1,);
CUSTMAST is a KSDS file indexed on CM_CUSTOMER_NUMBER.
Video
changes
Video
rentals
Customer
changes
Videos
Customers
List of
videos
Video
returns
Video
maintenance
Video
rental
Customer
maintenance
Video
list
Video
return
Customer
inquiry
Customer
data
Udhayas PL/I Material 6/06/2003 Page:- 153 / 161
VIDMAST
DCL "1 'IDEO/MASTER/RECORD,
", 'M/'IDEO/NUMBER,
1" 'M/TITLE/NUMBER CAR(-),
1" 'M/COPY/NUMBER CAR(!),
", 'M/TITLE CAR(*"),
", 'M/MEDIA/TYPE CAR(1),
", 'M/STATUS CAR(1),
", 'M/CUSTOMER/NUMBER CAR((),
", 'M/DATE/OUT CAR(1");
VDMAST is a KSDS file keyed on VM_VDEO_NUMBER. An alternate index is built on
VM_CUSTOMER_NUMBER.
The VM_MEDA_TYPE field has the following values:-
For media type of TAPE VALUE 'T'.
For media type of DVD VALUE 'D'.
For media type of GAME VALUE 'G'
The VM_STATUS field has the following values:-
For status of N VALUE '1'.
For status of OUT VALUE '2'.
T2' 9+6.2 4*/0*+1, 6/ 9' ./7'7 2+8' 62' 5/33/;-&0 5)&.6-/&+3-6<@"
C),6/1'* M+,6'* L/+7 4*/0*+1:-This program loads the initial data from the sequential
file to the VDCUST KSDS. A sample program CUSTLS is available. Ask your instructor for a
copy.
V-7'/ M+,6'* L/+7 4*/0*+1:-This program loads the initial data from the sequential file to
the VDMAST KSDS. A sample program VDLS is available. Ask your instructor for a copy.
C),6/1'* 1+-&6'&+&.' 4*/0*+1. This program will read input from a PS file and can
perform a delete / update of an existing record or insert a new record in the VDCUST file. The
first byte of the input file (CM-OP-CODE) will indicate the action to be performed, as follows:
a)Character (Upper case) for nsert of a new record
b)Character D (Upper case) for delete of an existing record. Deletes are not permitted if the
customer has any outstanding rentals.
c)Character U (Upper case) for update of an existing record.
The command byte is followed by the full record itself in the following format
T2' R'./*7 L+</)6 /5 62' -&4)6 5-3'
DCL "1 CUSTOMER/MASTER/INPUT/RECORD,
", CM/OP/CODE CAR(1),
", CM/CUSTOMER/NUMBER CAR("(),
", CM/FIRST/NAME CAR(!"),
", CM/LAST/NAME CAR(*"),
", CM/ADDRESS CAR(*"),
", CM/CITY CAR(!"),
Udhayas PL/I Material 6/06/2003 Page:- 154 / 161
", CM/STATE CAR("!),
", CM/.IP/CODE CAR(1"),
", CM/'IDEOS/OUT FIXED BINARY(1,);
The program should generate a SYSOUT data set that indicates the processing status of every
input record. A sample program CUSTUPD is available. Ask your instructor for a copy.
VIDEO 1+-&6'&+&.' 4*/0*+1. This program will read input from a PS file and can
perform a delete / update of an existing record or insert a new record in the VDMAST file. The
first byte of the input file (VM-OP-CODE )will indicate the action to be performed, as follows:
a)Character (Upper case) for nsert of a new record
b)Character D (Upper case) for delete of an existing record. Deletes must not be allowed if the
media is in rented out state.
T)# (o//!+- 32t# .* 0o==o>#- 32 t)# 01== #(o- .t*#=08 T)# #(o- 0o/!t 0o==o>*7<
T2' R'./*7 L+</)6 /5 62' -&4)6 5-3'
DCL "1 'IDEO/MASTER/INPUT/RECORD,
", 'M/OP/CODE CAR(1),
", 'M/'IDEO/NUMBER,
1" 'M/TITLE/NUMBER CAR("-),
1" 'M/COPY/NUMBER CAR("!),
", 'M/TITLE CAR(*"),
", 'M/MEDIA/TYPE CAR("1),
", 'M/STATUS CAR(1),
", 'M/CUSTOMER/NUMBER CAR("(),
", 'M/DATE/OUT CAR(1");
The program should generate a SYSOUT data set that indicates the processing status of every
input record. A sample program VDUPD is available. Ask your instructor for a copy.
V-7'/ R'&6+3 +&7 R'6)*& P*/0*+1:- This program will read its input from a PS file for
recording rentals and returns. The first character of the input file should be interpreted as follows:-
a)Character ( Upper case) for return (n)
b)Character O (Upper case) for rental (Out)
DCL "1 'IDEO/IO/RECORD,
", 'IO/OP/CODE CAR(1),
", 'IO/'IDEO/NUMBER,
1" 'IO/TITLE/NUMBER CAR(-),
1" 'IO/COPY/NUMBER CAR(!),
", 'IO/CUSTOMER/NUMBER CAR(();
The values that VRR_OP_CODE can have are
For RETURN(N) VALUE ''.
For RENTAL(OUT) VALUE 'O'.
Udhayas PL/I Material 6/06/2003 Page:- 155 / 161
The input video number and the customer number must be validated before an update is made to
the VDMAST master file. The rental / return date is not supplied on input. t is fetched from the
system using the DATE Builtin function.
A SYSOUT file must be created which has the processing status of every return / rental record in
the input stream. A sample program VDO is available. Ask your instructor for a copy.
R'4/*6 P*/0*+1:- This program can report status of a video(who has rented and when) or
report for a customer all the videos he or she has currently on rental. The input is via a sequential
file where the first character is interpreted as follows:-
a)Character V (Upper case) :-The next 6 bytes is the video number and the program is to output
the customer(s) who have rented out the videos and the date of rental. f the video is not rented, it
should report as such. Note that the 6 character video number is a generic key and the program
must examine all records which match this key.
b)Character C (Upper case):- The next seven characters is the customer number.
The program must first validate the customer number against the customer master file. t should
then access the VDMAST file via its alternate index (customer number) and fetch all records for
that customer, for report generation.
The report must show customer number, Customer name, Customer address, Video number,
Video title and date rented out.
The input file can have more than one record, each record representing a query.
Each page of the report must have a heading that includes the Report name, page number and
run date. The number of lines per page must be kept configurable via PARM field of the JCL
EXEC card.
A limited function sample program VDRPT is available. Ask your instructor for a copy.
T',6 7+6+
1. Test data for the customer master is available in the file KAM0001.CUSTMAS.DATA. Ask
your instructor for a copy.
2. Test data for the video master is available in the file KAM0001.VDMAS.DATA. Ask your
instructor for a copy.
3. Test data for issue and return is available in the file KAM0001.O. Ask your instructor for a
copy.
$CL
A comprehensive JCL is provided to install a basic system. t does the following:-
1)Creates the video and customer KSDS clusters, after deleting existing ones by the same name.
2)Prepares the CUSTLS and VDLS programs and then loads the clusters.
3)Defines an alternate index over the video master and then build the index and defines a path.
This JCL is available as file DCCUST . Ask your instructor for a copy.
Y/)* /9O'.6-8'@"
Study and understand existing programs. Test and debug if required.
Write a report program that supports the following:-
1)Report status for a specific video whose title is supplied via SYSN
Udhayas PL/I Material 6/06/2003 Page:- 156 / 161
2)Report status for a specific customer whose number is supplied via SYSN
3)Generate the report with headings and page number and run date with fields formatted.
Udhayas PL/I Material 6/06/2003 Page:- 157 / 161
Udhayas PL/I Material 6/06/2003 Page:- 158 / 161
Udhayas PL/I Material 6/06/2003 Page:- 159 / 161
Udhayas PL/I Material 6/06/2003 Page:- 160 / 161
!!"#U$" LIMITS

)00000000000000000000000000000000000000000000000000000000000000000000000000U
U L;ALP;L? U D?<B>GF:GHA U LGKG: U
U EN?K?A: U U U
)00000000000000)0000000000000000000000000000000000000000)000000000000000000U
U D;:; U M;EGKPK APKM?> H@ QGK?A<GHA< @H> ;A U 1, U
U ALL>?L;:?< U ;>>;J U U
U (A>>;J<, )0000000000000000000000000000000000000000)000000000000000000U
U S:>PB:P>?< U MGAGKPK NHS?> MHPAQ @H> ;A ;>>;J U 0!1+(+&*-+& U
U ;AQ AREA<) )0000000000000000000000000000000000000000)000000000000000000U
U U MGAGKPK NHS?> MHPAQ @H> ;A ;>>;J P<GAL U 0*!(-& U
U U CMPAT('1) U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK PFF?> MHPAQ @H> ;A ;>>;J U )!1+(+&*-+( U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK PFF?> MHPAQ @H> ;A ;>>;J P<GAL U )*!(-( U
U U CMPAT('1) U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ N?D?N< GA ; U 1, U
U U <:>PB:P>? U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK N?D?N APKM?> GA ; <:>PB:P>? U !,, U
)00000000000000)0000000000000000000000000000000000000000)000000000000000000U
U S:>GAL D;:; U M;EGKPK N?AL:O H@ ; CARACTER D;>G;MN? U *!(-( BO;>;B:?>< U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK N?AL:O H@ ; BIT D;>G;MN? U *!(-( MG:< U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK <:>GAL >?F?:G:GHA @;B:H> U *!(-( U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ FGB:P>? BO;>;B:?>< U ,11 U
U U GA ; BO;>;B:?> PICTURE U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ FGB:P>? BO;>;B:?>< U !,- U
U U GA ; APK?>GB PICTURE U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ APK?>GB FGB:P>? U 1, U
U U BO;>;B:?>< GA ; APK?>GB PICTURE U U
)00000000000000)0000000000000000000000000000000000000000)000000000000000000U
U A>G:OK?:GB U M;EGKPK F>?BG<GHA @H> FIXED DECIMAL U 1, U
U P>?BG<GHA< )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK F>?BG<GHA @H> FIXED BINARY U *1 U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK F>?BG<GHA @H> FLOAT DECIMAL U ** U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK F>?BG<GHA @H> FLOAT BINARY U 1"7 U
)00000000000000)0000000000000000000000000000000000000000)000000000000000000U
U P>HL>;K SGR? U M;EGKPK N?AL:O H@ ;A GQ?A:G@G?> U *1 MJ:?< U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK N?AL:O H@ ;A ?E:?>A;N A;K? U ( MJ:?< U
U U U U
U U $OGN? ?E:?>A;N A;K?< L?A?>;:?Q MJ PL/I U U
U U ;>? ;NS;J< & BO;>;B:?>< GA N?AL:O, U U
U U P<?>0Q?@GA?Q ?E:?>A;N A;K?< B;AAH: U U
U U ?EB??Q ( BO;>;B:?><. TOG< F>?D?A:< U U
Udhayas PL/I Material 6/06/2003 Page:- 161 / 161
U U QPFNGB;:? Q?@GAG:GHA H@ A;K?<. I@ ; U U
U U A;K? H@ KH>? :O;A ( BO;>;B:?>< G< U U
U U Q?BN;>?Q SG:O :O? EXTERNAL ;::>GMP:?, U U
U U :O? @G><: + BO;>;B:?>< ;>? U U
U U BHAB;:?A;:?Q SG:O :O? N;<: * U U
U U BO;>;B:?>< :H @H>K :O? EXTERNAL A;K?. U U
U U HS?D?>, ;A ?A:>J A;K? Q?BN;>?Q SG:O U U
U U ASSEMBLER, COBOL, H> FORTRAN <F?BG@G?Q U U
U U GA :O? OPTIONS ;::>GMP:? B;A O;D? PF U U
U U :H & BO;>;B:?><. I@ KH>? :O;A & U U
U U BO;>;B:?>< ;>? <F?BG@G?Q, HANJ :O? U U
U U N?@:KH<: & ;>? P<?Q. U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ F>HB?QP>?< GA ; U !,, U
U U F>HL>;K U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ ;>LPK?A:< GA ; CALL U -+ U
U U H> @PAB:GHA >?@?>?AB? U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK APKM?> H@ F;>;K?:?>< @H> ; U -+ U
U U F>HB?QP>? U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK A?<:GAL H@ BEGIN ;AQ PROCEDURE U +! U
U U MNHB=< U U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK A?<:GAL H@ DO L>HPF< U *& U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK A?<:GAL H@ IF <:;:?K?A:< U &" U
U )0000000000000000000000000000000000000000)000000000000000000U
U U M;EGKPK A?<:GAL H@ SELECT <:;:?K?A:< U ," U
)00000000000000)0000000000000000000000000000000000000000)000000000000000000U

S-ar putea să vă placă și