═══ 1. PL/I Product Help ═══ PL/I is a programming language you can use to develop structured applications and systems programs. PL/I has a number of features. For details, select from the following list:  Program organization and control transfer  Built-ins  Data items  Expressions and references  Variable storage  Statements  Input/output (I/O)  Condition handling  Compiler options If you are unfamiliar with the conventions followed for PL/I syntax notation, you may want to select the following:  Reading PL/I syntax diagrams Note: This PL/I product online help is intended to be used as a quick reference and backup to the IBM SAA AD/Cycle PL/I MVS and VM publications. It offers a subset of the information in those publications, and is not intended to replace them. ═══ 1.1. PL/I Input/Output (I/O) ═══ Description PL/I input and output statements (such as READ, OPEN, GET, and PUT) let you transmit data between the main and auxiliary storage of a computer. Collections of data external to a program are called data sets. If you are using a terminal, "data set" can also mean your terminal. Transmission of data from a data set to a program is called input. Transmission of data from a program to a data set is called output. PL/I input and output statements are concerned with the logical organization of a data set and not with its physical characteristics. Therefore, a program can be designed without specific knowledge of the input/output devices that will be used when the program is executed. To allow a source program to deal primarily with the logical aspects of data rather than with its physical organization in a data set, PL/I employs models of data sets, called files. A file can be associated with different data sets at different times during the execution of a program. Two types of data transmission can be used by a PL/I program: stream and record. It is possible for the same data set to be processed at different times by either stream data transmission or record data transmission. However, all items in the data set must be in character form.  In stream-oriented data transmission, the organization of the data in the data set is ignored within the program, and the data is treated as though it were a continuous stream of individual data values in character form. Data is converted from character form to internal form on input, and from internal form to character form on output. DBCS data is processed unchanged. Stream-oriented data transmission can be used for processing input data prepared in character form and for producing readable output, where editing is required. Stream-oriented data transmission allows synchronized communication with the program at run time from a terminal, if the program is running under an interactive system.  In record-oriented data transmission, the data set is a collection of discrete records. The record on the external medium is generally an exact copy of the record as it exists in internal storage. No data conversion takes place during record-oriented data transmission. Record-oriented data transmission can be used for processing files that contain data in any representation, such as binary, decimal, or character. Related Information  Declaring files  Opening and closing files  Using record-oriented data transmission  Using stream-oriented data transmission  Using the SYSPRINT file ═══ Data Sets ═══ Data sets are stored on a variety of auxiliary storage media, such as magnetic tape and direct-access storage devices, (as well as being input from or output to your terminal). Despite their variety, these media have characteristics that allow common methods of collecting, storing, and transmitting data. The organization of a data set determines how data is recorded in a data set and how the data is subsequently retrieved so that it can be transmitted to the program. Records are stored in and retrieved from a data set either sequentially on the basis of successive physical or logical positions, or directly by the use of keys specified in data transmission statements. These storage and retrieval methods provide PL/I with five sets of data set organizations. These five types of data sets differ in the way data is stored in them and in the allowable means of access to the data. The five data set organizations are the following:  Consecutive  Indexed  Regional The compiler recognizes a fourth type of data set called "teleprocessing" by the file attribute TRANSIENT. A fifth type, called "partitioned", has no corresponding PL/I organization. PL/I also provides support for three types of VSAM data organization: ESDS, KSDS, and RSDS. If the data set organization is not specified in the ENVIRONMENT option, the following default is obtained when the file is opened:  If the merged attributes from the DECLARE statement and OPEN statement do not include TRANSIENT, the default is CONSECUTIVE.  If the attributes include TRANSIENT, the default is TP(M). Following are descriptions of the five types of data set organizations: Consecutive In a consecutive data set, records are organized 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. In general, the records can be retrieved only in the order in which they were written. Indexed In an indexed data set, records are placed in the logical sequence based on the key of each record. An indexed data set must reside on a direct-access device. A character string key identifies the record and allows direct retrieval, replacement, addition, and deletion of records. Sequential processing is also allowed. Regional In a regional data set, records are placed in their relative position to each other. A regional data set must reside on a direct-access device. A key that specifies the record number identifies the record and allows direct retrieval, replacement, addition, and deletion of records. Sequential processing is also allowed. Teleprocessing A teleprocessing data set (associated with a TRANSIENT file in a PL/I program) must reside in storage. Records are placed in physical sequence. Partitioned In a partitioned data set, independent groups of sequentially organized data, each called a member, reside in a direct-access data set. The data set includes a directory that lists the location of each member. Partitioned data sets are often called libraries. The compiler includes no special facilities for creating and accessing partitioned data sets. Each member can be processed as a CONSECUTIVE data set by a PL/I program. ═══ Declaring Files ═══ Description To allow a source program to deal primarily with the logical aspects of data rather than with its physical organization in a data set, PL/I employs models of data sets, called files. These models determine how input and output statements access and process the associated data set. Unlike a data set, a file has significance only within the source program and does not exist as a physical entity external to the program. You can declare file data items as constants and variables, and use the file names as references. Use the FILE attribute to specify that the data item is a file type. A constant, variable, or file reference name that represents a file has the FILE attribute. The FILE attribute is explicitly or implicitly part of the file name declaration. Related Information  Declaring file constants  Declaring file variables  Using file references Syntax ─────FILE─────────── ═══ Declaring File Constants ═══ Description Each data set processed by a PL/I program must be associated with a file constant. The FILE attribute can be implied for a file constant by file description attributes. You can contextually declare a name as a file constant through its appearance in the FILE option of any input or output statement, or in an ON statement for any input/output condition. You describe the individual characteristics of each file constant with file description attributes. These attributes are either alternative attributes or additive attributes.  An alternative attribute is one that is chosen from a group of attributes. If no explicit or implied attribute is given for one of the alternatives in a group and if one of the attributes is required, a default attribute is used. The alternative attributes are: BUFFERED/UNBUFFERED attributes INTERNAL/EXTERNAL attributes INPUT/OUTPUT/UPDATE attributes SEQUENTIAL/DIRECT/TRANSIENT attributes STREAM/RECORD attributes  An additive attribute must be stated explicitly or implied by another explicitly stated attribute. The additive attributes are: BACKWARDS attribute ENVIRONMENT attribute EXCLUSIVE attribute KEYED attribute PRINT attribute Example In the following example, the name MASTER is declared as a file constant: DECLARE MASTER FILE; ═══ Declaring File Variables ═══ Description A file variable has the attributes FILE and VARIABLE. It cannot have any of the attributes used for declaring file constants. You can assign file constants to file variables. After assignment, a reference to the file variable has the same significance as a reference to the assigned file constant. The VARIABLE attribute is implied for a name with the FILE attribute if the name is an element of an array or structure, or if any of the following attributes is specified:  Storage class attribute  Parameter  Alignment attribute  DEFINED  INITIAL Example In the following statement, the name ACCOUNT is declared a file variable. ACCT1 and ACCT2 are declared as file constants. DECLARE ACCOUNT FILE VARIABLE, ACCT1 FILE, ACCT2 FILE; ACCT1 and ACCT2 can subsequently be assigned to ACCOUNT. Syntax ──────VARIABLE─────── ═══ Using File References ═══ Description You can use a file reference as a file constant, a file variable, or a function reference which returns a value with the FILE attribute. You can use file references:  In the FILE and COPY options  As an argument to be passed to a function or subroutine  To qualify an input/output condition for ON, SIGNAL, and REVERT statements  As the expression in a RETURN statement. Example In the following example, the statements labelled L1 and L2 both specify null ON-units for the same file: DCL F FILE, G FILE VARIABLE; G=F; L1: ON ENDFILE(G); L2: ON ENDFILE(F); ═══ STREAM/RECORD Attributes ═══ Description Use the STREAM and RECORD attributes to specify the kind of data transmission for your files. The default is STREAM.  STREAM indicates that the data of the file is a continuous stream of data items, in character form, assigned from the stream to variables, or from expressions into the stream. You can specify a file with the STREAM attribute only in the FILE option of the OPEN, CLOSE, GET, and PUT input/output statements.  RECORD indicates that the file consists of a collection of physically separate records, each of which consists of one or more data items in any form. Each record is transmitted as an entity to or from a variable. You can specify a file with the RECORD attribute only in the FILE option of the OPEN, CLOSE, READ, WRITE, REWRITE, LOCATE, and DELETE input/output statements. Syntax ┌─STREAM─┐ ─────┴─RECORD─┴───────────────────────────────────────────────── ═══ INPUT/OUTPUT/UPDATE Attributes ═══ Description Use the INPUT, OUTPUT, and UPDATE attributes to specify the direction of data transmission for a file. The default is INPUT.  INPUT specifies that data is transmitted from auxiliary storage to the program.  OUTPUT specifies that data is transmitted from the program to auxiliary storage, either to create a new data set or to extend an existing one.  UPDATE, which applies to RECORD files only, specifies that the data can be transmitted in either direction. A declaration of UPDATE for a SEQUENTIAL file indicates the update-in-place mode. Syntax ┌──INPUT───┐ ───┼──OUTPUT──┼─────── └──UPDATE──┘ ═══ SEQUENTIAL/DIRECT/TRANSIENT Attributes ═══ Description These access attributes apply only to RECORD files. Use SEQUENTIAL, DIRECT and TRANSIENT to specify how the records in the file are accessed. The default is SEQUENTIAL.  The SEQUENTIAL (abbreviation SEQL) attribute specifies that records in a CONSECUTIVE or REGIONAL data set are accessed in physical sequence and that records in an indexed data set are accessed in key sequence order. For certain data set organizations, a file with the SEQUENTIAL attribute can also be used for random access or for a mixture of random and sequential access. In this case, the file must have the additive attribute KEYED. Existing records of a data set in a SEQUENTIAL UPDATE file can be modified, ignored, or, if the data set is indexed, deleted.  The DIRECT attribute specifies that records in a data set can be accessed in any order. The location of the record in the data set is determined by a character-string key. Therefore, the DIRECT attribute implies the KEYED attribute. The associated data set must be on a direct-access storage device.  The TRANSIENT attribute applies to files used for teleprocessing applications. A TRANSIENT file is associated with a data set that consists of a queue of messages. The message queue data set contains messages originating from and destined for remote terminals while in transit between a message control program and the PL/I message processing program. The action of reading a record removes that record from the data set. Access is sequential, but the file must have the KEYED attribute since a key is used to identify the terminal concerned. A buffer is always used, and so the file must also have the BUFFERED attribute. Syntax ────┬──DIRECT──────┬────── ├──SEQUENTIAL──┤ └──TRANSIENT───┘ ═══ BUFFERED/UNBUFFERED Attributes ═══ Description The BUFFERED (abbreviation BUF) and UNBUFFERED (abbreviation UNBUF) attributes apply only to RECORD files. BUFFERED is the default for SEQUENTIAL and TRANSIENT files. UNBUFFERED is the default for DIRECT files. BUFFERED specifies that during transmission to and from auxiliary storage, each record of a RECORD file must pass through intermediate storage buffers. If BUFFERED is specified, data transmission (in most cases) is overlapped with processing. UNBUFFERED indicates that a record in a data set need not pass through a buffer but can be transmitted directly to and from the main storage associated with a variable. It does not, however, specify that records cannot be buffered. Buffers will, in fact, be used if you specify INDEXED, REGIONAL(2) or REGIONAL(3) is specified in the ENVIRONMENT attribute or if the records are variable-length. A file with the UNBUFFERED attribute must not be blocked. When you specify UNBUFFERED, data transmission is not overlapped with processing. You must use the EVENT option to achieve such overlapping. Note: ABEND OCX may occur when a PL/I program using a QSAM LOCATE mode attempts to reference data in the I/O buffer after the buffer is freed by DFP during CLOSE FILE processing. DFP frees buffers after CLOSE FILE processing. Do not attempt to access based variables in the buffers after you have closed the file and MVS/XA DFP has released the buffer. A protection exception might result. Syntax ────┬──BUFFERED────┬───── └──UNBUFFERED──┘ ═══ BACKWARDS Attribute ═══ Description The BACKWARDS attribute specifies that the records of a SEQUENTIAL RECORD INPUT file associated with a data set on magnetic tape are to be accessed in reverse order; that is, from the last record to the first record. Syntax ───BACKWARDS────────────────────────── Note: The BACKWARDS attribute is for MVS only. ═══ ENVIRONMENT Attribute ═══ Description Use the ENVIRONMENT (abbreviation ENV) attribute to specify various data set characteristics that are not part of the PL/I language. You provide these characteristics in a characteristic-list following the ENVIRONMENT attribute. Options in the characteristic list are separated by blanks or commas. The characteristic-list options are: F|FB|FS|FBS BUFN(n) INDEXAREA(n) REREAD V|VB|VS|VBS BUFSP(n) KEYLENGTH(n) REUSE U|D|DB COBOL KEYLOC(n) SCALARVARYING ADDBUFF CONSECUTIVE LEAVE SIS ASCII CTLASA NCP(n) SKIP BKWD CTL360 NOWRITE TOTAL BLKSIZE(n) GENKEY PASSWORD TP(M|R) BUFFERS(n) GRAPHIC RECSIZE(n) TRKOFL BUFFOFF(n) INDEXED REGIONAL(1|2|3) VSAM BUFND(n) Note: MVS and CMS each support a different subset of the set of all possible ENVIRONMENT options. Syntax ────ENVIRONMENT──(characteristic-list)──── ═══ EXCLUSIVE Attribute ═══ Description The EXCLUSIVE attribute specifies that records in a file can be locked by an accessing task to prevent other tasks from interfering with an operation. When protecting a data set by means of the EXCLUSIVE attribute, all files accessing the data set must have that attribute. Abbreviation: EXCL When access to a record is restricted to one task, the record is "locked" by that task. The EXCLUSIVE attribute provides a temporary locking mechanism to prevent one task from interfering with an operation by another task. Locking can be suppressed by the NOLOCK option on the READ statement. No other task operating upon the same data set can access a locked record until it is unlocked by the locking task. The record is protected from access by tasks in other jobs, as well as by those within the same job as the locking task. Any task referring to a locked record will wait at that point until the record is unlocked. Any READ statement referring to an EXCLUSIVE file locks the record unless the NOLOCK option is specified. Subsequent unlocking can be accomplished by the locking task through execution of an UNLOCK statement, a REWRITE statement, or a DELETE statement that specifies the same key, by a CLOSE statement, or by completion of the program. The EXCLUSIVE attribute applies to the data set and not to the file. Consequently, record protection is provided even when all tasks refer to the data set through the use of different files. The EXCLUSIVE attribute, the UNLOCK statement, and the NOLOCK option of the READ statement can be used for DIRECT UPDATE of INDEXED data sets, and can be used for DIRECT INPUT and DIRECT UPDATE of REGIONAL data sets. They have no effect for a file associated with a VSAM data set. Syntax ────EXCLUSIVE──────────────────────────── Note: The EXCLUSIVE attribute is for MVS only. ═══ KEYED Attribute ═══ Description The KEYED attribute applies only to RECORD files, and must be associated with direct access devices or with a file with the TRANSIENT attribute. Use the KEYED attribute to specify that records in the file can be accessed using one of the key options of the record I/O statements: KEY, KEYTO, or KEYFROM. You need not specify the KEYED attribute unless one of the key options is used. KEYED is implied by use of the DIRECT attribute. Syntax ────KEYED─────────────────────────────────── ═══ PRINT Attribute ═══ Description The PRINT attribute applies to files with the STREAM and OUTPUT attributes. Use the PRINT attribute to indicate that a file is intended to be printed. In other words, the data associated with the file is to appear on printed pages. Usage Rules Consider the following rules when using the PRINT attribute:  PRINT applies only to files with the STREAM and OUTPUT attributes.  The additive attribute PRINT can be implied by the output file name SYSPRINT.  When PRINT is specified, the first data byte of each record of a PRINT file is reserved for an American National Standard (ANS) printer control character. The control characters are inserted by the compiler.  Data values transmitted by list- and data-directed data transmission are automatically aligned on the left margin and on implementation-defined preset tab positions. These tab positions are 25, 49, 73, 97, and 121, but provision is made for you to alter these values. Related Information PRINT file options and format items Example Using PRINT file options and format items Syntax ───────PRINT──────── ═══ PRINT File Options and Format Items ═══ You can control the layout of a PRINT file by the use of options and format items listed below: ┌──────────┬─────────────┬───────────────┬──────────────────────────────────────┐ │ │ Statement │ Edit-Directed │ │ │Statement │ Option │ Format Item │ Effect │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │OPEN │ LINESIZE(n) │ - │ Establishes line width (n) │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │OPEN │ PAGESIZE(n) │ - │ Establishes page length (n) │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │PUT │ PAGE │ PAGE │ Skip to new page │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │PUT │ LINE(n) │ LINE(n) │ Skip to specified line (n) │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │PUT │ SKIP[(n)] │ SKIP[(n)] │ Skip specified number of lines (n) │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │PUT │ - │ COLUMN(n) │ Skip to specified character position │ │ │ │ │ in line (n) │ ├──────────┼─────────────┼───────────────┼──────────────────────────────────────┤ │PUT │ - │ X(n) │ Places blank characters (n) in line │ │ │ │ │ to establish position │ └──────────┴─────────────┴───────────────┴──────────────────────────────────────┘ Note: LINESIZE and PAGESIZE establish the dimensions of the printed area of the page, excluding footings. The LINESIZE option specifies the maximum number of characters included in each printed line. If it is not specified for a PRINT file, a default value of 120 characters is used. There is no default for a non-PRINT file. The PAGESIZE option specifies the maximum number of lines in each printed page; if it is not specified, a default value of 60 lines is used. ═══ Example- PRINT File Options and Format Items ═══ The following example illustrates the use of PRINT file options and format items: OPEN FILE(REPORT) OUTPUT STREAM PRINT PAGESIZE(55) LINESIZE(110); ON ENDPAGE(REPORT) BEGIN; PUT FILE(REPORT) SKIP LIST (FOOTING); PAGENO = PAGENO + 1; PUT FILE(REPORT) PAGE LIST ('PAGE '||PAGENO); PUT FILE(REPORT) SKIP (3); END; The OPEN statement opens the file REPORT as a PRINT file. The specification PAGESIZE(55) indicates that each page contains a maximum of 55 lines. An attempt to write on a page after 55 lines have already been written (or skipped) raises the ENDPAGE condition. The implicit action for the ENDPAGE condition is to skip to a new page, but you can establish your own action through use of the ON statement, as shown in the example. LINESIZE(110) indicates that each line on the page can contain a maximum of 110 characters. An attempt to write a line greater than 110 characters places the excess characters on the next line. When an attempt is made to write on line 56 (or to skip beyond line 55), the ENDPAGE condition is raised, and the begin block shown here is executed. The ENDPAGE condition is raised only once per page. Consequently, printing can be continued beyond the specified PAGESIZE after the ENDPAGE condition has been raised. This can be useful, for example, if you want to write a footing at the bottom of each page. The first PUT statement specifies that a line is skipped, and the value of FOOTING, presumably a character string, is printed on line 57 (when ENDPAGE is raised, the current line is always PAGESIZE+1). The page number, PAGENO, is incremented, the file REPORT is set to the next page, and the character constant "PAGE" is concatenated with the new page number and printed. The final PUT statement skips three lines, so that the next printing will be on line 4. Control returns from the begin block to the PUT statement that raised the ENDPAGE condition. However, any SKIP or LINE option specified in that statement has no further effect. ═══ GRAPHIC Option ═══ Description You specify the GRAPHIC option of the ENVIRONMENT attribute if you use DBCS variables or DBCS constants in GET and PUT statements for list- and data-directed I/O. The GRAPHIC option of the ENVIRONMENT attribute must be specified if any variable has a DBCS name, even if no DBCS data is present. You can also specify the GRAPHIC option for edit-directed I/O. The ERROR condition is raised for list- and data-directed I/O if you have graphics in input or output data and do not specify the GRAPHIC option. For edit-directed I/O, the GRAPHIC option specifies that left and right delimiters are added to DBCS variables and constants on output, and that input graphics will have left and right delimiters. If you do not specify the GRAPHIC option, left and right delimiters are not added to output data, and input graphics do not require left and right delimiters. When the GRAPHIC option is specified, the ERROR condition is raised if left and right delimiters are missing from the input data. Syntax ─────GRAPHIC──────────────────────────────────── ═══ SCALARVARYING Option ═══ Description Use the SCALARVARYING option in the input/output of varying-length strings. When storage is allocated for a varying-length string, a 2-byte prefix that specifies the current length of the string is included. For an element varying-length string, the prefix is included on output, or recognized on input, only if SCALARVARYING is specified for the file. When locate-mode statements (LOCATE and READ SET) are used to create and read a data set with element varying-length strings, you must specify SCALARVARYING to indicate that a length prefix is present, since the pointer that locates the storage area that contains the string is always assumed to point to the start of the length prefix. When you specify SCALARVARYING and element varying-length strings are transmitted, you must allow two bytes in the record length to include the length prefix. A data set created using SCALARVARYING should be accessed only by a file that also specifies SCALARVARYING. You must not specify SCALARVARYING and CTLASA/CTL360 for the same file, as this causes the first data byte to be ambiguous. Syntax ────SCALARVARYING─────────────────────────────────── ═══ Opening and Closing Files ═══ Description Before a file can be used for data transmission, by input or output statements, it must be associated with a data set. Opening a file associates a file with a data set and involves checking for the availability of external storage media, positioning the media, and allocating appropriate operating system support. When processing is completed, the file must be closed. Closing a file dissociates the file from the data set. PL/I provides two statements, OPEN and CLOSE, to perform these functions. However, these statements are optional. Implicit opening and closing may occur. Related Information  OPEN statement  CLOSE statement ═══ OPEN Statement ═══ Description Use the OPEN statement to associate a file with a data set or terminal. The OPEN statement merges its own attributes with those specified on the DECLARE statement. OPEN also completes the specification of attributes for the file, if a complete set of attributes has not been declared for the file being opened. When a STREAM file is opened, if the first GET or PUT specifies, by means of a statement option or format item, that n lines are to be skipped before the first record is accessed, the file is then positioned at the start of the nth record. Otherwise, it is positioned at the start of the first line or record. If the file has the PRINT attribute, it is physically positioned at column 1 of that line. If you open an already-open file, it does not affect the file. Related Information  Attribute merging for explicit opening  Implicit opening of files  OPEN statement Options Syntax ┌────────,────────┐  │ ────OPEN─────options-group──┴────;───────────────────────────── where options-group is: ┌─STREAM─┐ ──────FILE──(──file-reference──)─────┼────────┼───────────────── └─RECORD─┘ ┌──INPUT───┐ ─────┼──────────┼───┬──────────────┬───┬──────────────┬────────── ├──OUTPUT──┤ ├──DIRECT──────┤ ├──BUFFERED────┤ └──UPDATE──┘ ├──SEQUENTIAL──┤ └──UNBUFFERED──┘ └──TRANSIENT───┘ ─────┬───────────┬──────┬───────────┬──────────────────────────── └─BACKWARDS─┘ └─EXCLUSIVE─┘ ─────┬─────────┬───┬─────────┬───┬───────────────────────────┬─── └──KEYED──┘ └──PRINT──┘ └──TITLE──(──expression──)──┘ ─────┬──────────────────────────────┬──────────────────────────── └──LINESIZE──(──expression──)──┘ ─────┬──────────────────────────────┬─────────────────────────── └──PAGESIZE──(──expression──)──┘ ═══ PAGESIZE Option ═══ PAGESIZE (expression) is evaluated and converted to an integer value, and specifies the number of lines per page. The first attempt to exceed this limit raises the ENDPAGE condition. During subsequent transmission to the PRINT file, a new page can be started by use of the PAGE format item or by the PAGE option in the PUT statement. The default page size is 60. You can specify the PAGESIZE option only for a file with the STREAM and PRINT attributes. Syntax ─────PAGESIZE─(expression)───── ═══ OPEN Statement Options ═══ Description The STREAM, RECORD, INPUT, OUTPUT, UPDATE, DIRECT, SEQUENTIAL, TRANSIENT, BUFFERED, UNBUFFERED, BACKWARDS , EXCLUSIVE, KEYED, and PRINT options specify attributes that augment the attributes specified in the file declaration. You need not list the same attributes for both OPEN and DECLARE statements for the same file, and there must be no conflict of attributes. ═══ TITLE Specification ═══ TITLE is converted to a character string, if necessary. The first 8 characters of the character string identify the data set associated with the file. If the TITLE option does not appear, the default uses the first 8 characters of the file name (padded or truncated). This is not the same truncation as that for external names. Syntax ─────TITLE─(expression)───── ═══ LINESIZE Option ═══ Description LINESIZE is converted to an integer value, and specifies the length (in bytes) of a line during subsequent operations on the file. You start new lines by use of the printing and control format items or by options in a GET or PUT statement. If an attempt is made to position a file past the end of a line before explicit action to start a new line is taken, a new line is started, and the file is positioned to the start of this new line. The default line size for PRINT file is 120. Usage Rules You can specify the LINESIZE option only for a STREAM OUTPUT file. Whenever you use a SKIP option in a GET statement, the line size taken into consideration is the line size that was used to create the data set. Otherwise, the line size is taken as the current length of the logical record minus any control bytes. Syntax ─────LINESIZE─(expression)───── ═══ Implicit Opening of Files ═══ Description An implicit opening of a file occurs when a GET, PUT, READ, WRITE, LOCATE, REWRITE, DELETE, or UNLOCK statement is executed for a file for which an OPEN statement has not already been executed. If a GET statement contains a COPY option, execution of the GET statement can cause implicit opening of either the file specified in the COPY option or, if no file was specified, of the output file SYSPRINT. Implicit opening of the file specified in the COPY option implies the STREAM and OUTPUT attributes. Related Information Implied attributes Examples  Declaring and opening files  Implicit opening ═══ Implied Attributes ═══ The following list shows the attributes that are implied when an implicit opening is caused by the statement in the left-hand column: ┌──────────┬──────────────────────────────────────────┐ │Statement │ Implied Attributes │ ├──────────┼──────────────────────────────────────────┤ │GET │ STREAM, INPUT │ │PUT │ STREAM, OUTPUT │ │READ │ RECORD, INPUT (see below) │ │WRITE │ RECORD, OUTPUT (see below) │ │LOCATE │ RECORD, OUTPUT, BUFFERED, SEQUENTIAL │ │REWRITE │ RECORD, UPDATE │ │DELETE │ RECORD, UPDATE │ │UNLOCK │ RECORD, DIRECT, UPDATE, EXCLUSIVE │ └──────────┴──────────────────────────────────────────┘ Note: INPUT and OUTPUT are default attributes for READ and WRITE statements only if UPDATE has not been explicitly declared. An implicit opening by one of the above statements is equivalent to preceding the statement with an OPEN statement that specifies the same attributes. There must be no conflict between the attributes specified in a file declaration and the attributes implied as the result of opening the file. The attribute implications listed below are applied prior to the application of the default attributes discussed earlier. Implied attributes can also cause a conflict. If a conflict in attributes exists after the application of default attributes, the UNDEFINEDFILE condition is raised. Following is a list of merged attributes and attributes that each implies after merging: ┌──────────────────┬───────────────────────────┐ │Merged Attributes │Implied Attributes │ ├──────────────────┼───────────────────────────┤ │UPDATE │RECORD │ │SEQUENTIAL │RECORD │ │DIRECT │RECORD, KEYED │ │BUFFERED │RECORD │ │UNBUFFERED │RECORD │ │PRINT │OUTPUT, STREAM │ │BACKWARDS │RECORD, SEQUENTIAL, INPUT │ │KEYED │RECORD │ │EXCLUSIVE │RECORD │ └──────────────────┴───────────────────────────┘ ═══ Attribute Merging for Explicit Opening ═══ The following two examples illustrate attribute merging for an explicit opening using a file constant and a file variable.  Example of a file constant: DECLARE LISTING FILE STREAM; OPEN FILE(LISTING) PRINT; Attributes after merge caused by execution of the OPEN statement are STREAM and PRINT. Attributes after implication are STREAM, PRINT, and OUTPUT. Attributes after default application are STREAM, PRINT, OUTPUT, and EXTERNAL.  Example of a file variable: DECLARE ACCOUNT FILE VARIABLE, (ACCT1,ACCT2,...) FILE OUTPUT; ACCOUNT = ACCT1; OPEN FILE(ACCOUNT) PRINT; ACCOUNT = ACCT2; OPEN FILE(ACCOUNT) RECORD; The file ACCT1 is opened with attributes (explicit and implied) STREAM, EXTERNAL, PRINT, and OUTPUT. The file ACCT2 is opened with attributes RECORD, EXTERNAL, OUTPUT and SEQUENTIAL. ═══ Declaring and Opening Files ═══ The following are examples of declarations of file constants including the ENVIRONMENT attribute: DECLARE FILE#3 INPUT DIRECT ENVIRONMENT(V BLKSIZE(328) REGIONAL(3)); This declaration specifies three file attributes: INPUT, DIRECT, and ENVIRONMENT. Other implied attributes are FILE (implied by any of the attributes) and RECORD and KEYED (implied by DIRECT). Scope is EXTERNAL, by default. The ENVIRONMENT attribute specifies that the data set is of the REGIONAL(3) organization and contains unblocked varying-length records with a maximum length of 328 bytes. A maximum length record will contain only 320 bytes of data used by the program, because 8 bytes are required for control information in V-format records. The KEY option must be specified in each READ statement that refers to this file. DECLARE INVNTRY UPDATE BUFFERED ENVIRONMENT (F RECSIZE(100) INDEXED BUFFERS(4)); This declaration also specifies three file attributes: UPDATE, BUFFERED, and ENVIRONMENT. Other implied attributes are FILE (implied by any of the attributes) and RECORD and KEYED (implied by DIRECT). Scope is EXTERNAL, by default. The data set is of INDEXED organization, and contains fixed-length records of 100 bytes each. Four buffers are allocated for use in accessing the data set. Note that, although the data set actually contains recorded keys, the KEYTO option cannot be specified in a READ statement, since the KEYED attribute has not been specified. For both of the above declarations, all necessary attributes are either stated or implied in the DECLARE statement. None of the attributes can be changed in an OPEN statement or in a DD statement. The second declaration might also be written: DECLARE INVNTRY ENVIRONMENT(F RECSIZE(100) INDEXED); With such a declaration, INVNTRY can be opened for different purposes. For example: OPEN FILE (INVNTRY) UPDATE SEQUENTIAL BUFFERED; With this OPEN statement, the file attributes are the same as those specified (or implied) in the DECLARE statement in the second example above (the number of buffers would have to be stated in the associated DD statement). The file might be opened in this way, then closed, and then later opened with a different set of attributes. For example: OPEN FILE (INVNTRY) INPUT SEQUENTIAL KEYED; This OPEN statement allows records to be read with either the KEYTO or the KEY option. Because the file is SEQUENTIAL, and the data set is INDEXED, the data set can be accessed in a purely sequential manner. It can also be accessed randomly by means of a READ statement with a KEY option. A READ statement with a KEY option for a file of this description obtains a specified record. Subsequent READ statements without a KEY option access records sequentially, beginning with the next record. ═══ CLOSE Statement ═══ Description Use the CLOSE statement to dissociate the file from its data set. The CLOSE statement also dissociates from the file all attributes established for it by the implicit or explicit opening process. You can specify new attributes for the file constant in a subsequent OPEN statement. However, all attributes explicitly given to the file constant in a DECLARE statement remain in effect. Usage Rules Consider the following rules when closing files with CLOSE:  Closing an already-closed file has no effect.  A closed file can be reopened.  If a file is not closed by a CLOSE statement, it is closed at the completion of the main program.  All input/output events associated with the file that have a status value of zero when the file is closed are set to complete, with a status value of 1. Syntax ┌─,─────────────────────────────────────────────────────────────────┐  │ ───CLOSE─────FILE──(──file-reference──)───┬─────────────────────────────────┬──┴────;─── └─ENVIRONMENT─(──┬─LEAVE──┬───)───┘ └─REREAD─┘ ═══ Using the SYSPRINT File ═══ Description The file SYSPRINT, unless it is declared explicitly, is given the attribute PRINT. A new page is initiated automatically when the file is opened. If the first PUT statement that refers to the file has the PAGE option, or if the first PUT statement includes a format list with the PAGE as the first item, a blank page appears. Example If the following statement is executed: PUT SKIP LIST('Hello out there!'); the "Hello out there!" string gets put to SYSPRINT. Assuming an association between SYSPRINT and the user's terminal, the user would see the "Hello out there!" string displayed on the terminal. Because SYSPRINT serves as a default stream output file, the following statement is functionally equivalent to the preceding one: PUT FILE(SYSPRINT) LIST('Hello out there!); ═══ Using Record-Oriented Data Transmission ═══ Description In record-oriented data transmission, data in a data set is a collection of records recorded in any format acceptable to the operating system. No data conversion is performed during record-oriented data transmission. Use data transmission statements to transmit records to or from auxiliary storage. On input, the READ statement either transmits a single record to a program variable exactly as it is recorded in the data set, or sets a pointer to the record. On output, the WRITE, REWRITE, or LOCATE statement transmits a single record from a program variable exactly as it is recorded internally. Most variables can be transmitted by record-oriented data transmission. However, there are restrictions placed on certain data types. Record-oriented data transmission has two modes of handling data:  Move mode: you can process data by having the data moved into or out of the variable  Locate mode: you can process data by locating a record. The execution of a data transmission statement assigns to a pointer variable the location of the storage allocated to a record in the buffer. LOCATE mode is applicable only to BUFFERED files. The file must be either a SEQUENTIAL file or an INPUT or UPDATE file associated with a VSAM data set. Related Information  Rules for data types  MOVE mode for record-oriented data transmission  LOCATE mode for record-oriented data transmission  Data transmission statements  Options of data transmission statements ═══ Rules for Data Types ═══ Description Most variables, including parameters and DEFINED variables, can be transmitted by record-oriented data transmission statements. There are special considerations for several types of data, and these are given below. Data Aggregates An aggregate must be in connected storage. Unaligned Bit Strings The following cannot be transmitted:  BASED, DEFINED, parameter, subscripted, or structure-base-element variables that are unaligned fixed-length bit strings  Minor structures whose first or last base elements are unaligned fixed-length bit strings (except where they are also the first or last elements of the containing major structure)  Major structures that have the DEFINED attribute or are parameters, and that have unaligned fixed-length bit strings as their first or last elements. Varying-Length Strings A locate mode output statement specifying a varying-length string transmits a field having a length equal to the maximum length of the string, plus a 2-byte prefix denoting the current length of the string. You must specify the SCALARVARYING option of the ENVIRONMENT attribute for the file. A move mode output statement specifying a varying-length string variable transmits only the current length of the string. A 2-byte prefix is included only if the SCALARVARYING option of the ENVIRONMENT attribute is specified for the file. Graphic Strings If you specify a graphic string for input or output, you must specify the SCALARVARYING option for the file. Area Variables A locate mode output statement specifying an area variable transmits a field whose length is the declared size of the area, plus a 16-byte prefix containing control information. A move mode statement specifying an element area variable or a structure whose last element is an area variable transmits only the current extent of the area plus a 16-byte prefix. ═══ Move Mode for Record-Oriented Data Transmission ═══ Description In move mode, use a READ statement to transfer a record from external storage to the variable named in the INTO option. Use a WRITE or REWRITE statement to transfer a record from the variable named in the FROM option to external storage. The variables you name in the INTO and FROM options can be of any storage class. Example The following is an example of move mode input: EOF_IN = '0'B; ON ENFILE(IN) EOF_IN = '1'B; READ FILE(IN) INTO(DATA); DO WHILE (кEOF_IN); . . /* process record */ . READ FILE(IN) INTO(DATA); END; ═══ Locate Mode for Record-Oriented Data Transmission ═══ Description You use locate mode to assign the location of the next record to a pointer variable. A based variable describes the record. The same data can be interpreted in different ways by using different based variables. You can also use locate mode to read self-defining records, in which information in one part of the record is used to indicate the structure of the rest of the record. For example, this information could be an array bound or a code identifying which based structure should be used for the attributes of the data. Use a READ statement with a SET option to set the pointer variable in the SET option to point to the next record. The data in the record can then be referenced by a based variable qualified with the pointer variable. The pointer value is valid only until the execution of the next READ or CLOSE statement that refers to the same file. The LOCATE statement is used for output from a buffer for SEQUENTIAL files. A LOCATE statement allocated storage, within an output buffer for a based variable, and does the following: 1. Transfers a block of data to the data set from an output buffer, if the current block is complete. 2. Sets a pointer variable to the location in the buffer of the next output record. The pointer variable specified in the SET option, or if SET was omitted, the pointer variable specified in the declaration of the based variable, is used. The pointer value is valid only until the execution of the next LOCATE, WRITE, or CLOSE statement that refers to the same file. 3. Initializes components of the based variable that have been specified in REFER options. After execution of the LOCATE statement, values can be assigned directly into the output buffer by referencing based variables qualified by the pointer variable set by the LOCATE statement. If the current block is complete, the next LOCATE, WRITE, or CLOSE statement for the same file transmits the data in the output buffer to the data set. Care is necessary when using the LOCATE statement with device-associated files, where a number of files are grouped together. No data transmission can take place after any one of the group has been closed. Examples Locate mode input/output ═══ Examples- Locate Mode Input/Output ═══  The following example shows locate mode input: DCL 1 DATA BASED(P), 2 ... ; EOF_IN = '0'B; ON ENDFILE(IN) EOF_IN = '1'B; READ FILE(IN) SET(P); DO WHILE (кEOF_IN); . . /* process record */ . READ FILE(IN) SET(P); END;  The following example shows locate mode output: DCL 1 DATA BASED(P); 2 ... ; DO WHILE (MORE_RECORDS_TO_WRITE); LOCATE DATA FILE(OUT); . . /* build record */ . END; ═══ Data Transmission Statements ═══ Description The data transmission statements that you use to transmit records to or from auxiliary storage are READ, WRITE, LOCATE, and REWRITE. Use the DELETE statement to delete records from an UPDATE file. The attributes of the file determine which data transmission statements can be used. Related Information  DELETE statement  LOCATE statement  READ statement  REWRITE statement  WRITE statement ═══ READ Statement ═══ Description The READ statement can be used with any INPUT or UPDATE file. It either transmits a record from the data set to the program variable or sets a pointer to the record in storage. Syntax ────READ FILE──(──file─reference──)─────────────────────────────── ───┬─INTO─(ref)─┬──────────────────────────────────┬────┬────────── │ ├─KEY──(─expression─)──┬────────┬──┤ │ │ │ └─NOLOCK─┘ │ │ │ │ │ │ │ └─KEYTO──(──reference──)───────────┘ │ ├──SET─(pointer─ref)─┬─────────────────────────┬─────┤ │ ├─KEY──(──expression──)───┤ │ │ └─KEYTO──(──reference──)──┘ │ │ │ │ └──IGNORE──(──expression──)──────────────────────────┘ ────┬────────────────────────┬──;────────────────────────────────── └─EVENT─(──reference──)──┘ Note: The keywords can appear in any order. A READ statement without an INTO, SET, or IGNORE option is equivalent to a READ with an IGNORE(1). The option NOLOCK is MVS only. ═══ WRITE Statement ═══ Description The WRITE statement can be used with any OUTPUT file or DIRECT UPDATE file, and also with SEQUENTIAL UPDATE files associated with VSAM data sets. Use the WRITE statement to transmit a record from the program and add it to the data set. For unblocked records, transmission can be directly from a variable or from a buffer. For blocked records, the WRITE statement places a logical record into a buffer; only when the blocking of records is complete is there actual transmission of data to an output device. Syntax ──WRITE──FILE──(──file─reference──)──FROM──(──reference──)─── ───┬─────────────────────────────┬──────────────────────────── ├──KEYFROM──(──expression──)──┤ └──KEYTO──(──reference──)─────┘ ───┬───────────────────────────────┬─────;──────────────────── └─EVENT─(──event-reference──)───┘ Note: The keywords can appear in any order. ═══ REWRITE Statement ═══ Description Use the REWRITE statement to replace a record in an UPDATE file. For SEQUENTIAL UPDATE files, the REWRITE statement specifies that the last record read from the file is to be rewritten; consequently a record must be read before it can be rewritten. For DIRECT UPDATE files, and for KEYED SEQUENTIAL UPDATE files associated with VSAM data sets, any record can be rewritten whether or not it has first been read. You must specify the FROM option for UPDATE files having either the DIRECT attribute or both the SEQUENTIAL and UNBUFFERED attributes. A REWRITE statement that does not specify the FROM option has the following effect:  If the last record was read by a READ statement with the INTO option, REWRITE without FROM has no effect on the record in the data set.  If the last record was read by a READ statement with the SET option, the record is updated by whatever assignments were made to the variable identified by the pointer variable in the SET option. Syntax ────REWRITE──FILE──(──file─reference──)──┬─────────────────────────┬── └──FROM──(──reference──)──┘ ─────┬────────────────────────┬───────────────────────────────────── └──KEY──(──expression──)─┘ ─────┬──────────────────────────┬──────────;───────────────────────── └─EVENT──(event-reference)─┘ Note: The keywords can appear in any order. ═══ LOCATE Statement ═══ Description Use the LOCATE statement only with an OUTPUT SEQUENTIAL BUFFERED file for locate mode processing. LOCATE sets a pointer to the location of the next record. Syntax ────LOCATE──based-variable───FILE──(──file-reference──)───── ─────┬───────────────────────────────┬────────────────────── └─SET──(──pointer-reference──)──┘ ─────┬────────────────────────────┬───;───────────────────── └─KEYFROM──(──expression──)──┘ Note: The keywords can appear in any order. ═══ DELETE Statement ═══ Description Use the DELETE statement to delete a record from an UPDATE file. Under MVS, for a SEQUENTIAL UPDATE file for an INDEXED data set or a VSAM KSDS or RRDS, if the KEY option is omitted, the record to be deleted is the last record that was read. Under CMS, for a SEQUENTIAL UPDATE file for a VSAM KSDS, if the KEY option is omitted, the record to be deleted is the last record that was read. Syntax ────DELETE───FILE──(──file-reference──)──── ─────┬────────────────────────┬──────────── └─KEY──(──expression──)──┘ ─────┬────────────────────────────┬──;──── └─EVENT──(─event-reference─)─┘ Note: The keywords can appear in any order. ═══ Options of Data Transmission Statements ═══ Description Options that are allowed for record-oriented data transmission statements differ according to the attributes of the file and the characteristics of the associated data set. Following is a list of the options for data transmission statements:  FILE option  INTO option  FROM option  SET option  IGNORE option  KEY option  KEYFROM option  KEYTO option  EVENT option  NOLOCK option ═══ FILE Option ═══ Description You must use the FILE option in every record-oriented data transmission statement. The FILE option specifies the file upon which the operation takes place. Implicit opening of files will occur if the file specified is not open. Syntax ─────FILE─(file-reference)───── ═══ FROM Option ═══ Description Use the FROM option to specify the element or aggregate variable from which the record is written. You must use the FROM option in the WRITE statement for any OUTPUT or DIRECT UPDATE file. It can also be used in the REWRITE statement for any UPDATE file. If the variable is an aggregate, it must be in connected storage. Certain uses of unaligned fixed-length bit strings are disallowed. You must follow rules for data types. The FROM variable can be an element string variable of varying length. When using a WRITE statement with the FROM option, only the current length of a varying-length string is transmitted to a data set, and a 2-byte prefix specifying the length can be attached. It is attached only if the SCALARVARYING option of the ENVIRONMENT attribute is specified for the file. Records are transmitted as an integral number of bytes. Therefore, if a bit string (or a structure that starts or ends with a bit string) that is not aligned on a byte boundary is transmitted, the record will contain bits at the start or at the end that are not part of the string. The FROM option can be omitted from a REWRITE statement for SEQUENTIAL BUFFERED UPDATE files. If the last record was read by a READ statement with the INTO option, REWRITE without FROM has no effect on the record in the data set. If the last record was read by a READ statement with the SET option, the record (updated by whatever assignments were made) is copied back onto the data set. Examples Using the FROM option Syntax ─────FROM─(reference)───── ═══ Examples- Using the FROM Option ═══ In the following examples, the statements specify that the value of the variable MAS_REC is written into the file MASTER.  The following WRITE statement specifies a new record in a SEQUENTIAL OUTPUT file: WRITE FILE (MASTER) FROM (MAS_REC);  The following REWRITE statement specifies that MAS_REC replaces the last record read from a SEQUENTIAL UPDATE file: REWRITE FILE (MASTER) FROM (MAS_REC); ═══ IGNORE Option ═══ Description You can use the IGNORE option in a READ statement for any SEQUENTIAL INPUT or SEQUENTIAL UPDATE file. The expression in the IGNORE option is evaluated and converted to an integer value n. If n is greater than zero, n records are ignored. A subsequent READ statement for the file will access the (n+1)th record. If n is less than 1, the READ statement has no effect. The IGNORE option cannot be used with a TRANSIENT file. Example The following example specifies that the next three records in the file are to be ignored: READ FILE (IN) IGNORE (3); Syntax ─────IGNORE─(expression)───── ═══ INTO Option ═══ Description Use the INTO option to specify an element or aggregate variable into which the logical record is read. You can use the INTO option in the READ statement for any INPUT or UPDATE file. If the variable is an aggregate, it must be in connected storage. You must follow rules for data types. The INTO variable can be an element string variable of varying length. If the SCALARVARYING option of the ENVIRONMENT attribute was specified for the file, each record contains a 2-byte prefix that specifies the length of the string data. If SCALARVARYING was not declared then, on input, the string length is calculated from the record length and attached as a 2-byte prefix. For varying-length bit strings, this calculation rounds up the length to a multiple of 8 and therefore the calculated length might be greater than the maximum declared length. Example The following example specifies that the next sequential record is read into the variable RECORD_1: READ FILE (DETAIL) INTO (RECORD_1); Syntax ─────INTO─(reference)───── ═══ KEY Option ═══ Description Use the KEY option to specify a character or graphic key that identifies a record. You can use the KEY option in a READ statement for an INPUT or UPDATE file, or in a REWRITE statement for a DIRECT UPDATE file. The KEY option applies only to KEYED files associated with data sets of INDEXED, REGIONAL, or VSAM organization. The KEY option is required if the file has the DIRECT attribute. The KEY option can also appear for a file having INDEXED or VSAM organization and the SEQUENTIAL and KEYED attributes. The expression in the KEY option is evaluated and, if not character or graphic, is converted to a character value that represents a key. It is this character or graphic value that determines which record is read. Example The following example specifies that the record identified by the character value of the variable STKEY is read into the variable ITEM: READ FILE (STOCK) INTO (ITEM) KEY (STKEY); Syntax ─────KEY─(expression)───── ═══ KEYFROM Option ═══ Description The KEYFROM option specifies a character or graphic key that identifies the record on the data set, or (for TRANSIENT files) the terminal to which the message or the record is transmitted. It can be used in a WRITE statement for a SEQUENTIAL OUPUT or DIRECT UPDATE file or a DIRECT OUTPUT file that has REGIONAL organization, or in a LOCATE statement. It can also be used in a WRITE statement for a KEYED SEQUENTIAL UPDATE file associated with a VSAM data set. The KEYFROM option applies only to KEYED files associated with data sets of INDEXED, REGIONAL, or VSAM organization, or to TRANSIENT files. The expression is evaluated and, if not character or graphic, is converted to a character string and is used as the key of the record when it is written. REGIONAL(1) data sets can be created using the KEYFROM option. The region number is specified as the key. For REGIONAL(2), REGIONAL(3),and INDEXED data sets, KEYFROM specifies a recorded key whose length is determined by the KEYLEN subparameter or the KEYLENGTH option. Example The following example specifies that the value of LOANREC is written as a record in the file LOANS, and that the character string value of LOANNO is used as the key with which it can be retrieved: WRITE FILE (LOANS) FROM (LOANREC) KEYFROM (LOANNO); Syntax ─────KEYFROM─(expression)───── ═══ KEYTO Option ═══ Description The KEYTO option specifies a character or graphic key that identifies the record on the data set, or (for TRANSIENT files) the terminal to which the message or record is transmitted. The KEYTO option can specify any string pseudovarible other than STRING. It cannot specify a variable declared with a numeric picture specification. The KEYTO option can be used in a READ statement for a SEQUENTIAL INPUT, SEQUENTIAL UPDATE, or TRANSIENT INPUT file. The KEYTO option applies only to KEYED files associated with data sets of INDEXED, REGIONAL, or VSAM organization, or to TRANSIENT files. Assignment to the KEYTO variable always follows assignment to the INTO variable. If an incorrect key specification is detected, the KEY condition is raised. For this implementation, the value assigned is as follows:  For REGIONAL(1), the 8-character region number, padded or truncated on the left to the declared length of the character variable. If the character variable is of varying length, any leading zeros in the region number are truncated and the string length is set to the number of significant digits. An all-zero region number is truncated to a single zero.  For REGIONAL(2) and REGIONAL(3), the recorded key without the region number, padded or truncated on the right to the declared length of the character variable.  For INDEXED and for key-sequenced VSAM, the recorded key, padded or truncated on the right to the declared length of the character variable.  For entry-sequenced VSAM data sets (ESDS), a 4-character relative-byte address (RBA), padded or truncated on the right to the declared length of the character variable.  For relative-record VSAM data sets (RRDS), an 8-character relative-record number with leading zeros suppressed, truncated or padded on the left to the declared length of the character variable. The KEY condition is not raised for this type of padding or truncation. The KEYTO option can also be used in a WRITE statement for a SEQUENTIAL OUTPUT or SEQUENTIAL UPDATE file associated with a VSAM entry-sequenced or relative- record data set. Example The following example specifies that the next record in the file DETAIL is read into the variable INVTRY, and that the key of the record is read into the variable KEYFLD: READ FILE (DETAIL) INTO (INVTRY) KEYTO (KEYFLD); Syntax ─────KEYTO─(reference)───── ═══ SET Option ═══ Description You can use the SET option with a READ statement or a LOCATE statement. For the READ statement, it specifies a pointer variable that is set to point to the record read. For the LOCATE statement, it specifies a pointer variable that is set to point to the next record for output. If the SET option is omitted for the LOCATE statement, the pointer declared with the record variable is set. If an element string variable of varying-length is transmitted, the SCALARVARYING option must be specified for the file. Example The following example specifies that the value of the pointer variable P is set to the location of the next sequential record: READ FILE (X) SET (P); Syntax ─────SET─(pointer-reference)───── ═══ EVENT Option ═══ Description The EVENT option specifies that the input or output operation takes place asynchronously (that is, while other processing continues) and that no I/O conditions (except for UNDEFINEDFILE) are raised until a WAIT statement, specifying the same event variable is executed. The EVENT option can appear in any READ, WRITE, REWRITE, or DELETE statement for an UNBUFFERED file with CONSECUTIVE or REGIONAL organization or for any DIRECT file. The EVENT option cannot be used with a TRANSIENT file. A name declared implicitly that appears in an EVENT option is given the EVENT attribute. When any expressions in the options of the statement have been evaluated, the input operation is started, and the event variable is made active (that is, the variable cannot be associated with another event) and is given the completion value '0'B and zero status value, provided that the UNDEFINEDFILE condition is not raised by an implicit file opening. The sequence of these two assignments is uninterruptible and is completed before any transmission is initiated but after any action associated with an implicit opening is completed. As soon as this has happened, the statements following are executed. Any RECORD, TRANSMIT, KEY, or ENDFILE condition is not raised until control reaches the WAIT statement. The event variable remains active and retains its '0'B completion value until control reaches a WAIT statement specifying that event variable, or until termination of the application program. When the WAIT statement is executed, any of the following can occur:  If the input/output operation is not complete, and if none of the four conditions is raised, execution of further statements is suspended until the operation is complete.  If the input/output operation is executed successfully and none of the conditions ENDFILE, TRANSMIT, KEY, or RECORD is raised as a result of the operation, the event variable is made inactive (that is, it can be associated with another event).  Any ENDFILE, TRANSMIT, KEY, or RECORD conditions for the input/output operation are raised when the WAIT is encountered. At such a time, the event variable is set to have a status value of 1 and the corresponding ON-units (if any) are entered in the order in which the conditions were raised. After a return from the final ON-unit, or if one of the ON-units is terminated by a GO TO statement (abnormal return), the event variable is given the completion value '1'B and is made inactive. If some of the event variables in the WAIT list are associated with input/output operations and have not been set complete before the WAIT is terminated (either because enough events have been completed or due to an abnormal return), these incomplete events are not set complete until the execution of another WAIT referring to these events. Note: If the statement causes an implicit file opening that results in the raising of the UNDEFINEDFILE condition, the ON-unit associated with this condition is entered immediately and the event variable remains inactive and retains the same value it had when the statement was encountered. If the ON-unit does not correct the condition, then, upon normal return from the ON-unit the ERROR condition is raised. If the condition is corrected in the ON-unit, that is, if the file is opened successfully, upon normal return from the ON-unit, the event variable is set to '0'B, it is made active, and execution of the statement continues. Upon normal return from any ON-units entered, processing continues with the next statement following the WAIT statement. For consecutive and regional sequential files, only one outstanding input/output operation is allowed for a file unless a higher number is specified in the NCP option of the ENVIRONMENT attribute or DCB subparameter. The ERROR condition is raised if an attempt is made to initiate an input/output operation on a file in excess of the number allowed, while a previous input/output operation has not been waited for. Under CMS, the EVENT option can be used only if the NCP parameter is included in the ENVIRONMENT option of the file. Example The following example shows how to use the EVENT option: READ FILE (MASTER) INTO (REC_VAR) EVENT (RECORD_1); . . . WAIT (RECORD_1); ═══ NOLOCK Option ═══ Decsription The NOLOCK option can be used in a READ statement that refers to an EXCLUSIVE file. It specifies that the record accessed by the READ statement will not be locked between completion of a READ statement and commencement of the corresponding REWRITE. The record will continue to be available to other MVS tasks, in addition to that which issued the READ statement. Note: The NOLOCK option is for MVS only. ═══ Using Stream-Oriented Data Transmission ═══ Description Stream-oriented data transmission treats a data set as a continuous stream of data values in character, graphic, or mixed data form. Within a program, block and record boundaries are ignored. However, a data set consists of a series of lines of data, and each data set created or accessed by stream-oriented data transmission has a line size associated with it. In general, a line is equivalent to a record in the data set; however, the line size does not necessarily equal the record size. Stream-oriented data transmission uses only one input statement (GET) and one output statement (PUT). Stream-oriented data transmission can be list-directed, data-directed, or edit-directed: List-directed data transmission transmits the values of data list items without your having to specify the format of the values in the stream. The values are recorded externally as a list of constants, separated by blanks or commas. Data-directed data transmission transmits the names of the data list items, as well as their values, without your having to specify the format of the values in the stream. Edit-directed data transmission transmits the values of data list items and requires that you specify the format of the values in the stream. The values are recorded externally as a string of characters or graphics to be treated character by character (or graphic by graphic) according to a format list. Related Information  Data transmission statements  Data-directed data specification  Edit-directed data specification  List-directed data specification ═══ Data Transmission Statements ═══ Description Stream-oriented data transmission uses only one input statement (GET) and one output statement (PUT). The FORMAT statement specifies the format of data values being transmitted and is used only for edit-directed data transmission. You can use the COPY option to copy data into the output stream. The variables or pseudovariables to which data values are assigned, and the expressions from which they are transmitted, are generally specified with a data-specification options with each GET or PUT statement. The statements can also include options that specify the origin or destination of the data values or indicate where they appear in the stream relative to the preceding data values. Only sequential files can be processed with the GET and PUT statements. Options of data transmission statements Options that you can specify on stream-oriented data transmission statements (GET and PUT statements) are the following:  FILE Option  COPY Option  SKIP Option  PAGE Option  LINE Option  STRING Option Related Information  GET statement  PUT statement ═══ GET Statement ═══ Description The GET statement is a STREAM input data transmission statement that can:  Assign data values from a data set to one or more variables.  Assign data values from a string to one or more variables. Syntax Note: The keywords can appear in any order. The data specification must appear unless the SKIP option is specified.  The syntax of the GET statement for a stream input file is: ────GET──┬────────────────────────────┬───┬─────────────────────┬──── └─FILE──(──file─reference─)──┘ └─data─specification──┘ ─────┬─────────────────────────────┬─────────────────────────── └─COPY──(──file-reference──)──┘ ─────┬─────────────────────────────┬───;─────────────────────── └─SKIP──┬───────────────────┬─┘ └─(──expression──)──┘  The syntax of the GET statement for transmission from a string is: ────GET─STRING──(──expression──)──data-specification────;───── If neither the FILE nor the STRING option appears in a GET statement, the input file SYSIN is the default. ═══ PUT Statement ═══ Description The PUT statement is a STREAM output data transmission statement that you use to transmit values to a stream output file, or to assign values to a character variable. Syntax  The syntax of the PUT statement for a stream output file is: ────PUT──┬────────────────────────────┬───┬─────────────────────┬──── └─FILE──(──file─reference─)──┘ └─data─specification──┘ ─────┬────────────────────────────────────┬───;─────────────────────── ├─PAGE──┬─────────────────────────┬──┤ │ └─LINE──(──expression──)──┘ │ ├─SKIP──┬───────────────────┬────────┤ │ └─(──expression──)──┘ │ └─LINE──(──expression──)─────────────┘  The syntax of the PUT statement for transmission to a character string is: ────PUT STRING──(──character-reference──)──data-specification────;─── Note: The keywords can appear in any order. The data specification can be omitted only if one of the control options (PAGE, SKIP, or LINE) appears. If neither the FILE option nor the STRING option appears in a PUT statement, the output file SYSPRINT is the default. ═══ Data Specification Options ═══ Description Use data specifications in GET and PUT statements to specify the data to be transmitted. If a GET or PUT statement includes a data list that is not preceded by one of the keywords LIST, DATA, or EDIT, LIST is the default. In such a statement, the data list must immediately follow the GET or PUT keyword; any options required must be specified after the data list. Syntax ─────┬────────┬──(──data─list──)──────────────────────────┬─── ├──LIST──┘ │ ├──DATA──┬──────────────────────────────┬────────────┤ │ │ ┌────────,─────────┐ │ │ │ │  │ │ │ │ └──(─────data─list─item──┴──)──┘ │ │ ┌────────────────────────────────────────┐ │ │  │ │ └──EDIT───────(──data─list──)──(──format─list──)──┴──┘ where data-list is: ┌────────,─────────┐  │ ────┬─────data─list─item──┴──────────────────┬─────────────── │ ┌──────────────────────────────────┐ │ │  │ │ └─────(──data─list─item Type─3─DO──)──┴──┘ where format-list is: ┌────────────,──────────────┐  │ ─────┬─format-item ─────────┬──┴────────────────────────────── ├─n-format-item ───────┤ └─n─(──format-list──)──┘ ═══ data-list-item ═══ data-list-item On input, a data-list-item for edit-directed and list-directed transmission can be one of the following: an element, array, or structure variable or a pseudovariable other than STRING. For a data-directed data specification, a data-list-item can be an element, array, or structure variable. None of the names in a data-directed data list can be subscripted, or locator-qualified or ISUB-defined. However, qualified (that is, structure-member) or simple-defined, or string-overlay-defined names are allowed. On output, a data-list-item for edit-directed and list-directed data specifications can be an element expression, an array expression or a structure expression. For a data-directed data specification, a data-list-item can be an element, array, or structure variable. It must not be locator-qualified or ISUB-defined. It can be qualified (that is, a member of a structure) or simple-defined, or string-overlay-defined. The data types of a data-list-item can be any problem data. For list- and data-directed transmission of DBCS data or mixed data, the GRAPHIC option of the ENVIRONMENT attribute must be specified at compile-time. A data-list that specifies program-control data can only be used in PUT DATA statements that are processed at compile-time. In this case, the name of the variable is transmitted, but not its value. An array or structure variable in a data list is equivalent to n items in the data list, where n is the number of element items in the array or structure. For edit-directed transmission, each element item is associated with a separate use of a data format item. Related Information  Transmission of Data-List-Items ═══ Data-List-Item Type-3-Do ═══ Description When the last repetitive-specification is completed, processing continues with the next data list item. Each repetitive-specification must be enclosed in parentheses, as shown in the syntax diagram. If a data specification contains only a repetitive-specification, two sets of outer parentheses are required, since the data list is enclosed in parentheses and the repetitive-specification must have a separate set. Examples When repetitive-specifications are nested, the rightmost DO is at the outer level of nesting. For example: GET LIST (((A(I,J) DO I = 1 TO 2) DO J = 3 TO 4)); There are three sets of parentheses, in addition to the set used to delimit the subscripts. The outermost set is the set required by the data specification. The next set is that required by the outer repetitive-specification. The third set of parentheses is required by the inner repetitive-specification. This statement is equivalent in function to the following nested do-groups: DO J = 3 TO 4; DO I = 1 TO 2; GET LIST (A (I,J)); END; END; It assigns values to the elements of the array A in the following order: A(1,3), A(2,3), A(1,4), A(2,4) ═══ Transmission of Data-List-Items ═══ Description If a data-list-item is of complex mode, the real part is transmitted before the imaginary part. If a data-list-item is an array expression, the elements of the array are transmitted in row-major order; that is, with the rightmost subscript of the array varying most frequently. If a data-list-item is a structure expression, the elements of the structure are transmitted in the order specified in the structure declaration. Examples How data-list-items are transmitted ═══ Examples- How Data-List-Items Are Transmitted ═══ The statements: DECLARE 1 A (10), 2 B, 2 C; PUT FILE(X) LIST(A); result in the output being ordered as follows: A.B(1) A.C(1) A.B(2) A.C(2) A.B(3) A.C(3)...etc. If, however, the declaration is: DECLARE 1 A, 2 B(10), 2 C(10); the same PUT statement results in the output ordered as follows: A.B(1) A.B(2) A.B(3)...A.B(10) A.C(1) A.C(2) A.C(3)...A.C(10) If, within a data list used in an input statement for list-directed or edit-directed transmission, a variable is assigned a value, this new value is used if the variable appears in a later reference in the data list. For example: GET LIST (N,(X(I) DO I=1 TO N),J,K, SUBSTR (NAME, J,K)); When this statement is executed, values are transmitted and assigned in the following order: 1. A new value is assigned to N. 2. Elements are assigned to the array X as specified in the repetitive-specification in the order X(1),X(2),...X(N), with the new value of N specifying the number of assigned items. 3. A new value is assigned to J. 4. A new value is assigned to K. 5. A substring of length K is assigned to the string variable NAME, beginning at the Jth character. ═══ COPY Option ═══ Description Use the COPY option to specify that the source data stream will be written on the specified STREAM OUTPUT file without alteration. If you do not provide a file reference the default is the output file SYSPRINT. Each new record in the input stream starts a new record on the COPY file. If a condition is raised during the execution of a GET statement with a COPY option and an ON-unit is entered in which another GET statement is executed for the same file, and if control is returned from the ON-unit to the first GET statement, that statement executes as if no COPY option was specified. If, in the ON-unit, a PUT statement is executed for the file associated with the COPY option, the position of the data transmitted might not immediately follow the most recently-transmitted COPY data item. Note: If the COPY option file is not open, the file is implicitly opened for stream output transmission. Example The following statement: GET FILE(SYSIN) DATA(A,B,C) COPY(DPL); only transmits the values assigned to A, B, and C in the input stream to the variables with these names, but also writes them exactly as they appear in the input stream, on the file DPL. If they are written by default on the SYSPRINT file, they appear in data-directed format. Data values that are skipped on input, and not transmitted to internal variables, copy intact into the output stream. Syntax ─────COPY─(file-reference)───── ═══ FILE Option ═══ Description Use the FILE option to specify the file upon which an operation will take place. It must be a STREAM file. If neither the FILE option nor the STRING option appears in a GET statement, the input file SYSIN is the default; if neither option appears in a PUT statement, the output file SYSPRINT is the default. Related Information Declaring files ═══ LINE Option ═══ Description You can only specify the LINE option for output PRINT files. The LINE option defines a new current line for the data set. The expression is evaluated and converted to an integer value, n. The new current line is the nth line of the current page. If at least n lines have already been written on the current page or if n exceeds the limits set by the PAGESIZE option of the OPEN statement, the ENDPAGE condition is raised. If n is less than or equal to zero, a value of 1 is used. If n specifies the current line, ENDPAGE is raised except when the file is positioned on column 1. In this case, the effect is as for a SKIP(0) option. For displays at a terminal in interactive mode, the LINE option skips three lines. Example The LINE option takes effect before the transmission of any values defined by the data specification (if any). If both the PAGE option and the LINE option appear in the same statement, the PAGE option is applied first. For example: PUT FILE(LIST) DATA(P,Q,R) LINE(34) PAGE; prints the values of the variables P, Q, and R in data-directed format on a new page, commencing at line 34 Syntax ────LINE───(expression)───────────── ═══ PAGE Option ═══ Description You can specify the PAGE option only for output PRINT files. The PAGE option defines a new current page within the data set. If PAGE and LINE appear in the same PUT statement, the PAGE option is applied first. The PAGE option takes effect before the transmission of any values defined by the data specification (if any). The page remains current until the execution of a PUT statement with the PAGE option, until a PAGE format item is encountered, or until the ENDPAGE condition is raised, resulting in the definition of a new page. A new current page implies line one. For displays at a terminal in interactive mode, the PAGE option skips three lines. Syntax ───PAGE───────────────────────── ═══ SKIP Option ═══ Description The SKIP option specifies a new current line (or record) within the data set. The expression is evaluated and converted to an integer value, n. The data set is positioned to the start of the nth line (record) relative to the current line (record). If an expression is not specified, the default is SKIP(1). For output non-PRINT files and input files, if the expression in the SKIP option is less than or equal to zero, a value of 1 is used. For output PRINT files, if n is less than or equal to zero, the positioning is to the start of the current line. If fewer than n lines remain on the current page when a SKIP(n) is issued, ENDPAGE is raised. When printing at a terminal in conversational mode, SKIP(n) with n greater than 3 is equivalent to SKIP(3). No more than three lines can be skipped. Example The SKIP option takes effect before the transmission of values defined by the data specification (if any). For example: PUT LIST(X,Y,Z) SKIP(3); prints the values of the variables X, Y, and Z on the output file SYSPRINT, commencing on the third line after the current line. Syntax ─────SKIP-(expression)───── ═══ STRING Option ═══ Description Use the STRING option in GET and PUT statements to transmit data between main storage locations rather than between the main and auxiliary storage facilities. DBCS data items cannot be used with the STRING option. The GET statement with the STRING option specifies that data values assigned to the data list items are obtained from the expression, after conversion to character string. Each GET operation using this option always begins at the leftmost character position of the string. If the number of characters in this string is less than the total number of characters specified by the data specification, the ERROR condition is raised. In the STRING option of a PUT statement, the character-reference cannot be the STRING pseudovariable. The PUT statement with the STRING option specifies that values of the data list items are to be assigned to the specified character variable or pseudovariable. The PUT operation begins assigning values at the leftmost character position of the string, after appropriate conversions are performed. Blanks and delimiters are inserted as usual. If the string is not long enough to accommodate the data, the ERROR condition is raised. The NAME condition is not raised for a GET DATA statement with the STRING option. Instead, the ERROR condition is raised for situations that raise the NAME condition for a GET DATA statement with the FILE option. The STRING option is most useful with edit-directed transmission. The COLUMN control format option cannot be used with the STRING option. Examples Using the STRING option Syntax  The syntax for GET with the STRING option is: ─────GET─STRING─(expression)──data-specification──────────────  The syntax for PUT with the STRING option is: ─────PUT─STRING─(character-reference)──data-specification───── ═══ Examples- Using the STRING Option ═══ The STRING option allows you to perform data gathering or scattering operations with a single statement, and it allows stream-oriented processing of character strings that are transmitted by record-oriented statements. For example: READ FILE (INPUTR) INTO (TEMP); GET STRING(TEMP) EDIT (CODE) (F(1)); IF CODE = 1 THEN GET STRING (TEMP) EDIT (X,Y,Z) (X(1), 3 F(10,4)); The READ statement reads a record from the input file INPUTR. The first GET statement uses the STRING option to extract the code from the first byte of the record and assigns it to CODE. If the code is 1, the second GET statement uses the STRING option to assign the values in the record to X,Y, and Z. The second GET statement specifies that the first character in the string TEMP is ignored (the X(1) format item in the format list). The character that is ignored in the second GET statement is the same character that is assigned to CODE by the first GET statement. For example: PUT STRING (RECORD) EDIT (NAME) (X(1), A(12)) (PAY#) (X(10), A(7)) (HOURS*RATE) (X(10), P'$999V.99'); WRITE FILE (OUTPRT) FROM (RECORD); The PUT statement specifies, by the X(1) spacing format item, that the first character assigned to the character variable is to be a single blank, which is the ANS vertical carriage positioning character that specifies a single space before printing. Following that, the values of the variables NAME and PAY# and of the expression HOURS*RATE are assigned. The WRITE statement specifies that record transmission is used to write the record into the file OUTPRT. The variable referenced in the STRING option should not be referenced by name or by alias in the data list. For example: DECLARE S CHAR(8) INIT('YYMMDD'); PUT STRING (S) EDIT (SUBSTR (S, 3, 2), '/', SUBSTR (S, 5, 2), '/', SUBSTR (S, 1, 2)) (A); The value of S after the PUT statement is 'MM/bb/MM' and not 'MM/DD/YY' because S is blanked after the first data item is transmitted. The same effect would also be obtained if the data list contained a variable based or defined on the variable specified in the STRING option. ═══ Data-Directed Data Specification ═══ Description The syntax for a data-directed data specification (in a GET or a PUT statement) is the following: Description Data-directed data transmission transmits the names of the data list items, as well as their values, without your having to specify the format of the values in the stream. Usage Rules Consider the following rules when using data-directed data specification:  Names of structure elements in the data-list-item need only have enough qualification to resolve any ambiguity. Full qualification is not required.  Omission of the data-list results in a default data-list that contains all variables, except for ISUB-defined variables, that are known to the block and any containing blocks.  On output, all items in the data-list are transmitted. If two or more blocks containing the PUT statement each have declarations of items that have the same name, all the items are transmitted. The item in the innermost block appears first.  References to based variables in a data-list for data-directed input/output cannot be explicitly locator qualified. For example: DCL Y BASED(Q), Z BASED; PUT DATA(Y);  The variable Z cannot be transmitted since it must be explicitly qualified by a locator. The following restrictions apply to based variables in the data-list:  The variable must not be based on an OFFSET variable.  The variable must not be a member of a structure declared with the REFER option.  The pointer on which the variable is based must not be based, defined, or a parameter, and it must not be a member of an array or structure. Defined variables in the data-list must not be defined:  On a controlled variable  On an array with one or more adjustable bounds  With a POSITION attribute that specifies other than a constant Related Information  Data specification options  Specifying data-directed element assignments  GET data-directed  PUT data-directed Syntax ───DATA──┬───────────────┬────── └─(─data-list─)─┘ ═══ Specifying Data-Directed Element Assignments ═══ Description The stream associated with data-directed data transmission is in the form of a list of element assignments. For problem data, the element assignments have optionally signed constants, like the variable names and the equal signs, are in character or graphic form. The element-variable can be a subscripted name. Subscripts must be optionally-signed integers. On input, the element assignments can be separated by either a blank or a comma. Blanks can surround periods in qualified names, subscripts, subscript parentheses, and the assignment symbols. On output, the assignments are separated by a blank. (For PRINT files, items are separated according to program tab settings.) Each list-directed data value in the stream has one of the syntaxes described for list-directed transmission. The length of the data value in the stream is a function of the attributes declared for the variable and, since the name is also included, the length of the fully qualified subscripted name. The length for output items converted from coded arithmetic data, numeric character data, and bit-string data is the same as that for list-directed output data, and is governed by the rules for data conversion to character type. Qualified names in the input stream must be fully qualified. The name must not contain more than 256 characters. Locator qualifiers cannot appear in the stream. The locator qualifier declared with the based variable is used to establish the generation. Based variables that are not declared with a locator qualifier cannot be transmitted. Interleaved subscripts cannot appear in qualified names in the stream. Examples Specifying element assignments Syntax ┌─,───────────────────────────────────────┐ │ ┌───────────────────────────────────┐ │   │ │ ──────────element-variable──=──data-value──┴──┴──;──── ═══ GET Data-Directed ═══ Description If you use a data-list, each data-list-item must be an element, array, or structure variable. Names cannot be subscripted, but qualified names are allowed in the data-list. All names in the stream should appear in the data-list; however, the order of the names need not be the same, and the data-list can include names that do not appear in the stream. If the data-list contains a name that is not included in the stream, the value of the named variable remains unchanged. If the stream contains an unrecognizable element-variable or a name that does not have a counterpart in the data-list, the NAME condition is raised. Recognition of a semicolon (not enclosed in quotation marks) or an end-of-file causes transmission to cease, and thereby determines the number of element assignments that are actually transmitted by a particular statement, whether or not a data-list is specified. Examples  Consider the following data-list, where A, B, C, and D are names of element variables: DATA (B, A, C, D) This data-list can be associated with the following input data stream: A= 2.5, B= .0047, D= 125, Z= 'ABC'; C appears in the data-list but not in the stream; its value remains unaltered. Z, which is not in the data-list, raises the NAME condition.  General examples- data-directed transmission Related Information  GET statement syntax  GET data-directed with arrays  GET data-directed with structures ═══ GET Data-Directed with Arrays ═══ Description If you include the name of an array in the data-list, subscripted references to that array can appear in the stream although subscripted names cannot appear in the data-list. The entire array need not appear in the stream; only those elements that actually appear in the stream will be assigned. If a subscript is out of range, or is missing, the NAME condition is raised. Example Consider the following array declaration: DECLARE X (2,3); Now, consider the following data list and input data stream: ┌───────────────────┬───────────────────┐ │Data Specification │ Input Data Stream │ ├───────────────────┼───────────────────┤ │DATA (X) │ X(1,1)= 7.95, │ │ │ X(1,2)= 8085, │ │ │ X(1,3)= 73; │ └───────────────────┴───────────────────┘ Although the data-list has only the name of the array, the input stream can contain values for individual elements of the array. In this case, only three elements are assigned; the remainder of the array is unchanged. ═══ GET Data-Directed with Structures ═══ Description If you include the names of structures, minor structures, or structure elements in the data list, fully qualified names must appear in the stream, although full qualification is not required in the data-list. Example Consider the following declaration: DCL 1 IN, 2 PARTNO, 2 DESCRP, 2 PRICE, 3 RETAIL, 3 WHSL; If you would like to read a value for IN.PRICE.RETAIL, the input data stream must have the following form: IN.PRICE.RETAIL=1.23; The data specification can be any of: DATA(IN) DATA(PRICE) DATA(IN.PRICE) DATA(RETAIL) DATA(PRICE.RETAIL) DATA(IN.RETAIL) DATA(IN.PRICE.RETAIL) ═══ General Examples- Data-Directed Transmission ═══ Consider the following examples of data-directed transmission.  The following example shows data-directed transmission (both input and output): DECLARE (A(6), B(7)) FIXED; GET FILE (X) DATA (B); DO I = 1 TO 6; A (I) = B (I+1) + B (I); END; PUT FILE (Y) DATA (A); Input Stream: B(1)=1, B(2)=2, B(3)=3, B(4)=1, B(5)=2, B(6)=3, B(7)=4; Output Stream: A(1)= 3 A(2)= 5 A(3)= 4 A(4)= 3 A(5)= 5 A(6)= 7;  In the following example: DCL 1 A, 2 B FIXED, 2 C, 3 D FIXED; A.B = 2; A.D = 17; PUT DATA (A); the data fields in the output stream would be as follows: A.B= 2 A.C.D= 17; ═══ PUT Data-Directed ═══ Description Your data-list-items can be elements, arrays, structure variables, or repetitive specifications. For problem data, the names appearing in the data-list, together with their values, are transmitted in the form of a list of element assignments separated by blanks and terminated by a semicolon. For PRINT files, items are separated according to program tab settings. A semicolon is written into the stream after the last data item transmitted by each PUT statement. Subscript expressions that appear in a data-list are evaluated and replaced by their values. Items that are part of a structure appearing in the data-list are transmitted with the full qualification. Subscripts follow the qualified names rather than being interleaved. Data-directed output is not valid for subsequent data-directed input:  When the character-string value of a numeric character variable does not represent a valid optionally signed arithmetic constant, or a complex expression.  When a program control variable is transmitted, the variable must not be specified in an input data list. For character data, the contents of the character string are written out enclosed in quotation marks. Each quotation mark contained within the character string is represented by two successive quotation marks. Names are transmitted as all SBCS or all DBCS, regardless of how they are specified in the data-list. If a name contains a non EBCDIC DBCS character, it is transmitted as all DBCS. Each name in a qualified reference is handled independently. Examples Consider the following examples of data-directed PUT. If a data-list-item is specified for a structure element as follows: DATA (Y(1,-3).Q) the output stream written is: Y.Q(1,-3)= 3.756; Each name in a qualified reference is handled independently: PUT DATA (<.A.B.C>.S); would be transmitted as: ABC.<.Skk>=... Related Information  PRINT attribute  PUT statement ═══ Edit-Directed Data Specification ═══ Description Use edit-directed data transmission to transmit the values of data list items. Edit-directed transmission requires that you specify the format of the values in the stream. The values are recorded externally as a string of characters or graphics to be treated character by character (or graphic by graphic) according to a format list. Related Information  Data specification options  GET edit-directed  PUT edit-directed  FORMAT statement The syntax for an edit-directed data specification (in a GET or a PUT statement) is the following: Syntax ┌───────────────────────────────────────────┐  │ ────EDIT────(───data-list───)───(──┤ format-list ├──)─┴─────────── Where format-list is: ┌────────────,────────────┐  │ ──────┬─format-item─────────┬─┴──── ├─n─format-item───────┤ └─n─(──format-list──)─┘ ═══ Iteration Factor (n) ═══ n specifies an iteration factor, which is either an expression enclosed in parentheses or an integer. If it is an integer, a blank must separate the integer and the following format-item. The iteration factor specifies that the associated format-item or format-list is used n successive times. A zero or negative iteration factor specifies that the associated format-item or format-list is skipped and not used (the data-list item is associated with the next data format-item). If an expression is used to represent the iteration factor, it is evaluated and converted to an integer, once for each set of iterations. The associated format-item or format-list is that item or list of items immediately to the right of the iteration factor. ═══ Format Items ═══ Description Format items may be either data format items, control format items, or the remote format item.  Data format items describe the character or graphic representation of a single data item. The first data format item is associated with the first data list item, the second data format item with the second data list item, and so on. If a format list contains fewer data format items than there are items in the associated data list, the format list is reused. If there are excessive format items, they are ignored. The data format items are: A (character) format item B (bit) format item C (complex) format item E (floating-point) format item F (fixed-point) format item G (graphic) format item P (picture) format item  Control format items specify the layout of the data set associated with a file. If a control format item is encountered, the control action is executed. There are rules for using control format items. The control format items are: COLUMN format item LINE format item PAGE format item SKIP format item X format item  The remote or R format item specifies a label reference whose value is the label constant of the FORMAT statement located elsewhere. The FORMAT statement contains the remotely situated format items. ═══ A (Character) Format Item ═══ Description Use the character (A) format item to describe the representation of a character value.  On input, the specified number of characters is obtained from the data stream and assigned, with any necessary conversion, truncation, or padding, to the data list item. The field width is always required on input and, if it is zero, a null string is obtained. If quotation marks appear in the stream, they are treated as characters in the string.  On output, the data list item is converted, if necessary, to a character string and is truncated or extended with blanks on the right to the specified field-width before being placed into the data stream. If the field-width is zero, no characters are placed into the data stream. Enclosing quotation marks are never inserted, nor are contained quotation marks doubled. If the field width is not specified, the default is equal to the character-string length of the data list item (after conversion, if necessary). Example Consider the following statement that uses the A format item: GET FILE (INFILE) EDIT (ITEM) (A(20)); This statement assigns the next 20 characters in the file called INFILE to ITEM. The value is converted from its character representation specified by the format item A(20), to the representation specified by the attributes declared for ITEM. Syntax ────A──┬─────────────────────┬───── └──(──field-width──)──┘ ═══ B (Bit) Format Item ═══ Description Use the bit (or B) format item to describe the character representation of a bit value. Each bit is represented by the character zero or one.  On input, the character representation of the bit string can occur anywhere within the specified field. Blanks, which may appear before and after the bit string in the field, are ignored. Any necessary conversion occurs when the bit string is assigned to the data list item. The field width is always required on input, and if it is zero, a null string is obtained. Any character other than 0 or 1 in the string, including embedded blanks, quotation marks, or the letter B, raises the CONVERSION condition.  On output, the character representation of the bit string is left-adjusted in the specified field, and necessary truncation or extension with blanks occurs on the right. Any necessary conversion to bit-string is performed. No quotation marks are inserted, nor is the identifying letter B. If the field width is zero, no characters are placed into the data stream. If the field width is not specified, the default is equal to the bit-string length of the data list item (after conversion, if necessary). Example In the example: DECLARE MASK BIT(25); PUT FILE(MASKFLE) EDIT (MASK) (B); The PUT statement writes the value of MASK in the file called MASKFLE as a string of 25 characters consisting of 0's and 1's. Syntax ────B──┬─────────────────────┬──── └──(──field-width──)──┘ ═══ C (Complex) Format Item ═══ Description Use the complex (or C) format item to describe the character representation of a complex data value. You use one real-format-item to describe both the real and imaginary parts of the complex data value in the data stream. On input, the letter I in the input raises the CONVERSION condition. On output, the letter I is never appended to the imaginary part. If the second real format item (or the first, if only one appears) is an F or E item, the sign is transmitted only if the value of the imaginary part is less than zero. If the real format item is a P item, the sign is transmitted only if the S or - or + picture character is specified. If you require an I to be appended, it must be specified as a separate data item in the data list, immediately following the variable that specifies the complex item. The I, then, must have a corresponding format item (either A or P). Syntax ┌─,────────────────┐  │ ────C──(───real-format-item─┴──)───── ═══ E (floating-point) Format Item ═══ Description The floating-point (or E) format item describes the character representation of a real floating-point decimal arithmetic data value. The following must be true: (field-width) >= (significant-digits) >= (fractional-digits) or field-width = 0 and, when field-width к= 0 (significant digits) > 0, (fractional digits) >= 0  On input, either the data value in the data stream is an optionally signed real decimal floating-point or fixed-point constant located anywhere within the specified field or the CONVERSION condition is raised. (For convenience, the "E" preceding a signed exponent can be omitted.) The field-width includes leading and trailing blanks, the exponent position, the positions for the optional plus or minus signs, the position for the optional letter E, and the position for the optional decimal point in the mantissa. The data value can appear anywhere within the specified field; blanks can appear before and after the data value in the field and are ignored. If the entire field is blank, the CONVERSION condition is raised. When no decimal point appears, fractional-digits specifies the number of character positions in the mantissa to the right of the assumed decimal point. If a decimal point does appear in the number, it overrides the specification of fractional-digits. Significant-digits, if it appears, is evaluated and ignored. If field-width is 0, there is no assignment to the data list item.  On output, the data list item is converted to floating-point and rounded if necessary. The rounding of data is as follows: if truncation causes a digit to be lost from the right, and this digit is greater than or equal to 5, 1 is added to the digit to the left of the truncated digit. This addition might cause adjustment of the exponent. If significant-digits is not specified, it defaults to 1 plus fractional-digits. Related Information Character string syntax for output Example Consider the following example of input using the E format item: GET FILE(A) EDIT (COST) (E(10,6)); This statement obtains the next 10 characters from the file called A and interprets them as a floating-point decimal number. A decimal point is assumed before the rightmost 6 digits of the mantissa. The value of the number is converted to the attributes of COST and assigned to this variable. Syntax ────E──(──field-width─,─fractional-digits──────── ─────┬────────────────────────┬──)──────────────── └──,─significant-digits──┘ ═══ Character String Syntax for Output (for E-Format Item) ═══ The character string written in the stream for output has one of the following syntaxes: Note the following abbreviations: w = field-width d = fractional digits s = significant-digits  For d = 0 [-] {s digits}E{ё}exponent w must be >= s+4 for positive values, or >= s+5 for negative values. When the value is nonzero, the exponent is adjusted so that the leading digit of the mantissa is nonzero. When the value is zero, zero suppression is applied to all digit positions (except the rightmost) of the mantissa.  For 0 < d < s [-]{s-d digits}.{d digits} E{ё}exponent w must be >= s+5 for positive values, or >= s+6 for negative values. When the value is nonzero, the exponent is adjusted so that the leading digit of the mantissa is nonzero. When the value is zero, zero suppression is applied to all digit positions (except the first) to the left of the decimal point. All other digit positions contain zero.  For d = s [-]0.{d digits}E{ё}exponent w must be >= d+6 for positive values, or >= d+7 for negative values. When the value is nonzero, the exponent is adjusted so that the first fractional digit is nonzero. When the value is zero, each digit position contains zero. The exponent is a 2-digit integer, which can be two zeros. If the field width is such that significant digits or the sign are lost, the SIZE condition is raised. If the character string does not fill the specified field on output, the character string is right-adjusted and extended on the left with blanks. ═══ F (fixed-point) Format Item ═══ Description Use the fixed-point (or F) format item to describe the character representation of a real fixed-point decimal arithmetic value. Related Information  F format item on input  F format item on output Syntax ────F──(──field-width───────────────────────────────── ───┬─────────────────────────────────────────────┬──)── └─,─fractional-digits──┬────────────────────┬─┘ └──,─scaling-factor──┘ ═══ Using the F Format Item on Input ═══ On input, either the data value in the data stream is an optionally signed real decimal fixed-point constant located anywhere within the specified field or the CONVERSION condition is raised. Blanks can appear before and after the data value in the field and are ignored. If the entire field is blank, it is interpreted as zero. (This is different from CHAR to ARITH conversion and from E-format items.) Fractional-digits, if not specified, defaults to 0. If no scaling-factor is specified and no decimal point appears in the field, the expression for fractional-digits specifies the number of digits in the data value to the right of the assumed decimal point. If a decimal point does appear in the data value, it overrides the expression for fractional-digits. If a scaling-factor is specified, it effectively multiplies the data value in the data stream by 10 raised to the integer value (p) of the scaling-factor. Thus, if p is positive, the data value is treated as though the decimal point appeared p places to the right of its given position. If p is negative, the data value is treated as though the decimal point appeared p places to the left of its given position. The given position of the decimal point is that indicated either by an actual point, if it appears, or by the expression for fractional-digits, in the absence of an actual point. If the field-width is 0, there is no assignment to the data list item. ═══ G (Graphic) Format Item ═══ Description Use the graphic (or G) format item to describe the representation of a graphic string. Example In the example: DECLARE A GRAPHIC(3); PUT FILE(OUT) EDIT (A) (G(3)); If OUT does not have the GRAPHIC option, 6 bytes are transmitted; otherwise, 8 bytes (6 bytes and the left and right delimiters) are transmitted. Related Information  G on input  G on output Syntax ────G──┬─────────────────────┬───── └──(──field-width──)──┘ ═══ P (Picture) Format Item ═══ Description Use the picture (or P) format item to describe the character representation of real numeric character values and of character values. The picture specification of the P-format item, on input, describes the form of the data item expected in the data stream and, in the case of a numeric character specification, how the item's arithmetic value is to be interpreted. If the indicated character does not appear in the stream, the CONVERSION condition is raised. On output, the value of the associated element in the data list is converted to the form specified by the picture specification before it is written into the data stream. Example Consider the following statement: GET EDIT (NAME, TOTAL) (P'AAAAA',P'9999'); When this statement is executed, the input file SYSIN is the default. The next five characters input from SYSIN must be alphabetic or blank and they are assigned to NAME. The next four characters must be digits and they are assigned to TOTAL. Syntax ────P──'──picture-specification──'───── ═══ COLUMN Format Item ═══ Description Use the COLUMN format item to position the file to a specified character position within the current or following line. The file is positioned to the specified character position in the current line, provided it has not already passed this position. If the file is already positioned after the specified character position, the current line is completed and a new line is started; the format item is then applied to the following line. If the specified character position lies beyond the rightmost character position of the current line, or if the value of the expression for the character position is less than one, the default character position is one. The rightmost character position is determined as follows:  For output files, it is determined by the line size.  For input files, it is determined using the length of the current logical record to determine the line size and, hence, the rightmost character position. In the case of V-format records, this line size is equal to the logical record length minus the number of bytes containing control information. COLUMN must not be used in a GET STRING or PUT STRING statement. COLUMN cannot be used with input or output lines that contain graphics. On input, intervening character positions are ignored. On output, intervening character positions are filled with blanks. Syntax ───COLUMN──(──character-position──)───── ═══ LINE Format Item ═══ Description Use the LINE format item to specify the line on the current page of a PRINT file upon which the next data list item will be printed, or it raises the ENDPAGE condition. Blank lines are inserted, if necessary. If the specified line-number is less than or equal to the current line number, or if the specified line is beyond the limits set by the PAGESIZE option of the OPEN statement (or by default), the ENDPAGE condition is raised. An exception is that if the specified line-number is equal to the current line number, and the column 1 character has not yet been transmitted, the effect is as for a SKIP(0) item, that is, a carriage return with no line spacing. If line-number is zero, it defaults to one (1). Syntax ────LINE──(──line-number──)───── ═══ PAGE Format Item ═══ Description Use the PAGE format item to specify that a new page is established. PAGE can be used only with PRINT files. The establishment of a new page positions the file to line one of the next page. Syntax ────PAGE────────── ═══ SKIP Format Item ═══ Description Use the SKIP format item to specify that a new line is to be defined as the current line. With SKIP, you specify an expression which is converted to an integral number, n. The new line is the nth line after the present line. If n is greater than one, one or more lines are ignored on input; on output, one or more blank lines are inserted. Only PRINT files can have n equal to zero, in which case the positioning is at the start of the current line. Characters previously written can be overprinted. For PRINT files, if the specified relative-line n is beyond the limit set by the PAGESIZE option of the OPEN statement (or the default), the ENDPAGE condition is raised. If the SKIP format item is the first item to be executed after a file has been opened, output commences on the nth line of the first page. If n is zero or 1, it commences on the first line of the first page. Example Consider the following statement: GET FILE(IN) EDIT(MAN,OVERTIME) (SKIP(1), A(6), COL(60), F(4,2)); This statement positions the data set associated with file IN to a new line. The first 6 characters on the line are assigned to MAN, and the 4 characters beginning at character position 60 are assigned to OVERTIME. Syntax ────SKIP──┬───────────────────────┬────── └──(──relative-line──)──┘ ═══ X Format Item ═══ Description Use the spacing (or X) format item to specify the relative spacing of data values in the data stream. On input, the specified number of characters are spaced over in the data stream and not transmitted to the program. On output, the specified number of blank characters are inserted into the stream. Examples  In the example: GET EDIT (NUMBER, REBATE) (A(5), X(5), A(5)); The next 15 characters from the input file, SYSIN, are treated as follows: the first five characters are assigned to NUMBER, the next five characters are spaced over and ignored, and the remaining five characters are assigned to REBATE.  In the example: PUT FILE(OUT) EDIT (PART, COUNT) (A(4), X(2), F(5)); Four characters that represent the value of PART, then two blank characters, and finally five characters that represent the fixed-point value of COUNT, are placed in the file named OUT. Syntax ────X──(──field-width──)────── ═══ R Format Item ═══ Description Use the remote (or R) format item to specify that the format list in a FORMAT statement is to be used. The R-format item and the specified FORMAT statement must be internal to the same block, and they must be in the same invocation of that block. A remote FORMAT statement cannot contain an R-format item that references itself as a label-reference, nor can it reference another remote FORMAT statement that will lead to the referencing of the original FORMAT statement. Conditions enabled for the GET or PUT statement must also be enabled for the remote FORMAT statement(s) that are referred to. If the GET or PUT statement is the single statement of an ON-unit, that statement is a block, and it cannot contain a remote format item. Related Information FORMAT statement Syntax ────R──(──label-reference──)────────── ═══ Rules for Using Control Format Items ═══ Be aware of certain rules for the use of control format items. These rules are:  The PAGE and LINE format items can be used only with PRINT files and, consequently, can appear only in PUT statements. The SKIP, COLUMN, and X-format items apply to both input and output, however.  The PAGE, SKIP, and LINE format items have the same effect as the corresponding options of the PUT statement (and of the GET statement, in the case of SKIP), except that the format items take effect when they are encountered in the format list, while the options take effect before any data is transmitted.  The COLUMN format item cannot be used in a GET STRING or PUT STRING statement. ═══ GET Edit-Directed ═══ Description Data in the stream is a continuous string of characters and graphics without any delimiters between successive values. For files with the GRAPHIC attribute, graphic data must be enclosed in shift codes. The number of characters for each data value is specified by a format item in the format list. The characters are interpreted according to the associated format item. When the data-list has been processed, execution of the GET statement stops and any remaining format items are not processed. Each data format item specifies the number of characters or graphics to be associated with the data list item and how to interpret the data value. The data value is assigned to the associated data list item, with any necessary conversion. Fixed-point binary and floating-point binary data values must always be represented in the input stream with their values expressed in decimal digits. The F-, P-, and E-format items can then be used to access them, and the values are converted to binary representation upon assignment. All blanks and quotation marks are treated as characters in the stream. Strings should not be enclosed in quotation marks. Quotation marks (character or graphic) should not be doubled. The letter B should not be used to identify bit strings or G to identify graphic strings. If characters in the stream cannot be interpreted in the manner specified, the CONVERSION condition is raised. Example Using edit-directed GET Related Information GET statement ═══ PUT Edit-Directed ═══ Description The value of each data list item is converted to the character or graphic representation specified by the associated format item and placed in the stream in a field whose width also is specified by the format item. When the data-list has been processed, execution of the PUT statement stops and any remaining format items are not processed. On output, binary items are converted to decimal values and the associated F- or E-format items must state the field width and point placement in terms of the converted decimal number. For the P-format these are specified by the picture specification. On output, blanks are not inserted to separate data values in the output stream. String data is left-adjusted in the field to the width specified. Arithmetic data is right-adjusted. Because of the rules for conversion of arithmetic data to character type which can cause up to 3 leading blanks to be inserted (in addition to any blanks that replace leading zeros), generally there is at least 1 blank preceding an arithmetic item in the converted field. Leading blanks do not appear in the stream, however, unless the specified field width allows for them. Truncation, due to inadequate field-width specification, is on the left for arithmetic items, and on the right for string items. SIZE or STRINGSIZE is raised if truncation occurs. Examples  PUT with data format items  PUT with data and control format items Related Information PUT statement ═══ Put with Data and Control Format Items (Examples) ═══ The following examples show the use of the COLUMN, LINE, PAGE, and SKIP format items in combination with one another.  Consider the following: PUT EDIT ('QUARTERLY STATEMENT') (PAGE, LINE(2), A(19))(ACCT#, BOUGHT, SOLD, PAYMENT, BALANCE) (SKIP(3), A(6), COLUMN(14), F(7,2), COLUMN(30), F(7,2), COLUMN(45), F(7,2), COLUMN(60), F(7,2)); This PUT statement specifies that the heading QUARTERLY STATEMENT is written on line two of a new page in the output file SYSPRINT, two lines are skipped (that is, "skip to the third following line") and the value of ACCT# is written, beginning at the first character of the fifth line; the value of BOUGHT, beginning at character position 14; the value of SOLD, beginning at character position 30; the value of PAYMENT, beginning at character position 45; and the value of BALANCE at character position 60.  Consider the following: PUT EDIT (NAME,NUMBER,CITY) (A(N),A(N-4),A(10)); In this example, the value of NAME is inserted in the stream as a character string left-adjusted in a field of N characters; NUMBER is left-adjusted in a field of N-4 characters; and CITY is left-adjusted in a field of 10 characters. ═══ FORMAT Statement ═══ Description Use the FORMAT statement to specify a format list that can be used by edit-directed data transmission statements to control the format of the data being transmitted. A GET or PUT EDIT statement can include a remote format item, R, in its format-list. That portion of the format-list represented by the R format item is supplied by the identified FORMAT statement. The remote format item and the FORMAT statement must be internal to the same invocation of the same block. If a condition prefix is associated with a FORMAT statement, it must be identical to the condition prefix associated with the GET or PUT statement referring to that FORMAT statement. When a FORMAT statement is encountered in normal sequential flow, control passes around it. Syntax ┌──────────┐  │ ───────label:──┴───FORMAT──(──format-list──)────;──── ═══ Using the F Format Item on Output ═══ Description On output, the data list item is converted, if necessary, to fixed-point; floating-point data converts to FIXED DECIMAL (15,q) where q is the fractional-digits specified. The data value in the stream is the character representation of a real decimal fixed-point number, rounded if necessary, and right-adjusted in the specified field. The conversion from decimal fixed-point type to character type is performed according to the normal rules for conversion. Extra characters may appear as blanks preceding the number in the converted string. And, since leading zeros are converted to blanks (except for a 0 immediately to the left of the point), additional blanks may precede the number. If a decimal point or a minus sign appears, either will cause one leading blank to be replaced. If only the field-width is specified, only the integer portion of the number is written; no decimal point appears. If both the field-width and fractional-digits are specified, but scaling-factor is not, both the integer and fractional portions of the number are written. If the value of fractional-digits (d) is greater than 0, a decimal point is inserted before the rightmost d digits. Trailing zeros are supplied when fractional-digits is less than d (the value d must be less than field-width). If the absolute value of the item is less than 1, a 0 precedes the decimal point. Suppression of leading zeros is applied to all digit positions (except the first) to the left of the decimal point. The rounding of the data value is as follows: if truncation causes a digit to be lost from the right, and this digit is greater than or equal to 5, 1 is added to the digit to the left of the truncated digit. The integer value (p) of the scaling-factor multiplies the value of the data list item, after any conversion to FIXED DECIMAL by 10 raised to the power of p, before it is edited into its character representation. When fractional-digits is 0, only the integer portion of the data list item is used in the multiplication. On output, if the data list item is less than 0, a minus sign is prefixed to the character representation; if it is greater than or equal to 0, no sign appears. Therefore, for negative values, the field-width might need to include provision for the sign, a decimal point, and a 0 before the point. If the field-width is such that any character is lost, the SIZE condition is raised. Example Using F-format item on output ═══ List-Directed Data Specification ═══ Description List-directed data transmission transmits the values of data list items without your having to specify the format of the values in the stream. The list-directed data values are recorded externally as a list of constants, separated by blanks or commas. Examples Examples of list-directed data specifications are: LIST (CARD_RATE, DYNAMIC_FLOW) LIST ((THICKNESS(DISTANCE) DO DISTANCE = 1 TO 1000)) LIST (P, Z, M, R) LIST (A*B/C, (X+Y)**2) Note: The specification in the last example can be used only for output, since it contains expressions. These expressions are evaluated when the statement is executed, and the result is placed in the stream. Related Information  Data specification options  GET list-directed  PUT list-directed Syntax ──────┬──────┬─────(─data-list─)──;──────────────────────────────────── └─LIST─┘ ═══ List-Directed Data Values ═══ Description List-directed data values in the stream, either input or output, are character or graphic representations as demonstrated in the syntax diagram below. String repetition factors are not allowed. A blank must not follow a sign preceding a real constant, and must not precede or follow the central + or - in complex expressions. The length of the data value in the stream is a function of the attributes of the data value, including precision and length. Syntax ────┬─┬─────┬──arithmetic-constant─────────────────────────┬───── │ ├──+──┤ │ │ └──-──┘ │ ├─┬─────┬──real-constant──┬─ + ─┬──imaginary-constant──┤ │ ├──+──┤ └─ - ─┘ │ │ └──-──┘ │ ├───character-constant─────────────────────────────────┤ ├───bit-constant───────────────────────────────────────┤ └───graphic-constant───────────────────────────────────┘ ═══ GET List-Directed ═══ Description On input, data values in the stream must be separated either by a blank or by a comma. This separator can be surrounded by an arbitrary number of blanks. A null field in the stream is indicated either by the first nonblank character in the data stream being a comma, or by two commas separated by an arbitrary number of blanks. A null field specifies that the value of the associated data list item remains unchanged. Transmission of the list of constants or complex expressions on input is terminated by expiration of the list or at the end of the file. For transmission of constants, the file is positioned in the stream ready for the next GET statement. How data items are handled on input depends on the data type:  If the data is a character constant, the surrounding quotation marks are removed, and the enclosed characters are interpreted as a character string. A double quotation mark is treated as a single quotation mark.  If the data is a bit constant, the enclosing quotation marks and the trailing character B are removed, and the enclosed characters are interpreted as a bit string.  If the data is a hexadecimal constant (X, BX, B4, GX), the enclosing quotation marks and the suffix are removed, and the enclosed characters are interpreted as a hexadecimal representation of a character, bit, or graphic string.  If the data is a mixed constant, the enclosing quotation marks and the suffix M are removed, and the data is adjusted so that the DBCS portions are enclosed in shift codes.  If the data is a graphic constant, the enclosing shift codes, quotation marks, and the 'G' are removed, and the enclosed graphics are interpreted as a graphic string. If the data is an arithmetic constant or complex expression, it is interpreted as coded arithmetic data with the base, scale, mode, and precision implied by the constant or by the rules for expression evaluation. Related Information  GET statement syntax  GET-ting items separated by blanks  GET-ting items separated by commas  GET-ting DBCS data ═══ PUT List-Directed ═══ Description The values of the data-list-items are converted to character representations (except for graphics) and transmitted to the data stream. A blank separates successive data values transmitted. PRINT file data items are separated according to program tab settings. On output, a number of conversions may occur, depending on data type:  Arithmetic values are converted to character.  Binary data values are converted to decimal notation before being placed in the stream.  For numeric character values, the character value is transmitted.  Bit strings are converted to character strings. The character string is enclosed in quotation marks and followed by the letter B. How the data-list is written out depends upon the type of data. Select one of the following data types for additional information on how the data-list is written out by data type: Related Information  PRINT attribute  Character string output  Graphic string output  Mixed string output  PUT statement ═══ 1.2. PL/I Data Items ═══ Description You can use PL/I in a wide variety of applications because it has many different data types that can be represented and manipulated. These data types may be used to represent values processed by your program or may control the execution of your program. PL/I data items are the values of constants or variables. A constant has a value that cannot change. Depending on its usage, a constant may be referred to either by its name or by stating the value of the constant. A variable has a value or values that can change during the execution of a program. A variable is introduced by a declaration, which declares the name and certain attributes of the variable. A variable is referred to by its name or by a reference derived from its declared name (for example, a structure qualification). Related Information  Data types and attributes  Data aggregates  Declaring data items ═══ Data Types and Attributes ═══ Description You can access and manipulate a wide variety of data items in PL/I. The data items you use may represent values processed by the program or data that controls the execution of the program. Data items are the values of constants and variables. Data used in a PL/I program is either:  Problem data, which is used to represent values to be processed by a program. It consists of the coded arithmetic and string data types.  Program control data, which is used to control the execution of your program. It consists of the data types: area, entry, event, file, label, offset, and pointer. Related Information  Arithmetic data items  Area data items  Entry data items  Event data items  File data items  Label data items  Offset data items  Pointer data items  String data items ═══ Event Data Items ═══ Description Event variables are used to allow a degree of overlap between a record-oriented input/output operation (or the execution of a DISPLAY statement) and the execution of other statements in the procedure that initiated the operation. A variable is given the EVENT attribute by its appearance in an EVENT option or a WAIT statement, or by an explicit declaration. An event variable has two separate values:  A single bit which reflects the completion value of the variable. '1'B indicates complete, and '0'B indicates incomplete.  A real fixed-point binary value of precision (15,0) which reflects the status value of the variable. A zero value indicates normal status, and a nonzero value indicates abnormal status. On allocation of an event variable, its completion value is'0'B (incomplete). The status value is undefined. An event variable can be associated with an event, that is, an input/output operation (or DISPLAY), by means of the EVENT option of a statement. The variable remains associated with the event until the event is completed. For an input/output (or DISPLAY) event, the event is completed during the execution of the WAIT for the associated event which initiated the operation. During this period, the event variable is active. Related Information  Event variable values  Event variable errors  DISPLAY statement  WAIT statement  COMPLETION built-in subroutine  STATUS built-in subroutine Syntax ──────EVENT────── ═══ Arithmetic Data Items ═══ Description You can use arithmetic data items in your programs as variables and constants. Coded arithmetic data items are rational numbers. They have the attributes of base, scale, precision, and mode. Numeric character data is a string data type with arithmetic attributes. This type of data is stored as a character string but can be used in arithmetic computations. These variables must be declared with the PICTURE attribute. Related Information  Numeric character data  Precision attribute Syntax ──────────┬─────────┬──┬────────┬───┬─────────┬──────────────────── ├─BINARY──┤ ├─FIXED──┤ ├─REAL────┤ └─DECIMAL─┘ └─FLOAT──┘ └─COMPLEX─┘ ───────┬────────────────────────────────────────┬─────────────────── └(number-of-digits──┬────────────────┬)──┘ └,scaling factor─┘ 1 1 - Scaling factor applies to fixed-point data items only. ═══ BINARY Attribute ═══ Description The base of a coded arithmetic data item may be binary or decimal. You specify a data item with a binary base by using the BINARY attribute (abbreviation BIN). Binary data items may have either a fixed or floating binary point. Related Information  Binary fixed-point data  Binary floating-point data Syntax ┌─DECIMAL─┐ ────┴─BINARY──┴─────────────────────────────────────────────────────── ═══ DECIMAL Attribute ═══ Description The base of a coded arithmetic data item may be either binary or decimal. You specify a data item with a decimal base with the DECIMAL attribute (abbreviation DEC). Decimal data items may have either a fixed or floating decimal point. Syntax ┌─DECIMAL─┐ ────┴─BINARY──┴───────────────────────────────────────────────────────── Related Information  Decimal fixed-point data  Decimal floating-point data ═══ FIXED Attribute ═══ Description The scale of a coded arithmetic data item is either fixed-point or floating-point. You specify a data item with a fixed decimal point or binary point by using the FIXED attribute. A fixed-point data item is a rational number in which the position of the decimal or binary point is specified, either by its appearance in a constant or by a scaling factor declared for a variable. Fixed-point data items may have either a binary or a decimal base. Syntax ┌─FLOAT──┐ ──┴─FIXED──┴────────────────────────────────────────────────── Related Information  Binary fixed-point data  Decimal fixed-point data ═══ FLOAT Attribute ═══ Description The scale of a coded arithmetic data item is either fixed-point or floating-point. You specify a data item with a floating decimal or binary point with the FLOAT attribute. A floating-point data item is a rational number in the form of a fractional part and an exponent part. Floating-point data items may have either a binary or a decimal base. Syntax ┌─FLOAT─┐ ───┴─FIXED─┴────────────────────────────────────────────────────── Related Information  Binary floating-point data  Decimal floating-point data ═══ REAL Attribute ═══ Description The mode of an arithmetic data item is either real or complex. Both coded arithmetic data and numeric character data can be real values. You specify a data item representing a real value with the REAL attribute. Arithmetic data items default to the REAL attribute. Syntax ┌─REAL────┐ ───┴─COMPLEX─┴─────────────────────────────────────────────── ═══ COMPLEX Attribute ═══ Description The mode of an arithmetic data item is either real or complex. A real data item is a number that expresses a real value. A complex data item consists of the following 2 parts:  the first, a real part  the second, an imaginary part. For a variable representing complex data items, the base, scale, and precision of the 2 parts are identical. Both coded arithmetic data and numeric character data can be complex values. You specify a data item representing a complex value with the COMPLEX (abbreviation CPLX) attribute. Arithmetic variables default to REAL. Therefore, complex arithmetic variables must be explicitly declared with the COMPLEX attribute. Example Using complex data items Syntax ┌─REAL────┐ ───┴─COMPLEX─┴─────────────────────────────────────────────── ═══ Precision Attribute ═══ Description The precision of a coded arithmetic data item is:  For fixed-point, the number of digits the data item contains. For fixed-point data, the precision attribute can also specify the scaling factor.  For floating-point, the number of significant digits to be maintained (excluding the exponent). The precision attribute must follow, with no intervening attribute specifications, the scale (FIXED or FLOAT), base (DECIMAL or BINARY), or mode (REAL or COMPLEX) at the same factoring level. Syntax ──(─number-of-digits──┬───────────────────┬──)───────────── └─,──scaling-factor─┘ ═══ Number of Digits ═══ Description The precision of an arithmetic data item consists of the number of digits in the value followed by an optional scaling factor designating the location of the decimal or binary point in the value. These two precision attributes are enclosed in a single set of parentheses (and separated by a comma if both are present). The number of digits is an integer that specifies how many digits the arithmetic value can have. For fixed-point items, the integer is the number of significant digits. For floating-point items, the integer is the number of significant digits to be maintained, excluding the exponent. Example In the following, X is declared as a fixed-point decimal value with five digits: DECLARE X DECIMAL FIXED(5); ═══ Scaling Factor ═══ The precision of an arithmetic data item consists of the number of digits in the value followed by an optional scaling factor designating the position of the decimal or binary point in the value. These two precision attributes are enclosed in a single set of parentheses (and separated by a comma if both are present). The scaling factor applies to binary fixed-point or decimal fixed-point values only. The scaling factor is an optionally-signed integer. If no scaling factor is specified, the default is 0. The scaling factor is the assumed position of the decimal or binary point relative to the rightmost digit of the value. The precision attribute specification is often represented as (p,q), where "p" represents the number of digits, and "q" represents the scaling factor. A negative scaling factor (-q) specifies an integer, with the point assumed to be located q places to the right of the rightmost actual digit. A positive scaling factor (q) that is larger than the number of digits specifies a fraction, with the point assumed to be located q places to the left of the rightmost actual digit. In either of the above cases, intervening zeros are assumed, but they are not stored. Only the specified number of digits are actually stored. ═══ Binary Fixed-Point Data ═══ Description A binary fixed-point constant consists of one or more binary digits with an optional binary point, followed immediately by the letter "B". Binary fixed-point constants have precision (p,q) where p is the total number of binary digits in the value and q is the number of binary digits specified to the right of the binary point. The data attributes for declaring binary fixed-point data variables are BINARY and FIXED. The default precision is (15,0). A binary fixed-point data item with 15 digits or less is stored as a fixed-point binary halfword. A binary fixed-point data item with 16-31 digits is stored as a fullword. (A halfword is 15 bits plus a sign bit, and a fullword is 31 bits plus a sign bit.) The declared number of digits is in the low-order positions, but the extra high-order digits participate in any operations performed upon the data item. Any arithmetic overflow into such extra high-order positions can be detected only if the SIZE condition is enabled. Example Using binary fixed-point data ═══ Binary Floating-Point Data ═══ Description A binary floating-point constant is a mantissa followed by an exponent and the letter "B". The mantissa is a binary fixed-point value. The exponent is the letter "E", followed by an optionally-signed decimal integer, which specifies a power of two. The exponent cannot exceed three decimal digits. Binary floating-point data items have a precision (p) where p is the number of binary digits of the mantissa. Use the BINARY and FLOAT data attributes for declaring binary floating-point variables. The default precision is (21). Binary floating-point data is stored as normalized hexadecimal floating point. If the declared precision is less than or equal to (21), short floating-point form is used. If the declared precision is greater than (21) and less than or equal to (53), long floating-point form is used. If the declared precision is greater than (53), extended floating-point form is used. Note: You should avoid coding the internal representation of extended precision floating-point values. Under some circumstances, these values will not compare properly with other extended precision floating-point values. To avoid this problem, use binary floating-point constants to specify extended precision floating-point values. Example Using binary floating-point data ═══ Decimal Fixed-Point Data ═══ Description A decimal fixed-point constant consists of one or more decimal digits with an optional decimal point. If no decimal point appears, the point is assumed to be immediately to the right of the rightmost digit. Decimal fixed-point data items have the precision (p,q) where p is the total number of digits in the value and q is the number of digits specified to the right of the decimal point. Use the DECIMAL and FIXED attributes for declaring decimal fixed-point variables. The default precision is (5,0). Decimal fixed-point data is stored as two digits per byte, with a sign indication in the rightmost 4 bits of the rightmost byte. Consequently, a decimal fixed-point data item is always stored as an odd number of digits, even though the declaration of the variable may specify the number of digits, p, as an even number. When the declaration specifies an even number of digits, the extra digit place is in the high-order position, and it participates in any operations performed upon the data item, such as in a comparison operation. Any arithmetic overflow or assignment into an extra high-order digit place can be detected only if the SIZE condition is enabled. Example Using decimal fixed-point data ═══ Decimal Floating-Point Data ═══ Description A decimal floating-point constant is a mantissa followed by an exponent. The mantissa is a decimal fixed-point value. The exponent is the letter "E" followed by an optionally-signed integer, which specifies a power of ten. Decimal floating-point data items have a precision (p) where p is the number of digits in the mantissa. Use the data attributes DECIMAL and FLOAT for declaring decimal floating-point variables. The default precision is (6). Decimal floating-point data is stored as normalized hexadecimal floating-point, with the hexadecimal point assumed to the left of the first hexadecimal digit. If the declared precision is less than or equal to (6), short floating-point form is used. If the declared precision is greater than (6) and less than or equal to (16), long floating-point form is used. If the declared precision is greater than (16), extended floating-point form is used. Note: You should avoid coding the internal representation of extended precision floating-point values. Under some circumstances, these values will not compare properly with other extended precision floating-point values. To avoid this problem, use decimal floating-point constants to specify extended precision floating-point values. Example Using decimal floating-point data ═══ String Data Items ═══ Description A string data item is used to represent a sequence of characters, binary digits, or graphics. The length of the string is the number of characters, binary digits, or graphics it contains. String data items may be used in your programs as constants and variables. Related Information  Numeric character data  Bit string data  Character string data  Graphic string data  Mixed string data ═══ Numeric Character Data (PICTURE Specification) ═══ Description A numeric character data item is the value of a variable that has been declared with the PICTURE attribute and a numeric picture specification. Numeric picture specification describes a character string that can be assigned only data that can be converted to an arithmetic value. For example: DECLARE PRICE PICTURE '999V99'; specifies that any value assigned to PRICE is maintained as a character string of 5 decimal digits, with an assumed decimal point preceding the rightmost 2 digits. Data assigned to PRICE is aligned on the assumed point in the same way that point alignment is maintained for fixed-point decimal data. Numeric character data has arithmetic attributes, but it is not stored in coded arithmetic form. Numeric character data is stored as a character string. Before it can be used in arithmetic computations, it must be converted into either the decimal fixed-point or decimal floating-point data type. These conversions are carried out automatically, but they require extra execution time. Although numeric character data is in character form and it is aligned on a decimal point like arithmetic data, it is processed differently from either character or arithmetic data. Editing characters can be specified for insertion into a numeric character data item, and such characters are actually stored within the data item. Consequently, when the item is printed or treated as a character string, the editing characters are included in the assignment. When a numeric character data item is assigned to another numeric character data item or an arithmetic variable, the editing characters are not included in the assignment. Only the actual digits, signs, and the location of the assumed decimal place is included in the assignment. Example Using numeric character data Syntax ─────PICTURE────'picture specification'──────── The base of a numeric character data item is decimal. Its scale is either fixed-point or floating point (the K or E picture character denotes a floating-point scale). The precision of a numeric character data item is the number of significant digits (excluding the exponent in the case of floating-point). Significant digits are specified by the picture characters for digit positions and conditional digit positions. The scaling factor of a numeric character data item is derived from the V or the F picture character or the combination of V and F. Only decimal data can be represented by picture characters. Complex data can be declared by specifying the COMPLEX attribute along with a single picture specification that describes either a fixed-point or a floating-point data item. ═══ Example- Using Numeric Character Data ═══ If a numeric character item is assigned to another numeric character data item or an arithmetic variable, the editing characters are not included in the assignment. Only the actual digits, signs, and location of the assumed decimal place are assigned. For example: DECLARE PRICE PICTURE '$99V.99', COST CHARACTER (6), VALUE FIXED DECIMAL (6,2); PRICE = 12.28 COST = '$12.28' Above, in the picture specification for PRICE, the currency symbol ($) and the decimal point (.) are editing characters. They are stored as characters in the data item, but are not a part of its arithmetic value. After the two assignments are made, the internal character representation of PRICE and COST are identical. However, they will not always function the same way. For example: VALUE = PRICE; COST = PRICE; VALUE = COST; PRICE = COST; After the first two assignments are made, the value of VALUE is 0012.28 and the value of COST is '$12.28'. In the assignment of PRICE to VALUE, the currency symbol ($) and the decimal symbol (.) are not part of the assignment. The arithmetic value of PRICE is converted to internal coded arithmetic form. In the assignment of PRICE to COST, however, the assignment is to character string, and the editing characters of a numeric picture specification always participate in such assignments. No conversion is necessary in this assignment. No conversion is necessary because PRICE is stored in character form. The third and fourth statements would raise the CONVERSION condition. The value of COST cannot be assigned to VALUE because the currency symbol in the string makes it invalid as an arithmetic constant. The value of COST cannot be assigned to PRICE for the same reason. Only values that are of arithmetic type, or can be converted to arithmetic type, can be assigned to a variable declared with a numeric picture specification. Although the decimal point can be an editing character or an actual character in a character string, it will not raise CONVERSION in converting to arithmetic form, since its appearance is valid in an arithmetic constant. The same is true for a valid plus or minus sign, since converting to arithmetic form provides for a sign preceding an arithmetic constant. Other editing characters, including zero suppression characters, drifting characters, and insertion characters, can be used in numeric picture specifications. ═══ Picture Specification Characters ═══ Description A picture specification consists of a sequence of picture characters (enclosed in quotation marks) which is part of the PICTURE attribute. The picture specification describes a character data item or a numeric character data item. A character pictured item can consist of alphabetic characters, decimal digits, blanks, and any other EBCDIC codes. A numeric character pictured item can consist only of decimal digits, an optional decimal point, an optional letter "E", and optionally, one or two plus or minus signs. Other characters generally associated with arithmetic data, such as currency symbols, can also be specified, but they are not a part of the arithmetic value of the numeric character variable, although the characters are stored with the digits and are part of the character value of the variable. A picture repetition factor can be used to specify a number of repetitions of a picture character immediately following the repetition factor. Related Information  Picture characters for character data  Picture characters for numeric character data  P-format item ═══ Picture Characters for Character Data ═══ Description A character picture specification describes a fixed-length character data item, with the additional facility of indicating that any position in the data item can only contain characters from certain subsets of the complete set of available characters. A character picture specification is recognized by the occurrence of an 'A' or 'X' picture specification character. The only valid characters in a character picture specification are 'X', 'A', and '9': X Any character of the 256 possible bit combinations represented by the 8-bit byte. A Any alphabetic character, #, @, $, or blank. 9 Any digit or blank. (Note that the 9 picture specification character in numeric character specifications is different in that the corresponding character can only be digit.) When a character value is assigned, or transferred, to a pictured character data item, the particular character in each position is checked for validity, as specified by the corresponding picture specification character, and the CONVERSION condition is raised for an invalid character. Examples Examples of picture characters ═══ Picture Characters for Numeric Character Data ═══ Numeric character data represents numeric values; therefore, the associated picture specification cannot contain the characters "X" or "A" (reserved for character data items). The picture characters for numeric data can specify editing of the data. A numeric character variable can be thought of as having two different kinds of value, depending on its use. They are: Arithmetic value The arithmetic value is the value expressed by the decimal digits of the data item, the assumed location of a decimal point, possibly a sign, and an optionally signed exponent or scaling factor. The arithmetic value of a numeric character variable is used:  Whenever the variable appears in an expression that results in a coded arithmetic value or bit value  Whenever the variable is assigned to a coded arithmetic, numeric character, or bit variable  When used with the C, E, F, B, and P (numeric) format items in edit-directed I/O In such cases, the arithmetic value of the numeric character variable is converted to internal coded arithmetic representation. Character value The character value is the value expressed by the decimal digits of the data item as well as all of the editing and insertion characters appearing in the picture specification. The character value does not include the assumed location of a decimal point. The character value of a numeric character variable is used:  Whenever the variable appears in a character expression  In an assignment to a character variable  Whenever the data is printed using list-directed or data-directed output  Whenever a reference is made to a character variable that is defined or based on the numeric character variable  Whenever the variable is printed using edit-directed output with the "A" or "P" character format items The picture characters for numeric character specifications can be grouped into the following categories:  Credit, debit, overpunched, and zero replacement characters  Digit and decimal point characters  Exponent identifier characters  Insertion characters  Scaling factor character  Signs and currency characters  Zero suppression characters. All characters except for K, V, and F specify the occurrence of a character in the character representation. A numeric character specification consists of one or more "fields", each field describing a fixed-point number. A floating-point specification has two fields---one for the mantissa and one for the exponent. The first field can be divided into "subfields" by inserting a V picture specification character; the portion preceding the V (if any) and that following it (if any) are subfields of the specification. A requirement of the picture specification for numeric character data is that each field must contain at least one picture character that specifies a digit position. This picture character, however, need not be the digit character 9. Other picture characters, such as the zero suppression characters (Z or *), also specify digit positions. ═══ Digit and Decimal Point Characters ═══ The picture characters "9" and "V" are used in numeric character specifications that represent fixed-point decimal values: 9 specifies that the associated position in the data item contains a decimal digit. (The definition of 9 in a character picture is different in that the corresponding character can be blank or a digit.) V specifies that a decimal point is assumed at this position in the associated data item. However, it does not specify that an actual decimal point or decimal comma is inserted. If no V character appears in the picture specification of a fixed-point decimal value (or in the first field of a floating- point decimal value), a V is assumed at the right end of the field specification. This can cause the assigned value to be truncated, if necessary, to an integer. The V character cannot appear more than once in a picture specification. For example: DCL VALUE PICTURE 'Z9V999'; VALUE = 12.345; DCL CVALUE CHAR(5); CVALUE = VALUE; CVALUE, after assignment of VALUE, contains '12345'. ═══ Zero Suppression Characters ═══ The picture characters "Z" and "*" (asterisk) specify conditional digit positions in the character value and can cause leading zeros to be replaced by asterisks or blanks. Z specifies a conditional digit position and causes a leading zero in the associated data position to be replaced by a blank character. Otherwise the digit in the position is left unchanged. The picture character Z cannot appear in the same field as the picture character *, or a drifting character, nor can it appear to the right of any of the picture characters 9, T, I, R, or Y in a field. * specifies a conditional digit position. It is used the way the picture character Z is used, except that leading zeros are replaced by asterisks instead of blank characters. The * picture character faces the same restrictions listed above for the Z picture character. If one of the picture characters Z or * appears to the right of the picture character V, all fractional digit positions in the specification, as well as all integer digit positions, must employ the Z or * picture character, respectively. When all digit positions to the right of the picture character V contain zero suppression picture characters, fractional zeros of the value are suppressed only if all positions in the fractional part contain zeros and all integer positions have been suppressed. The character value of the data item will then consist of blanks or asterisks. No digits in the fractional part are replaced by blanks or asterisks if the fractional part contains any significant digit. ═══ Insertion Characters ═══ Description The picture characters "," (comma), "." (point), "/" (slash), and "B" (blank) cause the specified character to be inserted into the associated position of the numeric character data. They do not indicate digit or character positions, but are inserted between digits or characters. Each does, however, actually represent a character position in the character value, whether or not the character is suppressed. The comma, point, and slash are conditional insertion characters and can be suppressed within a sequence of zero suppression characters. The blank (B) is an unconditional insertion character; it always specifies that a blank appears in the associated position. Insertion characters are applicable only to the character value. They specify nothing about the arithmetic value of the data item. They never cause decimal point or decimal comma alignment in the picture specifications of a fixed-point decimal number and are not part of the arithmetic value of the data item. Decimal alignment is controlled by the picture characters V and F. , inserts a comma into the associated position of the numeric character data when no suppression occurs. If zero suppression does occur, the comma is inserted only:  When an unsuppressed digit appears to the left of the comma position  When a V (decimal point character) appears immediately to the left of the comma and the fractional part contains any significant digits  When the comma is at the start of the picture specification  When the comma is preceded only by characters not specifying digit positions Note: In all other cases where zero suppression occurs, the comma insertion character is treated as though it were a zero suppression character identical to the one immediately preceding it. . is used the same way the comma picture character is used, except that a point "." is assigned to the associated position. / is used the same way as the comma picture character is used, except that a slash "/" is inserted in the associated position. B specifies that a blank character always be inserted into the associated position of the character value of the numeric character data. Related Information Using insertion characters with the "V" decimal point character ═══ Signs and Currency Characters ═══ The picture characters "S", "+" and "-" specify signs in numeric character data. The picture character '$' specifies a currency symbol in the character value of numeric character data. Only one type of sign character can be used in each field. These picture characters are available for either static usage or drifting usage. $ specifies the currency symbol. The static character must appear either to the left or right of all digit positions in a field of specification. S specifies the plus sign character (+) if the data value is >=0. Otherwise, it specifies the minus sign character (-). The rules are identical to those for the currency symbol above. + specifies the plus sign character (+) if the data value is >=0. Otherwise, it specifies a blank. The rules are identical to those for the currency symbol above. - specifies the minus sign character (-) if the data value is <0. Otherwise, it specifies a blank. The rules are identical to those for the currency symbol above. If, during, or before assignment to a picture, the fractional digits of a decimal number are truncated so that the resulting value is zero, the sign inserted in the picture corresponds to the value of the decimal number prior to its truncation. Therefore, the sign in the picture depends on how the decimal value was calculated. ═══ Credit, Debit, Overpunched, and Zero Replacement Characters ═══ The picture characters "CR", "DB", "T", "I", and "R" cannot be used with any other sign characters in the same field.  The CR and DB (credit and debit) sign characters specify the signs of real numeric character data items.  Any of the picture characters T, I, or R (overpunched identifiers). specifies that an EBCDIC character represents the corresponding digit and the sign of the data item.  The Y picture character specifies that zero is replaced by the blank character. The replacement is unconditional. ═══ Exponent Identifier Characters ═══ Description The picture characters K and E delimit the exponent field of a numeric character specification that describes floating-point decimal numbers. The exponent field is the last field of a numeric character floating-point picture specification. The picture characters K and E cannot appear in the same specification. K specifies that the exponent field appears to the right of the associated position. It does not specify a character in the numeric data item. E specifies that the associated position contains the letter E, which indicates the start of the exponent field. The value of the exponent is adjusted in the character value so that the first significant digit of the first field (the mantissa) appears in the position associated with the first digit specifier of the specification. Examples Exponent picture specifications ═══ Exponent Picture Specifications ═══ Following are some examples of exponent characters in picture specification: SOURCE ATTRIBUTES SOURCE DATA PICTURE SPECIFICATION CHARACTER VALUE _____________________________________________________________________________ FLOAT(5) .12345E06 V.99999E99 .12345E06 FLOAT(5) .12345E-06 V.99999E99 .12345E-06 FLOAT(5) .12345E+06 V.99999KS99 .12345+06 _____________________________________________________________________________ FLOAT(5) -123.45E+12 S999V.99ES99 -123.45E+12 FLOAT(5) 001.23E-01 SSS9.V99ESS9 +123.00Eb-3 FLOAT(5) 001.23E+04 ZZZV.99KS99 123.00+02 _____________________________________________________________________________ FLOAT(5) 001.23E+04 SZ99V.99ES99 +123.00E+02 FLOAT(5) 001.23E+04 SSSSV.99E-99 +123.00Eb02 ═══ Scaling Factor Character ═══ Description The picture character "F" specifies a picture scaling factor for fixed-point decimal numbers. It can only appear once at the right end of the picture specification. F specifies that the decimal point in the arithmetic value of the variable is that number of places (F) to the right (if F>0) or to the left (if F<0) of its assumed position in the character value. The number of digits following the "V" (decimal point) picture character minus the integer specified with F must be between -128 and 127. Example Using picture scaling factors Syntax ───────F──(──┬──────┬───integer──)─────────────── ├──+───┤ └──-───┘ ═══ Using Picture Scaling Factors ═══ Following are some examples of scaling factor characters: SOURCE ATTRIBUTES SOURCE DATA PICTURE SPECIFICATION CHARACTER VALUE _____________________________________________________________________________ FIXED(4,0) 1200 99F(2) 12 FIXED(7,0) -1234500 S999V99F(4) -12345 FIXED(5,5) .00012 99F(-5) 12 _____________________________________________________________________________ FIXED(6,6) .012345 999V99F(-4) 12345 _____________________________________________________________________________ ═══ Using Drifting Strings ═══ Description The drifting use specifies that leading zeros are to be suppressed. In this case, the rightmost suppressed position associated with the picture character will contain a sign, a blank, or a currency symbol (except that where all digit positions are occupied by drifting characters and the value of the data item is zero, the drifting character is not inserted). A drifting character is specified by multiple use of that character in a picture field. Usage Rules  The drifting character must be specified in each digit position through which it can drift.  Any of the insertion characters slash, comma, or point within or immediately following the string is part of the drifting string.  A field of a picture specification can contain only one drifting string.  A drifting string cannot be preceded by a digit position, nor can it occur in the same field as the picture characters * and Z.  The position in the data associated with the characters slash, comma, and point appearing in a string of drifting characters will contain one of the following: - Slash, comma or point if a significant digit appears to the left - The drifting symbol, if the next position to the right contains the leftmost significant digit of the field - Blank, if the leftmost significant digit of the field is more than one position to the right.  If a drifting string contains the drifting character n times, the string is associated with n-1 conditional digit positions. The position associated with the leftmost drifting character can contain only the drifting character or blank, never a digit. Two different picture characters cannot be used in a drifting manner in the same field.  If a drifting string contains a "V" within it, the V delimits the preceding portion as a subfield, and all digit positions of the subfield following the V must also be part of the drifting string that commences the second subfield.  In the case in which all digit positions after the "V" contain drifting characters, suppression in the subfield occurs only if all of the integer and fractional digits are zero. The resulting edited data item is then all blanks (except for any insertion characters at the start of the field). If there are any nonzero fractional digits, the entire fractional portion appears, unsuppressed.  Drifting characters must appear in a sequence of the same drifting character, optionally containing a "V" and one of the insertion characters; "," (comma), "." (point), "/" (slash), or "B".  A "V" terminates the drifting string unless the arithmetic value of the string is zero, in which case the V is ignored.  The character "B" always causes insertion of a blank, wherever it appears. ═══ Overpunched Identifiers ═══ Any of the picture characters "T", "I", or "R" (known as overpunched characters) specifies that an EBCDIC character represents the corresponding digit and sign of the data item. This representation has arisen from the custom of indicating signs in numeric data held on punched cards, by overpunching a 12-punch (to represent +) or an 11-punch (to represent -) near the top of a card column containing a digit (usually the last column in a field). The rsulting EBCDIC card-code is, in most cases, the same as that for an alphabetic character. The 12-0 and 11-0 combinations are not characters in the PL/I set but are within the set of the 256 characters of the EBCDIC code. Only one overpunched sign can appear in a specification for a fixed-point number. A floating-point specification can contain two overpunched characters: one in the mantissa field and one in the exponent field. The overpunch character can be specified for any digit position within a field. T On input, T specifies that the EBCDIC characters { through I and the digits 0 through 9 represent positive values, and the EBCIDIC characters } through R represent negative values. On output, T specifies that the associated position contains one of the EBCDIC characters { through I if the input data represents positive values and one of the EBCDIC characters } through R if the input data represents negative values. The T can appear anywhere a "9" (digit character) picture specification character occurs. For example: DCL CREDIT PICTURE 'ZZV9T'; The character representation of CREDIT is 4 characters. +21.05 is held as '210E'. -0.07 is held as 'bb0P'. I On input, I specifies that the EBCIDIC characters { through I and the digits 0 through 9 represent positive values. On output, I specifies that the associated position contains one of the EBCIDIC characters { through I if the input data represents positive values; otherwise it contains one of the digits 0 through 9. R On input, R specifies that the EBCDIC characters } through R represent negative values and the digits 0 through 9 represent positive values. On output, R specifies that the associated position contains one of the EBCIDIC characters } through R if the input data represents negative values; otherwise, it contains one of the digits 0 through 9. The following table shows the interpretation of the T, I and R picture characters: ┌─────────────────────────────────────────────────┬───────┐ │ T │ │ ├────────────────────────┬────────────────────────┤ │ │ I │ R │ │ │ Digit with + │ Digit with - │ │ ├────────────────────────┼────────────────────────┤ Digit │ │ │ │ │ │ EBCDIC EBCDIC │ EBCDIC EBCDIC │ │ │ character card code │ character card code │ │ ├────────────────────────┼────────────────────────┼───────┤ │ │ │ │ │ { 12-0 │ } 11-0 │ 0 │ │ A 12-1 │ J 11-1 │ 1 │ │ B 12-2 │ K 11-2 │ 2 │ │ C 12-3 │ L 11-3 │ 3 │ │ D 12-4 │ M 11-4 │ 4 │ │ E 12-5 │ N 11-5 │ 5 │ │ F 12-6 │ O 11-6 │ 6 │ │ G 12-7 │ P 11-7 │ 7 │ │ H 12-8 │ Q 11-8 │ 8 │ │ I 12-9 │ R 11-9 │ 9 │ └────────────────────────┴────────────────────────┴───────┘ ═══ Bit Data ═══ Description A bit value can only contain bits 0 and 1. A collection of 8 or less unaligned bits occupies 1 byte of storage. You can use bit strings in your programs as constants and variables. Bit strings may also be represented in hexadecimal notation. Related Information  Bit string constants  B4 (Bit Hex) bit string constants  Bit string variables ═══ Bit String Constants ═══ Description A bit constant is represented by a series of the digits 0 and 1, enclosed in single quotation marks and followed immediately by the letter "B". A null bit constant is written as two quotation marks with no intervening blank, followed immediately by the letter "B". Examples Examples of some bit string constants are: CONSTANT LENGTH _________________________________ '1'B 1 '11111010110001'B 14 (64)'0'B 64 ''B 0 The parenthesized number in the third constant above is a string repetition factor which specifies that the following series of digits be repeated the specified number of times. The example shown would result in a string of 64 binary zeros. Syntax ──────'────┬─────────────────────────────┬────'B──── │ ┌────────────────────────┐ │ │  │ │ └──────┬──0──┬──────────────┴─┘ └──1──┘ ═══ B4 (Bit Hexadecimal) Bit String Constants ═══ Description The B4 string constant describes a bit string constant in hexadecimal notation. You can use it in the same places where you use a bit string constant. The B4 constant is a convenient way to represent long bit strings. Note: The term BX is a synonym for B4. Examples Some examples of B4 string constants and their bit equivalents are: 'CA'B4 is the same as '11001010'B '80'B4 is the same as '10000000'B '1'B4 is the same as '0001'B (2)'F'B4 is the same as '11111111'B ''B4 is the same as ''B Syntax ──────'────┬─────────────────────────────┬────'B4───── │ ┌────────────────────────┐ │ │  │ │ └────hex-digit──────────────┴─┘ ═══ Bit String Variables ═══ Description The BIT data attribute specifies a bit variable. A bit variable can only contain bits 0 and 1. A collection of 8 or less unaligned bits occupies 1 byte of storage. Syntax ─────BIT──┬───────────────────────────────────────┬────── └──(─length──┬─────────────────────┬─)──┘ └─REFER─(─variable─)──┘ ═══ Length Specification ═══ Description length specifies the length of a fixed-length string or the maximum length of a varying-length string. If length is not specified, the default is 1. The length is in:  bits for bit string  characters for character string  graphics (DBCS characters) for graphic strings. Usage Restrictions Consider the following rules when specifying string lengths:  You can specify length by an expression or an asterisk, but certain restrictions apply when specifying the length specifications of the elements of data aggregates in parameter descriptors. Expressions can be used only for controlled parameters, and asterisks must not be used if a dummy is created in the corresponding argument.  If the length specification is an expression, it is evaluated and converted to FIXED BINARY, which must be positive, when storage is allocated for the variable.  The asterisk notation can be used for parameters or controlled variables. For controlled variables, the length can be taken from a previous allocation or it can be specified in a subsequent ALLOCATE statement.  If the string has the STATIC attribute, length must be an integer.  If the string has the BASED attribute, length must be an integer unless the string is a member of a based structure and the REFER option is used. Related Information VARYING attribute ═══ REFER Option ═══ Description REFER is used in the declaration of a based structure to specify that, on allocation of the structure, the value of an expression is assigned to a variable in the structure and represents the length, bound, or size of another variable in the structure. String lengths can be defined by variables declared within a based structure. Syntax ────expression──REFER──(─variable─)────────────────────── ═══ VARYING Attribute ═══ Description VARYING specifies that the variable is to represent varying-length strings, in which case length (in the BIT, CHARACTER, or GRAPHIC attribute) specifies the maximum length. The length at any time is the length of the current value. The storage allocated for varying-length strings is 2 bytes longer that the declared maximum length. The leftmost 2 bytes hold the string's current length in:  Bytes for a character variable.  Bits for a bit variable.  Graphics for a graphic variable. Example The following declaration specifies that the variable USER represents varying-length character data items with a maximum length of 15: DECLARE USER CHARACTER (15) VARYING; The length for USER at any time is the length of the data item assigned to it at that time. You can determine the length at any given time by use of the LENGTH built-in function. Syntax ──────VARYING────────────────────── ═══ Character String Data ═══ Description When declared with the CHARACTER attribute, a character value can include any digit, letter, special character, blank, or any other of the 256 bit combinations in a byte. Each character of a character value occupies 1 byte of storage. When declared with the PICTURE attribute, the character value assigned must match the picture specification. You can use character data items as constants and variables in your programs. Related Information  Character string constants  X (Hex) character string constants  Character string variables ═══ Character String Constants ═══ Description A character constant is a contiguous sequence of characters enclosed in single quotation marks. If a single quotation mark is a character in a string, it must be written as two single quotation marks with no intervening blanks. The length of a character constant is the number of characters between the enclosing quotation marks. However, if two single quotation marks are used within a string to represent a single quotation mark, they are counted as a single character. A null character constant is written as two quotation marks with no intervening blanks. Examples Examples of character constants are: CONSTANT LENGTH ______________________________________ 'logarithm table' 15 'page 5' 6 'Shakespeare''s ''Hamlet''' 25 'AC438-19' 8 '/* THIS IS NOT A COMMENT */' 27 '' 0 (2)'WALLA ' 12 In the last example, the parenthesized number is a string repetition factor which indicates repetition of the characters that follow. In this case, the result is "WALLA WALLA ". The string repetition factor must be an integer, enclosed in parentheses. Syntax ────'──┬────────────────────┬──'─────────── │ ┌──────────────┐ │ │  │ │ └───┬─character─┬─┴──┘ └─────"─────┘ ═══ X (Hex) Character String Constants ═══ Description The X string constant describes a character string constant in hexadecimal notation. You can use the X constant to manipulate non-printable character strings. You can also use the X string constant in preprocessor statements. A null hex character string constant is two single quotes followed by an "X". An even number of hexadecimal digits must be specified. The use of X (hex) character string constants may limit the portability of your program. Syntax ──────'────┬───────────────────────────────────────┬────'X───── │ ┌──────────────────────────────────┐ │ │  │ │ └────hex-digit hex-digit──────────────┴─┘ ═══ Character String Variables ═══ Description The CHARACTER (abbreviation CHAR) attribute specifies a character variable. Character variables can contain any digit, letter, special character, blank, or any of the other 256 bit combinations in a byte. Syntax ─────CHARACTER──┬───────────────────────────────────────┬─────────── └──(─length──┬─────────────────────┬─)──┘ └─REFER─(─variable─)──┘ ═══ Graphic String Data ═══ Description When declared with the GRAPHIC attribute, a graphic value can contain any graphic, each occupying 2 bytes of storage. You can use graphic string data items in your programs as constants and variables. A graphic string may also be represented with hexadecimal notation. Related Information  Graphic string constants  GX (Graphic Hex) graphic string constants  Graphic string variables ═══ Graphic String Constants ═══ Description A graphic constant can contain values in the range X'00' through X'FF' in both bytes. However, you cannot use X'0E' and X'0F'. The constant must contain an even number of bytes, including zero (a null graphic constant). The GRAPHIC compile-time option must be in effect for graphic constants to be accepted. If the GRAPHIC ENVIRONMENT option is not specified for STREAM I/O files having graphic constants, the conversion condition is raised. Enclose the graphic values in quotes and use the G suffix after them. The quotes can be either single byte (outside the shift-out shift-in pair, <>) or double byte (inside the shift-out shift-in pair). However, the beginning and the ending quote must match. The G suffix can also be single or double byte. The preferred form for a graphic constant is : ''G where GG is a valid two-byte graphic. Other allowable forms are: <.'GGGG.'>G <.'GGGG.'.G> Some of the ways to represent the null graphic constant are : '<>'G <.'.'>G <.'.'.G> or ''G If you include a DBCS quotation mark within a graphic constant, and DBCS quotes enclose the GRAPHIC constant, you must double the included quote. The following examples show graphic constants that contain one DBCS quote: <.'.'.'.'>G /* contained quote doubled */ '<.'>'G /* single contained quote */ Syntax ────'──┬───────────────────────────┬──'G────────── │ ┌─────────────────────┐ │ │  │ │ └──<──graphic symbol──>──┴──┘ ═══ GX (Graphic Hex) Graphic String Constants ═══ Description The GX string constant describes a GRAPHIC constant using hexadecimal notation. The data type remains GRAPHIC. You can use GX string constants wherever you use character string constants. You do not need the GRAPHIC compile-time option or the GRAPHIC ENVIRONMENT option to use the GX string constant. Four hexadecimal digits (two bytes) represent each graphic element. Therefore, you must specify a number of digits that are a multiple of four. Enclose the digits in quotes and use the "GX" suffix after them. The use of GX might limit the portability of your program. Examples '42C142C242C3'GX is the same as '<.A.B.C>'G ''GX is the same as ''G Syntax ────'──┬─────────────────────────┬──'GX───────── │ ┌───────────────────┐ │ │  │ │ └─────hex-digit group──┴──┘ ═══ Graphic String Variables ═══ Description The GRAPHIC (abbreviation G) attribute specifies a graphic variable. Graphic variables can contain any DBCS characters. The variable must contain an even number of bytes. Syntax ─────GRAPHIC────┬───────────────────────────────────────┬─────────── └──(─length──┬─────────────────────┬─)──┘ └─REFER─(─variable─)──┘ ═══ Mixed String Data ═══ Description Mixed data can contain SBCS and DBCS data. Mixed data is represented by the CHARACTER data type, and follows the processing rules for character data. The GRAPHIC compile-time option must be in effect for mixed string constants to be accepted. If the GRAPHIC ENVIRONMENT option is not specified for STREAM I/O files having mixed constants, the CONVERSION condition is raised. Quotes must enclose a mixed character string constant (either SBCS or DBCS) and the M suffix must follow it. The data always begins and ends in SBCS, and shift codes enclose the DBCS portions. The following rules apply:  Shift-out/shift-in pairs must match; you cannot nest pairs.  The DBCS portion cannot contain '0E'X or 'OF'X in either byte.  The characters portion cannot contain the values '0E'X or '0F'X, unless specifically intended as shift codes. Examples Using mixed string constants Syntax ────'──┬──────────────────────────────────┬───'M───────────────── │ ┌───────────────────────────┐ │ │  │ │ └──┬──character──────────────┬─┴───┘ ├──"──────────────────────┤ │ ┌─────────────────┐ │ │  │ │ └──<──graphic-symbol──┴─>─┘ ═══ Area Data Items ═══ Description Area variables describe the 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, storage is obtained from wherever it is available. Consequently, allocated based variables can be scattered widely throughout main storage. This is not significant for internal operations because items are readily accessed using the pointers. However, if these allocations are transmitted to a data set, the items have to be collected together. Items allocated within an area variable are already collected and can be transmitted or assigned as a unit while retaining their separate identities. Review the following rules regarding the use of area variables:  Offset variables can be used to identify the locations of based variables within area variables.  An area can be assigned or transmitted complete with its contained allocations. Therefore, a set of based allocations can be treated as one unit for assignment and input/output while each allocation retains its original identity.  The size of an area is adjustable in the same way as string length or an array bound, and therefore can be specified by an expression or by a REFER option for a based area.  A variable is given the AREA attribute contextually by its appearance in the OFFSET attribute or an IN option, or by explicit declaration.  No operators, including comparison, can be applied to area variables. Examples Examples of AREA declarations are: DECLARE AREA1 AREA(2000), AREA2 AREA; Related Information Additional area variable storage considerations Syntax ───AREA──┬────────────────────────────────────┬───── ├─(*)────────────────────────────────┤ └─(expression──┬─────────────────┬─)─┘ └─REFER(variable)─┘ ═══ Area Variable Storage ═══ Review the following rules regarding storage considerations for area variables:  The area size for areas that have the storage classes AUTOMATIC or CONTROLLED is given by an expression whose integer value specifies the number of reserved bytes.  If an area has the BASED attribute, the area size must be an integer unless the area is a member of a based structure and the REFER option is used.  The size for areas of static storage class must be specified as an integer.  In addition to the declared size, an extra 16 bytes of control information precedes the reserved size of an area. It contains details such as the amount of storage in use.  The amount of reserved storage that is actually in use is known as the extent of the area. When an area variable is allocated, it is empty (the area extent is zero). The maximum extent is represented by the area size. Based variables can be allocated and freed within an area at any time during execution, thus varying the extent of the area.  When a based variable is freed, the storage it occupied is available for other allocations. A chain of available storage within an area is maintained; the head of the chain is held within the control information.  Inevitably, as based variables with different storage requirements are allocated and freed, gaps will occur in the area when allocations do not fit available spaces. These gaps are included in the extent of the area. ═══ Label Data Items ═══ Description A label data item is a label constant or the value of a label variable. Use labels to identify parts of your programs. The LABEL attribute specifies that the name being declared is a label variable and has label constants as values. To aid in optimization of the object program, the attribute specification can also include the values that the name can have during execution of the program. If a list of label-constants is given, the variable must have as its value a member of the list when used in a GO TO statement or R-format item. The label-constants in the list must be known in the block containing the declaration. The maximum allowable number of label-constants in the list is 125. The parenthesized list of label-constants can be used in a LABEL attribute specification for a label array. A label variable can have another label variable or a label constant assigned to it. When such an assignment is made, the environment of the source label is assigned to the target. Examples Using label data items Syntax ───────LABEL──┬───────────────────────┬───────────────────────────────── │ ┌─,──────────────┐ │ └─(┴─label-constant─┘─)─┘ ═══ Examples- Using Label Data Items ═══ You can use label data items as constants and variables in your programs. For example:  In the following example, ABCDE is a label constant. The statement can be executed either by normal sequential execution of instructions or by transferring control to this statement from some other point in the program by means of a GO TO statement. ABCDE: MILES = SPEED*HOURS  In the following example, transfer is made to a particular element of the array Z by giving I a value of 1, 2, or 3. If I=2, omitting Z(2) would cause an error. DECLARE Z(3) LABEL; GO TO Z(I); . . Z(1): IF X = Y THEN RETURN; . . Z(2): A = A + B + C * D; . . Z(3): A = A + 10; ═══ Data Aggregates ═══ Description Data items can be single data elements, or they can be grouped together to form data aggregates. Data aggregates are groups of data items that can be referred to either collectively or individually and can either be arrays or structures. Any type of data can be grouped into arrays or structures. Both arrays and structures use a name to refer to aggregate of data. Unlike arrays, however, each data element in a structure also has a name. Related Information  Array declarations  Structure declarations ═══ Declaring Data Items ═══ Description When a PL/I program is executed, it manipulates many different data items. Each data item, except an arithmetic or string constant, is referred to in the program by a name. You give attributes and meaning to a data name by using an explicit or implicit declaration. Most attributes of data items are known at the time the program is compiled. For non-STATIC items, attribute values (the bounds of the dimensions of arrays, the lengths of strings, area sizes, initial values) and some file attributes may not be determined until execution of the program. Related Information  Explicit declarations  Implicit declarations  Array declarations  Structure declarations  Alignment and attributes  Scope of declarations  Defaults for attributes ═══ Explicit Declarations ═══ Description A name is explicitly declared if it appears:  In a DECLARE statement. The DECLARE statement explicitly declares attributes of names.  In a parameter list. When a name appears in a parameter list, it is that same as if a DECLARE statement for that name appeared immediately following the PROCEDURE or ENTRY statement in which the parameter list occurs (though that same name can also appear in a DECLARE statement internal to the same block).  As an entry constant. Labels of PROCEDURE and ENTRY statements constitute declarations of the entry constants within the containing procedure.  As a label constant. A label constant may be non-executable statement that constitutes an explicit declaration of the label constant within the containing procedure. Example Using explicit declarations Related Information Scope of declarations ═══ Using Explicit Declarations ═══ You can explicitly declare variables in your PL/I programs. The scope of an explicit declaration of a name is the block containing the declaration. This includes all contained blocks, except those blocks (and any blocks contained within them) to which another explicit declaration of the same name is internal. Consider the following example: P A B B' C C' D Q R ┌─ ┌─ ┌─ ─┐ │ │ │ P: PROC; │ │ │ │ │ │ │ │ DCL A, B; │ │ │ └─ ┌─ ─┐ │ ─┐ │ │ │ Q: PROC; │ │ │ │ │ │ │ │ │ │ │ │ DCL B, C; │ │ │ │ │ │ ─┘ ─┐ ─┐ │ │ │ │ │ R: PROC; │ │ │ │ │ │ │ │ │ │ │ │ │ │ DCL C,D; │ │ │ │ │ │ │ │ │ │ │ │ │ │ END R; │ │ │ │ │ │ │ ─┐ ─┘ ─┘ │ │ │ │ └─ END Q; │ │ │ │ │ ┌─ ─┘ │ ─┘ │ │ │ END P; │ └─ └─ └─ ─┘ The lines indicate the scope of the declaration of the names. B and B' indicate the two distinct uses of the name B; C and C' indicate the two distinct uses of the name C. ═══ DECLARE Statement ═══ Description The DECLARE statement (abbreviation DCL) specifies some or all of the attributes of a name. Certain attributes are often determined by context. If the attributes are not explicitly declared and cannot be determined by context, default attributes are applied. In some cases, the combination of defaults and context determination make it unnecessary to use a DECLARE statement. DECLARE statements can be an important part of the documentation of a program. Consequently, you can make liberal use of declarations, even when default attributes suffice or when an implicit declaration is possible. Condition prefixes cannot be attached to a DECLARE statement. Related Information  Attribute specification  Factoring of attributes Syntax ┌─────────────────────────,────────────────────────┐  │ ────DECLARE────┬─────────┬──name──┬───────────────┬──┬────────┬─┴─;── └──level──┘ │ ┌───────────┐ │ └─SYSTEM─┘ │  │ │ └───attribute─┴─┘ where attribute is: ┌──ALIGNED─────┐ ├──AREA────────┤ ├──AUTOMATIC───┤ ├──BASED───────┤ ├──BINARY──────┤ ├──BIT─────────┤ ├──BUILTIN─────┤ ├──CHARACTER───┤ ├──COMPLEX─────┤ ├──CONDITION───┤ ├──CONNECTED───┤ ├──CONTROLLED──┤ ├──DECIMAL─────┤ ├──DEFINED─────┤ ├──ENTRY───────┤ ├──EXTERNAL────┤ ├──EVENT───────┤ ├──FILE────────┤ ├──FIXED───────┤ ├──FLOAT───────┤ ├──GRAPHIC─────┤ ├──INITIAL─────┤ ├──INTERNAL────┤ ├──LABEL───────┤ ├──OFFSET──────┤ ├──OPTIONS─────┤ ├──PICTURE─────┤ ├──POINTER─────┤ ├──POSITION────┤ ├──REAL────────┤ ├──RETURNS─────┤ ├──STATIC──────┤ ├──UNALIGNED───┤ ├──VARIABLE────┤ └──VARYING─────┘ Aggregate Variables: Arrays (dimension) may be added to the declaration of any variable. Structures  For a major structure; scope, storage (except INITIAL), and alignment, and the LIKE attribute may be specified.  For a minor structure; alignment and the LIKE attribute may be specified.  Members of structure have the INTERNAL attribute. _____________________________________________________________________________________________ Notes 1. Undeclared names, or names declared without a data type, default to coded arithmetic variables. 2. Arrays of nonstatic label variables may be initialized by subscripted label prefixes. 3. STATIC ENTRY and STATIC LABEL conflict with INITIAL. 4. INITIAL CALL conflicts with STATIC. 5. POSITION can be used only with string overlay defining. 6. FILE constant attributes are described in Declaring File Constants. ═══ Attribute Specification ═══ In an explicit declaration, the attributes can appear in any order, except for the dimension and the precision attributes. All attributes given explicitly for a name must be declared together in a DECLARE statement, except that:  Names having the FILE attribute can also be given attributes in an OPEN statement (or have attributes implied by an implicit opening) as well.  The parameter attribute is explicitly declared by the appearance of the name in a parameter list. A DECLARE statement internal to the block can specify additional attributes. Attributes of external names, in separate blocks and compilations, must be consistent (except that an INITIAL attribute given in one declaration in a compiled procedure need not be repeated). The use of the OPTIONS attribute does not imply ENTRY. ═══ Factoring of Attributes ═══ Description Attributes common to several names can be factored to eliminate repeated specification of the same attribute. Factoring is achieved by enclosing the names in parentheses followed by the set of attributes which apply to all of the names. The dimension attribute can be factored. The precision attribute can be factored only in conjunction with an associated keyword attribute. Factoring can also be used on elementary names within structures. A factored level number must precede the parenthesized list. Declarations within the parenthesized list are separated by commas. No factored attribute can be overridden for any of the names, but any name within the list can be given other attributes as long as there is no conflict with the factored attributes. Examples The following examples show factoring. DECLARE (A,B,C,D) BINARY FIXED (31); DECLARE (E DECIMAL(6,5), F CHARACTER(10)) STATIC; DECLARE 1 A, 2(B,C,D) (3,2) BINARY FIXED (15); Factoring can also be nested: DECLARE ((A,B) FIXED(10),C FLOAT(5)) EXTERNAL; ═══ Implicit Declarations ═══ Description If 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. Implicit 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. It is as if block B inherits the declaration from the external procedure that contains it. Related Information Contextual declaration ═══ Contextual Declarations ═══ Description 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 that is followed by an argument list, is given the BUILTIN and INTERNAL attributes.  A name that appears in a FILE or COPY option, or a name that appears in an ON, SIGNAL, or REVERT statement for a condition that requires a file name, is given the FILE attribute.  A name that appears in an ON CONDITION, SIGNAL CONDITION, or REVERT CONDITION statement is given the CONDITION attribute.  A name that appears in an EVENT option or in a WAIT statement is given the EVENT 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 POINTER attribute.  A name that appears in an IN option, or in the OFFSET attribute, is given the AREA attribute. Examples Using contextual declarations ═══ Using Contextual Declarations ═══ Examples of contextual declaration are: READ FILE (PREQ) INTO (Q); ALLOCATE X IN (S); In these statements, PREQ is given the FILE attribute, and S is given the AREA attribute. Implicit declarations that are not contextual declarations acquire all attributes by default. Since a contextual declaration cannot exist within the scope of an explicit declaration, it is impossible for the context of a name to add to the attributes established for that name in an explicit declaration. For example, the following procedure is invalid: P: PROC (F); READ FILE(F) INTO(X); END P; The name F is in a parameter list and is, therefore, explicitly declared. The language-specified defaults REAL DECIMAL FLOAT conflict with the attributes that would normally be given to F by its appearance in the FILE option. ═══ Array Declaration ═══ Description An array is an n-dimensional collection of elements that have identical attributes. Only the array itself is given a name. An individual item of an array is referred to by giving its position within the array. The parenthesized number or numbers following the array name in a DECLARE statement is the dimension attribute specification. Related Information Dimension attribute ═══ Dimension attribute ═══ Description The dimension attribute specifies the number of dimensions of an array. This attribute also specifies either the bounds of each dimension or indicates that the upper bound is taken from an associated argument. Bounds that are expressions are evaluated and converted to FIXED BINARY (31,0) when storage is allocated for the array beginning and end of that dimension. The extent is the number of integers between, and including, the lower and upper bounds. Examples Using arrays Related Information  Array subscripts  Cross sections of arrays Syntax ┌────,─────┐  │ ────(─────bound───┴──)─────────────────────────────────────── where bound is ────┬──┬─────────────────┬───upper-bound──┬────────────────── │ └──lower-bound─:──┘ │ └─────────────────*───────────────────┘ where upper-bound and lower-bound are ────expression──┬─────────────────────────┬────────────────── └──REFER──(──variable──)──┘ The bounds must be the first attribute after the name (or the parenthesized list of names) in the declaration. ═══ Using Arrays ═══ Review the following examples for help with using arrays of arithmetic data:  Consider the following declaration: DECLARE LIST (8) FIXED DECIMAL (3); LIST is declared as a one-dimensional array of eight elements, each one a fixed-point decimal element of three digits. The one dimension of LIST has bounds of 1 and 8; its extent is 8.  In the example: DECLARE TABLE (4,2) FIXED DEC (3); TABLE is declared as a two-dimensional array of eight fixed-point decimal elements. The two dimensions of TABLE have bounds of 1 and 4 and 1 and 2; the extents are 4 and 2.  Other examples are: DECLARE LIST_A (4:11); DECLARE LIST_B (-4:3); In the first example, the bounds are 4 and 11; in the second they are -4 and 3. The extents are the same; in each case, there are 8 integers from the lower bound through the upper bound. In the manipulation of array data involving more than one array, the bounds (not merely the extents) must be identical. Although LIST, LIST_A, and LIST_B all have the same extent, the bounds are not identical. ═══ Array Subscripts ═══ Description The bounds of an array determine the way in which you refer to elements of the array. A subscripted reference to an array must contain as many subscripts as there are dimensions in the array. Any expression that yields a valid arithmetic value can be used for a subscript. If necessary, the value is converted to FIXED BINARY(31,0). Examples  Using one-dimensional arrays  Using multi-dimensional arrays  Using arrays and bounds ═══ Using One-Dimensional Arrays ═══ Consider the following declaration: DECLARE LIST (8) FIXED DECIMAL (3); where the following data items are assigned to the one-dimensional array LIST: 20 5 10 30 630 150 310 70 The different elements are referred to as follows: REFERENCE ELEMENT ______________________ LIST (1) 20 LIST (2) 5 LIST (3) 10 LIST (4) 30 LIST (5) 630 LIST (6) 150 LIST (7) 310 LIST (8) 70 Each of the parenthesized numbers following LIST is a subscript. A parenthesized subscript following an array name reference identifies a particular data item within the array. A reference to a subscripted name, such as LIST(4), refers to a single element and is an element variable. The entire array can be referred to by the unsubscripted name of the array- for example, LIST. ═══ Using Multi-Dimensional Arrays ═══ Consider the following declaration: DECLARE TABLE (4,2) FIXED DEC (3); where the following data items are assigned to the two-dimensional array TABLE: 20 5 10 30 630 150 310 70 TABLE can be illustrated as a matrix of four rows and two columns: TABLE(m,n) (m,1) (m,2) ______________________________ (1,n) 20 5 (2,n) 10 30 (3,n) 630 150 (4,n) 310 70 Note: The use of a matrix to illustrate TABLE is purely conceptual. It has no relationship to the way the items are actually organized in storage. An element of TABLE is referred to by a subscripted name with two parenthesized subscripts, separated by a comma. For example, TABLE(2,1) would specify the first item in the second row, namely the data item 10. Data items are assigned to an array in row major order. This means that the rightmost subscript (representing rows) varies most rapidly. For example, assignment to TABLE would be to TABLE(1,1), TABLE(1,2), TABLE(2,1), TABLE(2,2), and so forth. ═══ Using Arrays and Bounds ═══ Consider the following declarations: DECLARE LIST_A (4:11); DECLARE LIST_B (-4:3); where the following data items are assigned to the arrays LIST_A and LIST_B: 20 5 10 30 630 150 310 70 In this case, it is referenced as follows: Reference Element Reference LIST_A (4) 20 LIST_B (-4) LIST_A (5) 5 LIST_B (-3) LIST_A (6) 10 LIST_B (-2) LIST_A (7) 30 LIST_B (-1) LIST_A (8) 630 LIST_B (0) LIST_A (9) 150 LIST_B (1) LIST_A (10) 310 LIST_B (2) LIST_A (11) 70 LIST_B (3) ═══ Cross Sections of Arrays ═══ Description Cross sections of arrays can be referred to by using an asterisk for a subscript. The asterisk specifies that the entire extent is used. A subscripted name containing asterisk subscripts represents not a single data element, but an array with as many dimensions as there are asterisks. Consequently, such a name is not an element expression, but an array expression. A reference to a cross section of an array can refer to two or more elements that are not adjacent in storage. The storage represented by such a cross section is known as unconnected storage. The rule is as follows: if a nonasterisk bound appears to the right of the leftmost asterisk bound, the array cross section is in unconnected storage. Thus, A(4,*,*) is in connected storage, but A(*,2,*) is not. Related Information (NON)CONNECTED attribute Example TABLE(m,n) (m,1) (m,2) ______________________________ (1,n) 20 5 (2,n) 10 30 (3,n) 630 150 (4,n) 310 70 TABLE(*,1) refers to all of the elements in the first column of TABLE. It specifies the cross section consisting of TABLE(1,1), TABLE(2,1), TABLE(3,1), and TABLE(4,1). The subscripted name TABLE(2,*) refers to all of the data items in the second row of TABLE. TABLE(*,*) refers to the entire array, as does TABLE. A matrix of four rows and two columns is illustrated by TABLE above. ═══ Structure Declarations ═══ Description A structure is a data aggregate whose elements need not have identical attributes. Like an array, the entire structure is given a name that can be used to refer to the entire aggregate of data. Unlike an array, however, each element of a structure also has a name. A structure has different levels:  At the first level is the structure name called a major structure.  At a deeper level are the names of substructures called minor structures.  At the deepest are the element names called elementary names. An elementary name in a structure can represent an array, in which case it is not an element variable, but an array variable. Usage Rules The organization of a structure is specified in a DECLARE statement through the use of level numbers preceding the associated names. Level numbers must be integers. A major structure name is declared with the level number 1. Minor structures and elementary names are declared with level numbers greater than 1. A delimiter (usually a blank) must separate the level number and its associated name. Examples Declaring structures Related Information  Arrays of structures  LIKE attribute  Structure mapping  Structure qualification ═══ Declaring Structures ═══ Description The organization of a structure is specified in a DECLARE statement through the use of level numbers preceding the associated names; level numbers must be integers. A major structure name is declared with level number 1. Minor structures and elementary names are declared with numbers greater than 1. A delimiter (usually a blank) must separate the level number and its associated name. For example, the items of a payroll can be declared as follows: Examples Review the following declarations of structures.  The items of a payroll can be declared as follows: DECLARE 1 PAYROLL, /* major structure name */ 2 NAME, /* minor structure name */ 3 LAST CHAR(20), /* elementary name */ 3 FIRST CHAR(15), 2 HOURS, 3 REGULAR FIXED DEC(5,2), 3 OVERTIME FIXED DEC(5,2), 2 RATE, 3 REGULAR FIXED DEC(3,2), 3 OVERTIME FIXED DEC(3,2); Indentation is only for readability. The statement could be written in a continuous string as: DECLARE 1 PAYROLL, 2 NAME, 3 LAST CHAR(20), etc... PAYROLL is declared as a major structure containing the minor structures: NAME, HOURS, and RATE. Each minor structure contains two elementary names. You can refer to the entire structure by the name PAYROLL, or to portions of the structure by the minor structure names. You can refer to an element by referring to an elementary name. The level numbers you choose for successively deeper levels need not be consecutive. A minor structure at level n contains all the names with level numbers greater than n that lie between that minor structure name and the next name with a level number less than or equal to n.  PAYROLL might have been declared as follows: DECLARE 1 PAYROLL, 4 NAME, 5 LAST CHAR(20), 5 FIRST CHAR(15), 2 HOURS, 6 REGULAR FIXED DEC(5,2), 5 OVERTIME FIXED DEC(5,2), 2 RATE, 3 REGULAR FIXED DEC(3,2), 3 OVERTIME FIXED DEC(3,2); This declaration results in exactly the same structuring as the previous declaration. The description of a major structure name is terminated by one of the following: - the declaration of another item with a level number 1 - the declaration of another item with no level number - a semicolon terminating the DECLARE statement. ═══ LIKE Attribute ═══ Description The LIKE attribute specifies that the variable being declared is a structure variable with the same structuring as the variable following the attribute keyword LIKE. Substructure names, elementary names, and their attributes are identical. Additional substructures or elementary names cannot be added to the created structure. Any level number that immediately follows the structure-variable in the LIKE attribute specification in a DECLARE statement must be equal to or less than the level number of the name declared with the LIKE attribute. Attributes of the structure-variable itself do not carry over to the created structure. For example, storage class attributes do not carry over. If the structure-variable following the keyword LIKE represents an array of structures, its dimension attribute is not carried over. However, attributes of substructure names and elementary names are carried over; contained dimension and length attributes are recomputed. If a direct application of the description to the structure declared LIKE causes an incorrect continuity of level numbers (for example, if a minor structure at level 3 were declared LIKE a major structure at level 1) the level numbers are modified by a constant before application. The LIKE attribute is expanded before the defaults are applied and before the ALIGNED and UNALIGNED attributes are applied to the contained elements of the LIKE structure-variable. The only ALIGNED and UNALIGNED attributes that are carried over from the structure-variable are those explicitly specified for its substructures and elements. Examples Using the LIKE attribute Syntax ────LIKE────structure-variable───────── ═══ structure-variable ═══ structure-variable can be a major structure or a minor structure. It can be qualified, but it cannot be subscripted. It must not contain a REFER variable. Additional usage rules for structure-variables are:  The structure-variable must be known in the block containing the LIKE attribute specification. The structure names in all LIKE attributes are associated with declared structures before any LIKE attributes are expanded.  Neither the structure-variable nor any of its substructures can be declared with the LIKE attribute.  The structure-variable must not be a substructure of a structure declared with the LIKE attribute.  No substructure of the major structure containing the structure-variable can have the LIKE attribute. ═══ Using the LIKE Attribute ═══  For example: DECLARE 1 A, 2 C, 3 E, 3 F, 1 D(10), 2 C, 3 G, 3 H; BEGIN; DECLARE 1 A LIKE D; DECLARE 1 B(2) LIKE A.C; END; These declarations result in the following: 1 A LIKE D is expanded to give: 1 A, 2 C, 3 G, 3 H 1 B(2) LIKE A.C is expanded to give: 1 B(2), 3 E, 3 F  The following declaration is invalid because references to the REFER object X would be ambiguous. DECLARE 1 A BASED, 2 X FIXED BINARY, 2 Y(Z REFER(X)), 1 B BASED LIKE A;  The following example is invalid because the LIKE attribute of A specifies a structure, C, that contains an identifier, E, that has the LIKE attribute. DECLARE 1 A LIKE C, 1 B, 2 C, 3 D, 3 E LIKE X, 2 F, 1 X, 2 Y, 2 Z;  The following example is invalid because the LIKE attribute of A specifies a substructure, G.C, of a structure, G, declared with the LIKE attribute. DECLARE 1 A LIKE G.C, 1 B, 2 C, 3 D, 3 E, 2 F, 1 G LIKE B;  The following example is invalid because the LIKE attribute of A specifies a structure, C, within a structure, B, that contains a substructure, F, having the LIKE attribute. DECLARE 1 A LIKE C, 1 B, 2 C, 3 D, 3 E, 2 F LIKE X, 1 X, 2 Y, 2 Z; ═══ Structure Qualification ═══ Description A minor structure or a structure element can be referred to by the minor structure name or the elementary name alone if there is no ambiguity. A qualified reference is an elementary name or a minor structure name that is qualified with one or more names at a higher level, connected by periods. Structure qualification is in the order of levels. That is, the name at the highest level must appear first, with the name at the deepest level appearing last. Names within a structure, except the major structure name itself, need not be unique within the procedure in which it is declared. Qualifying names must be used only so far as necessary to make the reference unique. An ambiguous reference is a reference with insufficient qualification to make the reference unique. A reference is always taken to apply to the declared name in the innermost block containing the reference. Examples Using ambiguous and unambiguous references ═══ Using Ambiguous and Unambiguous References ═══ An ambiguous reference is an elementary name or a minor structure name that is qualified with one or more names at a higher level, connected by periods. Blanks may appear surrounding the period. The following examples illustrate both ambiguous and unambiguous references.  In the following example, A.C refers to C in the inner block; D.E refers to E in the outer block: DECLARE 1 A, 2 C, 2 D, 3 E; BEGIN; DECLARE 1 A, 2 B, 3 C, 3 E; A.C = D.E;  In the following example, D has been declared twice: DECLARE 1 A, 2 B, 2 C, 3 D, 2 D; A reference to A.D refers to the second D, since A.D is a complete qualification of only the second D; the first D would have to be referred to as A.C.D.  In the following example, a reference to A.C is ambiguous because neither C is uniquely qualified by this reference: DECLARE 1 A, 2 B, 3 C, 2 D, 3 C;  In the following example, a reference to A refers to the first A, A.A to the second A, and A.A.A to the third A: DECLARE 1 A, 2 A, 3 A;  In the following example, a reference to X refers to the first DECLARE statement: DECLARE X; DECLARE 1 Y, 2 X, 3 Z, 3 A, 2 Y, 3 Z, 3 A; A reference to Y.Z is ambiguous; Y.Y.Z refers to the second Z; and Y.X.Z refers to the first Z. ═══ Structure Mapping ═══ Description For any major or minor structure, the length, alignment requirement, and position relative to a doubleword boundary depend on the lengths, alignment requirements, and relative positions of its members. The process of determining these requirements for each level and for the complete structure is known as structure mapping. During the structure mapping process, the compiler minimizes the amount of unused storage (padding) between members of the structure. It completes the entire process before the structure is allocated, according (in effect) to the rules discussed in the following paragraphs. Structure mapping is not a physical process. Terms such as shifted and offset are used purely for ease of discussion, and do not imply actual movement in storage. When the structure is allocated, the relative locations are already known as a result of the mapping process. The mapping for a complete structure reduces to successively combining pairs of items (elements, or minor structures whose individual mappings have already been determined). Once a pair has been combined, it becomes a unit to be paired with another unit, and so on until the complete structure is mapped. The rules for the process are categorized as:  Rules for determining the order of pairing  Rules for mapping one pair. The lower line shows the logical level for each item in the declaration. To better understand the process of structure mapping, select from the following topics:  Determining logical levels of items  Rules for order of pairing  Rules for mapping one pair  Uses for structure mapping Related Information Effect of UNALIGNED attribute ═══ Rules for Order of Pairing ═══ The steps in determining the order of pairing are as follows: 1. Find the minor structure at the deepest logical level (which we will call logical level n). 2. If more than one minor structure has the logical level n, take the first one that appears in the declaration. 3. Pair the first two elements appearing in this minor structure, thus forming a unit. Use the rules for mapping one pair. 4. Pair this unit with the next element (if any) declared in the minor structure, thus forming a larger unit. 5. Repeat step 4 until all the elements in the minor structure have been combined into one unit. This completes the mapping for this minor structure; its alignment requirement and length, including any padding, are now determined and will not change (unless you change the structure declaration). Its offset from a doubleword boundary is also now determined; note that this offset will be significant during mapping of any containing structure, and it may change as a result of such mapping. 6. Repeat steps 3 through 5 for the next minor structure (if any) appearing at logical level n in the declaration. 7. Repeat step 6 until all minor structures at logical level n have been mapped. Each of these minor structures can now be thought of as an element for structure mapping purposes. 8. Repeat the pairing process for minor structures at the next higher logical level; that is, make n equal to (n-1) and repeat steps 2 through 7. 9. Repeat step 8 until n = 1; then repeat steps 3 through 5 for the major structure. ═══ Rules for Mapping One Pair ═══ For purposes of this explanation, think of storage as contiguous doublewords, each having 8 bytes, numbered 0 through 7, which indicate the offset from a doubleword boundary. Think of the bytes as numbered continuously from 0 onwards, starting at any byte, so that lengths and offsets from the start of the structure can be calculated. 1. Begin the first element of the pair on a doubleword boundary; or, if the element is a minor structure that has already been mapped, offset it from the doubleword boundary by the amount indicated. 2. Begin the second element of the pair at the first valid position following the end of the first element. This position will depend on the alignment requirement of the second element. If the second element is a minor structure, its alignment requirement will have been determined already. 3. Shift the first element towards the second element as far as the alignment requirement of the first allows. The amount of shift determines the offset of this pair from a doubleword boundary. After this process has been completed, any padding between the two elements has been minimized and will not change throughout the rest of the operation. The pair is now a unit of fixed length and alignment requirement; its length is the sum of the two lengths plus padding, and its alignment requirement is the higher of the two alignment requirements (if they differ). ═══ Effect of UNALIGNED Attribute ═══ Description The example of structure mapping given below shows the rules that are applied to a structure declared ALIGNED. Mapping of aligned structures is more complex because of the number of alignment requirements. The effect of the UNALIGNED attribute is to reduce to 1 byte the alignment requirements for halfwords, fullwords, and doublewords, and to reduce to 1 bit the alignment requirement for bit strings. The same structure mapping rules apply, but the reduced alignment requirements are used. The only unused storage will be bit padding within a byte when the structure contains bit strings. EVENT and AREA data cannot be unaligned. If a structure has the UNALIGNED attribute and it contains an element that cannot be unaligned, UNALIGNED is ignored for that element; the element is aligned and an error message is put out. For example, in a program with the declaration: DECLARE 1 A UNALIGNED, 2 B, 2 C AREA(100); C is given the attribute ALIGNED, as the inherited attribute UNALIGNED conflicts with AREA. ═══ Arrays of Structures ═══ Description A structure name, either major or minor, can be given a dimension attribute in a DECLARE statement to declare an array of structures- an array whose elements are structures having identical names, levels, and elements. An item declared within an array of structures inherits dimensions declared in the containing structure. This applies to elements that are either base elements or minor structures. A reference to a cross section of an array of structures is not allowed- that is, the asterisk notation cannot be used in a reference. Examples Using arrays of structures and subscript-qualified references ═══ Using Arrays of Structures and Subscript-Qualified References ═══  If a structure, WEATHER, is used to process meteorological information for each month of a year, it might be declared as follows: DECLARE 1 WEATHER(12), 2 TEMPERATURE, 3 HIGH DECIMAL FIXED(4,1), 3 LOW DECIMAL FIXED(3,1), 2 WIND_VELOCITY, 3 HIGH DECIMAL FIXED(3), 3 LOW DECIMAL FIXED(2), 2 PRECIPITATION, 3 TOTAL DECIMAL FIXED(3,1), 3 AVERAGE DECIMAL FIXED(3,1); Thus, you could refer to the weather data for the month of July by specifying WEATHER(7). Portions of the July weather could be referred to by TEMPERATURE(7) and WIND_VELOCITY(7). TOTAL(7) would refer to the total precipitation during the month of July. TEMPERATURE.HIGH(3), which would refer to the high temperature in March, is a subscripted qualified reference.  The need for subscripted qualified references becomes apparent when an array of structures contains minor structures that are arrays. For example, consider the following array of structures: DECLARE 1 A (2,2), 2 B (2), 3 C, 3 D, 2 E; Both A and B are arrays of structures. To refer to a data item, it may be necessary to use as many as three names and three subscripts. For example: A(1,1).B refers to an array of structures. A(1,1) refers to a structure. A(1,1).B(1) refers to a structure. A(1,1).B(2).C refers to an element. As long as the order of subscripts remains unchanged, subscripts in such references can be moved to the right or left and attached to names at a lower or higher level. For example, A.B.C(1,1,2) and A(1,1,2).B.C have the same meaning as A(1,1).B(2).C for the above array of structures. Unless all of the subscripts are moved to the lowest level, the reference is said to have interleaved subscripts; thus, A.B(1,1,2).C has interleaved subscripts. Any item declared within an array of structures inherits dimensions declared in the containing structure. For example, in the above declaration for the array of structures A, the array B is a three-dimensional structure, because it inherits the two dimensions declared for A. If B is unique and requires no qualification, any reference to a particular B would require three subscripts, two to identify the specific A and one to identify the specific B within that A. ═══ Alignment and Attributes ═══ Description The computer holds information in multiples of units of 8 bits. Each 8-bit unit of information is called a byte. The computer accesses bytes singly or as halfwords, words, or doublewords. A halfword is 2 consecutive bytes. A fullword is 4 consecutive bytes. A doubleword is 8 consecutive bytes. Byte locations in storage are consecutively numbered starting with 0; each number is the address of the corresponding byte. Halfwords, words, and doublewords are addressed by the address of their leftmost byte. Your programs can execute faster if halfwords, words, and doublewords are located in main storage on an integral boundary for that unit of information. That is, the unit of information's address is a multiple of the number of bytes in the unit. It is possible in PL/I to align data on integral boundaries. This is not always desirable, however, since there may be unused bytes between successive data elements, which increases use of storage. This increase is particularly important when the data items are members of aggregates used to create a data set; the unused bytes increase the amount of auxiliary storage required. The ALIGNED and UNALIGNED attributes allow you to choose whether or not to align data on the appropriate integral boundary. Related Information  Aligning bytes on integral boundaries  ALIGNED and UNALIGNED attributes ═══ Aligning Bytes on Integral Boundaries ═══ The computer accesses bytes singly or as halfwords, words, or doublewords. A halfword is 2 consecutive bytes. A fullword is 4 consecutive bytes. A doubleword is 8 consecutive bytes. Byte locations in storage are consecutively numbered starting with 0; each number is the address of the corresponding byte. Halfwords, words, and doublewords are addressed by the address of their leftmost byte. Your programs can execute faster if halfwords, words, and doublewords are located in main storage on an integral boundary for that unit of information. That is, the unit of information's address is a multiple of the number of bytes in the unit. As an example, this information is summarized in the following table: ┌───────────────────────────────────────────────────────┐ │ ADDRESSES IN A SECTION OF STORAGE │ ├──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┤ │ 5000 │ 5001 │ 5002 │ 5003 │ 5004 │ 5005 │ 5006 │ 5007 │ ├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤ │ byte │ byte │ byte │ byte │ byte │ byte │ byte │ byte │ ├──────┴──────┼──────┴──────┼──────┴──────┼──────┴──────┤ │ halfword │ halfword │ halfword │ halfword │ ├─────────────┴─────────────┼─────────────┴─────────────┤ │ fullword │ fullword │ ├───────────────────────────┴───────────────────────────┤ │ doubleword │ └───────────────────────────────────────────────────────┘ In PL/I, it is possible to align data on integral boundaries. This is not always desirable, however, since there may be unused bytes between successive data elements, which increases use of storage. This increase is particularly important when the data items are members of aggregates used to create a data set; the unused bytes increase the amount of auxiliary storage required. The ALIGNED and the UNALIGNED attributes allow you to choose whether or not to align data on the appropriate integral boundary. ═══ ALIGNED and UNALIGNED Attributes ═══ Description  ALIGNED specifies that the data element is aligned on the storage boundary corresponding to its data-type requirement.  UNALIGNED specifies that each data element is mapped on the next byte boundary, except for fixed-length bit strings, which are mapped on the next bit. Usage Notes  Complex data requires twice as much storage as its real counterparts, but the alignment requirements are the same.  Defaults are applied at element level. UNALIGNED is the default for bit data, character data, graphic data, and numeric character data. ALIGNED is the default for all other types of data.  For all operators and user-defined (and built-in) functions, the default for ALIGNED or UNALIGNED is applicable to the elements of the result.  Constants take the default for ALIGNED or UNALIGNED.  ALIGNED or UNALIGNED can be specified for element, array, or structure variables. The application of either attribute to a structure is equivalent to applying the attribute to all contained elements that are not explicitly declared ALIGNED or UNALIGNED. Examples ALIGNED and UNALIGNED declarations Syntax ────┬──ALIGNED────┬─────────── └──UNALIGNED──┘ ═══ ALIGNED and UNALIGNED Declarations ═══ The following example illustrates the effect of ALIGNED and UNALIGNED declarations for a structure and its elements: DECLARE 1 S, 2 X BIT(2), /* UNALIGNED BY DEFAULT */ 2 A ALIGNED, /* ALIGNED EXPLICITLY */ 3 B, /* ALIGNED FROM A */ 3 C UNALIGNED, /* UNALIGNED EXPLICITLY */ 4 D, /* UNALIGNED FROM C */ 4 E ALIGNED, /* ALIGNED EXPLICITLY */ 4 F, /* UNALIGNED FROM C */ 3 G, /* ALIGNED FROM A */ 2 H; /* ALIGNED BY DEFAULT */ ═══ Scope of Declarations ═══ Description The part of the program to which a name applies is called the scope of the declaration of that name. In most cases, the scope of the declaration of a name is determined entirely by the position where the name is declared within the program. Implicit declarations are treated as if the name were declared in a DECLARE statement immediately following the PROCEDURE statement of the external procedure. It is not necessary for a name to have the same meaning throughout a program. A name explicitly declared within a block has a meaning only within that block. Outside the block, the name is unknown unless the same name has also been declared in the outer block. Each declaration of the name establishes a scope and in this case, the name in the outer block refers to a different data item. This enables you to specify local definitions and, hence, to write procedures or begin-blocks without knowing all the names used in other parts of the program. The INTERNAL and EXTERNAL attributes can be used to define a name. Examples  Determining the scope of data declarations (general)  Determining the scope of ENTRY and LABEL declarations Related Information INTERNAL/EXTERNAL attributes ═══ Determining the Scope of Data Declarations ═══ The following figure illustrates the scope of declarations. The brackets to the left indicate the block structure. The brackets to the right show the scope of each declaration of a name. The scopes of the two declarations of Q and R are shown as Q and Q' and R and R'. P Q Q' R R' S I ┌─ A: procedure; ─┐ ─┐ ─┐ ─┐ 1,2 │ declare P, Q; │ ─┘ │ │ │ ┌─ B: Procedure; │ ─┐ │ │ 2 │ │ declare Q; │ │ │ │ 3 │ │ R = Q; │ │ ─┘ │ │ │ ┌─ C: begin; │ │ ─┐ │ 3 │ │ │ declare R; │ │ │ │ 4 │ │ │ do I = 1 to 10; │ │ │ │ │ │ │ end; │ │ │ │ │ │ └─ end C; │ │ ─┘ │ │ └─ end B; │ ─┘ │ │ ┌─ D: procedure; │ ─┐ ─┐ ─┐ │ 5 │ │ declare S; │ │ │ │ │ │ └─ end D; │ │ │ ─┘ │ └─ end A; ─┘ ─┘ ─┘ ─┘ 1 P is declared in the block A and known throughout A since it is not redeclared. 2 Q is declared in block A, and redeclared 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. 3 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 in block B is all of A except block C. 4 I 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. 5 S is explicitly declared in procedure D and is known only within D. ═══ Determining the Scope of Entry and Label Declarations ═══ The following figure illustrates the scopes of entry constant and statement label declarations. L1 L1' L2 A B C D E 1 ┌─A: PROCEDURE; ─┐ ─┐ ─┐ ─┐ ─┐ 2 │ DECLARE E ENTRY; │ │ │ │ │ 3 │ L1: P = Q; │ │ │ │ │ 4 │ ┌─ B: PROCEDURE; │ ─┐ │ │ ─┐ │ │ 6 │ │ L2: CALL C; ─┘ │ │ │ │ │ │ 5 │ │ ┌─ C: PROCEDURE; ─┐ │ │ │ │ │ │ 3 │ │ │ L1: X = Y; │ │ │ │ │ │ │ │ │ │ CALL E; │ │ │ │ │ │ │ │ │ └─ END C; ─┘ │ │ │ │ │ │ 3 │ │ GO TO L1; ─┐ │ │ │ │ │ │ │ └─ END B; │ ─┘ │ │ ─┘ │ │ 4 │ ┌─ D: PROCEDURE; │ │ │ │ │ │ └─ END D; │ │ │ │ │ │ CALL B; │ │ │ │ │ └─ END A; ─┘ ─┘ ─┘ ─┘ ─┘ * PROCESS; 2 ┌─E: PROCEDURE; ─┐ L1 L1' L2 A B C D └─ END E; ─┘ 1 The scope of the declaration of the name A is only all of the block A, and not E. 2 E is explicitly declared in A as an external entry constant. The explicit declaration of E applies throughout block A. It is not linked to the explicit declaration of E that applies throughout block E. The scope of the declaration of the name E is all of block A and all of block E. 3 The label L1 appears with statements internal to A and to C. Two separate declarations are therefore established; the first applies to all of block A except block C, the second applies to block C only. Therefore, when the GO TO statement in block B executes, control transfers to L1 in block A, and block B terminates. 4 D and B are explicitly declared in block A and can be referred to anywhere within A; but since they are INTERNAL, they cannot be referred to in block E. 5 C is explicitly declared in B and can be referred to from within B, but not from outside B. 6 L2 is declared in B and can be referred to in block B, including C, which is contained in B, but not from outside B. ═══ Blocks ═══ All of the text of a block, from the PROCEDURE or BEGIN statement through the corresponding END statement (including condition prefixes of BEGIN and PROCEDURE statements), is said to be contained in that block. However, the labels of the BEGIN or PROCEDURE statement heading the block, as well as the labels of any ENTRY statements that apply to the block, are not contained in that block. Nested blocks are contained in the block in which they appear. Text that is contained in a block, but not contained in any other block nested within it, is said to be internal to that block. Entry names of a procedure (and labels of a BEGIN statement) are not contained in that block. Consequently, they are internal to the containing block. Entry names of an external procedure are treated as if they were external to the external procedure. ═══ INTERNAL/EXTERNAL Attributes ═══ Description The INTERNAL and EXTERNAL attributes define the scope of a name. INTERNAL (abbreviation INT) 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 (abbreviation EXT) 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. The scope of each declaration of the name (with the EXTERNAL attribute) includes the scopes of all the declarations of that name (with EXTERNAL) within the program. Because external declarations for the same name all refer to the same data, they must all result in the same set of attributes. It might be impossible for the compiler to check all declarations, particularly, if the names are declared in different external procedures, so care should be taken to ensure that different declarations of the same name with the EXTERNAL attribute have matching attributes. Example Using the EXTERNAL attribute Related Information Default INTERNAL and EXTERNAL attributes Syntax ┌─INTERNAL─────────────────────────────────┐ ────┴─EXTERNAL──┬─────────────────────────┬────┴─────────────────────────── └─(──environment-name──)──┘ ═══ Example - Using the EXTERNAL Attribute ═══ When a major structure name is declared EXTERNAL in more than one block, the attributes of the structure members must be the same in each case, although the corresponding member names need not be identical. For example: PROCA: PROCEDURE; DECLARE 1 A EXTERNAL, 2 B, 2 C; . . END PROCA; *PROCESS; PROCB: PROCEDURE; DECLARE 1 A EXTERNAL, 2 B, 2 D; . . END PROCB; If A.B is changed in PROCA, it is also changed for PROCB, and vice versa; if A.C is changed in PROCA, A.D is changed for PROCB, and vice versa. ═══ Defaults for Attributes ═══ Description Every name in a PL/I source program requires a complete set of attributes. Arguments passed to a procedure must have attributes matching the procedure's parameters. Values returned by functions must have the attributes expected. However, the attributes that you specify need rarely include the complete set of attributes. The set of attributes for the following:  Explicitly declared names  Implicitly (including contextually) declared names  Attributes to be included in parameter descriptors  Values returned from function procedures can be completed by using the language-specified defaults, or by defaults that you can define (using the DEFAULT statement) either to modify the language-specified defaults or to develop a completely new set of defaults. Attributes applied by default cannot override attributes applied to a name by explicit or contextual declaration. Related Information  Language-specified defaults  DEFAULT statement ═══ Language-Specified Defaults ═══ Description Review the following rules regarding the use of language-specified defaults:  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 data.  If mode, scale, and base are not specified by a DECLARE or DEFAULT statement, or by a RETURNS option, variables with names beginning with any of the letters I through N are given the attributes REAL FIXED BINARY (15,0). Those with names beginning with any other alphabetic character or with a non-EBCDIC DBCS character are given the attributes REAL FLOAT DECIMAL (6).  A scaling factor in the precision attribute constitutes an explicit declaration of FIXED. If mode, string, or base is specified by a DECLARE or DEFAULT statement, or by a RETURNS option, the remaining attributes are completed from the following list of defaults:  The default base is DECIMAL  The default scale is FLOAT  The default mode is REAL. Default precisions are then completed from the following list:  (5,0) for DECIMAL FIXED  (15,0) for BINARY FIXED  (6) for DECIMAL FLOAT  (21) for BINARY FLOAT. If no parameter descriptor list is given, the default is that the argument attributes match the parameter attributes. Examples Using language-specified defaults Related Information Restoring language-specified defaults ═══ DEFAULT Statement ═══ Description The DEFAULT statement (abbreviation DFT) 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. Structure elements are given default attributes according to the name of the element, not the qualified structure element name. The DEFAULT statement cannot be used to create a structure. Syntax ┌──,───────────────────────────────────┐  │ ────DEFAULT─────┬──┤ simple-specification ├─────┬───┴───;───────────────── └──┤ factored-specification ├───┘ where simple-specification is: ┌────────────────────────┐ │ │ │ ┌─────────┐ │   │ │ ├──┬─RANGE─(────────┬───letter──┴───┬──┴───)───┬────────────────────┬───┬───────┤ │ └─letter:letter─┘ └─┤ attribute-list ├─┘ │ ├─RANGE─(──*───)─────┬────────────────────┬──────────────────────────┤ │ └─┤ attribute-list ├─┘ │ └─DESCRIPTORS──┬────────────────────┬────────────────────────────────┘ └─┤ attribute-list ├─┘ where factored-list is: ┌──,───────────────────────────────┐  │ ├───(─────┬─┤ simple-specification ├───┬──┴───)────┬────────────────────┬───────┤ └─┤ factored-specification ├─┘ └─┤ attribute-list ├─┘ where attribute-list is: ┌────────────┐  │ ├───┬───attribute──┴──┬────────────────────────────────────────┬──┬────────────┤ │ │ ┌─,────────────────────────┐ │ │ │ │  │ │ │ │ └─VALUE(───┤ value-specification ├──┴──)─┘ │ │ ┌─,────────────────────────┐ │ │  │ │ └─VALUE(──┤ value-specification ├──┴──)───────────────────────┘ where value-specification is: ├───┬─AREA(size)──────────────┬────────────────────────────────────────────────┤ ├─BIT(length)─────────────┤ ├─CHARACTER(length)───────┤ ├─GRAPHIC(length)─────────┤ └─┤ additional-options ├──┘ where additional-options is: ├───┬──────────┬──┬───────┬──┬─────────┬─────────────────────────────────────── ├─REAL─────┤ ├─FIXED─┤ ├─BINARY──┤ └─COMPLEX──┘ └─FLOAT─┘ └─DECIMAL─┘ ───┬────────────────────────────────────────┬────────────────────────────────┤ └─(─precision──┬───────────────────┬──)──┘ └─,─scaling-factor──┘ There can be more than one DEFAULT statement within a block. The scope of a DEFAULT statement is the block in which it occurs, and all blocks within that block which neither include another DEFAULT statement with the same range, nor are contained in a block having a DEFAULT statement with the same range. A DEFAULT statement in an internal block affects only explicitly declared names. This is because the scope of an implicit declaration is determined as if the names were declared in a DECLARE statement immediately following the PROCEDURE statement of the external procedure in which the name appears. It is possible for a containing block to have a DEFAULT statement with a range that is partly covered by the range of a DEFAULT statement that is in a contained block. In such a case, the range of the DEFAULT statement in the containing block is reduced by the range of the DEFAULT statement in the contained block. For example: P: PROCEDURE L1: DEFAULT RANGE (XY) FIXED; Q: BEGIN; L2: DEFAULT RANGE (XYZ) FLOAT; END P; The scope of DEFAULT statement L1 is procedure P and the contained block Q. The range of DEFAULT statement L1 is all names in procedures P beginning with the characters XY, together with all names in begin block Q beginning with the characters XY, except for those beginning with the characters XYZ. Labels can be prefixed to DEFAULT statement. A branch to such a label is treated as a branch to a null statement. Condition prefixes cannot be attached to a DEFAULT statement. Related Information  Programmer-defined default for the returns option  Restoring language-specified defaults ═══ Programmer-Defined Default for the RETURNS Option ═══ Description The default attributes of values returned from function procedures are dependent on the entry name used to invoke the procedure. The DEFAULT statement can be used to specify these attributes when the entry name, or the initial letter of the entry name, is specified in the DEFAULT statement. For example: DEFAULT RANGE (X) FIXED BINARY; X : PROC(Y); would be interpreted as: X : PROC(Y) RETURNS (FIXED BINARY); ═══ Restoring Language-Specified Defaults ═══ Description The following statement: DEFAULT RANGE(*), DESCRIPTORS; overrides, for all names, any programmer-defined default rules established in a containing block. It can be used to restore language-specified defaults for contained blocks. ═══ 1.3. PL/I Expressions and References ═══ Description In PL/I, an expression is the representation of a value. The expression may consist of constants, variables, and function references alone or in combination using parentheses and/or operators. PL/I statements often contain more than one expression or reference. Except as described for specific instances (for example, the ASSIGNMENT statement) expression evaluation order may vary. The results of an expression evaluation or of a conversion are assigned to targets of expression evaluations. Related Information Select one of the following for additional help with using a specific kind of expression:  Using operational expressions  Using array expressions Syntax ────unary-expression────┬──────────────────────────────────────────┬─ │ ┌─────────────────────────────────────┐ │ │  │ │ └─────infix-operator───unary-expression──┴─┘ where unary-expression is: ────┬──────────────────────────┬───elementary-expression───────────── │ ┌───────────────────┐ │ │  │ │ └─────prefix-operator──┴───┘ where elementary-expression is: ────┬──(──expression──)──┬─────────────────────────────────────────── ├──reference─────────┤ ├──constant──────────┤ └──iSUB──────────────┘ where reference is: ────┬─────────────────────┬───basic-reference──────────────────────── └──locator-qualifier──┘ ─────┬────────────────────┬───┬─────────────────────────────┬───────── └──(subscript-list)──┘ └──(──┬─────────────────┬──)──┘ └──argument-list──┘ where locator-qualifier is: ────reference->────────────────────────────────────────────────────── where subscript-list is: ┌─────────,──────────┐  │ ───────┬──expression──┬──┴─────────────────────────────────────────── └──────*───────┘ where argument-list is: ┌──────,───────┐  │ ───────expression──┴───────────────────────────────────────────────── where basic-reference is: ────┬───────────────────────────┬───name───────────────────────────── └──structure-qualification──┘ where structure-qualification is: ────basic-reference────┬────────────────────────┬──────────────────── └──(──subscript-list──)──┘ ═══ Expression Evaluation Order ═══ Description Evaluation of PL/I expressions and references can be done in any order. Examples DCL (X,Y,Z) ENTRY RETURNS(FLOAT), (F,G,H) FLOAT; F = X( Y(G,H), Z(G,H) ); In the above example, the functions Y and Z may change the value of the arguments passed to them. Therefore, the value returned by function X may depend upon whether function Y or Z is invoked first. Do not assume that the first parameter is evaluated first, since optimization may involve processing in a sequence that is not first to last. Consider another example where operations may be evaluated in any order: DCL B(2,2); I=0; PUT LIST ( B( INC(I), INC(I) ) ); In the above example, the function INC increments the value of the number passed to it and returns the updated value. However, either occurrence of the INC function can be evaluated first. If the first occurrence of INC is evaluated first, the element referenced will be B(1,2). If the second occurrence of INC is evaluated first, the element referenced will be B(2,1). ═══ Targets of Expression Evaluations ═══ The results of an expression evaluation (or of an expression conversion) are assigned to a target. You may choose from three possible targets:  Variable targets  Pseudovariable targets  Intermediate result targets ═══ Pseudovariable Targets ═══ Description You may assign the results of the evaluation of an expression to a pseudovariable. A pseudovariable represents a target field. Example DECLARE A CHARACTER(10); B CHARACTER(30); SUBSTR(A,6,5) = SUBSTR(B,20,5); In this assignment statement, the SUBSTR function extracts a substring of length 5 from the string B, beginning with the 20th character. The SUBSTR pseudovariable indicates the location within string A that is the target. Thus the last 5 characters of A are replaced by characters 20 through 24 of B. The first five characters of A remain unchanged. ═══ Intermediate Result Targets ═══ Description When an expression is evaluated, the result is assigned to a target. The attributes of the target are derived partially from the source, partially from the operation being performed, and partially from the attributes of a second operand. Some default target attributes may be used. Also, some implementation restrictions (for example, maximum precision) and other conventions play a role in determining the target's attributes. An intermediate result may undergo data type conversion if a further operation is to be performed. After an expression is evaluated, the result may be further converted for assignment to a variable or pseudovariable. Example Using intermediate result targets ═══ Example- Using Intermediate Result Targets ═══ After an expression is evaluated, you may convert the result for assignment to a variable or pseudovariable. These conversions follow the same rules as the conversion of programmer-defined data. For example: DECLARE A CHARACTER(8), B FIXED DECIMAL(3,2), C FIXED BINARY(10); A = B + C; During the evaluation of the expression B+C and during the assignment of that result, there are four different results: 1. The intermediate result to which the converted binary equivalent of B is assigned. 2. The intermediate result to which the binary result of the addition is assigned. 3. The intermediate result to which the converted decimal fixed-point equivalent of the binary is assigned. 4. A, the final destination of the result, to which the converted character equivalent of the decimal fixed-point representation of the value is assigned. The attributes of result 1 are determined from the attributes of the source B, from the operator and from the attributes of the other operand. If one operand of an arithmetic infix operator is binary, the other is converted to binary before evaluation. The attributes of result 2 are determined from the attributes of the source (C and the converted representation of B) The attributes of the third result are determined in part from the source (result 2) and in part from the attributes of the eventual target A. The only attribute determined from the eventual target is DECIMAL. The attributes of A are known from the DECLARE statement. ═══ Using Operational Expressions ═══ Description An operational expression consists of one or more single operations. A single operation may be either a prefix operation (an operator preceding a single operand) or an infix operation (an operator between two operands). The operands of an operation in a PL/I expression must be of the same data type before the operation is performed. PL/I follows a fixed set of rules for data conversions. Related Information There are five classes of operations in PL/I. Choose one of the following for help with using a particular type of operation in an expression:  Using arithmetic operations  Using bit operations  Using comparison operations  Using concatenation operations  Using combinations of operations ═══ Using Arithmetic Operations ═══ You specify an arithmetic operation by combining operands with arithmetic operators. Arithmetic operations can also be specified using the ADD, SUBTRACT, MULTIPLY, and DIVIDE built-in functions. The two operands of an arithmetic operation may differ in type, base, mode, precision, and scale. When they differ, conversion must take place for the expression to be evaluated. After the necessary conversion of the operands in an expression has been carried out, the arithmetic operation is performed and a result is obtained. This result can be the value of the expression, or it can be an intermediate result target upon which further operations are to be performed, or a condition to be raised. ═══ Arithmetic Operators ═══ Description The arithmetic operators consist of: + - * / ** You may use the plus and minus signs as prefix operators (an operator preceding a single operand) or as infix operators (an operator between two operands). All other arithmetic operators can appear only as infix operators. Example Prefix operators can precede and be associated with any of the operands of an infix operation. For example, in the expression: A*-B the minus sign indicates that the value of A is to be to be multiplied by -1 times the value of B. More than one prefix operator can precede and be associated with a single variable. More than one positive prefix operator has no cumulative effect, but two negative prefix operators have the same effect as a single positive prefix operator. ═══ Using Bit Operations ═══ Description You specify a bit operation by combining operands with a logical operator. Operands of a bit operation are converted, if necessary, to bit strings before the operation is performed. If the operands of an infix operation (an operator between two operands) do not have the same length, the shorter operand is padded on the right with '0'B. The result of a bit operation is a bit string equal in length to the length of the operands. Because bit operations are performed on a bit-by-bit basis, there will be a result for each bit position for each of the operators. In addition to performing the NOT, XOR, AND, and OR operations using logical operators, you can perform Boolean operations using the BOOL built-in function. Example Using bit operations ═══ Examples- Using Bit Operations ═══ In the following examples:  The value of operand A is '010111'B  The value of operand B is '111111'B  The value of operand C is '110'B  The value of operand D is 5 Based on these values: к A yields '101000'B к C yields '001'B C & B yields '110000'B A | B yields '111111'B C | B yields '111111'B A | (кC) yields '011111'B к((кC)|(кB)) yields '110111'B SUBSTR (A,1,1)|(D=5) yields '1'B ═══ Bit Operations - Results (Bit-by-Bit) ═══ The following table illustrates the result for each bit position for each of the operators: ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┐ │ A │ B │ кA │ кB │ A&B │ A|B │ AкB │ │───────┼───────┼───────┼───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 0 │ 1 │ 1 │ 1 │ 0 │ ├───────┼───────┼───────┼───────┼───────┼───────┼───────┤ │ 1 │ 0 │ 0 │ 1 │ 0 │ 1 │ 1 │ ├───────┼───────┼───────┼───────┼───────┼───────┼───────┤ │ 0 │ 1 │ 1 │ 0 │ 0 │ 1 │ 1 │ ├───────┼───────┼───────┼───────┼───────┼───────┼───────┤ │ 0 │ 0 │ 1 │ 1 │ 0 │ 0 │ 0 │ └───────┴───────┴───────┴───────┴───────┴───────┴───────┘ ═══ Using Comparison Operations ═══ Description You specify a comparison operation by combining operands with one of the comparison operators. The result of a comparison operation is always a bit string of length 1. The value is '1'B if the relationship is true, or '0'B if the relationship is false. Related Information You can use several different types of comparisons. Select one of the following for additional help on a particular type of comparison operation:  Algebraic comparisons  Character comparisons  Bit comparisons  Graphic comparisons  Locator data comparisons  Program control data comparisons Example Using comparison operations ═══ Locator Data Comparisons ═══ Both pointers and offset variables can be compared using infix comparison operators. The following is a list of the infix operators which can be used in a comparison of locator data operands:  Less than <  Not less than к<  Less than or equal to <=  Equal to =  Not equal to к=  Greater than or equal to >=  Greater than >  Not greater than к> The only data type conversion that can take place is offset to pointer, and this only occurs if the comparison is = or к=. ═══ Program Control Data Comparisons ═══ Use only the comparison operators = and к= in comparing program control data. Also, be aware that no data type conversions can take place in program control data comparisons. Any data type differences between operands for program control data comparisons are in error. Comparisons are equal for the following types of program control data operands under the following conditions: Entry In a comparison operation, it is not an error to specify an entry variable whose value is an entry point of an inactive block. These variables will compare equal. However, entry names on the same PROCEDURE statement do not compare equal. File If the operands represent file values, all of whose parts are equal, the file variables will compare equal. Format Format labels on the same statement compare equal. Label Labels on the same statement compare equal. In a comparison operation, it is not an error to specify a label variable whose value is a label constant used in a block that is no longer active. The label on a compound statement does not compare equal with that on any label contained in the body of the compound statement. ═══ Examples of Comparison Operations ═══ Following are some examples of comparison operations used in several different ways.  The following example shows a comparison operation in an IF statement: IF A = B THEN action-if-true; ELSE action-if-false; The evaluation of the expression A = B yields either '1'B for true, or '0'B for false.  In the following assignment statement, the value '1'B is assigned to X if A is less than B. Otherwise, the value '0'B is assigned. X = A <= B;  In the following assignment statement: X = A = B; the first = symbol is the assignment symbol. The second = symbol is the comparison operator. The value '1'B is assigned to X if A is equal to B. Otherwise, the value '0'B is assigned.  An example of comparisons in an arithmetic expression is: (X<0)*A + (0<=X & X<=100)*B + (100 Using Concatenation Operations ═══ You specify a concatenation operation by combining operands with the concatenation operator, ║. This operator is an infix operator, so you must place it between two operands. Concatenation signifies that the operands are to be joined in such a way that the last character, bit, or graphic of the operand to the left immediately precedes the first character, bit, or graphic of the operand to the right (with nothing intervening). Concatenation can be performed only on strings- either character, bit, or graphic. String conversions in concatenation will occur if you mix string types. ═══ String Conversions in Concatenation ═══ The concatenation operator, ║, can cause conversion to a string type because concatenation can be performed only on strings (character, bit, or graphic). Note the following conversion rules:  If either operand is graphic, the result is graphic; otherwise,  If both operands are bit, the result is bit; otherwise,  Implicit conversion is to the character string type. ═══ Using Combinations of Operations ═══ Description An expression can contain multiple operations. You can use any combination of operations. If you use multiple operators in an expression, the expression will be evaluated based on a priority of operations. Each operation within an expression is evaluated according to the rules for that kind of operation, with necessary data conversions taking place before the operation is performed. Example Combining operations ═══ Example - Combining Operations ═══ Different types of combinations can be combined in a single operational expression. For example: DECLARE RESULT BIT(3), A FIXED DECIMAL(1), B FIXED BINARY(3), C CHARACTER(2), D BIT(4); RESULT = A + B < C & D; The final expression in the example is evaluated as follows:  The decimal value of A is converted to binary base.  The binary addition is performed, adding A and B.  The binary result is compared with the converted binary value of C.  The bit result of the comparison is extended to the length of the bit variable D, and the "and" operation is performed.  The result of the "and" operation, a bit string of length 4, is assigned to RESULT without conversion, but with truncation on the right. The expression in this example is evaluated operation-by-operation, from left to right. Such is the case for this particular expression. The order of evaluation, however, depends upon the priority of the operators appearing in the expression. ═══ Using Array Expressions ═══ Description Evaluation of an array expression yields an array result. All operations performed on arrays are performed element-by-element, in row-major order. Therefore, when you refer to arrays in an array expression, be sure that all of the arrays have the same number of dimensions. Furthermore, each dimension must be of identical bounds. Your array expressions can include variables and constants. You may combine operations, subject to necessary data type conversions. Related Information  Prefix operators and arrays  Infix operators and arrays ═══ Prefix Operators and Arrays ═══ Description The operation of a prefix operator (an operator preceding a single operand) on an array produces an array of identical bounds. Each element of this array is the result of the operation performed on each element of the original array. Example Using a prefix operator on an array ═══ Infix Operators and Arrays ═══ Description Array expressions can include infix operators (an operator between two operands). Infix operations that include an array variable as one operand can have a variable, constant, or another array as the other operand. If the two operands of an infix operator are arrays, the arrays must have the same number of dimensions. The corresponding dimensions must also have identical lower and upper bounds. The result is an array with bounds identical to those of the original arrays. Example Array and array infix operations ═══ Examples - Array and Array Infix Operations ═══ You may use infix operators between arrays of identical dimensions and bounds. For example: If A is the array 2 4 3 6 1 7 4 8 2 and if B is the array 1 5 7 8 3 4 6 3 1 then A + B is the array 3 9 10 14 4 11 10 11 3 and A*B is the array 2 20 21 48 3 28 24 24 2 and 9>A is the array 1 0 0 of length 1 bit strings 0 0 1 0 1 1 ═══ 1.4. PL/I Condition Handling ═══ Description While a PL/I program is executed, a number of conditions are detected if they are raised. These conditions can be errors (such as overflow or an input/output transmission error) or they can be conditions that are expected (such as the end of an input file or the end of a page when output is being printed). A condition is also raised when a SIGNAL statement for that condition is executed. A condition is enabled when raising it executes an action. An action specified to be executed when an enabled condition is raised is established. You use the enabling of conditions and specifying of the action required when a condition is raised to control the handling of conditions. The established action can be an ON-unit or the implicit action defined for the condition. When an ON-unit is invoked, it is treated as a procedure without parameters. To assist you in making use of ON-units, built-in functions and pseudovariables are provided so that you can find out about the cause of a condition. The implicit action for many conditions is raising the ERROR condition. This provides a common condition that can be used to check for a number of different conditions, rather than checking each condition separately. The condition handling built-in functions provide information, such as the name of the entry point of the procedure in which the condition was raised, the character or character string that raised a CONVERSION condition, the value of the key used in the last record transmitted, and so on. Some can be used as pseudovariables for error correction. The ONCODE built-in function provides a fixed-point binary value of precision (15,0) whose value depends on the cause of the last condition. ONCODE can be used to distinguish between the various circumstances that raise a particular condition (for instance, the ERROR condition). Related Information  Conditions  Condition enabling/disabling  ON-units  CONDITION attribute  Multiple conditions ═══ CONDITION Attribute ═══ Description The CONDITION attribute specifies that the declared name identifies a programmer-defined condition. A name that appears with the CONDITION condition in an ON, SIGNAL, or REVERT statement is contextually declared to be a condition name. The default scope is EXTERNAL. Syntax ────CONDITION──── ═══ Condition Enabling/Disabling ═══ Description Some conditions are always enabled; they cannot be disabled. Some are enabled unless you disable them. And some are disabled unless you enable them. Conditions are either enabled or disabled when the name of the condition appears in a condition-prefix on a statement. A condition prefix can be attached to any statement except a DECLARE statement, DEFAULT statement, or % statement. It indicates that the corresponding condition is enabled (or disabled) within the scope of the prefix. When an enabled condition is raised, it causes the established action to happen. The action performed can be the implicit action defined by the condition, or an action that you specify in an ON-unit. When a condition is disabled, the raising of the condition does not execute an action. Example Consider the following use of condition prefixes: (SIZE): L1: X=(I**N) / (M+L); (SIZE): is the condition prefix; L1 is the label prefix. Related Information  Classes and statuses of conditions  Scope of the condition prefix Syntax ┌──────────────────────────────────┐ │ ┌─────────,─────────┐ │   │ │ ──────(─────┬──condition────┬──┴──):──┴─┬──;──────────┬───── └──NO-condition─┘ └──statement──┘ ═══ Classes and Statuses of Conditions ═══ Key The following defines the classes and the statuses of conditions in the table below: Always enabled These conditions cannot be disabled. Default disabled These conditions are disabled until you enable them. Default enabled These conditions are enabled until you disable them. _____________________________________________________________________________ Class and conditions Status To enable/disable, use: _____________________________________________________________________________ Computational (for data handling, expression evaluation, and computation) CONVERSION Default enabled CONVERSION/NOCONVERSION FIXEDOVERFLOW Default enabled FIXEDOVERFLOW/NOFIXEDOVERFLOW OVERFLOW Default enabled OVERFLOW/NOOVERFLOW UNDERFLOW Default enabled UNDERFLOW/NOUNDERFLOW ZERODIVIDE Default enabled ZERODIVIDE/NOZERODIVIDE _____________________________________________________________________________ Input/Output ENDFILE Always enabled ENDPAGE Always enabled KEY Always enabled NAME Always enabled PENDING 1 Always enabled RECORD Always enabled TRANSMIT Always enabled UNDEFINEDFILE Always enabled _____________________________________________________________________________ Program Checkout (for debugging a program) SIZE Default disabled SIZE/NOSIZE STRINGRANGE Default disabled STRINGRANGE/NOSTRINGRANGE STRINGSIZE Default disabled STRINGSIZE/NOSTRINGSIZE SUBSCRIPTRANGE Default disabled SUBSCRIPTRANGE/NOSUBSCRIPTRANGE _____________________________________________________________________________ Miscellaneous AREA Always enabled ATTENTION Always enabled CONDITION Always enabled ERROR Always enabled FINISH Always enabled Note: 1 PENDING is for MVS only. _____________________________________________________________________________ ═══ Scope of the Condition Prefix ═══ The scope of a condition prefix (the part of the program throughout which it applies) is the statement or block to which the prefix is attached. The prefix does not necessarily apply to any procedures or ON-units that can be invoked in the execution of the statement. A condition prefix attached to a PROCEDURE or BEGIN statement applies to all the statements up to and including the corresponding END statement. This includes other PROCEDURE or BEGIN statements nested within that block. The enabling or disabling of a condition can be redefined within a block by attaching a prefix to statements within the block, including PROCEDURE and BEGIN statements (thus redefining the enabling or disabling of the condition within nested blocks). Such a redefinition applies only to the execution of the statement to which the prefix is attached. In the case of a nested PROCEDURE or BEGIN statement, it applies only to the block the statement defines, as well as any blocks contained within that block. ═══ ON-Units ═══ Description An implicit action exists for every language-defined condition. When an enabled condition is raised, this implicit action is executed unless an ON-unit for that condition is in effect. When an ON-unit is invoked, it is treated as a procedure without parameters. To assist you in making use of ON-units, you can use the condition handling built-in functions to inquire about the cause of the condition. They extract information such as the name of the entry point of the procedure in which the condition was raised, the character or character string that raised a CONVERSION condition, the value of the key used in the last record transmitted, and so on. You can use the ONSOURCE pseudovariable and the ONCHAR pseudovariable in CONVERSION ON-units to correct conversion errors. Related Information  ON statement  REVERT statement  SIGNAL statement  Null ON-unit  Scope of the ON-unit  Dynamically descendant ON-units  ON-units for file variables ═══ ON Statement ═══ Description The ON statement establishes the action to be executed for any subsequent raising of an enabled condition in the scope of the established action. Syntax ────ON─────condition──────┬────────┬──┬──SYSTEM;───┬──── └──SNAP──┘ └──ON-unit───┘ ═══ ON-Unit Specification ═══ ON-unit specifies the action to be executed when the condition is raised and 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. The ON-unit can be either a single unlabeled simple statement or an unlabeled begin block. If it is an unlabeled simple statement, it can be any simple statement except BEGIN, DECLARE, DEFAULT, DO, END, ENTRY, FORMAT, LEAVE, OTHERWISE, PROCEDURE, RETURN, SELECT, WHEN, or % statements. If the ON-unit is an unlabeled begin block, a RETURN statement can appear only within a procedure nested within the begin block; a LEAVE statement can appear only within a do-group nested within the begin block. An ON-unit is treated as a procedure (without parameters) that is internal to the block in which it appears. Any names referenced in an ON-unit are those known in the environment in which the ON statement for that ON-unit was executed, rather than the environment in which the condition was raised. When execution of the ON-unit is complete, control generally returns to the block from which the ON-unit was entered. Just as with a procedure, control can be transferred out of an ON-unit by a GO TO statement. In this case, control is transferred to the point specified in the GO TO, and a normal return does not occur. The specific point to which control returns from an ON-unit varies for different conditions. ON-units, except certain single-statement ON-units, are treated as separate program blocks. They are separated from the ON statement and compiled with prologue and epilogue code. In order to save the overhead of executing prologue and epilogue code, certain single-statement ON-units are not compiled. Instead, the action required is carried out under the control of the error handling routine. The types of ON-units involved are:  Null ON-units  ON-units containing only the SNAP option, the SNAP SYSTEM option, or the SYSTEM option  ON-units containing only a GO TO statement. ═══ REVERT Statement ═══ Description Execution of the REVERT statement in a given block cancels the action specification of any ON statement for the condition that executed in that block. Execution then re-establishes the action specification that was in force at the time of the activation of the block. It can affect only ON statements that are internal to the block in which the REVERT statement occurs and which have been executed in the same invocation of that block. The execution of a REVERT statement has the effect described above only if both of the following are true: 1. An ON statement, specifying the same condition and internal to the same invocation of the same block, was executed after the block was activated 2. The execution of no other similar REVERT statement has intervened. If either of these two conditions is not met, the REVERT statement is treated as a null statement. Syntax ────REVERT────────condition──────;──── ═══ SIGNAL Statement ═══ Description You can raise a condition by means of the SIGNAL 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. If the specified condition is disabled, the SIGNAL statement becomes equivalent to a null statement. Syntax ────SIGNAL────condition────;──── ═══ Scope of the ON-Unit ═══ 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. When another ON statement specifies the same conditions:  If a later ON statement specifies the same condition as a prior ON statement and this later ON statement is executed in a block which is a dynamic descendent of the block containing the prior ON statement, the action specification of the prior ON statement is temporarily suspended, or stacked. It can be restored either by the execution of a REVERT statement, or by the termination of the block containing the later ON statement. When control returns from a block, all established actions that existed at the time of its activation are re-established. This makes it impossible for a subroutine to alter the action established for the block that invoked the subroutine.  If the later ON statement and the prior ON statement are internal to the same invocation of the same block, the effect of the prior ON statement is logically nullified. No re-establishment is possible, except through execution of another ON statement (or re-execution of an overridden ON statement). ═══ Multiple Conditions ═══ A multiple condition is the simultaneous raising of two or more conditions. The conditions for which a multiple condition can occur are:  RECORD  TRANSMIT The TRANSMIT condition is always processed first. The RECORD condition is ignored unless there is a normal return from the TRANSMIT ON-unit. Multiple conditions are processed successively. When one of the following occurs, no subsequent conditions are processed:  The processing of a condition terminates the program, through either implicit action for the condition, normal return from an ON-unit, or abnormal termination in the ON-unit.  Control is transferred out of an ON-unit by means of a GO TO statement, so that a normal return is not allowed. ═══ Conditions ═══ Description In general, the following information is given for each condition:  A discussion of the condition, including its syntax and the circumstances under which the condition can be raised. A condition can always be raised by a SIGNAL statement; this fact is not included in the descriptions.  Result - the result of the operation that raised the condition. This applies when the condition is disabled as well as when it is enabled. In some cases, the result is undefined.  Implicit action - the action taken when an enabled condition is raised and no ON-unit is currently established for the condition.  Status - an indication of the enabled/disabled status of the condition at the start of the program, and how the condition can be disabled (if possible) or enabled.  Normal return - the point to which control is returned as a result of the normal termination of the ON-unit. A GO TO statement that transfers control out of an ON-unit is an abnormal ON-unit termination. If a condition (except the ERROR condition) has been raised by the SIGNAL statement, the normal return is always to the statement immediately following SIGNAL.  Condition codes - the codes corresponding to the conditions and errors for which the program is checked. For an explanation of each code, see "Related Information" below. Conditions The following are the PL/I conditions: AREA condition OVERFLOW condition ATTENTION condition PENDING condition CONDITION condition RECORD condition CONVERSION condition SIZE condition ENDFILE condition STRINGRANGE condition ENDPAGE condition STRINGSIZE condition ERROR condition SUBSCRIPTRANGE condition FINISH condition TRANSMIT condition FIXEDOVERFLOW condition UNDEFINEDFILE condition KEY condition UNDERFLOW condition NAME condition ZERODIVIDE condition Related Information Condition codes ═══ AREA Condition ═══ 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. The syntax for AREA is: ────AREA──── Result: In both cases the attempted allocation or assignment has no effect. Implicit Action: A message is printed and the ERROR condition is raised. Status: AREA is always enabled. Normal return: On normal return from the ON-unit, the action is as follows:  If the condition was raised by an allocation and the ON-unit is a null ON-unit, the allocation is not re-attempted.  If the condition was raised by an allocation, the allocation is re-attempted. Before the attempt is made, the area reference is re-evaluated. Thus, if the ON-unit has changed the value of a pointer qualifying the reference to the inadequate area so that it points to another area, the allocation is re-attempted within the new area.  If the condition was raised by an area assignment, or by a SIGNAL statement, execution continues from the point at which the condition was raised. Condition Codes: 360, 361, 362 ═══ ATTENTION Condition ═══ The ATTENTION condition is raised when the user signals attention at the terminal during interactive processing. Raising the condition causes an ATTENTION ON-unit to be entered. The condition can also be raised by a SIGNAL ATTENTION statement in batch or conversational processing. The syntax for ATTENTION is: ────ATTENTION──── Abbreviation: ATTN An ATTENTION ON-unit is entered when:  The environment passes an interrupt request to the program and the program was compiled using the INTERRUPT option.  A SIGNAL ATTENTION statement is executed. In this case, the compile time INTERRUPT option is not required. A SIGNAL ATTENTION statement causes an ON-unit to be entered. If there is no ATTENTION ON-unit, the condition is effectively ignored, and there is no change in the flow of control. Implicit action: The attention is effectively ignored. Status: ATTENTION is always enabled. Normal Return: On return from an ATTENTION ON-unit, processing is resumed at a point in the program immediately following the point at which the condition was raised. Condition Code: 400 ═══ CONDITION Condition ═══ The CONDITION condition is raised by a SIGNAL statement that specifies the appropriate name. The name specified in the SIGNAL statement determines which CONDITION condition is to be raised. The syntax for CONDITION is: ────CONDITION──(──name──)──── Abbreviation: COND The CONDITION condition allows you to establish an ON-unit that will be executed whenever a SIGNAL statement is executed specifying CONDITION 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 a SIGNAL statement. Normal rules of name scope apply; a condition name is external by default, but can be declared INTERNAL. Example: Including the CONDITION condition in a program Implicit action: A message is printed and execution continues with the statement following SIGNAL. Status: CONDITION is always enabled. Normal Return: Execution continues with the statement following the SIGNAL statement. Condition Code: 500 ═══ CONVERSION Condition ═══ The CONVERSION computational condition is raised whenever an invalid conversion is attempted on character data. This attempt can be made internally or during an input/output operation. The syntax for CONVERSION is: ────CONVERSION──── Abbreviation: CONV All conversions of character data are carried out character-by-character in a left-to-right sequence. The condition is raised for each invalid character. The condition is also raised if all the characters are blank, with the following exceptions:  For input with the F-format item, a value of zero is assumed.  For input with the E-format item, be aware that sometimes the ON-unit will be repeatedly entered. When an invalid character is encountered, the current action specification for the condition is executed (provided, of course, that CONVERSION is not disabled). If the action specification is an ON-unit, the invalid character can be replaced within the ON-unit by using the ONSOURCE or ONCHAR pseudovariables. If the CONVERSION condition is raised and it is disabled, the program is in error. If the CONVERSION condition is raised under graphic conditions (that is, GRAPHIC built-in), the ONCHAR and ONSOURCE built-in functions do not contain valid source data. If the program attempts a normal return under these conditions, the ERROR condition is raised. Loop Handling: An infinite loop can occur from either of the the following two situations: 1. If you are converting from a character string to a numeric, and you use a character string containing an 'E' or an 'F', the system can interpret the 'E' as part of a legitimate number in an exponential notation, or the 'F' as a scaling factor. The combination of the 'E' or the 'F' with other non-numeric characters can result in an infinite loop in the error handler. 2. If you are converting from a character string to a numeric, and the character string ends with the letter 'B', the conversion routine assumes that the field is fixed binary. This can also result in an infinite loop. Examples: When CONVERSION is raised Result: When CONVERSION is raised, the contents of the entire result field are undefined. Implicit Action: A message is printed and the ERROR condition is raised. Status: CONVERSION is enabled throughout the program, except within the scope of a condition prefix specifying NOCONVERSION. Normal Return: If CONVERSION was raised on a character string source (not graphic source) and either ONSOURCE or ONCHAR pseudovariables are used in the ON-unit, the program retries the conversion on return from the ON-unit. If the conversion error is not corrected using these pseudovariables, the program will loop. If these pseudovariables are not used, the ERROR condition is raised. Condition Codes: 600-642 ═══ ENDFILE Condition ═══ The ENDFILE input/output condition can be raised during an operation by an attempt to read past the end of the file specified in the GET statement or READ statement. It applies only to SEQUENTIAL INPUT, SEQUENTIAL UPDATE, and STREAM INPUT files. The syntax for ENDFILE is: ────ENDFILE────(──file-reference──)──── In record-oriented data transmission, ENDFILE is raised whenever an end of file is encountered during the execution of a READ statement. In stream-oriented data transmission, ENDFILE 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. If 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. If the file is not closed after ENDFILE is raised, any subsequent GET or READ statement for that file immediately raises the ENDFILE condition again. The ENDFILE condition for a data transmission statement using the EVENT option is raised when the WAIT statement for that event is encountered. Implicit action: A message is printed and the ERROR condition is raised. Status: The ENDFILE condition is always enabled. Normal Return: Execution continues with the statement immediately following the GET or READ statement that raised the ENDFILE. If a file is closed in an ON-unit for this condition, the results of normal return are undefined. Exit from such an ON-unit must be by means of a GO TO statement. Condition Code 70 ═══ ENDPAGE Condition ═══ 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 PAGESIZE option in an OPEN statement; if PAGESIZE 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 LINE option, or by the SKIP option. ENDPAGE can also be raised by a LINE option or LINE format item that specified a line number less than the current line number. The syntax for ENDPAGE is: ────ENDPAGE────(──file-reference──)──── ENDPAGE is raised only once per page, except when it is raised by the SIGNAL statement. When ENDPAGE is raised, the current line number is one greater than that specified by the PAGESIZE option (default is 61) so that it is possible to continue writing on the same page. 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. If the ON-unit does not start a new page, the current line number can increase indefinitely. If a subsequent LINE option or LINE format item specifies a line number that is less than or equal to the current line number, ENDPAGE is not raised, but a new page is started with the current line set to one. An exception is that if the current line number is equal to the specified line number, and the file is positioned on column one of the line, ENDPAGE is not raised. If ENDPAGE is raised during data transmission, on return from the ON-unit the data is written on the current line, which might have been changed by the ON-unit. If ENDPAGE results from a LINE or SKIP option, on return from the ON-unit the action specified by LINE or SKIP is ignored. Implicit Action: A new page is started. If the condition is signaled, execution is unaffected and continues with the statement following the SIGNAL statement. Status: ENDPAGE is always enabled. Normal Return: Execution of the PUT statement continues in the manner described above. Condition Code: 90 ═══ ERROR Condition ═══ The ERROR condition is the implicit action for many conditions. This provides a common condition that can be used to check for a number of different conditions, rather than checking each condition separately. The ERROR condition is raised under the following circumstances:  As a result of the implicit action for a condition, which is to raise the ERROR condition.  As a result of an error (for which there is no other PL/I-defined condition) during program execution.  As a result of an abend.  As a result of a SIGNAL ERROR statement. An error message is issued if no ON-unit is active when the ERROR condition arises or if the ON-unit does not use a GO TO (to exit the block) to recover from the condition. The syntax for ERROR is: ────ERROR──── Implicit Action: If a message has not already been printed as a result of an implicit action for some other condition, then a message is printed describing the error. In all cases, the FINISH condition is raised and the program terminates. Status: ERROR is always enabled. Normal Return: The implicit action is taken. Condition Codes:  Codes 3,9  All codes 1000 and above ═══ FINISH Condition ═══ The FINISH condition is raised during execution of a statement that would terminate the PL/I program. That is, by a STOP statement or an EXIT statement in any procedure, or a RETURN statement or an END statement in the MAIN procedure of the program. The condition is also raised by SIGNAL FINISH and as part of the implicit action for the ERROR condition. An abnormal return from the ON-unit avoids program termination and allows the program to continue. When a program is made up of PL/I and non-PL/I procedures, the following actions take place:  If the termination is normal: - The FINISH ON-Unit, if established, is given control only if the main procedure is PL/I.  If the termination is abnormal: - The FINISH ON-Unit, if established in an active block, is given control. The syntax for FINISH is: ────FINISH──── Implicit action: No action is taken and processing continues from the point where the condition was raised. Status: FINISH is always enabled. Normal return: Execution of the statement is resumed. Condition Code: 4 ═══ FIXEDOVERFLOW Condition ═══ The FIXEDOVERFLOW 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 FIXEDOVERFLOW condition differs from the SIZE condition in that SIZE is raised when a result exceeds the declared size of a variable, while FIXEDOVERFLOW is raised when a result exceeds the maximum allowed by the computer. The syntax for FIXEDOVERFLOW is: ────FIXEDOVERFLOW──── Abbreviation: FOFL If the FIXEDOVERFLOW condition is raised and it is disabled, the program is in error. Result: The result of the invalid fixed-point operation is undefined. Implicit Action: A message is printed and the ERROR condition is raised. Status: FIXEDOVERFLOW is enabled throughout the program, except within the scope of a condition prefix that specifies NOFIXEDOVERFLOW. Normal Return: Control returns to the point immediately following the point at which the condition was raised. Condition Code: 310 Note: If the SIZE condition is disabled, an attempt to assign an oversize number to a fixed decimal variable can raise the FIXEDOVERFLOW condition. Because this checking involves a substantial overhead in both storage space and at run-time, it usually is used only in program testing. You should consider removing it for production programs. ═══ KEY Condition ═══ The KEY input/output condition can be raised only during operations on keyed records. It is raised in the cases mentioned in the list of condition codes, below. The syntax for KEY is: ────KEY────(──file-reference──)──── When a LOCATE statement is used for VSAM key-sequenced data set, the KEY condition for this LOCATE statement is not raised until transmission of the record is attempted; that is, at the next WRITE statement or LOCATE statement for the file, or when the file is closed. The KEY condition for a data transmission statement using the EVENT option is raised when the WAIT statement for that event is encountered. When a LOCATE statement is used for REGIONAL(3) data set with V-format or U-format records, and there is not enough room in the specified region, the KEY condition is not raised until transmission of the record is attempted. Neither the record for which the condition is raised nor the current record is transmitted. Implicit Action: A message is printed and the ERROR condition is raised. Status: KEY is always enabled. Normal Return: Control passes to the statement immediately following the statement that raised KEY. If a file is closed in an ON-unit for this condition, the results of normal return are undefined. Exit from such an ON-unit should be by means of a GO TO statement. Condition Codes: 50-58 ═══ NAME Condition ═══ The NAME input/output condition can be raised only during execution of a data-directed GET statement with the FILE option. It is raised in any of the following situations:  The syntax is not correct.  The name is missing or invalid: - No counterpart is found in the data list. - If there is no data list, the name is not known in the block. - A qualified name is not fully qualified. - More than 256 characters have been specified for a fully qualified name. - The name is ISUB-defined - DBCS contains a byte outside the valid range of X'41' to X'FE'.  A subscript list is missing or invalid: - A subscript is missing. - The number of subscripts is incorrect. - More than 10 digits are in a subscript (leading zeros ignored). - A subscript is outside the allowed range of the current allocation of the variable. You can retrieve the incorrect data field by using the built-in function DATAFIELD in the ON-unit. The syntax for NAME is: ────NAME────(──file-reference──)──── Implicit Action: The incorrect data field is ignored, a message is printed, and execution of the GET statement continues. Status: NAME is always enabled. Normal Return: The execution of the GET statement continues with the next name in the stream. Condition Code: 10 ═══ OVERFLOW Condition ═══ The OVERFLOW computational condition is raised when the magnitude of a floating-point number exceeds the maximum allowed. The OVERFLOW condition differs from the SIZE condition in that SIZE is raised when a result exceeds the declared size of a variable, while OVERFLOW is raised when a result exceeds the maximum allowed by the computer. The syntax for OVERFLOW is: ────OVERFLOW──── Abbreviation: OFL If the OVERFLOW condition is raised and it is disabled, the program is in error. Result: The value of such an invalid floating-point number is undefined. Implicit action: A message is printed and the ERROR condition is raised. Status: OVERFLOW is enabled throughout the program, except within the scope of a condition prefix specifying NOOVERFLOW. Normal Return: Control returns to the point immediately following the point at which the condition was raised. Condition Code: 300 ═══ PENDING Condition ═══ Except when signaled, the PENDING input/output condition can be raised only during execution of a READ statement for a TRANSIENT INPUT file. It is raised when an attempt is made to read a record that is temporarily unavailable (that is, when the message queue associated with the file contains no messages at the time the READ statement is executed). The syntax for the PENDING condition is: ─────PENDING─(──file-reference──)─────────── The value of the ONKEY built-in function when the PENDING condition is raised is a null string. Implicit Action: The action is described for normal return. Status: PENDING is always enabled. Normal Return: Control returns to the point at which the condition was raised (unless the condition was signaled), where execution is suspended until an appropriate record becomes available. If the condition was signaled, execution continues with the statement immediately following the SIGNAL statement. Condition Code: 100 Note: PENDING is for MVS only. ═══ RECORD Condition ═══ The RECORD input/output condition can be raised only during a READ, WRITE, LOCATE, or REWRITE operation. It is raised in the cases mentioned in "Condition Codes" below. The syntax for the RECORD condition is: ────RECORD────(──file-reference──)──── If the SCALARVARYING option is applied to the file (it must be applied to a file using locate mode to transmit varying-length strings), a 2-byte length prefix is transmitted with an element varying-length string. The length prefix is not reset if the RECORD condition is raised. If the SCALARVARYING option is not applied to the file, the length prefix is not transmitted; on input, the current length of a varying-length string is set to the shorter of the record length and the maximum length of the string. The RECORD condition for a data transmission statement using the EVENT option is raised when the WAIT statement for that event is encountered. The RECORD condition is not raised for undefined-length records read from:  A CONSECUTIVE data set through a SEQUENTIAL UNBUFFERED file.  A REGIONAL(3) data set through a direct file. Implicit Action: A message is printed and the ERROR condition is raised. Status: RECORD is always enabled. Normal Return: Execution continues with the statement immediately following the one for which RECORD was raised. If a file is closed in an ON-unit for this condition, the results of normal return are undefined. Exit from such an ON-unit should be by means of a GO TO statement. Condition Codes: 20-24 ═══ SIZE Condition ═══ The SIZE 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 precisions. The size condition is not enabled unless it appears in a condition prefix. The syntax for SIZE is: ────SIZE──── The SIZE condition differs from the FIXEDOVERFLOW condition in that, whereas FIXEDOVERFLOW is raised when the size of a calculated fixed-point value exceeds the maximum allowed by the implementation, SIZE is raised when the size of the value being assigned to a data item exceeds the declared (or default) size of the data item. SIZE can be raised on assignment of a value regardless of whether or not FIXEDOVERFLOW was raised in the calculation of that value. The declared size is not necessarily the actual precision with which the item is held in storage; however, the limit for SIZE is the declared or default size, not the actual size in storage. For example, a fixed binary item of precision (20) will occupy a fullword in storage, but SIZE is raised if a value whose size exceeds FIXED BINARY(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 consider removing it for production programs. If the SIZE condition is raised and it is disabled, the program is in error. Result: The result of the assignment is undefined. Implicit Action: A message is printed and the ERROR condition is raised. Status: SIZE is disabled within the scope of a NOSIZE condition prefix and elsewhere throughout the program, except within the scope of a condition prefix specifying SIZE. Normal Return: Control returns to the point immediately following the point at which the condition was raised. Condition Codes: 340, 341 ═══ STRINGRANGE Condition ═══ The STRINGRANGE 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. It is raised for each such reference. The syntax for STRINGRANGE is: ────STRINGRANGE──── Abbreviation: STRG Implicit Action: A message is printed and processing continues as described for normal return. Status: STRINGRANGE is disabled by default and within the scope of a NOSTRINGRANGE condition prefix. It is enabled only within the scope of a STRINGRANGE condition prefix. Normal Return: Execution continues with a revised SUBSTR reference whose value is defined as follows: Assuming that the length of the source string (after execution of the ON-unit, if specified) is k, the starting point is i, and the length of the substring is j;  If i is greater than k, the value is the null string.  If i is less than or equal to k, the value is that substring beginning at the mth character, bit, or graphic of the source string and extending n characters, bits, or graphics, where m and n are defined by: m = MAX( i,1 ) n = MAX( 0,MIN( j + MIN(i,1) - 1,k - m + 1 )) -if j is specified- n = k - m + 1 -if j is not specified- This means that the new arguments are forced within the limits. The values of i and j are established before entry to the ON-unit. They are not re-evaluated on return from the ON-unit. The value of k might change in the ON-unit if the first argument of SUBSTR is a varying-length string. The value n is computed on return from the ON-unit using any new value of k. Condition Code: 350 ═══ STRINGSIZE Condition ═══ The STRINGSIZE program-checkout condition is raised when you attempt to assign a string to a target with a shorter maximum length. The syntax for STRINGSIZE is: ─────STRINGSIZE──── Abbreviation: STRZ Result: 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. Implicit Action: A message is printed and processing continues. However, if error messages and program output are using the same output stream, the output is unpredictable because no synchronization between them is provided. Status: STRINGSIZE is disabled by default and within the scope of a NOSTRINGSIZE condition prefix. It is enabled only within the range of a STRINGSIZE condition prefix. Normal Return: Execution continues from the point at which the condition was raised. Condition Codes: 150, 151 ═══ SUBSCRIPTRANGE Condition ═══ The SUBSCRIPTRANGE program-checkout condition is raised whenever a subscript is evaluated and found to lie outside its specified bounds. The condition is also raised when an iSUB subscript is outside the range given in the declaration of the iSUB defined array. The order of raising SUBSCRIPTRANGE relative to evaluation of other subscripts is undefined. The syntax for SUBSCRIPTRANGE is: ────SUBSCRIPTRANGE──── Abbreviation: SUBRG Result: When SUBSCRIPTRANGE has been raised, the value of the invalid subscript is undefined, and, hence, the reference is also undefined. Implicit Action: A message is printed and the ERROR condition is raised. Status: SUBSCRIPTRANGE is disabled by default and within the scope of a NOSUBSCRIPTRANGE condition prefix. It is enabled only within the scope of a SUBSCRIPTRANGE condition prefix. Normal Return: Normal return from a SUBSCRIPTRANGE ON-unit raises the ERROR condition. Condition Codes: 520, 521 ═══ TRANSMIT Condition ═══ The TRANSMIT input/output condition can be raised during any input/output operation. It is raised by an uncorrectable transmission error of a record (or of a block, if records are blocked) and, therefore, signifies that any data transmitted is potentially incorrect. "Uncorrectable transmission error" means an input/output error that could not be corrected during this execution. It can be caused by a damaged recording medium, or by incorrect specification or setup. The syntax for TRANSMIT is: ────TRANSMIT────(──file-reference──)──── During input, TRANSMIT is raised after transmission of the potentially incorrect record. If records are blocked, TRANSMIT is raised for each subsequent record in the block. During output, TRANSMIT is raised after transmission. If records are blocked, transmission will occur when the block is complete rather than after each output statement. When a spanned record is being updated, the TRANSMIT condition is raised on the last segment of a record only. It is not raised for any subsequent records in the same block, although the integrity of these records cannot be assumed. The TRANSMIT condition for a data transmission statement using the EVENT option is raised when the WAIT statement for that event is encountered in the same process. Implicit Action: A message is printed and the ERROR condition is raised. Status: TRANSMIT is always enabled. Normal Return: Processing continues as though no error had occurred, allowing another condition (for example, RECORD) to be raised by the statement or data item that raised the TRANSMIT condition. If a file is closed in an ON-unit for this condition, the results of normal return are undefined. Exit from such an ON-unit should be by means of a GO TO statement. Condition Codes: 40-46 ═══ UNDEFINEDFILE Condition ═══ The UNDEFINEDFILE input/output condition is raised whenever a nonzero return code is received from the OPEN SVC. If 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 UNDEFINEDFILE is: ────UNDEFINEDFILE────(──file-reference──)──── Abbreviation: UNDF If UNDEFINEDFILE is raised for more than one file in the same OPEN statement, ON-units are executed according to the order of appearance (taken from left to right) of the file names in that OPEN statement. The UNDEFINEDFILE condition is raised not only by conflicting attributes (such as DIRECT with PRINT), but also by:  Block size smaller than record size (except when records are spanned)  LINESIZE exceeding the maximum allowed  KEYLENGTH zero or not specified for creation of INDEXED, REGIONAL(2), or REGIONAL(3) data sets  Specifying a KEYLOC option, for an INDEXED data set, with a value resulting in KEYLENGTH + KEYLOC exceeding the record length  Specifying a V-format logical record length of less than 18 bytes for STREAM data sets  Specifying, for FB-format records, a block size that is not an integral multiple of the record size  Specifying, for VB-format records, a logical record length that is not at least 4 bytes smaller than the specified block size. Implicit Action: A message is printed and the ERROR condition is raised. Status: UNDEFINEDFILE is always enabled. Normal Return: Upon the normal completion of the final ON-unit, control is given to the statement immediately following the statement that raised the condition. Condition Codes: 80-89, 91-95 ═══ UNDERFLOW Condition ═══ The UNDERFLOW computational condition is raised when the magnitude of a floating-point number is smaller than the minimum allowed. The syntax for UNDERFLOW is : ────UNDERFLOW──── Abbreviation: UFL UNDERFLOW is not raised when equal numbers are subtracted (often called "significance error"). The expression "X**(-Y)" (where Y>0) can be evaluated by taking the reciprocal of "X**Y"; hence, the OVERFLOW condition might be raised instead of the UNDERFLOW condition. Result: The invalid floating-point value is set to 0. Implicit Action: A message is printed, and execution continues from the point at which the condition was raised. Status: UNDERFLOW is enabled throughout the program, except within the scope of a condition prefix specifying NOUNDERFLOW. Normal Return: Control returns to the point immediately following the point at which the condition was raised. Condition Code: 330 ═══ ZERODIVIDE Condition ═══ The ZERODIVIDE computational condition is raised when an attempt is made to divide by zero. This condition is raised for fixed-point and floating-point division. ZERODIVIDE condition is also raised instead of FIXEDOVERFLOW, 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 DIVIDE built-in function and the quotient exceeds the size specified for the result. The syntax for ZERODIVIDE is: ────ZERODIVIDE──── Abbreviation: ZDIV If the ZERODIVIDE condition is raised and it is disabled, the program is in error. Result: The result of a division by zero is undefined. Implicit Action: A message is printed and the ERROR condition is raised. Status: ZERODIVIDE is enabled throughout the program, except within the scope of a condition prefix specifying NOZERODIVIDE. Normal Return: Control returns to the point immediately following the point at which the condition was raised. Condition Code: 320 ═══ Condition Codes ═══ Description Condition codes listed here reflect an aggregate of condition codes generated by all implementations. Some might not be generated for a particular platform. Condition Codes The following is a summary of all condition codes in numerical sequence.  Condition codes 3 - 46  Condition codes 50 - 100  Condition codes 150 - 521  Condition codes 600 - 642  Condition codes 1002 - 1040  Condition codes 1500 - 1522  Condition codes 1550 - 2050  Condition codes 3000 - 3810  Condition codes 3901 - 9999 ═══ Condition Codes 3 - 46 ═══ 3 This condition is raised if, in a SELECT group, no WHEN clause is selected and no OTHERWISE clause is present. 4 SIGNAL FINISH, or STOP statement executed. 9 SIGNAL ERROR statement executed. 10 SIGNAL NAME statement executed or NAME condition occurred. 20 SIGNAL RECORD statement executed. 21 Record variable smaller than record size. Either:  The record is larger than the variable in a READ INTO statement; the remainder of the record is lost.  The record length specified for a file with fixed-length records is larger than the variable in a WRITE, REWRITE, or LOCATE statement; the remainder of the record is undefined. If the variable is a varying-length string, RECORD is not raised if the SCALARVARYING option is applied to the file. 22 Record variable larger than record size. Either:  The record length specified for a file with fixed-length records is smaller than the variable in a READ INTO statement; the remainder of the variable is undefined. If the variable is a varying-length string, RECORD is not raised if the SCALARVARYING option is applied to the file.  The maximum record length is smaller than the variable in a WRITE, REWRITE, or LOCATE statement. For WRITE or REWRITE, the remainder of the variable is lost; for LOCATE, the variable is not transmitted.  The variable in a WRITE or REWRITE statement indicates a zero length; no transmission occurs. If the variable is a varying-length string, RECORD is not raised if the SCALARVARYING option is applied to the file. 23 Record variable length is either zero or too short to contain the embedded key. The variable in a WRITE or REWRITE statement is too short to contain the data set embedded key; no transmission occurs. (This case currently applies only to VSAM key-sequenced data sets.) 24 Zero length record was read from a REGIONAL data set. 40 SIGNAL TRANSMIT statement executed. 41 Uncorrectable transmission error in output data set. 42 Uncorrectable transmission error in input data set. 43 Uncorrectable transmission error on output to index set (VSAM). 44 Uncorrectable transmission error on input from index set (VSAM). 45 Uncorrectable transmission error on output to sequence set (VSAM). 46 Uncorrectable transmission error on input from sequence set (VSAM). ═══ Condition Codes 50 - 100 ═══ 50 SIGNAL KEY statement executed. 51 Key specified cannot be found. 52 Attempt to add keyed record that has same key as a record already present in data set; or, in a REGIONAL(1) data set, attempt to write into a region already containing a record. 53 Value of expression specified in KEYFROM option during sequential creation of INDEXED or REGIONAL data set is less than value of previously specified key or region number. 54 Key conversion error, possibly due to region number not being numeric character. 55 Key specification is null string or begins (8)'1'B; or a change of embedded key has occurred on a sequential REWRITE[FROM] for an INDEXED or key-sequenced VSAM data set. 56 Attempt to access a record using a key that is outside the data set limits. 57 No space available to add a keyed record on ISAM insert. 58 Key of record to be added lies outside the range(s) specified for the data set. 70 SIGNAL ENDFILE statement executed or ENDFILE condition occurred. 80 SIGNAL UNDEFINEABLE statement executed. 81 Conflict in file attributes exists at open time between attributes in DECLARE statement and those in explicit or implicit OPEN statement. 82 Conflict between file attributes and physical organization of data set (for example, between file organization and device type), or VSAM data set has not been loaded. 83 After merging ENVIRONMENT options with DD statement and data set label, data set specification is incomplete; for example, block size or record format has not been specified. 84 No DD statement associating file with a data set. 85 During initialization of a DIRECT OUTPUT file associated with a REGIONAL data set, an input/output error occurred. 86 LINESIZE greater than implementation-defined maximum, or invalid value in an ENVIRONMENT option. 87 After merging ENVIRONMENT options with DD statement and data set label, conflicts exist in data set specification; the values of LRECL, BLKSIZE or RECSIZE are incompatible with one another or the DCB FUNCTION specified. 88 After merging ENVIRONMENT options with DD statement and data set label, conflicts exist in data set specification; the resulting combination of MODE/FUNCTION and record format are invalid. 89 Password invalid or not specified. 90 SIGNAL ENDPAGE statement executed or ENDPAGE condition occurred. 91 ENVIRONMENT option invalid for file accessing VSAM data set. 92 Error detected by VSAM while opening a VSAM data set; or during opening of a VSAM data set with the BKWD option, the attempt to position the data set at the last record failed. 93 Unidentified error detected by the operating system while opening a data set. 94 REUSE specified for a nonreusable data set. 95 Alternate index specified for a VSAM data set is empty. 100 SIGNAL PENDING statement executed or PENDING condition occurred. ═══ Condition Codes 150 - 521 ═══ 150 SIGNAL STRINGSIZE statement executed or STRINGSIZE condition occurred. 151 Truncation occurred during assignment of a mixed character string. 300 SIGNAL FIXEDOVERFLOW statement executed or FIXEDOVERFLOW condition occurred. 310 SIGNAL OVERFLOW statement executed or OVERFLOW condition occurred. 320 SIGNAL ZERODIVIDE statement executed or ZERODIVIDE condition occurred. 330 SIGNAL UNDERFLOW statement executed or UNDERFLOW condition occurred. 340 SIGNAL SIZE statement executed; or high-order nonzero digits have been lost in an assignment to a variable or temporary; or significant digits have been lost in an input/output operation. 341 High order nonzero digits have been lost in an input/output operation. 350 SIGNAL STRINGRANGE statement executed or STRINGRANGE condition occurred. 360 Attempt to allocate a based variable within an area that contains insufficient free storage for allocation to be made. 361 Insufficient space in target area for assignment of source area. 362 SIGNAL AREA statement executed. 400 SIGNAL ATTENTION statement executed or ATTENTION condition occurred. 500 SIGNAL CONDITION (name) statement executed. 510 SIGNAL CHECK statement executed. 520 SIGNAL SUBSCRIPTRANGE statement executed, or subscript has been evaluated and found to lie outside its specified bounds. 521 Subscript of iSUB-defined variable lies outside bounds of corresponding dimension of base variable. ═══ Condition Codes 600 - 642 ═══ 600 SIGNAL CONVERSION statement executed. 601 Invalid conversion attempted during input/output of a character string. 602 CONVERSION condition raised following TRANSMIT condition. 603 Error during processing of an F-format item for a GET STRING statement. 604 Error during processing of an F-format item for a GET FILE statement. 605 Error during processing of an F-format item for a GET FILE statement following a TRANSMIT condition. 606 Error during processing of an E-format item for a GET STRING statement. 607 Error during processing of an E-format item for a GET FILE statement. 608 Error during processing of an E-format item for a GET FILE statement following a TRANSMIT condition. 609 Error during processing of a B-format item for a GET STRING statement. 610 Error during processing of a B-format item for a GET FILE statement. 611 Error during processing of a B-format item for a GET FILE statement following a TRANSMIT condition. 612 Error during character value to arithmetic conversion. 613 Error during character value to arithmetic conversion for a GET or PUT FILE statement. 614 Error during character value to arithmetic conversion for a GET or PUT FILE statement following a TRANSMIT condition. 615 Error during character value to bit value conversion. 616 Error during character value to bit value conversion for a GET or PUT FILE statement. 617 Error during character value to bit value conversion for a GET or PUT FILE statement following a TRANSMIT condition. 618 Error during character value to picture conversion. 619 Error during character value to picture conversion for a GET or PUT FILE statement. 620 Error during character value to picture conversion for a GET or PUT FILE statement following a TRANSMIT condition. 621 Error in decimal P-format item for a GET STRING statement. 622 Error in decimal P-format input for a GET FILE statement. 623 Error in decimal P-format input for a GET FILE statement following a TRANSMIT condition. 624 Error in character P-format input for a GET FILE statement. 625 Error in character P-format input for a GET FILE statement. 626 Error in character P-format input for a GET FILE statement following a TRANSMIT condition. 627 A graphic or mixed character string encountered in a nongraphic environment. 628 A graphic or mixed character string encountered in a nongraphic environment on input. 629 A graphic or mixed character string encountered in a nongraphic environment on input after TRANSMIT was detected. 633 An invalid character detected in a X, BX, or GX string constant. 634 An invalid character detected in a X, BX, or GX string constant on input. 635 An invalid character detected in a X, BX, or GX string constant on input after TRANSMIT was detected. 636 A shift character detected in a graphic string. 639 During processing of a mixed character string, one of the following occurred:  A shift-in present in the SBCS portion.  A shift-out present in the graphic (double-byte) portion. (A shift-out cannot appear in either byte of a graphic character.)  A shift-in present in the second byte of a graphic character. 640 Conversion from picture contained an invalid character. 641 Conversion from picture contained an invalid character on input or output. 642 Conversion from picture contained an invalid character on input after TRANSMIT was detected. ═══ Condition Codes 1002 - 1040 ═══ 1002 GET or PUT STRING specifies data exceeding size of string. 1003 Further output prevented by TRANSMIT or KEY conditions previously raised for the data set. 1004 Attempt to use PAGE, LINE, or SKIP <= 0 for non-print file. 1005 In a DISPLAY(expression) REPLY (character-reference) statement, expression or character-reference is zero length. 1007 A REWRITE or a DELETE statement not preceded by a READ. 1008 Unrecognized field preceding the assignment symbol in a string specified in a GET STRING DATA statement. 1009 An input/output statement specifies an operation or an option which conflicts with the file attributes. 1011 Data management detected an input/output error but is unable to provide any information about its cause. 1012 A READ SET or READ INTO statement not preceded by a REWRITE. 1013 Previous input operation incomplete; REWRITE or DELETE statement specifies data which has been previously read in by a READ statement with an EVENT option, and no corresponding WAIT has been executed. 1014 Attempt to initiate further input/output operation when number of incomplete operations equals number specified by ENVIRONMENT option NCP(n) or by default. 1015 Event variable specified for an input/output operation when already in use. 1016 After UNDEFINEDFILE condition raised as a result of an unsuccessful attempt to implicitly open a file, the file was found unopened on normal return from the ON-unit. 1018 End of file or string encountered in data before end of data-list or (in edit-directed transmission) format list. 1019 Attempt to close file not opened in current process. 1020 Further input/output attempted before WAIT statement executed to ensure completion of previous READ. 1021 Attempt to access a record locked by another file in this process. 1022 Unable to extend VSAM data set. 1023 Exclusive file closed while records still locked in a subtask. 1024 Incorrect sequence of I/O operations on device-associated file. 1025 Insufficient virtual storage available for VSAM to complete request. 1026 No position established in VSAM data set. 1027 Record or VSAM control interval already held in exclusive control. 1028 Requested record lies on non-mounted volume. 1029 Attempt to reposition in VSAM data set failed. 1030 An error occurred during index upgrade on a index data set. 1031 Invalid sequential write attempted on index data set. 1040 A data set open for output used all available space. ═══ Condition Codes 1500 - 1522 ═══ 1500 Computational error; short floating point argument of SQRT built-in function is negative. 1501 Computational error; long floating point argument of SQRT built-in function is < 0. 1502 Computational error; extended floating point argument of SQRT built-in function is negative. 1503 Computational error in LOG, LOG2, or LOG10 built-in function; extended floating point argument is <= 0. 1504 Computational error in LOG, LOG2, or LOG10 built-in function; short floating point argument is <= 0. 1505 Computational error in LOG, LOG2 or LOG10 built-in function; long floating point argument is <= 0. 1506 Computational error in SIN, COS, SIND, or COSD built-in function; absolute value of short floating point argument exceeds (2**18)*pi (SIN and COS) or (2**18)*180 (SIND and COSD). 1507 Computational error in SIN, COS, SIND, or COSD built-in function; absolute value of long floating point argument exceeds (2**50)*pi (SIN and COS) or (2**50)*180 (SIND and COSD). 1508 Computational error; absolute value of short floating point argument of TAN or TAND built-in function exceeds, respectively, (2**18)*pi or (2**18)*180. 1509 Computational error; absolute value of long floating point argument of TAN or TAND built-in function exceeds, respectively, (2**50)*pi or (2**50)*180. 1510 Computational error; short floating point arguments of ATAN or ATAND built-in function both zero. 1511 Computational error; long floating point arguments of ATAN or ATAND built-in function both zero. 1514 Computational error; absolute value of short floating point argument of ATANH built-in function >= 1. 1515 Computational error; absolute value of long floating point argument of ATANH built-in function >= 1. 1516 Computational error; absolute value of extended floating point argument of ATANH built-in function >= 1. 1517 Computational error in SIN, COS, SIND, or COSD built-in function; absolute value of extended floating point argument exceeds (2**106)*pi (SIN and COS) or (2**106)*180 (SIND and COSD). 1518 Computational error; absolute value of short floating point argument of ASIN or ACOS built-in function exceeds 1. 1519 Computational error; absolute value of long floating point argument of ASIN or ACOS built-in function exceeds 1. 1520 Computational error; absolute value of extended floating point argument of ASIN or ACOS built-in function exceeds 1. 1521 Computational error; extended floating point arguments of ATAN or ATAND built-in function both zero. 1522 Computational error; absolute value of extended floating point argument of TAN or TAND built-in function >= (2**106)*pi or (2**106)*180, respectively. ═══ Condition Codes 1550 - 2050 ═══ 1550 Computational error; during exponentiation, real short floating-point base is zero and integer value exponent is not positive. 1551 Computational error; during exponentiation, real long floating-point base is zero and integer value exponent is not positive. 1552 Computational error; during exponentiation, real short floating-point base is zero and the floating-point or non-integer exponent is not positive. 1553 Computational error; during exponentiation, real long floating-point base is zero and the floating-point or non-integer exponent is not positive. 1554 Computational error; during exponentiation, complex short floating-point base is zero and integer value exponent is not positive. 1555 Computational error; during exponentiation, complex long floating-point base is zero and integer value exponent is not positive. 1556 Computational error; during exponentiation, complex short floating-point base is zero and floating-point or non-integer exponent is not positive and real. 1557 Computational error; during exponentiation, complex long floating- point base is zero and floating-point or non-integer exponent is not positive and real. 1558 Computational error; complex short floating-point argument of ATAN or ATANH built-in function has value, respectively, of ё1I or ё1. 1559 Computational error; complex long floating-point argument of ATAN or ATANH built-in function has value, respectively, of ё1I or ё1. 1560 Computational error; during exponentiation, real extended floating-point base is zero and integer value exponent is not positive. 1561 Computational error; during exponentiation, real extended floating-point base is zero and floating-point or non-integer exponent is not positive. 1562 Computational error; during exponentiation, complex extended floating-point base is zero and integer value exponent is not positive. 1563 Computational error; complex extended floating-point base is zero and floating-point or non-integral exponent is not positive. 1564 Computational error; complex extended floating-point argument of ATAN or ATANH built-in function has value, respectively, of ё1I or ё1. 2002 WAIT statement cannot be executed because of restricted system facility. 2050 WAIT statement would cause a permanent wait. ═══ Condition Codes 3000 - 3810 ═══ 3000 Field width, number of fractional digits, and number of significant digits (w, d, and s) specified for E-format item in edit-directed input/output statement do not allow transmission without loss of significant digits or sign. 3001 Value of W field in F-format specification too small. 3006 Picture description of target does not match non-character string source. 3009 A mixed character string contained a shift-out, then ended before a shift-in was found. 3010 During processing of a mixed character constant, one of the following occurred:  A shift-in present in the SBCS portion.  A shift-out present in the graphic (double-byte) portion. (A shift-out cannot appear in either byte of a graphic character.)  A shift-in present in the second byte of a graphic character. 3011 MPSTR built-in function contains an invalid character (or a null function string, or only blanks) in the expression that specifies processing rules. (Only V, v, S, s, and blank are valid characters). 3012 Retry for graphic conversion error not allowed. 3013 An assignment attempted to a graphic target with a length greater than 16,383 characters (32,766 bytes). 3014 A graphic or mixed string did not conform to the continuation rules. 3015 A X or GX constant has an invalid number of digits. 3016 Improper use of graphic data in Stream I/O. Graphic data can only be used as part of a variable name or string. 3017 Invalid graphic, mixed, or DBCS continuation when writing Stream I/O to a file containing fixed-length records. 3797 Attempt to convert to or from graphic data. 3798 ONCHAR or ONSOURCE pseudovariable used out of context. 3799 In an ON-unit entered as a result of the CONVERSION condition being raised by an invalid character in the string being converted, the character has not been corrected by use of the ONSOURCE or ONCHAR pseudovariables. 3800 Length of data aggregate exceeds system limit of 2**24 bytes. 3801 Array structure element not mapped. 3808 Aggregate cannot be mapped in COBOL or FORTRAN. 3809 A data aggregate exceeded the maximum length. 3810 An array has an extent that exceeds the allowable maximum. ═══ Condition Codes 3901 - 9999 ═══ 3901 Attempt to invoke task using a task variable that is already associated with an active task. 3904 Event variable referenced as argument to COMPLETION pseudovariable while already in use for a DISPLAY statement. 3906 Assignment to an event variable that is already active. 3907 Attempt to associate an event variable that is already associated with an active task. 3909 Attempt to create a subtask (using CALL statement) when insufficient main storage is available. 3910 Attempt to attach a task (using CALL statement) when number of active tasks was already at limit defined by ISASIZE parameter of EXEC statement. 3911 WAIT statement in ON-unit references an event variable already being waited for in task from which ON-unit was entered. 3912 Attempt to execute CALL with TASK option in block invoked while executing PUT FILE(SYSPRINT) statement. 3913 CALL statement with TASK option specifies an unknown entry point. 3914 Attempt to call FORTRAN or COBOL routines in two processes simultaneously. 3915 Attempt to call a task when the multitasking library was not selected in the link-edit step. 3920 An out-of-storage abend occurred. 4001 Attempt to assign data to an unallocated CONTROLLED variable during GET DATA. 8091 Operation exception. 8092 Privileged operation exception. 8093 EXECUTE exception. 8094 Protection exception. 8095 Addressing exception. 8096 Specification exception. 8097 Data exception. 9002 Attempt to execute GO TO statement referencing label in an inactive block. 9050 Program terminated by an abend. 9200 Program check in SORT/MERGE program. 9201 SORT not supported in CMS. 9250 Procedure to be fetched cannot be found. 9251 Permanent transmission error when fetching a procedure. 9252 FETCH/RELEASE not supported in CMS. 9253 Debugging tool unavailable. 9254 Attempt under CICS to FETCH a MAIN procedure from a PL/I routine. 9255 Attempt to release load module containing non-PL/I high-level language programs. 9999 A failure occurred during an invocation of an LE/370 service. ═══ 1.5. PL/I Variable Storage ═══ Description All variables require storage. The attributes specified for a variable describe the amount of storage required and how it is interpreted. Example In the following: DCL X FIXED BINARY(31,0) AUTOMATIC; A reference to X is a reference to a fullword that contains a value to be interpreted as fixed-point binary. X is allocated storage when its declaring block is activated and remains allocated until deactivated. Storage Control Tasks Consult the following table for a list of storage control tasks and the help that is available for them. ┌───────────────────────────────────────────────────────────────────────────┐ │ IF YOU WANT TO UNDERSTAND... YOU WILL WANT ADDITIONAL │ │ INFORMATION ABOUT... │ ├───────────────────────────────────────────────────────────────────────────┤ │ How and when a variable is o Storage allocation and classes │ │ allocated and freed │ │ o Static storage and attribute │ │ │ │ o Automatic storage and attribute │ │ │ │ o Controlled storage and attribute │ │ │ │ o Based storage │ │ │ │ o ALLOCATE statement │ │ │ │ o FREE statement │ ├───────────────────────────────────────────────────────────────────────────┤ │ Parameter storage o CONNECTED attribute │ ├───────────────────────────────────────────────────────────────────────────┤ │ How storage for one variable o DEFINED attribute │ │ is associated with another │ │ o POSITION attribute │ ├───────────────────────────────────────────────────────────────────────────┤ │ How to give a variable an initial o INITIAL attribute │ │ value when storage is allocated │ ├───────────────────────────────────────────────────────────────────────────┤ │ The establishment of a name as o VARIABLE attribute │ │ entry of file variable │ └───────────────────────────────────────────────────────────────────────────┘ ═══ Storage Allocation and Classes ═══ Description Storage allocation is the process of associating an area of storage with a variable so that the data item(s) represented by the variable can be recorded internally. When storage is associated with a variable, the variable is "allocated". 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. The degree of storage control and the manner in which storage is allocated for a variable are determined by the storage class of that variable. There are four storage classes: static, automatic, controlled, and based. You assign the storage class using its corresponding attribute in an explicit, implicit, or contextual declaration:  STATIC specifies that storage is allocated when the program is loaded. The storage is not freed until program execution is completed. For fetched procedures, the storage is not freed until the procedure is released.  AUTOMATIC 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. If the block is a procedure that is invoked recursively, the previously allocated storage is "pushed down" upon entry; the latest allocation of storage is "popped up" in a recursive procedure when each generation terminates.  CONTROLLED specifies that you use the ALLOCATE statement and FREE statement to control the allocation and freeing of storage. Multiple allocations of the same controlled variable in the same program, without intervening freeing, will stack generations of the variable.  BASED, like CONTROLLED, specifies that you control storage allocation and freeing. One difference is that multiple allocations are not stacked but are available at any time. Each allocation can be identified by the value of a pointer variable. Another difference is that based variables can be associated with an area of storage and identified by the value of an offset variable. Usage Rules Storage class attributes can be declared explicitly for element, array, and major structure variables. For array and major structure variables, the storage class declared for the variable applies to all of the elements in the array or structure. Storage class attributes cannot be specified for entry constants, file constants, members of structures, or defined data items. The scope of a variable depends on its storage class. The allocation of storage for variables is managed by PL/I. You do not specify where in storage the allocation is to be made. You can, however, specify where it is to be allocated relative to storage already allocated- for instance, by allocating based variables in an area variable. ═══ Static Storage and Attribute ═══ Description 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 STATIC attribute are allocated prior to running a program. They remain allocated until the program terminates (STATIC storage in fetched procedures is an exception). The program has no control on the allocation of static variables during execution. Example Static variables follow the normal scope rules for the validity of references to them. For example: A: PROC OPTIONS(MAIN); . . B: PROC; DECLARE X STATIC INTERNAL; . . 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. If static variables are initialized using the INITIAL attribute, the initial values must be specified as constants (arithmetic constants can be optionally signed) with the exception of locator variables. Any specification of lengths, sizes, or bounds must be integers. A STATIC pointer or offset variable can be initialized only by using the NULL built-in function or the SYSNULL built-in function. Syntax ────STATIC──── ═══ Automatic Storage and Attribute ═══ Description 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. AUTOMATIC is the default for internal variables. Whenever a block (procedure or begin) is active, storage is allocated for all variables declared automatic within that block. Whenever a block is inactive, no storage is allocated for the automatic variables in that block. Usage Rules  Only one allocation of a particular automatic variable can exist, except for those procedures that are called recursively or by more than one program.  Array bounds, string lengths, and area sizes for automatic variables can be specified as expressions. This means that you can allocate a specific amount of storage when you need it. Examples  In the following example: 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. The storage that is freed is available for allocation to other variables.  In the following example: A:PROC; DECLARE N FIXED BIN; . . B:PROC; DECLARE STR CHAR(N); The character string STR has a length defined by the value of the variable N that existed when procedure B was invoked. If the declare statements are located in the same procedure, PL/I requires that the variable N be initialized either to a constant or to an initialized static variable.  In the following example: DCL N FIXED BIN (15) INIT(10), M FIXED BIN (15) INIT(N), STR1 CHAR(N), STR2 CHAR(M); The length allocated is correct for STR1, but not for STR2. PL/I does not resolve this type of declaration dependency. Syntax ────AUTOMATIC──── Abbreviation: AUTO ═══ Controlled Storage and Attribute ═══ Description Variables declared as CONTROLLED are allocated only when you specify them in an ALLOCATE statement for controlled variables.. A controlled variable remains allocated until a FREE statement for controlled variables that names the variable is encountered or until the end of the program. Effectively, controlled variables are independent of the program block structure, but not completely. The scope of a controlled variable, when it is declared internal, is the block in which it is declared and any contained blocks. Any reference to a controlled variable that is not allocated produces undefined results. Generally, controlled variables are useful when a program requires large data aggregates with adjustable extents. Examples  In the following example: A:PROC; DCL X CONTROLLED; CALL B; . . B:PROC; ALLOCATE X; . . END B; END A; The variable X can be validly referred to within procedure B and that part of procedure A that follows execution of the CALL statement.  In the following example: DCL A(M,N) CTL; GET LIST(M,N); ALLOCATE A; GET LIST(A); . . FREE A; These statements allocate the exact storage required depending on the input data and free the storage when no longer required. This method is more efficient than the alternative of setting up a begin block, because block activation and termination are not required. Related Information  Built-in functions for controlled variables  Controlled structures  Multiple generations of controlled variables Syntax ────CONTROLLED──── Abbreviation: CTL ═══ ALLOCATE Statement for Controlled Variables ═══ Description The ALLOCATE statement allocates storage for controlled variables, independent of procedure block boundaries. Initial values are assigned to a variable upon allocation if it has an INITIAL attribute in either the ALLOCATE statement or the DECLARE statement. Expressions in the INITIAL attribute are evaluated at the point of allocation, using the conditions enabled at the ALLOCATE statement, although the names are interpreted in the environment of the declaration. If an INITIAL attribute appears in both DECLARE and ALLOCATE statements, the INITIAL attribute in the ALLOCATE statement is used. If initialization involves reference to the variable being allocated, the reference is to the new generation of the variable. Any evaluations performed at the time the ALLOCATE statement is executed (for example, evaluation of expressions in an INITIAL attribute) must not be interdependent. Usage Rules  Both controlled and based variables can be allocated in the same statement by separating them with commas. Bounds for arrays, lengths of strings, and sizes of areas are fixed at the execution of an ALLOCATE statement: - If a bound, length, or size is explicitly specified in an ALLOCATE statement, it overrides that given in the DECLARE statement. - If 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. If no generation of the variable exists, the bound, length, or size is undefined and the program is in error. - Either the ALLOCATE statement or a DECLARE or DEFAULT statement must specify any necessary dimension, size, or length attributes for a variable. Any expression taken from a DECLARE or DEFAULT statement is evaluated at the point of allocation using the conditions enabled at the ALLOCATE statement. However, names in the expression refer to variables whose scope includes the DECLARE or DEFAULT statement. - If, in either an ALLOCATE or a DECLARE statement, the bounds, lengths, or sizes are specified by expressions that contain references to the variable being allocated, the expressions are evaluated using the value of the most recent generation of the variable. For example: DCL X(20) FIXED BIN CTL; ALLOCATE X; ALLOCATE X(X(1)); In the first allocation of X, the upper bound is specified by the DECLARE statement, that is, 20. In the second allocation, the upper bound is specified by the value of the first element of the first generation of X. Related Information  Asterisk notation  Multiple generations of controlled variables Syntax ┌──,────────────────────────────────────────────────┐  │ ───ALLOCATE────┬───────┬──controlled-variable─┬───────────────┬─┴─── └─level─┘ └─┤ attribute ├─┘ where attribute is: ├──┬─dimension─────────────────────────────────────────┬─────────────┤ ├─CHARACTER(length)─────────────────────────────────┤ ├─BIT(length)───────────────────────────────────────┤ ├─GRAPHIC(length)───────────────────────────────────┤ ├─AREA(size)────────────────────────────────────────┤ │ ┌─,─────┐ │ │  │ │ ├─INITIAL(───item──┴──)─────────────────────────────┤ └─INITIAL─CALL──entry-reference──┬─────────────────┬┘ │ ┌─,────────┐ │ │  │ │ └─(──argument─┴─)─┘ Abbreviation: ALLOC ═══ FREE Statement for Controlled Variables ═══ Description 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 is made available, and subsequent references refer to that allocation. Usage Rules  Both controlled and based variables can be freed in the same statement by separating them with commas.  If a controlled variable has no allocated storage at the time the FREE statement is executed, no action is taken. Related Information Implicit freeing Syntax ┌───────────,───────────┐  │ ────FREE───────controlled-variable──┴────;──── ═══ Multiple Generations of Controlled Variables ═══ Description ALLOCATE statements for controlled variables for which storage was previously allocated and not freed "pushes down" or stacks storage for the variables. 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 for controlled variables or at termination of the program in which the storage was allocated, storage is "popped up" or removed from the stack. This is similar to the process described for automatic variables in a recursive procedure. For controlled variables, however, the stacking and unstacking of variables occur at ALLOCATE statement and FREE statement rather than at block boundaries and are independent of procedure invocations. Related Information Asterisk Notation ═══ Asterisk Notation ═══ Description In an ALLOCATE statement, values are inherited from the most recent previous generation when dimensions, lengths, or sizes are indicated by asterisks. For arrays, the asterisk must be used for every dimension of the array, not just one of them. For example: 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. For example: DCL Y CHAR(*) CTL, N FIXED BIN; 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. ═══ Controlled Structures ═══ Description When a structure is controlled, any arrays, strings, or areas it contains can be adjustable. Example Consider the following use of a controlled structure: DCL 1 A CTL, 2 B(N,M), 2 C CHAR(L) VARYING; N = -10; M = 10; L = 5; ALLOC A; FREE A; When the structure is allocated, A.B has the extent -10 to +10 and A.C is a VARYING character string with maximum length 5. When the structure is freed, only the major structure name is given. All of a controlled structure must be freed or allocated. An attempt to obtain storage for part of a structure is an error. ═══ Built-In Functions for Controlled Variables ═══ ALLOCATION Built-In Function When the allocation and freeing of a variable depend on flow of control, you can determine if a variable is allocated. The ALLOCATION built-in function returns a fixed binary value of precision (31,0) indicating the number of generations that you can access for a given controlled variable. If the variable is not allocated, the function returns the value zero. Additional Built-in Functions Consult the following task chart for additional help with the built-in functions available for controlled variables. ┌────────────────────────────────────────────────────────────────┐ │ WHEN YOU WANT TO... USE THIS BUILT-IN │ │ FUNCTION... │ ├────────────────────────────────────────────────────────────────┤ │ Determine the extent of a specific o DIM │ │ dimension of an array │ ├────────────────────────────────────────────────────────────────┤ │ Determine the lower or upper bound of o LBOUND │ │ a specified dimension of an array o HBOUND │ ├────────────────────────────────────────────────────────────────┤ │ Determine the amount of storage o CURRENTSTORAGE │ │ required by a specific variable o STORAGE │ ├────────────────────────────────────────────────────────────────┤ │ Determine the current length of o LENGTH │ │ a string │ └────────────────────────────────────────────────────────────────┘ ═══ Based Storage and Attribute ═══ Description You use the based storage class to store, access, and manipulate one or more generations of one or more variables. A generation is an amount of storage for a variable and the attributes of the data it contains. Based storage is especially useful when you generate or manipulate data sets of varying sizes of computational data at run time. It can also be useful for easily and efficiently storing and accessing the generations as a data set. How you store the generations determines how you can locate the one you want. Your choices are:  Allow PL/I to assign storage for a variable wherever storage is available. You use a pointer variable to locate the generation of the variable you need.  Define an area variable for an amount of contiguous storage to contain all generations of all related based variables. In addition to using a pointer variable, you can use an offset variable to locate the generation of the variable you need relative to the start of the area. Related Information  BASED attribute  ALLOCATE statement for based variables  FREE statement for based variables  Area data and attribute  Locator variables (pointers and offsets)  REFER option (self-defining data) ═══ BASED Attribute ═══ Description You use the BASED attribute to declare a variable as having the based storage class. A declaration of a based variable is a description of the generation; that is, the amount of storage required and its attributes. (A based variable does not identify the location of a generation in main storage.) A locator value identifies the location of the generation. Any reference to the value of a based variable that is not allocated produces undefined results. Examples  For example: DCL X FIXED BIN BASED(P); This declares that references to X, unless explicitly qualified by some other locator-variable, use the variable P to locate the storage for X.  A BASED VARYING string must have a maximum length equal to the maximum length of any string upon which it is defined. For example: DECLARE A CHAR(50) VARYING BASED(Q), B CHAR(50) VARYING; Q=ADDR(B); Usage Rules  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 record by means of the LOCATE statement or READ (with SET option) statement.  If no locator-variable is given, one must be given on allocation.  While the scope of a based variable is internal, the locator-variable can be external.  A based structure can be declared to contain adjustable area-sizes, array-bounds, and string-length specifications by using the REFER option.  If the INITIAL attribute is specified for a based variable, the initial values are assigned only upon explicit allocation of the based variable with an ALLOCATE statement or LOCATE statement. Syntax ────BASED────┬─────────────────────────────┬──── └──(───locator-reference───)──┘ ═══ ALLOCATE Statement for Based Variables ═══ Description 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. When an area is not used, the allocation is in storage associated with the program that executes the ALLOCATE statement. The locator variable must be a pointer variable. The amount of storage allocated for a based variable depends on its attributes, and on its dimensions, length, or size specifications if these are applicable at the time of allocation. These attributes are determined from the declaration of the based variable. When reference is made to a based variable, the data and alignment attributes used are those declared for it, while the qualifying locator variable identifies only the location of data. Storage is allocated in an area when the IN option is specified or the SET option specifies an offset variable. These options can appear in any order. For allocations in areas:  If sufficient storage for the based variable does not exist within the area, the AREA condition is raised.  If the IN option is not used when using an offset variable, the declaration of the offset variable must specify the AREA attribute.  If the IN option is used and the declaration of the offset variable specifies the AREA attribute, the areas must be the same or one must contain the other. Usage Rules  The ALLOCATE statement for controlled variables can be used in the same statement as the ALLOCATE statement for based variables by separating them with commas.  Any reference to the value of a based variable that is not allocated produces undefined results. Related Information  Area data and attribute  FREE statement for based variables Syntax ┌──────────────────,─────────────────────┐  │ ────ALLOCATE──────based─variable───┬───────────────┬────┴───;─── │ │ └─┤ reference ├─┘ where reference is: ────┬──────────────────────┬──┬──────────────────────────┬─────── └──IN(area─reference)──┘ └──SET(locator─reference)──┘ Abbreviation: ALLOC ═══ FREE Statement for Based Variables ═══ Description The FREE statement frees the storage allocated for both based variables and controlled variables. The amount of storage freed depends upon the attributes of the based variable, including bounds and/or lengths at the time the storage is freed. The user is responsible for determining that this amount coincides with the amount allocated. If the variable has not been allocated, the results are unpredictable. Usage Rules  A FREE statement for based variables and a FREE statement for controlled variables can be used in the same statement by separating them with commas.  A based variable can be used to free storage only if that storage has been allocated for a based variable having identical data attributes.  A FREE statement cannot be used to free a locate-mode I/O record. Related Information  Implicit freeing of based variables  ALLOCATE statement for based variables Syntax ┌────,─────┐  │ ────FREE──────┤option├─┴────;──────────────────── where option is: ────┬────────────────────────┬────based-variable─── └──locator-qualifier ─> ─┘ ─────┬────────────────────────────┬──────────────── └──IN──(──area-reference──)──┘ Note: A particular generation of a based variable is freed by specifying a locator qualifier in the statement. If the based variable is not explicitly locator-qualified, the locator variable declared in the BASED attribute is used to identify the generation of data to be freed. If no locator has been declared, the statement is in error. ═══ Area Data and Attribute ═══ Description Area variables describe contiguous blocks of storage that are reserved for the allocation of based variables. 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. Consequently, allocated based variables can be scattered widely throughout main storage. This is not significant for internal operations because items are readily accessed using the pointers. However, if these allocations are transmitted to a data set, the items have to be collected together. Items allocated within an area variable are already collected and can be transmitted or assigned as a unit while still retaining their separate identities. 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. An area can be assigned or transmitted complete with its contained allocations; thus, a set of based allocations can be treated as one unit for assignment and input/output while each allocation retains its individual identity. The size of an area is adjustable in a similar way as a string length or an array bound. It can be specified by an expression, an asterisk (for a controlled area or parameter), or by a REFER option (for self-defining data). The size for areas of static storage class must be specified as an integer. In addition to the declared size, an extra 16 bytes of control information precedes the reserved size of an area. The 16 bytes contain such details as the amount of storage in use.. The amount of reserved storage that is actually in use is known as the extent of the area. When an area variable is allocated, it is empty, that is, the area extent is zero. The maximum extent is represented by the area size. Based variables can be allocated and freed within an area at any time during execution, thus varying the extent of an area. When a based variable is freed, the storage it occupied is available for other allocations. A chain of available storage within an area is maintained; the head of the chain is held within the control information. Inevitably, as based variables with different storage requirements are allocated and freed, gaps will occur in the area when allocations do not fit available spaces. These gaps are included in the extent of the area. A variable is given the AREA attribute contextually by its appearance in the following places:  The OFFSET variable and attribute  The IN option of an ALLOCATE statement for based variables or FREE statement for based variables  Explicit declaration. Examples Examples of AREA declarations are: DECLARE AREA1 AREA(2000), AREA2 AREA; Usage Rule No operators, including comparison, can be applied to area variables. Related Information  Area assignment  Input/output of areas Syntax ────AREA──┬─────────────────────────────────────────┬──── ├──(*)────────────────────────────────────┤ └──(expression──┬───────────────────┬──)──┘ └──REFER(variable)──┘ ═══ Area Assignment ═══ Description 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. Area assignment can be used to expand a list of based variables beyond the bounds of its original area. If you attempt to allocate a based variable within an area that contains insufficient free storage to accommodate it, the AREA condition is raised. The ON-unit for this condition could be coded to change the value of a pointer qualifying the reference to the inadequate area, so that it points to a different area; on return from the ON-unit, the allocation is attempted again, within the new area. Alternatively, the ON-unit can write out the area and reset it to EMPTY. If an area containing no allocations is assigned to a target area, the effect is to free all allocations in the target area. Example In the following example: DECLARE X BASED (O(1)), O(2) OFFSET (A), (A,B) AREA; ALLOC X IN (A); X = 1; ALLOC X IN (A) SET (O(2)); O(2) -> X = 2; B = A; Using the POINTER storage control built-in function, the references POINTER (O(2),B) -> X and O(2) -> X represent the same value allocated in areas B and A respectively. ═══ Locator Variables (Pointers and Offsets) ═══ Description The mechanism for identifying a particular generation of a based variable is the locator variable. PL/I provides two types of locator variables to identify storage locations: pointer and offset. - A pointer variable can be used to qualify a reference to a variable with allocated storage in several different locations. - 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. Because an independent locator variable identifies the location of any generation, you can refer at any point in a program to any generation of a based variable by using an appropriate locator value. The association of a locator-variable with a based variable is not a special relationship. When a based variable is declared without a locator-variable, any reference to the based variable must always be explicitly locator-qualified. Usage Rules  A locator value can be assigned only to a locator variable. When an offset value is assigned to an offset variable, the area variables named in the OFFSET attributes are ignored.  A locator reference is a pointer or offset variable, which can be qualified or subscripted, or a function reference that returns a locator value. It can be used in the following ways: - As a locator qualifier, in association with a declaration or reference for a based variable - In a comparison operation, as in an IF statement (locator values can be compared whether equal or not equal) - As an argument in a procedure reference. - PL/I implicitly converts an offset to a pointer value. Thus, offset references can be used interchangeably with pointer references. Related Information  Locator qualification  Levels of locator qualification  Locator conversion  Pointer variable and attribute  Offset variable and attribute  Overlaying storage ═══ Locator Qualification ═══ Description Locator qualification is the association of one or more locator references with a based references 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". Reference to a based variable can be explicitly qualified as shown in the following syntax: Syntax ──locator-reference -> ──┬────────────────────────────────────┬─── │ ┌──────────────────────────────┐ │ │  │ │ └─────based-locator-reference -> ─┴──┘ ───based-reference──────────────────────────────────────────────── In the following example: P -> X X is a based variable and P is a locator variable. The reference means: that generation of X identified by the value of the locator P. X is said to be "explicitly locator-qualified". When more than one locator qualifier is used in a reference, they are evaluated from left to right. In these cases, only the first, or leftmost, can be a function reference. All other locator qualifiers must be based references. However, an entry variable can be based, and can represent a function that returns a locator value. 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. Examples Locator qualification ═══ Examples - Locator Qualification ═══ Consider the following examples of locator qualification.  Reference to a based variable can 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. In the following example: DCL X FIXED BIN BASED(P); ALLOCATE X; X = X + 1; The ALLOCATE statement sets a value in the pointer variable P so that the reference X applies to allocated storage. The references to X in the assignment statement are "implicitly locator-qualified" by P. References to X can also be explicitly locator-qualified as follows: P->X = P->X + 1; Q = P; Q->X = Q->X + 1; These assignment statements have the same effect as the previous example.  Because the locator declared with a based variable can also be based, a chain of locator qualifiers can be implied. In the following example: DECLARE (P(10),Q) POINTER, R POINTER BASED (Q), V BASED (P(3)), W BASED (R), Y BASED; ALLOCATE R,V,W; Given this declaration and allocation, the following are valid references: P(3) -> V V Q -> R -> W R -> W W The first two references are equivalent, as are the last three. Any reference to Y must include a qualifying locator variable. ═══ Levels of Locator Qualification ═══ Description A pointer that qualifies a based variable represents one level of locator qualification. An offset represents two levels because it is implicitly qualified within an area. The number of levels is not affected by a locator being subscripted and/or an element of a structure. The maximum number of levels of locator qualification allowed in a reference depends on the available storage, but it will never be less than ten. Example In the following example: DECLARE X BASED (P), P POINTER BASED (Q), Q OFFSET (A); The references: X, P -> X, and Q -> P -> X all represent three levels of locator qualification. ═══ Locator Conversion ═══ Description Locator data cannot be converted to any other data type, but pointer can be converted to offset, and vice versa. When an offset variable is used in a reference, its value is implicitly converted to a pointer value. The address value of the area variable designated in the OFFSET attribute is added to the offset value. Explicit conversion of an offset to a pointer value is accomplished using the POINTER built-in function. The OFFSET built-in function complements the POINTER built-in function and returns an offset value derived from a given pointer and area. The given pointer value must identify the location of a based variable in the given area. Usage Rules  In conversion of offset data to pointer, the offset value is added to the pointer value of the start of the area named in the OFFSET attribute. It is an error to attempt to convert an offset variable that is not associated with an area.  In any conversion of locator data, if the offset variable is a member of a structure, or if it appears in a do-specification or a multiple assignment statement, the area associated with that offset variable must be an unsubscripted, nondefined, element variable.  The area can be based, but if so, its qualifier must be an unsubscripted, nonbased, nondefined pointer; this pointer must not be used to explicitly qualify the area in declaration of the offset variable.  A pointer value is converted to offset by effectively deducting the pointer value for the start of the area from the pointer value to be converted. This conversion is limited to pointer values that relate to addresses within the area named in the OFFSET attribute. Except when assigning the NULL built-in function value, it is an error to attempt to convert to an offset variable that is not associated with an area. Example Consider the following: DCL P POINTER, O OFFSET(A),B AREA; P = POINTER(O,B); This statement assigns a pointer value to P, giving the location of a based variable, identified by offset O in area B. Because the area variable is different from that associated with the offset variable, you must ensure that the offset value is valid for the different area. It is valid, for example, if area A is assigned to area B prior to the invocation of the function. ═══ Pointer Variable and Attribute ═══ Description A pointer variable is a kind of locator variable. The value of a pointer variable that no longer identifies a generation of a based variable is undefined (for example, when a based variable has been freed). A pointer variable is declared contextually if it appears in one of the following places:  The BASED attribute  The SET option of an ALLOCATE, LOCATE, or READ statement. A pointer variable can also be declared explicitly. Related Information Setting pointer variables Syntax ────POINTER──── Abbreviation: PTR ═══ Setting Pointer Variables ═══ Description Before a reference is made to a pointer-qualified variable, the pointer must have a value. Pointer values are obtained from one of the following methods:  The NULL, SYSNULL, ADDR, ENTRYADDR, POINTERADD, POINTERVALUE or POINTER built-in functions  A READ statement with the SET option  An ALLOCATE statement or LOCATE statement  By assignment of the value of another locator variable, or a locator value returned by a user-defined function. Pointer values can be manipulated by the following:  An assignment that copies a pointer value to a pointer variable  A locator conversion that converts an offset value to a pointer value, or vice versa  Passing the pointer value as an argument in a procedure reference  Returning a pointer value from a function procedure. PL/I requires that all pointers declared in PL/I source be clean (that is, that the non-address bits in a fullword pointer are zero). Dirty pointers can result in unpredictable results, including program checks, incorrect pointer comparisons, and incorrect last argument flagging. In addition, dirty pointers can also cause you to mistake a pointer for the NULL pointer. ═══ Offset Variable and Attribute ═══ Description An offset variable is a kind of locator variable. The value of an offset variable specifies the location of a based variable within an area variable relative to the start of the area. Because the based variables are located relatively, if the area variable is assigned to a different part of main storage, the offset values remain valid. When an offset value is assigned to an offset variable, the area variable named in the OFFSET attribute is ignored because only the offset value is important. Usage Rules  Offset variables do not preclude the use of pointer variables within an area.  The association of an area variable with an offset variable is not a special relationship. An offset variable can be associated with any area variable by means of the POINTER built-in function. The advantage of making such an association in a declaration is that a reference to the offset variable implies reference to the associated area variable. If no area variable is specified, the offset can be used as a locator qualifier only through use of the POINTER built-in function. Examples Using offset variables Related Information Setting offset variables Syntax ────OFFSET────┬───────────────────────┬──── └──(──area-variable──)──┘ ═══ Examples- Offset Variables ═══  Consider the following example: DCL X BASED(O), Y BASED(P), A AREA, O OFFSET(A); ALLOCATE X; ALLOCATE Y IN(A); The storage class of area A and offset O is AUTOMATIC by default. The first ALLOCATE statement is equivalent to: ALLOCATE X IN(A) SET(O); The second ALLOCATE statement is equivalent to: ALLOCATE Y IN(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 IN(A); T=H; NEXT: ALLOCATE STR SET(T->P); T=T->P; . . GO TO NEXT; ═══ Overlaying Storage ═══ In 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) CHARACTER(5) BASED(P), B CHAR(5) BASED(Q), C(3,2) CHARACTER(5); P = ADDR(C); Q = ADDR(A(2,1)); Usage note: When a based variable is overlaid in this way (above), no new storage is allocated. The based variable uses the same storage as the variable on which it is overlaid (A(3,2) in the example). This overlay technique can be achieved by use of the DEFINED attribute, but an important difference is that the overlay is permanent. When based variables are overlaid, the association can be changed at any time in the program by assigning a new value to the locator variable. ═══ ALLOCATE Statement ═══ Use the ALLOCATE statement to allocate storage for variables, independent of procedure block boundaries. ALLOCATE can be used for both controlled and based variables, but the syntax and usage rules are not the same for both types of variables. Select one of the following for additional information about the ALLOCATE statement:  ALLOCATE statement for controlled variables  ALLOCATE statement for based variables ═══ REFER option (self-defining data) ═══ Description 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. When the structure is allocated (by either an ALLOCATE statement or a LOCATE statement), the value of an expression is assigned to a variable that defines a length, bound, or a size. For any other reference to the structure, the value of the defining variable is used. Use the REFER option in the declaration of a based structure to specify that, on allocation of the structure, the value of an expression is assigned to a variable in the structure and represents the length, bound, or the size of another variable in the structure. When the value of a refer object is changed, the next reference to the structure causes remapping. Examples Using the REFER option Usage Rules Any number of REFER options can be used in the declaration of a structure, provided that at least one of the following restrictions is satisfied:  All objects of REFER options are at logical level two, that is, not declared within a minor structure.  The structure is declared so that no padding between members of the structure can occur.  If the REFER option is used only once in a structure declaration, the two preceding restrictions can be ignored, provided that: - For a string length or area size, the option is applied to the last element of the structure. - For an array bound, the option is applied either to the last element of the structure or to a minor structure that contains the last element. The array bound must be the upper bound of the leading dimension. If the value of the object of a REFER option varies during the program, then:  The structure must not be freed until the object is restored to the value it had when allocated.  The structure must not be written out while the object has a value greater than the value it was allocated.  The structure can be written out when the object has a value equal to or less than the value it had when allocated. The number of elements, the string length, or area size actually written will be that indicated by the current value of the object. Syntax ────expression────REFER────(──variable──)──── ═══ Examples- Using the REFER Option ═══  Consider the following example: DECLARE 1 STR BASED(P), 2 X FIXED BINARY(31,0), 2 Y (L REFER (X)), L FIXED BINARY(31,0) INIT(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 of Y is set to the value of L (initialized to be 1000). As the REFER object, X also obtains this initialized value. For any other reference to Y, such as a READ statement that sets P, the bound value is taken from the current value of X.  If the value of the object of a REFER option varies during the program, then the structure can be written out when the object has a value equal to or less than the value it had when allocated. The number of elements, the string length, or area size actually written will be that indicated by the current value of the object. In the following example: DCL 1 REC BASED (P), 2 N FIXED BINARY(31), 2 A (M REFER(N)), M FIXED BINARY(31) INITIAL (100); ALLOCATE REC; N = 86; WRITE FILE (X) FROM (REC); 86 elements of REC are written. It 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). If N is assigned a value greater than 100, an error occurs when the WRITE statement is encountered.  When the value of a refer object is changed, the next reference to the structure causes remapping. In the following example: DCL 1 A BASED(P), 2 B FIXED BINARY(31), 2 C (I REFER(B)), 2 D, I FIXED BINARY(31) INIT(10); ALLOCATE A; B = 5; The next reference to A after the assignment to B remaps the structure to reduce the upper bound of C from 10 to 5, and to allocate to D storage immediately following the new last element of C. Although the structure is remapped, no data is reassigned-the contents of the part of storage originally occupied by the structure A are unchanged. If you do not consider remapping, errors can occur.  Consider the following example, in which there are two REFER options in the one structure: DCL 1 A BASED (P), 2 B FIXED BINARY (15,0), 2 C CHAR (I1 REFER (B)), 2 D FIXED BINARY (15,0), 2 E CHAR (I2 REFER (D)), (I1,I2) INIT (10); ALLOCATE A; B = 5; ═══ CONNECTED Attribute ═══ Description Elements, arrays, and major structures are always allocated in connected storage. References to unconnected storage arise only when you refer to cross sections of arrays.. For example, in the structure: 1 A(10), 2 B, 2 C; the interleaved arrays A.B and A.C are both in unconnected storage. Usage Rules  Certain restrictions apply to the use of unconnected storage. For example, a record variable (that is, a variable to or from which data is transmitted by a record-oriented transmission statement) must represent data in connected storage.  The CONNECTED attribute can be applied only to parameters. It specifies that the parameter is a reference to connected storage only and, hence, allows the parameter to be used as a target or source in record-oriented I/O or as a base in string overlay defining. When the parameter is connected and the CONNECTED attribute is used, the compiler may be able to generate significantly superior code when accessing aggregates.  CONNECTED can be specified for noncontrolled aggregate parameters and can be associated only with level-one names. Syntax ────CONNECTED───── Abbreviations: CONN ═══ DEFINED Attribute ═══ Description The DEFINED attribute specifies that the declared variable is associated with some or all of the storage associated with the designated base variable. There are three types of defining: simple, iSUB, and string overlay. If the POSITION attribute is specified, string overlay defining is in effect. In this case, the base variable must not contain iSUB references. If the subscripts specified in the base variable contain references to iSUB variables, iSUB defining is in effect. If neither iSUB nor the POSITION attribute is present, simple defining is in effect if the base variable and the defined variable match according the criteria below. Otherwise string overlay defining is in effect. Base and Defined Matching Criteria  A base variable and a defined variable match if the base variable, when passed as an argument, matches a parameter which has the attributes of the defined variable (except for the DEFINED attribute). For this purpose, the parameter is assumed to have all array bounds, string lengths, and area sizes specified by asterisks.  For simple and iSUB defining, a PICTURE attribute can only be matched by a PICTURE attribute that is identical except for repetition factors. For a reference to specify a valid base variable in string overlay defining, the reference must be in connected storage. You can override the matching rule completely, but this can cause unwarranted side effects within your program.  The values specified or derived for any array bounds, string lengths, and area sizes in a defined variable do not always have to match those of the base variable. However, the defined variable must be able to fit into the corresponding base array, string, or area. The determination of values and the interpretation of names occurs in the following sequence: 1. The array bounds, string lengths, and area sizes of a defined variable are evaluated on entry to the block that declares the variable. 2. A reference to a defined variable is a reference to the current generation of the base variable. When a defined variable is passed as an argument without creation of a dummy, the corresponding parameter refers to the generation of the base variable that is current when the argument is passed. This remains true even if the base variable is reallocated within the invoked procedure. 3. When a reference is made to the defined variable, the order of evaluation of the subscripts of the base and defined variable is undefined. If the defined variable has the BIT attribute, unpredictable results can occur under the following conditions:  If the base variable is not on a byte boundary  If the defined variable is not defined on the first position of the base variable and the defined variable is used as: - A parameter in a subroutine call (that is, referenced as internally stored data) - An argument in a PUT statement - An argument in a built-in function (library call) - If the base variable is controlled, and the defined variable is dimensioned and is declared with variable array bounds. Usage Rules  If the base variable is a data aggregate, a defined variable can comprise all the data or only a specified part of it.  The defined variable does not inherit any attributes from the base variable. The defined variable must be INTERNAL and a level-1 identifier. It can have the dimension attribute. It cannot be INITIAL, AUTOMATIC, BASED, CONTROLLED, STATIC, or a parameter.  In references to defined data, the STRINGRANGE, SUBSCRIPTRANGE, and STRINGSIZE conditions are raised for the array bounds and string lengths of the defined variable, not the base variable. Related Information  Simple defining  iSUB defining  String overlay defining  Unconnected storage  POSITION attribute Syntax ───DEFINED──┬──reference────────┬────────────────────────────────── └──(──reference──)──┘ Abbreviations: DEF for DEFINED ═══ Unconnected Storage ═══ Description The DEFINED attribute can overlay arrays. This allows array expressions to refer to array elements in unconnected storage (array elements that are not adjacent in storage). It is possible for an array expression involving consecutive elements to refer to unconnected storage in the two following cases:  Where an array is declared with iSUB defining. An array expression that refers to adjacent elements in an array declared with iSUB defining can be a reference to unconnected storage (that is, a reference to elements of an overlaid array that are not adjacent in storage).  Where a string array is defined on a string array that has elements of greater length. Consecutive elements in the defined array are separated by the difference between the lengths of the elements of the base and defined arrays, and are held in unconnected storage. An array overlay defined on another array is always assumed to be in unconnected storage. Related Information  CONNECTED attribute ═══ Simple Defining ═══ Description Simple defining allows you to refer to an element, array, or structure variable by another name. The defined and the base variables can comprise any data type, but they must match. The ALIGNED attribute and the UNALIGNED attribute must match for each element in the defined variable and the corresponding element in the base variable. The defined variable can have the dimension attribute. Usage Rules In simple defining of an array:  The base variable can be a cross-section of an array.  The number of dimensions specified for the defined variable must be equal to the number of dimensions specified for the base variable.  The range specified by a bound pair of the defined array must equal or be contained within the range specified by the corresponding bound pair of the base array. In simple defining of a string, the length of the defined string must be less than or equal to the length of the base string. In simple defining of an area, the size of the defined area must be equal to the size of the base area. A base variable can be, or can contain, a varying string, provided that the corresponding part of the defined variable is a varying string of the same maximum length. Examples DCL A(10,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. DCL B CHAR(10), Y CHAR(5) DEF B; Y is a character string that consists of the first 5 characters of B. DCL C AREA(500), Z AREA(500) DEF C; Z is an area defined on C. DCL 1 D UNALIGNED, 2 E, 2 F, 3 G CHAR(10) VAR, 3 H, 1 S UNALIGNED DEF D, 2 T, 2 U, 3 V CHAR(10) VAR, 3 W; S is a structure defined on D. For simple defining, the organization of the two structures must be identical. A reference to T is a reference to E, V to G, and so on. ═══ iSUB Defining ═══ Description By defining an iSUB, you can create a defined array that consists of designated elements from a base array. The defined and base arrays can be arrays of structures, can comprise any data types, and must have identical attributes (not including the dimension attribute). The defined variable must have the dimension attribute. In the declaration of the defined array, the base array must be subscripted. The subscript positions cannot be specified as asterisks. An iSUB variable is a reference, in the subscript list for the base array to the "ith" dimension of the defined array. At least one subscript in the base-array subscript-list must be an iSUB expression which, on evaluation, gives the required subscript in the base array. The value of "i" ranges from 1 to n, where n is the number of dimensions in the defined array. The number of subscripts for the base array must be equal to the number of dimensions for the base array. If a reference to a defined array does not specify a subscript expression, subscript evaluation occurs during the evaluation of the expression or assignment in which the reference occurs. The value of "i" is specified as an integer. Within an iSUB expression, and iSUB variable is treated as a REAL FIXED BINARY variable, with precision (31,0). A subscript in a reference to a defined variable is evaluated even if there is no corresponding iSUB in the base-variable subscript list. An iSUB-defined variable cannot appear in the explicit data-list of a data-directed transmission statement. Examples DCL A(10,10) X(10) DEFINED (A(1SUB, 1SUB)); X is a one-dimensional array that consists of a diagonal of A. DCL B(2,5) Y(10) DEFINED (A(ZSUB,1SUB)); Y is a two-dimensional array that consists of the elements of B with the bounds transposed. DCL A(10,10) , B(5,5) DEF A(1+1SUB/5,1+2SUB/5); In this case, there is a many-to-one mapping of certain elements of B to a single element of A. B(I,J) is defined on: A(1,1) for I<5 and J<5 A(1,2) for I<5 and J=5 A(2,1) for I=5 and J<5 A(2,2) for I=5 and J=5 Since all the elements B(I,J) are defined on the single element A(1,1) when I<5 and J<5, assignment of a value to one of these elements causes the same value to be assigned to all of them. ═══ String Overlay Defining ═══ Description String overlay defining allows you to associate a defined variable with the storage for a base variable. Both the defined and the base variable must be string or picture data. Neither the defined nor the base variable can have the ALIGNED attribute or the VARYING attribute. Both the defined and the based variables must belong to:  The bit class, consisting of: Fixed-length bit variables Aggregates of fixed-length bit variables  The character class, consisting of: Fixed-length character variables Character pictured and numeric pictured variables Aggregates of the two above  The graphic class, consisting of: Fixed-length graphic variables Aggregates of fixed-length graphic variables Examples DCL A CHAR(100), V(10,10) CHAR(1) DEF A; V is a two-dimensional array that consists of all of the elements in the character string A. DCL B(10) CHAR(1), W CHAR(10) DEF B; W is a character string that consists of all of the elements in the array B. ═══ POSITION Attribute ═══ Description The POSITION attribute, which can be used only with string-overlay defining, specifies the bit, character, or graphic within the base variable at which the defined variable is to begin. When the defined variable is a bit class aggregate:  The POSITION attribute can contain only an integer.  The base variable must not be subscripted. The base variable must refer to data in connected storage. Examples DCL C(10,10) BIT (1), X BIT(40) DEF C POS(20); X is a bit string that consists of 40 elements of C, starting at the 20th element. DCL E PIC'99V.999', Z1(6) CHAR(1) DEF (E), Z2 CHAR(3) DEF (E) POS(4), Z3(4) CHAR(1) DEF (E) POS(2); Z1 is a character string array that consists of all the elements of the decimal numeric picture E. Z2 is a character string that consists of the elements '999' of the picture E. Z3 is a character string array that consists of the elements '9.99' of the picture E. DCL A(20) CHAR(10), B(10) CHAR(5) DEF (A) POSITION(1); The first 50 characters of B consist of the first 50 characters of A. POSITION(1) must be explicitly specified. Otherwise, simple defining is used and gives different results. Related Information  Unconnected storage  Simple defining  iSUB defining  String overlay defining Syntax ───POSITION──(expression)───────────────────────────── ═══ INITIAL Attribute ═══ Description The INITIAL 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 initialized only by separate initialization of its elementary names, whether they are element or array variables. The INITIAL 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 initialization at allocation. The variable is initialized by assignment during the execution of the called routine (rather than by this routine being invoked as a function that returns a value to the point of invocation). Initial values specified for an array are assigned to successive elements of the array in row-major order (final subscript varying most rapidly). If too many initial values are specified, the excess values are ignored; if not enough are specified, the remainder of the array is not initialized. If the attributes of an item in the INITIAL attribute differ from those of the data item itself, conversion is performed, provided the attributes are compatible. Examples INITIAL attribute examples Usage Rules Using the INITIAL attribute Related Information  INITIAL on STATIC variables  INITIAL on AUTOMATIC variables Syntax ┌──,────────┐  │ ────INITIAL──(────┤item ├──┴─)────────────────────────────────── where item is: ────┬─────────*─────────────────┬─────────────────────────────── ├┤ initial─constant ├───────┤ ├──reference────────────────┤ ├──(expression)─────────────┤ └┤ iteration─specification ├┘ where iteration─specification is: ────(iteration─factor)───┤ iteration─item ├───────────────────── where iteration─item is: ────┬─────────*────────────┬──────────────────────────────────── ├┤ initial─constant ├──┤ ├──reference───────────┤ │ ┌─,──┐ │ │  │ │ └─(──item──)───────────┘ where initial-constant is: ────┬──┬─────┬──arithmetic─constant─────────────────────────┬─── │ ├─ + ─┤ │ │ └─ - ─┘ │ ├──bit─constant─────────────────────────────────────────┤ ├──character─constant───────────────────────────────────┤ ├──graphic─constant─────────────────────────────────────┤ ├──entry─constant───────────────────────────────────────┤ ├──file─constant────────────────────────────────────────┤ ├──label─constant───────────────────────────────────────┤ └──┬─────┬──real─constant──┬─ + ─┬──imaginary─constant──┘ ├─ + ─┤ └─ - ─┘ └─ - ─┘ OR ───INITIAL CALL──entry-reference──┬──────────────────┬────────── │ ┌─,────────┐ │ │  │ │ └─(───argument─┴─)─┘ Abbreviation: INIT ═══ Usage Rules- INITIAL Attribute ═══ Consider the following when using the INITIAL attribute:  The INITIAL attribute cannot be given for constants, defined data, parameters (except controlled parameters), or static entry variables.  The initialization of an array of strings can include both string repetition and iteration factors. Where only one of these is given, it is taken to be a string repetition factor unless the string constant is placed in parentheses. In the following examples: ((2)'A') is equivalent to ('AA') ((2)('A')) is equivalent to ('A','A') ((2)(1)'A') is equivalent to ('A','A')  An area variable is initialized with the value of the EMPTY built-in function, on allocation, after which any specified INITIAL is applied. An area can be initialized by assignment of another area, using the INITIAL attribute with or without the CALL option.  If the variable has the REFER option and the item involves a base element or a substructure of the current generation of the variable, the result of the INITIAL attribute is undefined. Therefore, in the following: DCL 1 A, 2 B, 2 C CHAR(N REFER(B)) INIT('AAB'), 2 D CHAR(5) INIT(C); ALLOCATE A; the result of initializing D is undefined. Note: If both the REFER option and the INITIAL attribute are used for the same member, initialization is done after the object of the REFER has been assigned its value. ═══ INITIAL on STATIC Variables ═══ Description 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 INITIAL attribute is assigned only once. However, static storage for fetched procedures is allocated and initialized each time the procedure is loaded. If static variables are initialized using the INITIAL attribute, the initial values must be specified as constants (arithmetic constants can be optionally signed) with the exception of locator variables. Any specification of lengths, sizes, or bounds must be integers. A STATIC pointer or offset variable can be initialized only by using the NULL built-in function or SYSNULL built-in function. Usage Restrictions  Static label variables cannot have the INTIAL attribute except when using the compiler to compile procedures containing STATIC LABEL arrays. In this case, improved performance can be obtained by specifying the INITIAL attribute.  If a STATIC EXTERNAL item is given the INITIAL attribute in more than one declaration, the value specified must be the same in every case. ═══ INITIAL Attribute Examples ═══ Description For based and controlled variables, which are allocated at the execution of ALLOCATE statement (also LOCATE statements for based variables), any specified initial value is assigned with each allocation. However, this initialization of controlled variables can be overridden in the ALLOCATE statement. Examples  In 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) INIT('JOHN DOE');  In the following example, when PI is allocated, it is initialized to the value 3.1416: DCL PI FIXED DEC(5,4) INIT(3.1416);  The following example specifies that A is to be initialized with the value of the expression B*C: DECLARE A INIT((B*C));  The following example results in each of the first 920 elements of A being set to 0; the next 80 elements consist of 20 repetitions of the sequence 5,5,5,9: DECLARE A (100,10) INITIAL ((920)0, (20) ((3)5,9));  In the following example, only the first, third, and fourth elements of A are initialized; the rest of the array is uninitialized. The array B is fully initialized, with the first 25 elements initialized to 0, the next 25 to 1, and the last 50 to 0. In the structure C, where the dimension (8) has been inherited by D and E, only the first element of D is initialized; all the elements of E are initialized. DECLARE A(15) CHARACTER(13) INITIAL ('JOHN DOE', *, 'RICHARD ROW', 'MARY SMITH'), B (10,10) DECIMAL FIXED(5) INIT((25)0,(25)1,(50)0), 1 C(8), 2 D INITIAL (0), 2 E INITIAL((8)0);  When an array of structures is declared with the LIKE attribute to obtain the same structuring as a structure whose elements have been initialized, only the first structure is initialized. In the following example: DECLARE 1 G, 2 H INITIAL(0), 2 I INITIAL(0), 1 J(8) LIKE G; Only J(1).H and J(1).I are initialized in the array of structures. ═══ VARIABLE Attribute ═══ Description The VARIABLE attribute can be specified only with the ENTRY or the FILE attributes. It establishes the name as an entry-variable or as a file-variable. The VARIABLE attribute is implied if the name is an element of an array or structure, or if any of the following attributes are specified:  ALIGNED/UNALIGNED attribute  DEFINED attribute  INITIAL attribute  Parameter attribute  Storage class attribute Syntax ──────VARIABLE──────────────────── ═══ 1.6. PL/I Built-In Functions, Subroutines, and Pseudovariables ═══ Description Built-ins are frequently used for tedious programming tasks that are part of the PL/I language library. Using them lets you write less code more quickly with less errors. The built-in functions, subroutines, and pseudovariables are listed in alphabetic order under their appropriate classes in the help (see "Classes of Built-Ins" below). Abbreviations  The abbreviations for built-in functions and pseudovariables have separate declarations (explicit or contextual) and name scopes.  Example- using built-in abbreviations Individual Built-In Descriptions In general, each built-in description has the following:  A description of the value returned, or for a pseudovariable, the value set  A description of any arguments  The syntax of the reference (the leading keyword CALL and trailing semicolon are omitted in the case of subroutines)  Any other qualifications on the use of the built-in. Arguments, which can be expressions, are evaluated and converted to a data type suitable for the built-in subroutine according to the rules for data conversion. Classes of Built-Ins To aid in their description, built-ins are grouped into the following classes. Select a class for a list of the individual built-ins in that class:  Arithmetic  Array-handling  Condition-handling  Event  Input/Output  Mathematical  Miscellaneous  Preprocessor  Storage control  String-handling  Built-In pseudovariables  Built-In subroutines Examples Declaring built-in names Related Information Arguments for built-ins Syntax The syntax for invoking a built-in function or pseudovariable reference is: ────name──┬─────────────────────────┬───────────── └─(─┬────────────────┬─)──┘ │┌──,────────────┤ │ │ └────argument────┘ The syntax for calling a built-in subroutine is: ───CALL───name───┬────────────────────────┬──;──── └─(─┬───────────────┬─)──┘ │ ┌─,───────────┤ │  │ └───argument────┘ The syntax for declaring a built-in name is: ─────┬─DECLARE─┬───name───BUILTIN───;───────────── └─DCL─────┘ Specific syntax is provided in the description for each built-in. ═══ Arithmetic Built-In Functions ═══ The arithmetic built-in functions allow you to:  Control conversion of base, scale, mode, and precision both directly and during basic arithmetic operations.  Determine properties of arithmetic values. For example, the SIGN built-in function indicates the sign of an arithmetic value. Some of these functions derive the data type of their results from one or more arguments. When the data types of the arguments differ, they are converted. When a data attribute of the result cannot agree with that of the argument (for example, the FLOOR built-in function), the rules are given in the individual function descriptions which you can select below. The arithmetic built-in functions are:  ABS  ADD  BINARY  CEIL  COMPLEX  CONJG  DECIMAL  DIVIDE  FIXED  FLOAT  FLOOR  IMAG  MAX  MIN  MOD  MULTIPLY  PRECISION  REAL  ROUND  SIGN  TRUNC ═══ Array-Handling Built-In Functions ═══ The array-handling built-in functions operate on array arguments and return an element value. Any conversion of arguments required for these functions is noted in the individual function descriptions which you can select below. The array-handling built-in functions are:  ALL  ANY  DIM  HBOUND  LBOUND  POLY  PROD  SUM ═══ Condition-Handling Built-In Functions ═══ The condition-handling built-in functions allow you to investigate the causes of enabled conditions. 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 FINISH condition when raised as an implicit action. All other uses are "out of context". The condition-handling built-in functions are:  DATAFIELD  ONCHAR  ONCODE  ONCOUNT  ONFILE  ONKEY  ONLOC  ONSOURCE ═══ Event Built-In Functions ═══ The event built-in functions allow you to determine the current state of an event. They are:  COMPLETION  STATUS ═══ Input/Output Built-In Functions ═══ The input/output built-in functions allow you to determine the current state of a file. They are:  COUNT  LINENO  SAMEKEY ═══ Mathematical Built-In Functions ═══ Description The mathematical built-in functions provide the capability for a wide variety of mathematical operations. All of these functions operate on floating-point values to produce a floating-point result. Any argument that is not floating-point is converted. Accuracy of Results The accuracy of a result is influenced by two factors: 1. The accuracy of the argument- most arguments contain errors 2. The accuracy of the algorithm used in the operation An error in a given argument might have accumulated over several steps prior to the evaluation of a function. Even data fresh from input conversion can contain slight errors. The effect of argument error on the accuracy of a result depends solely on the nature of the mathematical function and not on the algorithm that computes the result. Available Functions ACOS LOG ASIN LOG2 ATAN LOG10 ATAND SIN ATANH SIND COS SINH COSD SQRT COSH TAN ERF TAND ERFC TANH EXP ═══ Miscellaneous Built-In Functions ═══ The miscellaneous built-in functions do not fit into any of the classes of built-ins. They are:  DATE  DATETIME  PLIRETV  TIME ═══ Preprocessor Built-In Functions ═══ A functions 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. They are:  COMPILETIME  COUNTER  INDEX  LENGTH  PARMSET  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 statement or a %ACTIVATE statement. In preprocessor statement, the preprocessor built-in function names are always active as built-in functions unless they are declared with some other meaning. If a preprocessor built-in function name is used as the name of a user-defined preprocessor procedure, references to the name are references to the procedure, not to the built-in function. In such cases, the identifiers must be declared with the BUILTIN attribute when the built-in function is to be used within a preprocessor procedure. The preprocessor built-in functions COUNTER and COMPILETIME do not require arguments and must not be given a null argument list. ═══ String-Handling Built-In Functions ═══ The string-handling built-in functions simplify the processing of bit, character, and DBCS strings. The character-string and bit-string arguments can be represented by an arithmetic expression that will be converted to string either according to data conversion rules or according to the rules given in the individual function descriptions. The string-handling built-in functions are:  BIT  BOOL  CHAR  GRAPHIC  HIGH  INDEX  LENGTH  LOW  MPSTR  REPEAT  STRING  SUBSTR  TRANSLATE  UNSPEC  VERIFY Note: The functions REPEAT, TRANSLATE, and VERIFY do not support GRAPHIC data. ═══ Storage Control Built-In Functions ═══ 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  to obtain the number of generations of a controlled variable. The storage control built-in functions are:  ADDR  ALLOCATION  BINARYVALUE  CURRENTSTORAGE  EMPTY  ENTRYADDR  NULL  OFFSET  POINTER  POINTERADD  POINTERVALUE  STORAGE  SYSNULL ═══ Built-In Subroutines ═══ Built-in subroutines have entry names that are defined at compile time and are invoked by a CALL statement. The entry names are known as 'built-in names' and can be explicitly or contextually declared to have the BUILTIN attribute. You can use built-in subroutines to provide ready-made programming tasks. Their built-in names can be explicitly declared with the BUILTIN attribute. The PL/I built-in subroutines are the following:  PLICANC  PLICKPT  PLIDUMP  PLIREST  PLIRETC  PLISRTA  PLISRTB  PLISRTC  PLISRTD  PLITEST Syntax ────CALL-name──┬──────────────────────────────┬───;───── └──(──┬──────────────────┬──)──┘ │ ┌─────,──────┐ │ │  │ │ └─────argument──┴──┘ ═══ Built-In Pseudovariables ═══ Description Pseudovariables represent receiving fields. Except when noted in the description, the pseudovariable:  Can appear on the left of the assignment symbol in an assignment or a do-specification  Can appear in a data list of a GET statement or in the STRING option of a PUT statement  Can appear as the string name in a KEYTO or REPLY option. Pseudovariables cannot be nested. Example Because pseudovariables cannot be nested, the following is invalid: UNSPEC(SUBSTR(A,1,2)) = '00'B; Pseudovariables Available  COMPLEX  COMPLETION  ENTRYADDR  IMAG  ONCHAR  ONSOURCE  REAL  STATUS  STRING  SUBSTR  UNSPEC ═══ Examples- Declaring Built-In Names ═══ Consider the following declarations of built-in names. Descriptions follow the examples.  EXAMPLE 1 1 A: PROCEDURE; DECLARE SQRT FLOAT BINARY; 2 X = SQRT; 3 B: BEGIN; DECLARE SQRT BUILTIN; Z = SQRT(P); END B; END A;  EXAMPLE 2 A: PROCEDURE; 1 SQRT: PROC(PARAM) RETURNS(FIXED(6,2)); DECLARE PARAM FIXED (12); END SQRT; 2 X = SQRT(Y); 3 B: BEGIN; DECLARE SQRT BUILTIN; Z = SQRT (P); END B; END A; The following descriptions apply to both of the above examples: 1 SQRT is a programmer-defined name. 2 The assignment to the variable X is a reference to the programmer-defined name SQRT. 3 SQRT is declared with the BUILTIN attribute so that any reference to SQRT within B is recognized as a reference to the built-in function and not to the programmer-defined name SQRT declared in 1. In Example 2, if the procedure SQRT were an external procedure, procedure A would need to declare SQRT explicitly as an entry name, and to specify the attributes of the values passed to and returned from this programmer-written function procedure. The declaration for Example 2 would be: DCL SQRT ENTRY (FIXED (12)) RETURNS (FIXED(6,2)); ═══ Arguments for Built-Ins ═══ Description Arguments, which can be expressions, are evaluated and converted to a data type suitable for the built-in function or pseudovariable according to the rules for data conversion. Null and Optional Arguments Some built-in functions and pseudovariables do not require arguments. You must either explicitly declare these with the BUILTIN attribute or contextually declare them by including a null argument list in the reference- for example, ONCHAR(). Otherwise, the name cannot be recognized by the compiler as a built-in function or pseudovariable name. The built-in functions or pseudovariables that have no arguments or have a single optional argument are: DATAFIELD ONCODE ONSOURCE DATE ONCOUNT PLIRETV DATETIME ONFILE STATUS EMPTY ONKEY SYSYNULL NULL ONLOC TIME ONCHAR Aggregate Arguments All built-in functions and pseudovariables that can have arguments can have array arguments (if more than one is an array, the bounds must be identical). ADDR, ALLOCATION, CURRENTSTORAGE, STORAGE, STRING, and the array-handling functions return an element value. All other functions return an array of values. Specifying an array argument is equivalent to placing the function reference or pseudovariable in a do-group where one or more arguments is a subscripted array reference that is modified by the control variable. The built-in functions and pseudovariables that can accept structure arguments are: ADDR STORAGE ALLOCATION STRING CURRENTSTORAGE Example Specifying aggregate arguments ═══ COMPLETION Event Built-In Function ═══ COMPLETION returns a bit string of length 1, specifying the completion value of x; the event can be active or inactive. If the completion value of event is incomplete, '0'B is returned; if complete, '1'B is returned. Abbreviation: CPLN Syntax ───COMPLETION(x)────────────────────────── x is an event reference. ═══ STATUS Event Built-In Function ═══ STATUS returns a FIXED BINARY (15,0) value specifying the status value of an event-reference x. If the event-variable is normal, zero is returned; if abnormal, nonzero is returned. Syntax ───STATUS(x)──── x is an event-reference. ═══ COMPILETIME Preprocessor Built-In Function ═══ COMPILETIME returns a character string, length 18, in the format of DDbMMMbYYmHH.MM.SS. The character string contains the date and the time of the compilation. Syntax ───COMPILETIME──── The returned character string represents: b blank DD day of the month MMM month in the form JAN, FEB, MAR, etc. YY year HH hour MM minute SS second A leading zero in the day of the month field is replaced by a blank; no other leading zeros are suppressed. If not timing facility is available, the last 8 characters of the returned string are set to 00.00.00. The following example shows how to print the string returned by COMPILETIME when your program is executed: %DECLARE COMP_TIME CHAR; %COMP_TIME=''''||COMPLIETIME||''''; PUT EDIT (COMP_TIME) (A); ═══ COUNTER Preprocessor Built-In Function ═══ 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. If 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. Syntax ────COUNTER─────── ═══ INDEX Preprocessor Built-In Function ═══ INDEX returns a FIXED value indicating the starting position within the character expression x of a substring identical to character expression y. Syntax ───INDEX─(x,y)────── x character expression to be searched for y character expression to be searched for If y does not occur in x, of if either string is null, the value 0 is returned. If y occurs more than once in x, the starting position of the leftmost occurrence is returned. The arguments of INDEX are converted to character, if necessary. ═══ LENGTH Preprocessor Built-In Function ═══ LENGTH returns a FIXED value specifying the current length of a given character expression x. Syntax ───LENGTH(x)────── x character expression; x is converted to character, if necessary. ═══ PARMSET Preprocessor Built-In Function ═══ The PARMSET built-in function can be used only within a preprocessor procedure. It is used to determine whether a specified parameter is set on invocation of the procedure. 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, or was the null string in a function reference from input text. PARMSET can return '0'B, even if a matching argument does appear in the reference, but the reference is in another preprocessor procedure, as follows:  If the argument is not itself a parameter of the invoking procedure, PARMSET returns the value'1'B.  If the argument is a parameter of the invoking procedure, PARMSET returns the value for the specified parameter when the invoking procedure was itself invoked. Syntax ───PARMSET(x)─────── x must be a parameter of the preprocessor procedure. ═══ SUBSTR Preprocessor Built-In Function ═══ SUBSTR returns a substring of the character expression x. Syntax ───SUBSTR(x,y─┬────┬─)────── └─,z─┘ x character expression from which the substring is extracted. X converts to character, if necessary. y expression that can be converted to FIXED, specifying the starting position of the substring in x. z expression that can be converted to FIXED, specifying the length of the substring in x. If z is zero, a null string is returned. If z is omitted, the substring returned is position y in x to the end of x. If z is negative, or if the values of y and z are such that the substring does not lie entirely within x, the result is undefined. ═══ ABS Arithmetic Built-In Function ═══ Description ABS returns the absolute value of x. It is the positive value of x. The mode of the result is REAL. The result has the base, scale, and precision of x. Syntax ────ABS(x)──── x is an expression. ═══ ACOS Mathematical Built-In Function ═══ Description ACOS returns a real floating-point value that is an approximation of the inverse (arc) cosine in radians of x. The result is in the range: 0 <= ACOS(x) <= pi and has the base and precision of x. Syntax ────ACOS(x)──── x real expression, where ABS(x) <= 1. ═══ ADD Arithmetic Built-In Function ═══ Description ADD returns the sum of x and y with a precision specified by p and q. The base, scale, and mode of the result are determined by the rules for expression evaluation. ADD can be used for subtraction by prefixing a minus sign to the operand to be subtracted. Syntax ────ADD(x,y,p──┬────┬─)──── └─,q─┘ x and y expressions. p integer. It specifies the number of digits to be maintained throughout the operation. It must not exceed the implementation limit for the result base and scale. q optionally-signed integer specifying the scaling factor of the result. For a fixed-point result, if q is omitted, a scaling factor of zero is the default. For a floating-point result, q must be omitted. ═══ ADDR Storage Control Built-In Function ═══ Description ADDR returns the pointer value that identifies the generation of x. Usage Rules If x is a reference to:  An aggregate parameter, it must have the CONNECTED attribute  An aggregate, the returned value identifies the first element  A component or cross section of an aggregate, the returned value takes into account subscripting and structure qualification  A varying string, the returned value identifies the 2-byte prefix  An area, the returned value identifies the control information  A controlled variable that is not allocated in the current program, the null pointer value is returned  A based variable, the result is the value of the pointer explicitly qualifying x (if it appears), or associated with x in its declaration (if it exists), or a null pointer  A parameter, and a dummy argument has been created, the returned value identifies the dummy argument. Syntax ────ADDR(x)──── x is a reference. It refers to a variable of any data type, data organization, alignment, and storage class except:  A subscripted reference to a variable that is an unaligned fixed-length bit string  A reference to a DEFINED or BASED variable or simple parameter, which is an unaligned fixed-length bit string  A minor structure whose first base element is an unaligned fixed-length bit string (except where it is also the first element of the containing major structure)  A major structure that has the DEFINED attribute or is a parameter, and that has an unaligned fixed-length bit string as its first element  A reference that is not to connected storage. ═══ ALL Array-Handling Built-In Function ═══ Description 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. If x is not a bit string array, it is converted to bit string. Syntax ────ALL(x)──── x array reference. ═══ ALLOCATION Storage Control Built-In Function ═══ Description ALLOCATION returns a FIXED BINARY (31,0) value specifying the number of generations that can be accessed in the current program for x. If x is not allocated in the current program, the result is zero. Syntax ────ALLOCATION(x)──── Abbreviation: ALLOCN x level-one unsubscripted controlled variable. ═══ ANY Array-Handling Built-In Function ═══ Description 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. If x is not a bit string array, it is converted to bit string. X must not be iSUB-defined. Syntax ────ANY(x)──── x array reference. ═══ ASIN Mathematical Built-In Function ═══ Description ASIN returns a real floating-point value that is an approximation of the inverse (arc) sine in radians of x. The result is in the range: -pi/2 <= ASIN(x) <= pi/2 and has the base and precision of x. Syntax ────ASIN(x)──── x real expression, where ABS(x) <= 1. ═══ ATAN Mathematical Built-In Function ═══ Description ATAN returns a floating-point value that is an approximation of the inverse (arc) tangent in radians of x or of a ratio x/y. Syntax ────ATAN(x──┬────┬─)──── └─,y─┘ x and y expressions. If x alone is specified and is real, the result is real, has the base and precision of x, and is in the range: -pi/2 < ATAN(x) < pi/2 If x alone is specified and is complex, it must not +1I or -1I. The result is complex, has the base and the precision of x, and a value given by: -1I*ATANH(1I*x) If x and y are specified, each must be real. It is an error if x and y are both zero. The result for all other values of x and y is real, and has the precision of the longer argument, a base determined by the rules for expressions, and a value given by: ATAN(x/y) for y>0 pi/2 for y=0 and x>0 -pi/2 for y=0 and x<0 pi+ATAN(x/y) for y<0 and x>=0 -pi+ATAN(x/y) for y<0 and x<0 ═══ ATAND Mathematical Built-In Function ═══ Description ATAND returns a real floating-point value that is an approximation of the inverse (arc) tangent in degrees of x or of a ratio x/y. Syntax ────ATAND(x──┬────┬─)──── └─,y─┘ x and y expressions. If x alone is specified it must be real. The result has the base and precision of x, and is in the range: -90 ATANH Mathematical Built-In Function ═══ Description ATANH returns a floating-point value that has the base, mode, and precision of x, and is an approximation of the inverse (arc) hyperbolic tangent of x. The result has a value given by: LOG((1+x)/(1-x))/2 Syntax ────ATANH(x)──── x is an expression. ABS(x) < 1. ═══ BINARY Arithmetic Built-In Function ═══ Description BINARY returns the binary value of x, with a precision specified by p and q. The result has the mode and scale of x. If both p and q are omitted, the precision of the result is determined from the rules for base conversion. Syntax ────BINARY(x──┬───────────┬──)──── └─,p─┬────┬─┘ └─,q─┘ Abbreviation: BIN x expression. p integer. Specifies the number of digits to be maintained throughout the operation; it must not exceed the implementation limit. q optionally-signed integer. It specifies the scaling factor of the result. For a fixed-point result, if p is given and q is omitted, a scaling factor of zero is the default. For a floating-point result, q must be omitted. ═══ BINARYVALUE Storage Control Built-In Function ═══ Description BINARYVALUE returns a REAL FIXED BIN(31,0) value that is the converted value of its pointer expression, x. Syntax ────BINARYVALUE(x)──── Abbreviation: BINVALUE x expression. ═══ CURRENTSTORAGE Storage Control Built-In Function ═══ Description CURRENTSTORAGE returns a FIXED BINARY (31,0) value giving the implementation-defined storage, in bytes, required by x. Syntax ────CURRENTSTORAGE(x)─────── Abbreviation: CSTG x a variable of any data type, data organization, and storage class except:  A BASED, DEFINED, parameter, subscripted, or structure-base-element variable that is an unaligned fixed-length bit string.  A minor structure whose first or last base element is an unaligned fixed-length bit string (except where it is also the first or the last element of the containing major structure).  A major structure that has the BASED, DEFINED, or parameter attribute and which has an unaligned fixed-length bit string as its first or last element.  A variable not in connected storage. The value returned by CURRENTSTORAGE(x) is defined as the number of bytes that would be transmitted in the following circumstances: DECLARE F FILE RECORD OUTPUT ENVIRONMENT(SCALARVARYING); WRITE FILE(F) FROM(X); If x is a scalar-varying-length string, the returned value includes the length-prefix of the string and the number of currently-used bytes; it does not include any unused bytes in the string. If x is a scalar area, the returned value includes the area control bytes and the current extent of the area; it does not include any unused at the end of the area. If x is an aggregate containing areas or varying-length strings, the returned value includes the area control bytes, the maximum sizes of the areas, the length prefixes of the strings, and the number of bytes in the maximum lengths of the strings. There is one exception to this rule, however: If x is a structure whose last element is a nondimensional area, the returned value includes that area's control bytes and the current extent of that area; it does not include any unused bytes at the end of the area. Note: CURRENTSTORAGE cannot be used to obtain the storage requirements of a structure mapped according to the COBOL mapping algorithm. ═══ BIT String-Handling Built-In Function ═══ Description BIT returns the bit value of x, with a length specified by y. Syntax ────BIT(x──┬────┬─)──── └─,y─┘ x expression. y expression. If necessary, y is converted to a real fixed-point binary value (15,0). If y is omitted, the length is determined by the rules for type conversion. If y = 0, the result is the null bit string. y must not be negative. ═══ BOOL String-Handling Built-In Function ═══ Description BOOL returns a bit string that is the result of the Boolean operation z, on x and y. The length of the result is equal to that of the longer operand, x or y. Syntax ────BOOL(x,y,z)──── x and y expressions. x and y are converted to bit strings, if necessary. If x and y are of different lengths, the shorter is padded on the right with zeros to match the longer. z expression. z is converted to a bit string of length 4, if necessary. When a bit from x is matched with a bit from y, the corresponding bit of the result is specified by a selected bit of z, as follows: ┌──┬──┬───────────┐ │x │y │Result │ ├──┼──┼───────────┤ │0 │0 │bit 1 of z │ ├──┼──┼───────────┤ │0 │1 │bit 2 of z │ ├──┼──┼───────────┤ │1 │0 │bit 3 of z │ ├──┼──┼───────────┤ │1 │1 │bit 4 of z │ └──┴──┴───────────┘ ═══ CEIL Arithmetic Built-In Function ═══ Description CEIL determines the smallest integer value greater than or equal to x, and assigns this value to the result. The result has the mode, base, scale, and precision of x, except when x is fixed-point with precision (p,q). The precision of the result is then given by: (MIN(N,MAX(p-q+1,1)),0) where N is the maximum number of digits allowed. Syntax ────CEIL(x)───── x real expression. ═══ CHAR String-Handling Built-In Function ═══ Description CHAR returns the character value of x, with a length specified by y. It also supports conversion from graphic to character type. Examples Using the CHAR built-in function Syntax ───CHAR(x──┬────┬──)───────────── └─,y─┘ x expression. When x is non-GRAPHIC, CHAR returns x converted to character. When x is GRAPHIC, CHAR returns x converted to mixed character with the GRAPHIC data enclosed in shift-out/shift-in codes. The values of x are not checked. y expression. If necessary, y is converted to a real fixed-point binary value. If y is omitted, the length is determined by the rules for type conversion. y cannot be negative. If y=0, the result is the null character string. The following apply only when x is GRAPHIC:  If y = 1, the result is a character string of 1 blank.  If y = 2, the result is a character string of 2 blanks.  If y = 3, the result is a character string of 3 blanks.  If y is greater than the length needed to contain the character string, the result is padded with SBCS blanks.  If y is less than the length needed to contain the character string, the result is truncated. The integrity is preserved by truncating after a graphic, allowing space for and appending a shift-in code, and SBCS blank if necessary, to complete the length of the string. ═══ Examples- Using the CHAR Built-In Function ═══  EXAMPLE 1 Conversion from graphic to character, where "y" is long enough to contain the result: DCL X GRAPHIC(6); DCL A CHAR (14); A = CHAR(X); For X with value Intermediate Result A is assigned ---------------- ------------------- ------------- .A.B.C.D.E.F <.A.B.C.D.E.F> <.A.B.C.D.E.F>  EXAMPLE 2 Conversion from graphic to character, where "y" is too short: DCL X GRAPHIC(6); DCL A CHAR (11); A = CHAR(X); For X with values Intermediate Result A is assigned ----------------- ------------------- ------------- .A.B.C.D.E.F <.A.B.C.D.E.F> <.A.B.C.D> ═══ COMPLEX Arithmetic Built-In Function ═══ Description COMPLEX returns the complex value x + yI. The precision of the result, if fixed-point, is given by: (MIN(N,MAX(p1-q1,p2-q2)+MAX(q1,q2)),MAX(q1,q2)) where (p1,q1) and (p2,q2) are the precisions of x and y, respectively, and N is the maximum number of digits allowed. If the arguments, after any necessary conversions have been performed, are floating-point, the result has the precision of the longer argument. Syntax ────COMPLEX(x,y)──── Abbreviation: CPLX x and y real expressions. If x and y differ in base, the decimal argument is converted to binary. If they differ in scale, the fixed-point argument is converted to floating-point. The result has the common base and scale. ═══ COMPLEX Built-In Pseudovariable ═══ Description The COMPLEX pseudovariable assigns the real part of a complex value to x, and the real coefficient of the imaginary part to y. The attributes of x and y need not match, but if both are arrays they must have identical bounds. Only a complex value can be assigned to the pseudovariable. The COMPLEX pseudovariable cannot be used as the control variable in a do-specification. Syntax ────COMPLEX(x,y)──── Abbreviation: CPLX x and y real references. ═══ COMPLETION Built-In Pseudovariable ═══ Description The pseudovariable sets the completion value of x. No interrupt can occur during each assignment of the pseudovariable. For the compiler, the COMPLETION pseudovariable cannot be used as the control variable in a do-specification. Syntax ────COMPLETION(x)──────────────────── Abbreviation: CPLN x specifies the event reference. x must be inactive. ═══ ENTRYADDR Built-In Pseudovariable ═══ Description The ENTRYADDR pseudovariable initializes an entry variable, x, with the address of the entry to be invoked. Syntax ────ENTRYADDR(x)────────────────────── x is an entry reference. The ENTRYADDR pseudovariable cannot be used as the control variable in a DO loop. Note: If the address supplied to the ENTRYADDR variable is the address of an internal procedure, unpredictable results might occur. ═══ CONJG Arithmetic Built-In Function ═══ Description CONJG returns the conjugate of x; that is, the value of the expression with the sign of the imaginary part reversed. If x is real, it is converted to complex. The result has the base, scale, mode, and precision of x. Syntax ────CONJG(x)──── x expression. ═══ COS Mathematical Built-In Function ═══ Description COS returns a floating-point value that has the base, precision, and mode of x, and is an approximation of the cosine of x. Syntax ────COS(x)──── x expression whose value is in radians. If x = COMPLEX(a,b), the value of the result is given by: COMPLEX(COS(a)*COSH(b),-SIN(a)*SINH(b)) ═══ COSD Mathematical Built-In Function ═══ Description COSD returns a real floating-point value that has the base and precision of x, and is an approximation of the cosine of x. Syntax ────COSD(x)──── x real expression whose value is in degrees. ═══ COSH Mathematical Built-In Function ═══ Description COSH returns a floating-point value that has the base, precision, and mode of x, and is an approximation of the hyperbolic cosine of x. Syntax ────COSH(x)──── x expression. If x = COMPLEX(a,b), the value of the result is given by: COMPLEX(COSH(a)*COS(b),SINH(a)*SIN(b)) ═══ COUNT Input/Output Built-In Function ═══ Description COUNT returns a real binary fixed-point value (15,0) specifying the number of data items transmitted during the last GET or PUT operation on x. The count of transmitted items for a GET or PUT operation on x is initialized to zero before the first data item is transmitted, and is incremented by one after the transmission of each data item in the list. If x is not open in the current program, a value of zero is returned. If an ON-unit or procedure is entered during a GET or PUT operation, and within that ON-unit or procedure, a GET or PUT operation is executed for x, the value of COUNT is reset for the new operation. It is restored when the original GET or PUT is continued. Syntax ────COUNT(x)──── x file-reference. The file must be open and have the STREAM attribute. ═══ DATAFIELD Condition Handling Built-In Function ═══ Description DATAFIELD is in context in a NAME condition ON-unit (or any of its dynamic descendants). It returns a character string whose value is the contents of the field that raised the condition. It is also in context in an ON-unit (or any of its dynamic descendants) for an ERROR or FINISH condition raised as part of the implicit action for the NAME condition. If the string that raised the condition contains DBCS identifiers, GRAPHIC data, or mixed character data, DATAFIELD returns a MIXED character string adjusted, if necessary, so the DBCS portions are enclosed in shift codes. Note: If DATAFIELD is used out of context, a null string is returned. Syntax ────DATAFIELD───┬──────┬───── └──()──┘ ═══ DATE Miscellaneous Built-In Function ═══ Description DATE returns a character string, length 6, in the format of yymmdd. The time zone and accuracy are system dependent. Syntax ────DATE───┬──────┬──── └──()──┘ The returned character string yymmdd represents the following: yy represents the last two digits of the current year mm represents the current month dd represents the current day ═══ DATETIME Miscellaneous Built-In Function ═══ Description DATETIME returns a character string, length 17, in the format of yyyymmddhhmmsstt. Syntax ────DATETIME──┬────┬────── └─()─┘ yyyy is the current year mmm is the current month dd is the current day hh is the current hour mm is the current minute ss is the current second ═══ DECIMAL Arithmetic Built-In Function ═══ Description DECIMAL returns the decimal value of x, with a precision specified by p and q. The result has the mode and scale of x. If both p and q are omitted, the precision of the result is determined from the rules for base conversion. Syntax ────DECIMAL(x──┬───────────┬──)──── └─,p─┬────┬─┘ └─,q─┘ Abbreviation: DEC x expression. p integer specifying the number of digits to be maintained throughout the operation. It must not exceed the implementation limit. q optionally-signed integer specifying the scaling factor of the result. For a fixed-point result, if p is given and q is omitted, a scaling factor of zero is assumed. For a floating-point result, q must be omitted. ═══ DIM Array-Handling Built-In Function ═══ Description DIM returns a FIXED BINARY (31,0) value specifying the current extent of dimension y of x. If the extent of an array dimension exceeds the allowable number for the implementation, the DIM function returns an undefined value. Syntax ────DIM(x,y)──── x an array expression. x must not have less than y dimensions. Also, x must not be an array of structures. y expression specifying a particular dimension of x. If necessary, y is converted to a FIXED BINARY(31,0) value. Y must be greater than or equal to 1. ═══ DIVIDE Arithmetic Built-In Function ═══ Description DIVIDE returns the quotient of x/y with a precision specified by p and q. The base, scale, and mode of the result follow the rules for expression evaluation. Syntax ────DIVIDE(x,y,p──┬────┬─)──── └─,q─┘ x expression. y expression. If y=0, the ZERODIVIDE condition is raised. p integer specifying the number of digits to be maintained throughout the operation. q optionally-signed integer specifying the scaling factor of the result. For a fixed-point result, if q is omitted, a scaling factor of zero is the default. For a floating-point result, q must be omitted. ═══ EMPTY Storage Control Function ═══ Description EMPTY returns an area of zero extent. It can be used to free all allocations in an area. The value of this function is assigned to an area variable when the variable is allocated. Example Consider the following use of EMPTY: DECLARE A AREA, I BASED (P), J BASED (Q); ALLOCATE I IN(A), J IN (A); A = EMPTY(); /*EQUIVALENT TO: FREE I IN (A), J IN (A); */ Syntax ────EMPTY───┬──────┬──── └──()──┘ ═══ ENTRYADDR Storage Control Built-In Function ═══ Description 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. If x is a fetchable entry constant that has not been fetched or has been released, the NULL() value is returned. Syntax ────ENTRYADDR(x)──── x is an entry reference. ═══ ERF Mathematical Built-In Function ═══ Description ERF returns a real floating-point value that is an approximation of the error function of x. The result has the base and precision of x, and a value given by: (2/SQRT(pi)) times the integral over the range 0 to x of: EXP (-(t**2))dt Syntax ────ERF(x)──── x real expression. ═══ ERFC Mathematical Built-In Function ═══ Description ERFC returns a real floating-point value that is an approximation of the complement of the error function of x. The result has the base and precision of x, and a value given by: 1-ERF(x) Related Information ERF built-in function Syntax ────ERFC(x)──── x real expression. ═══ EXP Mathematical Built-In Function ═══ Description EXP returns a floating-point value that is an approximation of the base, e, of the natural logarithm system raised to the power x. The result has the base, mode, and precision of x. Syntax ────EXP(x)──── x expression. The result has the base, mode, and precision of x. If x = COMPLEX(a,b), the value of the result is given by: (e**a)*COMPLEX(COS(b),SIN(b)) ═══ FIXED Arithmetic Built-In Function ═══ Description FIXED returns the fixed-point value of x, with a precision specified by p and q. The result has the base and mode of x. Syntax ────FIXED(x──┬─────────┬──)──── └─,p─┬────┤ └─,q─┘ x expression. p integer. It specifies the total number of digits in the result; it must not exceed the implementation limit. q optionally-signed integer. It specifies the scaling factor of the result. If q is omitted, a scaling factor of zero is assumed. Note: If both p and q are omitted, the precision of the result is determined from the rules for base conversion. ═══ FLOAT Arithmetic Built-In Function ═══ Description FLOAT returns the approximate floating-point value of x, with a precision specified by p. The result has the base and mode of x. Syntax ────FLOAT(x──┬────┬─)──── └─,p─┘ x expression. p integer. It specifies the minimum number of digits in the result. It must not exceed the implementation limit. If p is omitted, the default value 21 is used for a binary result, or the value 6 is used for a decimal result. ═══ FLOOR Arithmetic Built-In Function ═══ Description FLOOR determines the largest integer value less than or equal to x, and assigns this value to the result. The mode, base, scale and precision of the result match the argument. Except when x is fixed-point with precision (p,q), the precision of the result is given by: (MIN(N,MAX(p-q+1,1)),0) where N is the maximum number of digits allowed. Syntax ─────FLOOR(x)──── x real expression. ═══ GRAPHIC String-Handling Built-In Function ═══ Description GRAPHIC can be used to explicitly convert character (or mixed character) data to GRAPHIC data. All other data first converts to character, and then to the GRAPHIC data type. GRAPHIC returns the graphic value of x, with a length in graphic characters specified by y. Characters convert to graphics, and shift codes, if any, are removed. The content of x is checked for validity during conversion, using the same rules as for checking graphic and mixed character constants. Examples Using the GRAPHIC built-in function Syntax ────GRAPHIC(x──┬────┬─)──── └─,y─┘ x expression. When x is GRAPHIC, it is subject to a length change, with applicable padding or truncation. The CONVERSION condition is raised if either half of the graphic character in the string contains a shift code. When x is non-GRAPHIC, it is converted to character, if necessary. SBCS characters are converted to equivalent DBCS characters. SBCS '40'X is converted to '4040'X, while other SBCS characters are converted by inserting '42'X in the first byte. Shift codes (if any) are discarded; DBCS data is copied. The CONVERSION condition is raised for any invalid use of shift codes, with the exception that the ERROR condition is raised for data ending with half of a graphic character or for data with a missing shift-in code. y expression. If necessary, y is converted to a real fixed-point binary value. If y is omitted, the length is determined by the rules for type conversion. y must not be negative. If y = 0, the result is the null graphic string. If y is greater than the length needed to contain the graphic string, the result is padded with graphic blanks. If y is less than the length needed to contain the graphic string, the result is truncated. ═══ Examples- Using the GRAPHIC Built-In Function ═══  EXAMPLE 1 Conversion from CHARACTER to GRAPHIC, where the target is long enough to contain the result: DCL X CHAR (11) VARYING; DCL A GRAPHIC (11); A = GRAPHIC(X,8); ┌───────────────────┬────────────────────────┬─────────────────────────┐ │ For X with values │ Intermediate Result │ A is assigned │ ├───────────────────┼────────────────────────┼─────────────────────────┤ │ ABCDEFGHIJ │ .A.B.C.D.E.G.H.I.J │ .A.B.C.D.E.F.G.H.b.b.b │ ├───────────────────┼────────────────────────┼─────────────────────────┤ │ 123 │ .1.2.3 │ .1.2.3.b.b.b.b.b.b.b.b │ ├───────────────────┼────────────────────────┼─────────────────────────┤ │ 123<.A.B.C> │ .1.2.3.A.B.C │ .1.2.3.A.B.C.b.b.b.b.b │ └───────────────────┴────────────────────────┴─────────────────────────┘ Where .b is a DBCS blank  EXAMPLE 2 Conversion from CHARACTER to GRAPHIC, where the target is too short to contain the result: DCL X CHAR (10) VARYING; DCL A GRAPHIC (8); A = GRAPHIC(X); ┌───────────────────┬────────────────────────┬─────────────────────────┐ │ For X with values │ Intermediate Result │ A is assigned │ ├───────────────────┼────────────────────────┼─────────────────────────┤ │ ABCDEFGHIJ │ .A.B.C.D.E.G.H.I.J │ .A.B.C.D.E.F.G.H │ └───────────────────┴────────────────────────┴─────────────────────────┘ ═══ HBOUND Array-Handling Built-In Function ═══ Description HBOUND returns a FIXED BINARY (31,0) value specifying the current upper bound of dimension y of x. Syntax ────HBOUND(x,y)──── x array expression. X must not have less than y dimensions, and must not be an array of structures. y expression. It specifies a particular dimension of x. If necessary, y is converted to a real fixed-point binary value. Y must be greater than or equal to 1. ═══ HIGH String-Handling Built-In Function ═══ Description HIGH returns a character string of length x, where each character is the highest character in the collating sequence (hexadecimal FF). Syntax ────HIGH(x)──── x expression. If necessary, x is converted to a positive real fixed-point binary value. If x=0, the result is the null character string. ═══ IMAG Arithmetic Built-In Function ═══ Description IMAG returns the coefficient of the imaginary part of x. The mode of the result is real and has the base, scale, and precision of x. Syntax ────IMAG(x)──── x expression. If x is real, it is converted to complex. ═══ IMAG Built-In Pseudovariable ═══ Description The IMAG pseudovariable assigns a real value or the real part of a complex value to the coefficient of the imaginary part of x. Syntax ────IMAG(x)───── x complex reference. ═══ INDEX String-Handling Built-In Function ═══ Description INDEX returns a real fixed-point binary value (15,0) indicating the starting position within x of a substring identical to y. You can also specify the location within x at which to begin processing. Syntax ────INDEX(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. If the first argument is GRAPHIC, the second must be GRAPHIC. If either argument is decimal, conversions are performed to produce character strings. Otherwise the arguments are bit and binary, or both binary, and conversions are performed to produce bit strings. ═══ LBOUND Array-Handling Built-In Function ═══ Description LBOUND returns a FIXED BINARY (31,0) value specifying the current lower bound of dimension y of x. Syntax ────LBOUND(x,y)──── x array expression. x must not have less than y dimensions, and must not be an array of structures. y expression. It specifies the particular dimension of x. If necessary, y is converted to a real fixed-point binary value. y must be greater than or equal to 1. ═══ POLY Array-Handling Built-In Function ═══ Description POLY returns a floating-point value that is an approximation of a polynomial formed from two one-dimensional array expressions x and y. The returned value has a mode and base given by the rules for expression evaluation, and the precision of the longest argument. Syntax ────POLY(x,y)──────────────────── x x is an array expression defined as x (m:n), where (m:n) represents the lower and the upper bounds. If x is a reference to a defined variable, x must not be iSUB-defined. y y is an array expression defined as y(a:b), where (a:b) represents the lower and the upper bounds; or, y is an element-expression. If y is a reference to a defined variable, y must not be iSUB-defined. Note: If the arguments are not floating-point, they are converted to floating-point. ═══ LENGTH String-Handling Built-In Function ═══ Description LENGTH returns a real fixed-point binary value specifying the current length of x. Example Consider the following declaration: DECLARE A GRAPHIC(3); The DECLARE statement defines 6 bytes of storage for A. Specifying LENGTH(A) returns the value 3. Syntax ────LENGTH(x)──── x string-expression. If x is binary, it is converted to bit string; otherwise, any other conversion required is to character string. ═══ LINENO Input/Output Built-In Function ═══ Description LINENO returns a real fixed-point binary value (15,0) specifying the current line number of x. The file must be open and have the PRINT attribute. Syntax ────LINENO(x)──── x file-reference. ═══ LOG Mathematical Built-In Function ═══ Description LOG returns a floating-point value that is an approximation of the natural logarithm (that is, the logarithm to the base e) of x. It has the base, mode, and precision of x. Syntax ────LOG(x)──── x expression. If x is real, it must be greater than zero. If x is complex, it must not be equal to 0 + 0I. The function is multiple-valued if x is complex; hence only the principal value can be returned. The principal value has the form: COMPLEX(a,b) where a is nonnegative, and b is with in the range: -pi LOG2 Mathematical Built-In Function ═══ Description LOG2 returns a real floating-point value that is an approximation of the binary logarithm (that is, the logarithm to the base 2) of x. It has the base and precision of x. Syntax ────LOG2(x)──── x real expression. It must be greater than zero. ═══ LOG10 Mathematical Built-In Function ═══ Description LOG10 returns a real floating-point value that is an approximation of the common logarithm (that is, the logarithm to the base 10) of x. It has the base and precision of x. Syntax ────LOG10(x)──── x real expression. It must be greater than zero. ═══ LOW String-Handling Built-In Function ═══ Description LOW returns a character string of length x, where each character is the lowest character in the collating sequence (hexadecimal 00). Syntax ────LOW(x)──── x expression. If necessary, x is converted to a positive real fixed-point binary value. If x=0, the result is the null character string. ═══ MAX Arithmetic Built-In Function ═══ Description MAX returns the largest value from a set of one or more expressions. All the arguments must be real. The result is real, with the common base and scale of the arguments. Precision of Results The precision of the results depends upon the precisions of the arguments.  If the arguments are fixed-point with precisions: (p1,q1),(p2,q2),...,(pn,qn) the precision of the result is given by: (MIN(N,MAX(p1-q1,p2-q2,...,pn-qn) + MAX(q1,q2,...,qn)),MAX(q1,q2,...,qn)) where N is the maximum number of digits allowed.  If the arguments are floating-point with precisions: p1,p2,p3,...pn then the precision of the result is given by: MAX(p1,p2,p3,...pn) Syntax ┌──,──┐  │ ────MAX(─────x──┴──)──── x expression. ═══ MIN Arithmetic Built-In Function ═══ Description MIN returns the smallest value from a set of one or more expressions. All the arguments must be real. The result is real with the common base and scale of the arguments. Precision of Results The precision of the results depends upon the precision of the arguments.  If the arguments are fixed-point with precisions: (p1,q1),(p2,q2),...,(pn,qn) the precision of the result is given by: (MIN(N,MAX(p1-q1,p2-q2,...,pn-qn) + MAX(q1,q2,...,qn)),MAX(q1,q2,...,qn)) where N is the maximum number of digits allowed.  If the arguments are floating-point with precisions: p1,p2,p3,...pn then the precision of the result is given by: MAX(p1,p2,p3,...pn) Syntax ┌───,──┐  │ ────MIN(──────x──┴──)──── x expression. ═══ MOD Arithmetic Built-In Function ═══ Description MOD returns the smallest nonnegative value, R, such that: (x - R)/y = n where n is an integer value. That is, R is the smallest nonnegative value that must be subtracted from x to make it divisible by y. The result, R, is real with the common base and scale of the arguments. Precision of Results  If the result is floating-point, the precision is the greater of those of x and y.  If the result is fixed-point, the precision is given by: (MIN(N,p2-q2+MAX(q1,q2)),MAX(q1,q2)) where (p1,q1) and (p2,q2) are the precisions of x and y, respectively, and N is the maximum number of digits allowed. Example If x and y are fixed-point with different scaling factors, R might be truncated on the left. This will cause the SIZE condition to be raised, as in the following example: MOD(10,8) /* is 2 */ MOD(-10,8) /* is 6 */ Syntax ────MOD(x,y)──── x real expression. y real expression. If y=0, the ZERODIVIDE condition is raised. ═══ MPSTR String-Handling Built-In Function ═══ Description MPSTR returns a mixed character string. The processing of the string is determined by the rules selected by the expression r, as described below. The length of the returned string is equal to the length of the expression x, or to the value specified by y. Syntax ────MPSTR(x,r──┬────┬─)──── └─,y─┘ x expression that yields the character string result. x cannot be GRAPHIC. x is converted to character if necessary. r expression that yields a character result; r specifies the rules to be used for processing the string. It is valid only in an EBCDIC environment and it is ignored in an ASCII environment. R cannot be GRAPHIC, and is converted to character if necessary. The characters that can be used in r and their usage rules are as follows: V or v Validates the mixed string x for balanced, unnested so/si pairs and returns a mixed string that has balanced pairs. V does not remove adjacent so/si pairs. If x contains unbalanced or nested so/si pairs, ERROR condition is raised. S or s Removes adjacent so/si pairs and any null DBCS strings and creates a new string. Returns a mixed string with balanced so/si pairs. If both V and S are specified, V takes precedence over S, regardless of the order in which they were specified. If S is specified without V, the string x is assumed to be a valid string. If the string is not valid, undefined results occur. y expression. If necessary, y is converted to a FIXED BINARY (15,0) value. If y is omitted, the length is determined by the rules for type conversion. y cannot be negative. If y = 0, the result is the null character string. If y is greater than the length needed to contain x, the result is padded with blanks. If y is less than the length needed to contain x, the result is truncated by:  Discarding excess characters from the right (if they are SBCS characters) or  Discarding as many DBCS characters (2-byte pairs) as needed. A shift-in is inserted to make the DBCS data valid in an EBCDIC environment. ═══ MULTIPLY Arithmetic Built-In Function ═══ Description MULTIPLY returns the product of x and y, with a precision specified by p and q. The base, scale, and mode of the result are determined by the rules for expression evaluation. Syntax ────MULTIPLY(x,y,p──┬────┬──)──── └─,q─┘ x and y expressions. p integer. Specifies the number of digits to be maintained throughout the operation. It must not exceed the implementation limit for the base and scale of the result. q optionally-signed integer. It specifies the scaling factor of the result. For a fixed-point result, if q is omitted, a scaling factor of zero is assumed. For a floating-point result, q must be omitted. ═══ NULL Storage Control Built-In Function ═══ Description 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. Syntax ────NULL───┬──────┬──── └──()──┘ ═══ OFFSET Storage Control Built-In Function ═══ Description OFFSET returns an offset value derived from a pointer reference x and relative to an area y. If x is the null pointer value, the null offset value is returned. Syntax ────OFFSET(x,y)──── x pointer reference. It must identify a generation of a based variable within the area y, or be the null pointer value. y area reference. Note: If x is an element reference, y must be an element variable. ═══ ONCHAR Condition-Handling Built-In Function ═══ Description ONCHAR returns a 1-character string containing the character that caused the CONVERSION condition to be raised. It is in context in an ON-unit (or any of its dynamic descendants) for the CONVERSION condition or for the ERROR or FINISH condition raised as the implicit action for the CONVERSION condition. Note: If the ONCHAR built-in function is used out of context, a blank is returned, unless ONCHAR has a value given to it by an assignment to the pseudovariable out of context. In this case, the character assigned to the pseudovariable is returned by the built-in function. Syntax ────ONCHAR───┬──────┬──── └──()──┘ ═══ ONCHAR Built-In Pseudovariable ═══ Description The ONCHAR pseudovariable sets the current value of the ONCHAR built-in function. The element value assigned to the pseudovariable is converted to a character value of length 1. The new character is used when the conversion is re-attempted. Note: If the pseudovariable is used out of context, and the next reference to the built-in function is also out of context, the character assigned to the pseudovariable is returned. The out-of-context assignment is otherwise ignored. Related Information ONCHAR built-in function Syntax ────ONCHAR───┬──────┬──── └──()──┘ ═══ ONCODE Condition-Handling Built-In Function ═══ Description The ONCODE built-in function provides a fixed-point binary value (15,0) that depends on the cause of the last condition. ONCODE can be used to distinguish between the various circumstances that raise a particular condition (for instance, the ERROR condition). ONCODE returns a real fixed-point binary value that is the condition code. It is in context in any ON-unit or its dynamic descendant. Note: If ONCODE is used out of context, zero is returned. Syntax ────ONCODE───┬──────┬──── └──()──┘ ═══ ONCOUNT Condition-Handling Built-In Function ═══ Description ONCOUNT returns a real fixed-point binary FIXED BINARY (15,0) value specifying the number of conditions that remain to be handled when an ON-unit is entered. It is in context in any ON-unit, or any dynamic descendant of an ON-unit. Note: If ONCOUNT is used out of context, zero is returned. Syntax ────ONCOUNT───┬──────┬──── └──()──┘ ═══ ONFILE Condition-Handling Built-In Function ═══ Description ONFILE returns a character string whose value is the name of the file for which an input/output or CONVERSION condition is raised. If the name is a DBCS name, it will be returned as a mixed character string. It is in context in the following circumstances:  In an ON-unit, or any of its dynamic descendants  For any input/output or CONVERSION condition  For the ERROR or FINISH condition raised as implicit action for an input/output or the CONVERSION condition. Syntax ────ONFILE───┬──────┬──── └──()──┘ ═══ ONKEY Condition Handling Built-In Function ═══ Description ONKEY returns a character string whose value is the key of the record that raised an input/output condition. ONKEY is always set for operations on a KEYED file, even if the statement that raised the condition has not specified the KEY, KEYTO, or KEYFROM options. For indexed files, if the key is GRAPHIC, the string is returned as a mixed character string. It is in context in the following circumstances:  An ON-unit, or any of its dynamic descendants  For any input/output condition, except ENDFILE  For the ERROR or FINISH condition raised as implicit action for an input/output condition. Note: If ONKEY is used out of context, a null string is returned. Results The results of specifying ONKEY in context are:  For any input/output condition (other than ENDFILE), or for the ERROR or FINISH condition raised as implicit action for these conditions, the result is the value of the recorded key from the I/O statement causing the error.  For relative data sets, the result is a character string representation of the relative record number. If the key was incorrectly specified, the result is the last 8 characters of the source key. If the source key is less than 8 characters, it is padded on the right with blanks to make it 8 characters. If the key was correctly specified, the character string consists of the relative record number in character form padded on the left with blanks, if necessary.  For a REWRITE statement that attempts to write an updated record on to an indexed data set when the key of the updated record differs from that of the input record, the result is the value of the embedded key of the input record. Syntax ────ONKEY───┬──────┬──── └──()──┘ ═══ ONLOC Condition-Handling Built-In Function ═══ Description 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. If the name is a DBCS name, it is returned as a mixed character string. It is in context in any ON-unit, or in any of its dynamic descendants. Note: If ONLOC is used out of context, a null string is returned. Syntax ────ONLOC───┬──────┬──── └──()──┘ ═══ ONSOURCE Condition Handling Built-In Function ═══ Description ONSOURCE returns a character string whose value is the contents of the field that was being processed when the CONVERSION condition was raised. It is in context in an ON-unit, or any of its dynamic descendants, for the CONVERSION condition or for the ERROR or FINISH condition raised as the implicit action for the CONVERSION condition. Note: If ONSOURCE is used out of context, a null string is returned. Syntax ────ONSOURCE───┬──────┬──── └──()──┘ ═══ ONSOURCE Built-In Pseudovariable ═══ Description The pseudovariable sets the current value of the ONSOURCE built-in function. The element value assigned to the pseudovariable 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 CONVERSION condition. The new string is used when the conversion is re-attempted. When conversion is re-attempted, the string assigned to the pseudovariable is processed as a single data item. For this reason, the error correction process should not assign a string containing more than one data item when the conversion occurs during the execution of a GET LIST or GET DATA statement. The presence of blanks or commas in the string could raise CONVERSION again. Syntax ────ONSOURCE───┬──────┬──── └──()──┘ ═══ PLICANC Built-In Subroutine ═══ Description This built-in subroutine allows you to cancel automatic restart activity. Syntax ─────PLICANC───────────────────────── ═══ PLICKPT Built-In Subroutine ═══ Description This built-in subroutine allows you to take a checkpoint for later restart. It also allows you to request, at suitable points in your program, that a checkpoint record is written. Syntax ┌──,─────────┐  │ ─────PLICKPT(────argument──┴──)─────────────── ═══ PLIDUMP Built-In Subroutine ═══ Description The PLIDUMP built-in subroutine allows you to obtain a formatted dump of selected parts of storage used by your program. Syntax ┌──────,─────┐  │ ────PLIDUMP(──────argument──┴──)──── ═══ PLIREST Built-In Subroutine ═══ Description This built-in subroutine allows you to restart program execution. Syntax ────PLIREST─────────────────────────────── ═══ PLIRETC Built-In Subroutine ═══ Description The PLIRETC built-in subroutine allows you to set a return code that can be examined by the program or (sub)system that invoked this PL/I program or by another PL/I procedure via the PLIRETV built-in function. Related Information PLIRETV built-in function Syntax ────PLIRETC(return-code)──── ═══ PLIRETV Miscellaneous Built-In Function ═══ Description PLIRETV returns a FIXED BINARY (31,0) value that is the PL/I return code. The value of the PL/I return code is any one of the following:  The most recent value specified by a CALL PLIRETC statement  The value returned by an Assembler routine whose entry-point is declared with the option OPTIONS(RETCODE)  Zero. Syntax ────PLIRETV───┬──────┬──── └──()──┘ ═══ PLISRTA Built-In Subroutine ═══ Description This built-in subroutine allows you to use DFSORT to sort an input file to produce a sorted output file. Syntax ┌─,──────────┐  │ ─────PLISRTA(─────argument───┴──)────────────────────── ═══ PLISRTB Built-In Subroutine ═══ Description This built-in subroutine allows you to use DFSORT to sort input records provided by an E15 PL/I exit procedure to produce a sorted output file. Syntax ┌─,─────────┐  │ ──────PLISRTB(────argument──┴──)───────────────── ═══ PLISRTC Built-In Subroutine ═══ Description This built-in subroutine allows you to use DFSORT to sort an input file to produce sorted records that are processed by an E35 PL/I exit routine. Syntax ┌─,─────────┐  │ ──────PLISRTC(────argument──┴─)───────────────── ═══ PLISRTD Built-In Subroutine ═══ Description This built-in subroutine allows you to use DFSORT to sort input records provided by an E15 PL/I exit procedure to produce sorted records that are processed by an E35 PL/I exit procedure. Syntax ┌─,─────────┐  │ ──────PLISRTD(────argument──┴─)─────────────── ═══ PLITEST Built-In Subroutine ═══ Description The PLITEST built-in subroutine allows you to invoke the interactive test facility. Syntax ─────PLITEST─┬────────────────┬────── └─(command-list)─┘ ═══ POINTER Storage Control Built-In Function ═══ Description POINTER returns a pointer value that identifies the generation specified by an offset reference x, in an area specified by y. If x is the null offset value, the null pointer value is returned. Generations of based variables in different areas are equivalent if, up to the allocation of the latest generation, the variables have been allocated and freed the same number of times as each other. Syntax ────POINTER(x,y)──── Abbreviation: PTR x offset reference. It can be the null offset value. If it is not, x must identify a generation of a based variable, but not necessarily in y. If it is not in y, the generation must be equivalent to a generation in y. y area reference. ═══ POINTERADD Storage Control Built-In Function ═══ Description POINTERADD returns a pointer value that is the sum of its arguments. POINTERADD can be used as a locator for a based variable. POINTERADD can also be used for subtraction by prefixing the operand to be subtracted with a minus sign. Syntax ────POINTERADD(x,y)──── Abbreviation: PTRADD x pointer expression. y expression. Y must have a computational type and should be declared REAL FIXED with a scale factor of 0. If not, it is converted to REAL FIXED BIN(31,0). ═══ POINTERVALUE Storage Control Built-In Function ═══ Description POINTERVALUE returns a pointer value that is the value of x converted from OFFSET. POINTERVALUE(x) can be used to initialize static pointer variables if x is a constant. Syntax ────POINTERVALUE(x)──── Abbreviation: PTRVALUE x expression. X must have a computational type and should be declared REAL FIXED with a scale factor of 0. If not, it is converted to REAL FIXED BIN(31,0). ═══ STORAGE Storage Control Built-In Function ═══ Description STORAGE returns a FIXED BINARY (31,0) value giving the implementation defined storage, in bytes, allocated to a variable x. Usage Rules  STORAGE cannot be used to obtain the storage requirements of a structure mapped according to the COBOL mapping algorithm.  x cannot be: - A BASED, DEFINED, parameter, subscripted, or structure-base element variable that is an unaligned fixed-length bit string. - A minor structure whose first or last base element is an unaligned fixed-length bit string (except where it is also the first or the last element of the containing major structure). - A major structure that has the BASED, DEFINED, or parameter attribute and which has an unaligned fixed-length bit string as its first or its last element. - A variable that is not in connected storage.  The value returned by STORAGE(x) is the maximum number of bytes that could be transmitted in the following circumstances: DECLARE F FILE RECORD INPUT ENVIRONMENT(SCALARVARYING) READ FILE(F) INTO(x);  If x is: - A varying length string, the returned value includes the length-prefix of the string and the number of bytes in the maximum length of the string. - An area, the returned value includes the area control bytes and the maximum size of the area. - An aggregate containing areas or varying-length strings, the returned value includes the area control bytes, the maximum sizes of the areas, length prefixes of the strings, and the number of bytes in the maximum lengths of the strings. Syntax ────STORAGE(x)────── Abbreviation: STG x a variable of any data type, data organization, alignment, and storage class, except for those listed above (see "Usage Rules"). ═══ PRECISION Arithmetic Built-In Function ═══ Description PRECISION returns the value of x, with a precision specified by p and q. The base, mode, and scale of the returned value are the same as that of x. Syntax ────PRECISION(x,p──┬────┬─)──── └─,q─┘ Abbreviation: PREC x expression. p integer. P specifies the number of digits that the value of the expression x is to have after conversion. It must not exceed the implementation limit for the base and scale. q optionally-signed integer. It specifies the scaling factor of the result. For a fixed-point result, if q is omitted, a scaling factor of zero is assumed. For a floating-point result, q must be omitted. ═══ PROD Array-Handling Built-In Function ═══ Description PROD returns the product of all the elements in x. The result has the precision of x, except that the result for fixed-point integer values and strings is fixed-point with precision (n,0), where n is the maximum number of digits allowed. The base and mode match the converted argument x. Syntax ────PROD(x)──── x array reference. If the elements of x are strings, they are converted to fixed-point integer values. If the elements of x are not fixed-point integer values or strings, they are converted to floating-point and the result is floating-point. ═══ REAL Arithmetic Built-In Function ═══ Description REAL returns the real part of x. The result has the base, scale, and precision of x. Syntax ────REAL(x)──── x expression. If x is real, it is converted to complex. ═══ REAL Built-In Pseudovariable ═══ Description The REAL pseudovariable assigns a real value or the real part of a complex value to the real part of x. Syntax ────REAL(x)──── x complex reference. ═══ STATUS Built-In Pseudovariable ═══ Description The pseudovariable sets the status value of an event-reference x. The variable can be active or inactive, and complete or incomplete. The value assigned to the pseudovariable is converted to FIXED BINARY (15,0), if necessary. No interrupt can occur during each assignment to the pseudovariable. Syntax ─────STATUS(x)──────────────────────────── x specifies an event-reference. ═══ REPEAT String-Handling Built-In Function ═══ Description REPEAT returns a bit or character string consisting of x concatenated to itself the number of times specified by y. That is, there will be (y+1) occurrences of x. If y is zero or negative, the string x is returned. REPEAT does not support GRAPHIC data. Syntax ────REPEAT(x,y)──── x bit- or character-expression to be repeated. If x is arithmetic and binary, it is converted to bit string If x is arithmetic and decimal, it is converted to character string. y expression. If necessary, y is converted to a real fixed-point binary value (15,0). ═══ ROUND Arithmetic Built-In Function ═══ Description ROUND is used to round the value of x at a digit specified by n. The result has the mode, base, and scale of x. The precision of a fixed-point result is given by: (MAX(1,MIN(p-q+1+n,N)),n) where (p,q) is the precision of x, and N is the maximum number of digits allowed. Thus, n specifies the scaling factor of the result. Example Consider the following example: DCL X FIXED DEC(5,4) INIT(6.6666); PUT (ROUND(X,2)); The value 6.67 is returned by ROUND. Syntax ────ROUND(x,y)──── x real expression. If x is negative, the absolute value is rounded and the sign is restored. y optionally-signed integer. It specifies the digit at which rounding is to occur. Y must conform to the limits of scaling-factors for FIXED data. If y is greater than 0, rounding occurs at the (y)th digit to the right of the point. If y is zero or negative, rounding occurs at the (1-y)th digit to the left of the point. The valid range of y is: 127is greater than or equal to y, and y is greater than or equal to -128. If x is floating-point, y must be specified but is ignored; the rightmost bit of the machine representation of the mantissa is set to 1, and the result has the precision of x. If x is negative, the absolute value is rounded and the sign is restored. ═══ SAMEKEY Input/Output Built-In Function ═══ Description SAMEKEY returns a bit string of length 1 indicating whether a record that has been accessed is followed by another with the same key. Upon successful completion of an input/output operation on file x, or immediately before the RECORD condition is raised, the value accessed by SAMEKEY is set to '1'B if the record processed is followed by another record with the same key, and set to '0'B if it is not. The value accessed by SAMEKEY is also set to '0'B if:  An input/output operation that raises a condition other than RECORD also causes file positioning to be changed or lost.  The file is not open.  The file is not associated with a VSAM path assessing a data set through an alternate index.  The record processed is not followed by another record with the same key. Syntax ────SAMEKEY(x)──── x file reference. The file must have the RECORD attribute. ═══ SIGN Arithmetic Built-In Function ═══ Description SIGN returns a FIXED BINARY (15,0) value that indicates whether x is positive, zero, or negative. The returned value is given by: ┌─────────────┬─────────────────┐ │ Value of x │ Value Returned │ ├─────────────┼─────────────────┤ │ x > 0 │ +1 │ ├─────────────┼─────────────────┤ │ x = 0 │ 0 │ ├─────────────┼─────────────────┤ │ X < 0 │ -1 │ └─────────────┴─────────────────┘ Syntax ────SIGN(x)──── x real expression. ═══ SIN Mathematical Built-In Function ═══ Description SIN returns a floating-point value that is an approximation of the sine of x. It has the base, mode, and precision of x. Syntax ────SIN(x)──── x expression whose value is in radians. If X = COMPLEX(a,b), the value of the result is given by : COMPLEX(SIN(a)*COSH(b),COS(a)*SINH(b)) ═══ SIND Mathematical Built-In Function ═══ Description SIND returns a real floating-point value that is an approximation of the sine of x. It has the base and precision of x. Syntax ────SIND(x)──── x real expression whose value is in degrees. ═══ SINH Mathematical Built-In Function ═══ Description SINH returns a floating-point value that represents an approximation of the hyperbolic sine of x. It has the base, mode, and precision of x. Syntax ────SINH(x)──── x expression whose value is in radians. If x = COMPLEX(a,b), the value of the result is given by: COMPLEX(SINH(a)*COS(b),COSH(a)*SIN(b)) ═══ SQRT Mathematical Built-In Function ═══ Description SQRT returns a floating-point value that is an approximation of the positive square root of x. It has the base, mode, and precision of x. Syntax ────SQRT(x)──── x expression. If x is real, it must not be less than zero. If x = COMPLEX(a,b), the value of the result is given by: If x is complex, the function is multiple-valued; hence, only the principal value can be returned. The principal value has the form COMPLEX(a,b). ═══ STRING Miscellaneous Built-In Function ═══ Description STRING returns an element bit or character string that is the concatenation of all the elements of x. Syntax ────STRING(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. If x is a structure that has padding caused by ALIGNED elements, the padding is not included in the result. If 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. ═══ STRING Built-In Pseudovariable ═══ Description The STRING pseudovariable assigns a bit or character expression, piece by piece, to x, until either all of the elements are filled or no piece of the assigned string remains. Any remaining strings in x are filled with blanks or zero bits, or, if varying-length, are given zero length. A varying-length string is filled to its maximum length, if possible. Restrictions The STRING pseudovariable must not be used in the data specification of a GET statement, in an INTO or KEYTO option of a READ statement, in the REPLY option of the DISPLAY statement, nor the KEYTO option of a WRITE statement. The pseudovariable cannot be used as the control variable in a do-specification. Syntax ────STRING(x)──── x aggregate or element reference. Each base element of x must be either all bit-string or all character-string. ═══ SUBSTR Built-In Pseudovariable ═══ Description The SUBSTR pseudovariable assigns a string value to a substring, 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. Syntax ────SUBSTR(x,y──┬────┬─)──── └─,z─┘ x string-reference. x must not be a numeric character. y expression. y specifies the starting position of the substring in x. It will be converted to a FIXED BINARY (15,0) value. z expression. z specifies the length of the substring in x. It will be converted to a FIXED BINARY (15,0) value. If z is zero, a null string is returned. If z is omitted, the substring returned is position y in x to the end of x. Note: y and z can be arrays only if x is an array. ═══ STRING String-Handling Built-In Function ═══ Description STRING returns an element bit or character string that is the concatenation of all of the elements of x. If x is a structure that has padding caused by ALIGNED elements, the padding is not included in the results. If 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. Syntax ────STRING(x)──────────────────────────────── x X is an aggregate or an element reference. If x is a reference to a defined variable, x must not be iSUB-defined. Each base element of x must be either all bit-string, or all character-string and/or numeric character, in any combination. ═══ SUBSTR String-Handling Built-In Function ═══ Description SUBSTR returns a substring, specified by y and z, of x. Syntax ────SUBSTR(x,y──┬────┬─)──── └─,z─┘ x string expression. It must not be a numeric character. y expression. y specifies the length of the substring in x. It can be converted to a real fixed-point binary value. z expression. Z specifies the length of the substring in x. It can be converted to a real fixed-point binary value. If z is zero, a null string is returned. If z is omitted, the substring returned is position y in x to the end of x. Note: The STRINGRANGE condition is raised if z is negative or if the values of y and z are such that the substring does not lie entirely within the current length of x. It is not raised when y=LENGTH(x)+1 and z=0. ═══ SUM Array-Handling Built-In Function ═══ Description SUM returns the sum of all the elements in x. The base, mode, and scale of the result match those of x. Syntax ────SUM(x)──── x array expression. If the elements of x are strings, they are converted to fixed-point integer values. If the elements of x are fixed-point, the precision of the result is (n,q), where n is the maximum number of digits allowed, and q is the scaling factor of x. If the elements of x are floating-point, the precision of the result matches x. x must not be iSUB-defined. ═══ SYSNULL Storage Control Built-In Function ═══ Description SYSNULL returns the system null pointer value. It can be used to initialize static pointer and offset variables. It also can be assigned or converted to offset variables (like NULL). SYSNULL is valid without the LANGLVL(SPROG) option. In the following example: BINVALUE(SYSNULL()) the returned value is zero. Note: NULL and SYSNULL do not compare equal. However, you should not write code that depends on them being unequal. Syntax ────SYSNULL───┬──────┬──── └──()──┘ ═══ TAN Mathematical Built-In Function ═══ Description TAN returns a floating-point value that is an approximation of the tangent of x. It has the base, mode, and precision of x. Syntax ────TAN(x)──── x expression whose value is in radians. If x = COMPLEX(a,b), the value of the result is given by : REAL(TAN(x)) = SIN(2*a)/ (COS(2*a)+COSH(2*b)) IMAG(TAN(x)) = SINH(2*b)/ (COS(2*a)+COSH(2*b)) ═══ TAND Mathematical Built-In Function ═══ Description TAND returns a real floating-point value that is an approximation of the tangent of x. It has the base and precision of x. Syntax ────TAND(x)──── x real expression whose value is in degrees. ═══ TANH Mathematical Built-In Function ═══ Description TANH returns a floating-point value that is an approximation of the hyperbolic tangent of x. It has the base, mode, and precision of x. Syntax ────TANH(x)──── x expression whose value is in radians. If x = COMPLEX, the result is given by: -1I*TAN(1I*x) ═══ TIME Miscellaneous Built-In Function ═══ Description TIME returns a character string, length 9, in the format of hhmmssttt. The time zone and accuracy are system dependent. Syntax ────TIME───┬──────┬──── └──()──┘ The returned character string hhmmssttt represents: hh the current hour mm the current minute ss the current second ttt the current millisecond ═══ TRANSLATE String-Handling Built-In Function ═══ Description TRANSLATE returns a character string of the same length as x. TRANSLATE does not support GRAPHIC data. TRANSLATE operates on each character of x as follows: 1. If a character in x is found in z, the character in y that corresponds (by position) 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. 2. Y is padded with blanks, or truncated, on the right to match the length of z. 3. Any arithmetic or bit arguments are converted to character. Example Consider the following use of the TRANSLATE built-in function: DECLARE (W, X) CHAR (3); X='ABC'; W = TRANSLATE (X, 'TAR', 'DAB'); /* W = 'ARC' */ Syntax ────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. If z is omitted, a string of 256 characters is assumed. It contains one instance of each EBCDIC code arranged in ascending collating sequence (hexadecimal 00 through FF). ═══ UNSPEC String-Handling Built-In Function ═══ Description UNSPEC returns a bit string that is the internal coded form of x. Syntax ─────UNSPEC(x)───── x is an expression. Note: If you intend to migrate the program to OS/2, be aware that in PL/I Package 2, the UNSPEC of an array yields a result of BIT(*) scalar. If you need an array of returned values from UNSPEC, use a loop to obtain the result for each array element, and store each result in the array. The length of the returned bit string depends on the attributes of x. Related Information  Lengths of bit strings returned by UNSPEC.  If x is a varying-length string, its 2-byte prefix is included in the returned bit string. If x is an area, the returned value includes the control information. If x is complex, the length of the returned string is twice the value shown above. For example: R = ARRAY(UNSPEC('A')); In this statement, the internal representation of the character 'A' (a bit string 8 bytes in length) is converted to a fixed binary arithmetic value, and used as a subscript for the array. (The decimal value of this particular subscript is 193). ═══ TRUNC Arithmetic Built-In Function ═══ Description TRUNC returns an integer value that is the truncated value of x. If x is positive or 0, this is the largest integer value less than or equal to x. If x is negative, this is the smallest integer value greater than or equal to x. This value is assigned to the result. The base, mode, scale, and precision of the result match those of x. Except when x is fixed-point with precision (p,q), the precision of the result is given by: (MIN(N,MAX(p-q+1,1)),0) where N is the maximum number of digits allowed. Syntax ────TRUNC(x)──── x real expression. ═══ Lengths of Bit Strings Returned by UNSPEC ═══ The length of the returned bit string depends on the attributes of x, as shown in the following table. The maximum length allowed for a bit or elementary variable can vary across supported systems. ┌────────────────────┬───────────────────────────────────────────────────────┐ │ Bit String Length │ Attribute of x │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 16 │ FIXED BINARY (p,q), p <= 15 │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 32 │ FIXED BINARY (p,q) p >= 16 │ │ │ FLOAT BINARY (p), p > 21 │ │ │ FLOAT DECIMAL (p), p <= 6 │ │ │ OFFSET (based on 4-byte pointers) │ │ │ FILE constant or variable (based on 4-byte pointers) │ │ │ POINTER (based on 4-byte pointers) │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 64 │ FLOAT BINARY (p), 22 <= p <= 53 │ │ │ FLOAT DECIMAL (p), 7 <= p <= 16 │ │ │ LABEL constant or variable (based on 4-byte pointers)│ │ │ ENTRY constant or variable (based on 4-byte pointers)│ ├────────────────────┼───────────────────────────────────────────────────────┤ │ OS/2 ONLY - │ FLOAT BINARY (p), 22 <= p <= 52 │ │ 64 │ FLOAT DECIMAL (p), 7 <= p <= 15 │ │ │ LABEL constant or variable │ │ │ ENTRY constant or variable │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 128 │ FLOAT BINARY (p), 54 <= p <= 109 │ │ │ FLOAT DECIMAL (p) 17 <= p <= 33 │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ n │ BIT (n) │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 8*n or 32767 │ CHARACTER (n) │ │ │ PICTURE (with character string length of n) │ │ │ (when n>4096, a length of 32767 is returned) │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 16*n │ GRAPHIC (n) │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 16 + n │ BIT VARYING where n is the maximum length of x. │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 16 + (8*n) │ CHARACTER VARYING where n is the maximum length of x.│ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 16 + (16*n) │ GRAPHIC VARYING where n is the maximum length of x. │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 8*(n+16) │ AREA (n) - (based on 4-byte pointers) │ ├────────────────────┼───────────────────────────────────────────────────────┤ │ 8*FLOOR(n) │ FIXED DECIMAL (p,q) where n = (p+2) / 2 │ └────────────────────┴───────────────────────────────────────────────────────┘ Note: The bit string lengths listed above are system dependent. The lengths listed are for the 370 system. Lengths are equal to 8 times the value given by the STORAGE built-in function. ═══ UNSPEC Built-In Pseudovariable ═══ Description The UNSPEC pseudovariable assigns a bit value directly to x; that is, without conversion. The bit value is padded, if necessary, on the right with '0'B to match the length of x. See "Related Information" below. If x is a varying length string, its 2-byte prefix is included in the field to which the bit value is assigned. If x is an area, its control information is included in the receiving field. Related Information UNSPEC built-in function Syntax ────UNSPEC(x)──── x reference. ═══ VERIFY String-Handling Built-In Function ═══ Description VERIFY returns a real fixed-point binary value indicating the position in x of the leftmost character or bit that is not in y. If all the characters or bits in x do appear in y, a value of zero is returned. If x is the null string, a value of zero is returned. If x is not the null string and y is the null string, a value of one is returned. If either argument is character or decimal, conversions are performed to produce character strings. Otherwise, the arguments are bit and binary or both binary, and conversions are performed to produce bit strings. VERIFY does not support GRAPHIC data. Syntax ────VERIFY(x,y)──── x string-expression. y string-expression. ═══ 1.7. PL/I Program Organization and Control Transfer ═══ Description PL/I is a block-oriented language, consisting of procedures, BEGIN blocks, statements, expressions, and built-in functions that allow program logic, I/O operations, and commentary to be expressed in concise but meaningful self-documenting terms. Unlike many other languages, PL/I is totally free-form and has no reserved keywords. A PL/I application consists of one of more separately loadable entities, known as load modules. Each of these may consist of one or more separately compiled entities, known as compilation units (CU). Unless otherwise stated, a program refers to a PL/I application or a compilation unit. A compilation unit is an external PROCEDURE. A PL/I external or internal procedure contains zero or more blocks. A PL/I block is either a PROCEDURE or a BEGIN block, which contains zero or more statements and/or zero or more blocks. A PROCEDURE block nested within other blocks is called an internal procedure. A PROCEDURE block that is not nested within other blocks is called an external procedure. A procedure is either a subroutine or a function. Subroutines are always called using the CALL statement and may have many (or zero) arguments, some of which may be input only, output only, or both input and output. Functions, however, are invoked by their appearance in an expression and may pass many (or zero) arguments but always return one result value that participates in expression evaluation at the point of function reference. The names of programmer-defined subroutines and functions are established by entry declaration and referenced by entry invocation. Usage Notes Proper division of a program into blocks simplifies the writing and testing of the program, particularly when many programmers are writing it. Proper division can also result in more efficient use of storage, since automatic storage is allocated on entry to the block in which it is declared and released when the block is terminated. A PL/I block allows you to produce highly-modular applications, because blocks can contain declarations that define variable names and storage class. Thus, programmers can restrict the scope of a variable to a single block or a group of blocks, or can cause it to be known throughout a compilation unit or a load module. By giving programmers freedom to determine the degree to which a block is self-contained, PL/I makes it possible to produce blocks that many compilation units and applications can share, leading to code reuse. Related Information  Blocks  FETCH statement  RELEASE statement  GENERIC attribute  Program activation  Program termination ═══ Blocks ═══ Description A block is a delimited sequence of statements that does the following:  Determines the scope of the declaration of names declared within it;  Limits the allocation of automatic variables;  Determines the scope of DEFAULT statements. Kinds of Blocks  Procedures  Begin-blocks Scope of Blocks Blocks can contain declarations that are treated as local definitions of names. This is done to establish the scope of the names and to limit the allocation of automatic variables. These declarations are not known outside their own block, and the names cannot be referred to in the containing block. Automatic storage is allocated upon entry to the block where the storage is declared. The storage is freed upon exit from the block. Related Information  Block activation  Block termination  Internal and external blocks ═══ Block Activation ═══ Description Although the begin block and the procedure play the same role in the allocation and freeing of storage and in delimiting the scope of names, they differ in the way they are activated and executed:  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. Each block plays the same role in the allocation and freeing of storage and in delimiting the scope of names. During block activation, the following are performed:  Expressions for automatic and defined variables are evaluated for dimension bounds, area sizes, string lengths, and initial values (including iteration factors).  Currently active blocks known to the procedure are identified, so that the correct generations of automatic storage are accessible, and the correct ON-units may be entered.  Storage is allocated for automatic variables and initial values, if specified.  Storage is allocated for dummy arguments that might be created in this block. Errors Errors can occur during block activation, and the ERROR condition (or other condition) can be raised. If so, the environment of the block might be incomplete. In particular, some automatic variables might not have been allocated. Statements referencing automatic variables executed after the ERROR condition has been raised may reference unallocated storage. The results of referring to unallocated storage are undefined. Examples The compiler assigns values in the following order for each block in the program. 1. Values that are independent of other declarations in the block. (Values may be inherited from an outer block.) 2. Values that are dependent on other declarations in the block. If a value depends on more than one other declaration in the block, correct initialization is not guaranteed. In the following example: DCL I INIT(10),J INIT(K),K INIT(I); Correct initialization of K is not guaranteed. Declarations of data items must not be mutually interdependent. For example, the following declarations are invalid: DCL A(B(1)), B(A(1)); DCL D(E(1)), E(F(1)), F(D(1)); ═══ Internal and External Blocks ═══ Description Blocks can contain other blocks. The outermost block is called an external block. A block within a block is called an internal block. An internal block must be totally encompassed by another internal block or by an external block. Begin-blocks are always internal; they must always be contained within another block. Internal procedures and begin-blocks can be nested. Nested blocks, in turn, can have blocks nested within them, and so on. The outermost block must be a procedure. Example The following example helps illustrate internal and external blocks. An explanation follows the example. 1 A: PROCEDURE; . 2 B: BEGIN; . 3 END B; . 4 C: PROCEDURE; . 5 D: BEGIN; . E: PROCEDURE; . END E; . 6 END D; 7 END C; . 8 END A; Explanation- 1,8 Procedure A is an external procedure because it is not contained in any other block. 2,3 Begin-block B is contained in A. It contains no other blocks. 4,7 Internal procedure C contains begin-block D. 5,6 Begin-block D contains internal procedure E. This example shows a depth of nesting of three levels relative to A. B and C are at a depth of one, D is at a depth of two, and E is at a depth of three. ═══ Procedures ═══ Description A procedure is a main procedure, a subroutine, or a function. It is a labeled block of statements delimited by an ENTRY statement, or by a PROCEDURE statement and its END statement. It is the basic building block of a PL/I program. Entry points are exclusive to procedures. They indicate the locations to which control can be transferred. 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. For example: B: ENTRY; A procedure block nested within a procedure or BEGIN block is called an internal procedure. A procedure block not nested within procedure or begin blocks is called an external procedure. Procedures or begin blocks can invoke other procedures. A recursive procedure, can be reactivated from within itself or from within another active procedure while it is already active. Subroutines and functions are procedure blocks to which you can temporarily transfer control of a program to perform some frequently used task or run a frequently used sequence of statements. They can be internal or external to the invoking block. Usage Notes You use arguments in the invoking block to pass data to the parameters in the invoked subroutine or function procedure. A parameter has no storage associated with it. It is merely a means of allowing the invoked procedure to access storage allocated in the invoking procedure. A reference to a parameter in a procedure is a reference to the corresponding argument. Any change to the value of the parameter is made to the value of the argument. However, in certain circumstances, a dummy argument is created and the value of the original argument is not changed. In these cases, a reference to the parameter is a reference to the dummy argument. The dummy argument initially has the same value as the original argument, but subsequent changes to the parameter do not affect the original argument's value. Both internal and external procedures are normally loaded into main storage at the same time as the invoking procedure. However, an external procedure can be compiled separately from the invoking procedure and loaded when needed by the use of the FETCH statement and the RELEASE statement . Example Consider the following procedure, NAME: 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. Related Information  Procedure activation  Procedure termination  Passing an argument to the main procedure  Passing arguments between procedures ═══ PROCEDURE Statement ═══ Description The PROCEDURE statement:  And the corresponding END statement delimit a procedure.  Defines the primary entry point to the procedure (and optionally, secondary entry points).  Specifies the parameters, if any, for the primary entry point.  Can specify options that a procedure can have.  Can specify the attributes of the value returned by the procedure if it is invoked as a function. Syntax ┌────────────────┐  │ ───entry-constant:─┴─PROCEDURE──┬────────────────────┬────── │ ┌─────,─────┐ │ │  │ │ └─(───parameter─┴──)─┘ ─────┬────────────────────────────────┬────────────────────── │ ┌─────────────┐ │ │  │ │ └─RETURNS──(─────attribute──┴──)─┘ ─────┬────────────────────────────────────┬────────────────── └────OPTIONS(characteristic list)────┘ ┌─IRREDUCIBLE─┐ ┌─ORDER────┐ ┌─NOCHARGRAPHIC─┐ ───┼─────────────┼──┬────────────┬───┼──────────┼───┼───────────────┼──;── └─REDUCIBLE───┘ └─RECURSIVE──┘ └─REORDER──┘ └─CHARGRAPHIC───┘ Abbreviations: CHARG for CHARGRAPHIC NOCHARG for NOCHARGRAPHIC PROC for PROCEDURE ═══ Parameter Attributes ═══ Description The parameter attribute specifies that a name in an invoked procedure represents an argument passed to that procedure. A name is explicitly declared with the parameter attribute by its appearance in the parameter list of a PROCEDURE or an ENTRY statement. Attributes other than parameter can be supplied by a DECLARE statement internal to the procedure. If attributes are not supplied in a DECLARE statement, default attributes are applied. A parameter always has the attribute INTERNAL. It must be a level-one name, and must not be subscripted or qualified. If an argument is an array, a string, or an area, the bounds of the array, the length of the string, or the size of the area must be declared for the corresponding parameter. The number of dimensions and the bounds of an array parameter, or the length and size of an area or string parameter, must be the same as the current generation of the corresponding argument. Parameter Storage Because a parameter has no associated storage within the invoked procedure, it cannot be declared to have any of the storage attributes STATIC, AUTOMATIC, BASED, or DEFINED. However, it can be declared to have the CONTROLLED attribute. Thus, there are two classes of parameters, as far as storage allocation is concerned: those that have no storage class (simple parameters) and those that have the CONTROLLED attribute (controlled parameters). Only controlled parameters can have the INITIAL attribute. Parameters used in record-oriented input/output, or as the base variable for DEFINED terms, must be in connected storage. If such a parameter is an aggregate, it must have the CONNECTED attribute, both in its declaration in the procedure, and, where applicable, in the descriptor list of the procedure entry declaration. Simple Parameter Bounds, Lengths, and Sizes Bounds, lengths, and sizes of simple parameters must be specified either by asterisks or by constants. When the actual length, bounds, or size may be different for different invocations, each can be specified in a DECLARE statement by an asterisk. When an asterisk is used, the length, bounds, or size are taken from the current generation of the associated argument. An asterisk is not allowed as the length specification of a string that is an element of an aggregate, if the associated argument creates a dummy. The string length must be specified as an integer. Controlled Parameter Bounds, Lengths, and Sizes The bounds, length, or size of a controlled parameter can be specified in a DECLARE statement either by asterisks or by element expressions. Asterisk Notation: When asterisks are used, length, bounds, or size of the controlled parameter are taken from the current generation of the associated argument. Any subsequent allocation of the controlled parameter uses these same bounds, length, or size, unless they are overridden by a different length, bounds, or size specification in the ALLOCATE statement. If no current generation of the argument exists, the asterisks determine only the dimensionality of the parameter, and an ALLOCATE statement in the invoked procedure must specify bounds, length, or size for the controlled parameter before other references to the parameter can be made. Expression Notation: Each time the parameter is allocated, the expressions are evaluated to give current bounds, lengths, or sizes for the new allocation. However, such expressions in a DECLARE statement can be overridden by a bounds, length, or size specification in the ALLOCATE statement itself. ═══ Procedure Activation ═══ Description A procedure can be invoked at any point at which an entry name of the procedure is known. Execution of the invoked procedure can be only synchronous. The execution of the invoking procedure is suspended until the invoked procedure returns control to it. Sequential program flow passes around a procedure, from the statement before the PROCEDURE statement to the statement after the END statement of that procedure. The only way that a procedure can be activated is by a procedure reference. When a procedure reference is executed, the procedure containing the specified entry point is said to be "invoked". The point at which the procedure reference appears is called the "point of invocation" and the block in which the reference is made is called the "invoking block". An invoking block remains active even though control is transferred from it to the procedure it invokes. When a procedure is invoked, arguments and parameters are associated and execution begins with the statement following the PROCEDURE or the ENTRY statement in the invoked procedure. A procedure reference is the appearance of an entry expression in one of the following contexts:  Using a CALL statement to invoke a subroutine or function.  After the keyword CALL in the CALL option of the INITIAL attribute.  Invoking functions. Examples Consider the following examples of procedure activation. This procedure: READIN: PROCEDURE; statement-1 statement-2 statement-3 ... END READIN; can be activated by this entry reference: CALL READIN; The entry-constant (such as READIN) can also assigned to an entry variable that is used in a procedure reference: DECLARE READIN ENTRY, ENT1 ENTRY VARIABLE; ENT1 = READIN; CALL ENT1; CALL READIN; These two CALL statements have the same effect. Related Information Program activation ═══ Procedure Termination ═══ Description A procedure is terminated when, by some means other than a procedure reference, control passes back to the invoking program, block, or to some other active block. 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. If the point of invocation is a CALL statement, execution in the invoking procedure resumes with the statement following the CALL. If the point of invocation is 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. Abnormal procedure termination occurs when:  Control reaches a GO TO statement that transfers control out of the procedure. The GO TO statement can specify a label in a containing block (the label must be known within the procedure), or it can specify a parameter that has been associated with a label argument passed to the procedure.  A STOP statement is executed.  An EXIT statement is executed.  The ERROR condition is raised and there is no established ON-unit for ERROR or FINISH. Also, if one or both of the conditions has an established ON-unit, ON-unit exit is by normal return, rather than by a GO TO statement. Usage Notes 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 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. Example Procedure termination ═══ Example- Procedure Termination ═══ In the following example: A: PROCEDURE OPTIONS(MAIN); statement-1 statement-2 B: BEGIN; statement-b1 statement-b2 CALL C; statement-b3 END B; statement-3 statement-4 C: PROCEDURE; statement-c1 statement-c2 statement-c3 D: BEGIN; 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. In 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. ═══ Recursive Procedures ═══ Description An active procedure that is invoked from within itself or from within another active procedure is a "recursive" procedure. Such an invocation is called "recursion". A procedure that is invoked recursively must have the RECURSIVE option specified in its PROCEDURE statement. The environment (that is, values of automatic variables, etc.) of every invocation of a recursive procedure is preserved in a manner analogous to the stacking of allocations of a controlled variable. Think of an environment as being "pushed down" at a recursive invocation, and "popped up" at the termination of that invocation. A label constant in the current block is always a reference to the current invocation of the block that contains the label. If a label constant is assigned to a label variable in a particular invocation, a GO TO statement naming that variable in another invocation restores the environment that existed when the assignment was performed. Example Using the RECURSIVE option Related Information Effect of recursion on automatic variables Syntax ─────RECURSIVE───── ═══ Example- Using the RECURSIVE Option ═══ The environment of a procedure that was invoked from within a recursive procedure by means of an entry variable is the one that was current when the entry-constant was assigned to the variable. Consider the following example: I=1; CALL A; /* FIRST INVOCATION OF A */ A: PROC RECURSIVE; DECLARE EV ENTRY VARIABLE STATIC; IF I=1 THEN DO; I=2; EV=B; CALL A; /* 2ND INVOCATION OF A */ END; ELSE CALL EV; /* INVOKES B WITH ENVIRONMENT */ /* OF FIRST INVOCATION OF A */ B: PROC; GO TO OUT; END B; OUT: END A; The GO TO statement in the procedure B transfers control to the END A statement in the first invocation of A, and terminates B and both invocations of A. ═══ Effect of Recursion on Automatic Variables ═══ Description The values of variables allocated in one activation of a recursive procedure must be protected from change by other activations. This is arranged by "stacking" the variables. A stack operates on a last-in first-out basis: the most recent generation of an automatic variable is the only one that can be referenced. Usage Notes Static variables are not affected by recursion. Thus, they are useful for communication across recursive invocations. This also applies to:  Automatic variables that are declared in a procedure that contains a recursive procedure  Controlled and based variables. Example In the following example: A: PROC; DCL X; . . B: PROC RECURSIVE; DCL Z, Y STATIC; CALL B; . . END B; END A; A single generation of the variable X exists throughout invocations of procedure B. The variable Z has a different generation for each invocation of procedure B. The variable Y can be referred to only in procedure B and will not be reallocated at each invocation. ═══ FETCH Statement ═══ Description The FETCH statement checks main storage for the named procedures. The named procedures must not be internal procedures. Procedures not already in main storage are loaded from auxiliary storage. FETCH and RELEASE Restrictions When using dynamically-loaded procedures: 1. Only external procedures can be fetched. 2. Variables with the EXTERNAL attribute are not allowed in a fetched procedure. 3. Variables with the CONTROLLED attribute are not allowed in a fetched procedure unless they are parameters. 4. With the exception of the file SYSPRINT, variables with the FILE attribute are not allowed in a fetched procedure unless they are parameters. This means that any other file used in the fetched procedure, including the file SYSIN, must be passed from the calling procedure. A file that is explicitly opened in a fetched procedure must be explicitly closed in that procedure before that procedure ends. A file that is implicitly opened in a fetched procedure must be closed only in the fetching procedure. The close must be prior to releasing the fetched procedure. A file that is open when it is passed to a fetched procedure must not be closed in the fetched procedure. 5. Storage for STATIC variables in the fetched procedures is allocated when the FETCH statement is executed, and is freed when a corresponding RELEASE statement is executed. Each time a procedure is fetched into main storage, a STATIC variable either is given the value specified in an INITIAL attribute, or if there is no INITIAL attribute, is not initialized. 6. The FETCH, RELEASE, and CALL statements must specify entry-constants. An entry-constant for a fetched procedure cannot be assigned to an entry variable. 7. Fetched procedures cannot fetch further procedures. Related Information  RELEASE statement Syntax ┌──,──────────────┐  │ ───FETCH─────entry-constant─┴──;────────────────────────── ═══ RELEASE Statement ═══ Description The RELEASE statement frees the main storage occupied by procedures identified by its specified entry-constants. Usage Notes The fetched procedure is compiled and link-edited separately from the calling procedure. You must ensure that the entry-constant specified in; FETCH statements, RELEASE statements, and CALL statements, options, and in function references is the name known in auxiliary storage. Example Consider the following example in which PROGA and PROGB are entry names of procedures resident on auxiliary storage: PROG: PROCEDURE; 1 FETCH PROGA; 2 CALL PROGA; 3 RELEASE PROGA; 4 CALL PROGB; GO TO FIN; FETCH PROGB; FIN: END PROG; 1:PROGA is loaded into main storage by the first FETCH statement 2: PROGA executes when the first CALL statement is reached. 3: Storage for PROGA is released when the RELEASE statement is executed. 4: PROGB is loaded and executed when the second CALL statement is reached, even though the FETCH statement referring to this procedure is never executed. The same results would be achieved if the statement FETCH PROGA was omitted. The appearance of PROGA in a RELEASE statement causes the statement CALL PROGA to load the procedure, as well as invoke it. Syntax ┌────────,────────┐  │ ────RELEASE─────entry-constant──┴──;──── ═══ Passing an Argument to the Main Procedure ═══ Description The PROCEDURE statement for the main procedure can have a parameter list. Such parameters require no special considerations in PL/I. However, you must be aware of any requirements of the invoking program (for example, not to use a parameter as the target of an assignment). When the invoking program is the operating system, a single argument is passed to the program. If this facility is used, the parameter must be declared as a VARYING character string within the procedure. The current length is set equal to the argument length at run time. Restrictions When the MAIN and NOEXECOPS attributes are specified, the main procedure can have one of the following as parameters:  A single parameter that is a VARYING CHARACTER string. The parameter passes as is, and a descriptor is set up. ("/", if contained in the string, is treated as part of the string). For example: MAIN:PROC(PARM) OPTIONS(MAIN NOEXECOPS); DCL PARM CHAR(100) VARYING;  Other parameters (such as, more than one parameter or a single parameter that is not a VARYING CHARACTER string). The parameter list passes as is, and no descriptors are set up. The caller of the PL/I MAIN procedure must know what is expected by the procedure, including any required descriptors. ═══ Begin Blocks ═══ Description A begin-block is a sequence of statements delimited by a BEGIN statement and a corresponding END statement. Begin blocks are always internal. They must be contained within another block and can be nested. One of the containing blocks must be a procedure. Example For example: B: BEGIN; statement-1 statement-2 . . statement-n END B; Unlike a procedure, a label is optional for a begin block. If one or more labels are prefixed to a BEGIN statement, they serve only to identify the starting point of the block. The label following END is optional. Related Information  BEGIN statement  Begin-block activation  Begin-block termination ═══ BEGIN Statement ═══ Description The BEGIN statement and a corresponding END statement delimit a begin-block. The options of the BEGIN statement can appear in any order. Syntax ┌──ORDER────┐ ┌──NOCHARGRAPHIC──┐ ────BEGIN───┼───────────┼──┼─────────────────┼──;──── └──REORDER──┘ └──CHARGRAPHIC────┘ ═══ Subroutines ═══ Description A subroutine is an internal or external procedure that is invoked by a CALL statement. It obtains temporary control of the program. The arguments of the CALL statement are associated with the parameters of the invoked procedure. The subroutine is activated, and execution begins. The arguments (zero or more) may be input only, output only, or both. A subroutine is normally terminated by the RETURN or END statements. Control is then returned to the invoking block. Like any procedure, a subroutine can be abnormally terminated. Examples Invoking subroutines Related Information  Built-in subroutines  PROCEDURE statement  Procedure termination ═══ Examples- Invoking Subroutines ═══ The following examples illustrate the invocation of subroutines that are internal to and external to the invoking block.  Example 1: PRMAIN: PROCEDURE; DECLARE NAME CHARACTER (20), ITEM BIT(5), 4 OUTSUB ENTRY; 1 CALL OUTSUB (NAME, ITEM); END PRMAIN; *PROCESS; 2 OUTSUB: PROCEDURE (A,B); DECLARE A CHARACTER (20), B BIT(5); 3 PUT LIST (A,B); END OUTSUB; Explanation- 1 The CALL statement in PRMAIN invokes the procedure OUTSUB in 2 with the arguments NAME and ITEM. 2 OUTSUB associates NAME and ITEM passed from PRMAIN with its parameters, A and B. When OUTSUB is executed, each reference to A is treated as a reference to NAME. Each reference to B is treated as a reference to ITEM. 3 The PUT LIST (A,B) statement transmits the values of NAME and ITEM to the default output file, SYSPRINT. 4 In the declaration of OUTSUB as an entry-constant, no parameter descriptor has to be given with the ENTRY attribute, because the attributes of the arguments and parameters match.  Example 2: A: PROCEDURE; DECLARE RATE FLOAT (10), TIME FLOAT(5), DISTANCE FLOAT(15), MASTER FILE; 1 CALL READCM (RATE, TIME, DISTANCE, MASTER); 3 READCM: 2 PROCEDURE (W,X,Y,Z); DECLARE W FLOAT (10), X FLOAT(5), Y FLOAT(15), Z FILE; GET FILE (Z) LIST (W,X,Y); Y = W*X; IF Y > 0 THEN RETURN; ELSE PUT LIST('ERROR READCM'); END READCM; END A; Explanation- 1 The arguments RATE, TIME, DISTANCE, and MASTER are passed to the procedure READCM in 3 and associated with the parameters W, X, Y, and Z. 2 A reference to W is the same as a reference to RATE, X the same as TIME, Y the same as DISTANCE, and Z the same as MASTER. 3 Note that READCM is not explicitly declared in A. It is implicitly declared with the ENTRY attribute by its specification on the PROCEDURE statement. ═══ Functions ═══ Description A function is a procedure that has zero or more arguments and is invoked by a function reference in an expression. The function reference transfers control to a function procedure, and returns a value, and control, to replace the function reference in the evaluation of the expression. This single value can be of any data type except entry. The evaluation of the expression then continues. The function is distinguished from a subroutine by the RETURNS attribute on the PROCEDURE statement. Whenever a function is invoked, the arguments in the invoking expression are associated with the parameters of the entry point. Control is then passed to that entry point. The function is activated and execution begins. The RETURN statement terminates a function and returns the value specified in its expression to the invoking expression. Usage Notes A function can be abnormally terminated. If this method is used, evaluation of the expression that invoked the function is not completed, and control goes to the designated statement. In some instances, a function can be defined so that it does not require an argument list. In such cases, the appearance of an external function name within an expression is recognized as a function reference only if the function name has been explicitly declared as an entry name. Examples Invoking functions Related Information  Entry invocation  Built-in functions  BUILTIN attribute  PROCEDURE statement  Procedure termination ═══ Examples- Invoking Functions ═══ The following examples illustrate the invocation of functions that are internal to and external to the invoking block.  In the following example, the assignment statement contains a reference to the SPROD function: MAINP: PROCEDURE; GET LIST (A, B, C, Y); 1 X = Y**3+SPROD(A,B,C); 2 SPROD: PROCEDURE (U,V,W) RETURNS (BIN FLOAT(21)); DCL (U,V,W) BIN FLOAT(53); IF U > V + W THEN 3 RETURN (0); ELSE 3 RETURN (U*V*W); END SPROD; Explanation- 1 When SPROD is invoked, the arguments A, B, and C are associated with the parameters U, V, and W in 2, respectively. 2 SPROD is an internal function. If SPROD were external, MAINP would contain an entry declaration with RETURNS specified. 3 SPROD returns either 0 or the value represented by U*V*W, along with control to the expression in MAINP. The returned value is taken as the value of the function reference, and evaluation of the expression continues.  Consider the following: MAINP: PROCEDURE; DCL TPROD ENTRY (BIN FLOAT(53), BIN FLOAT(53), BIN FLOAT(53), LABEL) EXTERNAL RETURNS (BIN FLOAT(21)); GET LIST (A,B,C,Y); 1 X = Y**3+TPROD(A,B,C,LAB1); LAB1: CALL ERRT; END MAINP; *PROCESS 1 TPROD: PROCEDURE (U,V,W,Z) RETURNS (BIN FLOAT(21)); DCL (U,V,W) BIN FLOAT(53); DECLARE Z LABEL; 2 IF U > V + W THEN GO TO Z; 3 ELSE RETURN (U*V*W); END TPROD; Explanation- 1 When TPROD is invoked, LAB1 is associated with parameter Z. 2 If U is greater than V + W, control returns to MAINP at the statement labeled LAB1. Evaluation of the assignment in 1 is discontinued. 3 If U is not greater than V + W, U*V*W is calculated and returned to MAINP in the normal fashion. Evaluation of the assignment in 1 continues. Notice that TPROD is an external procedure. It has an explicit entry declaration in MAINP. ═══ RETURNS Attribute ═══ Description The RETURNS attribute specifies (within the invoking procedure) that the value returned from an external function procedure is treated as though it had the attributes given in the attribute list. The word "treated" is used because no conversion is performed in an invoking block upon any value returned to it. It further specifies, by implication, the ENTRY attribute for the name. Unless attributes for the returned value can be determined correctly by default, any invocation of an external function must appear within the scope of a declaration with the RETURNS attribute for the entry name. If more than one attribute is specified, they must be separated by blanks (except for attributes such as precision, that are enclosed in parentheses). The attributes that can be specified are any of the data attributes and alignment attributes for variables (except those for ENTRY variables). The OFFSET attribute can include an area reference. String lengths and area sizes must be specified by integers. The returned value has the specified length or size. The RETURNS attribute must agree with the attributes specified in (defaults for) the RETURNS option of the PROCEDURE statement or the ENTRY statement to which the entry name is prefixed. The value returned will have attributes determined from the RETURNS option. If they do not agree, there is an error, since no conversion is performed. If the RETURNS attribute is not specified for an external entry-constant, or an entry variable, the attributes for the value returned are set by default. Related Information  ENTRY attribute  RETURN statement  CALL statement Syntax ┌───────────┐  │  ────RETURNS──(───attribute─┴───,────────────────── ═══ CALL Statement ═══ Description Use the CALL statement to invoke a procedure and transfer control to it. References and expressions in the CALL statement are evaluated in the block in which the call is executed. This includes execution of any ON-units entered as the result of the evaluations. The environment of the invoked procedure is established after evaluation of any expressions and before the procedure is invoked. A CALL statement must not be used to invoke a procedure if control is to be returned to the invoking procedure by means of a RETURN(expression) statement. If the procedure invoked by the CALL statement has been specified in a FETCH statement or a RELEASE statement, and if it is not present in main storage, the CALL statement initiates dynamic loading of the procedure from auxiliary storage. Syntax ────CALL──┬─entry-reference─┬───┬──────────────────────────┬─;──── ├─generic-name────┤ └─(─┬──────────────────┬─)─┘ └─built-in-name───┘ │ ┌─,────────────┐ │ │  │ │ └───┬─argument─┬─┴─┘ └─*────────┘ ═══ BUILTIN Attribute ═══ Description The BUILTIN attribute specifies that a name is a built-in function name, pseudovariable name, or built-in subroutine name. Usage Notes Built-in names can be used as programmer-defined names, defined by explicit or implicit declaration. The BUILTIN attribute can be declared for a built-in name in any block that has inherited, from a containing block, some other declaration of the name. Note: PLITDLI and ASMTDLI cannot be declared with the BUILTIN attribute but are treated as special subroutines. Related Information PL/I Built-in subroutines, functions, and pseudovariables Syntax ────BUILTIN──── ═══ Passing Arguments between Procedures ═══ Description Passing arguments from one procedure to another happens in the following ways: - By means of arguments passed from an invoking procedure to the parameters of an invoked procedure - By a value returned from an invoked procedure - By names known within both procedures. Therefore, a procedure can operate upon different data when it is invoked from different points. The use of arguments and parameters provides the means for generalizing procedures so that data whose names are not known within the invoking procedure can be operated on by the invoked procedure. When a subroutine or function is invoked, the arguments of the invoking reference are associated, from left to right, with the parameters in the parameter list of the procedure. The number of arguments and parameters must be the same. Expressions in the argument list are evaluated in the invoking block before the subroutine or function is invoked. A parameter has no storage associated with it. It is merely a means of allowing the invoked procedure to access storage allocated in the invoking procedure. A reference to a parameter in a procedure is a reference to the corresponding argument. Any change to the value of the parameter is made to the value of the argument. 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 procedure) for some arguments using attributes that agree with the parameter, converts, and assigns 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. Argument attributes are derived for internal entry constants using the declarations of the parameters. But for entry variables and external entry-constants, a parameter-descriptor list must be given in an appropriate entry declaration, if conversion is required. Usage Rules Rules for passing arguments to procedures Related Information  Parameter attributes  Passing an argument to the main procedure  Dummy argument attributes ═══ Rules for Passing Arguments to Procedures ═══ In general:  Problem data arguments can be passed to parameters of any problem data type, except that graphic values can only be passed to graphic parameters, and graphic parameters must have graphic arguments.  Program control data arguments must be passed to parameters of the same type.  Aggregate parameters can have aggregate or element arguments. In addition, the following argument passing rules apply:  If a parameter is an element (that is, a variable that is neither a structure nor an array) the argument must be an element expression.  If a parameter is an array, the argument can be an array expression or an element expression. If the argument is an element expression, the corresponding parameter descriptor or declaration must specify the bounds of the array parameter as integers. This causes the construction of a dummy array argument, whose bounds are those of the array parameter. The value of the element expression is then assigned to the value of each element of the dummy array argument.  If the argument is an array expression, the number of dimensions must be the same, and the bounds must either be the same or must, for the parameter, be declared with asterisks.  If a parameter is a structure, the argument must be a structure expression or an element expression. If the argument is an element expression, the corresponding parameter descriptor for an external entry point must specify the structure description of the structure parameter. This causes the construction of a dummy structure argument, whose description matches that of the structure parameter. The value of the element expression then becomes the value of each element of the dummy structure argument. The relative structuring of the argument and the parameter must be the same; the level numbers need not be identical. The element value must be one that can be converted to conform with the attributes of all the elementary names of the structure.  If the parameter is an array of structures, the argument can be an element expression, an array expression, a structure expression, or an array of structures expression.  Whenever a varying-length element string argument is passed to a nonvarying element string parameter whose length is undefined (that is, specified by an asterisk), a dummy argument whose length is the current length of the original argument is passed to the invoked procedure.  When the argument is a varying-length string array passed to a nonvarying undefined-length array parameter, a dummy argument whose element length is the maximum length is passed.  If the parameter has one of the program control data (except locator) attributes, the argument must be a reference of the same data type.  If a parameter is a locator of either pointer or offset type, the argument must be a locator reference of either type. If the types differ, a dummy argument is created. The parameter descriptor of an offset parameter must not specify an associated area.  Entry variables passed as arguments are assumed to be aligned, so that no dummy argument is created when only the alignments of argument and parameter differ.  A simple parameter can be associated with an argument of any storage class. However, if more than one generation of the argument exists, the parameter is associated only with that generation existing at the time of invocation.  A controlled parameter must always have a corresponding controlled argument that cannot be subscripted, cannot be an element of a structure, and cannot cause a dummy to be created. If more than one generation of the argument exists at the time of invocation, the parameter corresponds to the entire stack of these generations. Thus, at the time of the invocation, a controlled parameter represents the current generation of the corresponding argument. A controlled parameter can be allocated and freed in the invoked procedure, thus allowing the manipulation of the allocation stack of the associated argument.  When no parameter descriptor is given, the entire stack is passed. In this case, the parameter can be simple or controlled and can be correspondingly associated with either the latest generation or the entire stack.  In addition, 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 or connected attribute 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. This does not apply when an expression other than an integer is used to define the bounds, length or size of a controlled parameter. The compiler assumes that the argument and parameter bounds, length or size match. In the case of arguments and parameters with the PICTURE attribute, a dummy argument is created unless the picture specifications match exactly, after any repetition factors are applied. The only exception is that an argument or parameter with a + sign in a scaling factor matches a parameter or argument without the + sign. - A controlled string or area (because an ALLOCATE statement could change the length or extent). - A string or area with an adjustable length or size, associated with a noncontrolled parameter whose length or size is a constant. - An iSUB-defined array ═══ Entry Declaration ═══ Description Entry declaration means declaring the names of programmer-defined subroutines and functions. The 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 statement, or an ENTRY statement or a name declared with the ENTRY attribute and not the VARIABLE attribute, or the name of a mathematical built-in function. It can be assigned to an entry variable. When an entry-constant that is an entry point of an internal procedure is assigned to an entry variable, the assigned value remains valid only for as long as the block that the entry-constant was internal to remains active (and, for recursive procedures, remains current). Examples  Consider the following example of entry declaration:. P: PROCEDURE; DECLARE EV ENTRY VARIABLE, (E1,E2) ENTRY; EV = E1; CALL EV; EV = E2; CALL EV; P, E1, and E2 are entry-constants. EV is an entry variable. The first CALL statement invokes the entry point E1. The second CALL invokes the entry point E2.  The following example declares F(5), a subscripted entry variable: DECLARE (A,B,C,D,E) ENTRY, DECLARE F(5) ENTRY VARIABLE INITIAL (A,B,C,D,E); DO I = 1 TO 5; CALL F(I) (X,Y,Z); The five entries A, B, C, D, and E are each invoked with the parameters X, Y, and Z. Related Information  Entry-constants  Entry variables  GENERIC attribute  ENTRYADDR built-in function ═══ Entry Constants ═══ Description Entry constants may be internal or external. Internal entry-constants are explicitly declared by the appearance of a label prefix to a PROCEDURE statement. or an ENTRY statement. A parameter-descriptor list is obtained from the parameter declarations, if any, and by defaults. External entry-constants must be explicitly declared. This declaration:  Defines an entry point to an external procedure.  Optionally specifies a parameter-descriptor list (the number of parameters and their attributes), 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. External Entry Constant Syntax ─────ENTRY───┬─────────────────────────────────────┬────────────── └─(──┤ parameter-descriptor-list ├──)─┘ ───┬───────────────────────────────┬───┬────────────────────────────────────┬───── └─RETURNS─(──attribute-list──)──┘ └─OPTIONS─(──characteristic-list──)──┘ ┌─IRREDUCIBLE─┐ ───┬──────────┬───┼─────────────┼────────────────────────────────────────── └─EXTERNAL─┘ └─REDUCIBLE───┘ where parameter-descriptor-list is: ┌──,──────────────────────────┐  │ ├──────┤ parameter-descriptor ├───┴───────────────────────────────────────────┤ where parameter-descriptor is: ├──┬──────────────────────────────────────┬───────────────────────────────────┤ │ ┌─────────┐ │ │  │ │ ├──attribute┴──────────────────────────┤ ├─*─┬──────────┬───────────────────────┤ │ └─OPTIONAL─┘ │ │ │ └──┤ structure-parameter-descriptor ├──┘ where structure-parameter-descriptor is: ┌──,───────────────────────────┐  │ ├──1─┬─────────────────┬─,────level──┬─────────────────┬───┴──────────────────────┤ │ ┌────────────┐ │ │ ┌───────────┐ │ │  │ │ │  │ │ └────attribute──┴─┘ └───attribute──┴──┘ ═══ Entry Variables ═══ Description The possible attributes of the declaration of an entry variable (which can contain both internal and external entry values) are listed below. The variable can be part of an aggregate, although structuring and dimension attributes are not shown. VARIABLE must be specified or implied to establish the name as an entry variable. An ENTRY can be BASED, but a based ENTRY cannot be used as (or as part of) an argument of a CALL statement. The ENTRYADDR built-in function and ENTRYADDR built-in pseudovariable can be used to manipulate entry point addresses of procedures. Entry Variable Syntax ───ENTRY─┬─────────────────────────────────┬───┬──────────┬─ └─(─┤parameter─descriptor─list├─)─┘ └─VARIABLE─┘ ─────┬───────────────────────────────┬─────────────────────── └─RETURNS──(──attribute─list──)─┘ ─────┬────────────────────────────────────┬────────────────── └─OPTIONS──(──characteristic─list──)─┘ ┌─IRREDUCIBLE─┐ ─────────────────┼─────────────┼──────────────────────────── └─REDUCIBLE───┘ ─────┬─────────────────┬──────┬───────────────────┬────────── └─scope-attribute─┘ └─storage-attribute─┘ ───┬──────────────────────┬───┬───────────┬────────────────── └─alignment-attribute──┘ └─parameter─┘ ─────┬─────────┬──────┬─────────┬─────────────────────────── └─DEFINED─┘ └─INITIAL─┘ where parameter-descriptor-list is: ┌──,──────────────────────────┐  │ ├──────┤ parameter-descriptor ├───┴─────────────────────────────────┤ where parameter-descriptor is: ├──┬──────────────────────────────────────┬─────────────────────────┤ │ ┌─────────┐ │ │  │ │ ├──attribute┴────────────────────────────────────────────────────┤ ├─*─┬──────────┬───────────────────────┤ │ └─OPTIONAL─┘ │ │ │ └──┤ structure-parameter-descriptor ├──┘ where structure-parameter-descriptor is: ┌──,───────────────────────────┐  │ ├──1─┬─────────────────┬─,────level──┬─────────────────┬───┴────────┤ │ ┌────────────┐ │ │ ┌───────────┐ │ │  │ │ │  │ │ └────attribute──┴─┘ └───attribute──┴──┘ Note: The attributes can appear in any order. ═══ ENTRY Attribute ═══ Description The ENTRY attribute specifies that the name being declared is either an external entry-constant or an entry variable. It also describes the attributes of the parameters of the entry point. Usage Rules  Defaults are not applied to a parameter-descriptor unless attributes or level numbers are specified in the descriptor. If a level number and/or the dimension attribute only is specified in the descriptor, FLOAT DECIMAL(6) REAL are the defaults.  Defaults are not applied if an asterisk is specified. For example, in the following declaration, defaults are applied only to the third parameter: DCL X ENTRY(*, * OPTIONAL, ALIGNED);/* DEFAULTS APPLIED TO 3RD PARM */  Extents (lengths, sizes, and bounds) in parameter-descriptors must be specified by integers or by asterisks. Extents in descriptors for controlled parameters must be specified by asterisks. Syntax ────ENTRY──┬───────────────────────────────────┬─────────── └(──┬───────────────────────────┬─)─┘ └┤parameter-descriptor-list├┘ where parameter-descriptor-list is: ┌───────────,──────────┐  │ ─────┤parameter-descriptor├┴──────────────────────────────── where parameter-descriptor is: ────┬────────────────────────────────┬────────────────────── │ ┌─────────────┐ │ │  │ │ ├────────────attribute──┴────────┤ ├────────────────*─┬──────────┬──┤ │ └─OPTIONAL─┘ │ │ │ └┤structure-parameter-descriptor├┘ where structure-parameter-descriptor is: ┌──,────────────────────────┐  │ ────1──┬─────────────────┬───,──level─┬─────────────────┬─┴─ │ ┌────────────┐ │ │ ┌────────────┐ │ │  │ │ │  │ │ └────attribute──┴─┘ └────attribute──┴─┘ ═══ OPTIONAL attribute ═══ Description The OPTIONAL attribute can be specified in the parameter-descriptor-list of the ENTRY attribute. The ENTRY must have the OPTIONS(ASSEMBLER) attribute. OPTIONAL arguments can be omitted in calls by specifying an asterisk for the argument. The parameter descriptor corresponding to the omitted argument must have the OPTIONAL attribute. An omitted item can be anywhere in the argument list, including at the end. You cannot specify OPTIONAL in the declaration of a parameter, in the DEFAULT statement, or as a generic-descriptor attribute. You also cannot:  Apply OPTIONAL and BYVALUE to the same parameter  Omit arguments of generic names or built-in names. Syntax ──────OPTIONAL──────────────────────────── Example Consider the following example: DCL X ENTRY (FLOAT OPTIONAL, FLOAT OPTIONAL) EXTERNAL OPTIONS (ASM); DCL F FLOAT; CALL X (*, *); /* BOTH ARGUMENTS ARE OMITTED*/ CALL X (*, F); /* FIRST ARGUMENT IS OMITTED */ CALL X (F, *); /* LAST ARGUMENT IS OMITTED */ Note: An omitted argument is indicated by a word of zeros in the argument list. If the omitted argument is also the last argument, the high order bit of the zero word is set to '1'B. ═══ IRREDUCIBLE and REDUCIBLE Attributes ═══ Description If the REDUCIBLE or the IRREDUCIBLE attributes are specified in your program, they are checked for syntax errors, and the implied attribute ENTRY is applied; otherwise, they are ignored. Syntax ┌─IRREDUCIBLE─┐ ────┴─REDUCIBLE───┴─────────────────────── ═══ GENERIC Attribute ═══ Description A generic name is declared with the GENERIC attribute, and specifies a set of entry references. During compilation, other occurrences of the generic name are replaced by one of the set of entry references. Compilation then continues, using the entry reference. (Thus, generic declarations are a kind of macro.) Replacement is determined according to generic selection. When a generic name is encountered, the number of arguments and their attributes are compared with each generic-descriptor list. The entry reference that replaces the generic name is the first one whose generic-descriptor list matches the arguments both in number and attributes. Usage Notes  If all of the descriptors are omitted or consist of an asterisk, the first entry reference with the correct number of descriptors is selected.  An entry expression used as an argument in a reference to a generic value only matches a descriptor of type ENTRY. If there is no such description, the program is in error.  The program is in error if no generic-descriptor list is found to match the attributes of the arguments to a particular generic name. Examples Using generic names Syntax for Declaring Generic Entry Data ────────DECLARE────generic-name──GENERIC─────────────────────────── ┌───,──────────────────────────,─────────────────────────┐ │ ┌───────,───────────────┐ │   │ │ ─────────entry-reference──WHEN──(───┬────────────────────┬┴──)─┴─)── └─generic-descriptor─┘ ═══ Examples- Using Generic Names ═══ If a generic data declaration is: DECLARE CALC GENERIC (FXDCAL WHEN (FIXED,FIXED), FLOCAL WHEN (FLOAT,FLOAT), MIXED WHEN (FLOAT,FIXED)), X DECIMAL FLOAT (6), Y BINARY FIXED (15,0); and the invoking statement is: Z = X+CALC(X,Y); The compiler looks in CALC for an entry reference with one comma, whose descriptors are DECIMAL or FLOAT, and BINARY or FIXED. It selects MIXED as the replacement. In a similar manner, an entry point to a procedure can be selected by means of dimensionality: DCL D GENERIC (D1 WHEN((*)), D2 WHEN((*,*))), A(2), B(3,5); CALL D(A); CALL D(B); The generic name D in the first CALL statement is replaced by the entry expression D1. This is because A and D1 have one dimension. The generic name D in the second CALL statement is replaced by the entry expression D2. ═══ Entry Invocation ═══ Description There are times when it may not be apparent whether an entry value itself is used, or if the value returned by the invocation is used. First, if the entry reference has an argument list, even if null, it is always invoked. For example, 'E(1)'. All of the following are for the no-argument cases: If the entry reference is used as an argument to a function that will not accept an argument of type ENTRY, the entry is invoked. For example: DCL DATE BUILTIN Z = SUBSTR (DATE,5,2); Date is invoked. The function is not invoked when the entry reference is any of the following:  Used as an argument to a function that will accept an ENTRY argument.  The right-hand side of an assignment to an entry variable.  In comparison to another entry reference (this comparison can be implied by a SELECT statement).  An argument passed to an entry parameter.  Used in a context that requires an entry variable.  Used as an argument to a generic name.  An argument enclosed in parentheses. In the following example, the value of the entry B is passed as the argument to A: CALL A((B)); In all remaining cases, the entry is invoked. ═══ RETURN Statement ═══ Description The RETURN statement terminates execution of the subroutine or function procedure and returns control to the invoking procedure. Syntax for terminating a procedure ──RETURN───┬────────────────┬───;────────── └─(─expression─)─┘ The RETURN statement with "expression" is used to terminate a procedure invoked by a function reference. The value returned to the function reference is the value of the expression specified, converted to conform to the attributes specified in the RETURNS option of the invoked procedure. Control is returned to the function reference. The RETURN statement without "expression" is used to terminate procedures invoked as subroutines; control is returned to the point following the CALL statement. If the RETURN statement terminates the main procedure, the FINISH condition is raised prior to block termination. ═══ OPTIONS Attribute ═══ Description The OPTIONS attribute specifies options that an entry point can have, similar to the OPTIONS option of the PROCEDURE statement and the ENTRY statement. The keywords can appear in any order. The OPTIONS attribute is required if the entry point is for a routine that is written in COBOL or assembler language. Example An example using the OPTIONS attribute is: DCL ASSEM OPTIONS(ASM RETCODE) ENTRY(FIXED DEC,*,*,FLOAT); CALL ASSEM(A,B,C,D); /* VALID */ CALL ASSEM(A,B); /* VALID */ CALL ASSEM; /* VALID */ CALL ASSEM(A,,,D); /* INVALID */ Syntax ────OPTIONS─(──┤ characteristic-list ├──)─── where characteristic-list is: │───┬──BYADDR──────────────────────────────────────┬───────────────────────┤ ├──BYVALUE─────────────────────────────────────┤ │ ┌─BYADDR──┐ │ ├──ASSEMBLER─┼─────────┼─┬───────┬─┬─────────┬─┤ │ └─BYVALUE─┘ └─INTER─┘ └─RETCODE─┘ │ │ │ └──COBOL──┬────────────────────────┬───────────┘ └─┤ additional options ├─┘ where additional-options is: ├───┬───────────────────────────┬───┬───────────────────────────────┬────── └─NOMAP─┬───────────────┬───┘ └─NOMAPIN───┬───────────────┬───┘ │ ┌─,─────┐ │ │ ┌─,─────┐ │ │  │ │ │  │ │ └─(───ARGi──┴─)─┘ └─(──ARGi───┴─)─┘ ─────┬──────────────────────────────┬────┬───────┬───┬──────────┬────┤ └─NOMAPOUT──┬──────────────┬───┘ └─INTER─┘ └─RETCODE──┘ │ ┌─,─────┐ │ │  │ │ └─(───ARGi─┴─)─┘ where i is an integer. ═══ 1.8. PL/I Statements ═══ Description You use identifiers, delimiters, operators, and constants to construct PL/I statements. Although your source program consists of a series of records or lines, the PL/I compiler and macro processor view the program as a continuous stream of characters. There are few restrictions on the format of PL/I statements, and programs can be written without considering special coding rules or checking to see that each statement begins in a specific column. A statement can begin in the next position after the previous statement, or it can be separated by blanks. Some statements begin with a percent symbol. These statements are either %directives that direct preprocessor and compiler operations (controlling listings) or are PL/I Macro Facility % statements. A % statement must appear on a line by itself. Usage Tips To improve readability and maintainability and to avoid unexpected results caused by loss of trailing blanks in source lines:  Do not split a language element across lines. If a string constant must be written on multiple lines, use the concatenation operator.  Do not write more than one statement on a line.  Do not split % directives across lines. List of Statements Please choose among the following PL/I statements and % statements. %ACTIVATE LOCATE ALLOCATE %NOPRINT BEGIN %NOTE CALL null CLOSE %null %DEACTIVATE ON DECLARE OPEN %DECLARE OTHERWISE (SELECT option) DEFAULT %PAGE DELAY %PRINT DELETE PROCEDURE DISPLAY %PROCEDURE DO %PROCESS %DO *PROCESS END PUT %END READ ENTRY RELEASE EXIT RETURN FETCH REVERT FORMAT REWRITE FREE SELECT GET SIGNAL GO TO %SKIP %GO TO STOP IF UNLOCK %IF WAIT %INCLUDE WHEN LEAVE WRITE ═══ %ACTIVATE Statement ═══ Description A %ACTIVATE preprocessor statement makes an identifier active and eligible for replacement. Any subsequent encounter of that identifier in the input text while the identifier is active will initiate replacement activity. The execution of a %ACTIVATE statement for an identifier that is already activated has no effect, except to change from RESCAN to NORESCAN, or vice versa. Abbreviation: %ACT Syntax ┌─,────────────────────────┐  ┌─RESCAN───┐ │ ───%──┬────────────┬──ACTIVATE───identifier──┼──────────┼─┴─;─── │ ┌────────┐ │ └─NORESCAN─┘ │  │ │ └───label:─┴─┘ ═══ ALLOCATE Statement ═══ Description The ALLOCATE statement allocates storage for either controlled or based variables. The syntax specification for ALLOCATE depends upon the variable type. Related Information  ALLOCATE statement for based variables  ALLOCATE statement for controlled variables ═══ BEGIN Statement ═══ Description The BEGIN statement, and corresponding END statement delimit a begin-block. Syntax ┌─ORDER────┐ ┌─NOCHARGRAPHIC─┐ ────BEGIN──┼──────────┼──┼───────────────┼─;──── └─REORDER──┘ └─CHARGRAPHIC───┘ ═══ CALL Statement ═══ Description The CALL statement invokes a procedure and transfers control to a specified entry point of the procedure.  The environment of the invoked procedure is established after evaluation of any expressions and before the procedure is invoked.  A CALL statement must not be used to invoke a procedure if control is to be returned to the invoking procedure by means of a RETURN(expression) statement.  If the procedure invoked by the CALL statement has been specified in a FETCH or RELEASE statement, and if it is not present in main storage, the CALL statement initiates dynamic loading of the procedure from auxiliary storage. Syntax ────CALL────┬─entry-reference──┬───┬─────────────────────────┬─────── ├──generic-name────┤ └─(──┬───────────────┬─)──┘ └──built-in-name───┘ │ ┌────,──────┐ │ │  │ │ └─┬─argument─┬┴─┘ └─*────────┘ ═══ %DEACTIVATE Statement ═══ Description The %DEACTIVATE statement makes an identifier inactive. 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. Deactivation of a deactivated identifier has no effect. Abbreviation: %DEACT Syntax ┌─,──────────┐  │ ───%──┬───────────┬───DEACTIVATE───identifier─┴──;──── │ ┌───────┐ │ │  │ │ └──label:─┴─┘ ═══ %DECLARE Statement ═══ Description The %DECLARE preprocessor statement establishes an identifier as a preprocessor name, specifies attributes of the name, and establishes the scope of the name. Factoring of attributes is allowed. Abbreviation: %DCL Related Information A %DECLARE statement behaves as a %ACTIVATE statement when it is encountered outside a preprocessor procedure, and activates, with the RESCAN option, all identifiers declared in the %DECLARE statement. Syntax ┌─,─────────────────────────┐  │ ───%──┬───────────┬──DECLARE────identifier──┬─FIXED─────┬─┴─;──── │ ┌───────┐ │ ├─CHARACTER─┤ │  │ │ ├─ENTRY─────┤ └──label:─┴─┘ └─BUILTIN───┘ ═══ DELAY Statement ═══ Description The DELAY statement suspends the execution of your program for at least the specified period of time. The maximum wait time is 23 hours and 59 minutes. Under CMS, the value rounds to the nearest whole second. Examples Consider the following uses of DELAY:  This statement suspends execution for 20 milliseconds (0.02 seconds) under MVS but has no effect under CMS: DELAY (20);  This statement suspends execution for one second under both MVS and CMS: DELAY (10**3);  This statement suspends execution for ten seconds under both MVS and CMS: DELAY (10*10**3); Syntax ───DELAY───(expression)───;──── ═══ DISPLAY Statement ═══ Description The DISPLAY statement displays a message on the user's terminal or on the system console. A response might be requested from the operator. DISPLAY can also be used with the REPLY option to allow operator communication with the program by typing in a code or message. The REPLY option will suspend program execution until the operator acknowledges the message. The character data for DISPLAY or REPLY can contain mixed character data. To display graphic data, you must use the CHAR built-in function to convert the graphic data to mixed-character data. If graphic data was entered in the REPLY, it is received as character data that contains mixed data. This can then be converted to graphic data using the GRAPHIC built-in function. Example DISPLAY ('END OF JOB'); displays the message: END OF JOB Syntax Type 1 ───DISPLAY──(expression)────;──────────────────────────────────────── Type 2 ───DISPLAY──(expression)────────────────────────────────────────────── ────┬─REPLY─(character-reference)─┬─────────────────────────────┬─┬─;─ │ └─EVENT─(event-reference)─────┘ │ │ │ └──EVENT─(event-reference)─┬───────────────────────────────┬──┘ └─REPLY─(character-reference)───┘ ═══ DO Statement ═══ Description The DO statement and its corresponding END statement, delimit a group of statements collectively called a do-group. Type 1- The Type 1 do-group specifies that the statements in the group are executed. It does not provide for the repetitive execution of the statements within the group. Types 2 and 3- Types 2 and 3 provide for the repetitive execution of the statements within the do-group. Related Information Select one of the following for more information about using Type 2 and Type 3 DO groups:  Using Type 2 with WHILE and UNTIL  Using Type 3 with one specification  Using Type 3 with two or more specifications  Using Type 3 with TO, BY, REPEAT Examples Using Type 2 and Type 3 DO groups Syntax Type 1: ────DO────;────────────────────────────────────────────────────────── Type 2: ────DO────┬──WHILE──(──exp4──)────┬─────────────────────┬──┬────;──── │ └──UNTIL──(──exp5──)──┘ │ └──UNTIL──(──exp5──)────┬─────────────────────┬──┘ └──WHILE──(──exp4──)──┘ Type 3: ┌───────,─────────┐  │ ────DO────reference──=─────specification──┴────;───────────────────── where specification is: ────exp1───┬────────────────────────────┬──────────────────────────── ├──TO──exp2──┬────────────┬──┤ │ └──BY──exp3──┘ │ ├──BY──exp3──┬────────────┬──┤ │ └──TO──exp2──┘ │ └──REPEAT──exp6──────────────┘ ─────┬─────────────────────────────────────────────────┬────────────── ├──WHILE──(──exp4──)──┬────────────────────────┬──┤ │ └─────UNTIL──(──exp5──)──┘ │ └──UNTIL──(──exp5──)──┬────────────────────────┬──┘ └─────WHILE──(──exp4──)──┘ Note: 1. expn is an abbreviation for expression n. 2. Condition prefixes are invalid on DO statements. ═══ Using Type 2 with WHILE and UNTIL ═══ If a Type 2 DO specification includes both the WHILE and UNTIL option, the DO statement provides for repetitive execution as defined by the following: LABEL: DO WHILE (exp4) UNTIL (exp5) statement-1 . . . statement-n END; NEXT: statement /* STATEMENT FOLLOWING THE DO GROUP */ The above is equivalent to the following expansion: LABEL: IF (exp4) THEN; ELSE GO TO NEXT; statement-1 . . . statement-n LABEL2: IF (exp5) THEN; ELSE GO TO LABEL; NEXT: statement /* STATEMENT FOLLOWING THE DO GROUP */ If the WHILE option is omitted, the IF statement at label LABEL is replaced by a NULL statement. Note that if the WHILE option is omitted, statements 1 through n are executed at least once. If the UNTIL option is omitted, the IF statement at label LABEL2 in the expansion is replaced by the statement GO TO LABEL. ═══ Using Type 3 with One Specification ═══ The following sequence of events summarizes the effect of executing a do-group with one specification: 1. If reference is specified and BY and TO options are also specified, exp1, exp2, and exp3 will be evaluated prior to the assignment of exp1 to the reference. Then the initial value is assigned to reference. For example: DO reference = exp1 TO exp2 BY exp3; For a variable that is not a pseudovariable, the above action of the do-group definition is equivalent to the following expansion: p=ADDR(variable); e1=exp1; e2=exp2; e3=exp3; v=e1; where v is a compiler-created based variable based on p, a compiler-created pointer. e1, e2, and e3 are compiler-created variables. 2. If the TO option is present, test the value of the control variable against the previously-evaluated expression (e2) in the TO option. 3. If the WHILE option is specified, evaluate the expression in the WHILE option. If it is false, leave the do-group. 4. Execute the statements in the do-group. 5. If the UNTIL option is specified, evaluate the expression in the UNTIL option. If it is true, leave the do-group. 6. If there is a reference: a) If the TO or BY option is specified, add the previously-evaluated exp3 (e3) to the reference. b) If the REPEAT option is specified, evaluate the exp6 and assign it to the reference. c) If the TO, BY, and REPEAT options are all absent, leave the do-group. d) Begin again with Step 2, above. ═══ Using Type 3 with Two or More Specifica tions ═══ If the DO statement contains more than one specification, the second expansion is analogous to the first expansion in every respect. However, the statements in the do-group are not actually duplicated in the program. A succeeding specification is executed only after the preceding specification has been terminated. Control can transfer into a do-group from outside the do-group only if the do-group is delimited by the DO statement in Type 1. Control can also return to a do-group from a procedure or ON-unit invoked from within that do-group. ═══ Using Type 3 with TO, BY, REPEAT ═══ The TO and BY options let you vary the reference in fixed positive or negative increments. In contrast, the REPEAT option, which is an alternative to the TO and BY options, lets you vary the control variable nonlinearly. The REPEAT option can also be used for nonarithmetic control variables (such as pointer). If the Type 3 DO specification includes the TO and BY options, the action of the do-group is defined by the following: LABEL: DO variable= exp1 TO exp2 BY exp3 WHILE (exp4) UNTIL(exp5); statement-1 . . . statement-m LABEL1: END; NEXT: statement For a variable that is not a pseudovariable, the above action of the do-group definition is equivalent to the following expansion. In this expansion, v is a compiler-created based variable based on p with the same attributes as variable; and e1, e2, and e3 are compiler-created variables: LABEL: e1=exp1; e2=exp2; e3=exp3; v=e1; LABEL2: IF (e3>=0)&(v>e2)│(e3<0)&(v Examples ═══ The DO statement can specify a group of statements to be executed in the THEN or ELSE clauses of an IF statement, or in the WHEN or OTHERWISE statements in a select-group. Select among the following DO statement examples:  IF..THEN..ELSE  Basic repetitions  Repetition using the reference as a subscript  Repetition with TO..BY  DO with WHILE, UNTIL  DO with REPEAT ═══ %DO Statement ═══ Description The %DO preprocessor statement, and its corresponding %END statement, delimit a preprocessor do-group, and can also specify repetitive execution of the do-group. Usage Rules  Preprocessor do-groups can be nested.  Control cannot transfer to a Type 3 preprocessor do-group, except by return from a preprocessor procedure invoked within the do-group.  Preprocessor statements, input text, and listing control statements can appear within a preprocessor do-group. The preprocessor statements are executed; input text is scanned for possible replacement activity. Syntax Type 1: ───%──┬───────────┬───DO──;───────────────────────────────────── │ ┌───────┐ │ │  │ │ └──label:─┴─┘ Type 3: ───%──┬───────────┬───DO──│ preprocessor do-specification │──;── │ ┌───────┐ │ │  │ │ └──label:─┴─┘ preprocessor do-specification: │──preprocessor-variable = preprocessor-exp1──────────────────────── ──┬───────────────────────────────────────────────┬────────────────│ ├─TO─preprocessor-exp2─┬──────────────────────┬─┤ │ └─BY─preprocessor-exp3─┘ │ └─BY─preprocessor-exp3─┬────────────────────────┤ └─TO─preprocessor-exp2───┘ ═══ END Statement ═══ Description The END statement ends one or more blocks and groups. Every block or group must have an END statement. Usage Notes  Execution of a block terminates when control reaches the END statement for the block. Although every block must have an END statement, this is not the only means of block termination.  If control reaches an END statement for a procedure, it is treated as a RETURN statement.  Normal termination of a program occurs when control reaches the END statement of the main procedure. Syntax ────END────┬───────────────────┬────;─────── └──statement-label──┘ ═══ %END Statement ═══ Description The %END preprocessor statement is used in conjunction with %DO or %PROCEDURE statements to delimit preprocessor do-groups or preprocessor procedures. Syntax ───%───┬────────────┬───END───┬───────┬──;──── │ ┌────────┐ │ └─label─┘ │  │ │ └───label:─┴─┘ ═══ ENTRY Statement ═══ Description The ENTRY statement specifies a secondary entry point of a procedure. When an ENTRY statement is encountered in sequential program flow, control passes around it. Usage Rules The ENTRY statement:  Must be internal to the procedure for which it defines a secondary entry point.  Cannot be used within a do-group that specifies repetitive execution or within an ON-unit. Syntax ┌─────────────────┐  │ ────entry constant:─┴───ENTRY──┬───────────────────┬─────────────────── │ ┌─,─────────┐ │ │  │ │ └─(───parameter─┴─)─┘ ───┬────────────────────────────┬─┬──────────────────────────────────┬── │ ┌───────────┐ │ └─OPTIONS─(─characteristic-list─)──┘ │  │ │ └─RETURNS─(───attribute─┴──)─┘ ┌─IRREDUCIBLE─┐ ───┼─────────────┼───;───────────────────────────────────────────────── └─REDUCIBLE───┘ ═══ EXIT Statement ═══ Description The EXIT statement immediately terminates the program. Prior to termination, the FINISH condition is raised. On normal return from the FINISH ON-unit, the program terminates. Syntax ──────EXIT──────;────────── ═══ FREE Statement ═══ Description Use the FREE statement to free storage allocated for variables. FREE statement syntax specification is different for controlled and based variables. Related information Please select one of the following for detailed information on the FREE statement:  FREE statement for controlled variables  FREE statement for based variables ═══ GO TO Statement ═══ Description The GO TO statement transfers control to the statement identified by the specified label reference. The GO TO statement is an unconditional branch. If a GO TO statement transfers control from within a block to a point not contained within that block, the block is terminated. If the transfer point is contained in a block that did not directly activate the block being terminated, all intervening blocks in the activation sequence are also terminated. When a GO TO statement specifies a label constant contained in a block that has more than one activation, control is transferred to the activation current when the GO TO is executed. If the destination of the GO TO is specified by a label variable, it can then be used as a switch by assigning label constants to the label variable. If the label variable is subscripted, then the switch can be controlled by varying the subscript. By using label variables or function references, quite complex switching can be effected. It is usually true, however, that simple control statements are the most efficient. Usage Rules A GO TO statement cannot transfer control:  To an inactive block or to another program. Detection of such an error is not guaranteed.  From outside a do-group to a statement inside a Type2 or a Type3 do-group, unless the GO TO terminates a procedure or ON-unit invoked from within the do-group.  To a FORMAT statement. Syntax ────┬──GO TO─┬────label─reference─────;────── └──GOTO──┘ ═══ %GO TO Statement ═══ Description The %GO TO preprocessor statement causes the preprocessor to continue its scan at the specified label. The label following the GO TO specifies the point to which the scan is transferred. It must be a label of a preprocessor statement, although it cannot be the label of a preprocessor procedure. A preprocessor GO TO statement appearing within a preprocessor procedure cannot transfer control to a point outside of that procedure. In other words, the label following GO TO must be contained within the procedure. Related Information The %INCLUDE preprocessor statement has certain restrictions regarding the use of %GO TO with included strings. Syntax ───%──┬────────────┬───GO──TO──label──────;───── │ ┌────────┐ │ │  │ │ └───label:─┴─┘ ═══ IF Statement (IF, THEN, ELSE) ═══ Description The IF statement evaluates an expression and controls the flow of execution according to the result of that evaluation. The IF statement thus provides a conditional branch. IF is a compound statement. The semicolon terminating the last unit also terminates the IF statement IF statements can be nested. That is, either unit can itself be an IF statement, or both can be. Since each ELSE is always associated with the innermost unmatched IF in the same block or do-group, an ELSE with a null statement might be required to specify a desired sequence of control. Usage Rules The following refers to the syntax below. If any bit in the string expression has the value '1'B, unit1 is executed and unit2, if present, is ignored. If all bits are '0'B, or the string is null, unit1 is ignored and unit2, if present, is executed. Examples  In the following example, if the comparison is true (if A is equal to B), the value of D is assigned to C, and the ELSE unit is not executed. If the comparison is false (A is not equal to B), the THEN unit is not executed, and the value of E is assigned to C. IF A = B THEN C = D; ELSE C = E;  Either the THEN unit or the ELSE unit can contain a statement that transfers control, either conditionally or unconditionally. If the THEN unit ends with a GO TO statement there is no need to specify an ELSE unit. For example: IF ALL(ARRAY1 = ARRAY2) THEN GO TO LABEL_1; next-statement If the expression is true, the GO TO statement of the THEN unit transfers control to LABEL_1. If the expression is false, the THEN unit is not executed and control passes to the next statement. Syntax ────IF──expression───THEN───unit1───┬───────────────┬── └──ELSE──unit2──┘ ═══ %IF Statement ═══ Description The %IF preprocessor statement controls the flow of the scan according to the bit value of a preprocessor expression. If any bit in preprocessor-expression has the value '1'B, then preprocessor-unit1 is executed and preprocessor-unit2, if present, is ignored. If all bits in preprocessor-expression are '0'B, then preprocessor-unit1 is ignored and preprocessor-unit2, if present, is executed. Scanning resumes immediately following the %IF statement, unless a %GO TO or preprocessor RETURN statement in one of the units causes the scan to resume elsewhere. Related Information %IF statements can be nested in the same manner used for nesting IF statements. Syntax ───%───┬─────────────┬───IF──preprocessor-expression──%──THEN──preprocessor-unit1─── │ ┌─────────┐ │ │  │ │ └───label:──┴─┘ ────────┬────────────────────────────┬────────────────────────────────────────────── └─%──ELSE─preprocessor-unit2─┘ ═══ %INCLUDE Statement ═══ Description The %INCLUDE statement is used to incorporate source code from an external library into the source program. %INCLUDE statements can be nested. In other words, %INCLUDEd text can contain %INCLUDE statements. Usage Rules Do not put other statements on the same line as the %INCLUDE statement. Example For example, if the source program contains the following statement: % INCLUDE PAYRL; the following example is generated: /* BEGIN %INCLUDE SYSLIB (PAYRL ) ***********/ Declare 1 payroll 2 Name, 3 Last character (30) varying, 3 First character (15) varying, 3 Middle character (3) varying, 2 Hours, 3 Regular fixed decimal (8,2), 3 Overtime fixed decimal (8,2) 2 Rate like hours; /* END %INCLUDE SYSLIB (PAYRL ) **********/ the structure declaration for PAYROLL is inserted into the source program. In this way, a central library of declarations can be used., Syntax ────%───INCLUDE───┬─member─────────────┬──;───── └─dataset─(─member─)─┘ ═══ LEAVE Statement ═══ Description The LEAVE statement transfers control from within a do-group to the statement following the END statement that delimits the group and terminates the do-group. Usage Rules  The LEAVE statement and the referenced or implied DO statement must not be in different blocks.  If the LEAVE statement is contained within a complex statement, control is transferred to the first statement following the termination of the complex statement.  LEAVE is valid only within a do-group. Examples  In the following example, the LEAVE statement transfers control to the next statement: DO . . . ; . . LEAVE; . . END; next statement;  In the following example, the statement LEAVE A transfers control to statement after group A: A: DO I = 1 TO 10; B: DO J = 1 TO 5; IF X(I,J)=0 THEN LEAVE; ELSE . . . ; END A; statement after group A; The LEAVE statement causes control to leave group B. If there is another iteration of group A, then it begins after control leaves group B. Syntax ───────LEAVE─────┬──────────────────┬────;──── │ │ └──label-constant──┘ ═══ %NOPRINT Statement ═══ Description The %NOPRINT preprocessor statement causes printing of the source and insource listings to be suspended until a %PRINT statement is encountered. Usage Rules The %NOPRINT statement must be on a line with no other statements. It must not appear within another statement. Syntax ────%NOPRINT────;────── ═══ %NOTE Statement ═══ Description The %NOTE preprocessor statement generates a preprocessor diagnostic message of specified text and severity. Related Information  Generated messages are placed together with other preprocessor messages. Whether or not a particular message is subsequently printed depends upon its severity level and the setting of the FLAG compiler option.  Generated messages of severity U cause immediate termination of preprocessing and compilation. Generated messages of severity S, E, or W might cause termination of compilation, depending upon the setting of the NOSYNTAX, and NOCOMPILE compiler options.  DBCS messages can be generated by using mixed data when the GRAPHIC compiler option is in effect. Syntax ────%───┬────────────┬──NOTE──(message─┬─────────┬─)───;──── │ ┌────────┐ │ └─,──code─┘ │  │ │ └───label:─┴─┘ ═══ null Statement ═══ Description The null statement does nothing and does not modify sequential statement execution. It is often used to denote null action for THEN and ELSE clauses and WHEN and OTHERWISE statements. Syntax ─────;─────── ═══ %null Statement ═══ Description The %null statement does nothing and does not modify sequential statement execution. Syntax ───%────;───── ═══ %PAGE Statement ═══ Description The statement following a %PAGE preprocessor statement in the program listing is printed on the first line (after the page heading) of the next page. This statement controls both the insource and the source listing. When paging takes place, %PAGE does not appear in the formatted listing. Usage Rules For paging to take place, the %PAGE statement must be on a line with no other statements. Syntax ───%──PAGE──;───── ═══ %PRINT Statement ═══ Description The %PRINT preprocessor statement causes printing of the source and insource listings to be resumed. %PRINT is in effect at the onset of both the insource and the source listings, provided that the relevant compile-time options are specified. Usage Rules The %PRINT statement must be on a line with no other statements. It must not appear within another statement. Syntax ───%──PRINT──;───── ═══ %PROCEDURE Statement ═══ Description The %PROCEDURE preprocessor statement is used in conjunction with a %END statement to delimit a preprocessor procedure. Abbreviation: %PROC Syntax ┌────────────┐  │ ───%────entry-name:─┴──PROCEDURE───┬───────────────────┬──┬───────────┬──── │ ┌─,─────────┐ │ └─STATEMENT─┘ │  │ │ └─(───parameter─┴─)─┘ ────RETURNS──(──┬─CHARACTER─┬──)───;─────────────────────────────────────── └─FIXED─────┘ ═══ %PROCESS, *PROCESS Statements ═══ Description The %PROCESS statement is used to override compiler options. The *PROCESS statement is a synonym for %PROCESS. Usage Rules  The % must be the first data position of a source record.  Any number of %PROCESS statements can be specified, but they all must appear before the first language element appears. Syntax ┌──────────────────────┐  │ ───%──PROCESS───┬──────────────────┬─┴── └─compiler option──┘ ═══ SELECT Group (SELECT, WHEN, OTHERWISE) ═══ Description A select-group provides a multi-way conditional branch. A select-group contains:  a SELECT statement,  one or more WHEN statements (optional),  an OTHERWISE statement (optional),  and an END statement. SELECT and its corresponding END statement delimit a group of statements collectively called a select-group. The expression in the SELECT statement is evaluated and its value is saved for later comparison. Usage Rules  If exp1 is omitted, each exp2 is evaluated and converted, if necessary, to a bit string. If any bit in the resulting string is '1'B, the unit of the associated WHEN statement is executed. If all bits are 0 or the string is null, the unit of the OTHERWISE statement is executed.  After the execution of a unit of a WHEN or OTHERWISE statement, control passes to the statement following the select-group, unless the normal flow of control is altered within the unit.  If exp1 is specified, each exp2 must be such that the comparison expression (exp1) = (exp2) has a scalar bit value.  Array operands cannot be used in exp1 nor exp2. Examples Using SELECT groups Syntax ──SELECT─┬────────────┬──;──┬────────────────────────────────┬─── └─(──exp1──)─┘ │ ┌────────────────────────────┐ │ │  ┌─,─────┐ │ │ │  │ │ │ └───WHEN──(───exp2──┴──)──unit─┴─┘ ─┬────────────────┬──END───;────────────────────────────────────── └─OTHERWISE─unit─┘ ═══ Using SELECT groups ═══ In the following examples, E, E1, etc., are expressions. When control reaches the SELECT statement, the expression E is evaluated and its value is saved. The expressions in the WHEN statement are then evaluated in turn (in the order in which they appear), and each value is compared to the value of E If a value is found that is equal to the value of E, the action following the corresponding WHEN statement is performed; no further WHEN statement expressions are evaluated. If none of the expressions in the WHEN statements are equal to the expression in the SELECT statement, the action specified after the OTHERWISE statement is executed. For example: SELECT (E); WHEN (E1,E2,E3) action-1; WHEN (E4,E5) action-2; OTHERWISE action-n; END; NL: next statement; An example of the omission of exp1 is: SELECT; WHEN (A>B) CALL BIGGER; WHEN (A=B) CALL SAME; OTHERWISE CALL SMALLER; END; If a select-group contains no WHEN statements, the action in the OTHERWISE statement is executed unconditionally. If the OTHERWISE statement is omitted, and the execution of the select-group does not result in the selection of a WHEN statement, the ERROR condition is raised. ═══ %SKIP Statement ═══ Description The specified number of lines following a %SKIP statement in the program listing are left blank. This statement controls both the insource and the source listing. When skipping takes place, %SKIP does not appear in the format listing. For skipping to take place, the %SKIP statement must be on a line with no other statements. Syntax ───%SKIP───┬───────────┬─────;───── │ │ └──(──n──)──┘ ═══ UNLOCK Statement (MVS) ═══ Description This is an MVS-only statement. The UNLOCK statement makes the specified locked record available to other MVS tasks. Syntax ───UNLOCK──FILE──(─file-reference─)───KEY──(─expression─)───;──── ═══ WAIT Statement ═══ Description The execution of a WAIT statement within an activation of a block retains control for that activation of that block within the WAIT statement until specified events have completed. Usage Rules  Control for a given block activation remains within the statement until, at possibly separate times during the execution of the statement, the completion value has been set complete for some or all of the event-variables on the list.  If an ON-unit entered due to the WAIT is terminated abnormally, control might not pass to the statement following the WAIT.  If an abnormal return is made from any ON-unit entered from a WAIT, the associated event-variable is set complete, the execution of the WAIT is terminated, and control passes to the point specified by the abnormal return. Syntax ┌─,───────────────┐  │ ───WAIT──(────event-reference─┴──)─┬─────────────────┬─;────── └─(─expression─)──┘ ═══ OPTIONS Option ═══ Description The OPTIONS option of the ENTRY statement and PROCEDURE statement specifies one or more processing characteristics. Usage Rules  OPTIONS can be specified only for an external procedure.  Only one procedure must have the OPTIONS(MAIN) designation. Syntax for OPTIONS with PROCEDURE Statement ───OPTIONS─(─│ characteristic-list │─)───────────────────────────── characteristic-list: ┌─BYADDR──┐ │───┬─┬────────────────────┬──┼─────────┼─────────┬─┬────────────┬────│ │ ├─FETCHABLE──────────┤ └─BYVALUE─┘ │ └─REENTRANT──┘ │ └─MAIN─┬───────────┬─┘ │ │ └─NOEXECOPS─┘ │ │ │ └─COBOL──┬───────────┬─┬───────────────────┬──┘ └─FETCHABLE─┘ └─│ nomap-options │─┘ nomap-options: │───┬─────────────────────────────┬─┬───────────────────────────────┬─ └─NOMAP──┬──────────────────┬─┘ └─NOMAPIN─┬───────────────────┬─┘ └─(parameter-list)─┘ └─(parameter-list)──┘ ───┬────────────────────────────────┬────────────────────────────────│ └─NOMAPOUT─┬──────────────────┬──┘ └─(parameter-list)─┘ Syntax for OPTIONS with ENTRY Statement ───OPTIONS─(─│ characteristic-list │─)───────────────────────────── characteristic-list: │───COBOL─┬───────────────────┬───────────────────────────────────────│ └─│ nomap-options │─┘ nomap-options: │───┬─────────────────────────────┬─┬───────────────────────────────┬─│ └─NOMAP──┬──────────────────┬─┘ └─NOMAPIN─┬───────────────────┬─┘ └─(parameter-list)─┘ └─(parameter-list)──┘ ───┬────────────────────────────────┬────────────────────────────────│ └─NOMAPOUT─┬──────────────────┬──┘ └─(parameter-list)─┘ ═══ STOP Statement ═══ Description The STOP statement immediately terminates the program. Prior to any termination activity, the FINISH condition is raised. On normal return from the FINISH ON-unit, the program terminates. Syntax ───────STOP────;──── ═══ 1.9. PL/I Compiler Options ═══ Description Most compiler options have a positive and a negative form. The negative form is the positive form with 'NO' added at the beginning (as in TEST and NOTEST). Some options have only a positive form (as in SYSTEM). You can change the IBM-supplied defaults when this product is installed. Therefore, the defaults listed for these options might not be the same as those chosen by your installation. You can override most defaults when you compile your PL/I program. There are three types of compiler options: 1. Simple pairs of keywords: a positive form that requests a facility, and an alternative negative form that inhibits that facility (for example, NEST and NONEST). 2. Keywords that allow you to provide a value-list that qualifies the option (for example, FLAG(W)). 3. A combination of 1 and 2 above (for example, NOCOMPILE(E)). Note: Under CMS, use only the abbreviated form of the compiler option if the option name is longer than eight characters. List of Compiler Options For detailed information about specific PL/I compiler options, select from the following list: AGGREGATE NOLIST ATTRIBUTES NOMACRO CMPAT NOMAP COMPILE NOMARGINI CONTROL NOMDECK DECK NONEST ESD NONUMBER FLAG NOOBJECT GONUMBER NOOFFSET GOSTMT NOOPTIMIZE GRAPHIC NOOPTIONS IMPRECISE NOSEQUENCE INCLUDE NOSOURCE INSOURCE NOSTMT INTERRUPT NOSTORAGE LANGLVL NOSYNTAX LINECOUNT NOT LIST NOTERMINAL LMESSAGE NOTEST MACRO NOXREF MAP NUMBER MARGINI OBJECT MARGINS OFFSET MDECK OPTIMIZE NAME OPTIONS NEST OR NOAGGREGATE SEQUENCE NOATTRIBUTES SIZE NOCOMPILE SMESSAGE NODECK SOURCE NOESD STMT NOGONUMBER STORAGE NOGOSTMT SYNTAX NOGRAPHIC SYSTEM NOIMPRECISE TERMINAL NOINCLUDE TEST NOINSOURCE XREF NOINTERRUPT Related Information  PLI command (TSO only)  PLIOPT command (CMS only) ═══ AGGREGATE/NOAGGGREGATE Compiler Options ═══ Description The AGGREGATE option specifies that the compiler will include a table in the compiler listing that gives the lengths of all arrays and major structures in the source program. NOAGGREGATE is the default. Abbreviations: AG│NAG Syntax ┌─NOAGGREGATE─┐ ────┴─AGGREGATE───┴─────── ═══ ATTRIBUTES/NOATTRIBUTES Compiler Options ═══ Description The ATTRIBUTES option specifies that the compiler will include in the compiler listing a table of source-program identifiers and their attributes. NOATTRIBUTES is the default. Abbreviations: A[(F│S)]│NA Related Information If you include both ATTRIBUTES and XREF, the two tables are combined. However, if the SHORT and FULL suboptions are in conflict, the last option specified will be used. For example, ATTRIBUTES(SHORT) XREF(FULL) results in FULL applying to the combined listing. Syntax ────┬──ATTRIBUTES──┬───────────────────┬──┬───── │ └──(─┬──FULL───┬─)──┘ │ │ └──SHORT──┘ │ └──NOATTRIBUTES───────────────────────┘ ═══ CMPAT Compiler Option ═══ Description The CMPAT option specifies whether object compatibility with OS PL/I Version 1 will be maintained for those programs sharing arrays, AREAs, and/or aggregates. CMPAT(V2) is the default. Abbreviation: CMP(V1│V2) Syntax ────CMPAT──(──┬──V1──┬──)────── └──V2──┘ ═══ COMPILE/NOCOMPILE Compiler Options ═══ Description The COMPILE option specifies that the compiler will compile the source program unless it detects an unrecoverable error during preprocessing or syntax checking. Whether the compiler continues or not depends on the severity of the error detected, as specified by the NOCOMPILE option in the list below. NOCOMPILE(S) is the default. Abbreviations: C│NC[(W│E│S)] Syntax ─┬──COMPILE──────────────────────┬── └──NOCOMPILE──┬───────────────┬─┘ └──(─┬──W──┬─)──┘ ├──E──┤ └──S──┘ ═══ CONTROL Compiler Option ═══ Description The CONTROL option specifies that any compile-time options for your installation are available for this compilation. However, you still need to specify the appropriate keywords to use the options. The CONTROL option must be specified with a password that is established for each installation. If you use an incorrect password, processing will be terminated. If you use the CONTROL option, it must be specified first in the list of options. Abbreviation: None Syntax ────CONTROL──(──'──password──'──)────── ═══ DECK/NODECK Compiler Options ═══ Description The DECK option specifies that the compiler will produce an object module in the form of 80-character records and store it in the data set defined by the SYSPUNCH DD statement. Columns 73-76 of each record contain a code to identify the object module. This code comprises the first 4 characters of the first label in the external procedure represented by the object module. Columns 77-80 contain a 4-digit decimal number: the first record is numbered 0001, the second 0002, and so on. NODECK is the default. Abbreviations: D│ND Syntax ────┬──DECK────┬────── └──NODECK──┘ ═══ ESD/NOESD Compiler Options ═══ Description The ESD option specifies that the external symbol dictionary (ESD) will be listed in the compiler listing. NOESD is the default. Abbreviations: None Syntax ────┬──ESD────┬───── └──NOESD──┘ ═══ FLAG Compiler Option ═══ Description The FLAG option specifies the minimum severity of error that requires a message listed in the compiler listing. For MVS, the default is FLAG(I). For TSO and CMS, the default is FLAG(W). Abbreviation: F[(I│W│E│S)] Syntax ────FLAG───┬─────────────────┬────── └──(──┬──I──┬──)──┘ ├──W──┤ ├──E──┤ └──S──┘ ═══ GONUMBER/NOGONUMBER Compiler Options ═══ Description The GONUMBER option specifies that the compiler will produce additional information that allows line numbers from the source program to be included in run-time messages. Alternatively, these line numbers can be derived by using:  The offset address, which is always included in run-time messages, and  The table produced by the OFFSET option (the NUMBER option must also apply). If you specify the GONUMBER option, it implies NUMBER, NOSTMT, and NOGOSTMT. If NUMBER applies, GONUMBER is forced by the ALL, STMT, and PATH suboptions of the TEST option. The OFFSET option is separate from these numbering options and must be specified if required. NOGONUMBER is the default. Abbreviations: GN│NGN Syntax ────┬──GONUMBER────┬────── └──NOGONUMBER──┘ ═══ GOSTMT/NOGOSTMT Compiler Options ═══ Description The GOSTMT option specifies that the compiler will produce additional information that allows statement numbers from the source program to be included in run-time messages. If you specify the GOSTMT option, it implies STMT, NONUMBER, and NOGONUMBER. If STMT applies, GOSTMT is forced by the ALL, STMT, and PATH suboptions of the TEST option. The OFFSET option is separate from these numbering options and must be specified if required. NOGOSTMT is the default. Abbreviations: GS│NGS Related Information These statement numbers can also be derived by using the offset address, which is always included in run-time messages and the table produced by the OFFSET option. Syntax ────┬──GOSTMT────┬────── └──NOGOSTMT──┘ ═══ GRAPHIC/NOGRAPHIC Compiler Options ═══ Description The GRAPHIC option specifies that the source program can contain double-byte characters. The hexadecimal codes 'OE' and 'OF' are treated as the shift-out and shift-in control codes, respectively, wherever they appear in the source program. This includes occurrences in comments and string constants. The GRAPHIC compiler option must be specified if the source program uses any of the following:  DBCS identifiers  Graphic string constants  Mixed string constants  Shift codes anywhere else in the source. NOGRAPHIC is the default. Abbreviations: GR│NGR Syntax ────┬──GRAPHIC────┬────── └──NOGRAPHIC──┘ ═══ IMPRECISE/NOIMPRECISE Compiler Options ═══ Description The IMPRECISE option specifies that the compiler will include extra text in the object module to localize imprecise interrupts when executing the program with an IBM System/370 Model 165 or 195. This extra text is generated for ON statements (to ensure that, if interrupts occur, the correct ON-units will be entered), for null statements, and for ENTRY statements. The correct line or statement numbers will not necessarily appear in run-time messages. If you need more accurate identification of the statement in error, insert null statements at suitable points in your program. NOIMPRECISE is the default. Abbreviations: IMP│NIMP Syntax ────┬──IMPRECISE────┬────── └──NOIMPRECISE──┘ ═══ INCLUDE/NOINCLUDE Compiler Options ═══ Description The INCLUDE compiler option specifies that the %INCLUDE statements are handled without using the full preprocessor facilities and incurring more overhead. This method is faster than using the preprocessor for programs that use the %INCLUDE statement but no other PL/I preprocessor statements. The INCLUDE option has no effect if preprocessor statements other than %INCLUDE are used in the program. In these cases, the MACRO option must be used. If you specify the MACRO option, it overrides the INCLUDE option. NOINCLUDE is the default. Abbreviations: INC│NINC Syntax ────┬──INCLUDE────┬────── └──NOINCLUDE──┘ ═══ INSOURCE/NOINSOURCE Compiler Options ═══ Description The INSOURCE option specifies that the compiler will include a listing of the source program before the PL/I macro preprocessor translates it. Thus, the INSOURCE listing contains preprocessor statements that do not appear in the SOURCE listing. This option is applicable only when the preprocessor is used; therefore, the MACRO option must also be specified. For MVS, the default is INSOURCE. For TSO and CMS, the default is NOINSOURCE. Abbreviations: IS│NIS Syntax ────┬──INSOURCE────┬────── └──NOINSOURCE──┘ ═══ INTERRUPT/NOINTERRUPT Compiler Options ═══ Description The INTERRUPT option determines the effect of attention interrupts when the compiled PL/I program runs under an interactive system. If specified on a batch system, INTERRUPT can cause an abend. NOINTERRUPT is the default. Abbreviations: INT│NINT Related Information If you require the attention interrupt capability purely for testing purposes, you do not need to use the INTERRUPT option. The TEST option provides this capability. Syntax ────┬──INTERRUPT────┬────── └──NOINTERRUPT──┘ ═══ LANGLVL Compiler Option ═══ Description The LANGLVL option specifies the level of the PL/I language supported, including whether pointers in expressions are to be supported. The default is LANGLVL(OS,NOSPROG). Abbreviation: None Syntax ────LANGLVL──(──┬──OS──┬────────────┬──┬──)─────── │ ├──,NOSPROG──┤ │ │ └──,SPROG────┘ │ ├──NOSPROG──┬───────┬──┤ │ └──,OS──┘ │ └──SPROG────┬───────┬──┘ └──,OS──┘ ═══ LINECOUNT Compiler Option ═══ Description The LINECOUNT option specifies the number of lines included in each page of the compiler listing, including heading lines and blank lines. The default is LINECOUNT(55). Abbreviation: LC(n) Syntax ────LINECOUNT──(──n──)─────── ═══ LIST/NOLIST Compiler Options ═══ Description The LIST option specifies that the compiler will include a listing of the object module (in a syntax similar to assembler language instructions) in the compiler listing. NOLIST is the default. Abbreviations: None Usage Rules  If both m and n are omitted, the compiler produces a listing of the whole program.  If the NUMBER option applies, m and n must be specified as line numbers.  If the STMT option applies, m and n must be statement numbers.  If you use LIST in conjunction with MAP, it increases the information generated by MAP. Related Information Under TSO, use the option LIST(m[n]) to direct a listing of particular statements to the terminal in either of the following ways:  Use the LIST option, with no statement numbers, within the TERMINAL option.  Use the PRINT(*) operand in the PLI command. Syntax ┌─NOLIST────────────────────────────┐ ─────┴─LIST───┬───────────────────────┬──┴────── └──(──m─┬───────┬─)─────┘ └──,─n──┘ ═══ LMESSAGE Compiler Option ═══ Description The LMESSAGE option produces messages in a long form. LMESSAGE is the default. Abbreviation: LMSG Related Information Use the SMESSAGE option to specify messages in a short form. Syntax ────┬──LMESSAGE──┬───── └──SMESSAGE──┘ ═══ MACRO/NOMACRO Compiler Options ═══ Description The MACRO option specifies that the source program will be processed by the macro preprocessor. MACRO overrides INCLUDE if you specify both. NOMACRO is the default. Abbreviations: M│NM Syntax ────┬──MACRO────┬─────── └──NOMACRO──┘ ═══ MAP/NOMAP Compiler Options ═══ Description The MAP option specifies that the compiler produces tables showing the organization of the static storage for the object module. These tables show how variables are mapped in the static internal control section and in DSA's, thus enabling STATIC INTERNAL and AUTOMATIC variables to be found in PLIDUMP. NOMAP is the default. Abbreviations: None Related Information If LIST is also specified, the MAP option produces tables showing constants, control blocks, and INITIAL variable values. LIST generates a listing of the object code in pseudo-assembler language format. Example If you want a complete MAP, but not a complete LIST, you can specify a single statement as an argument for LIST to minimize the size of the LIST. For example: %PROCESS MAP LIST(1); Syntax ────┬──MAP────┬─────── └──NOMAP──┘ ═══ MARGINI/NOMARGINI Compiler Options ═══ Description The MARGINI compiler option specifies that the compiler includes a specified character in the column preceding the left-hand margin, and also in the column following the right-hand margin of the compiler listings resulting from the INSOURCE and the SOURCE options. Any text in the source input which precedes the left-hand margin will be shifted left one column, and any text that follows the right-hand margin will be shifted right one column. Thus, text outside of the source margins can be easily detected. NOMARGINI is the default. Abbreviations: MI('c')│NMI Syntax ────┬──MARGINI──(──'──c──'──)───┬────── └──NOMARGINI────────────────┘ ═══ MARGINS Compiler Option ═══ Description The MARGINS option specifies which part of each compiler input record contains PL/I statements, and the position of the ANS control character that formats the listing, if the SOURCE and/or INSOURCE options apply. The compiler will not process data that is outside these limits (but it will include it in the source listings). The IBM-supplied default for fixed-length records is MARGINS(2,72). For variable-length and undefined-length records, the IBM-supplied default is MARGINS(10,100). This specifies that there is no printer control character. Abbreviation: MAR(m,n[,c]) Usage Rules  The PL/I source is extracted from the source input records so that the first data byte of a record immediately follows the last data byte of the previous record. For variable records, you must ensure that when you need a blank you explicitly insert it between the margins of records.  The MARGINS option allows you to override the default for the primary input in a program. The secondary input must have either the same margins as the primary input if it is the same type of record, or default margins if it is a different type. Syntax ────MARGINS──(──m─,─n──┬───────┬──)─────── └──,─c──┘ ═══ MDECK/NOMDECK Compiler Options ═══ Description The MDECK option specifies that the preprocessor produces a copy of its output on the file defined by the SYSPUNCH DD statement. The MDECK option allows you to retain the output from the preprocessor as a file of 80-column records. MDECK is ignored if NOMACRO is in effect. NOMDECK is the default. Abbreviations: MD│NMD Syntax ────┬──MDECK────┬────── └──NOMDECK──┘ ═══ NAME Compiler Option ═══ Description The NAME option specifies that the TEXT file created by the compiler will be given a specified external name. This allows you to create more than one TEXT file while doing batched compilation. It also allows you to produce TEXT files that can be included in a text library. You can also use the NAME option to cause the linkage editor to substitute a new load module for an existing load module with the same name in the library. NAME has no default. Abbreviation: N('name') Syntax ────NAME──(──'──name──'──)────── ═══ NEST/NONEST Compiler Options ═══ Description The NEST option specifies that the listing resulting from the SOURCE option indicates, for each statement, the block level and the do-group level. NONEST is the default. Abbreviations: None Syntax ────┬──NEST────┬────── └──NONEST──┘ ═══ NUMBER/NONUMBER Compiler Options ═══ Description The NUMBER option specifies that the numbers in the sequence fields in the source input records are used to derive the statement numbers in the listings resulting from the AGGREGATE, ATTRIBUTES, LIST, OFFSET, SOURCE, and XREF options. For MVS, NONUMBER is the default. For TSO and CMS, NUMBER is the default. Abbreviations: NUM│NNUM Related Information The position of the sequence field can be specified in the SEQUENCE option. Otherwise, the following default positions are assumed:  First eight columns for undefined-length or variable-length source input records.  Last eight columns for fixed-length source input records. If NONUMBER is specified, STMT and NOGONUMBER are implied. NUMBER is implied by NOSTMT or GONUMBER. Syntax ────┬──NUMBER────┬────── └──NONUMBER──┘ ═══ OBJECT/NOOBJECT Compiler Options ═══ Description The OBJECT option specifies that the compiler will create an object module and store it in a TEXT file (CMS) or in a data set defined by the DD statement with the name SYSLIN (MVS). OBJECT is the default. Abbreviations: OBJ│NOBJ Syntax ────┬──OBJECT────┬────── └──NOOBJECT──┘ ═══ NOT Compiler Option ═══ Description The NOT option specifies up to seven alternate symbols, any of which you can use as the logical NOT operator (к). The IBM-supplied default code point for the NOT symbol is X'5F'. This logical NOT sign might be recognized as a logical NOT symbol (к) or a caret symbol (^) on your keyboard. Abbreviation: None Examples  NOT('~') means that the tilde character, X'A1', will be recognized as the logical NOT operator, and the standard NOT symbol (к) X'5F', will not be recognized.  NOT('~к') means that either the tilde or the standard NOT symbol will be recognized as the logical NOT operator. Syntax ┌─────┐  │ ───NOT──(──'──char─┴─'─)──── ═══ OFFSET/NOOFFSET Compiler Options ═══ Description The OFFSET option specifies that the compiler prints a table of statement or line numbers for each procedure with their offset addresses relative to the primary entry point of the procedure. You can use this table to identify a statement from a run-time error message if the GONUMBER or GOSTMT options are not in effect. NOOFFSET is the default. Abbreviations: OF│NOF Related Information If GOSTMT applies, statement numbers, as well as offset addresses, will be included in run-time messages. If GONUMBER applies, line numbers, as well as offset addresses, will be included in run-time messages. Syntax ────┬──OFFSET────┬────── └──NOOFFSET──┘ ═══ OPTIMIZE/NOOPTIMIZE Compiler Options ═══ Description The OPTIMIZE option specifies the type of optimization required. NOOPTIMIZE is the default. Abbreviations: OPT(TIME│0│2)│NOPT Syntax ────┬──OPTIMIZE──(──┬──TIME──┬──)──┬────── │ ├──0─────┤ │ │ └──2─────┘ │ └──NOOPTIMIZE──────────────────┘ ═══ OPTIONS/NOOPTIONS Compiler Options ═══ Description The OPTIONS option specifies that the compiler listing will include a list showing the compile-time options to be used during this compilation. This list includes all those applied by default, those specified in the PARM parameter of an EXEC statement or in the invoking command (PLI or PLIOPT), and those specified in a %PROCESS statement. Under MVS, OPTIONS is the default. Under TSO and CMS, NOOPTIONS is the default. Abbreviations: OP│NOP Note: Under TSO, if the PRINT(*) operand of the PL/I command applies, the list of options prints at the terminal. Syntax ────┬──OPTIONS────┬────── └──NOOPTIONS──┘ ═══ OR Compiler Option ═══ Description The OR option specifies up to seven alternate symbols, any of which is interpreted as the logical OR operator (│). These symbols are also used as the concatenation operator, which is defined as two consecutive logical OR symbols. The default is OR('│'). Abbreviation: None Examples  OR('\') means that the backslash character, X'E0', will be recognized as the logical OR operator, and two consecutive backslashes will be recognized as the concatenation operator. The standard OR symbol X'4F' (│) will not be recognized as either operator.  OR('\│') means that either the backslash or the standard OR symbol will be recognized as the logical OR operator, and either symbol or both symbols may be used to form the concatenation operator. Syntax ┌─────┐  │ ────OR──(──'──char─┴─'─)──── ═══ SEQUENCE/NOSEQUENCE Compiler Options ═══ Description The SEQUENCE option defines the section of the input record from which the compiler takes the sequence numbers. These numbers are included in the source listings produced by the INSOURCE and SOURCE options. The IBM-supplied default for fixed-length records is SEQUENCE (73,80). For variable-length and undefined-length records, the default is SEQUENCE (1,8). Abbreviations: SEQ(m,n)│NSEQ Related Information Sequence numbers are used to calculate statement numbers if the NUMBER option is in effect. No attempt is made to sort the input lines or records into the specified sequence. The extent specified should not overlap with the source program (as specified by the MARGINS option). Syntax ────┬──SEQUENCE──(──m─,─n──)──┬────── └──NOSEQUENCE─────────────┘ ═══ SIZE Compiler Option ═══ Description The SIZE option can be used to limit the amount of main storage used by the compiler. This may be valuable, for example, when you invoke the compiler dynamically to ensure that space is left for other purposes. The IBM-supplied default is SIZE(MAX), which allows the compiler to use as much main storage in the region as it can. The negative forms of SIZE can be useful when a certain amount of space must be left free and the maximum size is unknown, or can vary because the job is run in regions of different sizes. Abbreviation: SZ([-]yyyyyyyy│[-]yyyyyK│MAX) Usage Rules  Under MVS: If you use the DBCSOS Ordering Product under MVS (a utility to sort DBCS characters), storage must be reserved for the operating system to load it. Specify SIZE(-n) to reserve sufficient storage, where n is at least 128K.  Under TSO: An additional 10K to 30K bytes must be allowed. The actual size required for TSO depends on which routines are placed in the link pack area (a common main storage pool available to all regions).  Under CMS: SIZE(MAX) should always be used in CMS unless it is essential to limit the space used. If a limit is set in the SIZE option, the value used will exceed that which is specified. Syntax ┌─MAX─────────────┐ ──SIZE──(──┼─┬───┬──yyyyyyyy─┼──)───── │ └─-─┘ │ └─┬───┬──yyyyyK───┘ └─-─┘ ═══ SMESSAGE Compiler Option ═══ Description The SMESSAGE option produces messages in shortened form. Abbreviation: SMSG Related Information Use LMESSAGE to produce messages in long form. LMESSAGE is the default. Syntax ────┬──LMESSAGE──┬────── └──SMESSAGE──┘ ═══ SOURCE/NOSOURCE Compiler Options ═══ Description The SOURCE option specifies that the compiler listing includes a listing of the source program. The source program listed is either the original source input or, if the MACRO option applies, the output from the preprocessor. For MVS, the default is SOURCE. For TSO and CMS, the default is NOSOURCE. Abbreviations: S│NS Syntax ────┬──SOURCE────┬────── └──NOSOURCE──┘ ═══ STMT/NOSTMT Compiler Options ═══ Description The STMT option specifies that statements in the source program are counted, and this statement number is used to identify statements in the compiler listings resulting from the AGGREGATE, ATTRIBUTES, LIST, OFFSET, SOURCE, and XREF options. STMT is implied by NONUMBER or GOSTMT. If NOSTMT is specified, NUMBER and NOGOSTMT are implied. For MVS, the default is STMT. For TSO and CMS, the default is NOSTMT. Abbreviations: None Syntax ────┬──STMT────┬────── └──NOSTMT──┘ ═══ STORAGE/NOSTORAGE Compiler Options ═══ Description The STORAGE option specifies that the compiler listing includes a table giving the main storage requirements for the object module. NOSTORAGE is the default. Abbreviations: STG│NSTG Syntax ────┬──STORAGE───┬────── └──NOSTORAGE─┘ ═══ SYNTAX/NOSYNTAX Compiler Options ═══ Description The SYNTAX option specifies that the compiler continues into syntax checking after preprocessing when the MACRO option is specified, unless it detects an unrecoverable error. Continuation depends on the severity of the error, as specified by the NOSYNTAX option. You can use this option to prevent wasted runs when debugging a PL/I program that uses the preprocessor. The default is NOSYNTAX(S). Abbreviations: SYN│NSYN[(W│E│S)] Related Information If the SOURCE option applies, the compiler will generate a source listing even if syntax checking is not performed. Syntax ────┬──SYNTAX─────────────────────────┬────── └──NOSYNTAX──┬─────────────────┬──┘ └──(──┬──W──┬──)──┘ ├──E──┤ └──S──┘ ═══ SYSTEM Compiler Option ═══ Description The SYSTEM option specifies the format used to pass parameters to the MAIN PL/I procedure, and indicates the host system under which the program will run. MVS, CMS, CMSTPL, CICS, IMS, and TSO are the subparameters recognized. This option allows a program compiled under one system to run under another. For example, a program compiled under CMS can run under MVS, and parameters are passed according to MVS conventions. For MVS and TSO, the default is SYSTEM(MVS). For CMS, the default is SYSTEM(CMS). Abbreviation: None Syntax ────SYSTEM───(──┬──CMS─────┬──)────── ├──CMSTPL──┤ ├──MVS─────┤ ├──TSO─────┤ ├──CICS────┤ └──IMS─────┘ ═══ TERMINAL/NOTERMINAL Compiler Option ═══ Description The TERMINAL option is applicable only in a conversational environment. It specifies that a subset of, or all of, the compiler listing produced during compilation prints at the terminal. If you specify TERMINAL without an argument, diagnostic and information messages are printed at the terminal. You can add an argument, which takes the form of an option list, to specify other parts of the compiler listing that are printed at the terminal. NOTERMINAL specifies that no portion of the compiler listing is output to the terminal. For MVS, the default is NOTERMINAL. For TSO and CMS, the default is TERMINAL. Abbreviations: TERM[(opt-list)]│NTERM Syntax ────┬──TERMINAL──┬──────────────────┬──┬─────── │ └──(──opt─list──)──┘ │ └──NOTERMINAL──────────────────────┘ ═══ TEST/NOTEST Compiler Options ═══ Description Use the TEST option to specify the level of testing capability that the compiler generates as part of the object code. It allows you to control the location of test hooks and to control whether or not the symbol table will be generated. Because the TEST option can increase the size of the object code and can affect performance, you might want to limit the number and placement of hooks. Any TEST option other than NOTEST and TEST(NONE,NOSYM) will automatically provide the attention interrupt capability for program testing purposes. NOTEST(NONE,SYM) is the default. Abbreviations: None Related Information  The TEST option can imply GONUMBER or GOSTMT, depending on whether NUMBER or STMT is in effect.  If the program has an ATTENTION ON-unit that you want invoked, you must compile the program with either of the following: - The INTERRUPT option, or - A TEST option other than NOTEST or TEST(NONE,NOSYM). Syntax ────┬──TEST──┬────────────────────────────────────────────┬──┬─────── │ └──(──┬──┬──BLOCK──┬──┬─────────────┬──┬──)──┘ │ │ │ ├──STMT───┤ └─,─┬──SYM────┤ │ │ │ │ ├──PATH───┤ └──NOSYM──┘ │ │ │ │ ├──ALL────┤ │ │ │ │ └──NONE───┘ │ │ │ │ │ │ │ └──┬──SYM────┬──┬─────────────┬──┘ │ │ └──NOSYM──┘ └─,─┬──BLOCK──┤ │ │ ├──STMT───┤ │ │ ├──PATH───┤ │ │ ├──ALL────┤ │ │ └──NONE───┘ │ └──NOTEST────────────────────────────────────────────────┘ ═══ XREF/NOXREF Compiler Options ═══ Description The XREF option specifies that the compiler will include in the compiler listing a cross-reference table of names used in the program together with the numbers of the statements in which they are declared or referenced. The only exception is that label references on END statements are not included. For example, assume that statement number 20 in the procedure PROC1 is END PROC1;. In this situation, statement number 20 will not appear in the cross-reference listing for PROC1. NOXREF is the default. Abbreviations: X[(F│S)]│NX Related Information If both XREF and ATTRIBUTES are specified, the two listings are combined. If there is a conflict between SHORT and FULL, the usage is determined by the last option specified. For example, ATTRIBUTES(SHORT) XREF(FULL) results in FULL applying to the combined listing. Syntax ────┬──XREF──┬──────────────────────┬──┬───── │ └──(───┬──FULL───┬──)──┘ │ │ └──SHORT──┘ │ └──NOXREF──────────────────────────┘ ═══ PLI Command (TSO Only) ═══ Description Use the PLI command to invoke the compiler under TSO. The command processor for the PLI command is known as the PL/I prompter. When you enter the PLI command, the prompter checks the operands and allocates the data sets required by the compiler. Then, it passes control to the compiler and displays a confirmation message. Usage Rules If you use an unqualified data set name (for example, CALTROP) the system generates a name for the object module data set. It takes the unqualified name of the source data set and adds your user-identification and the descriptive qualifier "OBJ". For example, if a user with the identification WSMITH entered the following command: PLI MYSOURCE the object module would be written onto the data set named WSMITH.MYSOURCE.OBJ. Examples Select one of the following examples of the PLI command:  Simplest form of PLI  PLI when source has unconventional name  Choosing your own object module name Related Information Allocating data sets for compilation Syntax ───PLI──data-set-name──option-list───┬────────────────────────────────────────┬─── ├─PRINT─┬─────────────────────┬──────────┤ │ ├─(*)─────────────────┤ │ │ └─(dsname─┬────────┬─)┘ │ │ └,─┬────┬┘ │ │ ├─n──┤ │ │ └─,m─┘ │ ├─SYSPRINT─┬────────────────────────────┬┤ │ └─(sysout-class─┬────────┬─)─┘│ │ └,─┬────┬┘ │ │ ├─n──┤ │ │ └─,m ┘ │ ├─NOPRINT────────────────────────────────┤ └─LIB(dslist)────────────────────────────┘ ═══ Allocating Data Sets for Compilation ═══ Description The compiler requires the use of a number of data sets in order to process a PL/I program. The following data sets are always required by the compiler:  The data set holding the PL/I program  A data set for the compiler listing. Up to six more data sets can be required, depending on which compiler options have been specified. These data sets must be allocated before the compiler can use them. If you use the PLI command, you invoke the compiler via the prompter, and the prompter allocates the necessary data sets. If you invoke the compiler without the prompter, you must allocate the necessary data sets yourself. Usage Rules When the prompter allocates compiler data sets, it uses ddnames generated by TSO rather than the ddnames that are used in batch mode. If the compiler is invoked via the prompter, you cannot refer to the data sets by these names. To control the allocation of compiler data sets, you need to use the appropriate operand of the PLI command. For example, to allocate the standard output file (ddname SYSPRINT in batch mode) to the terminal, you should use the PRINT(*) operand of the PLI command. You cannot make the allocation by using the ALLOCATE command with FILE(SYSPRINT) and DATASET(*) operands. When the prompter is not invoked, the batch-mode ddnames are recognized as referring to the compiler data sets. Related Information Compiler data sets ═══ Compiler Data Sets ═══ Description The following table summarizes compiler usage of data sets. Notes are designated by numbers in paretheses and are explained following the table. ┌────────────────────┬────────────────────────┬───────────────────┬──────────────┬─────────────────┬──────────────────┬────────────────────┐ │ DATA SET (AND │ WHEN REQUIRED │ WHERE TO │ DESCRIPTIVE │ ALLOCATED │ PARAMETERS │ PARAMETERS │ │ BATCH-MODE │ │ SPECIFY DATA │ QUALIFIER │ BY │ USED BY │ USED BY │ │ DDNAME) │ │ SET IN PLI │ │ │ PROMPTER │ PROMPTER │ │ │ │ COMMAND │ │ │ SPACE= (1,2) │ DISP= (1,3) │ ├────────────────────┼────────────────────────┼───────────────────┼──────────────┼─────────────────┼──────────────────┼────────────────────┤ │ Primary input │ ALWAYS │ 1st operand │ PLI │ Prompter │ --- (4) │ SHR │ │ (SYSCIN or │ │ │ │ │ │ │ │ SYSIN) │ │ │ │ │ │ │ ├────────────────────┼────────────────────────┼───────────────────┼──────────────┼─────────────────┼──────────────────┼────────────────────┤ │ Temporary work │ When insufficient │ Cannot │ --- │ Prompter │ (1024,(60,60)) │ (NEW, DELETE) │ │ data set (SYSUT1) │ main storage │ specify │ │ │ │ │ ├────────────────────┼────────────────────────┼───────────────────┼──────────────┼─────────────────┼──────────────────┼────────────────────┤ │ Compiler listing │ Always │ Argument of │ LIST │ Prompter │ (629,(n,m)) │ (OLD, KEEP) or │ │ (SYSPRINT) │ │ PRINT │ │ │ │ (NEW, CATLG) (5) │ │ │ │ operand │ │ │ │ │ ├────────────────────┼────────────────────────┼───────────────────┼──────────────┼─────────────────┼──────────────────┼────────────────────┤ │ Object module │ When OBJECT │ 1st argument of │ OBJ │ Prompter, │ (400,(50,50)) │ (OLD, KEEP) or │ │ (SYSLIN) │ option applies │ OBJECT │ │ when │ │ (NEW, CATLG) │ │ │ │ operand │ │ required (6) │ │ │ ├────────────────────┼────────────────────────┼───────────────────┼──────────────┼─────────────────┼──────────────────┼────────────────────┤ │ Object module or │ When MACRO │ Argument of │ DECK │ Prompter, │ (400,(50,50)) │ (OLD, KEEP) or │ │ preprocessor │ and MDECK │ MDECK, │ │ when │ │ (NEW, CATLG) │ │ output in card │ options apply │ DECK │ │ required (6) │ │ │ │ format │ │ operands │ │ │ │ │ │ (SYSPUNCH) │ │ │ │ │ │ │ ├────────────────────┼────────────────────────┼───────────────────┼──────────────┼─────────────────┼──────────────────┼────────────────────┤ │ Secondary input to │ When LIB │ Arguments │ --- │ Prompter, │ --- (7) │ SHR │ │ preprocessor │ operand is │ of LIB │ │ when │ │ │ │ (SYSLIB) (7) │ used │ operand │ │ required │ │ │ └────────────────────┴────────────────────────┴───────────────────┴──────────────┴─────────────────┴──────────────────┴────────────────────┘ Notes: (1) - Unit is determined by entry in User Attribute Data Set. (2) - These space allocations apply only if the data set is new. The first argument of the SPACE parameter established the block size. For the SYSUT1, SYSPRINT, SYSLIN, and SYSPUNCH data sets, the record format, record length, and number of buffers are established by the compiler when it opens the data sets. (3) - The prompter first tries to allocate the SYSPRINT, SYSLIN, and SYSPUNCH data sets with DISP=(OLD, KEEP). This will cause any existing data set (or partitioned data set member) with the same name to be replaced with the new one. If the data set name cannot be found in the system catalog, the data set is allocated with DISP=(NEW,CATLG). (4) - The data set already exists; therefore, SPACE (and also UNIT) are already established. (5) - DISP parameter used only if PRINT(dsname) operand applies. Otherwise, prompter supplies the following parameters:  TERM=TS if PRINT(*) operand applies  DUMMY if NOPRINT operand applies  SYSOUT if SYSPRINT operand applies (6) - Except when the associated option has been specified by means of a %PROCESS statement. In this case, the data set(s) must be allocated by the user. (7) - If any ddnames are specified in %INCLUDE statements, allocate the data sets with the ALLOCATE statement. ═══ PLIOPT Command (CMS Only) ═══ Description The PLIOPT command compiles a PL/I program or a series of PL/I programs into machine language object code. If the file type is missing, the file type defaults to PLIOPT or PLI. Syntax ───PLIOPT────┬─────────┬──── ├─PRINT───┤ ├─DISK────┤ ├─TYPE────┤ ├─NOPRINT─┤ └─OBJECT──┘ ═══ 1.10. Reading PL/I Syntax Diagrams ═══ Throughout the online help, syntax is described using the structure defined below.  Read the syntax diagrams from left to right, from top to bottom, following the path of the line. The ─── symbol indicates the beginning of a statement. The ─── symbol indicates that the statement syntax is continued on the next line. The ─── symbol indicates that a statement is continued from the previous line. The ─── symbol indicates the end of a statement. Diagrams of syntactical units other than complete statements start with the ─── symbol and end with the ─── symbol.  Required items appear on the horizontal line (the main path). ───STATEMENT───────required_item──────────────────────  Optional items appear below the main path. ───STATEMENT─────┬───────────────┬──────────────────── └─optional_item─┘  If you can choose from two or more items, they appear vertically, in a stack. If you must choose one of the items, one item of the stack appears on the main path. ───STATEMENT───┬──required_choice1──┬─────────────── └──required_choice2──┘ If choosing one of the items is optional, the entire stack appears below the main path. ───STATEMENT───┬────────────────────┬─────────────── ├──optional_choice1──┤ └──optional_choice2──┘  An arrow returning to the left above the main line indicates an item that can be repeated. ┌──────────────────┐  │ ───STATEMENT─────repeatable_item──┴───────────────── A repeat arrow above a stack indicates that you can repeat the items in the stack.  Keywords appear in uppercase (for example, "PARM1"). They must be spelled exactly as shown. Variables appear in all lowercase letters (for example, "parmx"). They represent user-supplied names or values.  If punctuation marks, parentheses, arithmetic operators, or such symbols are shown, you must enter them as part of the syntax.  Defaults appear above the main path unless otherwise noted in the description of the item. ═══ Help Is Not Available ═══ Online help is not available for this OS/2 keyword. Help for OS/2 language is not a part of the CODE/370 product. ═══ ═══ To allow a source program to deal primarily with the logical aspects of data rather than with its physical organization in a data set, PL/I employs models of data sets, called files. A file can be associated with different data sets at different times during the execution of a program. ═══ ═══ If an OPEN statement is not executed for a file, the file is opened implicitly before the first data transmission statement for that file is executed. In this case, the file opening uses information about the file as specified in a DECLARE statement (or defaults derived from the transmission statement). Similarly, if a file has not been closed before a program ends, the file is closed during program termination. When a file for stream input, sequential input, or sequential update is opened, the associated data set is positioned at the first record. When a BACKWARDS file is opened, the associated data set is positioned at the last record. ═══ ═══ FILE (file reference) specifies the name of the file that is associated with a data set. ═══ ═══ The following example illustrates implicit opening: DECLARE MASTER FILE KEYED INTERNAL; READ FILE (MASTER) INTO (MASTER_RECORD) KEYTO(MASTER_KEY); Attributes after merge (due to the implicit opening caused by execution of the READ statement) are KEYED, INTERNAL, RECORD, and INPUT. No additional attributes are implied. Attributes after default application are KEYED, INTERNAL, RECORD, INPUT, and SEQUENTIAL. ═══ ═══ FILE (file-reference) specifies the name of the file that is to be dissociated from the data set. ═══ ═══ ENVIRONMENT can be used to control the disposition of magnetic tapes. ═══ ═══ based-variable must be an unsubscripted level-1 based variable. ═══ ═══ data-list identifies a list of data items to be transmitted. ═══ ═══ format-list consists of either data format items, control format items, or the remote format item. ═══ ═══ Interleaved subscripts cannot appear in qualified names in the stream. For example, assume that Y is declared as follows: DECLARE 1 Y(5,5),2 A(10),3 B, 3 C, 3 D; An element name has to appear in the stream as follows: Y.A.B(2,3,8)= 8.72 ═══ ═══ format-list is the list of format items and is associated with a data list. ═══ ═══ field-width specifies the number of character positions in the data stream that contain (or will contain) the string. It is an expression that is evaluated and converted to an integer value, which must be nonnegative, each time the format item is used. ═══ ═══ field-width specifies the number of data-stream character positions that contain (or will contain) the bit string. It is an expression that is evaluated and converted to an integer value, which must be nonnegative, each time the format item is used. ═══ ═══ real-format-item is specified by one of the F-, E-, or P-format items. The P-format item must describe numeric character data. ═══ ═══ field-width, fractional-digits, significant-digits expressions, which are evaluated and converted to integer values each time the format item is used. Field-width: specifies the total number of characters in the field. Fractional-digits: specifies the number of digits in the mantissa that follow the decimal point. Significant-digits: specifies the number of digits that must appear in the mantissa. ═══ ═══ field-width, fractional-digits, scaling-factor expressions are evaluated and converted to integer values each time the format item is used. The evaluated field-width and fractional-digits must both be nonnegative. ═══ ═══ field-width specifies the number of 2-byte positions in the data stream that contain (or will contain) the graphic string. It is an expression that is evaluated and converted to an integer value, which must be nonnegative, each time the format item is used. End of record must not occur between the 2 bytes of a graphic. ═══ ═══ On input, the specified number of graphics is obtained from the data stream and assigned, with any necessary truncation or padding, to the data list item. If the input file has the GRAPHIC option of the ENVIRONMENT attribute, the specified number of graphics must be enclosed in shift codes. The field-width is always required on input, and if it is zero, a null string is obtained. ═══ ═══ On output, the data list item is truncated or extended (with the padding graphic) on the right to the specified field-width before being placed into the data stream. No enclosing graphic quotation marks are inserted, nor is the identifying graphic G inserted. If the field-width is zero, no graphics are placed into the data stream. If the field-width is not specified, it defaults to be equal to the graphic-string length of the data list item. If the output file has the GRAPHIC option of the ENVIRONMENT attribute, the specified number of graphics is enclosed in shift codes. ═══ ═══ character-position specifies an expression which is evaluated and converted to an integer value, which must be nonnegative, each time the format item is used. ═══ ═══ line-number can be represented by an expression, which is evaluated and converted to an integer value, which must be nonnegative, each time the format item is used. ═══ ═══ relative-line specifies an expression, which is evaluated and converted to an integer value, "n", which must be nonnegative and less than 32,768, each time the format item is used. It must be greater than zero for non-PRINT files. If it is zero, or if it is omitted, the default is 1. ═══ ═══ field-width is an expression that is evaluated and converted to an integer value, which must be nonnegative, each time the format item is used. The integer value specifies the number of characters before the next field of the data stream, relative to the current position in the stream. ═══ ═══ label-reference has as its value the name written as the label prefix of a FORMAT statement. ═══ ═══ Consider the following statement that uses edit-directed GET: GET EDIT (NAME, DATA, SALARY)(A(N), X(2), A(6), F(6,2)); This example specifies that the first N characters in the stream are treated as a character string and assigned to NAME. The next 2 characters are skipped. The next 6 are assigned to DATA in character format. The next 6 characters are considered an optionally signed decimal fixed-point constant and assigned to SALARY. ═══ ═══ Consider the following: PUT EDIT('INVENTORY='║INUM,INVCODE)(A,F(5)); This example specifies that the character string 'INVENTORY=' is concatenated with the value of INUM and placed in the stream in a field whose width is the length of the resultant string. Then the value of INVCODE is converted to character, as described by the F-format item, and placed in the stream right-adjusted in a field with a width of 5 characters (leading characters can be blanks). ═══ ═══ label has as its value the name written as the label prefix of a statement. ═══ ═══ In the example: DECLARE TOTAL FIXED(4,2); PUT EDIT (TOTAL) (F(6,2)); The PUT statement specifies that the value of TOTAL is converted to the character representation of a fixed-point number and written into the output file SYSPRINT. A decimal point is inserted before the last two numeric characters, and the number is right-adjusted in a field of six characters. Leading zeros are changed to blanks (except for a zero immediately to the left of the point), and, if necessary, a minus sign is placed to the left of the first numeric character. ═══ ═══ If the items are separated by a comma, the first character scanned when the next GET statement is executed is the one immediately following the comma: Xbb,bbbXX  If the record terminates with a comma, the succeeding record is not read in until the next GET statement requires it. ═══ ═══ DBCS note: Double quotation marks (a pair of SBCS or a pair of DBCS) are treated as single quotation marks only if the enclosing quotation marks are from the same character set. Single quotation marks are treated as single when the enclosing quotes are not from the same character set. ═══ ═══ If the items are separated by blanks only, the first item scanned is the next nonblank character: XbbbbXXX  unless the end of the record is encountered, in which case the file is positioned at the end of the record: Xbb-bbXXX  However, if the end of the record immediately follows a nonblank character (other than a comma), and the following record begins with blanks, the file is positioned at the first nonblank character in the following record: X-bbbXXX  ═══ ═══ Character strings are written out as follows:  If the file does not have the attribute PRINT, enclosing quotation marks are supplied, and contained single quotation marks or apostrophes are replaced by two quotation marks. The field width is the current length of the string plus the number of added quotation marks.  If the file has the attribute PRINT, enclosing quotation marks are not supplied, and contained single quotation marks or apostrophes are unmodified. The field width is the current length of the string. ═══ ═══ Mixed strings are enclosed in SBCS quotation marks and followed by the letter M. Contained SBCS quotes are replaced by two quotes. ═══ ═══ Graphic strings are written out as follows:  If the file does not have the attribute PRINT, enclosing shift codes, SBCS quotation marks, and the letter G are supplied. Since the enclosing quotation marks are SBCS, contained graphic quotation marks are represented by a single graphic quotation mark (unmodified).  If the file has the attribute PRINT, only enclosing shift codes are supplied. Graphic quotation marks are represented by a single graphic quotation mark (unmodified). ═══ ═══ It is an error to:  Associate an active event variable with another event  Modify the completion value of an active event variable by event variable assignment or by use of the COMPLETION pseudovariable  Assign a value to an active event variable (including an event variable in an array, structure, or area) by means of an input/output statement. ═══ ═══ The values of the event variable can be set by one of the following means:  By using the COMPLETION pseudovariable to set the completion value  By using the STATUS pseudovariable to set the status value  By an event variable assignment  By a statement with the EVENT option  By a WAIT statement for an event variable associated with an input/output event or a DISPLAY statement  By closing a file on which an input/output operation with an event option is in progress ═══ ═══ An imaginary value is written as a real constant of any type followed by the letter "I". Examples are: 27I 3.968E10I 11011.01BI Each of the above has a real part of zero. A complex value with a non-zero real part is represented as the signed sum/difference of a real constant and an imaginary constant. For example: 38 + 27I Given two complex numbers, y and z: y = COMPLEX(a,b) z = COMPLEX(c,d) x = y/z is calculated by: REAL(x) = (a*c + b*d)/(c**2 + d**2) IMAG(x) = (b*c - a*d)/(c**2 + d**2) x = y*z is calculated by: REAL(x) = a*c - b*d IMAG(x) = b*c + a*d Computational conditions can be raised during these conditions. ═══ ═══ number-of-digits is an integer that specifies how many digits the value can have. For fixed-point items, the integer is the number of significant digits. For floating-point items, the integer is the number of significant digits to be maintained, excluding the exponent. ═══ ═══ scaling-factor (fixed-point only) specifies an optionally-signed integer. If no scaling factor is specified, the default is 0. The precision attribute specification is often represented as (p,q), where "p" represents the "number-of-digits" and "q" represents the "scaling-factor". A negative scaling factor (-q) specifies an integer, with the point assumed to be located q places to the right of the rightmost actual digit. A positive scaling factor (q) that is larger than the number of digits specifies a fraction, with the point assumed to be located q places to the left of the rightmost actual digit. In either case, intervening zeroes are assumed, but they are not stored; only the specified number of digits is actually stored. ═══ ═══ Binary fixed-point data items have precision (p,q) where p is the total number of digits, and q is the number of binary digits to the right of the binary point. Examples are: CONSTANT PRECISION 10110B (5,0) 11111B (5,0) 101B (3,0) 1011.111B (7,3) Use the BINARY and FIXED attributes in declaring binary fixed-point variables. To declare a binary fixed-point variable X of 20 digits, 2 of which are fractional, you could use the declaration: DECLARE X FACTOR BINARY FIXED (20,2); FACTOR is declared a variable that can represent binary fixed-point data items of 20 digits, two of which are fractional. ═══ ═══ Binary floating-point data items have precision (p) where p is the number of binary digits of the mantissa. Examples are: CONSTANT PRECISION 101101E5B (6) 101.101E2B (6) 11101E-28B (5) 11.01E+42B (4) Use the BINARY and FLOAT attributes in declaring binary floating-point data items. To declare a floating-point binary variable X with a precision of 16 binary digits, you might use the declaration: DECLARE X BINARY FLOAT (16); S represents binary floating-point data items with a precision of 16 binary digits. ═══ ═══ Decimal fixed-point data items have the precision (p,q) where p is the total number of digits in the value and q is the number of digits specified to the right of the decimal point. Examples are: CONSTANT PRECISION 3.1416 (5,4) 455.3 (4,1) 732 (3,0) 003 (3,0) 5280 (4,0) .0012 (4,4) Use the DECIMAL and FIXED data attributes for declaring decimal fixed-point variables. For example: DECLARE X FIXED DECIMAL (5,4); specifies that X represents a decimal fixed-point item of 5 digits, in the range from -9.9999 to 9.9999. ═══ ═══ Decimal floating-point constants have a precision (p) where p is the number of digits in the mantissa. Examples are: CONSTANT PRECISION 15E-23 (2) 15E23 (2) 4E-3 (1) 1.96E+07 (3) 438E0 (3) 3141593E-6 (7) .003141593E3 (9) Use the DECIMAL and FLOAT attributes to declare decimal floating-point data. For example, to declare X a floating-point decimal with at least 5 decimal digits, you could use the declaration: DECLARE X DECIMAL FLOAT (5); ═══ ═══ A picture repetition factor specifies the number of repetitions of the picture character immediately following the repetition factor. A picture repetition factor is an integer, n, enclosed in parentheses. No blanks are allowed in the parentheses. If n is 0, the picture character is ignored. For example, the following two picture specifications have the same result: '999V99' '(3)9V(2)9' ═══ ═══ Examples of picture characters are the following: DECLARE PART# PICTURE 'AAA99X'; PUT EDIT (PART#) (P'AAA99X'); The following values are valid for PART#: 'ABC12M' 'bbb09/' 'XYZb13' ═══ ═══ The point, comma or slash can be used in conjunction with the V to cause insertion of the point (or comma or slash) in the position that delimits the end of the integer portion in and the beginning of the fractional portion of a fixed-point or floating-point number, as might be desired in printing, since the V does not cause printing of a point. The point must immediately precede or immediately follow the V. If the point precedes the V, it is inserted only if an unsuppressed digit appears to the left of the V, even if all fractional digits are significant. If the point immediately follows the V, it is suppressed if all digits to the right of the V are suppressed, but it appears if there are any unsuppressed fractional digits (along with any intervening zeros). ═══ ═══ The static use specifies that a sign, currency symbol, or blank appears in the associated position. An "S", "+" or "-" used as a static character can appear:  to the right or left of all digits in the mantissa and exponent fields of a floating-point specification.  to the right or left of all digit positions of a fixed-point specification. ═══ ═══ The character pairs "CR" (credit) and "DB" (debit) specify the signs of real numeric character data items. CR specifies that the associated positions will contain the letters '"CR"' if the value of the data is <0. Otherwise, the positions will contain two blanks. The characters CR can only appear to the right of all digit positions of a field. DB is used in the same way that CR is used (above) except that the letters "DB" appear in the associated positions. ═══ ═══ F specifies the picture scaling factor. The picture scaling factor specifies that the decimal point in the arithmetic value of the variable is that number of places (F) to the right (if F>0) or to the left (if F<0) of its assumed position in the character value. The number of digits following the V picture character minus the integer specified with F must be between -128 and 127. ═══ ═══ expression When the based structure is allocated, the expression is evaluated and converted to FIXED BINARY (31,0). Any variables used as operands in the expression must not belong to the structure containing the REFER option. ═══ ═══ variable The variable, known as the object of the REFER option, must be a member of the declared structure. The REFER object must conform to the following rules:  It must be REAL FIXED BINARY(P,0).  It must precede the first level-2 element that has the REFER option or contains an element that has the REFE7R option.  It must not be locator-qualified or subscripted.  It must not be part of any array. ═══ ═══ character can be any digit, letter, special character, blank, or any other of the 256 bit combinations in a byte. ═══ ═══ hex-digit hex-digit represents a pair of hexadecimal numbers. Each hex-digit may be 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, or F. ═══ ═══ Specify hex-digit group using: hex-digit hex-digit hex-digit hex-digit where each hex-digit is 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, or F. ═══ ═══ The preferred form for mixed character string is: 'cc'M Other allowable forms are: <'.kkkk>cc<.'.M> <'.>cc where: cc = CHARACTER data kk = DBCS character Other examples include: 'IBM'M is the same as 'IBM' '<.I.B.M>'M is stored as <.I.B.M> <'.kkkk.'>.M is stored as (6 bytes) ''M is the same as '' ═══ ═══ * An asterisk can be used to specify the size if the area variable declared is controlled or is a parameter. If a controlled area variable is declared with an asterisk, the size must be specified in the ALLOCATE statement used to allocate the area. If a parameter is declared with an asterisk, the size is inherited from the argument. ═══ ═══ expression specifies the size of the area. If expression, or asterisk (*), is not specified, the default is 1000. ═══ ═══ A label constant is a name written as the label prefix of a statement (other than PROCEDURE or ENTRY) so that, during execution, program control can be transferred to that statement through a reference to its label prefix. ═══ ═══ A data item may be a constant or a variable. A constant has a value that cannot change. A constant may be referred to by stating its value (for example, arithmetic constants) or by its name (for example, of label constants). A variable has a value or values that can change during the execution of a program. A variable is introduced by a declaration. ═══ ═══ SYSTEM Specifies that the language-specified default attributes are to be applied to the name rather than taken from DEFAULT statements. SYSTEM can appear before, after, or between other attributes, but cannot immediately precede the dimension or precision attributes. ═══ ═══ level A nonzero integer. If a level number is not specified, level 1 is the default for element and array variables. Level 1 must be specified for major structure names. ═══ ═══ name Each level 1 name must be unique within a particular block. ═══ ═══ The number of bounds specifications indicates the number of dimensions in the array, unless the declared variable is in an array of structures. In this case it inherits dimensions from the containing structure. The bounds specification indicates the bounds as follows:  If only the upper bound is given, the lower bound defaults to 1.  The lower bound must be less than or equal to the upper bound.  An asterisk (*) specifies that the actual bounds are specified in an ALLOCATE statement, if the variable is CONTROLLED, or in a declaration of an associated argument, if the variable is a simple parameter. Additional rules for specifying array bounds are:  The bounds of arrays declared STATIC must be optionally-signed integers. The bounds of arrays declared BASED must be optionally-signed integers unless the array is part of a based structure and the REFER option is used.  The dimension attribute must follow, with no intervening attribute specifications, the array name (or the parenthesized list of names, if it is being factored). ═══ ═══ You can use structure mapping for determining the record length required for a structure when record-oriented input/output is used, and determining the amount of padding or rearrangement required for correct alignment of a structure for locate-mode input/output. ═══ ═══ Description It is necessary to understand the difference between the logical level and the level number of structure elements. The logical levels are immediately apparent if the structure declaration is written with consistent level numbers or suitable indentation (as in the detailed example given after the rules). In any case, you can determine the logical level of each item in the structure by applying the following rule to each item in turn, starting at the beginning of the structure declaration: Note: The logical level of a given item is always one unit deeper than that of its immediate containing structure. Example The following declaration illustrates logical level assignment: DCL 1 A, 4 B, 5 C, 5 D, 3 E, 8 F, 7 G; 1 2 3 3 2 3 3 ═══ ═══  INTERNAL is the default for entry names of internal procedures and for automatic, static, and based variables.  EXTERNAL is the default for controlled variables, file constants, entry constants, and programmer-defined conditions. ═══ ═══ environment-name specifies the name by which an assembler entry is known outside of the compilation unit. When so specified, the name being declared effectively becomes internal and is not known outside of the compilation unit. The environment name is known instead. You can only specify the environment name for OPTIONS(ASSEMBLER) entry constants. You cannot specify the environment name in the DEFAULT statement. PL/I does not monocase the name that you specify. The name must:  Be up to 8 characters in length.  Be a character constant that does not contain a repetition factor, hex character constants, or mixed character constants.  Differ from names internally generated by the compiler. Using 7-character names or shorter names ensures this. ═══ ═══ A set of attributes can be completed by language-specified defaults. For example, consider the declaration: DCL A BINARY(5,2) /* scale specified */ In this declaration, A gets the attributes REAL FIXED BINARY(5,2). Whereas, in the following declaration: DCL B BINARY(5) /* no scale specified */ B gets the attributes REAL FLOAT BINARY(5). ═══ ═══ The following statement: DEFAULT RANGE(*), DESCRIPTORS; overrides, for all names, any programmer-defined default rules established in a containing block. It can be used to restore language-specified defaults for contained blocks. ═══ ═══ 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. For example: RANGE (ABC) applies to the following names: ABC ABCD ABCDE But not to: ABD ACB AB A Hence, a single letter in the range-specification applies to all names that start with that letter. The RANGE can also be a non-EBCDIC DBCS character. ═══ ═══ RANGE(*) specifies all names in the scope of the DEFAULT statement. For example: DFT RANGE (*) PIC '99999'; This statement specifies default attributes REAL PICTURE '99999' for all names. ═══ ═══ attribute-list specifies a list of attributes from which selected attributes are applied to names in the specified range. Attributes in the list can appear in any order and must be separated by blanks. Only those attributes that are necessary to complete the declaration of a data item are taken from the list of attributes. The file description attributes, and the attributes ENTRY, RETURNS, LIKE, and VARIABLE cannot be used in an attribute-list. If FILE is used, it implies the attributes VARIABLE and INTERNAL. Although the DEFAULT statement can specify the dimension attribute for names that have not been declared explicitly, a subscripted name is contextually declared with the BUILTIN attribute. Therefore, the dimension attribute can be applied by default only to explicitly declared names. Attributes that conflict, when applied to a data item, do not necessarily conflict when they appear in an attribute specification. For example: DEFAULT RANGE(S) BINARY VARYING; This means that any name that begins with the letter "S" and is declared explicitly with the BIT, CHARACTER, or GRAPHIC attribute will receive the VARYING attribute; all others that are not declared explicitly or contextually as other than arithmetic data will receive the BINARY attribute. ═══ ═══ 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. The letters cannot be DBCS. The letters given in the specification must be in increasing alphabetic order. For example: RANGE(A:G,I:M,T:Z) ═══ ═══ DESCRIPTORS specifies that the attributes are included in any parameter descriptors in a parameter descriptor list of an explicit entry declaration, provided that:  The inclusion of any such attributes is not prohibited by the presence of alternative attributes of the same class.  At least one attribute is already present. (The DESCRIPTORS default attributes are not applied to null descriptors.) For example: DEFAULT DESCRIPTORS BINARY; DCL X ENTRY (FIXED, FLOAT); The attribute BINARY is added to each parameter descriptor in the list, producing the equivalent list: (FIXED BINARY, FLOAT BINARY) ═══ ═══ VALUE can appear anywhere within an attribute-specification except before a dimension attribute. VALUE establishes any default rules for area size, string length, and precision. The size of AREA data, or length of BIT, CHARACTER, or GRAPHIC data, can be an expression or an integer and can include the REFER option, or can be specified as an asterisk. For example: DEFAULT RANGE(A:C) VALUE (FIXED DEC(10), FLOAT DEC(14) AREA(2000)); DECLARE B FIXED DECIMAL, C FLOAT DECIMAL, A AREA; These statements are equivalent to: DECLARE B FIXED DECIMAL(10), C FLOAT DECIMAL(14), A AREA(2000); The only attributes that the VALUE option can influence are area size, string length, and precision. Other attributes in the option, such as CHARACTER and FIXED BINARY in the above examples, merely indicate which attributes the value is to be associated with. ═══ ═══ value-specification The base and scale attributes in value-specification must be present to identify a precision specification with a particular attribute. The base and scale attributes can be factored. ═══ ═══ factored-specification An example of factored-specification with the range options is: DEFAULT (RANGE(A)FIXED, RANGE(B) FLOAT)BINARY; This statement specifies default attributes FIXED BINARY for names with the initial letter "A", and FLOAT BINARY for those with the initial letter "B". ═══ ═══ Following is a list of attributes and their restrictions: AREA without a size specification BIT, CHARACTER, or GRAPHIC without a string length specification LABEL without a label list Arithmetic base, mode, and scale attributes without precision specifications CONTROLLED For a parameter name, a specification of CONTROLLED as a default attribute is ignored. The CONTROLLED attribute is also ignored if it appears in a DESCRIPTORS attribute specification. dimension The dimension attribute is allowed, but only as the first item in an attribute specification. The bounds can be specified as an arithmetic constant or an expression and can include the REFER option. ═══ ═══ 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. ═══ ═══ An infix operator is an operator between two operands. ═══ ═══ A prefix operator is an operator preceding a single operand. ═══ ═══ Description You may assign the results of the evaluation of an expression to a variable. Example In the following expression: A = B; the target A is the variable on the left of the assignment symbol (=). ═══ ═══ There are few restrictions on the use of different types of data in an expression. However, mixing data types implies that a conversion must take place. If conversions take place at run time, the program takes longer to run. Also, conversion can result in loss of precision. When using expressions that mix data types, you should understand the relevant conversion rules. ═══ ═══ In a bit operation, use one of the following as a logical operator:  Logical NOT/XOR к  Logical AND &  Logical OR │ The first operator, the NOT/XOR symbol, can be used as a prefix operator (an operator preceding a single operand) or as an infix operator (an operator between two operands). The logical AND and OR operators can be used as infix operators only. The operators have the same function as in Boolean algebra. ═══ ═══ A comparison operation is specified by using one of the following as an infix operator (an operator between two operands):  Less than <  Not less than к<  Less than or equal to <=  Equal to =  Not equal to к=  Greater than or equal to >=  Greater than >  Not greater than к> ═══ ═══ Algebraic comparison operations involve the comparison of signed arithmetic values. If operands differ in base, scale, precision, or mode, they are converted. Numeric character data is converted to arithmetic data before comparison. Only the operators = and к= are valid for comparison of complex operands. ═══ ═══ Character comparison operations involve left-to-right, character-by-character comparison according to the binary value of the bytes. If you compare strings of unequal lengths, the shorter string is padded on the right. The padding consists of blanks. ═══ ═══ Bit comparison involves left-to-right, bit-by-bit comparison of binary digits. If you compare bit strings of unequal lengths, the shorter string is padded on the right. The padding consists of '0'B. ═══ ═══ Graphic comparison involves left-to-right, symbol-by-symbol comparison of DBCS (Double-Byte-Character Set) characters. The comparison is based on the binary value of the DBCS characters. If you compare strings of unequal lengths, the shorter string will be padded on the right with the padding graphic. ═══ ═══ You may include prefix operators in your array expressions. For example: If A is the array 5 3 -9 1 2 7 6 3 -4 then the expression -A is the array -5 3 9 -1 -2 -7 -6 -3 4 ═══ ═══ condition/NO-condition You can select any condition that is not always disabled. You can add NO to the condition name so that it is disabled. ═══ ═══ statement Any statement except DECLARE, DEFAULT, or % statements is valid. Condition prefixes attached to a compound statement do not apply to the statement or statements contained in the statement body of the compound statement. ═══ ═══ The effect of a null statement ON-unit is to execute normal return from the condition. Use of the null ON-unit is different from disabling a condition, 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. (If a null ON-unit is specified, the system must still check for the raising of the condition.) ═══ ═══ It is possible to raise a condition during execution of an ON-unit and enter a further ON-unit. An ON-unit entered due to a condition either raised or signalled in another ON-unit is a dynamically-descendant ON-unit. A normal return from a dynamically-descendant ON-unit reestablishes the environment of the ON-unit in which the condition was raised. 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 BEGIN; ON ERROR SYSTEM; . . . END; ═══ ═══ An ON statement that specifies a file variable refers to the file constant that is the current value of the variable when the ON-unit is established.  Example 1 DCL F FILE, G FILE VARIABLE; G = F; L1: ON ENDFILE(G); L2: ON ENDFILE(F); The statements labeled L1 and L2 are equivalent.  Example 2 DECLARE FV FILE VARIABLE, FC1 FILE, FC2 FILE; FV = FC1; ON ENDFILE(FV) GO TO FIN; . . . FV = FC2; READ FILE(FC1) INTO (X1); READ FILE(FV) INTO (X2); An ENDFILE condition raised during the first READ statement causes the ON-unit to be entered, since the ON-unit refers to file FC1. If the condition is raised in the second READ statement, however, the ON-unit is not entered, since this READ refers to file FC2. ═══ ═══ SNAP specifies that when the enabled condition is raised, a list is printed of all the blocks and ON-units active at the time the condition is raised. The action of the SNAP option precedes the action of the ON-unit. If SNAP and SYSTEM are specified, the implicit action is followed immediately by the list of active blocks. ═══ ═══ 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. ═══ ═══ dcl Test condition; on condition (Test) begin; . . . end; The begin block is executed whenever the following statement is executed: SIGNAL CONDITION (TEST); ═══ ═══ For example, the CONVERSION condition is raised when:  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. ═══ ═══ controlled variable a controlled variable or an element of a controlled major structure. A structure element, other than the major structure, can appear only if the relative structuring of the entire major structure containing the element appears as in the DECLARE statement for that structure. In this case, dimension attributes must be specified for all names that are declared with the dimension attribute. ═══ ═══ level indicates a level number. The first name appearing after the keyword ALLOCATE must be a level-1 variable. ═══ ═══ BIT, CHARACTER, GRAPHIC, and AREA can appear only for variables having the same attributes, respectively. ═══ ═══ dimension The dimension attribute must specify the same number of dimensions as declared. The dimension attribute can appear with any of the other attributes and must be the first attribute specified. For example: DCL X(20) CHAR(5) CONTROLLED; ALLOCATE X(25) CHAR(6); ═══ ═══ INITIAL, INITIAL CALL Initial values are assigned to a variable upon allocation, if it has an INITIAL attribute in either the ALLOCATE statement or DECLARE statement. Expressions or a CALL option in the INITIAL attribute are executed at the point of allocation, using the conditions enabled at the ALLOCATE statement, although the names are interpreted in the environment of the declaration. If an INITIAL attribute appears in both DECLARE and ALLOCATE statements, the INITIAL attribute in the ALLOCATE statement is used. If initialization involves reference to the variable being allocated, the reference is to the new generation of the variable. ═══ ═══ controlled-variable is a level-1, unsubscripted variable. ═══ ═══ A controlled variable need not be explicitly freed by a FREE statement. However, it is a good practice to explicitly FREE controlled variables. All controlled storage is freed at the termination of the program. ═══ ═══ based-variable can be any data type. It can be an element variable, an array, or a major structure. When it is a major structure, only the major structure name is specified. ═══ ═══ IN 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. If the SET option is not specified, the declaration of the based variable must specify a locator variable. ═══ ═══ based-variable must be a level-1 unsubscripted based variable. ═══ ═══ IN (area-reference) must be specified or the based variable must be qualified by an offset declared with an associated area, if the storage to be freed was allocated in an area. The IN option cannot appear if the based variable was not allocated in an area. Area assignment allocates based storage in the target area. These allocations can be freed by the IN option naming the target area. ═══ ═══ A based variable need not be explicitly freed by a FREE statement, but it is a good practice to do so. All based storage is freed at the termination of the program. ═══ ═══ expression specifies the size of the area. If expression, or *, is not specified, the default is 1000. ═══ ═══ * An asterisk can be used to specify the size if the area variable declared is controlled or is a parameter. If a controlled area variable is declared with an asterisk the size must be specified in the ALLOCATE statement used to allocate the area. If a parameter is declared with an asterisk, the size is inherited from the argument. ═══ ═══ 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, except when the area is in a structure and is not the last item in it-then, the declared size is transmitted. Thus the unused part of an area does not take up space on the data set. Because the extents of areas can vary, the maximum record length required is governed by the area length (area size + control information size). ═══ ═══ 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. Note: If no area variable is specified, the offset can be used only as a locator qualifier through use of the POINTER built-in function. ═══ ═══ expression The value of this expression defines the length, bound, or size of the member when the structure is allocated (using ALLOCATE or LOCATE). The expression is evaluated and converted to FIXED BINARY (31,0). Any variables used as operands in the expression must not belong to the structure containing the REFER option. Subsequent references to the structure obtain this member's length, bound, or size from the current value of "variable". ═══ ═══ variable The variable, known as the "object" of the REFER option must be a member of the declared structure. The REFER object must conform to the following rules:  It must be REAL FIXED BINARY (p,0).  It must precede the first level-2 element that has the REFER option or contains an element that has the REFER option.  It must not be locator-qualified or subscripted.  It must not be part of an array. ═══ ═══ reference to the variable (the base variable) whose storage is associated with the declared variable; the latter is the defined variable. The base variable can be EXTERNAL or INTERNAL. It can be a parameter (in string overlay defining, the parameter must refer to connected storage). It cannot be BASED or DEFINED. A change to the base variable's value is a corresponding change to the value of the defined variable, and vice versa. ═══ ═══ expression specifies the position relative to the start of the base variable. If the POSITION attribute is omitted, POSITION(1) is the default. The value specified in the expression can range from l to n, where n is defined as: n = N(b) - N(d) + 1 where N(b) is the number of bits, characters, or graphics in the base variable, and N(d) is the number of bits, characters, or graphics in the defined variable. The expression is evaluated and converted to an integer value at each reference to the defined item. ═══ ═══ iteration-factor specifies the number of times the iteration-item is to be repeated in the initialization of elements of an array. The iteration-factor can be an expression, except for static data, in which case it must be an integer. When storage is allocated for the array, the expression is evaluated to give an integer that specifies the number of iterations. A negative or zero iteration-factor specifies no initialization. ═══ ═══ constant reference expression specifies an initial value to be assigned to the initialized variable. ═══ ═══ * specifies that the element is to be left uninitialized. ═══ ═══ For automatic variables, which are allocated at each activation of the declaring block, any specified initial value is assigned with each allocation. ═══ ═══ In the following example: DCL (STG, STORAGE) BUILTIN; is not a multiple declaration, and DCL BINARY FILE; X = BIN(VAR, 6,3); is valid. ═══ ═══ Specifying an aggregate argument is equivalent to placing the function reference or pseudovariable in a DO-group where one or more arguments is a subscripted array reference that is modified by the control variable. For example: DCL A(2)CHAR(2)VARYING; DCL B(2)CHAR(2) INIT('AB','CD'); DCL C(2)FIXED BIN INIT(1,2); A=SUBSTR(B,1,C); results in A(1) having the value "A" and A(2) having the value "CD". ═══ ═══ command-list specifies a list of commands to be processed. ═══ ═══ A PL/I application program becomes active when a calling program invokes the main procedure. This calling program usually is the operating system, although it could be another program. The main procedure must be an external procedure whose PROCEDURE statement has the OPTIONS(MAIN) specification. For example: CONTRL: PROCEDURE OPTIONS(MAIN); CALL A; CALL B; CALL C; END CONTRL; In this example, CONTRL is the main procedure and it invokes other procedures in the program. The main procedure remains active for the duration of the program. ═══ ═══ A PL/I application program is terminated when the main procedure is terminated. Whether termination is normal or abnormal, control returns to the calling program. In the following example, when control transfers from the C procedure back to the CONTRL procedure, CONTRL terminates. CONTRL: PROCEDURE OPTIONS(MAIN); CALL A; CALL B; CALL C; END CONTRL; ═══ ═══ 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 block, by means other than a procedure reference. There are a number of ways that control can be transferred, and their implementations differ according to the type of block being terminated. During block 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. ═══ ═══ RECURSIVE must be specified if the procedure might be invoked recursively. ═══ ═══ ORDER, REORDER ORDER and REORDER are optimization options that are specified for a procedure or begin block. If neither option is specified for the external procedure, ORDER is the default. The default for internal blocks is to inherit ORDER or REORDER from the containing block. The ORDER option indicates that only the most recently assigned values of variables modified in the block are available for ON-units that are entered because of computational conditions raised during statement execution and expressions in the block. The REORDER option allows the compiler to generate optimized code to produce the result specified by the source program when error-free execution takes place. ═══ ═══ CHARGRAPHIC, NOCHARGRAPHIC The default for an external procedure is NOCHARG. Internal procedures and begin blocks inherit their defaults from the containing procedure. When NOCHARG is in effect, no semantic changes occur. When CHARG is in effect, the following semantic changes occur:  All character string assignments are mixed character assignments.  STRINGSIZE condition causes MPSTR to be called. STRINGSIZE must be enabled for character assignment that can cause truncation. For example, based on: NAME: PROCEDURE CHARGRAPHIC; DCL A CHAR(5); DCL B CHAR(8); the following statement: (STRINGSIZE): A=B; is logically transformed into: A=MPSTR(B,'VS',LENGTH(A)); ═══ ═══ IRREDUCIBLE, REDUCIBLE If REDUCIBLE or IRREDUCIBLE is specified, it is checked for syntax errors and ignored. ═══ ═══ entry-constant specifies the name by which the procedure to be fetched is known to the operating system. The entry-constant must be the same as the one that you use in the corresponding CALL statement, CALL option, or function reference. ═══ ═══ entry-constant must be the same as the one used in the corresponding CALL statement, CALL option, function reference, and/or FETCH statements. ═══ ═══ Begin-blocks are activated through sequential flow or as a unit in an IF, ON, WHEN, or OTHERWISE statement. You can transfer control to a labeled BEGIN statement by issuing the GO TO statement. ═══ ═══ A begin-block is terminated when control passes to another active block by some means other than a procedure reference. Begin-block termination occurs when:  The END statement for the begin-block is executed. Control continues with the statement physically following the END, except when the block is an ON-unit.  A GO TO statement within the begin-block (or within any block internal to it) is executed where control transfers to a point outside the block.  A STOP or EXIT statement is executed.  Control reaches a RETURN statement that transfers control out of the begin-block (and out of its containing procedure as well). Note: 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. In this case, all intervening blocks in the activation sequence are terminated. ═══ ═══ entry-reference, generic-name, or built-in name specifies the name of the subroutine to be invoked. Entry-reference is a function or subroutine name declared with the ENTRY attribute. Generic-name is a name declared with the GENERIC attribute. Built-in name is a name declared with the BUILTIN attribute. ═══ ═══ argument is an element, an aggregate expression, or an asterisk (*) to be passed to the invoked procedure. PL/I has a limit of 64 arguments in a single CALL statement. ═══ ═══ The attributes of a dummy argument are derived as follows:  From the attributes declared for the associated parameter in an internal procedure.  From the attributes specified in the parameter descriptor for the associated parameter in the declaration of the external entry. If there was not a descriptor for this parameter, the attributes of the constant or expression are used.  For the bounds of an array, the length of a string, or the size of an area, if specified by asterisk notation in the parameter declaration, from the bound, length or size of the argument itself. ═══ ═══ parameter-descriptor-list specifies the attributes of the parameters, if any, for the entry point. ═══ ═══ ENTRY The ENTRY attribute without a parameter-descriptor-list is implied by the OPTIONS or the RETURN attribute. ═══ ═══ parameter-descriptor A parameter-descriptor list can be given to describe the attributes of the parameters of the associated external entry constant or entry variable. It is used for argument and parameter attribute matching and the creation of dummy arguments. If no parameter-descriptor list is given, the default is for the argument attributes to match the parameter attributes. Thus, the parameter-descriptor list must be supplied if argument attributes do not match the parameter attributes. Each parameter-descriptor corresponds to one parameter of the entry point invoked and, if given, specifies the attributes of that parameter. The parameter-descriptors must appear in the same order as the parameters they describe. If a descriptor is absent, the default is for the argument to match the parameter. If a descriptor is not required for a parameter, the absence of the descriptor must be indicated by a comma, by an asterisk followed by a comma, or followed by the closing parenthesis of the parameter-descriptor list. For example: ENTRY(CHARACTER(10),*,*,FIXED DEC) /* Indicates four arguments */ ENTRY(*) /* Indicates one argument */ ENTRY(FLOAT BINARY,*) /* Indicates two arguments */ ENTRY( ) /* Specifies that the entry name */ /* must never have any arguments */ ENTRY /* Specifies that it can have any */ /* number of arguments */ ═══ ═══ attribute The attributes can appear in any order in a parameter-descriptor. For an array parameter-descriptor, the dimension attribute must be the first specified. ═══ ═══ * An asterisk specifies that, for that parameter, any data type is allowed. No conversion will be done. ═══ ═══ structure-parameter-descriptor For a structure-parameter-descriptor, the descriptor level numbers need not be the same as those of the parameter, but the structuring must be identical. The attributes for a particular level can appear in any order. ═══ ═══ entry-reference must not be based, subscripted, or defined. The same entry-reference can appear more than once within a single GENERIC declaration with different lists of descriptors. ═══ ═══ generic-descriptor correspond to a single argument. It specifies the attributes that the corresponding argument must have in order that the associated entry reference can be selected for replacement. Level numbers must not be specified. Where no descriptor is required, it can be either omitted or indicated by an asterisk. ═══ ═══ * The asterisk form is required if the missing descriptor is the only descriptor. For example, whereas (,) represents two descriptors, (*) represents one. ═══ ═══ ASSEMBLER ASSEMBLER specifies that the designated entry point is an assembler subroutine. PL/I will pass arguments directly to the subroutine, rather than via PL/I 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. Abbreviation: ASM ═══ ═══ RETCODE specifies that, on return from the non-PL/I routine, the fullword value in register 15 is to be saved as the PL/I return code. This option enables non-PL/I routines to pass return codes to PL/I. The value of the return code can be determined by means of the PLIRETV built-in function. ═══ ═══ BYADDR or BYVALUE options specify how all arguments defined for this entry are passed. If you specify BYADDR, parameters are received by address. If 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 entry points can only have scalar arguments and return values that are either POINTER or REAL FIXED BINARY(31,0). ═══ ═══ COBOL specifies that the designated entry point is in a COBOL subprogram. ═══ ═══ NOMAP, NOMAPIN, NOMAPOUT The mapping of a data aggregate passed by PL/I to COBOL might not match the mapping used by COBOL. If PL/I detects a possible mapping discrepancy, PL/I creates a dummy argument for the data aggregate, assigns data aggregate values to the dummy argument, and passes the dummy argument to the COBOL routine. The dummy argument uses the COBOL mapping algorithm. On return to the PL/I routine, the values in the dummy argument are remapped to the original data argument. You can use the NOMAP, NOMAPIN, and NOMAPOUT options to prevent this automatic mapping of values: NOMAP Specifies no mapping of values either at invocation of the COBOL routine or on return to PL/I. When you specify this option, PL/I does not create a dummy argument. NOMAPIN Specifies no mapping of values at invocation of the COBOL routine. When you specify this option, PL/I creates a dummy argument. NOMAPOUT Specifies no mapping of values on return to PL/I. When you specify this option, PL/I creates a dummy argument. The NOMAP, NOMAPIN, and NOMAPOUT options are effective only for structure arguments that are passed to COBOL. The options do not apply to scalars. Use these options when program efficiency is important. These options help you to avoid unnecessary mapping code. Note: NOMAP, NOMAPIN, and NOMAPOUT can be specified on the same OPTIONS specification. ═══ ═══ ARGi ARGi refers to items in the argument list to which the NOMAP, NOMAPIN, and NOMAPOUT options are to be applied. When you use ARGi, ARG1 specifies that the option refers to the first argument. ARG2 specifies that the option refers to the second argument, and so on. If you do not specify ARGi, the option is applied to all the data aggregates being passed. ═══ ═══ INTER INTER is syntax checked and ignored. ═══ ═══ label: is the optional statement label prefix. ═══ ═══ 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 and rescanning takes place. ═══ ═══ NORESCAN specifies that when the identifier is scanned by the preprocessor, 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. ═══ ═══ The ORDER and REORDER options are optimization options that are specified for a procedure or a begin block. If neither option is specified for the external procedure, ORDER is the default. The default for internal blocks is to inherit ORDER or REORDER from the containing block. ORDER indicates that only the most recently assigned values of variables modified in the block are available for ON-units that are entered because of computational conditions raised during statement execution and expressions in the block. REORDER allows the compiler to generate optimized code to produce the result specified by the source program when error-free execution takes place. ═══ ═══ The default for an external procedure is NOCHARGRAPHIC. Internal procedures and begin blocks inherit their defaults from the containing procedure. When CHARGRAPHIC is in effect, the following semantic changes occur:  All character string assignments are mixed character assignments.  STRINGSIZE condition causes MPSTR to be called. STRINGSIZE must be enabled for character assignment that can cause truncation. For example: NAME: PROCEDURE CHARGRAPHIC; DCL A CHAR(5); DCL B CHAR(8); /* the following statement... */ (STRINGSIZE): A=B; /*...is logically transformed into... */ A=MPSTR(B,'VS',LENGTH(A)); When NOCHARGRAPHIC is in effect, no semantic changes occur. ═══ ═══ entry-reference, generic-name, or built-in name specify the entry point of the subroutine to be invoked, whether it is an entry name, generic name, or built-in name. ═══ ═══ argument is an element, aggregate expression, or asterisk (*) to be passed on to the invoked subroutine. PL/I has a limit of 64 arguments in a single CALL statement. ═══ ═══ label: is the optional statement label prefix. ═══ ═══ identifier specifies the name of either a preprocessor variable, a preprocessor procedure, or a preprocessor built-in function. ═══ ═══ label: is the optional statement label prefix. ═══ ═══ identifier specifies the name of either a preprocessor variable, a preprocessor procedure, or a preprocessor built-in function. ═══ ═══ FIXED A preprocessor variable declared with the attribute FIXED is also given the attributes DECIMAL(5,0). ═══ ═══ CHARACTER specifies that the identifier represents a varying-length string that has no maximum length. ═══ ═══ ENTRY An entry declaration can be specified for each preprocessor entry name in the source program. The declaration activates the entry name. The declaration of a preprocessor procedure entry name can be performed explicitly by its appearance as the label of a %PROCEDURE statement. This explicit declaration, however, does not activate the preprocessor procedure name. ═══ ═══ BUILTIN specifies that the identifier is the preprocessor built-in function of the same name. ═══ ═══ expression specifies an expression that is evaluated and converted to a fixed-point binary value of precision (31,0). Execution is suspended for the number of milliseconds specified by the expression. ═══ ═══ expression converted, where necessary, to a varying character string. This character string is the message displayed. It can contain mixed character data. ═══ ═══ REPLY(character-reference) receives a string that is an operator-supplied message. The STRING pseudovariable must not be used. The reply message can contain character, graphic, or mixed data. If the reply contains graphic data it is assigned, along with the shift codes, to the character string reference. The content of the reply is not checked for matched pairs of shift codes. ═══ ═══ EVENT(event-reference) If the EVENT option is not specified, execution is suspended until the operator's message is received. If the EVENT option is given, execution does not wait for the reply to be completed before continuing with subsequent statements. The status of the event-variable is set to 0, and the completion part of the event variable is given the value '0'B until the reply is completed, at which point it is given the value '1'B. The reply is complete only after the execution of a WAIT statement naming the event. Another DISPLAY statement must not be executed until the previous reply is complete. REPLY and EVENT can appear in any order. ═══ ═══ WHILE (exp4) specifies that, before each repetition of do-group execution, exp4 is evaluated and, if necessary, converted to a bit string. If any bit in the resulting string is 1, the do-group is executed. If all bits are 0, or the string is null, execution of the Type 2 do-group is terminated; while for Type 3, only the execution associated with the specification containing the WHILE option is terminated. Execution for the next specification, if one exists, then begins. ═══ ═══ UNTIL (exp5) specifies that, after each repetition of do-group execution, exp5 is evaluated, and, if necessary, converted to a bit string. If all the bits in the resulting string are 0, or the string is null, the statements of the do-group are executed. If any bit is 1, execution of the Type 2 do-group is terminated; while for Type 3, only the execution associated with the specification containing the UNTIL option is terminated. Execution for the next specification, if one exists, then begins. ═══ ═══ Reference: The pseudovariables COMPLETION, COMPLEX, and STRING cannot be used as a reference variable. All data types are allowed. The generation, g, of a reference is established once at the beginning of the do-group, immediately before the initial value expression (exp1) is evaluated. If the reference generation is changed to h in the do-group, the do-group continues to execute with the reference derived from the generation g. However, any reference to the reference inside the do-group is a reference to generation h. It is an error to free generation g in the do-group. If a reference is made to a reference after the last iteration is completed, the value of the variable is the value that was out of range of the limit set in the specification. Leave the do-group if the reference is out of range. That is, if:  The BY value is positive and the reference is > the TO value  The BY value is negative and the reference is < the TO value of the limit set in the specification. If reference is a program-control variable, the BY and TO options cannot be used in specification. ═══ ═══ exp1 specifies the initial value of the reference. If TO exp2, BY exp3, and REPEAT exp6 are all omitted from a specification, there is a single execution of the do-group, with the reference having the value of exp1. If WHILE(exp4) is included, the single execution does not take place unless exp4 is true. ═══ ═══ TO exp2: exp2 is evaluated at entry to the specification and saved. This saved value specifies the terminating value of the reference. Execution of the statements in a do-group terminates for a specification as soon as the value of the reference, when tested at the end of the do-group, is out of range. Execution of the next specification, if one exists, then begins. When execution of the last specification terminates, control passes to the statement following the do-group. If TO exp2 is omitted from a specification, and if BY exp3 is specified, repetitive execution continues until it is terminated by the WHILE or UNTIL option, or until some statement transfers control out of the do-group. ═══ ═══ BY exp3: exp3 is evaluated at entry to the specification and saved. This saved value specifies the increment to be added to the reference after each execution of the do-group. If BY exp3 is omitted from a specification, and if TO exp2 is specified, exp3 defaults to 1. If BY 0 is specified, the execution of the do-group continues indefinitely unless it is halted by a WHILE or UNTIL option, or control is transferred to a point outside the do-group. ═══ ═══ REPEAT exp6: exp6 is evaluated and assigned to the reference after each execution of the do-group. Repetitive execution continues until it is terminated by the WHILE or UNTIL option, or some statement transfers control out of the do-group. ═══ ═══ IF . . . THEN . . . ELSE IF A=B THEN DO; . . . END; ELSE DO I=1 TO 2; . . . END; ═══ ═══ Basic repetitions In the following example, the do-group is executed ten times, while the value of the reference I progresses from 1 through 10. DO I = 1 TO 10; . . . END; The effect of this DO and END statement is equivalent to: I = 1; A: IF I > 10 THEN GO TO B; . . . I = I +1; GO TO A; B: next statement The following DO statement executes the do-group three times: once for each assignment of 'TOM', 'DICK', and 'HARRY' to NAME: DO NAME = 'TOM','DICK','HARRY'; The following statement specifies that the do-group executes thirteen times: ten times with the value of I equal to 1 through 10, and three times with the value of I equal to 13 through 15: DO I = 1 TO 10, 13 TO 15; ═══ ═══ Repetition using the reference as a subscript The reference of a DO statement can be used as a subscript in statements within the do-group, so that each execution deals with successive elements of a table or array. In the following example, the first ten elements of A are set to 1,2,...,10, respectively: DO I = 1 TO 10; A(I) = I; END; ═══ ═══ Repetition with TO . . . BY The following example specifies that the do-group is executed five times, with the value of I equal to 2, 4, 6, 8, and 10: DO I = 2 TO 10 BY 2; If negative increments of the reference are required, the BY option must be used. For example, the following is executed with I equal to 10, 8, 6, 4, 2, 0, and -2: DO I = 10 TO -2 BY -2; In the following example, the do-group is executed with I equal to 1, 3, 5: I=2; DO I=1 TO I+3 BY I; . . . END; It is equivalent to the following: DO I=1 TO 5 BY 2; . . . END; ═══ ═══ DO with WHILE, UNTIL The WHILE and UNTIL options make successive executions of the do-group dependent upon a specified condition. For example: DO WHILE (A=B); . . . END; is equivalent to the following: S: IF A=B THEN; ELSE GOTO R; . . . GOTO S; R: next statement The example: DO UNTIL (A=B); . . . END; is equivalent to the following: S: . . . IF (A=B) THEN GOTO R; GOTO S; R: next statement In the absence of other options, a do-group headed by a DO UNTIL statement is executed at least once, but a do-group headed by a DO WHILE statement might not be executed at all. That is, the statements DO WHILE (A=B) and DO UNTIL (Aк=B) are not equivalent. In the following example, if A к=B when the DO statement is first encountered, the do-group is not executed at all. DO WHILE(A=B) UNTIL(X=10); However, if A=B, the do-group is executed. If X=10 after an execution of the do-group, no further executions are performed. Otherwise, a further execution is performed provided that A is still equal to B. In the following example, the do-group is executed at least once, with I equal to 1: DO I=1 TO 10 UNTIL(Y=1); If Y=1 after an execution of the do-group, no further executions are performed. Otherwise, the default increment (BY 1) is added to I, and the new value of I is compared with 10. If I is greater than 10, no further executions are performed. Otherwise, a new execution commences. The following statement specifies that the do-group executes ten times while C(I) is less than zero, and then (provided that A is equal to B) once more: DO I = 1 TO 10 WHILE (C(I)<0), 11 WHILE (A = B); ═══ ═══ REPEAT In the following example, the do-group is executed with I equal to 1, 2, 4, 8, 16, and so on: DO I = 1 REPEAT 2*I; . . . END; This is equivalent to the following: I=1; A: . . . I=2*I; GOTO A; In the following example, the first execution of the do-group is performed with I=1. DO I=1 REPEAT 2*I UNTIL(I=256); After this and each subsequent execution of the do-group, the UNTIL expression is tested. If I=256, no further executions are performed. Otherwise, the REPEAT expression is evaluated and assigned to I, and a new execution commences. The following example shows a DO statement used to step along a chained list: DO P=PHEAD REPEAT P -> FWD WHILE(Pк=NULL()); The value PHEAD is assigned to P for the first execution of the do-group. Before each subsequent execution, the value P -> FWD is assigned to P. The value of P is tested before the first and each subsequent execution of the do-group. If it is NULL, no further executions are performed. The following statement specifies that the do-group is to be executed nine times, with the value of I equal to 1 through 9; then successively with the value of I equal to 10, 20, 40, and so on. Execution ceases when the do-group has been executed with a value of I greater than 10000. DO I = 1 TO 9, 10 REPEAT 2*I UNTIL (I>10000); ═══ ═══ label: is the optional statement label prefix. ═══ ═══ preprocessor-variable is the control variable. All data types except the COMPLETION, COMPLEX, and STRING pseudovariables can be used. The generation, g, of a control variable is established once at the beginning of the do-group, immediately before the initial value expression (preprocessor-exp1) is evaluated. If the control variable generation is changed, to h, in the do-group, the do-group continues to execute with the control variable derived from the generation g. However, any reference to the control variable inside the do-group is a reference to generation h. It is an error to free generation g in the do-group. If the reference is made to a control variable after the last iteration is completed, the value of the variable is the value that was out of range of the limit set in the specification. Leave the do-group if the control variable is out of range. That is, if:  The BY value is positive and the control variable is > the TO value.  The BY value is negative and the control variable is < the TO value. If the preprocessor-variable is a program-control variable, the BY and TO options cannot be used in the specification. ═══ ═══ preprocessor-exp1 specifies the initial value of the control variable, preprocessor-variable. ═══ ═══ preprocessor-exp2 is evaluated at entry to the specification and saved. This saved value specifies the terminating value of the control variable, preprocessor-variable. Execution of the statements in a do-group terminates for a specification as soon as the value of the control variable, when tested at the end of the do-group, is out of range. Execution of the next specification, if one exists, then begins. When execution of the last specification terminates, control passes to the statement following the do-group. ═══ ═══ preprocessor-exp3 is evaluated at entry to the specification and saved. This saved value specifies the increment to be added to the control variable after each execution of the do-group. If BY preprocessor-exp3 is omitted from a specification, and if TO preprocessor-exp2 is specified, preprocessor-exp3 defaults to 1. If BY 0 is specified, the execution of the do-group continues indefinitely unless control is transferred to a point outside the do-group. ═══ ═══ statement-label cannot be subscripted. If a statement-label follows END, the END statement closes the unclosed group or block headed by the nearest preceding DO, SELECT, BEGIN, or PROCEDURE statement having that statement-label. It also closes any unclosed groups or blocks physically within that group or block; this is known as multiple closure. If a statement-label does not follow END, the END statement closes the one group or block headed by the nearest preceding DO, SELECT, BEGIN, or PROCEDURE statement for which there is no corresponding END statement. ═══ ═══ The label following %END must be a label of a %PROCEDURE or %DO statement. Multiple closure is allowed. ═══ ═══ parameter is a name in an invoked procedure represents an argument passed to that procedure. A name is explicitly declared with the parameter attribute by its appearance in a parameter list of the ENTRY statement. The name must not be subscripted or qualified. Keywords following the procedure can appear in any order. ═══ ═══ RETURNS(attribute list) specifies, for a function procedure, the attributes of the value returned by the function. If more than one attribute is specified, they must be separated by blanks (except for attributes, such as precision, that are enclosed in parentheses). Any data and alignment attributes can be specified except those for ENTRY variables. String lengths and sizes must be specified by integers. The returned value has the specified length or size. The RETURNS attribute must agree with the attributes specified in (or defaults for) the RETURNS option of the PROCEDURE or ENTRY statement to which the entry name is prefixed. If they do not agree there is an error, since no conversion is performed. If RETURNS option is left unspecified, the attributes of the returned value are determined by default. ═══ ═══ IRREDUCIBLE, REDUCIBLE If you specify either IRREDUCIBLE or REDUCIBLE, the statement is syntax checked and ignored. ═══ ═══ label-reference specifies a label constant, a label variable, or a function reference that returns a label value. Since a label variable can have different values at each execution of the GO TO statement, control might not always transfer to the same statement. ═══ ═══ The label: preceding the GO TO is the preprocessor statement label, not the labelled point to which the scan is to be transferred. ═══ ═══ The label: following the GO TO indicates the statement label of a preprocessor statement to which the scan is to be transferred. ═══ ═══ expression is evaluated, and, if necessary, converted to a bit string. ═══ ═══ unit1, unit2 is either a valid single statement, a group, or a begin block. All single statements are considered valid and executable except DECLARE, DEFAULT, END, ENTRY, FORMAT, PROCEDURE, or % statement. If a nonexecutable statement is used, the result can be unpredictable. Each unit can contain statements that specify a transfer of control (for example, GO TO). Hence, the normal sequence of the IF statement can be overridden. Each unit can be labeled and can have condition prefixes. If any bit in the string expression has the value '1'B, unit1 is executed and unit2, if present, is ignored. If all bits are '0'B, or the string is null, unit1 is ignored and unit2, if present, is executed. ═══ ═══ preprocessor-expression is evaluated and converted to a bit string. If the conversion cannot be made, the expression is in error. ═══ ═══ preprocessor unit is any single preprocessor statement (other than %DECLARE, %PROCEDURE, %END, or %DO) or a preprocessor do-group. ═══ ═══ label is the preprocessor statement label. ═══ ═══ member specifies the name of the library member to be incorporated in VM or the name of the data set member to be incorporated in MVS. ═══ ═══ dataset is optional; dataset specifies the ddname used in the FILEDEF command for the CMS library, or in the ddname of the appropriate DD statement for MVS. The default ddname is SYSLIB. The ddname must refer to a partitioned data set. ═══ ═══ label-constant must be a label of a containing do-group. The do-group that is left is the do-group that has the specified label. If label-constant is omitted, the do-group that is left is the group that contains the LEAVE statement. ═══ ═══ message a character expression whose value is the required diagnostic. ═══ ═══ code a fixed expression whose value indicates the severity of the message as follows: Code Severity 0 I 4 W 8 E 12 S 16 U If code is omitted, the default is 0. If code has a value other than those listed above, a diagnostic message is produced and a default value is taken. If the value is less than 0 or greater than 16, severity U is the default. Otherwise, the next lower severity is the default. ═══ ═══ label: is the optional statement label prefix. ═══ ═══ parameter specifies a parameter of the function procedure. ═══ ═══ STATEMENT If the reference occurs in input text and the STATEMENT option is present:  The arguments can be specified either in the positional argument list or by keyword reference.  The end of the reference must be indicated by a semicolon. The semicolon is not retained when the replacement takes place. ═══ ═══ RETURNS The attribute CHARACTER or FIXED must be specified in the RETURNS attribute list to specify the attribute of the value returned by the function procedure. ═══ ═══ entry-name: name written as the label prefix to the %PROCEDURE statement. ═══ ═══ WHEN(exp2, exp3,...) specifies an expression or expressions that are evaluated and compared with the saved value from the SELECT statement. If an expression is found that is equal to the saved value, the evaluation of expressions in WHEN statements is terminated, and the unit of the associated THEN statement is executed. If no such expression is found, the unit of the OTHERWISE statement is executed. The WHEN statement must not have a label prefix. ═══ ═══ OTHERWISE specifies the unit to be executed when every test of the preceding WHEN statement fails. If the OTHERWISE statement is omitted and execution of the select-group does not result in the selection of a unit, the ERROR condition is raised. The OTHERWISE statement must not have a label prefix. ═══ ═══ unit is either a valid single statement, a group, or a begin block. All single statements are considered valid and executable except DECLARE, DEFAULT, END, ENTRY, FORMAT, PROCEDURE, or a % statement. If a non-executable statement is used, the result can be unpredictable. Each unit can contain statements that specify a transfer of control (for example GO TO). Hence, the normal sequence of the SELECT statement can be overridden. ═══ ═══ n specifies the number of lines to be skipped. It must be an integer in the range 1 through 999. If n is omitted, the default is 1. If n is greater than the number of lines remaining on the page, the equivalent of a %PAGE statement is executed in place of the %SKIP statement. ═══ ═══ FILE(file-reference) specifies the name of the file. ═══ ═══ KEY(expression) specifies the key of the locked record. ═══ ═══ event-reference specifies an element, or an array. ═══ ═══ expression is evaluated and converted to FIXED BINARY (31,0) when the WAIT statement is executed. This value specifies the number of events in the list that must be set complete before control for the block passes to the statement following the WAIT. If the value is zero or negative, the WAIT statement is treated as a null statement. If the value is greater than the number, n, of event names in the list, the value is n. If the statement refers to an aggregate event-variable, each of the elements contributes to the count. If the expression does not appear, all the event-variables in the list must be set complete before control is passed to the next statement in the block following the WAIT. ═══ ═══ BYADDR, BYVALUE Specify how all parameters defined for this procedure entry are passed. If you specify BYADDR, parameters are received by address. If 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 unless the procedure is MAIN and is being compiled with the SYSTEM(CICS) or SYSTEM(IMS) compiler options. In these cases, BYVALUE is implied and BYADDR is invalid. BYADDR  Can be specified for EXTERNAL PROCEDURE statements. BYVALUE  May be specified for EXTERNAL PROCEDURE statements.  Cannot be specified for ENTRY statements and internal procedures.  When specified for a MAIN procedure, implies the specification of NOEXECOPS.  Procedures can only have scalar parameters and return values that are either POINTER or REAL FIXED BINARY(31,0). If all parameters are POINTER, the last parameter must not have the NULL pointer value.  Should not be used with SYSTEM(CMS), SYSTEM(CMSTPL), SYSTEM(MVS), or SYSTEM(TSO). ═══ ═══ MAIN Specifies the procedure that is the initial procedure of a PL/I program. The operating system invokes it as the first step in the execution of the program. ═══ ═══ COBOL The PL/I procedure is invoked at this entry point by only a COBOL subprogram. ═══ ═══ NOEXECOPS Is valid only with the MAIN option. It indicates that the character string is passed to the main procedure without evaluating the run-time options for the SYSTEM(MVS), SYSTEM(CMS), and SYSTEM(CMSTPL) compiler options. ═══ ═══ FETCHABLE Specifies that an external procedure can be fetched and is entered through this entry point. If the procedure has multiple labels, the FETCHABLE option is applied to the primary entry point. When a load module containing a FETCHABLE procedure is fetched, control passes to the procedure, except when the load module also has a MAIN procedure. In that case, control passes to the MAIN procedure. If the load module has multiple FETCHABLE procedures, then the linkage editor may choose any of those procedures as the one that gets control. The FETCHABLE option is valid only on external procedures. ═══ ═══ NOMAP, NOMAPIN, NOMAPOUT Are used to prevent the automatic mapping of values: NOMAP Specifies no mapping of values either at entry to PL/I or on return to COBOL. When you specify this option, PL/I does not create a dummy argument. NOMAPIN Specifies no mapping of values at entry to PL/I. When you specify this option, PL/I creates a dummy argument. NOMAPOUT Specifies no mapping of values on return to COBOL. When you specify this option, PL/I creates a dummy argument. ═══ ═══ parameter-list Specifies the name of the parameters, already specified in the PROCEDURE or ENTRY statement, to which the NOMAP, NOMAPIN, or NOMAPOUT option is to be applied. If you do not specify a list, the option is applied to all parameters. Parameters can appear in any order, and are separated by commas or blanks. ═══ ═══ REENTRANT Allows a program to be reentrant. You must not do anything that alters static storage during execution. ═══ ═══ If you specify ATTRIBUTES, identifiers and attributes are included in the compiler listing. ═══ ═══ If you specify FULL, all identifiers and attributes are included in the compiler listing. FULL is the default. ═══ ═══ If you specify SHORT, unreferenced identifiers are omitted, making the listing more manageable. ═══ ═══ If you specify NOATTRIBUTE, neither identifiers nor attributes are included in the compiler listing. ═══ ═══ If you use CMPAT(V1), you can use arrays, AREAS, and aggregates in exactly the same way that they were used in OS PL/I Version 1 as long as other external procedures sharing them are not compiled with CMPAT(V2). If any procedures in an application load module (MAIN or FETCHed) are recompiled (and therefore relink-edited), object code compatibility with OS PL/I Version 1 Release 5.1 is provided under the following guidelines:  If arrays, aggregates, or AREAs are to be shared between OS PL/I Version 1 Release 5.1, object code and PL/I MVS and VM object code, PL/I MVS and VM compilations must use CMPAT(V1).  If arrays, aggregates, or AREAs are to be shared between PL/I MVS and VM object code only, PL/I MVS and VM compilations must use either CMPAT(V1) or CMPAT(V2), but not both.  Using CMPAT(V2) is required for larger arrays, aggregates, or AREAs and is recommended even if you do not use larger arrays, aggregates, or AREAs.  If arrays, aggregates, or AREAs are to be shared between OS PL/I Version 1 Release 5.1 object code only, no precautions need to be taken. ═══ ═══ If you use CMPAT(V2), it does not provide object compatibility with OS PL/I Version 1. You need to make code changes if:  You want to use fullword subscripts.  You have any expressions that rely on precision and scale returned from the BUILTIN functions HBOUND, LBOUND, DIM, or ALLOCATION. If you do not have either of the above situations, you do not need to make code changes to use CMPAT(V2) as long as all external procedures sharing the same array or aggregate are also compiled with CMPAT(V2). ═══ ═══ Continuation depends on the severity detected, as specified by the NOCOMPILE option. The NOCOMPILE option specifies that processing stops unconditionally after syntax checking. If the compilation is terminated by the NOCOMPILE option, the cross-reference listing and attribute listing can be produced; the other listings that follow the source program will not be produced. ═══ ═══ If you specify NOCOMPILE(W), there will be no compilation if a warning, error, severe error, or unrecoverable error is detected. ═══ ═══ If you specify NOCOMPILE(E), there will be no compilation if an error, severe error, or unrecoverable error is detected. ═══ ═══ If you specify NOCOMPILE(S), there will be no compilation if a severe error or unrecoverable error is detected. ═══ ═══ If you specify COMPILE, the program will be compiled. ═══ ═══ password is a character string not exceeding eight characters. Note: Under CMS, if you use CONTROL in the PLIOPT command, the password cannot have a right or left parenthesis or lower case characters. ═══ ═══ DECK specifies that the compiler will produce an object module in the form of 80-character records and store it in the data set defined by the SYSPUNCH DD statement. ═══ ═══ NODECK specifies that the compiler will not produce an object module in the form of 80-character records. ═══ ═══ If you specify FLAG(I), you will get a list of all messages. ═══ ═══ If you specify FLAG(W), you will get a list of all messages except for information messages. ═══ ═══ If you specify FLAG(E), you will get a list of all messages except for warning and information messages. ═══ ═══ If you specify FLAG(S), you will get a listing of only severe error and unrecoverable error messages. ═══ ═══ The INTERRUPT option causes the compiled program to respond to attention requests (interrupts). If you have written a program that relies on raising the ATTENTION condition, it must be compiled with the INTERRUPT option. If you specify the INTERRUPT option, an established ATTENTION ON-unit will gain control when an attention interrupt occurs. When the execution of an ATTENTION ON-unit is complete, control returns to the point of interrupt unless directed elsewhere by means of a GOTO statement. If an ATTENTION ON-unit is not established, the attention interrupt is effectively ignored. ═══ ═══ If you specify NOINTERRUPT, an attention interrupt during a program run will not give control to any ATTENTION ON-units. ═══ ═══ OS specifies the level of PL/I language that the compiler is to support. OS is the only level currently supported. ═══ ═══ NOSPROG specifies that the compiler is not to allow the additional support for pointers allowed under SPROG. ═══ ═══ SPROG specifies that the compiler is to allow extended operations on pointers, including arithmetic and use of the POINTERADD, BINARYVALUE, and POINTERVALUE built-in functions. ═══ ═══ n is the number of lines. It must be in the range 1 through 32,767, but only headings are generated if you specify less than 7. When you specify less than 100, the static internal storage map and the object listing are printed in double column format. Otherwise, they are printed in single column format. ═══ ═══ m is the number of the first, or only, source statement for which an object listing is required. ═══ ═══ n is the number of the last source statement for which an object listing is required. If n is omitted, only statement m is listed. ═══ ═══ c is the character to be printed as the margin indicator. ═══ ═══ m is the column number of the leftmost character (first data byte) that will be processed by the computer. It should not exceed 100. ═══ ═══ n is the column number of the rightmost character (last data byte) that will be processed by the compiler. It should be greater than m, but not greater than 100. For variable-length records, n is interpreted as the rightmost column, or the last data byte if the record has less than n data bytes. Thus, the last character of a variable-length record is usually a non-blank character and is immediately followed (without an intervening blank) by the first data byte (m) of the next record. If you do not intend to have continuation, be sure that at least one blank occurs at the beginning (m) of the next record. ═══ ═══ c is the column number of the ANS printer control character. It should not exceed 100 and should be outside the values specified for m and n. A value of 0 for c indicates that no ANS control character is present. Only the following control characters can be used: (blank) Skip one line before printing. 0 Skip two lines before printing. - Skip three lines before printing. + No skip before printing. 1 Start a new page. Any other character is an error and is assumed to be a blank. Specifying MARGINS(,,c) is an alternative to using %PAGE and %SKIP statements. ═══ ═══ name has from one through eight characters, and begins with an alphabetic character. name has no default. ═══ ═══ char is a single SBCS character. You cannot specify any of the alphabetic characters, digits, and special characters defined in the "PL/I MVS and VM Language Reference" except for the logical NOT symbol (к). If you specify the NOT option, the standard NOT symbol is no longer recognized unless you specify it as one of the characters in the character string. ═══ ═══ OPTIMIZE(TIME) specifies that the compiler will optimize the machine instructions generated to produce a more efficient object program. The use of OPTIMIZE(TIME) could result in a substantial increase in compile time over NOOPTIMIZE. ═══ ═══ OPTIMIZE(O) is the equivalent of NOOPTIMIZE. ═══ ═══ OPTIMIZE(2) is the equivalent of OPTIMIZE(TIME). ═══ ═══ NOOPTIMIZE specifies fast compilation speed but inhibits optimization. ═══ ═══ char is a single SBCS character. You cannot specify any of the alphabetic characters, digits, and special characters defined in the "PL/I MVS and VM Language Reference", except for the logical OR symbol (│). If you specify the OR option, the standard OR symbol is no longer recognized unless you specify it as one of the characters in the character string. ═══ ═══ m specifies the column number of the left-hand margin. ═══ ═══ n specifies the column number of the right-hand margin. ═══ ═══ If the SEQUENCE option is in effect, an external procedure cannot contain more than 32,767 lines. The SEQUENCE option is used to override the default margin positions that are set up during compiler installation by the FSEQUENCE and VSEQUENCE options. Because NUMBER and GONUMBER imply SEQUENCE, the NOSEQUENCE option should not be specified. ═══ ═══ The NOSEQUENCE option must be specified to be able to compile an external procedure containing more than 32,767 lines. ═══ ═══ SIZE(yyyyyyyy) specifies that yyyyyyyy bytes of main storage are requested. Leading zeros are not required. ═══ ═══ SIZE(yyyyyK) specifies that yyyyyK bytes of main storage are requested (1K=1024). Leading zeros are not required. ═══ ═══ SIZE(MAX) specifies that the compiler will obtain as much main storage as it can. ═══ ═══ SIZE(-yyyyyyyy) specifies that the compiler obtains as much main storage as it can, and then releases yyyyyyyy bytes to the operating system. Leading zeros are not required. ═══ ═══ SIZE(-yyyyyK) specifies that the compiler obtains as much main storage as it can, and then releases yyyyyK bytes to the operating system (1K=1024). Leading zeros are not required. ═══ ═══ If you specify NOSYNTAX, processing will be stopped unconditionally after preprocessing. Thus, the cross-reference listing, attribute listing, and other listings that follow the source program are not produced. ═══ ═══ If you specify NOSYNTAX(W), there will be no syntax checking if a warning, error, severe error, or unrecoverable error is detected. ═══ ═══ If you specify NOSYNTAX(E), there will be no syntax checking if an error, severe error, or unrecoverable error is detected. ═══ ═══ If you specify NOSYNTAX(S), there will be no syntax checking if a severe error or unrecoverable error is detected. ═══ ═══ If you specify SYSTEM(MVS), the program will run as an MVS application program. ═══ ═══ If you specify SYSTEM(CMS), the program will run as a CMS application program. ═══ ═══ If you specify SYSTEM(CMSTPL), the program will run as a CMS application program. ═══ ═══ If you specify SYSTEM(CICS), the program will run as a CICS transaction. ═══ ═══ If you specify SYSTEM(IMS), the program will run as an IMS application program. ═══ ═══ If you specify SYSTEM(TSO), the program will run as a TSO command processor. ═══ ═══ opt-list is specified with the following option keywords, their negative forms, or their abbreviated forms, in the option list: AGGREGATE ATTRIBUTES ESD INSOURCE LIST MAP OFFSET OPTIONS SOURCE STORAGE XREF The other options that relate to the listing (FLAG, GONUMBER, GOSTMT, LINECOUNT, LMESSAGE/SMESSAGE, MARGINI, NEST, NUMBER, and the SHORT and FULL suboptions of ATTRIBUTES and XREF) are the same as for the SYSPRINT listing. ═══ ═══ BLOCK tells the compiler to insert hooks at block boundaries (block entry and block exit). ═══ ═══ STMT tells the compiler to insert hooks at statement boundaries and block boundaries. STMT causes a statement table to be generated. ═══ ═══ PATH tells the compiler to insert hooks:  Before the first statement enclosed by an iterative DO statement  Before the first statement of the true part of an IF statement  Before the first statement of the false part of an IF statement  Before the first statement of a true WHEN or OTHERWISE statement of a SELECT. group  Before the statement following a user label  At CALLs or function references, both before and after control is passed to the routine  At block boundaries. When PATH is specified, the compiler generates a statement table. ═══ ═══ ALL tells the compiler to insert hooks at all possible locations and to generate a statement table. ═══ ═══ NONE tells the compiler not to put hooks in the program. ═══ ═══ SYM tells the compiler to create a symbol table that will allow you to examine variables by name. ═══ ═══ NOSYM tells the compiler not to generate a symbol table. ═══ ═══ NOTEST suppresses the generation of all testing information. ═══ ═══ FULL is the default suboption. All identifiers and attributes are included in the compiler listing. FULL applies by default if the XREF option is specified with no suboption. ═══ ═══ SHORT specifies that unreferenced identifiers are to be omitted from the compiler listing. If the suboption SHORT is specified, unreferenced identifiers are omitted. ═══ ═══ In its simplest form, the PLI command consists of the keyword and the conventional name of the TSO data set holding the PL/I source program. For example: PLI CALTROP ═══ ═══ If the source program does not have a conventional data set name, you need to specify the full name and enclose it in single quotation marks: PLI 'JJONES.SAMPLE.PLI' ═══ ═══  You can make your own choice of name for the object module data set by including the OBJECT compile-time option as an operand of the PLI command. For example, if you issue the command: PLI CALTROP OBJECT(TRAPA) the system adds the same qualifiers to this name as it does to the source data set simple name, so the object module is written onto a data set. In this example, if the user identification was WSMITH, the object module data set would be named WSMITH.TRAPA.OBJ.  You can specify the full name of the object module data set by enclosing it in quotation marks. For example, if you issue the command: PLI CALTROP OBJECT('NATANS') the system in this case adds no qualifiers, so the object module is stored on a data set called NATANS.  You can specify a full name to store the object module with another user's user-identification. For example, the following command would store the object module using the user-identification JJONES: PLI CALTROP OBJECT('JJONES.CALTROP.OBJ') ═══ ═══ data-set-name specifies the name of the primary input data set for the compiler. This can be either a fully qualified name (enclosed in single quotation marks) or a simple name (for which the prompter adds the identification qualifier, and the descriptive qualifier PLI). This must be the first operand specified when you use the PLI command. ═══ ═══ option-list specifies one or more compiler options that apply for this compilation. Programmers familiar with batch processing should note that defaults are altered for TSO, and that the DECK, MDECK, and OBJECT options are extended to allow specific names of data sets onto which the output is written. Separate the options by at least one blank or comma. The order of the options is unimportant. If two contradictory options are specified, the last is accepted and the first ignored. Options specified in the PLI command can be overridden by options specified by %PROCESS compiler control statements in the primary input. If the DECK, MDECK, and OBJECT options are required for any program in a batched compilation, the options should be specified with the PLI command so that the prompter allocates the required data sets. The negative forms can then be used on the %PROCESS statements for the programs that do not require the options. The options are described below.  DECK[(dsname)]: This can be a full-qualified name (enclosed in single quotation marks) or a simple name (to which the user identification and descriptive qualifier DECK is added). If dsname is not specified, the user-supplied name is taken from the first operand of the PLI command, and the user-identification and descriptive qualifier DECK is added. If dsname is not specified and the first operand of the PL/I command specifies a member of a partitioned data set, the member name is ignored- the generated data set name is based on the name of the partitioned data set.  MDECK[(dsname)]: This can be a fully-qualified name (enclosed in single quotation marks) or a simple name (to which the user identification and descriptive qualifier MDECK is added). If dsname is not specified, the user-supplied name is taken from the first operand of the PLI command, and the user-identification and descriptive qualifier MDECK is added. If dsname is not specified and the first operand of the PL/I command specifies a member of a partitioned data set, the member name is ignored- the generated data set name is based on the name of the partitioned data set.  OBJECT[(dsname)]: This can be a fully-qualified name (enclosed in single quotation marks) or a simple name (to which the user identification and descriptive qualifier OBJ is added). If dsname is not specified, the user-supplied name is taken from the first operand of the PLI command, and the user-identification and descriptive qualifier OBJ is added. If dsname is not specified and the first operand of the PL/I command specifies a member of a partitioned data set, the member name is ignored- the generated data set name is based on the name of the partitioned data set. ═══ ═══ PRINT specifies that the compiler listing will be written, either to the terminal or to a file (depending upon which PRINT arguments are used). If you specify PRINT with no arguments the compiler listing, on the SYSPRINT file, is written at the terminal. ═══ ═══ PRINT(*) specifies that the compiler listing, on the SYSPRINT file, is written at the terminal. No other copy will be available. The PRINT(*) operand is implemented by generating a TERMINAL option with a list of options which correspond to the listings printed at the terminal. If you specify the TERMINAL option after the PRINT(*) operand, this overrides the TERMINAL option generated by the PRINT(*) operand. ═══ ═══ dsname specifies the name of the data set to which the compiler listing is written. This can be either a full-qualified name (enclosed in single quotation marks) or a simple name (for which the prompter adds the identification qualifier, and the description qualifier LIST). If you do not specify a dsname argument for the PRINT operand, the prompter adds the identification and descriptive qualifiers to the data set name specified in the first operand, producing a data set name of the form: user-identification.user-supplied-name.LIST If dsname is not specified and the first operand of PLI specifies a member of a partitioned data set, the member name is ignored- the generated data set name is based on the name of the partitioned data set. ═══ ═══ , If n is omitted, the preceding comma must be included. For example, to enter only the size of the secondary allocation and accept the default for the primary you would enter: PRINT(printds,,500) The space allocation used if n and m are not specified is the allocation specified during compiler installation. ═══ ═══ n and m specify the space allocation in lines for the listing data set. They should be used when the size of the listing has caused a B37 abend during compilation. n specifies the number of lines in the primary allocation. If n is omitted, the preceding comma must be included. For example, to enter only the size of the secondary allocation and accept the default for the primary you would enter: PRINT(printds,,500) The space allocation used if n and m are not specified is the allocation specified during compiler installation. ═══ ═══ m and n specify the space allocation in lines for the listing data set. They should be used when the size of the listing has caused a B37 abend during compilation. m specifies the number of lines in the secondary allocation. The space allocation used if n and m are not specified is the allocation specified during compiler installation. ═══ ═══ SYSPRINT specifies that the compiler listing, on the SYSPRINT file, is to be written to the sysout class named in parentheses. If no class is specified, the output is written to a default sysout class. The IBM-supplied default is class A. ═══ ═══ sysout-class specifies the sysout class to which the compiler listing, on the SYSPRINT file, is to be written. If no class is specified, the output is written to a default sysout class. The IBM-supplied default is class A. ═══ ═══ NOPRINT specifies that the compiler listing is not produced on the SYSPRINT file. You can still get most of the listing written at the terminal by using the TERMINAL compiler option. ═══ ═══ LIB(dslist) specifies one or more data sets that are used as the secondary input to the preprocessor. These data sets are concatenated in the order specified and then associated with the ddname in the %INCLUDE statement in the PL/I program. You must allocate the data sets associated with that ddname yourself. The data sets can be either fully qualified (each enclosed in single quotation marks) or simple names (for which the prompter adds the identification qualifier, but no descriptive qualifier). Separate the data set names by at least one blank or one comma; you can add any number of extra blanks. If you use the LIB operand, either the INCLUDE or the MACRO compiler option must also apply. ═══ ═══ PRINT specifies that the listing file is directed to the PRINTER and is not placed on a disk. ═══ ═══ DISK specifies that the listing file is placed on a disk. ═══ ═══ TYPE specifies that the listing file is displayed on your terminal and is not placed on a disk. ═══ ═══ NOPRINT specifies that the listing file is not produced. ═══ ═══ OBJECT An additional facility, OBJECT[(file name)] allows you to specify a different name for your file. In the OBJECT option specification, "file name" is the name that will be given to the text file. If it is omitted, the text file will be given the same name as the file specified in the PLIOPT command. The text file will be placed on one of your disks in accordance with the following rules: ┌─────────────────────────────────┬──────────────────────────────────────┐ │ IF THE DISK THAT CONTAINS THE │ THEN THE DISK THAT CONTAINS THE │ │ PL/I SOURCE FILE IS ACCESSED... │ OUTPUT FILES (TEXT, LISTING) IS: │ ├─────────────────────────────────┼──────────────────────────────────────┤ │ Read/Write... │ the disk that holds the PL/I source.│ ├─────────────────────────────────┼──────────────────────────────────────┤ │ as an extension of a │ the Read/Write disk. │ │ READ/WRITE disk... │ │ ├─────────────────────────────────┼──────────────────────────────────────┤ │ as an extension of a Read-only │ the A-disk. │ │ Disk and the A-disk is accessed │ │ │ Read/Write... │ │ ├─────────────────────────────────┼──────────────────────────────────────┤ │ as an extension of a Read-only │ ERROR DMSPLI006E- program │ │ Disk and the A-disk is accessed │ terminates. │ │ Read Only... │ │ └─────────────────────────────────┴──────────────────────────────────────┘