This chapter defines the Open PL/I statements. The statements are presented in alphabetical order by name.
Each statement definition consists of the following subsections: purpose, syntax, parameters, description (the effect of executing the statement), examples (one or more examples of the statement's usage), and restrictions (any limitations on using the statement). In most cases, the statement is described in the context of the example(s) given in the "Example" section of the statement definition.
Where one statement has several different forms, each form of the statement is presented. The header lists the main statement with the variation of that statement following it. For example:
The previous example shows the header for the INT pseudovariable assignment, which is one type of assignment statement.
Statements may be prefixed by one or more statement labels. A statement label is a name followed by a colon (:). The name can be specified with a subscript. For example:
DCL_TOP: DECLARE (A,B) FIXED BINARY(31) ... LL(1): READ FILE(F) INTO(REC(1)); GOTO NAME_X; LL(2): READ FILE(F) INTO(REC(2)); GOTO NAME_Y; ... NAME_X: NAME_Y: A = B + 1
Square brackets used in the syntax diagrams indicate optional parts of statements and are not part of statement punctuation. Unless a label prefix is required by a statement, it is not shown in the syntax diagram of the statement.
Allocates a block of storage for the values described by a based or controlled variable. The ALLOCATE statement also permits the assignment of explicit attributes to CONTROLLED variables at the time of allocation.
ALLOCATE var_ref [IN (area_ref)] [SET(loc_ref)] [, var_ref [IN ( area_ref)] [SET( loc_ref)]]...
For CONTROLLED variables:
ALLOCATE based-or-controlled-alloc[, based-or-controlled-alloc]...;
where based-or-controlled-alloc is:
based-alloc|controlled-alloc
where based-alloc is:
var_ref[IN(area-ref)][SET(loc_ref)]
and controlled-alloc is:
[level-num]cvar_ref[attribute]...
where attribute is:
dimension-attribute |CHARACTER(length) |BIT(length) |AREA(size) |initial-attribute
Abbreviation(s): ALLOC for ALLOCATE
var_ref | One or more references to a based or controlled nonmember variable or variables. |
loc_ref | Specifies the locator variable (for based variables) to which the storage location is assigned if the SET option is chosen. |
area_ref | Identifies the area in which the based storage is allocated if the IN option is used. |
cvar_ref | A CONTROLLED variable |
The dimension-attribute can be specified only for variables that are declared with a dimension-attribute, and it must specify the same number of dimensions as in the declaration.
The CHARACTER, BIT, and AREA attributes can be specified only for variables that are declared with the same attribute.
For more detailed information on BASED and CONTROLLED variables and their use with ALLOCATE statements, see the sections Based Variables and Controlled Variables.
The ALLOCATE statement allocates a block of storage for the values described by a based variable.
The SET option and the IN option are not required in an ALLOCATE statement. If used, they can be specified in either order.
If the SET option is used in conjunction with any var_ref, the address of the allocated storage will be stored in the specified loc_ref for that var_ref. The SET option cannot be used when controlled variables are allocated.
If the SET option is not used, the allocated address will be stored in the locator reference that was assigned with the based variable when it was declared. If no locator reference was assigned with the based variable, an error occurs.
If the IN option is used, or if the SET option specifies an offset variable, the allocation occurs in an area. If the IN option is omitted and the SET option specifies an offset variable, that variable must, in its declaration, have been associated with an area. See the description of the OFFSET attribute in the section Offset.
DECLARE 1 A_STRUCT BASED (A_PTR), 2 A_MEMBER FIXED BIN(15); DECLARE (A_PTR, B_PTR, C_PTR) POINTER; DECLARE 1 B_STRUCT BASED (B_PTR), 2 B_MEMBER FIXED BIN(15); DECLARE 1 C_STRUCT BASED (C_PTR); 2 C_MEMBER FLOAT BIN(23); DECLARE (P,Q) POINTER; ALLOCATE A_STRUCT; A_STRUCT.A_MEMBER = 5; ALLOCATE B_STRUCT SET (P), C_STRUCT SET(Q);
In the preceding example, A_STRUCT is allocated, and since no SET option was specified and A_STRUCT was declared as based on A PTR, the allocated address is stored in A_PTR. When B_STRUCT is allocated, the SET option specifies that P is to be assigned the allocated address. When B_STRUCT and C_STRUCT are allocated, the SET options cause the addresses of the allocated storage for them to be assigned to P and Q, respectively.
DECLARE (A, B) AREA; DECLARE A1 CHAR(20) BASED; DECLARE A2 CHAR(20) BASED(02); DECLARE A3 CHAR(20) BASED(03); DECLARE (01, 02) OFFSET(A); DECLARE 03 OFFSET; DECLARE (P1, P3) POINTER; ALLOCATE A1 SET(P1); ALLOCATE A1 SET(01); ALLOCATE A2; ALLOCATE A3 IN(B); P3 = POINTER(03, B);
In Example 8-2 above, the first allocation of A1 is not in an area because the locator reference in the SET option specifies a pointer variable. The second allocation of A1 occurs in area A, because the locator in the SET option specifies an offset variable associated with area A. The allocation of A2 again occurs in area A, because A2 is based on offset variable 02, which was associated with area A in its declaration. The IN option causes the allocation of A3 to occur in area B. (Note that, in order to address A3, the POINTER built-in function must be used, because 03 was not declared with an area association).
None.
Assigns a value to one or more specified variables.
target[,targetn]… =expression[,BY NAME];
target(s) | Either variable references or pseudovariables. |
expression | Any valid expression. |
The assignment statement evaluates expression and assigns its value to the specified variable or variables.
The assignment statement evaluates the target references and the expression in an unspecified order, converts the expression's value to the data type of each target, and then assigns the converted value to each of the targets in turn (in left-to-right order). For the rules for converting data types, see the chapter Data Type Conversions.
Assignments to a bit-string or character-string target that is shorter than the converted source value cause truncation of the rightmost bits or characters of the source value.
Assignments to nonvarying character-string targets result in padding of the converted source value on the right with sufficient blanks to make it the length of the target.
Assignments to a varying character-string target cause the target to obtain the current length of the newly assigned value.
Assignments to bit-string targets result in padding of the source value on the right with sufficient zero bits to make it the length of the target.
The value of expression can be assigned to more than one target. If the assignment is a structure assignment using the BY NAME option, such a multiple assignment affects only those elementary items that have names in common in all of the structures on both sides of the statement.
The BY NAME option is used in structure assignments to assign to the target structure only the values of those items in the structures specified in expression that have names in common with items contained in the target. The BY NAME option can be used only when the right-hand side contains at least one structure. In such a case, the BY NAME structure assignment is equivalent to a series of scalar or array assignments. There is one such assignment for each scalar or array member of the target structure for which the following condition is true: every structure referenced in the right-hand side has a corresponding scalar or array member whose full structure name (except for the top-level structure name) is identical to the target member's full structure name (except for its top-level structure name). These separate assignments are generated in the order in which the scalar and array members occur in the target structure. For example:
DECLARE 1 STRUC1, 2 A … , 2 B, 3 M … , 3 N … , 3 O … , 2 C … , 2 D … ; DECLARE 1 STRUC2, 5 C … , 5 D … , 5 B, 10 L … , 10 M … , 10 O … ; DECLARE 1 STRUC3, 2 A … , 2 D … , 2 C … , 2 E, 3 M … , 3 N … , 3 O … , 2B, 3 M … , 3 N … ; STRUC1 = STRUC2 + STRUC3, BY NAME;
This assignment is equivalent to the series of assignments:
STRUC1.B.M = STRUC2.B.M + STRUC3.B.M; STRUC1.C = STRUC2.C + STRUC3.C; STRUC1.D = STRUC2.D + STRUC3.D;
A = B+C; A,B = B*C; /*A and B will each have the value of B*C */ X(K) = 5; P->NODE.VALUE = SQRT(X(J)); SUBSTR(S,I,J) = 'ABC';
In case of array assignment, each target variable must be an array. The right-hand side can be an array or element expression. If the right-hand side contains an array, its shape must be identical to the shape of the target array.
In case of structure assignment, each target variable must be a structure. The right-hand side can be a structure or element expression. If the right-hand side contains a structure, its shape must be identical to the shape of the target structure.
Because the target and the expression are evaluated in an unspecified order, functions or ON-units called during these evaluations may be affected by possible side effects, such as assignments to subscripts or pointers used in the target reference or freeing the target's storage. Likewise, the storage of the target must not be freed by the execution of a function or ON-unit called during evaluation of the expression.
Programs that depend on the order of evaluation may fail when moved to other implementations of PL/I.
Assigns a signed integer value to specified storage.
INT(reference[, position[, length]]) = expression
reference | A reference to connected storage; reference cannot be an array, structure, or named constant. |
position | A positive integer value specifying the position of the first bit in the field. |
length | A positive integer value in the range 0 – 32 specifying the length of the field. |
The INT pseudovariable assigns a signed integer value to specified storage. expression is converted to Fixed Bin(31). The internal representation of the resulting integer value is then assigned to the storage specified by the arguments to INT.
If position is specified, its minimum value is 1 and its maximum value is the length in bits of the storage specified by reference. If positionis omitted, the default value is 1.
If length is specified, its minimum value is 0 and its maximum value is the length in bits of the storage specified by reference, less the value of position. If length is omitted, the default value is equal to the number of bits from the bit indicated by position to the end of the storage specified by reference.
INT and POSINT are identical pseudovariables, except that POSINT assigns an unsigned integer.
The result of this pseudovariable is dependent on the native byte ordering of the hardware you are using. For this reason, the use of this function may not be portable across different platforms.
None.
Sets the current value of the ONCHAR built-in function.
ONCHAR() = string
or
ONCHAR = string
The second syntax form can be used only when ONCHAR has been explicitly declared using the BUILTIN attribute.
string | An expression that is converted to a character string of length 1. |
The ONCHAR pseudovariable is used to replace the invalid character that caused the CONVERSION condition to be raised. This new character is used when the conversion is attempted again.
The ONCHAR pseudovariable is valid only in the context of a CONVERSION ON-unit. In all other cases the ONCHAR pseudovariable is ignored.
DCL I FIXED BIN(15); ON CONVERSION BEGIN; ONCHAR() = '0'; END; I ='34Z9'; PUT LIST(I);
In the above example, an invalid character, 'Z,' is changed to '0'; therefore, the program will display an integer value of 3409.
None.
Sets the current value of the ONSOURCE built-in function.
ONSOURCE() = string
or
ONSOURCE = string
The second syntax form can be used only when ONSOURCE has been explicitly declared using the BUILTIN attribute.
string | An expression that is converted to a character string. If the length of the field that caused the CONVERSION condition is greater than the length of string, string is padded with blanks. If the length of the field is less than the length of string, string is truncated to match the field length. |
is
The ONSOURCE pseudovariable is used to replace the invalid string that caused the CONVERSION condition to be raised. This new string is used when the conversion is attempted again.
The ONSOURCE pseudovariable is valid only in the context of a CONVERSION ON-unit. In all other cases, the ONSOURCE pseudovariable is ignored.
DCL I FIXED BIN(15); ON CONVERSION BEGIN; ONSOURCE() = '0'; END; I = STRING VALUE; PUT LIST(I);
If STRING_VALUE contains an invalid character, use of the ONSOURCE pseudovariable in the above example resets STRING_VALUE to zero. Therefore, the program will display an integer value of 0.
None.
Changes the current page number that serves as the value of the PAGENO built-in function.
PAGENO(f) = e;
f | A reference to a file constant, or to a file variable that has been assigned a file constant value. |
e | Any valid expression. |
The PAGENO pseudovariable refers to the page number of the referenced print file.
Assignment to the PAGENO pseudovariable modifies the current page number by causing the expression e to be evaluated and converted to a binary integer value of default precision, then assigned as the current page number of the file identified by f. (For details on default precisions, see your Open PL/I User's Guide.)
The file must be open and must describe a STREAM OUTPUT PRINT file.
The PAGENO assignment does not cause any additional pages to be output to the file; it simply changes the current page number that serves as the value of the PAGENO built-in function.
DECLARE F FILE; . . . PAGENO(F) = 10;
None.
Assigns an integer value to specified storage.
POSINT(expression1[,position[,length]]) = expression2
expression1 | A reference to connected storage; expression1 cannot be an array, structure, or named constant. |
position | A positive integer value specifying the position of the first bit in the field. |
length | A positive integer value in the range 0 – 32 specifying the length of the field. |
expression2 | Any expression that evaluates to an integer. |
The POSINT pseudovariable assigns an integer value to specified storage. expression2 is converted to Fixed Bin(31). The internal representation of the resulting integer value is then assigned to the storage specified by the arguments to POSINT
If position is specified, its minimum value is 1 and its maximum value is the length in bits of the storage specified by expression1. If position is omitted, the default value is 1.
If length is specified, its minimum value is 0 and its maximum value is the length in bits of the storage specified by expression1, less the value of position. If length is omitted, the default value is equal to the number of bits from the bit indicated by position to the end of the storage specified by expression1.
POSINT and INT are identical pseudovariables, except that INT assigns a signed integer.
The result of this pseudovariable is dependent on the native byte ordering of the hardware you are using. For this reason, the use of this function may not be portable across different platforms.
None.
Assigns the converted value of the expression e to r, as if r were a nonvarying string variable whose length is the total number of characters or bits in the variable identified by r.
STRING(r)=e;
r | A reference to a string, array, or structure variable that is also suitable for string overlay storage sharing, as described in the section Storage Sharing. |
e | Any valid expression. |
The STRING pseudovariable interprets an appropriate reference as a reference to a fixed-length string.
The STRING assignment assigns the converted value of the expression e to r, as if r were a nonvarying string variable whose length is the total number of characters or bits in the variable identified by r. The STRING assignment can modify an entire aggregate with a single string assignment or assign the aggregate to a pictured variable as if it were a character-string variable.
DECLARE A(5) CHARACTER(1); . . . STRING(A) = 'ABCDE';
After the previous assignment, A (1) has the value of 'A' , A (2 ) has the value of 'B', and so forth.
None.
Modifies only the substring.
SUBSTR(r,i,j)=e;
or
SUBSTR(r,i)=e;
or
SUBSTR(array,i,j)=string_value;
r | A reference to a character or bit-string variable. |
I | A fixed-point integer-valued expression; the index of the first character or bit in r to change. |
j | A fixed-point integer-valued expression; the number of bits or characters to be changed. |
e | An expression that can be converted to a character string or bit string. |
array | ? |
The SUBSTR pseudovariable refers to a substring of a specific string variable reference.
Assignment to the SUBSTR pseudovariable modifies only the substring portion of r. If r identifies a varying string, the substring assignment does not modify the length component of that string.
If r identifies a varying string, w is the current length of r. If r identifies a nonvarying string, w is the declared length of the string variable. If j is omitted, j is assumed to be w-I+1. The value of e is assigned to the substring according to the assignment rules for nonvarying strings.
DECLARE S CHARACTER(10); . . . SUBSTR(S,3,4) = 'ABC';
After the assignment, the 3rd character of S is 'A', the 4th is 'B', the 5th is 'C', and the 6th is blank. The other characters of S are unchanged by the assignment.
The following restrictions on I, j, and w must be satisfied or the program may be in error, causing the ERROR condition to be generated if compiled with subscript checking enabled, or unpredictable results if compiled without subscript checking enabled.
1<=I<=w I+j-1<=w j>0
The previous restrictions ensure that I is the index of a character or bit within the string, and that a substring of j characters or bits beginning with the Ith character or bit can be accessed without exceeding the length of the string. These formulas also ensure that I is less than or equal to the length of string r if j=0. If j is omitted, the substring begins with the Ith character or bit and extends to the end of the string. No other portion of the target string is affected by the assignment.
The substring described by I and j is assigned the converted value of the expression e as if the substring were a nonvarying string.
Evaluates and converts an expression to a bit string.
UNSPEC(r)=e;
r | A reference to any variable except an array or structure. |
e | Any valid expression. |
The UNSPEC pseudovariable interprets any reference to a scalar variable as a reference to a bit string.
Assignment to the UNSPEC pseudovariable evaluates and converts the expression e to an implementation-defined bit string that is copied into the storage of r (For more information, see your Open PL/I User's Guide.) Subsequent use of r is invalid unless the bit string is a valid value for that variable.
Use of the UNSPEC pseudovariable is discouraged, since it relies heavily on particulars of the PL/I implementation and, as such, may prove to be an obstacle to portability.
UNSPEC©) = '0'B;
After the previous assignment, C contains all zero bits.
None.
Groups a set of program statements and defines a scope for the names declared within it.
BEGIN[ORDER|REORDER];
The BEGIN statement defines a begin block and indicates the start of that block. The block must end with an END statement.
The BEGIN statement is an executable statement that may appear as a THEN clause or as an ELSE clause of an IF statement, as an ON-unit of an ON statement, or as a simple statement anywhere in a procedure.
When the BEGIN statement executes, it activates the begin block. The block activation terminates when the corresponding END statement executes, when a RETURN statement executes (which terminates the enclosing procedure), or when a GOTO statement that references a label external to the block executes.
Since the execution of a BEGIN statement incurs the additional time and space overhead needed to set up a block activation, a simple DO group is preferred for elementary statement bracketing. Note, however, that the DO group cannot serve as an ON-unit, nor does it introduce a new scope for declarations. The BEGIN statement must be used in such instances.
ORDER and REORDER are options sometimes used for optimization in IBM mainframe PL/I programs. They are not needed by Open PL/I; these options are simply parsed and otherwise ignored by Open PL/I.
BEGIN; . . . END; ON ERROR BEGIN; . . . END;
None.
Transfers control to an entry point of a procedure and optionally passes arguments to the procedure.
CALL reference[([argument][,argument]…)];
reference | Identifies an entry name, entry variable, or entry-valued function. |
argument | An expression. |
The CALL statement transfers control to an entry point of a procedure and optionally passes arguments to the procedure.
Execution of a CALL statement activates the procedure block identified by a reference, which can be an entry name, entry variable, or entry-valued function. The procedure designated by that entry value is called and passed any arguments given with the reference. The procedure thus activated must not have a RETURNS option and must have the same number of parameters as the reference has arguments, unless the declaration of the ENTRY name includes the OPTIONS(VARIABLE) attribute. A procedure with no argument can be called using a reference with an empty argument list () or no argument list. If the procedure is called with an argument list, each argument in that list is evaluated and, if necessary, converted to the data type of the corresponding parameter. For a discussion of argument passing and parameters, see the section Parameter Storage Class.
The order in which arguments and other components of the reference in a CALL statement are evaluated is unspecified.
DECLARE E ENTRY (FIXED BINARY, FIXED BINARY, FLOAT BIN); DECLARE F ENTRY; DECLARE G ENTRY; CALL E(A,B,5+X); CALL F; CALL G();
None.
Disassociates a file value from the physical file with which it was associated when it was opened.
CLOSE FILE(reference)[ENVIRONMENT(LEAVE|REREAD)] [,FILE(reference)[ENVIRONMENT(LEAVE|REREAD)]]…;
Abbreviation(s): ENV for ENVIRONMENT.
reference | Identifies one or more file constants, file variables, or file-valued functions. |
ENVIRONMENT | An option used by IBM PL/I programs to control disposition of magnetic tapes after the file is closed. Open PL/I simply parses and otherwise ignores this option. |
The CLOSE statement disassociates an Open PL/I file value from the physical file with which it was associated when it was opened.
Execution of a CLOSE statement closes the files identified by the references. Once closed, the files can be reopened and given different file attributes. It can also be used to designate a different operating system file or device.
Closing a closed file has no effect and is not an error.
Upon program termination (including abnormal termination), files not closed will be implicitly closed.
CLOSE FILE(F); CLOSE FILE(G(K)); CLOSE FILE (L), FILE (M);
None.
Specifies the attributes associated with names.
DECLARE declaration[,declaration]…;
Abbreviation(s): DCL for DECLARE.
declaration |
One or more declarations consisting of an identifier and attributes. The format of each declaration is: [level]identifier[(bound-pair,…)][attribute…] or [level](declaration,…)[(bound-pair,…)] [attribute…] where: level specifies the relationship of members of structures bound-pair specifies the dimensions of arrays attribute specifies one or more attributes of the identifier If a level is specified, it must be written first in the declaration. If a bound-pair is used, it must be in parentheses and must immediately follow the identifier or the parenthetical list of declarations. |
The format of the DECLARE statement varies according to the number and nature of the items being declared. For example, the DECLARE statement can list one identifier and optionally specify a level, bound-pair list, and other attributes for that identifier. Or the statement can include, in parentheses, a list of declarations to which the level and all subsequent levels apply. The declarations in the second case can be simple identifiers or can include attributes that are specific to individual identifiers.
The DECLARE statement specifies the attributes associated with names. This statement has five formats:
Each of these formats is described separately in the following sections. (for more information on attributes, see the chapter Declarations and Attributes.)
A DECLARE statement cannot be used as a THEN clause or ELSE clause of an IF statement or as the ON-unit of an ON statement. A DECLARE statement cannot be used in a WHEN or OTHERWISE clause of a SELECT statement.
Defines one name and describes its attributes.
DECLARE identifier[attribute];
identifier | A user-supplied name of 1 – 32 characters that is unique within the current block and can consist of any alphanumeric character A through Z, a through z, 0 through 9, @, #, $, and _, but must begin with a letter, dollar sign ($), at sign (@), or underscore (_). |
attribute | One or more valid attributes of the name, each of which must be separated by a space, but can appear in any order. |
A simple declaration defines one name and describes its attributes. (For more information on attributes, see the chapter Declarations and Attributes.)
DECLARE COUNTER FIXED BINARY (8); DECLARE TEXT_STRING CHARACTER (60) VARYING BASED (P);
In this example, the variable COUNTER is declared with the data type attribute FIXED and BINARY (8) , and the variable TEXT_STRING is declared with the attribute CHARACTER (60), VARYING, and BASED (P).
None.
Allows a variable to be declared outside of any procedure and to be visible within all procedures contained in the module.
DECLARE identifier[attribute];
A variable can be declared outside of any procedure and will be visible within all procedures contained in the module (for more information, see the section Modules). If no storage class is specified, STATIC is supplied by default.
The storage class for declarations outside of procedures cannot be AUTOMATIC.
DECLARE B STATIC FIXED BINARY(31); . . . SECOND: PROCEDURE; DECLARE C FIXED BINARY (31); . . . THIRD: PROCEDURE; DECLARE D FIXED BINARY(31); . . . END THIRD; END SECOND;
In this example, variable B can be referenced from both the SECOND and the THIRD procedure.
None.
Defines two or more names and their individual attributes.
DECLARE identifier[attribute…][,identifier[attribute…]]…;
Multiple declarations define two or more names and their individual attributes. (for more information on attributes, see the chapter Declarations and Attributes.)
Each set of names and its attributes must be separated from other sets of names and their attributes by a comma. A semicolon must follow the last name.
DECLARE COUNTER FIXED BINARY (6), TEXT_STRING CHARACTER (79) VARYING, Y FILE;
In this example, the variable COUNTER is declared with the data type attribute FIXED and BINARY (6), the variable TEXT_STRING is declared with the attribute CHARACTER (79) and VARYING, and the variable Y is declared with the data type attribute FILE .
None.
Allows two or more names that have the same attribute to be combined into a single, factored declaration.
DECLARE(identifier[,identifier…])[attribute…];
Names that share common attributes can be placed within parentheses and must be separated with commas. The attributes that follow the parenthetical list of names are applied to all of the named identifiers.
You can also specify, within the parentheses, attributes that are unique to specific variable names using the following format:
DECLARE(identifier[attribute]…,identifier[attribute]…)attribute…;
When two or more names have the same attribute, you can combine the declarations into a single, factored declaration. (For more information on attributes, see the chapter Declarations and Attributes.)
DECLARE (COUNTER, RATE, INDEX) FIXED BINARY (6) INITIAL (0);
In this example, the variables COUNTER, RATE, and INDEX share the attributes FIXED BINARY (6) and are given the initial value of zero.
DECLARE (INFILE INPUT RECORD, OUTFILE OUTPUT STREAM) FILE;
In this example, the DECLARE statement declared INFILE as a RECORD INPUT file and OUTFILE as an OUTPUT STREAM file.
Parentheses can be nested, as shown in the following example.
DECLARE ((INFILE INPUT, OUTFILE OUTPUT) RECORD, SYSFILE STREAM) FILE;
In this example, the DECLARE statement declares INFILE as a RECORD INPUT file, OUTFILE as a RECORD OUTPUT file, and SYSFILE as a STREAM INPUT file (STREAM implies INPUT).
None.
Specifies the dimensions of the array and the bounds of each dimension.
DECLARE identifier(bound-pair,…)[attribute…];
Or
DECLARE(declaration,…)(bound-pair,…)[attribute…];
Each bound-pair has the format:
[lower-bound:]upper-bound
or
*
The declaration of an array specifies the dimensions of the array and the bounds of each dimension.
One bound-pair is specified for each dimension of the array. The number of elements per dimension is defined by the bound pair. The extent of the array is the product of the numbers of elements in its dimensions. If the lower bound is omitted, the lower bound for that dimension is 1 by default.
The asterisk (*) can be used as the bound pair when arrays are declared as parameters of a procedure. The asterisk causes the indicated parameter subscript to be the same bound pair as the corresponding argument subscript. (If one dimension is specified with an asterisk, then all dimensions must be so specified.)
DECLARE SALARIES(200) FIXED DECIMAL(6,2);
In the previous example, the DECLARE statement declares a 200-element array with the identifier SALARIES. Each element of the array is a fixed-point decimal number with a total of six digits, two of which are fractional.
The identifier in the previous statement can be replaced with a list of declarations, to declare several objects with the same attributes, as shown in the following example:
DECLARE (SALARIES,PAYMENTS) (100) FIXED DECIMAL(6,2);
This declaration declares SALARIES and the array PAYMENTS with the same dimensions and the same type.
DECLARE TOTALS(*,*) FIXED BINARY(15);
This declaration declares TOTALS with two subscripts, each with variable extents. Note that TOTALS must be a parameter.
Up to eight subscripts can be used to reference the elements of an array. For example:
DECLARE TOTALS(*,*) FIXED BINARY(15);
This declaration declares TOTALS with two subscripts, each with variable extents. Note that TOTALS must be a parameter.
Defines the organization of the structure and the names of members at each level of the structure.
DECLARE declaration[,…];
Each declaration is:
level identifier[(bound-pair)][(,…bound-pair)][attribute…]
or
level(declaration)[,…(declaration)][(bound-pair)][(,…bound-pair)][attribute…]
The declaration of a structure defines the organization of the structure and the names of members at each level of the structure. Each declaration specifies a member of the structure and must be preceded by a level-number. A single variable can be declared at a particular level, or the level can contain one or more complete declarations, including declarations of arrays or other structures. The major structure name is declared as structure level 1. Minor members must be declared with level-numbers greater than 1.
DECLARE 1 PAYROLL, 2 NAME, 3 LAST CHARACTER(70) VARYING, 3 FIRST CHARACTER(70) VARYING, 2 SALARY FIXED DECIMAL(6,2);
The following statement declares a structure named PAYROLL, whose last name can be accessed with a qualified reference:
PAYROLL.NAME.LAST = 'JONES';
Since the last and first names have the same attributes, the same structure can be declared as follows:
DECLARE 1 PAYROLL, 2 NAME, 3 (LAST,FIRST) CHARACTER(70) VARYING 2 SALARY FIXED DECIMAL(6,2);
The following example shows a declaration containing the UNION attribute.
DECLARE 1 CONSUMER_INFO, . . . 3 PHONE_DATA UNION, 4 PHONE_NUMBER CHARACTER (13), 4 ELEMENTS, 5 LEFT_PAREN CHARACTER (1), 5 AREA_CODE CHARACTER (3), 5 RIGHT_PAREN CHARACTER (1), 5 EXCHANGE CHARACTER (3), 5 HYPHEN CHARACTER (1), 5 ACTUAL_NUMBER CHARACTER (4), 3 ADDRESS_DATA, . . .
In this example, the UNION attribute associated with the declaration of PHONE_DATA's immediate members (PHONE_NUMBER and ELEMENTS) share the same storage, so any change to PHONE NUMBER also changes one or more members of ELEMENTS. Conversely, changing a member of ELEMENTS also changes PHONE_NUMBER. However, the UNION attribute does not apply to the members of ADDRESS_DATA, because these members are not immediate members of PHONE_DATA. The members of ADDRESS_DATA occupy separate storage, as is typical for structure members.
None.
Specifies data attribute defaults in cases where attribute sets are incomplete.
DEFAULT simple-spec|factored-spec[,simple-spec|factored-spec]…;
where simple-spec is:
RANGE(letter[:letter][,letter[:letter]…)attribute-spec;
or
RANGE(*)[attribute-spec];
where factored-spec is:
(simple-spec|factored-spec[,simple-spec|factored-spec]…)[attribute-spec]
where attribute-spec is:
[attribute-list][VALUE(value-spec[,value-spec]…)
where attribute-list is a list of attributes separated by at least one space.
attribute[ attribute]…
where attribute is:
ALIGNED | AREA | AUTOMATIC | BASED | BINARY | BIT | CHARACTER | CONTROLLED | DECIMAL | DEFINED | DIMENSION | ENTRY | EXTERNAL | FILE | FIXED | FLOAT | INITIAL | INTERNAL | LABEL | OFFSET | PICTURE | POINTER | STATIC | VARYING | UNALIGNED | VARIABLE
where value-spec is:
CHARACTER(length)|BIT(length)|AREA(size)|numeric-spec
where numeric-spec is:
FIXED|FLOAT|BINARY|DECIMAL[(precision[,scale])]
Abbreviation(s):
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 given in the specification must be in increasing alphabetic order. |
RANGE (letter) | Specifies that the defaults apply to names beginning with the letter specified. |
RANGE (*) | Specifies that the defaults apply to all names. |
VALUE | Establishes default rules for a string
length and numeric precision. The only attributes that the VALUE
option can influence are length and precision. Other attributes in
the option, such as FIXED or DECIMAL,
merely indicate which attributes the value is associated with. Note: A length or precision specification can be made only in the VALUE clause. They may not be specified with the attributes in attribute-list. |
Specifies data attribute defaults in cases where declared attribute sets are incomplete. Any attributes not suppled by the DEFAULT statement for any incomplete explicit, contextual, or implicit declarations are supplied by the Open PL/I default rules. (See the section Compiler-supplied 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 declare a structure.
You can use more than one DEFAULT statement within a block. The scope of a DEFAULT statement includes the block in which it occurs and all nested blocks, except those which include another DEFAULT statement with the same range or which are contained in a block having a DEFAULT statement with the same range.
Note the following special case of a DEFAULT statement that is used to restore language-specified defaults in the containing block:
MAIN: PROCEDURE; DEFAULT RANGE (a:d) FIXED DECIMAL VALUE (FIXED DECIMAL(10,2)); DCL CL_INDEX; BEGIN; DEFAULT RANGE (*); DCL C_INTERNAL FIXED DECIMAL; END; END MAIN:
in the previous example, the CL_INDEX in the MAIN routine will have precision and scale of (10,2) in accordance with the DEFAULT statement specification, while the C_INTERNAL variable will have a language default precision (5,0).
DEFAULT RANGE (l:m) FLOAT; DECLARE (low, medium) BINARY; /*In this case both variables, low and medium, will be declared as FLOAT BINARY(23).*/ DFT RANGE (*) STATIC; DECLARE (x,y) FIXED BINARY(15) INITIAL (0); DECLARE t FLOAT DECIMAL AUTOMATIC; /* In this example both x and y will have STATIC storage class, while t will have AUTOMATIC storage class due to its explicit storage class declaration. */ DEFAULT RANGE (t) VALUE (CHARACTER(6)); DCL tony CHAR; DCL tiger CHAR(20);
This statement specifies that all character variables whose name begins with the letter t have the length of 10 characters. Here, tony will have length 6, while tiger will have its explicitly specified length of 20.
None.
Delays execution for a specified length of time.
DELAY(expression)
expression is evaluated and converted to a Fixed Binary(31) value.
The DELAY statement delays execution for a length of time equal to the number of milliseconds specified by expression, rounded to the nearest whole second.
/* Both of the following statements suspend /* /* execution for one second. */ DELAY (10**3); DELAY (800);
Deletes a record from a DIRECT UPDATE or a KEYED SEQUENTIAL UPDATE file.
DELETE FILE(reference)[KEY(e)];
reference | Identifies a file value that has been opened with the DIRECT UPDATE or KEYED SEQUENTIAL UPDATE attributes. |
e | Any valid key expression. |
The DELETE statement deletes a record from a DIRECT UPDATE or a KEYED SEQUENTIAL UPDATE file. For both DIRECT UPDATE and KEYED SEQUENTIAL UPDATE files, the key expression is evaluated and converted to the appropriate form. For an indexed (VSAM) file, the key expression is converted to CHARACTER. For a relative record I/O file, it is converted to a positive integer. For indexed (VSAM) files, if the KEY clause is omitted, the last record read is deleted. The KEY clause is required for relative record I/O files. If a record with that key does not exist, the KEY condition is signaled. Return from a KEY condition ON-unit resumes execution with the statement following the DELETE statement. (For more information on record I/O, see the section Input and Output.)
DELETE FILE(F) KEY('203XJ42');
None.
Begins a sequence of statements to be executed as a group, possibly to be executed iteratively.
DO [while-until-spec]|[index = iteration-spec[,iteration-spec]…];
where while-until-spec is:
WHILE(test-expression)[UNTIL(test-expression)]
or
UNTIL(test-expression)[WHILE(test-expression)]
and where iteration-spec is:
start[to-by-spec|repeat-spec][while-until-spec]
where to-by-spec is:
TO finish[BY increment]
or
BY increment[TO finish]
and where repeat-spec is:
REPEAT next
test-expression | Any expression that yields a scalar bit string value of length >= 1. If any bit of the value is 1, the test-expression is true; otherwise, it is false. test-expression must be enclosed in parentheses. |
index | A reference to a scalar variable. |
start, next, finish, and increment | Expressions valid for assignment to index. |
The DO statement begins a sequence of statements to be executed in a group. The group ends with the nonexecutable statement END.
A DO-group is executed a variable number of times under the control of its DO statement.
A DO statement cannot be used as an ON-unit, but can appear anywhere within a procedure or BEGIN block, including a THEN or ELSE clause of an IF statement or as an object of a WHEN or OTHERWISE clause.
The following sections explain each DO statement. In all of these discussions, you can assume that the DO-group neither transfers control out of the group nor skips statements within the group when the statements of the group are executed once, twice, n times, and so on. However, any DO-group can contain IF statements, other DO-groups, RETURN, or GOTO statements that alter the order of execution.
Control cannot be transferred initially into a non-simple DO-group except by executing that DO-group's DO statement. Also, if control is transferred out of a non-simple DO-group (other than by a procedure or function call), control cannot generally be transferred back into the group. Violation of these rules causes unpredictable results.
The simple DO statement causes the statements in the DO-group to be executed one time only. Control may be transferred into a simple DO-group by a GOTO statement, but this should be avoided in structured programming.
IF C < D THEN DO; PUT LIST ('More data needed'); GET LIST (VALUE); C = C + VALUE; END;
The DO WHILE statement causes the statements in the DO-group to be executed in a loop, provided the condition specified in the test expression is satisfied. When the condition is not true, the statements in the DO-group are not executed, and control passes to the statement following the END statement.
Execution of a DO WHILE statement causes the test expression to be evaluated to produce a value b, which must be a bit-string of length greater than or equal to one.
The test expression will be considered true if any of the bits in the string are one, and will be considered false only when all bits are zero.
If b is true, the statements of the group are executed; when the corresponding END statement is executed, control is transferred back to evaluate the test expression again, and the new value of b is tested. If b is false, the statements in the group are not executed, and execution resumes with the statement following the END statement.
The DO UNTIL statement causes a group of statements to execute until a certain condition is satisfied. As long as the condition is false, the group is repeated.
The test-expression is evaluated after each execution of the DO-group. For the DO-group to be repeated, the expression must have a false value. If the expression has a true value, control passes to the next executable statement following the END statement that terminates the DO-group.
The DO UNTIL option resembles the DO WHILE option, in that both options evaluate the status of test expressions; however, the DO WHILE option checks the test expression's value at the beginning of the DO-group, whereas the DO UNTIL statement checks its value at the end of the DO-group. Consequently, a DO-group containing a DO UNTIL statement with no WHILE clause will always be executed at least one time, but a DO-group containing a DO WHILE statement may never be executed.
DO WHILE(EOF = 0);/* an end of file ON-unit sets EOF = 1 */ READ FILE(F) INTO(REC); END; DO UNTIL(B = 1); ARRAY(B) = B; B = B - 1; END; DO WHILE(EOF = 0) UNTIL(SUBSTR(REC,1,6) = 'marker'); READ FILE(F) INTO(REC); END;
The DO REPEAT statement executes a DO-group repetitively for different values of a variable.
The variable is assigned a start value that is used on the first iteration of the group. The REPEAT expression is evaluated before each subsequent iteration, and its result is assigned to the variable. If a WHILE option is included, the WHILE expression is evaluated before each iteration, including the first. If an UNTIL option is included, the UNTIL expression is evaluated at the end of each iteration. Unless the WHILE or UNTIL option is present, the loop repeats indefinitely.
The DO REPEAT statement causes the start expression to be evaluated and assigned to the index variable. If the WHILE option is given, the test expression is evaluated to produce a value b, which must be a bit-string of length greater than or equal to one. (See the section DO WHILE and DO UNTIL Statements.) If b is false, execution resumes with the statement following the corresponding END statement. If b is true or if a WHILE option is not given, the statements of the group are executed. When control reaches the END statement, if the UNTIL option is given, the test expression is evaluated to produce a value b. If b is true, execution resumes with the statement following the corresponding END statement. Otherwise, the next expression contained in the REPEAT option is evaluated and assigned to the index variable. Any WHILE option is again evaluated; if the value is true or the WHILE is omitted, the group is executed again.
index must be a reference to a variable whose data type makes it a suitable target for assignment of both start and next. Both start and next may be expressions of any data type, provided they both can be assigned to index.
The index reference is not completely reevaluated each time a next value is assigned to it. The original values of any subscripts, pointer qualifiers, or string lengths used in index are used in all subsequent assignments of next values. The next and test expressions are completely reevaluated each time.
The index variable must not be an array or structure, but it can be a reference to an element of an array or a member of a structure.
DECLARE (HEAD,P) POINTER; DECLARE 1 NODE BASED; 2 VALUE FLOAT; 2 NEXT POINTER; DO P = HEAD REPEAT(P->NODE.NEXT) WHILE(P^=NULL); . . . END;
The previous DO-group is executed repeatedly for each non-null pointer in the chain of nodes rooted in the pointer HEAD.
The iterative DO statement identifies a variable whose value controls the execution of the DO-group and defines the conditions under which the control variable is to be modified and tested.
Execution of an iterative DO causes the start, finish, and increment expressions, as well as the index reference, to be evaluated in an unspecified order. Once evaluated, the finish and increment values are used throughout execution of the group and are not reevaluated. The subscripts, pointers, and so on, in the index reference are also not reevaluated.
The start value is converted, if necessary, to the data type of the index variable, and the converted value is assigned to the index variable.
If a WHILE option is given, the test-expression is evaluated to produce a value b that must be a bit-string of length greater than or equal to one. (See the section DO WHILE and DO UNTIL Statements.) If b is false, execution resumes with the statement following the END statement.
If b is true or a WHILE option is not given, the value of the index variable is compared to the finish value. If the increment is positive or zero, and if the index value is greater than the finish value, execution resumes with the statement following the END statement.
If the increment is negative and the index value is less than the finish value, execution resumes with the statement following the END statement.
If none of the above conditions caused execution of the group to end, the statements of the group are executed. If an UNTIL option is given, the test-expression is evaluated to produce a value b that must be a bit string of length 1. If b is true, execution resumes with the statement following the END statement, the increment value is added to the index variable, and any WHILE test is reevaluated. The new values of b and index are then used to determine if the group should be executed again.
The TO and BY options may be given in any order followed by the WHILE or UNTIL options. Either of the TO or the BY options may be omitted. If the BY option is omitted, a default increment of one is supplied. If the TO option is omitted, index is not compared against limit and the group repeats indefinitely unless stopped by the WHILE or UNTIL option. If both the TO option and the WHILE option are omitted, the DO-group repeats indefinitely. Both the WHILE and UNTIL options may be specified.
DO K = 1 TO 10; . . /* EXECUTES 10 TIMES */ . END; DO K = 10 TO 1 BY -1; . . /* EXECUTES 10 TIMES */ . END; DO K = 1 TO 1 BY -1; . . /* EXECUTES 1 TIME */ . END; DO K = 1 TO 10 WHILE(B<0); . . . END;
In this last example, the DO-group executes 10 times or until B ≥ 0, whichever comes first.
DO A(J) = B+1 TO N BY -M WHILE(T); . . . END;
In the previous example, the DO-group executes [B-N+2/M] times or until T becomes false, whichever comes first. All executions of the DO-group use the same element of A as the index, even if J has been altered by the execution of the group. These executions also all use the initial values of B+1, N and -M. However, T is repeatedly evaluated.
A special form of iterative DO statement is one in which none of the TO, BY, or REPEAT options are used, but in which multiple instances of the start expression are specified. In this case the DO-group is executed once for each specified start value.
DO name 'Bob', 'Ann', 'Fred', 'Joan', 'Sue'; READ FILE(F) KEY(name) INTO(REC); CALL SEND_REPT; END;
An iterative DO statement can include multiple instances of the iteration-spec. The DO list statement described above is a simple example of this. When multiple instances of the iteration-spec are specified, the DO-group is first executed as many times as required to satisfy the conditions for the first iteration-spec, then as many times as required for the second iteration-spec, and so on, until all instances of the iteration-spec have been used.
DO J = 1 TO 9 WHILE(B(J) ^-= 'xx'), J = 16 TO 20 BY 2; READ FILE(F) INTO(REC); B(J) = SUBSTR(REC,6,2); END;
If none of the first eight records read by this loop produce B (J) = 'xx', entries B (1) through B (9) , plus B (16) , B (18) , and B (20) , are set by the loop. If, for example, the third record read produces B (J) = 'xx', only entries B (1) through B (3) , plus B (16) , B (18) , and B (20) are set.
Terminates a block or group headed by the most recent DO, PROCEDURE, SELECT, or BEGIN statement.
END [statement_label];
statement_label | The label prefix of the corresponding statement. |
The END statement terminates a block or group headed by the most recent DO, PROCEDURE, SELECT, or BEGIN statement.
Execution of an END statement that closes a DO-group may cause the group to be repeated, depending on the DO statement that heads the group. (Refer to previous sections of this chapter regarding DO statements.)
Execution of an END statement that closes a PROCEDURE statement is valid only if the PROCEDURE statement does not contain a RETURNS option. Open PL/I or another implementation of PL/I might not diagnose all violations of this requirement. The END statement ends the current block activation and returns control to the statement following the CALL statement that called the procedure.
Execution of an END statement that closes a BEGIN block ends the current block activation and resumes execution of the previous block activation with the statement following the END statement. If the BEGIN block is an ON-unit, control returns to the source of the signal. This return is not possible if the ON-unit has been established for the ERROR condition; an attempt to return to the source of the ERROR condition stops execution of the program and produces a run-time error message.
An END statement can have a label prefix and can be referenced by a GOTO statement, including GOTO statements contained within the DO-group or block that is closed by the END statement.
If a name is given, it must be the same name as occurs in the label prefix of the corresponding DO, BEGIN, or PROCEDURE statement. If the name is not the same, the Compiler issues an error message.
An END statement cannot appear as a THEN, ELSE, WHEN, or OTHERWISE clause or as an ON-unit.
P: PROCEDURE; DO K=1 TO 10; . . . END; END P;
If control passes to an END statement that implicitly closes a repetitive DO group, no further repetitions of the DO group occur. It is equivalent to a branch out of the DO group.
None.
Defines an alternate entry point to a procedure.
name:ENTRY[(parameter,…)][RETURNS(returns-descriptor)][EXTERNAL|INTERNAL];
name | Identifies the entry point. |
parameter | Represents any parameters required by the procedure at this entry point. |
The scope of name is external if the ENTRY statement is contained in an external procedure. The scope of name is internal if the ENTRY statement is contained in an internal procedure.
The RETURNS option is required for entry points that are invoked by function references and provides the data type attributes of the function value returned. The RETURNS option is invalid for entry points procedures that are invoked by CALL statements.
The COBOL NOMAP [map-list] option
The FORTRAN NOMAPIN [map-list] option
The TASK NOMAPOUT [map-list] option
The NOEXECOPS option
The OPTION(BYTEADDR) option can be used to ensure the passing of byte addresses, even for items allocated on a bit boundary. When this option is not specified, Open PL/I passes bit addresses for unaligned bit strings. When this option is specified, Open PL/I passes just the address of the first byte of unaligned bit strings.
Only one of EXTERNAL or INTERNAL may be specified and only on top-level procedures, that is, those that are not contained within the scope of any other procedure. If EXTERNAL is given, the procedure will be external to the current file being compiled and can be called by other separately compiled procedures. This is the default. If INTERNAL is given, the procedure can be called only by other procedures within the current compilation. Its name is not made available outside this file.
For more information, see the sections Entry Data and ENTRY.
FILE_MANAGER: PROCEDURE; DECLARE 1 FILE_IOCB BASED (IOCB_PTR), . . . OPEN: ENTRY (IOCB_PTR, FILE_PTR, OPEN_MODE); . . . RETURN; CLOSE: ENTRY(IOCB_PTR); . . . RETURN; READ_RECORD: ENTRY (IOCB_PTR, BUFFER_PTR, READ_COUNT); . . . END;
FILE_MANAGER is a single procedure that has been designed to process three kinds of calls:
A separate entry has been created for each kind of call, each with its own parameters.
ENTRY statements are not allowed in BEGIN blocks, ON-units, or DO groups, except for simple DOs.
Controls the transmission of data to and from a stream I/O file by a GET or PUT statement.
name:FORMAT(format-list);
name | An unsubscripted label prefix that is not a statement label and cannot be used by a GOTO statement. |
format-list | A list of format specification items. |
The FORMAT statement describes the format-specification list to be used by the GET or PUT statement to control the transmission of data to and from a stream I/O file or string. The FORMAT statement has no effect unless it occurs as a consequence of executing the GET or PUT statement.
The format list consists of a list of format items separated by commas. Each format item can be preceded by an optional repetition factor. The repetition factor is either an expression enclosed in parentheses or an integer. The repeat count must be separated from the item by at least one space for all but the parenthetical format list. The value of the repetition factor must be greater than zero and less than 255.
The format items are:
(format-list) is a parenthetical format list used as a format item; A–P are data format items; and each w, d, or n is an integer constant or an expression whose value k must be 0<=k<=255, unless further restricted by the definition of a particular format item.
Each time control passes to a format list, all format items between the last used format item and the next data format item are evaluated. The next data format item is then used to control the conversion of the data being transmitted to or from the stream file.
If control reaches the end of a format list in a FORMAT statement, it returns to the R-format that transferred control to the FORMAT statement.
If control reaches the end of a format list in a GET or PUT statement, and one or more values are still to be transmitted in the statement's I/O list, control transfers to the beginning of the format list. If there are more format items than values to be transmitted in the statement's I/O list, the extra format items are ignored.
Each format item is described as follows. (Examples of the FORMAT statement are included in the format item descriptions.)
When a parenthetical format list is used as a format item, it is used as many times as specified by its repeat count.
F: FORMAT(F(10,4),2(A(5),E(14,3)),SKIP);
This example is equivalent to:
F: FORMAT(F(10,4),A(5),E(14,3),A(5),E(14,3),SKIP);
The data format items A, B, B1, B2, B3, B4, E, F, and P control the transmission and conversion of a value to or from a stream file. Each data format causes w characters to be read from an input stream or written to an output stream, where w is the field width given in the format or calculated during the conversion. (For additional information, see the chapter Data Type Conversions.)
If fewer than w characters remain in an input line, any characters remaining on that line are read and a fresh line is obtained. Additional characters are then read from the fresh line so that a total of w characters are read.
If fewer than w characters remain in an output line, as many characters as fit are written on that line and a fresh line is begun. Any remaining characters are written onto the line so that a total of w characters are written.
For a detailed description of how each data format controls conversion of a value, see the section Format Controlled Conversion .
The R(label) format item indicates that format items are to be acquired from the FORMAT statement at the specified label. That is, the R(label) format item transfers control to the format list of the FORMAT statement whose name appears in the R-format.
The effect of this transfer is as if the format list of the FORMAT statement were called as a subroutine; when the remote format list is exhausted, control returns to the format item following the R-format.
F: FORMAT(A,X(3)); PUT EDIT(P,Q) (R(F),E(14,3));
In the previous example, the value of P is transmitted by the A-format contained in the FORMAT statement. Transmission of Q finishes the remote format list by evaluating the X control format and returns to use the E-format to transmit the value of Q. This is equivalent to the following:
PUT EDIT(P,Q) (A,X(3),E(14,3));
The COLUMN or COL format item puts blanks into an output stream or skips characters of an input stream so that the next character is read or written into column n of a line.
The COLUMN format is valid for files only.
If the current output line contains exactly n-1 characters, no output is performed and the next output begins in column n of the current line.
If the current output line contains less than n-1 characters and n is less than or equal to the line size, sufficient blanks are placed into the current line to cause the next output to begin in column n.
If the current output line contains less than n-1 characters and n is greater than the line size of this file, the current line is written and a new line is begun. The next output begins in column 1 of the new line.
If the current output line already contains more than n characters, it is written to the stream file and a new line is begun. If n is greater than the line size of this file, no blanks are placed into the new line; otherwise, n-1 blanks are placed into the new line, causing the next output to begin in column n of the line.
If the current input line is positioned such that the next character to be read is located in column n, no characters are skipped.
If the current input line is positioned such that the current column is less than column n and n does not exceed the size of the current line, sufficient characters of the line are skipped so that the next input occurs from column n.
If the current input line is positioned such that the current column is less than column n, but n exceeds the size of the current line, or if the current column is greater than column n, a fresh line is read. If n exceeds the size of the fresh line, no characters are skipped and the next input occurs from column 1; otherwise, n-1 characters are skipped, causing the next input to occur from column n.
The value n must be greater than zero.
Example:
COL(n) | COLUMN | LINENO | NEW COLUMN | NEW LINENO |
---|---|---|---|---|
25 | 25 | 1 | 25 | 1 |
24 | 25 | 1 | 24 | 2 |
26 | 25 | 1 | 26 | 1 |
30 | 25 | 1 | 1 | 2 |
The previous examples assume a linesize, s, that is 26≤s≤30.
The LINE format item sets a print file to a specific line; therefore, it can be used only to control output to a stream file that has been opened with the PRINT attribute and that, consequently, has a page size.
The LINE format item is valid for print files only; it positions the stream file to a specified line relative to the top of a page.
If the current line number is less than n and n does not exceed the page size, sufficient lines are written to the output so that the current line is line number n.
If the current line number is greater than n or if n exceeds the page size, the remainder of the page is filled with blank lines and the ENDPAGE condition is signaled, unless the current line number already exceeds the page size. In that case, a new page is begun without signaling the ENDPAGE condition.
If n equals the current line and the current column is one, no output occurs. If n equals the current line, but the current column is not one, the ENDPAGE condition is signaled, unless the current line number already exceeds the page size. In that case, a new page is begun without signaling the ENDPAGE condition.
The value n must be greater than zero.
The PAGE format item is used with print files to begin a new page. It can be used only to control output to a stream file that has been opened with the PRINT attribute.
The PAGE format item positions the stream to the top of a new page and thereby resets the line number to one and increases the page number by one.
The SKIP format item sets a stream file to a new position relative to the current line. It can be used only with input and output files.
The SKIP format item applied to an input stream skips the rest of the current input line and n-1 subsequent lines; that is, it skips over n line boundaries.
A SKIP format applied to an output stream writes the current line and n-1 empty lines; that is, it writes n line boundaries.
If n is omitted, a value of one is supplied. The value of n must be greater than zero. If the value of n is less than or equal to zero, the SKIP option is ignored.
If the output stream file has been opened with the PRINT attribute, and if the total number of lines written as a result of the SKIP format item would exceed the page size, the current line is written, followed by sufficient empty lines to fill the page, and the ENDPAGE condition is signaled.
The TAB format item sets a print file to a specified tab stop n. It can be used only to control output to a stream file opened with the PRINT attribute.
The TAB format item causes sufficient blanks to be placed into the current line to position it to the nth tab stop relative to the current column of the line. The relative positions of tabs are implementation-defined (8 characters apart in this implementation). Other implementations may differ and may in fact not place tab stops at constant intervals.
If the current column is a tab stop, the TAB format item produces sufficient blanks to cause the next output to begin at the next tab stop.
If n tab stops do not remain on the current line, the current line is written and a new line begun. If the first tab stop is not column 1, sufficient blanks are placed into this line to position it to the first tab stop.
If TAB format items are used, line size must not be less than the first tab stop. If n is omitted, a default value of one is supplied.
The value of n must be greater than zero.
If either of the two preceding rules are violated, a line feed is inserted and data continues to be transmitted.
The X format item writes n blanks to an output file or skips n positions in an input file. If n is omitted, the default value of n is 1. The X format item is valid with both the FILE and STRING options of the GET EDIT and PUT EDIT statements.
If fewer than n characters remain in the current line, the remaining characters are skipped on input or written as blanks on output, and additional characters are skipped or written as blanks on the next line so that a total of n characters are written or skipped.
The value of n must be greater than zero.
None.
Frees the storage that was allocated for a based or controlled variable identified by reference.
FREE reference[IN(area-reference)]…;
reference | One or more references to based or controlled variables. |
area-reference | A reference to a scalar or subscripted area variable. |
The FREE statement frees all blocks of storage that were allocated for based or controlled variables identified by reference.
If the reference is not locator-qualified in the FREE statement, the variable will be implicitly qualified using the locator from the declaration of the based variable. If the declaration had no locator, the FREE statement is in error.
If the allocation to be freed occurred in an area, either the IN clause must be specified or the based variable must be qualified by an offset variable that was associated with an area in its declaration.
The locator qualifier used explicitly or implicitly by the reference must point to a block of storage allocated by execution of an ALLOCATE statement. The results are unpredictable when a FREE statement is used on a based or controlled variable that has not had storage allocated for it by an ALLOCATE statement.
The reference must not be subscripted and must identify a nonmember based or controlled variable whose size, shape, and component data types are the same as were used when the storage was allocated.
When a FREE statement has freed storage allocated for a controlled variable, the next most recent allocation for that variable is made available and subsequent references refer to that allocation.
When a FREE statement has freed storage allocated for a based variable, that block of storage must no longer be referenced. Any pointers that address the block are invalid and must not be used. Violation of this rule produces unpredictable results.
In the following example, the FREE statement frees the storage block allocated by the ALLOCATE statement.
DECLARE TABLE(100) FLOAT BASED; DECLARE P POINTER; . . . ALLOCATE TABLE SET(P); . . . FREE P->TABLE;
In the following example, the FREE statement frees an AREA.
DECLARE ITEM1 BIN BASED(O1); DECLARE ITEM2 BIN BASED(02); DECLARE ITEM3 BIN BASED; DECLARE A AREA(64); DECLARE 01 OFFSET(A); DECLARE 02 OFFSET; DECLARE 03 OFFSET; ALLOCATE ITEM1; /* implicitly in area A; implicitly set 01 */ ALLOCATE ITEM2 IN(A); /* explicitly in area A; implicitly set 02 */ ALLOCATE ITEM3 IN(A) SET(03); /* explicitly in area A; explicitly set 03 */ FREE ITEM1; /* both implicit */ FREE ITEM2 IN(A); /* IN is required */ FREE 03->ITEM3 IN(A); /* Locator and IN required */
None.
Gets data from an input stream that is either a stream file or a character-string expression.
GET [FILE(f)][SKIP[(n)]][LIST](input-list);
or
GET [FILE(f)][SKIP[(n)]]EDIT(input-list)(format-list)[(input-list)(format-list)]…;
or
GET STRING(s)[LIST](input-list);
or
GET STRING(s) EDIT(input-list)(format-list)[(input-list)(format-list)]…;
If neither LIST nor EDIT is specified, LIST is assumed. In this default case, the input-list must occur immediately after the word GET.
input-list is input-item [,input-item]...
An input-item is either:
variable-reference
or
(input-list iterative-DO)
No comma separates the iterative-DO from its associated input list.
An input list consisting of one iterative-DO has two sets of parentheses, as shown in the following example:
GET LIST (((ARR(I,J) DO I = 1 TO 5) DO J = 1 TO 5))
Each variable reference may be either an array reference, structure reference, or scalar variable reference. Structures with the UNION attribute cannot be used as variables in a GET statement.
The options may appear in any order.
The GET statement gets data from an input stream that is either a stream file or a character-string expression. The input file may be declared either with the STREAM attribute or with the default SYSIN, commonly associated with the user's default input device.
The GET statement has several forms, which include the following options: format-list, FILE, SKIP, STRING, and LIST, or EDIT.
format-list | Specifies a list of format items separated by commas. |
FILE | References a file value whose associated file has either been opened as a STREAM input file, or is closed. If closed, the file is opened by the GET statement, as described in the section Stream I/O, and given the STREAM and INPUT attributes. |
STRING | Specifies that the input item is a character-string expression. The STRING option cannot be used with the FILE or SKIP option. |
SKIP | Advances the input file a specified number of lines before processing the input list. The expression in the SKIP option must produce a positive fixed-point integer value n. The SKIP option skips across n line boundaries and resets the current column to one. |
LIST | Specifies list-directed input. |
EDIT | Specifies edit-directed input. |
The FILE, SKIP, and LIST options or the FILE, SKIP, and EDIT options may be given in any order, but a format list is contained in the EDIT option and must immediately follow the input list. If SKIP is given without (n), a value of one is supplied. If FILE is not given, FILE(SYSIN) is supplied by default.
After any SKIP option has been evaluated, the input list is evaluated together with any format list.
The input list is evaluated from left-to-right. Each variable reference may be an array reference, structure reference, or scalar variable reference.
A scalar variable reference causes one value to be transmitted from the input stream and, if EDIT is specified, it uses one data format. An array variable causes n values to be transmitted, where n is the number of elements in the array. If EDIT is specified, it uses n data formats. Values are transmitted to the array in row-major order, as defined in the section Arrays. A structure variable causes all members of the structure and members of all contained substructures to receive a value. The values are transmitted in left-to-right order. If EDIT is specified, each value requires a data format.
Only arithmetic, pictured, and string values can be transmitted by a GET statement. In Open PL/I, the maximum length of a string value transmitted by a GET statement is 256 bits for bit strings or 256 characters for character strings.
A parenthetical input list containing an iterative-DO transmits values under control of the iterative-DO as if it were a DO-group.
The number of lines read by a GET statement is determined by the size of the list, the SKIP option, and any control formats given in the format list. However, unless control items or SKIP forces new lines to be read, transmission begins with the current position of the current line and uses as many lines as are necessary to satisfy the input list.
The maximum length of any line in the input file is limited to the larger of 258 or the value of the LINESIZE option (specified in the OPEN statement) plus 2. If a line in the file is longer than this limit, the GET processing will truncate it with no run-time warning.
The following example shows a GET statement whose input list consists of one iterative-DO.
GET FILE(F) LIST((A(K),B(K) DO K = 1 TO 10))
Note that this is the same as:
DO K = 1 TO 10; GET FILE(F) LIST(A(K),B(K)); END;
The following example shows a GET statement whose parenthetical input-list contains an iterative-DO, which transmits values under control of the iterative- DO as if it were a DO-group.
DECLARE A(10) FLOAT; DECLARE (B,C) FLOAT; . . . GET FILE(F) LIST(A,B,C); GET FILE(F) EDIT(A(K),K,B(K)) (3 E(14,6)); GET FILE(F) LIST(B,(A(K) DO K = 1 TO 5),C);
In this example, the first GET statement transmits 10 values to the array A and then transmits values to B and C in that order. The second GET statement transmits a value to A (K) , transmits a value to K, and then transmits a value to B (K) using the new value of K as a subscript. All three values are transmitted using the same E-format. The third GET statement transmits a value to B, transmits values to A(1),A(2),A(3),A(4), and A(5), and to C in that order.
The following example shows a GET statement with the STRING option.
GET EDIT (NAME.FIRST,NAME.LAST) (A(8),X(3),A(20)) STRING('Deborah M. Park ');
In this example, the GET statement assigns the
character string 'Deborah ' to the structure NAME.FIRST,
skips the middle initial, periods, and space, and assigns the character
string 'Park
' to NAME.LAST. Blanks may be used to separate items in
list-directed I/O, but for edit-directed I/O they are interpreted differently
for character strings. For example, the same example would be interpreted as
follows for edit-directed I/O with the format (A (10) , X (3) ,
A(20)):
For list-directed I/O, the following example:
GET LIST(NAME.FIRST, NAME.LAST) STRING('Deborah M. Park ');
would assign 'Deborah' to NAME.FIRST and 'M.' to NAME.LAST.
The following sections contain additional information on the EDIT and LIST options.
The EDIT option of the GET statement specifies edit-directed input.
The GET EDIT statement uses a format list to control scanning of the input stream and conversion of fields. Each field is first converted under control of a data format and the converted value is then assigned to the corresponding list variable. An additional conversion may occur as part of that assignment.
For a description of each data format conversion, see the section Format Controlled Conversion on page 189,and for a description of format-list evaluation, see the section FORMAT Statement.
GET FILE(F) EDIT(A,B,C) (E(14,3),SKIP,F(10)); GET FILE(F) EDIT(D) (A(10));
In this example, A is assigned the field converted by E (14,3) , a new line is read by SKIP, B is assigned the field converted by F (10) , and C is assigned the next field converted by E (14, 3). The SKIP is not evaluated a second time, because no variables remain in the list. D receives a value from the field converted by A (10) . That field is the 10 characters that immediately follow the second field that was converted by E (14, 3) and assigned to C. Note that the A-Format is used without a field width to read a variable-length line, as discussed in the section A-Format.
When multiple (input-list) (format-list) pairs are specified, this is equivalent to specifying all the input items consecutively in one list, then all the format items consecutively in one list.
The LIST option of the GET statement specifies list-directed input.
The GET LIST statement causes each value expected by the input list to be read from the stream file without the use of a format item.
For list-directed input, the stream file must contain a sequence of fields, each of which is followed by a blank or a comma. Excess blanks may occur between fields.
A field whose value is to be assigned to an arithmetic, pictured, or bit-string variable X must contain an optionally signed constant of the same form as could appear on the right side of an assignment statement whose target was X.
A field whose value is to be assigned to a character-string variable begins with the next non-blank character in the stream and ends with the character immediately before the next blank or comma. However, the field can be delimited by single quote characters, and in this case it can contain embedded blanks and commas. If single quote delimiters are used, two adjacent single quotes are interpreted as one single quote in the field's value.
DECLARE (A,B) CHAR(8) GET LIST(A,B);
If the stream contains:
word-one word-two
or
word-one,word-two
the resulting values of a and b are:
a=word-one and b=word-two
If the stream contains:
'text one','it''s one'
the resulting values of a and b are:
a=text one and b=it's one
An empty field is a field ended by a comma that contains only blanks or contains no characters.
,5
,
,,
In this example, the last line contains two empty fields. An empty field causes no assignment to its corresponding list variable.
Note that all fields, including the last field in a file, are followed by a blank or a comma.
A field may be split across two or more lines; that is, a line boundary does not end a field. However, to facilitate input from certain devices such as online terminals, this implementation inserts a blank at the end of each line read from a terminal (when not scanning a quoted character-string constant) and thereby prevents a field from continuing onto another line. This may not be true of other implementations.
Multiple blanks following a field are scanned when the field is read and the stream is positioned at the next nonblank or end of the line, whichever occurs first.
GET FILE(F) LIST(A,B); GET FILE(F) LIST©);
In this example, if the stream contains:
A is assigned 52, B is assigned 1.07E+5, and C is assigned 'ABCX'. The position of the file after the second GET statement is executed is column 3. If the second line contained only two columns, the stream would be positioned at the end of the line such that any subsequent input would read a new line or detect the end of file if no lines remained. If the 7 on the second line had been a comma, it would be ignored by the next GET LIST operation, but would be read if the next operation was GET EDIT.
Note: If the stream is a terminal device, C is assigned 'ABC', since this implementation inserts a blank at the end of the line.
None.
Transfers control to a labeled statement in the current procedure or in another active procedure.
GOTOlabel-reference[OTHERWISE];
Alternate form: GO TO for GOTO
Abbreviation(s): OTHER for OTHERWISE.
label-reference | Identifies a label value. |
The GOTO statement transfers control to a labeled statement in the current procedure or in another active procedure.
If the label value is a label variable or label-valued function, its value must designate a statement in the current procedure block or in a containing procedure block. The value must also designate a stack frame belonging to a Nock activation of that block.
If the statement to which control is transferred is not within the current block, the current block activation is ended, as are all previous block activations back to the block containing the statement. That block activation is made current, and control is transferred to the statement.
The OTHERWISE option can be used only with a subscripted GOTO statement. A subscripted GOTO statement is defined as a statement directing control to a label that is subscripted.
References to an invalid subscripted label in a GOTO statement are generally considered to be errors. For example, ALABEL ( 1 ) in the second example below, is an undefined member of the array, and ALABEL ( 3 ) is a member that is out of bounds of the array.
However, the OTHERWISE option can be used to cause control to pass to the statement that follows the GOTO statement if the element referred to is not a valid member of the array of label constants.
For a more complete discussion of label values, see the section Label Data.
GOTO L; GOTO CASE(K); GO TO L;
The following example contains an array of subscripted label constants called ALABEL. The GOTO statement directs control to the statement that accompanies the subscripted label ALABEL (2) .
ALABEL(0): STATEMENT; ALABEL(2): STATEMENT; X = 2; GOTO ALABEL( X );
The following program sample presents the variable I used as a subscript in a GOTO statement that is subscripted on the third line. If the reference ALABEL ( I ) is not valid, the OTHERWISE option causes control to pass directly to the PUT LIST statement on the fourth line.
NEXT: GET LIST (I); GOTO ALABEL (I) OTHERWISE; PUT LIST( "INVALID"); GOTO NEXT; ALABEL( 1 ): . . . GOTO NEXT; ALABEL( 2 ): . . . GOTO NEXT;
None.
Conditionally executes code based on a test expression.
IF test-expression THEN clause[;ELSEclause];
test-expression | Any expression that results in a scalar bit string value of length ≥1. The test-expression is considered true if any bit in the string is one; the expression is considered false only when all bits are zero. |
clause | Either a BEGIN block, DO-group, or statement other than END, PROCEDURE, DECLARE, or FORMAT. |
The IF statement evaluates the test-expression. If the expression is true, the THEN clause is executed; otherwise, the ELSE clause, if present, is executed.
When an IF statement is used as a THEN or ELSE clause of another IF statement, any ELSE is always matched with the nearest unmatched preceding THEN.
test-expressions in IF statements may produce bit(n) values, where n>1. In this case, the test expression will be considered true if any of the bits in the string are 1 and false only when all bits are 0.
IF A>B THEN IF C>D THEN X = 5; ELSE X = 10;
In this example, the ELSE clause is associated with IF C > D THEN X = 5 ;
To associate an ELSE with the first THEN, you may write an ELSE or an empty ELSE with the second THEN, as shown in the following examples.
IF A>B; IF C>D THEN X=5; ELSE; ELSE X = 10;
or
IF A>B THEN DO; IF C>D THEN X=5; END; ELSE X = 10;
None.
Incorporates text from other files into the current source file during compilation.
%INCLUDE filename[,filename]…;
filename | One of the following: a
character string, an Open PL/I name, or an Open PL/I name enclosed in
parentheses.
The specified filename is used to locate a text file whose content is inserted into the program text in place of the %INCLUDE statement. |
The %INCLUDE statement incorporates text from other files into the current source file during compilation.
The %INCLUDE statement can appear in place of a name, constant, or punctuation symbol. The included text may contain additional %INCLUDE statements. %INCLUDE statements normally contain declarations that are common to more than one program module.
Open PL/I searches for a file to satisfy the %INCLUDE statement according to the following rules. (See the chapter/section Using Open PL/I/Compiler Options in your Open PL/I User's Guide.
In the following rules, we use the term "absolute directory path" for a path specifier beginning with a slash (/), such as /tmp/inc, and "relative directory path" for other path specifiers, such as sys/ or .. /.
%INCLUDE 'fiiename.pl1.inc';
It may also contain a directory path, as in,
%INCLUDE '/pl1/src/inc/filename';
In this case, with the filename not in quotes, Open PL/I first searches for the file with filename in uppercase characters; that is, FILENAME. If that search fails, Open PL/I tries again using lowercase letters.
%INCLUDE 'FILE1.IN','FILE2.IN','FILE3.IN'; %INCLUDE FILE4,'FILE5',(FILE6),(FILE7); %INCLUDE 'TOTAL.IN';
In the previous examples, the contents of the files referenced by FILEn, and so on, and by 'TOTAL.IN' will be copied into the current file at compile time.
DECLARE I %INCLUDE 'FDCL.IN'; STATIC INITIAL (0);
Assuming that the file referenced by ' FDCL.IN ' contains the single line FIXED BINARY (31) , this example is equivalent to the following:
DECLARE I FIXED BINARY (31) STATIC INITIAL (0);
None.
Transfers control out of the immediately containing DO-group or the containing DO-group whose label is specified with the statement.
LEAVE [label-reference];
label-reference | A reference to a label on a DO statement that heads a containing DO-group. The label reference must be a label constant or a subscripted label constant for which the subscript is specified with an integer constant. |
The LEAVE statement transfers control out of the immediately containing DO-group or the containing DO-group whose label is specified with the statement.
Execution of a LEAVE statement with no label reference transfers control to the first statement following the END statement that ends the immediately controlling DO-group. If the LEAVE statement has a label, control is passed to the first executable statement after the END statement for the corresponding DO label indicated in the LEAVE statement. In this manner, the LEAVE statement serves as an alternate means to end the execution of a DO-group.
A LEAVE statement with a label reference can cause several nested DO-groups to be ended as control transfers outside the referenced DO-group.
In the following example, the LEAVE statement, shown without a label reference, transfers control directly to the PUT statement if the condition in the IF statement is satisfied.
DO K = 9 TO 91; . . . IF COMMAND = 'QUIT' THEN LEAVE; . . . END; PUT LIST ('Job finished');
In the next example, the LEAVE statement, shown with a label reference, transfers control to the first statement following the END statement that ends LOOP2:
LOOP2: DO WHILE (MORE); . . . LOOP3: DO J = 2 TO 5; . . . IF QUAN(J) > 150 THEN LEAVE LOOP2; END; /* Loop 3 */ . . . END; /* Loop 2 */
The LEAVE statement must be contained within a DO-group and must be in the same block as the DO statement to which it refers.
If the LEAVE statement has a label reference, it must refer to a label on a DO statement that heads a DO-group that contains the LEAVE statement. The LEAVE statement must be in the same block as the labeled DO statement.
The label reference cannot be a label variable or a subscripted label constant.
Causes the Compiler to resume placement of listing information to the list file.
%LIST;
The %LIST statement causes the Compiler to resume placement of listing information to the list file.
None.
Stops the placement of listing information to the list file.
%NOLIST;
The %NOLIST statement stops the placement of listing information to the list file.
None.
Placeholder statement.
;
The NULL statement performs no action, but is used to provide null THEN or ELSE clauses in IF statements, null ON-units in ON statements, or to allow multiple label prefixes.
A:; B:; C: ON ENDPAGE (F);
In this example, the ON statement has a null ON-unit and is preceded by two labeled null statements, effectively giving the ON statement three labels. However, these labels do not compare equally because they designate different statements.
None.
Identifies the action to be taken when a particular condition is raised during execution of a program.
ON condition-name ON-unit;
or
ON condition-name SYSTEM;
condition-name | ANYCONDITION, AREA, ATTENTION, CONDITION(name), CONVERSION, ENDFILE(f), ENDPAGE(f), ERROR, FINISH, FIXEDOVERFLOW, KEY(f), OVERFLOW, RECORD(f), UNDEFINEDFILE(f), UNDERFLOW, USERCONDITION (expression), USERCONDITION(SS$_UNWIND), VAXCONDITION (expression), or ZERODIVIDE. |
ON-unit | A BEGIN block or a statement other than PROCEDURE, DO, END, DECLARE, FORMAT, or RETURN, which may include the CALL RESIGNAL statement. |
Abbreviation(s):
The ON statement identifies the action to be taken when a particular condition is signaled during execution of a program.
The ON statement is executable and must be executed before the statement that signals the specified condition.
Execution of the ON statement establishes the ON-unit as if it were a procedure that is to be called when the condition is signaled. It does not execute the ON-unit.
If an ON-unit for this condition has already been established in the current block activation, it is replaced by this ON-unit.
During its execution, an ON-unit can do any of the following:
An ON-unit remains established until it is replaced by another, until it is reverted by a REVERT statement, or until the block activation in which it was established is ended.
When a condition is signaled, each block activation, beginning with the current block activation, is examined to see if it has an established ON-unit for the condition. If it does not, the previous block activation is examined until an ON-unit for the condition is found. If no ON-unit exists, a default ON-unit is invoked. The default ON-unit for ENDFILE signals the ERROR condition. The default ON-unit for ENDPAGE puts a new page; that is, it is equivalent to executing a PUT PAGE statement. The default ON-unit for FINISH returns control to the point in the program following the location where the signal occurred. The default ON-unit for all the other conditions signal the ERROR condition which, if not handled by an ON-unit for ERROR, causes an error diagnostic to display and then halts the program.
The consequence of this mechanism is that a block may establish its own ON-unit for a condition or may choose to let its caller's ON-unit handle the condition. Any ON-unit established by a block is reverted to when the block returns to its caller or is otherwise terminated.
A signal causes an ON-unit to be called just as if it were a procedure that had no parameters. The block activation resulting from this call is terminated when the ON-unit executes a GOTO or executes its END statement. In the latter case, control returns to the source of the signal.
A GOTO executed within an ON-unit and transferring control out of the ON-unit terminates the block activation of the ON-unit and any block activations back to, but not including, the activation of the block to which control is transferred. (See the section Statement that Handles Exceptional Conditions.)
The ON-conditions ENDFILE, ENDPAGE, KEY, and UNDEFINEDFILE are uniquely established for each file control block and are always written with a reference f that must identify a file value. The condition so referenced is effectively qualified by the file control block associated with f. Thus, ENDFILE(g) and ENDFILE(h) are different conditions if g and h identify different file control blocks, but they are the same condition if g and h identify the same file control block.
Just before these conditions are signaled, the value of the ONFILE built-in function is set to the file ID of the file control block for which the condition is being signaled. An ON-unit must not have a label prefix.
Unless otherwise specified, the default ON-units for the following conditions signal the ERROR condition which, if not caught, will print a message and end the execution of the program.
The SYSTEM keyword indicates that instead of executing the code in the ON-unit, a message describing the condition is printed and the ERROR condition is raised.
The ON condition SYSTEM statement can be useful when the user is trying to prevent an infinite loop in the exception handler when, for instance, an ERROR condition is raised in an ERROR ON-unit .
ON ERROR BEGIN; ON ERROR SYSTEM; . . . END;
If in the above example, the code following the ON ERROR SYSTEM statement causes an error exception, the program will be terminated after the message describing the error condition is printed.
The ON conditions are described as follows.
The ANYCONDITION ON-unit handles any signaled condition that cannot be handled by any other ON-unit. The ANYCONDITION ON-unit executes after every other ON-unit established in the block has been examined and found not to match the signaled condition.
The AREA condition is raised when an attempt is made to allocate a based variable within an area that has too little free storage to accommodate it. The ON-unit for the AREA condition (for example, for a based area) can change the value of the pointer qualifying the area reference to point to a different area, where the allocation will be attempted again; or it can write out the area and reset it to empty.
The AREA condition is also raised when an area assignment is attempted where the maximum size of the source area exceeds that of the target area.
The ATTENTION condition is raised when you signal attention at the terminal during program execution. This condition interrupts processing to enter an ATTENTION ON-unit.
Upon return from an ATTENTION ON-unit, processing resumes at the point in the program immediately after the point at which the interrupt occurred.
The CONDITION condition is signaled by a SIGNAL statement that specifies the appropriate name. The name specified in the SIGNAL statement specifies which CONDITION condition is to be signaled. Note that the name specified in the CONDITION should be a condition name.
This condition allows the user to establish an ON-unit that will be executed whenever a SIGNAL statement is executed specifying CONDITION and a name that matches the name in the ON statement.
The following is an example of an ON CONDITION statement:
ON CONDITION(OVERDRAFT) BEGIN; PUT SKIP LIST('ACCOUNT HAD AN OVERDRAFT ON'||DATE())'); END; . . . IF ACCOUNT_BALANCE < TOTAL WITHDRAWAL THEN SIGNAL CONDITION(OVERDRAFT);
The CONVERSION condition is signaled whenever an invalid conversion is attempted on character data. This attempt can be made during direct assignment of character data to numeric variable or during an input/output operation. For example, this condition can be raised when a character value that is being converted to a Fixed Binary value contains non-numeric characters, or if a character other than 0 or 1 is being converted to a bit data type.
All conversions of character data are carried out character-by-character in a left-to-right sequence. The condition is raised for every invalid character.
When an invalid character is encountered, the invalid character can be replaced within the ON-unit by using the ONSOURCE or ONCHAR pseudovariables.
Upon return from a CONVERSION ON-unit, the program will retry the conversion if the ONSOURCE or ONCHAR pseudovariable has been used. If the error is not corrected, the ERROR condition is raised and control is passed back to the code that caused the exception to occur.
The ENDFILE condition is signaled when an attempt is made to read past the end of a file. The end-of-file status of the file control block remains set so that subsequent reads also cause the signal to occur.
Returning from the ON-unit transfers control to the statement following the GET or READ statement.
The ENDPAGE condition is signaled when the line to be written has a line number that is one greater than the page size or when a line number option that specifies a line number less then the current line number is issued for the STREAM OUTPUT PRINT file identified by f.
If an ON-unit returns without writing a new page, the line number of the file increases indefinitely and the ENDPAGE condition is not signaled by subsequent output. However, if a new page is written by the ON-unit or at any time later, it resets the line number and allows ENDPAGE to be signaled the next time that the line number is one greater than the page size.
Returning from the ON-unit returns to the point where the signal occurred and any additional output is then written to the stream.
The default ON-unit puts a new page and returns.
The ERROR condition is signaled whenever the implementation detects an error. Just prior to signaling the condition, the value of the ONCODE built-in function is set to an implementation-defined integer value that serves as an error code that indicates which error occurred. (For more information, see your Open PL/I User's Guide.)
Returning from the ON-unit produces an error message and ends program execution by executing a STOP statement.
The default ON-unit writes an error message on an implementation-defined error file and executes a STOP statement. (For more information, see your Open PL/I User's Guide.)
The following is an example of an ON ERROR statement.
ON ERROR BEGIN; PUT SKIP LIST ('AN UNIDENTIFIED ERROR OCCURRED'); END;
The FINISH condition handles the following conditions:
The default ON-unit does nothing and simply returns. If an ON FINISH ON-unit executes a STOP statement, the result is undefined.
Open PL/I accepts the syntax for the ON FIXEDOVERFLOW statement. However, since there is not adequate hardware support for this condition on the computers supported by Open PL/I, the FIXEDOVERFLOW condition is never raised (unless explicitly raised by the SIGNAL statement).
The KEY condition is signaled when a READ, REWRITE, or DELETE statement containing a KEY option cannot find a record with the specified key. It is also signaled by a WRITE statement whose KEYFROM option specifies a key of an existing record.
Just before the condition is signaled, the key value is assigned as the value to be returned by the ONKEY built-in function.
Returning from the ON-unit resumes execution with the statement following the record I/O statement.
The following is an example of the ON KEY(f) statement.
ON KEY(OUTFILE) BEGIN; PUT SKIP LIST('INVALID KEY SPECIFIED FOR OUTFILE'); PUT SKIP LIST('KEY WAS'||ONKEY()); END;
The OVERFLOW condition is signaled when the result of an arithmetic operation on a floating-point value exceeds the maximum value that can be represented.
The maximum values for decimal float values and binary float numbers are described in your Open PL/I User's Guide.
Returning from the ON-unit produces an error message and ends program execution by executing a STOP statement.
The RECORD condition can be raised during a READ, WRITE, or REWRITE operation. This condition is raised when:
The UNDEFINEDFILE condition is signaled when an error occurs while attempting to open a file.
Returning from the ON-unit transfers control to the statement following the OPEN statement.
The UNDERFLOW condition is signaled when the absolute value of the result of an arithmetic operation on a floating-point value is smaller than the minimum value that can be represented. (See your Open PL/I User's Guide.)
The default ON-unit simply returns. The value resulting from an operation that causes the UNDERFLOW condition is set to zero.
The USERCONDITION (expression) ON-unit handles the condition specified by expression, which must be evaluated to an integer. This ON-unit is invoked in response to execution of the SIGNAL USERCONDITION statement matching the expression value. For more information, see the section SIGNAL Statement.
The USERCONDITION condition may be signaled using the SIGNAL statement. The value of the expression specified as the USERCONDITION is determined when the ON statement is executed, and not when the condition is signaled. A range of numbers specified in your Open PL/I User's Guide will be allocated for system use.
The USERCONDITION (SS$_UNWIND) ON-unit handles the condition that is signaled by an UNWIND condition. An UNWIND condition occurs when a nonlocal GOTO forces execution to proceed from a previous block which, in turn, causes frames to be removed from the call stack.
This is a special case of USERCONDITION (expression). The name SS$_UNWIND is available as a GLOBALREF and must be declared as such.
The VAXCONDITION (expression) ON-unit is synonymous with the USERCONDITION (expression) ON-unit, and is provided for ease of program conversion. An ON-unit for one can be used to catch a SIGNAL of either.
The ZERODIVIDE condition is signaled when the divisor in a division operation has a value of zero. The resulting value is undefined.
Returning from the ON-unit produces an error message and ends program execution by executing a STOP statement.
None.
Causes the file identified by file_id to be opened with the attributes specified. .
OPEN file_attribute_list[,file_attribute_list]…;
file_attribute_list must include the FILE(file_id) option. It may include any of the following: [TITLE(s)] [LINESIZE(n)] [PAGESIZE(m)] [STREAM] [RECORD] [INPUT] [OUTPUT] [UPDATE] [PRINT] [KEYED] [SEQUENTIAL] [DIRECT], where:
file_id | One or more references to the files to be opened, and bracketed items are file attributes. |
s | The name by which the operating system knows the file(s). |
n | The maximum number of characters that can be output in a single line for the STREAM file. |
m | The maximum number of lines that can be written to the print file without signaling the ENDPAGE condition. |
These attributes, including FILE(file_id), may be in any order.
Execution of the OPEN statement causes the file identified by file_id to be opened with the attributes specified in the OPEN statement.
The FILE option must be specified and file_id must be a reference that produces a file value. If the file identified by file_id is already open, the OPEN statement is ignored, even if its attributes disagree with those of the already opened file. The program in which file_id is declared should be compiled with the -defext compiler option. For more information on compiler options, see your Open PL/I User's Guide.
The OPEN statement opens each specified file with a specified set of attributes that describe both the file and the file access method. The options and attributes may be specified in any order. If specified, line size n and pagesize m must be expressions that produce positive integer values. The default value of the LINESIZE option is 120, and the default value of the PAGESIZE option is 60. (For more information on record I/O, see the section Input and Output.)
For indexed or VSAM files, the record size is specified in the ENVIRONMENT options in the declaration of the file.
OPEN FILE(F) STREAM INPUT; OPEN FILE(F) TITLE ('MASTER_FILE.NEW') UPDATE; OPEN FILE(G) LINESIZE(80) PAGESIZE(60) STREAM OUTPUT PRINT;
None.
Causes the statement following the %PAGE statement in the program listing to be printed on the first line of the next page.
%PAGE;
The %PAGE statement causes the statement following the %PAGE statement in the program listing to be printed on the first line of the next page of the listing file.
None.
Causes the Compiler to resume placement of listing information to the list file.
%PRINT;
The %PRINT statement causes the Compiler to resume placement of listing information to the list file.
None.
Stops the placement of listing information to the list file.
%NOPRINT;
The %NOPRINT statement stops the placement of listing information to the list file.
None.
Defines the start of a procedure block and specifies the parameters of the procedure, if any.
name:PROCEDURE[(parameter-list][RETURNS(t)][EXTERNAL|INTERNAL] [RECURSIVE][ORDER|REORDER][REDUCIBLE|IRREDUCIBLE] [OPTIONS(options-list)];
Abbreviation(s):
parameter-list | One or more parameters, separated by commas, which are expected by the procedure when it is activated. Each parameter specifies the name of a variable declared in the procedure headed by the PROCEDURE statement. |
t | A list of data type attributes. |
options-list | May be MAIN or VARIABLE. |
Options may be specified in any order.
The PROCEDURE statement defines the start of a procedure block and specifies the parameters of the procedure, if any. If the procedure is invoked as a function, the PROCEDURE statement also specifies the data type attributes of the value that the function returns to its point of invocation. Execution of a PROCEDURE statement as a consequence of the normal flow of control from the previous statement has no effect and execution resumes with the statement following the procedure's END statement.
The PROCEDURE statement must have a label prefix that declares the name of the procedure. The label declares the primary entry point. That declaration is established in the block that contains the PROCEDURE statement, and consequently makes the name known in that block and in all contained blocks. The procedure's END statement may contain the name of the procedure so that it can be easily identified as the closing END statement. (See the section END Statement.)
Each name in the parameter-list must be declared within the procedure, must not be a member of a structure, and must not be declared with a storage class attribute.
Every call to a procedure not declared with the OPTIONS(VARIABLE) attribute must be made with an argument list containing the same number of arguments as there are parameters in the parameter list, and each argument must be capable of being passed either by reference or by value to its corresponding parameter. For a discussion of argument passing, see the section Parameter Storage Class.
If a RETURNS option is not specified, the procedure must always be called by a CALL statement, and it must not contain any RETURN statements that specify a return value.
If a RETURNS option is specified, t must be a set of data type attributes that specify a scalar value. All values returned by the procedure are converted to this data type prior to being returned as the function value of the procedure. All RETURN statements must specify a return value and the procedure must not execute its own END statement. All calls to the procedure must result from the evaluation of a function reference.
Only one of EXTERNAL or INTERNAL may be specified and only on top-level procedures, that is, those procedures that are not contained within the scope of any other procedure. If EXTERNAL is given, the procedure will be external to the current file being compiled and can be called by other separately compiled procedures. This is the default. If INTERNAL is given, the procedure can only be called by other procedures within the current compilation. Its name is not made available outside this file.
OPTIONS(MAIN) explicitly defines the routine where execution of the program begins. Only one OPTIONS(MAIN) statement is allowed within a program. In a linked executable program, one and only one procedure must be so identified as the main procedure. See the section Main Procedure of your Open PL/I User's Guide.
ORDER and REORDER are options sometimes used for optimization in IBM mainframe PL/I programs. Similarly, REDUCIBLE and IRREDUCIBLE are attributes sometimes used by IBM mainframe PL/I programs. None of these are needed by Open PL/I. These options are simply parsed and otherwise ignored by Open PL/I.
The COBOL NOMAP [map-list] option
The FORTRAN NOMAPIN [map-list] option
The TASK NOMAPOUT [map-list] option
The NOEXECOPS option
The OPTION(BYTEADDR) option can be used to ensure the passing of byte addresses, even for items allocated on a bit boundary. When this option is not specified, Open PL/I passes bit addresses for unaligned bit strings. When this option is specified, Open PL/I passes just the address of the first byte of unaligned bit strings.
The word RECURSIVE may be supplied for purposes of documentation. All Open PL/I procedures are capable of recursive use, provided they follow standard recursive programming requirements, such as not using STATIC data.
Procedures may contain other procedures and BEGIN blocks, as well as any other statements.
P: PROCEDURE(A,B) RETURNS(FIXED BINARY(15)); DECLARE(A,B) FLOAT; DECLARE C FIXED BINARY(15); . . . RETURN ©); END P; Q:PROCEDURE(X) RECURSIVE; DECLARE X CHARACTER(*); . . . CALL Q('HELLO'); END Q;
None.
Sets the margins within which characters of the source file are interpreted as source code and outside which all characters are ignored by the Compiler.
*PROCESS[MARGINS l,r[,p]];
I | The column number of the leftmost character to be interpreted as source code. |
r | The column number of the rightmost character to be interpreted as source code. |
p | The column number of the pointer control character. This is currently ignored by the Open PL/I Compiler. |
*PROCESS MARGINS sets the margins within which the Compiler interprets the code in the source file. The statement may be inserted anywhere within the source file. The limits apply to all source code following the *PROCESS MARGINS statement until another *PROCESS MARGINS statement is encountered or until the file ends. If tabs are used, each tab is counted as a single character.
Note: The same effect may be achieved for an entire source file by using the -margins compiler option switch. For more information, see your Open PL/I User's Guide.
*PROCESS MARGINS 5,55;
In this example, only the text contained between columns 5 and 55 of the source line will be interpreted by the Compiler; however, the source listing will contain the whole source line.
None.
Transfers data from the program to the output stream.
PUT[FILE(f)][SKIP[(n)]][LINE(m)][PAGE][list];
or
PUT STRING(r)[list];
list | [LIST](output-list)
or DATA (output-list) or EDIT(output-list) (format-list)[(output-list) (format-list)]... |
output-list | output-item [,output-item]... |
output-item | expression
or (output-list iterative-DO) |
If specified:
n and m | Expressions that produce integer values. |
f | A reference that produces a file value. |
r | A reference to a character-string variable that is the output stream. |
For the definition of a format list, see the section FORMAT Statement.
No comma separates an iterative-DO from its output-list.
An output-list containing one iterative-DO has two sets of parentheses, as shown in the following example:
PUT LIST (((ARR(I,J) DO I = 1 TO 5) DO J = 1 TO 5))
A parenthetical output-list containing an iterative-DO transmits values under control of the iterative-DO, as if it were a DO-group.
If none of LIST, DATA, EDIT is specified, LIST is assumed. In this default case, the output-list must occur immediately after the word PUT.
The PUT statement transfers data from the program to the output stream. The output stream can be either a stream file or a character-string variable.
The PUT statement has several forms that include the following options: format-list, FILE, SKIP, STRING, LINE, PAGE, and LIST, DATA, or EDIT.
The options may be given in any order, but the format-list is part of the EDIT option and must always immediately follow the output-list.
The FILE option must reference a file value whose associated file control block has either been opened as a STREAM OUTPUT file or is closed. If closed, it is opened automatically by the PUT statement and with the attributes STREAM OUTPUT LINESIZE(80). If the FILE option is omitted, FILE(SYSPRINT) is supplied by default. When SYSPRINT is opened, it acquires the PRINT attribute by default. Note that the LINESIZE value for an implicit OPEN differs from that in an explicit OPEN where the LINESIZE option is omitted.
The SKIP option positions the output file at the start of a new line. The expression in the SKIP option must produce a positive integer value n. The option writes n lines, beginning with the current line so that any subsequent output begins on a new line. If SKIP is given without n, a value of one is supplied by default.
The STRING option specifies that the output item is a referenced character-string variable rather than a file. The STRING option cannot be used with FILE, LINE, PAGE, or SKIP. The target of the PUT STRING operation must have sufficient space allocated to store the entire result of the operation, including any spaces, semicolons, and quotation marks added by the PUT LIST or PUT DATA processing. If the target does not have enough space, the ERROR condition is signaled.
The LINE option positions the stream file to a specific line relative to the top of the page. Subsequent output begins on that line. The LINE option is evaluated as if it were a LINE format; see the section LINE(n). If n is less than the current line position, the ENDPAGE condition is signaled.
If both SKIP and LINE are specified, LINE is evaluated first.
The PAGE option positions the output file at the start of a new page so that subsequent output begins on line one of that page. If the PAGE and LINE options are both given, PAGE is evaluated first.
SKIP, PAGE, and LINE are always evaluated prior to writing any output produced by the PUT statement, regardless of their position in the PUT statement. If the output from a statement does not share its last line with subsequent output, two statements must be used. (See the section Examples.)
The output-list is evaluated from left-to-right. Each expression may be either an array reference, structure reference, or scalar-valued expression. Structures with the UNION attribute cannot be used as variables in a PUT statement.
A scalar value causes one value to be transmitted to the output stream and, if EDIT is specified, uses one data format. An array variable causes n values to be transmitted, where n is the number of elements in the array. If EDIT is specified, it uses n data formats. Values are transmitted from the array in row-major order, as defined in the section Arrays. A structure variable causes all members of the structure and members of all contained substructures to transmit a value. The values are transmitted in left-to-right order. If EDIT is specified, each value requires a data format.
Only arithmetic, pictured, or string values can be transmitted by a PUT statement.
The number of lines written by a PUT statement is determined by the number of values specified by the output-list, as well as by the SKIP, LINE, and PAGE options, and any control formats given in the format list. However, unless control items or options force new lines to be written, transmission begins with the current position of the current line and uses as many lines as are necessary to satisfy the output list.
The LIST option specifies list-directed output.
The PUT LIST statement causes each value specified by the output list to be written to the stream file without the use of a format item. Each value to be output is converted to a character-string value using the normal rules for converting to a character string given in the chapter Data Type Conversions.
If the original output value is a bit string, the resulting character string is enclosed in quotation marks and a B is appended to its right end.
The DATA option specifies data-directed output.
The PUT DATA statement is equivalent to the PUT LIST statement, with the following differences:
The EDIT option specifies edit-directed output.
The PUT EDIT statement uses a format list to control the position of the output stream and the conversion of the values specified by the output list. Each output value is converted under control of a data format, and the resulting characters are written to the output stream.
When multiple (output-list) (format-list) pairs are specified, this is equivalent to specifying all the output items consecutively in one list, then all the format items consecutively in one list.
For a description of each data format conversion, see the section Format Controlled Conversion, and for a description of format list evaluation, see the section FORMAT Statement.
PUT FILE(F) EDIT(A,B,C) (E(14,3),SKIP,F(10)); PUT FILE(F) EDIT(D) (A);
In this example, A is converted under control of E (14,3), and 14 characters are written to the output stream, a new line is begun by SKIP, B is converted under control of F (10), and 10 characters are written to the output stream, C is then converted under control of E (14,3) and written to the output stream. The SKIP is not evaluated a second time because no more values remain to be output from the output list. The second statement converts D to a character string whose length is determined by the normal rules for conversion to character string. For further information on conversions, see the chapter Data Type Conversions. The resulting value is written to the same line as C, unless C happened to just fill a line. In that case, D begins on the next line.
If the original output value is a character string or a pictured value, and the file control block does not have the PRINT attribute, each contained quotation mark is replaced by two quotation marks and the entire string is enclosed by quotation marks.
The possibly modified character string is placed into the output stream followed by a single blank. If the file control block has the PRINT attribute and LINESIZE 20, for example, the value is followed by sufficient blanks to ensure that the next output begins in the next tab stop. At least one blank always separates fields.
If a character string does not fit on a line, a new line is begun and the string is written on that line and subsequent lines, if necessary.
PUT FILE(F) LIST(52,1.07E+5); PUT FILE(F) LIST('ABCX');
would produce (assuming a line size of 20):
In this example, the value 52 converts to 52 and is
output followed by a single blank, 1.07E+5 converts to
1.07E+05 and is followed by a single blank, and 'ABCX '
converts to ABCX. The resulting value does not fit on a
line of size 20, so it is written on the next line followed by a blank. If the
file control block had the PRINT attribute, the last value would be output
without quotation marks and each value would be followed by sufficient blanks
to ensure that the next value would begin at the next tab stop.
If the PRINT attribute does not exist, the output would look like this:
This example shows a PUT LIST statement.
PUT FILE(F) LIST((A(K),B(K) DO K = 1 TO 10));
This is the same as:
DO K = 1 TO 10; PUT FILE(F) LIST(A(K), B(K)); END;
This example shows the use of two PUT statements. The PUT SKIP causes any subsequent output to file F to appear on the next line.
PUT FILE(F) LIST(A,B,C); PUT FILE(F) SKIP;
This example shows a parenthetical output list containing an iterative-DO.
DECLARE A(10) FLOAT; DECLARE (B,C) FLOAT; /*HERE IS A COMMENT*/ . . . PUT FILE(F) LIST(A,B,C); PUT FILE(F) EDIT(A(K),C) (E(14,6)); PUT FILE(F) LIST(B,(A(K) DO K = 1 TO 5), C);
In this example, the first PUT statement transmits 10 values from the array A and then transmits values from B and C in that order.
The second PUT statement transmits a value from A (K) , and then transmits a value from C. Both values are transmitted using the same E-format.
The last PUT statement transmits a value from B, transmits values from A(1), A(2),A(3),A(4),A(5) , and from C, in that order.
The following sections contain additional information about the EDIT and LIST options.
This example shows data-directed output.
DECLARE X FIXED DECIMAL(5,2) INIT(123.45); DECLARE Y(4) BIT(2) INIT('00'b,'01'b,'10'b,'11'b); DECLARE 1 S(2), 2 A(3) CHAR(2) INIT('aa','bb','cc','dd','ee','ff'), 2 B CHAR(3) INIT('xxx','yyy'); PUT DATA(X,Y); PUT SKIP DATA(S);
The results of these statements in the output are:
X=123.45 Y(1)='00'B Y(2)='01'B Y(3)='10'B Y(4)='11'B ; S.A(1,1)='aa' S.A(1,2)='bb' S.A(1,3)='cc' S.B(1)='xxx' S.A(2,1)='dd' S.A(2,2)='ee' S.A(2,3)='ff' S.B(2)='yyy' ;
None.
Reads a record from an input or update file.
READ FILE(f)[INTO(v) [KEY(k)|KEYTO(r)]| SET(p)[KEY(k)|KEYTO(r)] IGNORE(expr)];
f | A reference to the file from which the record is to be read. |
v | A reference to the variable to which the record contents are to be assigned. |
p | A pointer variable. |
expression | Is evaluated and converted to an integer value. |
k | An expression that specifies the key to be used to locate the record to be read. |
r | The designated variable to which the key of the record being read is to be assigned. |
The FILE, INTO, KEYTO, and KEY specifiers may be written in any order. KEYTO must not be specified if KEY is specified. A READ statement without an INTO, SET, or IGNORE option is equivalent to a READ with an IGNORE(1).
The READ statement reads a record from a record file.
The FILE option must contain a reference f that produces a file value. The file identified by f must either have been previously opened with RECORD INPUT or UPDATE, or must be closed. If closed, it is opened by the READ statement and given the INPUT RECORD SEQUENTIAL attributes.
If the file has been opened with the KEYED SEQUENTIAL attributes, the KEY option may be specified. If the file has been opened with the DIRECT attribute, the KEY option must be specified.
The READ statement with INTO option copies the data record into the referenced variable. The SET option specifies a pointer variable that is set to point to the location in a buffer into which data has been moved during the READ operation. The storage for this buffer is handled by the run-time system.
In the following example, the value of the pointer value P is set to the location of F in the buffer of the next sequential record:
READ FILE (F) SET (P) ;
The IGNORE option can be used in a READ statement for any indexed SEQUENTIAL INPUT or SEQUENTIAL UPDATE file.
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 non-indexed files.
The following example specifies that the next five records in the file are to be ignored:
READ FILE (IN) IGNORE (5 ) ;
If specified for non-indexed files, the KEY option must be an expression whose value can be converted to a positive integer. Its value must be a key value of a record in the keyed file identified by the file associated with f. An attempt to read the file using a key value that does not identify a record in f results in a signal of the KEY condition. For indexed (VSAM) files, the key value is treated as a Character, and is converted to Character if necessary.
If specified, the KEYTO option must reference a character string variable whose maximum length is implementation-defined. (For details, see your Open PL/I User's Guide.) The file must be a keyed file. The key value of the record is assigned to r.
If a KEY option is given, the file must have been opened previously with the KEYED attribute. The presence of the KEY option does not cause implicit opening to produce the KEYED attribute.
Regardless of how the file was opened, it must have either the INPUT or UPDATE attribute.
If a KEY option is given, the file is positioned to read the record identified by the key value; otherwise, it is positioned to read the current record of a SEQUENTIAL file. After reading the record, the current position is advanced to the next record if the file is SEQUENTIAL. The current position for a DIRECT file is not changed.
Open PL/I allows the use of READ with a stream file, as long as the READ statement specifies a scalar character varying string variable in its INTO option. The READ statement reads the next complete input line and assigns it to the character varying string specified by the INTO option. The string does not include any new-line character.
READ FILE(F) INTO(X); READ FILE(G) INTO(Y) KEY(N+1); READ FILE (TOWN_FILE) INTO (TOWN_BUFFER) KEYTO (SAVE_ADDRESS);
In the last example, the READ statement reads the next sequential record in the file TOWN_FILE into the variable TOWN_BUFFER. The key associated with the record that is read is copied into the variable SAVE_ADDRESS.
None.
Specifies that an identifier is a constant of a given value.
%REPLACE name BY constant;
The %REPLACE statement specifies that an identifier is a constant of a given value.
Beginning at the point at which the %REPLACE statement is encountered, each occurrence of name that follows the %REPLACE statement is replaced by the constant until the end of compilation.
The %REPLACE statement is normally used to supply the sizes of tables or to give names to special constants whose meaning would not otherwise be obvious.
%REPLACE TRUE BY '1'B; %REPLACE TABLE_SIZE BY 400; %REPLACE MOTOR_POOL BY 5; %REPLACE X BY -3.0E0; DECLARE X(TABLE_SIZE) FIXED STATIC; DO K = 1 TO TABLE_SIZE; IF DEPARTMENT_NUMBER = MOTOR_POOL THEN DO; . . .
The %REPLACE statement operates on the program text without regard to the meaning of the text, which means that a replaced name can accidentally be a keyword such as STOP or READ. in this case, an "unrecognizable statement" error message is issued by the Compiler when it reads a subsequent STOP or READ statement. An error statement is also issued by the Compiler when an attempt is made to replace one name by two different constants.
The %REPLACE statement substitutes all subsequent occurrences of the name without regard to the block structure of the module, as explained in the section Procedure Blocks.
Ends execution of the current procedure and returns control to the calling block.
RETURN[(result)];
result | Must be an expression whose value can be converted to the data type specified in the RETURNS option of the containing procedure. |
The RETURN statement ends execution of the current procedure and returns control to the calling block.
If a result is specified, the containing procedure must have a RETURNS option and must have been called by a function reference. In this case, the result expression is evaluated, converted to the data type specified by the RETURNS option of the PROCEDURE statement, and returned as the function value.
If a result is not specified, the containing procedure must not have a RETURNS option and can be called only by a CALL statement.
A RETURN statement executed in a BEGIN block returns from the activation of the containing procedure block and terminates any BEGIN blocks that contain the RETURN statement.
RETURN; RETURN(A+B); RETURN('STRING RESULT'); RETURN('1'B);
A BEGIN block that is an ON-unit must not contain a RETURN statement.
Cancels an ON-unit established for a specified condition in the current block.
REVERT condition-name;
condition-name | The keyword name associated with the condition for which the ON-unit is to be reverted, namely: ANYCONDITION, AREA, ATTENTION, CONDITION(name), CONVERSION, ENDFILE(f), ENDPAGE(f), ERROR, FINISH, FIXEDOVERFLOW, KEY(f), OVERFLOW, RECORD(f), UNDEFINEDFILE, UNDERFLOW, USERCONDITION(expression), USERCONDITION(SS$_UNWIND), VAXCONDITION(expression), or ZERODIVIDE. |
Abbreviation(s):
The REVERT statement cancels an ON-unit established for a specified condition in the current block. If no ON-unit for the condition is established in the current block activation, the REVERT statement has no effect.
The reference given in an I/O condition name must produce a file value. The I/O condition is qualified by the file I/O associated with f. This means that in the example below, REVERT ENDPAGE (F) ; and REVERT ENDPAGE (G); revert to different ON-units if F and G designate different files; otherwise, they revert to the same ON-unit.
REVERT ERROR; REVERT ENDPAGE(F); REVERT ENDPAGE(G);
None.
Replaces a record in a DIRECT UPDATE, SEQUENTIAL UPDATE, or a KEYED SEQUENTIAL UPDATE file.
REWRITE FILE(f)[FROM(v)][KEY(k)];
f | A reference to the file containing the record to be replaced. |
v | A reference to the variable whose value is to be used to rewrite the specified record. |
k | An expression specifying the key to be used to locate the record to be rewritten. |
The REWRITE statement replaces a record in an UPDATE file. For SEQUENTIAL UPDATE files, the REWRITE statement specifies that the last record read form the file is to be rewritten. Note that, in this case, a record must be read before it can be rewritten. For DIRECT UPDATE files, and for KEYED SEQUENTIAL UPDATE files associated with indexed (VSAM) files, any record can be rewritten, whether or not it has first been read.
Because the set of file attributes that would be supplied as a result of an implicit file opening caused by a REWRITE statement does not include DIRECT, the FILE specifier must reference a file value whose associated file has been opened with the DIRECT and UPDATE attributes.
The KEY option is required for DIRECT non-indexed files and not allowed for SEQUENTIAL files.
The FROM specifier must contain a variable reference. The storage of that variable is copied as the new record. The FROM specifier must not contain a variable that is an unaligned bit string or a structure that consists entirely of unaligned bit strings or a structure with the UNION attribute.
If the last record read was read by a READ statement with the INTO option, a REWRITE statement without the FROM option has no effect. If the last record read was read by a READ statement with the SET option, a REWRITE without the FROM option causes the data record to be updated with the current contents of the buffer indicated by the pointer variable specified by the SET option of the READ.
The FILE, FROM, and KEY specifiers may be given in any order.
REWRITE FILE(F) FROM(X) KEY(N+1); REWRITE FILE(F) FROM(Y(K)) KEY('ABC');
None.
Heads a SELECT-group, which provides a multi-path conditional branch.
SELECT[(select-expression)]; WHEN(e⊃1[,e⊃2[,e⊃3[…]]]) action_1; WHEN(e⊃4[,e⊃5[,e⊃6[…]]]) action_2; . . .
OTHERWISE action_m;
END;
Abbreviation(s): OTHER for OTHERWISE.
select-expression and e⊃1, e⊃2... are all valid expressions, and each action is a single or compound statement, a DO-group, a SELECT-group, an ON-unit, or a BEGIN block.
The SELECT statement heads a SELECT-group, which provides a multi-path conditional branch. The SELECT statement tests the expressions in the SELECT-group and performs a particular action if the result of any test is true.
SELECT; WHEN (condition B) SELECT; WHEN (condition B1) statement_1; WHEN (condition B2) statement_2; END; WHEN (condition C) SELECT; WHEN (condition C1) statement_3; WHEN (condition C2) statement_4; OTHERWISE statement_5; END; OTHERWISE statement_6; END;
statement_1 is executed when both B and B1 are true conditions and statement_2 is executed when both B and B2 are true conditions. If B is true, but B1 and B2 are false, nothing happens. If condition B is false, the C conditions are checked. statement_5 is executed when condition B is false, condition C is true, and conditions C1 and C2 are false. statement_6 is executed when condition B and condition C are both false.
When control reaches a SELECT statement with a select-expression present, the select-expression is evaluated and its value saved. Next, the expressions in the WHEN clauses are evaluated in the order in which they appear, and each value is compared with the value of select-expression. If a value is found that is equal to the value of select-expression, the action following the corresponding WHEN clause is performed, and no further WHEN clause expressions are evaluated. If none of the expressions in the WHEN clauses is equal to the select-expression, the action specified after the OTHERWISE clause, if present, is executed unconditionally. If there is no OTHERWISE clause and there is no matching WHEN value, the ERROR condition is raised.
Note: OTHERWISE may be abbreviated to OTHER.
After the action has been performed, control passes to the first executable statement following the SELECT-group, unless the normal flow is changed by the specified action.
If the select-expression is omitted, each WHEN clause expression is evaluated and converted, if necessary, to a bit string. The action after the WHEN clause is performed if any bit in the resulting bit string is a '1'B.
If a SELECT-group does not contain any WHEN clauses, the action in the OTHERWISE clause is executed unconditionally. If the OTHERWISE clause is omitted, and execution of the SELECT-group does not result in the selection of a WHEN clause, the ERROR condition is raised.
In nested SELECT statements, conditions are checked from top to bottom. If two conditions are true, only the first course of action is taken.
You must close each group in nested SELECT-groups with an END statement.
SELECT; WHEN (9>B, C,D, FOUND) CALL PROC_1; WHEN (A=B) CALL PROC_2; OTHERWISE CALL PROC_3; END;
In the previous example, select-expression is omitted, so each WHEN clause expression is evaluated and converted to bit strings. The action after the WHEN clause is performed if any bit in any resulting string is a 1.
DECLARE MONTH CHAR(3), YEAR PIC'99', NO_DAYS FIXED BINARY; . . . SELECT(MONTH); WHEN ('FEB') SELECT (MOD(YEAR,4)); WHEN (0) NO_DAYS = 29; OTHERWISE NO_DAYS = 28; END; WHEN ('APR','JUN','SEPT','NOV') NO_DAYS = 30; OTHERWISE NO_DAYS = 31; END;
The previous example shows nested SELECT-groups used to set a variable to the number of days in a specified month. Here, the MOD built-in function returns the remainder when YEAR is divided by 4. (The algorithm is incorrect for some century years.)
None.
Causes a specified condition to be signaled.
SIGNAL condition-name;
condition-name | ANYCONDITION, AREA, ATTENTION, CONDITION(name), CONVERSION, ENDFILE(f), ENDPAGE(f), ERROR, FINISH, FIXEDOVERFLOW, KEY(f), OVERFLOW, RECORD(f), UNDEFINEDFILE(f), UNDERFLOW, USERCONDITION (expression), USERCONDITION(SS$_UNWIND), VAXCONDITION (expression), or ZERODIVIDE. |
Abbreviation(s):
The SIGNAL statement forces a specified condition to be raised. for detailed information on condition handling, see the section ON Statement.
A signal from a SIGNAL statement or from a condition raised during run-time calls the most recently established ON-unit for the specified condition.
SIGNAL ERROR; SIGNAL ENDFILE(F);
The ONCODE built-in function returns the value of the expression in the SIGNAL USERCONDITION (expression) or VAXCONDITION (expression) statement that caused the ON-unit to be invoked. For this reason, take care to choose expression values that do not conflict with any of the values used to indicate system or run-time errors or conditions.
In general, you can avoid conflicts with system and run-time-defined codes by using values greater than or equal to 100000 (one hundred thousand) for user-defined conditions. Code values between 0 and 99999 that are currently unused by the system are reserved for future expansions.
Causes a specified number of lines in the list file to be left blank.
%SKIP (n);
n | An integer in the range of 1 to 999. If n is omitted, the default value of 1 is supplied. |
The %SKIP statement causes n lines following the %SKIP statement in the program listing to be left blank. The %SKIP statement does not appear in the listing.
None.
Raises the FINISH condition, closes all open files, and ends program execution.
STOP;
The STOP statement raises the FINISH condition, closes all open files, and ends program execution.
A RETURN from a main procedure (declared with OPTIONS(MAIN)) has the same effect as STOP.
CLOSE: PROCEDURE; IF CLOSEDATE(FILE_NO) = 0 THEN CALL ERROR(7); . . . STOP; END CLOSE;
None.
Adds a record to a STREAM OUTPUT, RECORD OUTPUT, or RECORD UPDATE file.
WRITE FILE(f)FROM(v)[KEYFROM(k)];
f | A reference to the file to which the record will be written. |
v | A reference to the variable that contains data for the output record. |
k | An expression that specifies a key position. |
The FILE, FROM, and KEYFROM specifiers may be written in any order.
The WRITE statement adds a record to a file, either at the end of the file having the SEQUENTIAL and OUTPUT attributes, or into a file having the KEYED and OUTPUT attributes or the KEYED and UPDATE attributes.
The variable that contains data for the output record cannot be an unaligned bit string, a structure consisting entirely of unaligned bit strings, or a structure with the UNION attribute.
If the file associated with f has been opened with the KEYED and SEQUENTIAL attributes, the KEYFROM option may be specified. If the KEYFROM option is specified, the value of the expression k serves as the key value of the new record. If a record with this key value already exists, the KEY condition is signaled.
For non-VSAM files, if the file associated with f has been opened with the KEYED and DIRECT attributes, the KEYFROM option must be specified. The value of the expression k serves as the record number of the new record. If a record with this record number already exists, the KEY condition is signaled.
If a KEYFROM option is given, the file must have been previously opened with the KEYED attribute. The presence of the KEYFROM option does not supply the KEYED attribute in an implicit file opening.
The FILE option must contain a reference f that produces a file value. The file associated with f must either have been previously opened with RECORD OUTPUT, or it must be closed. If closed, it is opened by the WRITE statement and given the OUTPUT RECORD SEQUENTIAL attributes.
Open PL/I allows the use of WRITE with a stream file, as long as the WRITE statement specifies a scalar character varying string variable in its FROM option. The WRITE statement does an implicit SKIP and then writes a line consisting of the current value of the varying string specified by the FROM option followed by a new-line character.
WRITE FILE(F) FROM(CUSTOMER) KEYFROM(N+1); DECLARE 1 CUSTOMER, 2 NAME CHAR(20) VARYING, 2 ADDRESS 3 NUMBER FIXED BINARY(15), 3 STREET CHAR(12) VARYING, 3 CITY CHAR(20) VARYING; DECLARE F FILE; . . .
For DIRECT and KEYED SEQUENTIAL files the first WRITE that is performed on the file sets the default record size. This means that if a small record is the first record written to a file, subsequent WRITEs of large records could cause errors to occur. For example:
DECLARE F1 FILE, RECORD_ONE CHAR(5), RECORD_TWO CHAR(6); OPEN FILE(F1) RECORD DIRECT OUTPUT; WRITE FILE(F1) FROM(RECORD_ONE) KEYFROM(1); WRITE FILE(F1) FROM(RECORD_TWO) KEYFROM(2);
In the previous program the first WRITE will cause the default record size to be set to 5. Since the second WRITE is of a value greater than 5, an ERROR will be signaled. This restriction does not apply if the file is opened with the -DAM switch in the TITLE option to specify the record size in the file. For example, the program fragment in the above example would have worked correctly if the OPEN statement had read:
OPEN FILE(F1) TITLE('TESTFILE -DAM 10') RECORD DIRECT OUTPUT;
This would have set the default record size to 10 and the WRITE of both the CHAR (5) and CHAR ( 6 ) would have worked correctly.
Copyright © 2009 Micro Focus (IP) Ltd. All rights reserved.