Open PL - I Language Reference Manual
Open PL - I Language Reference Manual
1.13.1.1. List-Directed Stream I/O 1.13.1.2. Data-Directed Stream I/O 1.13.1.3. Edit-Directed Stream I/O 1.13.1.4. Terminal I/O on a Stream File 1.13.1.4.1. Stream File Attributes 1.13.1.4.1.1. Examples: 1.13.1.4.2. Print Files 1.13.2. Record I/O 1.13.2.1. Record File Attributes 1.13.2.2. Consecutive Record I/O 1.13.2.3. Indexed Record I/O 1.13.2.4. Relative Record I/O 1.13.2.5. REGIONAL(1) Record I/O 1.13.2.5.1. Example of REGIONAL(1) I/O 1.13.2.6. TITLE Options 2. Data Types 2.1. Introduction 2.2. Arithmetic Data 2.2.1. Fixed-Point Binary Literals 2.2.2. Floating-Point Binary Literals 2.2.3. Fixed-Point Data 2.2.4. Floating-Point Data 2.3. Picture Data 2.3.1. Picture Specification Characters 2.3.2. Rules for Using Numeric Picture Data 2.3.2.1. Drifting Characters and Strings 2.3.2.2. Credit and Debit Characters 2.3.3. Picture Repetition Factors 2.4. Character-String Data 2.4.1. String Repetition Factors 2.5. Wide Character-String Data (UTF-16 Support) 2.6. Bit-String Data 2.7. Area Data 2.8. Locator Data 2.8.1. Pointer Data 2.8.2. Offset Data 2.9. Label Data 2.10. Entry Data 2.10.1. Entry Constants 2.10.2. Entry Variables 2.10.3. Entry Values 2.10.3.1. The Stack Frame Designator 2.11. File Data 2.12. Arrays 2.13. Structures 2.14. Arrays of Structures 2.15. Data Size and Alignment
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (2 of 166) [16-03-2013 17:31:33]
2.15.1. ALIGNED and UNALIGNED Attributes 3. Storage Classes 3.1. Introduction 3.2. Automatic Storage 3.3. Static Storage 3.4. Based Variables 3.5. Controlled Variables 3.6. Defined Variables 3.7. Parameter Storage Class 3.8. Storage Sharing 4. Declarations and Attributes 4.1. Introduction 4.2. Label Prefixes 4.3. DECLARE Statements 4.3.1. Recommended Forms 4.3.1.1. Simple Declarations 4.3.1.2. Factored Declarations 4.3.1.3. Structure Declarations 4.3.2. The General Form 4.3.3. Defaults 4.3.3.1. Compiler-supplied Defaults 4.3.3.2. The Default Statement 4.3.4. Attribute Consistency 4.4. Attributes of DECLARE Statements 4.4.1. ALIGNED 4.4.2. ANY 4.4.3. AREA 4.4.4. AUTOMATIC 4.4.5. BASED 4.4.6. BIGENDIAN 4.4.7. BINARY 4.4.8. BIT 4.4.9. BUILTIN 4.4.10. CHARACTER 4.4.11. CONDITION 4.4.12. CONNECTED 4.4.13. CONTROLLED 4.4.14. DECIMAL 4.4.15. DEFINED 4.4.16. DIMENSION 4.4.17. DIRECT 4.4.18. ENTRY 4.4.19. ENVIRONMENT 4.4.20. EXCLUSIVE 4.4.21. EXTERNAL 4.4.22. FILE 4.4.23. FIXED
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (3 of 166) [16-03-2013 17:31:33]
4.4.24. FLOAT 4.4.25. GLOBALDEF 4.4.26. GLOBALREF 4.4.27. INITIAL 4.4.27.1. Examples of the INITIAL Attribute 4.4.28. INPUT 4.4.29. INTERNAL 4.4.30. IRREDUCIBLE 4.4.31. KEYED 4.4.32. LABEL 4.4.33. LIKE 4.4.34. NATIVE 4.4.35. NONNATIVE 4.4.36. OFFSET 4.4.37. OPTIONS(DESCRIPTOR) 4.4.38. OPTIONS(NODESCRIPTOR) 4.4.39. OPTIONS(VARIABLE) 4.4.40. OUTPUT 4.4.41. PICTURE 4.4.42. POINTER 4.4.43. POSITION 4.4.44. PRINT 4.4.45. READONLY 4.4.46. REAL 4.4.47. RECORD 4.4.48. REDUCIBLE 4.4.49. REFER 4.4.50. RETURNS 4.4.51. SEQUENTIAL 4.4.52. STATIC 4.4.53. STREAM 4.4.54. TYPE 4.4.54.1. TYPE Attribute Extensions 4.4.54.2. TYPE and Extent Expressions 4.4.54.3. Using the TYPE Attribute 4.4.54.4. Examples of the TYPE Attribute 4.4.55. UNALIGNED 4.4.56. UNION 4.4.57. UPDATE 4.4.58. VALUE 4.4.59. VARIABLE 4.4.60. VARYING 5. References 5.1. Introduction 5.2. Simple and Subscripted References 5.3. Structure Qualified References 5.4. Locator Qualified References
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (4 of 166) [16-03-2013 17:31:33]
5.5. Procedure References 5.6. Built-In Function References 5.7. Variable References 5.8. Reference Resolution 6. Expressions 6.1. Introduction 6.2. Order of Evaluation 6.3. Array Expressions 6.3.1. Prefix Operators and Arrays 6.3.2. Infix Operators and Arrays 6.3.3. Array and Element Operations 6.3.4. Array and Array Operations 6.4. Types of Operators 6.4.1. Arithmetic Operators 6.4.2. Relational Operators 6.4.3. Bit-String Operators 6.4.4. The Concatenate Operator 7. Data Type Conversions 7.1. Introduction 7.2. Arithmetic to Arithmetic Conversion 7.3. Arithmetic to Bit-String Conversion 7.4. Arithmetic to Character-String Conversion 7.4.1. Case 1 7.4.1.1. Examples 7.4.2. Case 2 7.4.2.1. Examples 7.4.3. Case 3 7.4.3.1. Examples 7.5. Bit-String to Arithmetic Conversion 7.6. Bit-String to Character-String Conversion 7.7. Character-String to Arithmetic Conversion 7.8. Character-String to Bit-String Conversion 7.9. Format Controlled Conversion 7.9.1. F-Format 7.9.1.1. Input Conversion 7.9.1.2. Output Conversion 7.9.2. E-Format 7.9.2.1. Input Conversion 7.9.2.2. Output Conversion 7.9.3. A-Format 7.9.3.1. Input Conversion 7.9.3.2. Output Conversion 7.9.4. B-Format 7.9.4.1. Input Conversion 7.9.4.2. Output Conversion 7.9.5. P-Format 7.9.5.1. Input Conversion
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (5 of 166) [16-03-2013 17:31:33]
7.9.5.2. Output Conversion 7.10. Pictured to Arithmetic Conversion 7.11. Pictured to Bit-String Conversion 7.12. Pictured to Character-String Conversion 7.13. Conversion to Pictured Data 8. Statements 8.1. Introduction 8.2. ALLOCATE 8.3. Assignment 8.3.1. Assignment - INT Pseudovariable 8.3.2. Assignment - ONCHAR Pseudovariable 8.3.3. Assignment - ONSOURCE Pseudovariable 8.3.4. Assignment - PAGENO 8.3.5. Assignment - POSINT Pseudovariable 8.3.6. Assignment - STRING Pseudovariable 8.3.7. Assignment - SUBSTR Pseudovariable 8.3.8. Assignment - UNSPEC 8.4. BEGIN 8.5. CALL 8.6. CLOSE 8.7. DECLARE 8.7.1. DECLARE - Array Format 8.7.2. DECLARE - Factored Format 8.7.3. DECLARE - Multiple Format 8.7.4. DECLARE - Outside of Procedure Format 8.7.5. DECLARE - Simple Format 8.7.6. DECLARE - Structure Format 8.8. DEFAULT 8.9. DELAY 8.10. DELETE 8.11. DISPLAY 8.12. DO 8.12.1. Simple DO Statement 8.12.2. DO WHILE and DO UNTIL Statements 8.12.3. DO REPEAT Statement 8.12.4. Iterative DO Statement 8.12.5. DO List Statement 8.12.6. Complex Iterative DO Statement 8.13. END 8.14. ENTRY 8.15. FETCH 8.16. FORMAT 8.17. FREE 8.18. GET 8.18.1. Edit-Directed Input 8.18.2. List-Directed Input 8.19. GOTO
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (6 of 166) [16-03-2013 17:31:33]
8.20. IF 8.21. %INCLUDE 8.22. LEAVE 8.23. %LIST 8.24. %NOLIST 8.25. NULL 8.26. ON 8.27. OPEN 8.28. %OPTION 8.29. %PAGE 8.30. %POP 8.31. %PRINT 8.32. %NOPRINT 8.33. PROCEDURE 8.34. %PROCESS 8.35. *PROCESS 8.36. %PUSH 8.37. PUT 8.37.1. List-Directed Output 8.37.2. Data-Directed Output 8.37.2.1. Edit-Directed Output 8.38. READ 8.39. RELEASE 8.40. %REPLACE 8.41. RETURN 8.42. REVERT 8.43. REWRITE 8.44. SELECT 8.45. SIGNAL 8.46. %SKIP 8.47. STOP 8.48. WRITE 8.49. %XINCLUDE 9. Open PL/I Built-ins 9.1. Introduction 9.2. ABS Function 9.3. ACOS Function 9.4. ADD Function 9.5. ADDR Function 9.6. ADDRDATA 9.7. ALL Function 9.8. ALLOCATION Function 9.9. ANY Function 9.10. ASIN Function 9.11. ATAN Function 9.12. ATAND Function 9.13. ATANH Function
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (7 of 166) [16-03-2013 17:31:33]
9.14. BINARY Function 9.15. BINARYVALUE Function 9.16. BIT Function 9.17. BOOL Function 9.18. BYTE Function 9.19. CEIL Function 9.20. CENTERLEFT / CENTRELEFT Function 9.21. CENTERRIGHT / CENTRERIGHT Function 9.22. CHARACTER Function 9.23. COLLATE Function 9.24. CONJG Function 9.25. COPY Function 9.26. COS Function 9.27. COSD Function 9.28. COSH Function 9.29. COUNT Function 9.30. CURRENTSTORAGE Function 9.31. DATAFIELD Function 9.32. DATE Function 9.33. DATETIME Function 9.34. DECIMAL Function 9.35. DIMENSION Function 9.36. DIVIDE Function 9.37. EMPTY Function 9.38. ERF Function 9.39. ERFC Function 9.40. EXP Function 9.41. FILEDDINT Function 9.42. FILEDDWORD Function 9.43. FILEOPEN Function 9.44. FIXED Function 9.45. FLOAT Function 9.46. FLOOR Function 9.47. FLUSH Subroutine 9.48. GRAPHIC Function 9.49. HBOUND Function 9.50. HEX Function 9.51. HIGH Function 9.52. INDEX Function 9.53. INT Function 9.54. LBOUND Function 9.55. LENGTH Function 9.56. LEFT Function 9.57. LINENO Function 9.58. LOG Function 9.59. LOG10 Function 9.60. LOG2 Function
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (8 of 166) [16-03-2013 17:31:33]
9.61. LOW Function 9.62. LOWERCASE Function 9.63. LPIPARAMCOUNT Function 9.64. MAX Function 9.65. MAXLENGTH Function 9.66. MIN Function 9.67. MOD Function 9.68. MPSTR Function 9.69. MULTIPLY Function 9.70. NULL Function 9.71. OFFSET Function 9.72. ONCHAR Function 9.73. ONCODE Function 9.74. ONFILE Function 9.75. ONKEY Function 9.76. ONLOC Function 9.77. ONSOURCE Function 9.78. PACKAGENAME Function 9.79. PAGENO Function 9.80. PLIRETC Subroutine 9.81. PLIFILL Subroutine 9.82. PLIMOVE Subroutine 9.83. PLIOVER Subroutine 9.84. PLIRETV Function 9.85. PLISRTx Subroutines 9.86. PLITEST Subroutine 9.87. POINTER Function 9.88. POINTERADD Function 9.89. POINTERDIFF / PTRDIFF Function 9.90. POINTERSUBTRACT / PTRSUBTRACT 9.91. POINTERVALUE Function 9.92. POLY Function 9.93. POSINT Function 9.94. PRECISION Function 9.95. PROCEDURENAME() Function 9.96. PROD Function 9.97. RANDOM Function 9.98. RANK Function 9.99. REPEAT Function 9.100. RESIGNAL() Subroutine 9.101. REVERSE Function 9.102. RIGHT Function 9.103. ROUND Function 9.104. SEARCH Function 9.105. SEARCHR Function 9.106. SIGN 9.107. SIN Function
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (9 of 166) [16-03-2013 17:31:33]
9.108. SIND Function 9.109. SINH Function 9.110. SIZE Function 9.111. SQRT Function 9.112. STORAGE Function 9.113. STRING Function 9.114. SUBSTR Function 9.115. SUM Function 9.116. SYSNULL Function 9.117. TALLY Function 9.118. TAN Function 9.119. TAND Function 9.120. TANH Function 9.121. TIME Function 9.122. TRANSLATE Function 9.123. TRIM Function 9.124. TRUNC Function 9.125. UNSPEC Function 9.126. UPPERCASE Function 9.127. VALID Function 9.128. VERIFY Function 9.129. WCHARVAL Function 9.130. WHIGH Function 9.131. WIDECHAR Function 9.132. WLOW Function 10. Open PL/I Macro Preprocessor 10.1. Overview 10.1.1. Preprocessor I/O 10.1.1.1. Preprocessor Statements 10.1.1.2. Listing Control Statements 10.2. Preprocessor Scan 10.3. Preprocessor Variables and Data Elements 10.4. Preprocessor References and Expressions 10.5. Scope of Preprocessor Names 10.6. Preprocessor Statements 10.6.1. %ACTIVATE 10.6.2. %ASSIGNMENT 10.6.3. %DEACTIVATE 10.6.4. %DECLARE 10.6.5. %DO 10.6.6. %END 10.6.7. %GOTO 10.6.8. %IF 10.6.9. %INCLUDE 10.6.10. %NOTE 10.6.11. %NULL 10.6.12. %REPLACE
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (10 of 166) [16-03-2013 17:31:33]
10.7. Preprocessor Procedures 10.7.1. Invocation of Preprocessor Procedures 10.7.1.1. %PROCEDURE 10.7.1.2. RETURN 10.7.2. Preprocessor Built-In Functions 11. Features Unsupported by Open PL/I 11.1. Built-in Subroutines 11.2. Attributes 11.3. Options 11.4. Conditions 11.5. Statements 11.6. Constants 11.7. Items 11.8. Operations 11.9. Arrays 11.10. Others 12. Glossary
Language Concepts This chapter provides an overview of the Open PL/I language, explaining the following basic concepts: program structure and statement syntax, block structure, variables, files, input and output. Data Types This chapter discusses the various data types that are available to you in Open PL/I. Storage Classes This chapter describes storage classes and how they are used. Declarations and Attributes This chapter explains how label prefixes and DECLARE statements are used for declarations, and also describes the attributes that can be used in a DECLARE statement. References This chapter describes each type of reference and the rules and basic steps involved in resolving references. Expressions This chapter explains expressions and how they are used. Data Type Conversions This chapter defines the conversions that result from assignments to arithmetic variables, bit-string variables, and pictured variables. Statements This chapter defines the Open PL/I statements. The statements are presented in alphabetical order by name.
Open PL/I Built-ins This chapter defines the built-in functions and subroutines provided by Open PL/I. Open PL/I Macro Preprocessor Features Unsupported by Open PL/I A list of features that are currently unsupported by Open PL/I. Glossary This chapter provides definitions for terms used in the Open PL/I manuals.
Parent topic: General Reference Related concepts Features added in Enterprise Developer 2.1 Related information Compiled File Types Delegates and Events IBM External Call Interface (ECI) To associate file extensions with COBOL Tutorials on COBOL and PL/I in the Visual Studio IDE Language Concepts
1. Language Concepts
Statements Names Constants Punctuation Comments Statement Sub-Groups Text Replacement and Insertion Statements Modules Blocks
Parent topic: Open PL/I Language Reference Manual Send feedback about this topic
1.1. Statements
Open PL/I is a block-structured language. Each block consists of a group of statements. Statements are used to declare constants and variables, and to express actions to be performed by your program. For example: READ FILE (G) INTO (Y) ; In this example, the READ statement reads the next record in file G into storage Y. Each Open PL/I statement consists of a series of elements ending with a semicolon. These elements can be PL/I keywords, user-specified identifiers, literal constants, or punctuation symbols. Parent topic: Language Concepts Send feedback about this topic
1.2. Names
A name used to denote part of a statement such as a verb, option, or clause, is called a keyword. All statements, except the assignment statement, begin with a keyword that identifies the purpose of the statement. A name can also denote an object operated upon by the program, such as a variable, file, or label. These names are known as identifiers. Their meanings are established by a declaration. In this example, G and Y are identifiers. READ, FILE, and INTO are keywords. READ FILE (G) INTO (Y) ; There are no reserved words in Open PL/I. In this example, TO names a storage location. GOTO L; CALL S(B,C,D); RETURN; STOP; DO K = 1 TO 11; TO = 20; /* ASSIGNMENT STATEMENT*/ The following example shows how names can either establish an object to be operated on or denote part of a
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (13 of 166) [16-03-2013 17:31:33]
statement. DECLARE X(5) FIXED; L: X(3) = 25; Both X and L are identifiers, but DECLARE and FIXED are keywords. X is declared by a DECLARE statement; L is implicitly declared as a label. A name consists of any combination of the following:
letters digits _ (underscore character) @ (at sign character) # (pound sign character) $ (dollar sign character) a sequence of any of the above characters
Any of the alphanumeric characters A through Z, a through z, and 0 through 9 can be used. A name must not contain more than 32 characters. Names cannot contain blanks or hyphens.
Examples: STREET_NAME @BETA #Y7 C $7 Names can be written using both uppercase and lowercase letters. By default, all lowercase letters are interpreted as their uppercase equivalents. The -lowercase compiler option causes the reverse of this behavior. Refer to the Open PL/I User's Guide for more information on this option. Because there are no reserved names in Open PL/I. Names that are used as keywords, such as READ or INTO, can also be identifiers. However, this practice makes programs difficult to read and should be avoided whenever possible.
Parent topic: Language Concepts Related information Open PL/I User's Guide
1.3. Constants
A constant is a sequence of characters that represents a particular, unchanging value. In Open PL/I, five kinds of constants are permissible:
Literal constants These are actual numbers or strings written in the source program. Literal constants are restricted to character strings, bit strings, and fixed- or floating-point numbers.
Label constants These are established using a label prefix in the source program that declares a name either as the name of a format or a procedure, or as a statement label. Label constants cannot be declared in a DECLARE statement.
File and entry constants These constants are typically established by DECLARE statements. File constants are identifiers declared with the FILE attribute to describe the type of input/output to be performed on a file. Entry constants are used to invoke procedures at certain entry points.
Replace constants These are identifiers that are to be changed with the %REPLACE statement. Like literal constants, constant identifiers can also be character strings, bit strings, and fixed- or floating-point decimal numbers.
Named constants These constants are scalar identifiers that are declared by the VALUE attribute. They can be declared for arithmetic data, string data, and for pointers and offsets.
Examples:
Constant
Type
25 7.5 3.12E-01 'How are you?' '1'B '1011'B '775'B3 'A7O'B4 STARTUPD: %REPLACE TABLE_SIZE BY 350; DECLARE E ENTRY; DECLARE F FILE;
Integer constant Fixed-point decimal constant Floating-point decimal constant Character-string constant Bit-string constant (binary notation) Bit-string constant (binary notation) Bit-string constant (octal notation) Bit-string constant (hexadecimal notation) Label constant TABLE_SIZE is an identifier to be replaced by an integer constant E is an entry constant F is a file constant
For a table showing the expansion of nonbinary notation into binary notation, see the section Bit-String Data. Arithmetic constants represent decimal values, whereas binary arithmetic values have no constant representation. Nevertheless, any decimal constant can be converted easily to a binary value by using it in a context that expects a binary arithmetic value. As a result of Open PL/I language rules, all constants that appear as floating-point numbers in a source program are actually of type float decimal and are subject to the rules of float decimal arithmetic. A character-string constant can contain any character, except that, if an apostrophe is required within a characterstring constant, it is written as two apostrophes. For example, 'He said, "I''m fine."' Note: The double quotation mark character is not equivalent to a single quotation mark or two adjacent single quotation marks and has no more significance than any other character within a constant. In Open PL/I, the maximum size of a string constant is 256 characters or bits (for details, see the section Open PL/I Compiler Implementation Limits). The Compiler checks this limit after bit-string constants written in the B2, B3, or B4 format have been expanded. Refer to the data type descriptions in the chapter Language Concepts in your Open PL/I
User's Guide for the maximum size limits for floating- and fixed-point data. A named constant is similar to a scalar declaration with the appropriate data attributes, plus the VALUE attribute. The VALUE attribute signifies this identifier is named constant, with all of the attributes taken as applied to the declaration. Named constants differ from simple constants in that they retain the attributes from the declaration. For example, declare i fixed bin (15) value(1); declare j fixed bin (15); j = 1; j = i; /* 1 is fixed decimal, requires conversion */ /* i is fixed bin (15), no conversion (integer 1 assigned, not "i" ) */
or string data items, the length is determined from the length of the string value when the length is not specified. declare string char value ('abcdef') ; /* string is char(6) */ In Open-PLI, named constants can be declared as arithmetic or string; pointers and offsets are not yet supported. In Open-PLI, the named constants may be declared before or after it is used, and the same scoping rules as any declaration apply. Example: cool: proc options(main); dcl pname char (16) value (procedurename()); dcl flag bit(1) aligned static init(true); dcl true bit(1) value ('1'b); dcl false bit(1) value('0'b); dcl myarr (n) fixed bin (15); dcl n fixed bin(15) value (800); dcl arr (k/3) fixed bin (15) static init (k+1, k, k+3); dcl arr1 (100+100) fixed bin (15); dcl arr2 (n+100) fixed bin (15); dcl i fixed bin (15); dcl k fixed bin (15) value (9); if flag then put skip list ('Named Constants are ', pname); put skip list(arr); i = n + 100; arr1 (k) = 99;
put skip list (size(arr1), size(arr2), i, arr1(K*2-K)); put skip list(arr); end; Named Constants are 10 400 10 COOL 9 1800 9
12 900 12
99
Parent topic: Language Concepts Related information Text Replacement and Insertion Statements Bit-String Data Open PL/I Compiler Implementation Limits B-Format Language Concepts
1.4. Punctuation
In Open PL/I, punctuation symbols are either operators or separators. Operators define the arithmetic or comparative operations to be performed on expressions in a statement. The table below lists the Open PL/I operators.
Symbol
Meaning
Addition or the plus prefix Subtraction or the minus prefix Multiplication Exponentiation Division Logical NOT Logical OR Logical AND Greater than Less than Equal to
Not greater than Not less than Not equal to Greater than or equal to Less than or equal to String concatenation Pointer resolution
Separators delimit and separate identifiers, keywords, and constants in statements. The table below lists the Open PL/ I separators.
Symbol
Meaning
Encloses lists, defines order of expression evaluation, separates names of statements and options from specific keywords Separates subscripts and procedure arguments, separates identifiers in a structure name, and precedes the BY NAME option Delimits bit strings and character strings Specifies a decimal point. Connects elements of a qualified name Terminates a procedure name or a statement label Delimits statements
Names and constants may be separated from one another by one or more blanks, or tabs, rather than by separators. Additional blanks surrounding punctuation symbols are optional. In the following examples, blanks are represented by boxes ( ).
The first statement requires no blanks because each name is separated from the next by a punctuation symbol. The second statement shows the optional use of extra blanks. The third statement shows optional blanks surrounding the equal symbol (=) and after the semicolon, the remaining blanks being required blanks. Note that when an arithmetic constant is followed by a name, at least one blank or punctuation symbol is required to separate the arithmetic constant from the name. Parent topic: Language Concepts Send feedback about this topic
1.5. Comments
Comments are used to document an Open PL/I program. A comment can appear anywhere that a blank can appear and is equivalent to a blank. Comments cannot be nested. The general form of a comment is: /*Comments open with a slash* and close with a *slash */ For example, /*HERE IS A COMMENT*/ IF A<25 /* HERE IS ANOTHER ONE */ THEN /*HERE IS AN /* ERRONEOUS */ COMMENT */ The final comment is invalid because comments cannot be nested; it ends at the first * / in the line and the Compiler attempts to interpret COMMENT */ as code and produces an error message. The Compiler puts an asterisk (*) into the line number field of the listing file for each line on which a comment is continued from a preceding line. This convention can be used to determine if some text was accidentally included in a comment. Comments can continue over any number of lines of program text; thus, if the */ is omitted from a comment, all program text up to the next */ is considered part of the comment. This causes part of the program to be ignored by the Compiler and may cause it to produce misleading error messages. The same problem occurs if a character-string or bit-string constant is not terminated with an apostrophe. Parent topic: Language Concepts Send feedback about this topic
Compound Statements Statements that Alter the Order of Execution Statement that Handles Exception Conditions
IF ON DO SELECT
They are called compound statements because they each contain other statements.
1.6.1.1. IF Statement
The IF statement tests an expression and performs a specified action if the result of the expression is true. Its general form is: IF expression THEN statement; [ELSE statement]; where expression is any valid expression that yields a scalar bit-string value, and statement is any unlabeled statement (except DECLARE, END, ENTRY, FORMAT, or PROCEDURE) or an unlabeled DO-group or BEGIN block. For example: IF A>B THEN READ FILE (F) INTO (X); In this example, the IF statement contains the READ statement. If the expression A>B is true, the READ statement executes. The IF statement needs no semicolon of its own because each statement contained within it has its own semicolon. IF statements can be nested, as shown in the following example.
IF A>B THEN IF D<C THEN READ FILE(F) INTO(X); ELSE STOP; In this example, the second IF statement has both a THEN clause and an ELSE clause. An ELSE clause always corresponds to the THEN clause that immediately precedes it. The first IF statement has only a THEN clause. If you want to STOP when A ^> B, you may provide a null ELSE clause to the innermost IF, forcing the ELSE STOP to be associated with the first IF. It is preferable to use structured IF, THEN, and DO statements to accomplish this, as shown in the following example. IF A>B THEN DO; IF D<C THEN READ FILE(F) INTO (X); END; ELSE STOP;
1.6.1.2. ON Statement
The ON statement defines the action to be taken when a specific condition is signaled during the execution of a program. Its general form is: ON conditionname ON-unit, or ON conditionname SYSTEM where: condition-name is ANYCONDITION, AREA, ATTENTION, CONDITION(name), CONVERSION, ENDFILE(f), ENDPAGE(f), ERROR, FINISH, KEY(f), OVERFLOW, RECORD(f), SIZE, UNDEFINEDFILE(f), UNDERFLOW, USERCONDITION(expression), USERCONDITION(SS$_UNWIND), or ZERODIVIDE. ON-unit is a BEGIN block or any statement other than DECLARE, DEFAULT, DO, END, ENTRY, FORMAT, LEAVE, OTHERWISE, PROCEDURE, RETURN, or SELECT. The keyword SYSTEM indicates that, instead of executing user-specified code in the ON-unit, a system-generated message describing the condition is displayed and the ERROR condition is signaled. For example: ON ENDFILE (F ) BEGIN; . . . END; In this example, the block of statements between the BEGIN and END statement executes if the end-of-file condition is reached.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (23 of 166) [16-03-2013 17:31:33]
ON is a compound statement, but it cannot be nested. The ON statement's use in responding to exceptional conditions is explained more fully in the section Statement that Handles Exception Conditions. Parent topic: Compound Statements Related information Statement that Handles Exception Conditions
1.6.1.3. DO Statement
The DO statement begins a sequence of statements to be executed in a group, called a DO-group. Its general form is: DO; . . . END; For example: IF B < C THEN DO; PUT LIST ('ADDED DATA REQUIRED'); GET LIST (VALUE); B = B + VALUE; END; In this example, the PUT LIST, GET LIST, and assignment statements execute if B < C. DO statements can contain IF statements, other DO-groups, RETURN statements, or GOTO statements that alter the order of execution. Parent topic: Compound Statements Send feedback about this topic
. [OTHERWISE action_m;] END; where select-expression and e1, e2... are valid expressions, and each action is a single or compound statement or a BEGIN block. For example: SELECT; WHEN (F=40) G=G+1; WHEN (F=50) IF G > 0 THEN G=G+2; . . . OTHERWISE DO; . . . END; END; This example shows the SELECT statement used with the expression omitted. When the expression is omitted from the SELECT statement, each WHEN clause expression is evaluated and converted, if necessary, to a bit string. The action after the WHEN clause is performed if the resulting bit string is nonzero. In the above example, if F=40 is true, the action G=G+1 is executed and the SELECT group is exited. If F=50 is true, the IF statement is executed and the SELECT group is exited. If more than one WHEN statement is true, the action associated with the first true WHEN clause is executed. If no WHEN clauses are true, the DO group associated with the OTHERWISE clause is executed. When control reaches a SELECT statement with a selectexpression 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 selectexpression. 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 selectexpression, the action specified after the OTHERWISE clause is executed unconditionally. for more information, see the section SELECT in the chapter Statements. Parent topic: Compound Statements Related information SELECT
or GO TO labelreference[OTHERWISE]; where: labelreference is a label constant or an expression that, when evaluated, yields a label value. (A label value denotes a statement in the program.) For example: A = 5; GOTO L2; L1: B = 7; . . . L2: B = 4; In this example, A is assigned 5 and B is assigned 4. The statements beginning with label L1 can be executed only if a GOTO statement transfers control to the label L1. Although labels are a convenient means to represent a specific location in a program, programs that contain many labels are generally more difficult to read and modify. The use of labels and GOTOs can be avoided or minimized by using the compound statements IF and DO to control the order of statement execution. The DO statement causes all statements between the DO statement and its corresponding END statement to be executed a number of times as determined by the form of the DO statement. Parent topic: Statement Sub-Groups Send feedback about this topic
until the ON-unit is reverted using the REVERT statement. If one of the possible conditions occurs during the execution of a block, and that block does not have an established ON-unit for that condition, the calling block's ON-unit is used to respond to the condition. If the calling block has no established ON-unit for the condition, its caller's ON-unit is used, and so on. If no ancestor has an ON-unit for the condition, a default action is taken. Except for the ENDPAGE, FINISH, and UNDERFLOW conditions, this default action ends program execution and issues a run-time error message. ON-units for the ERROR condition cannot resume execution of the statement in which the error was detected. Parent topic: Statement Sub-Groups Send feedback about this topic
Parent topic: Language Concepts Related information Open PL/I Macro Preprocessor
The specified filename is used to locate a text file whose content is inserted into the program text in place of the % INCLUDE statement. Your selection of one of these forms in combination with the presence or absence of the -ipath compiler option affects the search pattern used in locating files to be included. For more information, see the section %INCLUDE in the chapter Statements. Note: The Open PL/I Macro Preprocessor has its own %INCLUDE statement. Its use is documented in the appendix Open PL/I Macro Preprocessor.
Parent topic: Text Replacement and Insertion Statements Related information %INCLUDE Open PL/I Macro Preprocessor
of the module, as explained in the section Blocks. Parent topic: Text Replacement and Insertion Statements Related information Blocks
1.8. Modules
One or more external procedures can be present within a single Open PL/I source file. All external procedures within a source file will be compiled by the Compiler into a single object file. A module is defined as a single compilation unit, a source file that is compiled into object code. A module consists of one or more external procedures. A source file may contain declarations that appear outside the scope of any external procedure, as long as all variables that appear in such declarations are BASED, STATIC, or DEFINED. A variable that is defined this way is known within the scope of all external procedures. If a declaration is provided with the EXTERNAL attribute, it will be known outside the source file. A source file may also contain %REPLACE statements and declarations of named constants (for example, file and entry constants) before the first external procedure. The following example illustrates a source file that has declarations and %REPLACE statements preceding the first external procedure. There are two procedures (GETREC and PUTREC) in the source file that can be used as part of the program. By default, Open PL/I declares these entry constants, GETREC and PUTREC, with the EXTERNAL attribute; therefore, a procedure from another module outside of this source file can invoke GETREC or PUTREC. If a procedure in another module needs to reference GETREC and PUTREC, they must be declared within that module with the attributes ENTRY and EXTERNAL. At the top of this source file are other items (REC, NAME, ADDRESS) that are hidden from any procedures compiled in other modules, and are known only to GETREC and PUTREC. Because Open PL/I, by default, provides file constant declarations with the EXTERNAL attribute, the file DATA_BASE can be known in other modules. %REPLACE DATA_SIZE BY 80; DECLARE 1 REC BASED 2 NAME CHAR(40), 2 ADDRESS CHAR(DATA_SIZE); DECLARE DATA_BASE KEYED FILE UPDATE; GETREC: PROCEDURE(P); DECLARE P POINTER; READ FILE(DATA_BASE) INTO(P->REC); END GETREC; PUTREC: PROCEDURE(P); DECLARE P POINTER; REWRITE FILE(DATA_BASE) FROM(P->REC); END PUTREC;
1.9. Blocks
PL/I is a block-structured language. Just as certain language elements make up statements, groups of statements make up blocks. Two types of blocks exist in Open PL/I:
A procedure block is the basic executable program unit of Open PL/I and is made up of a group of statements contained within the limits of a pair of statements, PROCEDURE and END. A BEGIN block is a program unit into which control flows during the typical execution of a procedure. The statements within a BEGIN block are contained within the limits of a pair of statements, BEGIN and END. Whenever a procedure block or BEGIN block is entered, a block activation is created for that block. The block activation consists of the allocation of storage for the variables declared within the block and the system information that links that block to the previous block in the activation chain. The following sections provide detailed information on procedure and BEGIN blocks and activation of these blocks.
Procedure Blocks
Procedures contained within other procedures are called nested or internal procedures. Procedures not contained within other procedures are called external procedures. A program module consists of one or more external procedures. For example: A: PROCEDURE; . . . B: PROCEDURE; . . . END B; C: PROCEDURE . . . D: PROCEDURE; . . . END D; END C; END A; In this example, Procedure A is external, and procedures B and C are nested within it. Procedure D is nested within procedure C.
Scope Calls and Returns Parameters and Arguments Block Activation and Recursion Guidelines for Using Procedures Dynamic Fetching and Releasing of External Procedures
1.9.1.1. Scope
Each procedure block establishes a distinct region of the program text called "scope," throughout which the names declared within that procedure block are known. The scope of a name is defined as the region of the program in which the name has meaning and can be referenced.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (31 of 166) [16-03-2013 17:31:33]
The scope of a name includes the procedure in which the name is declared and all procedures contained within that procedure, except those contained procedures in which the same name is redeclared. For example: A: PROCEDURE; DECLARE (X,Y) FLOAT; . . . B: PROCEDURE; DECLARE X FILE; DECLARE Z FIXED; . . . END B; END A; In this example, the scope of Y includes both procedure A and procedure B. The scope of X as a float is only procedure A. The scope of X as a file is procedure B. The scope of Z is procedure B. Z cannot be referenced from within procedure A. The scope of the procedure name B includes both procedure A and procedure B. Parent topic: Procedure Blocks Send feedback about this topic
shown in the following example: A: PROCEDURE; . . . IF X<0 THEN RETURN; . . . END A; Control does not "flow" into a procedure; that is, if control reaches a statement immediately preceding a procedure declaration, then (unless the statement is a control-flow statement such as GOTO) control will automatically skip to the statement following the declared procedure. Parent topic: Procedure Blocks Send feedback about this topic
When an argument is a variable, the actual address of the variable is passed to the called procedure. This allows the invoked procedure to change the value of the argument. When an argument is a constant or an expression, a temporary location is used to store the current value of the argument, and the address of that temporary location is passed to the called procedure. Parent topic: Procedure Blocks Send feedback about this topic
IF IN = NULL THEN RETURN(NULL); ALLOCATE RECORD SET(OUT); OUT->RECORD.FIELD1 = IN->RECORD.FIELD1; OUT->RECORD.FIELD2 = IN->RECORD.FIELD2; OUT->RECORD.DAUGHTER = COPY(IN->RECORD.DAUGHTER); OUT->RECORD.SON = COPY(IN->RECORD.SON); RETURN(OUT); END COPY; As demonstrated in this example, each record of the original tree structure may be linked using pointers to a SON record and/or a DAUGHTER record. Either the SON or the DAUGHTER field may contain a null pointer value. COPY is called with a pointer to the root in the original tree structure. It returns a pointer to the root in a new tree structure that is a copy of the original. Each activation of the COPY procedure has its own instance of the variables IN and OUT. For additional information about recursive procedures, see the section Entry Data in the chapter Data Types. Parent topic: Procedure Blocks Related information Entry Data
Write procedures with minimal dependence on their ability to access the values of their containing procedure. All such use of nonlocal variables should be clearly documented by comments in both the declaring and the using procedures. Write procedures that are used only from within a given procedure as internal procedures within the calling procedure. Write internal procedures following the executable statements of the containing procedure. Make each procedure as small as possible to enable understanding of program logic.
can be loaded into it and then deleted from it at any time during the execution of the calling procedure. This is useful when it is not necessary to call the external procedure every time when the calling procedure is executed. A procedure has to be loaded into main storage before it can be executed, unless it is already there. Once loaded, the procedure can remain in main storage until the execution of the whole program is completed, or it can be deleted at any time using the RELEASE statement. A fetched procedure is compiled and linked separately from the calling procedure. For more information, see Compiling, Linking and Debugging of Fetchable Procedures. Whenever the load module containing the fetched procedure is loaded into memory, the STATIC variables in the fetched procedure are given the initial values indicated by their declarations. Note that EXTERNAL files and CONDITION conditions are shared across the whole application, including the fetched procedures.
Parent topic: Procedure Blocks Related information Compiling, Linking and Debugging of Fetchable Procedures
Syntax
FETCH entry-constant [SET(ptr-ref)][TITLE (char-expr)]
Parameters
entry-constant The name by which the loaded procedure is known to the operating system. It is the same as the one used in the corresponding CALL statement, or CALL option of an INITIAL attribute, or function reference.
ptr-ref A pointer reference that is set to the address of the entry point of the module that is loaded. char-expr Any character expression.
Description
The FETCH statement is used to dynamically load modules into main storage. It must specify an entry constant, which is the name by which the fetched procedure is known to the operating system. When this name is referenced in a FETCH statement, the procedure can also be loaded into main storage when a CALL statement, or a CALL option of an INITIAL attribute, or a function reference is executed.
Restrictions
See Restrictions under Dynamic Fetching and Releasing of External Procedures. Parent topic: Dynamic Fetching and Releasing of External Procedures Related reference RELEASE Statement Related information Dynamic Fetching and Releasing of External Procedures
Syntax
RELEASE entry-constant
Parameters
entry-constant The RELEASE statement must specify an entry constant. It is the name by which the loaded procedure is known to the operating system. It is the same as the one used in the corresponding FETCH statement, CALL statement, CALL option of an INITIAL attribute, or function reference.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (37 of 166) [16-03-2013 17:31:33]
Description
The RELEASE statement releases (deletes) from main storage a previously fetched modules. RELEASE * deletes all previously fetched modules. It must not be executed from within a fetched module.
Restrictions
See Restrictions under Dynamic Fetching and Releasing of External Procedures. Note: RELEASE* is not currently supported but an API can be provided if this functionality is needed.
Parent topic: Dynamic Fetching and Releasing of External Procedures Related reference FETCH Statement Related information Dynamic Fetching and Releasing of External Procedures
1.9.1.6.3. Restrictions
If you have an ON CONVERSION on unit that is located in the main program and triggered by a fetchable procedure, or located within a fetchable procedure and triggered within another fetchable procedure that is subordinate to it on the callstack, then the ONCHAR() and ONSOURCE() built-in functions will not correctly "reset" the triggering variables values within the fetchable procedure that caused the condition. If the ON CONVERSION on unit is within the triggering fetchable procedure (or main program), then there is no problem. If the fetchable module has its procedure declared with OPTIONS(MAIN) or if when linking you specify the options -cics, -ims, or -mvs, then your fetchable routine will have its own runtime context and ON UNIT's memory chains, and file variables will not be shared across fetchable boundaries. For any program which does any form of file I/O, the following needs to be done:
r
For each FILE declaration it must have storage allocated to its FILE constant. This is achieved through the use of the -defext compile option and/or through the use of an optional parameter called GLOBALDEF. It is important that within a fetchable procedure or a program compiled with OPTIONS (MAIN), this is done exactly one time per FILE constant. If this is not done, the results are completely unpredictable and the behaviors will not be supported. For typical usage, compiling with -defext is more than adequate. If you have two or more subroutines which are all accessing the same FILE constant, and they are linked into a single fetchable procedure or program, only one of the programs should be compiled with -defext. As an alternative approach you can add the attribute GLOBALDEF to one of the file declarations and not use the -defext switch for any of the compiles.
Parent topic: Dynamic Fetching and Releasing of External Procedures Send feedback about this topic
1.11. Variables
A variable is a named object that is capable of holding values. Each variable has two properties: Data type Determines the kind of values a variable holds. Storage class Determines the duration of a variable's existence and how it is referenced.
In these examples, variable A is capable of holding any floating-point decimal value with mantissa of up to 7 digits and exponent of up to 3 digits; variable N is capable of holding any binary integer value between -32768 and +32767 inclusive; variable C is capable of holding any string of 30 characters; and variable B is capable of holding either '1'B or '0'B. Although each variable is capable of holding values of only a specific data type, the Open PL/I language provides a complete set of operations that convert values from one data type to another. Whenever a value is assigned to a variable, it is first converted to the data type of the variable, as illustrated in the following examples (which refer to the declarations in the previous examples). Examples: A N C B = = = = 1; /* converts 1 to FLOAT DECIMAL(7) */ 2.5; /* converts 2.5 to the FIXED BIN(15) integer 2 */ -4.5; /* converts -4.5 to a character string */ 0; /* converts integer 0 to '0'B */
For a complete discussion of data type conversions, see the chapter Data Type Conversions. Parent topic: Variables Related information Data Types Data Type Conversions
Unless declared otherwise, a variable's storage class is AUTOMATIC, meaning that it is allocated storage each time its immediately enclosing scope becomes active (as happens during a procedure call or the execution of a BEGIN statement. Exiting the scope frees this allocated storage (as happens at procedure or BEGIN block termination). Consequently, AUTOMATIC variables do not retain their values after deactivation of the block in which they are contained. If a variable must retain its value between calls of its containing procedure, it should be declared to have the STATIC storage class. For example: DECLARE K FIXED BINARY STATIC; DECLARE TABLE(4) CHARACTER(5) STATIC INITIAL('A','B','C','D'); In this example, each element of the array TABLE is given an initial value. Storage for STATIC variables is allocated prior to program execution by the Compiler and linker. Consequently, the length (precision) of each STATIC variable must be constant at compile time. Parent topic: Variables
1.12. Files
In Open PL/I, a file is a source of input data or a target for data output. Files are referenced in I/O statements by using a file name declared with the FILE attribute. The file reference actually refers to a file constant or to a file variable that has been assigned a value. Each file used by the program must be declared in exactly one module in the program. That module must either declare the file with the GLOBALDEF attribute or must be compiled with the -defext option.
If you do not use environment variables to connect these openings with systems files, the following system names will be assumed for the files: DATA2 and Report. Instead, prior to running the application, you could set environment variables as follows, causing the specified system files to be used. (Any directories used in the path names must exist.)
setenv LPI_DATA2 /dir1/dir2/master.data setenv LPI_Report /doc/reports/deptA/week23.rep In the second example, LPI_Report was used rather than LPI_FACTS, because of the TITLE option in that file's OPEN statement. Parent topic: Files Send feedback about this topic
List-directed stream I/O, as performed by the GET LIST and PUT LIST statements. Edit-directed stream I/O, as performed by the GET EDIT and PUT EDIT statements.
In both list-directed and edit-directed stream I/O, the files are written by the PUT statement and are read by the GET statement. In edit-directed stream I/O, data is transmitted to or from a stream file under the control of a format-list. In
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (44 of 166) [16-03-2013 17:31:33]
list-directed stream I/O, data is transmitted to and from the stream file without a format-list. In edit-directed stream I/O, format-lists can be part of the GET or PUT statement or can be given by a FORMAT statement. Execution of a GET or PUT statement transmits data from or to the current line of a stream file and may not consume or produce an entire line of the stream file. Several PUT statements can be used to build a given line, or a single PUT statement can be used to output several lines. Similarly, several GET statements can read values from a given line, or a single GET statement can be used to read one or more lines. Lines read from a disk file are not modified by Open PL/ I in any way; however, lines read from all other devices have trailing blanks removed and have one blank appended to the end of each line that is read by a GET statement. This blank ensures that a field typed at the beginning of a line is not appended to a field typed at the end of the previous line. Each stream file has an associated line size that is determined when the file is opened. Lines of an output file contain n characters, where n is the line size of the file. (For more information, see the discussion of the LINESIZE option in the section Stream File Attributes.) A shorter line can be created by using the SKIP option on a PUT statement, as shown in the following example of a list-directed stream I/O statement. The shorter lines are padded to the right with blanks to obtain a length of n characters. For example: PUT FILE(F) SKIP LIST(A,B,C); PUT FILE(F) SKIP; In this example, the current line (consisting of data previously output) is output and one or more new lines containing the values of A, B, and C are created. The second PUT statement forces the last line containing A, B, and C to be output and starts a new line. The SKIP option is always executed before any new data is transmitted. On input, each line can be of any length up to the value of the line size. Execution of a GET statement reads from the current line until a new line is reached, the new line is ignored, and execution continues reading values and lines until the list of variables has been read. A SKIP option can be used to force a new line to be read prior to reading any values, as shown in the following example. GET FILE(F) LIST(A,B,C); GET FILE(F) LIST(D); GET FILE(F) SKIP LIST(X,Y); In the previous example, A, B, and C are read from the current line or from as many lines as are necessary. D is read from the same line as C, unless C happened to be the last value on its line. The SKIP option skips to a new line and consequently ignores any values remaining on the line after the value received by D. X and Y are read from the line that is current after the SKIP option, as well as any additional, necessary lines. The PAGE option can be used in a PUT statement to begin a new page prior to transmitting any values, as shown in the following example. PUT FILE(F) PAGE LIST(A,B,C); For a complete discussion of GET, PUT, and FORMAT statements, see the chapter Statements. Note: Standard PL/I, in a stream file, does not provide a way to read a variable-length input line from the current position to a newline indicator. Open PL/I provides two nonstandard methods to read all characters from current position to new line into a character varying variable: a READ statement and an edit-directed GET statement. To read a variable-length line with a GET statement, you must use an A-format without a field width.
Data-Directed Stream I/O Edit-Directed Stream I/O Terminal I/O on a Stream File
Parent topic: Input and Output Related information Stream File Attributes Statements READ A-Format
in the current output line of file F. The field -75 is produced by converting the fixed binary(15) integer to a character-string. The many blanks allow for the maximum possible value, plus sign and decimal point and leading 0 for fractional values, as explained in the section Arithmetic to Character-String Conversion in the chapter Data Type Conversions. A single blank separates the value of A from the value of B. The last blank separates B from the next field. For input, list-directed I/O considers each blank or comma as a field terminator. Excess commas are not allowed. Excess blanks within a field to be assigned to an arithmetic variable are ignored. Such fields must simply contain a valid constant, as could be written in the text of a program. A field to be assigned to a character-string variable may contain a character-string constant, as written in the text of a program, or it may contain a sequence of any characters. In the latter case, the sequence begins with the first nonblank character in the field and ends with the character immediately preceding the next comma or blank, as shown in the following example of a GET LIST operation. Note that character sequences containing blanks or commas that are to be treated as a unit must be enclosed in single quotation marks ("). For example:
GET FILE(F) LIST(A,B); In this example, if A is fixed binary(15) and B is character(5), the following lines have the indicated effect on the values of A and B.
Line
5 -4 5 -4 5 abc-4
Each data value is preceded by the fully-qualified and specifically subscripted PL/I program name of that data value, as shown. The values themselves are formatted as they would be by a PUT LIST statement, except that character values are always enclosed in quotes. Parent topic: Stream I/O Send feedback about this topic
PUT FILE(F) EDIT(A,B) (F(7,2),A(6)); In this example, if A is declared fixed binary(15) and has a current value of -45, and B is declared character(4) and has a current value of HAT , the following is written into the current line of file F.
Control formats can be used to force new lines and skip parts of lines, as shown in the next example. If there are more format items than values to be transmitted in the statement's I/O list, the extra format items are ignored. For example: PUT FILE(F) EDIT(A,B) (X(3),F(7,2),SKIP,X(4),A(6),SKIP); Using the same values of A and B as in the previous example, the above statement produces the following:
In this example, the first line is placed at the end of the current line, and the second line starts a new output line. The PUT statement does not start another new line, because B was the last item output; hence, the PUT statement terminated before the second SKIP was executed. Edit-directed input requires that each input line be described precisely by the controlling format. If the current input line contains fewer characters than are required to satisfy the format, additional lines are read until the format is satisfied, as shown in the following example. GET FILE(F) EDIT (X) (A(80)); In this example, if X is declared as character(100) and the current line contains only 60 characters, the 60 characters are read, a new line is read, processing advances to the next line, and 20 additional characters are read from that line. The 80 characters thus read are then assigned to X, and 20 blanks are used to pad the value of X on the right. Parent topic: Stream I/O Send feedback about this topic
Each PUT statement transmits data to the device without waiting for the line to be filled. A GET statement resets the current column position used by subsequent PUT statements.
Attribute
Permitted in Specification
DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN OPEN OPEN OPEN
The use of PRINT implies STREAM OUTPUT. If neither INPUT, OUTPUT, nor PRINT is specified, INPUT is assumed. LINESIZE and PAGESIZE can be used only for PRINT files. If neither STREAM nor RECORD is specified, the default is STREAM. (See the section Record I/O.) STREAM and RECORD are mutually exclusive, as are INPUT and OUTPUT. If attributes are specified both in the DECLARE statement and the OPEN statement for a file, the attributes used are the combination of those in the two statements. The combination may include only one of each mutually exclusive set. The TITLE option is used to associate a file as declared in the PL/I program with a file or device as known to the operating system. In the following examples of OPEN statements, the quoted text in the TITLE options specifies the system filename or device name to be used in I/O operations with the opening of the PL/I file indicated by the FILE option. If the TITLE option is not specified in an OPEN statement, the declared name of the file constant is used as the default title. The LINESIZE option is used in an OPEN statement to specify the maximum number of characters that can be output in a single line for a STREAM file. If no line size is specified, a default line size is assumed. For more information on LINESIZE, see the section PUT in the chapter Statements. The LINESIZE option can appear in the OPEN statement only and is valid only with STREAM OUTPUT files. During output, a newline will be inserted whenever the column position equals (LINESIZE+1). The SKIP or LINE options with a PUT statement cause a newline character to be inserted and the column position to be reset. The COLUMN format with a PUT EDIT statement may cause a newline to be inserted. The default may vary according to the file name or device. In Open PL/I, the default value of the LINESIZE option is 120. The PAGESIZE option is used in an OPEN statement to specify the maximum number of lines that can be written to a print file without signaling the ENDPAGE condition. If no page size is specified, a default page size is supplied. In Open PL/I, the default value of the PAGESIZE option is 60.
If a GET or PUT statement is executed on a file that has not been opened, the file is implicitly opened as a STREAM file using the declared name of the file constant as the title. A file so opened by a GET statement is opened as an INPUT file, one so opened by a PUT statement is opened as an OUTPUT file. You can add text to any existing stream file (any ASCII file) by using the -APPEND option in the TITLE option of the OPEN statement. Thus, if the file you wish to append to is named "logfile," open it with the following TITLE option: TITLE('logfile -APPEND') Any subsequent PUT statements to this file simply append their output to the end of the file.
Examples:
Parent topic: Terminal I/O on a Stream File Related information Record I/O PUT TITLE Options
1.13.1.4.1.1. Examples:
OPEN FILE(F) OUTPUT TITLE('thedata'); OPEN FILE(TTY) TITLE('CONSOLE') STREAM INPUT; OPEN FILE(PTR) TITLE('LPT1') STREAM OUTPUT PRINT LINESIZE(132) PAGESIZE(60); OPEN FILE(MSG_FILE) INPUT; /* The default title is 'MSG_FILE' */
Parent topic: Stream File Attributes Send feedback about this topic
The LINENO built-in function allows you to access the current line number of an output stream file opened with the PRINT attribute. Each time a line is written to the output stream, the line number is incremented by one. Each new line is initially positioned so that the next item is written to column 1 of the line. The PAGENO built-in function lets you read the current page number of an output stream file opened with the PRINT attribute. The current page number can be set using the PAGENO pseudo-variable. The ENDPAGE condition is signaled when the line to be written has a line number that is the page size plus one, or when a SKIP option positions the file to (or past) page size + 1. Each time a new page is written, the line number is reset to one and the page number is incremented by one. If an ON-unit for the ENDPAGE condition does not write a new page, the line number is allowed to increase indefinitely until a new page is written. The ENDPAGE condition is signaled only when the line to be written has a line number that is one greater than the page size. A new page is written only by a PAGE option of a PUT statement, by a PAGE format-item, and by the default ON-unit for the ENDPAGE condition. In Open PL/I, tab stops are set every eight columns for a stream file that has the PRINT attribute. Parent topic: Terminal I/O on a Stream File Send feedback about this topic
Record File Attributes Consecutive Record I/O Indexed Record I/O Relative Record I/O REGIONAL(1) Record I/O
TITLE Options
Parent topic: Input and Output Send feedback about this topic
Attribute
Permitted in Specification
Implied
DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE OPEN RECORD RECORD RECORD RECORD KEYED
If neither INPUT, OUTPUT, nor UPDATE is specified, INPUT is assumed. If neither SEQUENTIAL nor DIRECT is specified, SEQUENTIAL is assumed. If neither STREAM nor RECORD is specified, the default is STREAM. (See the section Stream I/O.) The following sets of attributes are mutually exclusive:
STREAM and RECORD INPUT, OUTPUT, and UPDATE SEQUENTIAL and DIRECT
If attributes are specified both in the DECLARE statement and the OPEN statement for a file, the attributes used are the combination of those in the two statements. The combination may include only one of each mutually exclusive set. The TITLE option is used to associate a file as declared in the PL/I program with a file as known to the operating system. In the following examples of OPEN statements, the quoted text in the TITLE options specifies the system filename to be used in I/O operations with this opening of the PL/I file indicated by the FILE option. If the TITLE option is not specified in an OPEN statement, the declared name of the file constant is used as the default title. Examples:
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (52 of 166) [16-03-2013 17:31:33]
OPEN FILE(F) RECORD OUTPUT TITLE('thedata'); OPEN FILE(F) RECORD INPUT; /* The default title is 'F' */ If a READ, WRITE, REWRITE, or DELETE statement is executed on a file that has not been opened, the file is implicitly opened as a RECORD file using the declared name of the file constant as the title. The attributes assigned to the file implicitly opened depend on the I/O statement used, as indicated below:
Assigned Attributes
Record input and output operations are restricted to files opened with certain attributes. These restrictions are shown in the following table:
File Attributes
If a file opened for INPUT or UPDATE does not exist, an error is signaled. If a file opened for OUTPUT does not exist, a file is created. If the file has been opened as DIRECT or KEYED SEQUENTIAL, a keyed file is created; otherwise, a non-keyed file is created. If a file opened for OUTPUT already exists, it is deleted and a new file is created. However, if the -APPEND option is specified in opening the file, an existing file can be opened for OUTPUT. You can add records to an existing record file by using the -APPEND option in the TITLE option of the OPEN statement. Thus, if the file you wish to append to is named "logfile," open it with the following TITLE option: TITLE ('logfile -APPEND') Any subsequent WRITE statements to this file simply append their output to the end of the file. A REWRITE statement replaces an existing record in an UPDATE file with a new record. A DELETE statement basically removes an existing record from an UPDATE file. A WRITE to an existing record and a READ from a nonexistent record are not allowed. A WRITE to a record past EOF will append the record to the end of the file. A DELETE or REWRITE of a nonexistent record signals a KEY condition. (For further information, see the description of KEY in the section ON in the chapter Statements.) Record I/O statements copy the storage of a variable to or from a record in a file (except in the case of READ
operations using locate mode I/O, see below). No conversion is performed and no check is made to ensure that the data being read is of the proper type to store into the variable. The variables used in INTO or FROM options cannot be unaligned bit strings or structures consisting entirely of unaligned bit strings, because such variables normally share a portion of their storage with other members of the same array or structure. Also, an expression cannot be used in a FROM or INTO option. Note: Structures with the UNION attribute cannot be used as variables in READ, WRITE, PUT, and GET statements. READ operations can be performed in two "modes": move mode and locate mode. A READ statement that specifies the INTO option causes the input data to be stored directly into the variable referenced by the INTO option. This is called a "move mode" READ. A READ statement that specifies the SET option instead of the INTO option causes the input data to be stored in an unnamed storage buffer and causes the address of this buffer to be assigned to the pointer variable referenced by the SET option. This is called a "locate mode" READ. A complete discussion of record I/O statements is found in the chapter Statements. Examples: READ FILE(CUSTOMERS) KEY(CUST_ID) INTO(CUST_RECORD); PUT SKIP LIST(CUST_RECORD.NAME); READ FILE(CUSTOMERS) KEY(CUST_ID) SET(CPTR); PUT SKIP LIST(CPTR->BASED_RECORD.NAME);
Parent topic: Record I/O Related information Stream I/O TITLE Options ON Statements
Example: CONFILE: PROCEDURE OPTIONS(MAIN); DECLARE TEST RECORD OUTPUT FILE ENV(CONSECUTIVE); DECLARE REC1 CHAR(5) INIT('AAAAA'); DECLARE REC2 CHAR(10) INIT('BEEBBBBBBB'); OPEN FILE(TEST) TITLE('testdata'); WRITE FILE(TEST) FROM(REC1); WRITE FILE(TEST) FROM(REC2); WRITE FILE(TEST) FROM(REC1); CLOSE FILE(TEST); END CONFILE; The file testdata resulting from this program will contain the following 20 bytes: AAAAABBBBBBBBBBAAAAA Note: Open PL/I has an older method of accomplishing the same thing. It is done by using the TITLE option of the OPEN statement rather than the ENVIRONMENT attribute of the DECLARE statement. The following illustrates the old method. DECLARE RECORD TEST OUTPUT FILE; OPEN FILE (TEST) TITLE ('testfile -SAM');
File Attributes
Permitted Access
SEQUENTIAL
SEQUENTIAL only
An INDEXED (equivalently, VSAM) file is declared by including either the INDEXED or the VSAM option of the ENVIRONMENT attribute. For example, DECLARE MASTER RECORD OUTPUT FILE ENVIRONMENT(VSAM KEYLOC(1) KEYLENGTH(12) RECSIZE(130)); The KEYLOC option specifies the byte position of the first byte of the key in the records, counting the first byte as KEYLOC(1). The KEYLENGTH option specifies the number of characters in the key. RECSIZE specifies the record length or, in the case of a file of variable-length records, it specifies the maximum record length. Actually, it is necessary to specify RECSIZE, KEYLOC, and KEYLENGTH for a file only when it is created. Programs that read or update an existing indexed file do not need to include these options, although they may. Open PL/I can determine these characteristics from an existing file. If you are using full IBM mode, file header information is used when opening a VSAM file for output, rather than requiring you to specify RECSIZE, KEYLOC, or KEYLENGTH with the ENVIRONMENT attribute. There are a number of options that can be specified with the ENVIRONMENT attribute. These options are described in the table below. This table also lists a number of options that are not needed or not supported in Open PL/I, but which a user may expect to find based on experience with other compilers.
Option
Description
ASCII BKWD
The ASCII option is assumed in Open PL/I. Specifies backward processing for indexed files read in the SEQUENTIAL mode; that is, sequential processing will start with the current record (or last, by default) in the file and proceed to previous records. The BUFFERS option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFOFF option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFND option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFNI option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFSP option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies a file with consecutive organization. For related information, see the description of the -defext compiler option in your Open PL/I User's Guide. The CTLASA option is ignored. The CTL360 option is not implemented in Open PL/I. If it is used, the Compiler issues a warning.
F | FB | FS | FBS GENKEY
Specifies record format, where F = fixed length, B = blocked, and S = standard. Open PL/I treats any such specification as though it were F alone fixed length. Specifies a generic key, a character string that is a prefix of a key. A READ with a KEY clause returns the first record whose key is greater than or equal to the string specified by the KEY clause. A subsequent sequential READ (no KEY clause) will return the next record greater than the current record. The INDEXAREA option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies a file with indexed organization. For related information, see the description of the -defext compiler option in your Open PL/I User's Guide. Specifies the length, n, of the embedded key for indexed files. KEYLENGTH can be specified only when INDEXED or VSAM is specified. Specifies the starting location of an embedded key in a record. n must be within the limits: 1 n recordsize keylength + 1. The default KEYLOC value is 1. KEYLOC can be specified only when INDEXED or VSAM is specified. Note: Be sure that KEYLOC considers the 2-byte prefix generated by specification of the SCALARVARYING option.
LEAVE MINRECSIZE(n)
The LEAVE option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies the minimum record length, n. n must be an integer. This option allows for better disk space utilization. The MINRECSIZE option is required with V (variablelength) record formats. It is ignored for F (fixed-length) record formats. The values specified for the KEYLOC and KEYLENGTH options must be within the value specified by the MINRECSIZE option. For more information on the MINRECSIZE option, see below. The NCP option is not applicable in Open PL/I. Open PL/I treats INDEXED files the same as VSAM files. The NOWRITE option is not needed in Open PL/I. If it is used, the Compiler ignores it. The PASSWORD option is not implemented in Open PL/I. If it is used, the Compiler issues a warning. Specifies the maximum record length, n. n must be an integer.
REGIONAL(1 | 2 | 3)
The REGIONAL(1) option specifies files whose records are identified by their region numbers. The REGIONAL(2) and REGIONAL(3) options are not implemented in Open PL/I. If they are used, the Compiler flags it as an error.
REUSE SCALARVARYING
The REUSE option specifies that an OUTPUT file associated with a VSAM data set is to be used as a work file. . Used for the input and output of varying length records. SCALARVARYING enables the recognition of a two-byte prefix that specifies the current length of the records. Note: Be sure that KEYLOC considers the 2-byte prefix generated by specification of the SCALARVARYING option.
The SIS option is not needed in Open PL/I. If it is used, the Compiler ignores it. The SKIP option is not needed in Open PL/I. If it is used, the Compiler ignores it. The TP(MIR) option is not implemented in Open PL/I. If it is used, the Compiler flags it as an error. The TRKOFL option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies record format. Open PL/I treats any such specification as though it were F fixed length. Specifies record format, where V = variable length, B = blocked, and S = spanned. Open PL/I treats any such specification as though it were V. Specifies files organized for the virtual storage access method (VSAM). For related information, see the description of the -defext compiler option in your Open PL/I User's Guide.
A random access read of a record in an indexed (VSAM) file opened with the INPUT or UPDATE attribute is accomplished by a READ statement that includes the KEY option. For example, READ FILE(PARTS) INTO(PART_REC) KEY(PART_NUM); A sequential read reads the next record of the file after the last one read using the key ordering or the first record of the file, if no record has previously been read. For a sequential READ statement, the KEY option is omitted. If a record has previously been read from a file opened with the UPDATE attribute, and no other intervening I/O operation has been performed, a REWRITE without key may be executed. In this case, the previously read record is overwritten with the new value. For example, READ FILE(PARTS) INTO(PART_REC) KEY(PART_NUM); PART_REC = NEW VALUE; REWRITE FILE(PARTS) FROM(PART_REC); However, a record of an indexed file can be randomly updated by specifying the KEYFROM option in the REWRITE statement. For example,
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (58 of 166) [16-03-2013 17:31:33]
REWRITE FILE(PARTS) FROM(PART_REC) KEYFROM('12XJ04'); If an indexed file has been opened with the OUTPUT or UPDATE attribute, a WRITE statement using the KEYFROM option can be used to add new records to the file. The WRITE statement without KEYFROM is used to sequentially add new records to a file. The DELETE statement can be used to remove records from an indexed file opened with the UPDATE attribute. The KEY option must be used to delete a record. All keys used in an indexed (VSAM) file must by of type CHARACTER. If a KEY or KEYFROM option references a value that is not of type CHARACTER, the value is converted to CHARACTER before the I/O operation begins. Note that keys of type PICTURE are converted to CHARACTER without any actual change in the key contents. (See the chapter Data Type Conversions.) An indexed (VSAM) file can have either fixed-length or variable-length records. The records are fixed-length if the F option is used with the ENVIRONMENT attribute when the file is created; they are variable-length if the V option is used. (See the table above.) If neither F nor V is specified, F is assumed. In a fixed-length record file, all records must have the same length, which is the length specified by the RECSIZE option of the ENVIRONMENT attribute when the file was created. For a variable-length record file, RECSIZE specifies the maximum record length that is permitted in the file. The MINRECSIZE option must also be specified for a variablelength record file. This value specifies the minimum length that all records in the file must have. The keys of the file must be contained within this minimum portion of the file. The SCALARVARYING option specifies that there is a two-byte prefix on all records in the data file. A user must take this into account when specifying the KEYLOC value. The KEYLOC value is the absolute byte position of the record starting at 1. This option can be used on either F or V record formats. It allows for more general use of character varying records in I/O statements, although character records can also be transmitted. When a character varying item is used in a WRITE or REWRITE statement, the two-byte prefix is retained with the record as it gets written out to the data file, if the SCALARVARYING option is set. Without the SCALARVARYING option, the prefix is not written; in this case, the remainder of the record is undefined beyond its current length. When a character record is written, a prefix will be added if SCALARVARYING option is set. The SCALARVARYING option lets you write and read records smaller then your max record size, without getting the RECORD condition. It also is useful when doing locate mode I/O. When setting KEYLOC, it is very important to "compensate" for the two-byte prefix when the SCALARVARYING option is used. The use of V type records provide a way to transmit partial records. Open PL/I does not require control bytes in the record for this support. The run-time system will automatically retain information concerning the number of bytes transmitted. Since no control information is needed in the record, the user should not change KEYLOC based on the record type. Only the SCALARVARYING option has impact on the KEYLOC location. Although the PL/I language does not provide a mechanism by which multiple keys can be specified for a file, Open PL/ I does provide a means for accessing data via multiple keys. After an indexed file has been created using one key (which is called the primary key), you can use the utility Ipivsam to add additional indexes (that is, keys) to the file. In the PL/I program each different key version of the data must be declared as a separate file. However, all of these declared files can actually be referencing the same set of data. For example, DECLARE EMPFILE1 RECORD UPDATE FILE ENV(VSAM KEYLOC(1) KEYLENGTH(6) RECSIZE(145)); DECLARE EMPFILE2 RECORD UPDATE FILE ENV(VSAM KEYLOC(31) KEYLENGTH(3) RECSIZE(145) GENKEY); DECLARE 1 EMP_ 2 EMP_ID (CHAR(6), 2 NAME (CHAR(24),
2 DEPARTMT ...
(CHAR(3),
OPEN FILE(CUSTFILE1) TITLE('employee'); OPEN FILE(CUSTFILE2) TITLE('employee'); /* same file, different key */ The following example program illustrates the use of the ENVIRONMENT variable and its options for I/O on a file with VSAM organization. /* Example of VSAM I/O */ TEST: PROCEDURE OPTIONS(MAIN); %REPLACE TRUE BY '1'B; %REPLACE FALSE BY '0'B; DECLARE DB FILE ENV(VSAM KEYLOC(21) KEYLENGTH(120) RECSIZE(244)); DECLARE DBG FILE ENV(INDEXED GENKEY KEYLOC(21) KEYLENGTH(120) RECSIZE(244)); DECLARE 1 DB_RECORD, 2 HEADER CHAR(20), 2 DBKEY CHAR(120), 2 STUFF CHAR(100), 2 NUMBER FIXED BIN(31); DECLARE I FIXED BIN(31); DECLARE CS CHAR(26) STATIC INIT('THEQUICKBROWNFXJMPSVLAZYDG'); DECLARE C(26) CHAR DEFINED(CS); DECLARE LETTERS CHAR(30); /* CREATE DB */ OPEN FILE(DB) RECORD KEYED SEQUENTIAL OUTPUT TITLE('MYFILE1'); HEADER = 'DATA RECORD HEADER'; STUFF = COPY('ABCDE',20); DO I = 1 TO 26; NUMBER = I; DBKEY = '@'||C(I) ||COPY('@',118); WRITE FILE(DB) FROM(DB_RECORD) KEYFROM(DBKEY); END; CLOSE FILE(DB); /* TRY A GENERIC READ THEN MOVE SEQUENTIALLY THRU THE FILE */ OPEN FILE(DBG) RECORD KEYED SEQUENTIAL INPUT TITLE('MYFILE1'); ON ENDFILE(DBG) GOTO EXIT_1; READ FILE(DBG) KEY('@') INTO(DB_RECORD); LETTERS = SUBSTR(DBKEY,2,1); DO WHILE(TRUE); READ FILE(DBG) INTO(DB_RECORD); LETTERS = TRIM(LETTERS) ||SUBSTR(DBKEY,2,1); END;
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (60 of 166) [16-03-2013 17:31:33]
EXIT_1: CLOSE FILE(DBG); PUT EDIT(LETTERS)(A); IF LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' THEN PUT SKIP LIST('TEST PASSES'); ELSE PUT SKIP LIST('TEST FAILS'); PUT SKIP; END TEST;
Parent topic: Record I/O Related information Open PL/I User's Guide Data Type Conversions
declare FirstByte char(1) defined(Buffer); declare Key char(4) varying; declare Eof bit; put skip list('Creating REGIONAL(1) file with records 1, 5 and 9.'); open file(File1) output; Buffer = copy('1',size(Buffer)); write file (File1) from(Buffer) keyfrom (1); Buffer = copy('5',size(Buffer)); write file (File1) from(Buffer) keyfrom (5); Buffer = copy('9',size(Buffer)); write file (File1) from(Buffer) keyfrom (9); close file(File1); open file(File1) update; on endfile(File1) Eof = '1'b1; Eof '0'b1; /* Initialize */ put skip list('Reading file and updating the even numbered records.'); read file(File1) into(Buffer) keyto(Key); do while (^Eof); if unspec(FirstByte) = 'FF'b4 then do; /* dummy record */ if (mod(fixed(Key,15),2) = 0) then do; /* change even number ones * Buffer = 'rewritten'; rewrite file(File1) from (Buffer); /* rewrite current record */ end; end; read file(File1) into (Buffer) keyto(Key); end; Eof = '0'b1; /* Reset */ put skip(2) list ('Reading and displaying all records in file.'); Key = '1'; read file(File1) into(Buffer) key(Key); /* direct read */ do while (^Eof); if unspec(FirstByte) = 'FF'b4 then put skip list(Key,'<dummy record>'); else put skip list(Key,Buffer); read file(File1) into(Buffer) keyto(Key); /* sequential read */ end; close file(File1); put skip; end sample; You can compile, link, execute, and display the output of the above sample program with the following commands: mfplx sample.pl1 -defext -o sample.out sample.out The output is as follows: Creating REGIONAL(1) file with records 1, 5 and 9. Reading file and updating the even numbered records. Reading and displaying all records in file. 1 11111111111111111111 2 rewritten
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (63 of 166) [16-03-2013 17:31:33]
3 4 5 6 7 8 9
Parent topic: REGIONAL(1) Record I/O Send feedback about this topic
The -SAM and -APPEND options can be used with stream files, in which case the length, if specified, is ignored. -SAM is never required for stream files. -SAM [n] specifies that the file is a consecutive file. If n is specified when the file is created, the file is created with records of fixed length n. The maximum value for n is 131,017 bytes. If n is not specified when the file is created, records written to the file can be of any length and of varying lengths. If -SAM is used when opening a file for OUTPUT, if the file already exists, it is deleted and a new file is created. -DAM [n] specifies that the file is a relative record I/O file. If n is specified when the file is created, the file is created with records of fixed length n. If n is not specified when the file is created, the file is created as a variable-length record file. If -NOSIZE is not also specified, this length n includes the two bytes that are added as a halfword of length information at the beginning of each record. -NOSIZE can be used alone or in combination with -DAM [n]. It specifies that the length halfword is not included at the beginning of each record. If -NOSIZE is used without -DAM [n], -DAM is implied. -APPEND [n] has the same meaning as -SAM, except that when used in opening a file for OUTPUT, it causes an already existing file to be appended to rather than replaced. -DELABORT causes the file to be deleted when it is closed.
If a file is opened for OUTPUT and none of these TITLE options is specified, and there is no ENVIRONMENT attribute in the file declaration, if the opening is for a DIRECT file, -DAM is assumed, and if the opening is not for a DIRECT file, -SAM is assumed. Parent topic: Record I/O Send feedback about this topic
2. Data Types
Introduction Arithmetic Data Picture Data Character-String Data Wide Character-String Data (UTF-16 Support) Bit-String Data Area Data Locator Data Label Data Entry Data File Data Arrays Structures Arrays of Structures Data Size and Alignment
Parent topic: Open PL/I Language Reference Manual Send feedback about this topic
2.1. Introduction
Each value has a data type that determines which operations can be performed on the value and the way in which the
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (65 of 166) [16-03-2013 17:31:33]
value is represented in storage. Data types are declared for variables, function results, named constants (such as files), and external procedures. They are also used with the ENTRY attribute to describe the data type of each parameter of a procedure. Data types are declared using the following attributes:
Computational Data
Non-Computational Data
FIXED BINARY FIXED DECIMAL FLOAT BINARY FLOAT DECIMAL PICTURE CHARACTER CHARACTER VARYING WIDECHAR WIDECHAR VARYING BIT
AREA
The attributes in the first column represent data items whose values can be manipulated by arithmetic or string operations and are therefore computational. The attributes in the second column refer to data used within a program for control structures and linkage and are therefore non-computational. The data type of a value produced by an expression is determined by the operands and the built-in functions within the expression. The data type of a constant is determined by the syntax of the constant. A variable capable of storing only one value, such as an integer or a character string, at any one time is called a scalar variable. An array variable is a collection of variables all of the same type. For example, an array might consist of 20 individual character strings. The variables contained in the array are called elements of the array. These elements all have the same name as the array. They are ordered by a numeric index, or perhaps several indices, and they are referenced by use of these indices. A structure variable is a collection of variables of arbitrarily mixed types. The variables contained in a structure are called members of the structure. The members each have their own name. A member may be referenced by its name alone, or its name may be qualified by the structure name to distinguish it from a member of another structure. A structure can contain subordinate structures as members, as well as array members and scalar members. Also, the elements of an array can be structures. This chapter discusses each data type, beginning with computational data types. Parent topic: Data Types Related information ENTRY Types of Operators Open PL/I Built-Ins
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (66 of 166) [16-03-2013 17:31:33]
FIXED BINARY(p) and FIXED DECIMAL(p,q) for fixed-point data FLOAT BINARY(p) and FLOAT DECIMAL(p) for floating-point data
where p is the precision and q is the number of fractional digits in the precision. Each implementation of PL/I imposes limits on the maximum values of p and q, and these limits typically differ for each combination of base and scale. Refer to your Open PL/I User's Guide for information on the default precision and maximum precision for each arithmetic data type in Open PL/I.
Fixed-Point Binary Literals Floating-Point Binary Literals Fixed-Point Data Floating-Point Data
The IBM compiler converts binary floating-point literals to short floating-point values if the precision is less than 21. However, Open PL/I ignores precision, and always converts the string to a floating-point decimal with the maximum permitted precision. Examples of floating-point binary literals are: 1000E201b, 1000.101E2B
5 4.5 4100.01 If a fixed-point constant contains a decimal point, it is considered to be a scaled fixed-point value and is stored and accessed like a fixed decimal variable. Fixed-point constants without a decimal point are integer constants and can be used safely in operations with any other arithmetic value, regardless of that value's base or scale. It is advisable to always write integer constants without a decimal point. The precision of a fixed-point constant is the number of digits in the constant. Parent topic: Arithmetic Data Related information Open PL/I User's Guide Data Type Conversions Open PL/I Built-Ins
result in an equal comparison to the constant 3111.14. If the constant is a long floating-point number, 38 of the 25 precision bits will be fractional and the comparison will still fail. One attempt to fix this might be to change the program as follows: SAMPLE: PROCEDURE OPTIONS (MAIN); DECLARE (F, G, H) FLOAT BINARY (23); RESULT FLOAT BINARY (23) STATIC INITIAL (3111.14) F = 3111; G = .14; H = F + G IF H ^= 3111.14 THEN PUT LIST ('UNEQUAL RESULT') END SAMPLE; This appears to truncate the sum to a "real" 23 bits of precision and to compare it to a constant of known precision. This will normally work. However, in the presence of optimization, the value of F + G may be used without reducing its precision through storing it in H and then reloading it. Thus, as a general rule, comparing floating-point numbers for equality and inequality does not work reliably. Instead, check for equality using the following method: ABS(FIRST-SECOND) < EPSILON where the constant EPSILON must be chosen considering the goal of the application. Floating-point numbers consist of a mantissa m, a base b, and an exponent e. A floating-point number is represented in the following format: m*b**e The mantissa m is a fraction containing at least p digits. The value of b and the possible range of e are defined by each implementation (for information on this implementation, refer to your Open PL/I User's Guide); however, if the base is binary, m contains the equivalent of at least p binary digits, and if the base is decimal, m contains the equivalent of at least p decimal digits. For example: DECLARE X FLOAT BINARY(23); DECLARE Y FLOAT DECIMAL(7); In this example, the values of X are floating-point numbers whose mantissa contains the equivalent of at least 23 binary digits. The values of Y are floating-point numbers whose mantissa contains the equivalent of at least 7 decimal digits. The representation of floating-point values in storage also depends on the implementation. An implementation may represent the mantissa in any base that it chooses, provided that it contains an equivalent of at least p binary or p decimal digits. On some computers, decimal floating-point values are represented by using a decimal mantissa, while other implementations use a binary or hexadecimal mantissa for all floating-point numbers. Open PL/I represents floating-point decimal using a decimal mantissa and decimal exponent, and represents floatingpoint binary using a binary mantissa and binary exponent. For more information, refer to your Open PL/I User's Guide. Because floating-point values may be represented in either base, and because excess digits may be lost during calculations, floating-point values may be approximate. However, any integer value that is converted to floating-point and converted back to integer retains its original value. Likewise, the floating-point calculations of addition, subtraction, and multiplication, when performed on integer values, produce integer values.
Floating-point constants are written as fixed-point constants followed by an exponent, as shown in the following examples: 5E+02 4.5E1 100E-04 .001E-04 0E0 Floating-point constants have a decimal precision of p, where p is the number of digits in the fixed-point constant. For example, 4.5E1 has a precision of 2. When fixed-point constants such as 1.5 are used in operations with floating-point values, they should be written with an exponent to avoid run-time conversion of fixed-point decimal values to floating-point. If floating-point values are converted to character strings or bit strings, the length of the resulting string is determined by p, not by the actual value. For a discussion of conversion rules, see the chapter Data Type Conversions. Caution is necessary when using floating-point constants in arithmetic expressions. Floating-point constants are considered to be of type Float Decimal, and the rules for the precision of arithmetic results specify that the precision of the result of a floating-point operation is the maximum of the precisions of the operands. Consider the following example: SAMPLE2: PROCEDURE OPTIONS(MAIN); DECLARE X FLOAT BIN(52); X = 1E0 + .4999E0; PUT SKIP LIST(X); END SAMPLE2; The answer printed by this program is, surprisingly, .500000000000000E+000. This is because the two constants are Float Decimal with precisions of 1 and 4, respectively. The addition is performed and the result is converted to Float Decimal(4); the intermediate result of 1.4999 is rounded to 4 decimal digits, and the result is converted to Float Binary and stored in X. An attempt to correct this might be to change the expression to read X = BINARY(1E0) + BINARY(.4999E0); This does the computation in Float Binary. However, this converts the first constant to Float Bin(4) and the second to Float Bin(14), and does the computation in short floating-point on most machines. The short floating-point result is lengthened to Float Bin(52) and is then stored in X, giving an answer of 1.499900013208389E+000. The correct fix is to use the two-argument form of the BINARY built-in function: X = BINARY(1E0,52) + BINARY(.4999E0,52); This produces long floating-point constants and the computation is done with maximal precision, printing 1.499900000000000E+000. Another solution would be to rewrite the constants using trailing zeros to indicate a more precise constant: X = 1.0000000000000000E0 + .4999000000000000E0; This also gives 1.499900000000000E+000, since the computation is done in large enough precision and the result is converted directly to a high-precision floating-point value. In general, when using floating-point constants in arithmetic expressions with floating-point variables, the precision of
the result can be controlled by using the FLOAT and BINARY built-in functions on the operands. The results of operations on two floating-point constants may not be what is expected. Exponentiation, MOD, and all transcendental functions (including SORT) operations on floating-point decimal data are actually performed using the floating-point binary operations. Thus, the range of the operands and the results of these operations are limited to the ranges for floating-point binary numbers. Parent topic: Arithmetic Data Related information Data Type Conversions Open PL/I User's Guide
If the value -1234.56 was assigned to each of the variables in these examples, the resulting picture values would be as follows:
Repetition factors can be used for sequences of identical picture characters. For example, the following declaration of J is equivalent to the one given above: DECLARE J PICTURE '(4)9V(4)9S';
Picture Specification Characters Rules for Using Numeric Picture Data Picture Repetition Factors
Character Description
X, A, 9
Character Description
Any character of the 256 possible bit combinations represented by the 8-bit byte.
Any alphabetic or extra-lingual (#, @, $) character, or blank. Any digit, or blank. Blanks are only allowed for character data.
A character picture specification describes a nonvarying character data item. You can specify that any position in the data item contain characters only from certain subsets of the available character set. Data consists of alphabetic characters, decimal digits, and blanks. The only valid characters in a character picture specification are X, A, and 9. When a character value is assigned or transferred to a picture character data item, the particular character in each position is validated according to the corresponding picture specification character. If the character data does not match the specification at a given position, the CONVERSION condition is raised for the invalid character. In the following example, valid values for PartNum include: 'BF123M' 'KL092/' 'BT013' declare PartNum picture'AA999X'; put skip edit(PartNum)(P'AA999X');
Category
Character
Description
Affects the numeric interpretation of the value only. The decimal point character is not actually stored. Mark the positions occupied by decimal digits and affect both the numeric interpretation and character representation of the value.
digit characters
9, Z, *, Y
T, I, R
Represent a digit that has the sign of the value encoded in the same position with the digit, thereby affecting both the numeric interpretation and character representation of the value. These characters can be used wherever the digit specifier '9' is valid. Indicates digits or symbols to be inserted in the internal representation of a character. (See the section Drifting Characters and Strings.) Inserted between digits to indicate that characters are inserted in the internal representation of the pictured value. Drifting characters also function as insertion characters when they are used singly. Always specified as two-character symbols. (See the section Credit and Debit Characters.)
drifting characters
$, +, , S
insertion characters
Decimal point (.), comma (,), slash (/), and space (B)
CR, DB
Note: A character picture specification cannot be mixed with numeric picture specification. However the character 9 can be used both as a character picture character and a numeric picture character. The following describes the numeric picture characters.
Character
Description
Indicates the position of the "assumed" decimal point. All digit positions to the right of the 'V' are fractional digits. Any value assigned to a pictured value is first scaled so that its decimal point is aligned with the 'V'. Only one 'V' character can appear in a picture. If a
picture does not contain the 'V' character, it is assumed to be at the right end of the picture, implying an integer value. B, ./ Indicate the positions at which a space (B), comma, decimal point, or slash, respectively, are inserted. These picture characters are inserted into the pictured value only if they are preceded by a nonzero digit or if they are preceded by a '9' or 'V' picture character. If they are not inserted, a zero suppression character (a blank) or an asterisk (*) is inserted instead. If an asterisk or drifting string occupies the position preceding the insertion character and that position corresponds to a leading zero, the asterisk or drifting string character also suppresses the insertion character. The 'V' and
decimal point (.) must be adjacent to one another to ensure that the decimal point is in the same position in both the numeric and character interpretations. The period should follow the 'V' to ensure that it will be in the correct location and will appear whenever any fractional digit is significant. Z Indicates a decimal digit with leading zero suppression. The 'Z' causes zero suppression using a blank as the suppression character. A 'Z' must not be preceded by a '9' or a drifting string. A picture containing a 'Z' must also not contain an asterisk (*). If 'Z' picture characters appear to the left of 'V', all leading zeros in positions corresponding to those 'Z' characters are suppressed. Nonzero digits and significant zeros are never
suppressed. Suppressed zeros are represented by spaces. If a 'Z' appears to the right of 'V', all digits in the value must be indicated by 'Z' characters. Fractional zeros are then suppressed only if all fractional digits are zero and all integer digits are suppressed. In this case, the internal representation contains only spaces in the digit positions. Note: Refer to the examples in the section Rules for Using Picture Data. * Indicates a decimal digit with leading zero suppression. The '*' causes zero suppression using an asterisk as the suppression character. An '*' must not be preceded by a '9' or a drifting string. A picture containing an '*' must also not
contain a 'Z'. The rules for '*' are otherwise the same as those for 'Z'. S Indicates the position of the plus sign (+) or minus sign (-), which may or may not be drifting. The 'S' causes the plus sign to be inserted if the numeric value is greater than or equal to zero, and causes the minus sign to be inserted if the value is less than zero. If an 'S' occurs more than once in a picture, the entire field of 'S's is a drifting string and can only contain a 'V' and one or more 'B' , '.' or '/' picture characters. Such a field cannot be preceded by a '9', 'Z', or '*', and if it contains a 'V' followed by one or more 'S's, it cannot be followed by a '9'. The total number of digits represented by a drifting string is one less than the number of 'S's in the field. The
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (79 of 166) [16-03-2013 17:31:33]
digits are zero suppressed and a sign of '+' or '-' is inserted immediately preceding the most significant digit of the value. A single 'S' causes a sign of '+' or '-' to be inserted into the pictured value, at the location implied by the position of 'S' in the picture. + Indicates the position of the plus sign (+) to be inserted if the numeric value is greater than or equal to zero. Operates exactly like 'S', except that the sign of negative values is indicated by a blank. Indicates the position of the minus sign () to be inserted if the numeric value is less than zero. Operates exactly like 'S', except that the sign of positive values is indicated by a blank.
Indicates the position of the dollar sign ($) to be inserted. Operates like 'S', except that a '$' is inserted instead of either sign. Indicates a decimal digit, including leading zeros. The position occupied by '9' always contains a decimal digit, regardless of whether the digit is, or is not, significant in the numeric interpretation of the pictured value. Indicates the position of a decimal digit in which the zero digit is always suppressed by a blank, regardless of the position of 'Y' relative to other picture characters.
CR
Indicates the position at which 'CR' is inserted if the number is less than zero. These two characters must appear as a pair on the rightmost end of the picture. They are replaced by two blanks in internal representation if the value is not negative. Indicates the position at which 'DB' is inserted if the number is less than zero. Like 'CR,' these two characters must appear as a pair, may only appear on the rightmost end of the picture, and are replaced by two blanks in internal representation if the value is not negative. Indicates the position of a decimal digit with an encoded plus or minus sign. The digit contains an encoded plus sign if the numeric value is greater than or equal to zero and an encoded minus sign if the value is less than zero. (See table
DB
below for representations of encoded sign digits.) I Indicates the position of a decimal digit with an encoded plus sign if the numeric value is greater than or equal to zero. If the value is less than zero, the position contains an ordinary digit. Indicates the position of a decimal digit with, possibly, an encoded minus sign if the numeric value is less than zero. If the value is greater than or equal to zero, the position contains an ordinary digit.
ASCII Character ASCII Character
Digit
Digit
0 1 2 3 4 5 6 7 8
} J K L M N O P Q
+0 +1 +2 +3 +4 +5 +6 +7 +8
{ A B C D E F G H
+9
Parent topic: Picture Data Related information Drifting Characters and Strings Credit and Debit Characters Rules for Using Picture Data
4. If a 'V' is not given, a 'V' is implied at the rightmost end of the numeric picture. 5. Each '9', 'Z', or '*' is considered to be a digit of precision. Within a drifting string each 'S', '+', '', or '$', except the first one, is considered to be a digit of precision. All digits of precision following the 'V' are fractional digits. For example: DECLARE A PICTURE 'ZZZV.ZZ' DECLARE B PICTURE '---V.z--' In this example, A has a precision of (5,2), while B has a precision of (4,2). 6. Negative values cannot be assigned to a numeric pictured variable unless the picture contains a 'CR', 'DB', '', or 'S'. An error condition is signaled if a negative value is assigned to a numeric pictured variable that does not contain 'S', '+', '', 'T', 'I', 'R', 'CR', or 'DB'. 7. Values assigned to numeric pictured variables are truncated and aligned with the `V' as they would be when assigned to a fixed decimal variable of the equivalent precision.
8. Used in contexts that expect an arithmetic value, or used with a relational operator, numeric pictured values are converted to fixed-point decimal values with a precision p and q that are determined by the numeric picture. 9. A numeric pictured value is operated upon as if it were a character-string value only when it is assigned to a character-string variable, and when it is an operand of the concatenate operator or of a built-in function that expects character-string operands. In all other contexts, numeric pictured values are operated upon as if they were fixed-point decimal values. Following are more examples of picture format output.
Example
Data
Picture
Output
1 2 3 4 5 6 7 8 9 10 11 12
12345.60 1.23 1.23 1234.56 11011111 011335 1234567890 .33 .75 1234567.89 -1234567.89 1023
$SSSSSSSSV.99 **********V.99 ZZZZZZZZZZV.99S Z.ZZZ ZZZV,99 9999B9999 **/**/** 999999999V.99 ZV.ZZ ZV.ZZ $999,999,999V.99DB $999,999,999V.99CR YYYYY
+12345.60
.********1.23 1.23 1.234,56 1101 *1/13/35 234567890.00 .33 .75 $001,234,567.89 $001,234,567.89CR 1 23 1111
In example 1, '$' is a static character because it appears only once, whereas 'S' is a drifting character because it appears all the way to the decimal. In examples 2, 3, and 4, the characters 'Z' and '*' are zero-suppression characters. The asterisk prints wherever a zero or blank would have printed, and the 'Z' substitutes blanks. In example 5 the insertion character 'B' results in a space (blank). A blank is inserted wherever the 'B' appears in the numeric picture format unless it is in a field of zero-suppression characters that are suppressing zeros at the time. In example 7, the appearance of the character '9' results in the printing of a digit. All digits 0 through 9 are printed, except the leading one, which is truncated. In examples 8 and 9, the character 'V', once encountered, turns off suppression; all characters after the 'V' are printed. Note that in Example 8, 'V' is not used before the decimal point, so the point is turned off, not on. Examples 10 and 11 show the result of positive and negative data applied to numeric pictures that contain either 'CR' or 'DB'.
If the drifting string contains an insertion character, the insertion character is inserted in the internal representation only if a significant digit appears to its left. In the position of the insertion character, a space appears if the leftmost significant digit is more than one position to the right; the drifting symbol appears if the next position to the right contains the leftmost significant digit. If the drifting string contains a 'V' character, all digit positions to the right of the 'V' (the fractional digits) must also be part of the drifting string. Insignificant fractional digits are suppressed only if all integral and fractional digits are zeros; if so, they are replaced by spaces in the internal representation. If any digit is not zero, all fractional digits appear as actual digits. Insertion characters that appear to the immediate right of a drifting string are considered part of the drifting string.
Note: Refer to the examples in the section Rules for Using Numeric Picture Data.
A character-string variable or character-string valued function is declared with the following attributes: CHARACTER(n) or CHARACTER(n) VARYING where n is an integer valued expression that specifies the maximum length of all string values that can be held by the variable or returned by the function. The VARYING attribute causes the string variable or function to hold or return values of varying lengths. Internally, the length of the varying string is recorded along with the value. Varying strings are not padded to assume their maximum length, n. The representation of a varying string variable in storage is such that any string up to n characters may be held by the variable, and the length of the current string is retained as part of the value. Without the VARYING attribute, a string variable or function always holds or returns values of length n. An assignment to a nonvarying string always extends short values with blanks on the right to make them n characters long. Assignments of a string of more than n characters to either a VARYING or a nonvarying string variable cause only the leftmost n characters to be assigned and excess characters to be truncated. Character-string values are compared from left to right using the collating sequence of the computer. Strings of unequal length are compared by effectively extending the shorter string with blanks on the right. Nonvarying character-string variables always occupy exactly n bytes of storage. As elements of arrays or members of a structure, they begin on the next available byte and are not aligned on word or other storage address boundaries. This permits an array of nonvarying characters to be stored and accessed as if it were a single string. See the section Storage Sharing in the chapter Storage Classes. Varying character-string variables always occupy n+2 bytes of storage. The first 2 bytes contain an integer L (0 <= L <= n) that specifies the length of the string value currently stored in the variable. The string text occupies the first L bytes of the storage following the 2 length bytes. The value of the last nL bytes of the variable is undefined. The value L can be accessed using the LENGTH built-in function. An array of varying character strings cannot be accessed as if it were a single character string. See the Open PL/I User's Guide for specific alignment of varying character strings. A character-string constant is written in the following format: 'Any characters except quote' If an apostrophe is required within the constant, it must be written as an adjacent pair of apostrophes. Examples: 'ABC' 'He said, "I don"t know."' '' In these examples, the second string displays a pair of single quotation marks used within the text string "don't". This text string also shows that the double quotation mark is insignificant as a delimiter of a character-string constant. The string in the last example is a null string.
Parent topic: Data Types Related information Storage Sharing Open PL/I User's Guide
WIDECHAR(n) VARYING where n is an integer valued expression that specifies the maximum length of all wide string values that can be held by the variable or returned by the function. WCHAR can be used as a synonym for WIDECHAR. The VARYING attribute causes the string variable or function to hold or return values of varying lengths. Internally, the length of the varying string is recorded along with the value. Varying strings are not padded to assume their maximum length, n. The representation of a varying string variable in storage is such that any string up to n wide characters may be held by the variable, and the length of the current string is retained as part of the value. The length field is always stored according the native architecture of the machine for fixed binary (15) data items. Without the VARYING attribute, a wide string variable or function always holds or returns values of length n. An assignment to a non-varying string always extends short values with blanks (0x0020) on the right to make them n wide characters long. Assignments of a string of more than n wide characters to either a VARYING or a non-varying string variable cause only the leftmost n wide characters to be assigned and excess characters to be truncated. Character-string values are compared from left to right using the binary values of the byte-pairs. Strings of unequal length are compared by effectively extending the shorter string with blanks (0x0020) on the right. Non-varying character-string variables always occupy exactly n*2 bytes of storage. As elements of arrays or members of a structure, they begin on the next available byte and are not aligned on word or other storage address boundaries. This permits an array of non-varying characters to be stored and accessed as if it were a single wide string. Varying wide character-string variables always occupy (n*2)+2 bytes of storage. The first 2 bytes contain an integer L (0 <= L <= n) that specifies the length of the wide string value currently stored in the variable. The string text occupies the first L*2 bytes of the storage following the 2-byte length field. The value of the last n-L byte-pairs of the variable is undefined. The value L can be accessed using the LENGTH built-in function. An array of varying wide character strings cannot be accessed as if it were a single wide character string. See the Open PL/I User's Guide for specific alignment of varying character strings.
Restrictions
All WIDECHAR byte-pairs are stored in Big Endian format. All WIDECHAR VARYING length-fields are stored in the native machine architecture for integer values. WIDECHAR characters in source files is not supported. W string constants is not supported. WIDECHAR expressions in stream I/O is not supported. Implicit conversions to/from WIDECHAR in record I/O are not supported. Implicit endian-ness flags in record I/O are not supported. Only Big Endian byte-pairs within WIDECHAR files is supported. WIDECHAR(x) VARYINGZ is not supported. Surrogate pairs are not supported.
In this example the A and D strings are aligned because they inherit the ALIGNED attribute from the structure declaration. A bit string occupies a full byte. If the structure S had been declared with the UNALIGNED attribute, the A and D strings would be unaligned. Bit-string values are compared from left to right, a bit at a time until an inequality is found. The shorter operand is effectively extended by zero bits on the right to make it the length of the other operand for purposes of comparison. A bit-string is not a word of storage in a computer and is not an arithmetic value. It is a sequence of bits that is always operated upon from left to right, just as a character string is operated upon from left to right. A bit-string constant is written as a quoted string of zeros and ones followed by a B. A bit string of length one is a boolean value with the possible values of '0'B and '1'B, which denote false and true, respectively. Note: No assumptions should be made about the form in which a bit-string is stored. Examples: '1'B '10110'B 'O'B ''B The last string in the previous set of examples is a null bit string. Bit-string constants may also be written using a string of characters to represent the bit string: 'character string'Bn where n is 1, 2, 3, or 4 and is the number of bits each character represents. The table below gives the set of permissible characters and shows the corresponding bit-string values. In this table, a '' indicates 'invalid.'
Character
B or B1
B2
B3
B4
0 1 2 3 4 5 6
0 1
00 01 10 11
7 8 9 A B C D E F
For example:
111 _
BitString
Equivalent Value
'073'B3 'A04'134
'000111011'B '101000000100'B
1 S BASED, 2 X FIXED BIN(15), 2 AREA3(1024 REFER(X)); An alternate way to declare an AREA is implicitly, through its use in the following contexts:
The IN option of an ALLOCATE statement. For example: ALLOCATE X IN(A1); The OFFSET attribute of an offset variable declaration. For example: DECLARE 0 OFFSET(A1);
Area variables are always aligned on 8-byte boundaries. The UNALIGNED attribute is not applicable to AREA variables. Only based variables can be allocated in an area. Use of an area allows related items to be allocated and freed only in that region of storage reserved for the area. The area can be assigned or transmitted as a unit, complete with all the allocations it contains. To preserve the desired alignment constraints in the area, the size of any allocation within the area is always rounded to an 8-byte boundary. The amount of reserved storage that is actually in use is known as the "extent" of the area. When first allocated (prior to any allocation in it), the extent of the area is zero. The maximum extent is represented by the "area size." When a based variable is allocated or freed, the extent of the area is updated to reflect the change in the amount of storage in use. In addition, when a based variable is freed, the storage it occupied is added to a chain of available storage blocks within the area. The area extent and the free chain are maintained in an 8-byte control block, adjacent to the space reserved for the area. Areas may be assigned and passed as arguments. However, areas cannot be compared or otherwise have any operators applied to them. When an area variable is assigned to another, all allocations in the target area are freed and the extent of the target area is set equal to that of the source area. The AREA condition is raised for an illegal area assignment detected at run-time. This situation occurs if the maximum size of the source area exceeds that of the target area. The AREA condition is also raised when an attempt is made to allocate a based variable within an area that has too little free storage to accommodate it. For more information about the AREA condition, see the "Area" section in the section ON in the chapter Statements. Offset variables are used to indicate the locations of based variables within the area. See the discussion in the section Offset Data. Parent topic: Data Types Related information ON Offset Data
CHAIN_HEAD = NULL(); The internal representation of NULL is determined by the -setnull compiler option. For more information on compiler options, see your Open PL/I User's Guide. Pointer values may be assigned, compared for equality or inequality, passed as arguments, and returned from functions, but no calculations or conversions can be performed on them. They cannot be transmitted in stream I/O. If the variable whose storage is addressed by a pointer value is freed, the pointer value should no longer be used. Use of such a pointer to access the storage causes unpredictable results. The ADDR built-in function must not be used to calculate the address of an unaligned bit data. Consequently, when such a restriction is imposed, pointer values never address unaligned bit-string data. However, all other data can always be addressed by a pointer, regardless of the addressing capabilities of the computer. Note: The based variable that is used as a template normally must have the same data type as the variable addressed by the pointer. Violations of this rule cause unpredictable results. Programs that violate this rule and produce "correct" results may fail when compiled with optimization enabled or may fail when moved to another implementation of PL/ I. A pointer value cannot be represented by a constant. However, the NULL built-in function can be used in any context, including an INITIAL attribute, where a constant might be desired. Parent topic: Locator Data Related information Open PL/I User's Guide Based Variables Storage Sharing
ALLOCATE X IN(A) SET(O); X = 5; /* Implies area and offset */ This association can be done in the declaration by specifying the area variable, as shown in the previous example. This type of declaration has the convenience of implicitly referring to the associated area whenever a reference is made to the offset variable used as a locator. When an offset value is assigned to or compared with another offset variable, only its actual value is used the implicit area reference is ignored. However, when used as a locator, or when compared to or assigned to a pointer, the offset value is implicitly converted to a pointer by generating an address derived from the offset value combined with the address of the area with which it is associated. If this association was not done in the declaration, it can still be done using the POINTER built-in function: P = POINTER(Z, A); /* offset Z was not associated with area A in its declaration */
Note that, if the offset variable did not have an area association in its declaration, then it is only with the POINTER builtin function that the offset variable can be used as a locator to address a variable within an area. For more information, see the description of the POINTER built-in function in the section POINTER in the chapter Open PL/I Built-Ins. An OFFSET variable may be assigned a value in the following ways:
With the ALLOCATE statement For example: DECLARE X Al 01 ALLOCATE X; FIXED BIN(31 BASED(01), AREA, OFFSET(A1); /*sets 01 = to the offset of X in area A1 */
Since the locator for X and the associated area of 01 are both specified in their respective declarations, the previous ALLOCATE statement is equivalent to: ALLOCATE X IN(A1) SET(01); By assignment of another locator (offset or pointer) value By assignment of the NULL() built-in function By assignment of the OFFSET built-in function, which complements the POINTER built-in function (see the section POINTER in the chapter Open PL/I Built-Ins).
In this example, execution of the first GOTO statement simply transfers control to L1 because it occurs within the same block activation in which L1 was assigned to L (and consequently, the stack frame component of L designates the stack frame that is current when the GOTO statement is executed). However, execution of the second GOTO statement occurs within a block activation other than that whose designator was assigned to L. Execution of the second GOTO statement first uses the stack frame designator of L to terminate the block activation of B and restore the block activation of A. The second GOTO statement then transfers control to the statement labeled L1. If A were a recursive procedure with more than one activation, the statement GOTO L in B would restore the most recent activation of A. Note that a label variable that is given L as a value will denote the activation of A current at the moment L is assigned, which may not be A's most recent activation. Use of a label variable after its associated block has exited may cause unpredictable results. A single, optionally signed integer constant in the range -32768 to +32767 may be used to subscript a label. An array of labels is declared by the occurrence of subscripted labels. The elements of the array are all the subscripted labels having the same name and appearing within the same block. The highest subscript used is the upper bound of the array. The lowest subscript used is the lower bound of the array. The number of integers between the lower bound and the upper bound, inclusive, is the extent of the array. The array contains one element of each integer in the extent, although there may not be a subscripted label corresponding to the element. If you refer to an undefined element, the result is unpredictable. For example: GOTO CASE(K); CASE(1): . . . CASE(2): . . . CASE(3): . . . CASE(6): . . . In this example, CASE is a one-dimensional array of statement labels containing six elements. Elements 4 and 5 are undefined and should not be used. Using an undefined element produces unpredictable results. Label prefixes on PROCEDURE, FORMAT, BEGIN, and ENTRY statements cannot be subscripted. Because the label array is declared by label prefixes, it cannot also be declared as a LABEL variable by appearing in a DECLARE statement. Label values may be assigned, compared for equality or inequality, passed as arguments, and returned from functions, but no calculations or conversions can be performed on them. You may specify potential label values that can be assigned to a LABEL variable. They cannot be transmitted in stream I/O. Parent topic: Data Types Send feedback about this topic
A: PROCEDURE; . . . DECLARE E ENTRY VARIABLE; . . . E = A; In this example, E is an entry variable that is capable of being assigned any entry value. The assignment causes the value of E to become a descriptor of the procedure named A. Any parameter attribute or RETURNS attribute specified as part of an ENTRY attribute has no effect on the values that can be assigned to the ENTRY variable. However, when the entry variable is called, the value that it currently holds must designate a PROCEDURE statement whose parameters and RETURNS option match those given in the declaration of the entry variable. In the previous example, a program that calls E as a function or calls E with arguments is invalid and produces unpredictable results. Parent topic: Entry Data Send feedback about this topic
outer procedure's stack frame is the stack frame designator. Except when the outer procedure has been activated recursively, only one stack frame for the outer procedure exists. The existing stack frame is the one that is always used when the inner procedure references variables declared in the outer procedure. If the outer procedure has been activated recursively, the entry value used to call the inner procedure determines which stack frame is to be used when the inner procedure references the outer procedure's variables. For example: A: PROCEDURE RECURSIVE; DECLARE X FIXED BINARY(15); DECLARE E ENTRY VARIABLE STATIC; IF FIRST-TIME THEN E=B; ELSE CALL F; CALL G; . . . B: PROCEDURE; . . . X=5; In this example, assume that A calls G and that G calls A, then A calls F, and F calls the entry value held by E. When E is called, an activation of B results, because B was assigned to E. When that activation of B references X, two stack frames containing an instance of X exist. Two stack frames exist because two calls of A are still active. However, because the first of these two activations of A assigned B to E, E contains a designator to the first stack frame of A. Consequently, B assigns 5 to the first instance of X. If B were called directly from A, B would always use the most recent stack frame of A when referencing X. An older stack frame is used only when an entry name is assigned to an entry variable or passed as an argument to an entry parameter. When the entry name is thus passed or assigned, the current stack frame of its containing block is assigned as the second component of the entry value produced by that assignment. If the procedure name being assigned or passed as an argument is not declared within the block that is assigning or passing it, but is declared in a containing block, the containing block's stack frame is found using the same principle as was used to find X in the previous example. Once found, a designator to that stack frame is assigned as part two of the entry value. Each stack frame for a block A has a designator to a stack frame of the block that contains A. That designator is the designator that was supplied as the second part of the entry value used to activate A. Unless the activation of A was the result of calling an entry variable or entry parameter, and unless recursion has been used, the stack frame thus designated is also the immediately preceding stack frame. Parent topic: Entry Values Send feedback about this topic
operating system. For example: DECLARE F FILE; In this example, F is a file constant that designates a file control block. That file control block can be opened, closed, and used to perform I/O on files and devices known to the operating system. A file variable is represented internally as a longword containing a pointer to a file control block. When evaluated, the value of the file variable is the address of the associated file's control block. A file variable is capable of being assigned any file value; it is declared using both the FILE and VARIABLE attributes. For example: DECLARE G FILE VARIABLE; DECLARE F FILE; . . . G = F; In the previous example, G is a file variable assigned the value of the file constant F. After the assignment, operations on G are equivalent to operations on F because they both designate the file control block belonging to F. File values may be assigned, compared for equality or inequality, passed as arguments, or returned from functions; however, no calculations or conversions can be performed on them, and they cannot be transmitted by stream l/o. Parent topic: Data Types Related information File Constants
2.12. Arrays
An array is an ordered set of values all having the same data type. Elements of an array are referenced by their position within the array. Each array has a specified number of dimensions and each dimension has a specified lower and upper bound. The default low bound of a dimension is 1. Array elements are stored in row-major order. The successive elements of a row are stored in adjacent memory locations. In arrays with more than two dimensions, the net effect is that when the elements are accessed in their storage order, the rightmost subscript varies most rapidly. Examples: DECLARE DECLARE DECLARE DECLARE A(1:4) FIXED BINARY(15); B(0:3,0:5) FLOAT BINARY(21); C(-2:10) CHARACTER(5); D(25,4,2) POINTER;
In these examples, A is a one-dimensional array capable of holding fixed-point binary values. The lower bound is 1, the upper bound is 4, and the number of elements is 4.
B is a two-dimensional array capable of holding floating-point binary values. Both lower bounds are zero, and the upper bounds are 3 and 5. Therefore, B has 4 rows of 6 columns each. C is a one-dimensional array capable of holding character-string values each of which has 5 characters. Its lower bound is -2 and its upper bound is 10, giving it a total of 13 elements. D is a three-dimensional array capable of holding pointer values. Because no lower bounds are given, they are assumed to be 1. The array has a total of 200 elements organized as 25 planes, each of which is 4 rows in length and 2 columns in width. The maximum number of array dimensions is 8. An array bound may be any number in the range -2^31 to 2^31 -1. Array bounds are also subject to the following restrictions:
The lower bound must be less than or equal to the upper bound. The value (upper bound lower bound) must be less than 2^31 -1. The total size of the array must be less than 2^31 bytes. For information on calculating the size of an individual array element, see your Open PL/I User's Guide.
Note: The particular implementation of PL/I or the underlying operating system may also impose restrictions on the size of an individual data item, or on the total sizes of static and/or automatic data regions. For more information, see your Open PL/I User's Guide. The bounds of AUTOMATIC, DEFINED, CONTROLLED, or BASED arrays may be specified by integer-valued expressions, as explained in the chapter Storage Classes. The bounds of STATIC arrays must be integer constants. The bounds of parameter arrays can be either integer constants or an asterisk (*). If an asterisk is given as the bound of a parameter array, it represents both the lower and upper bound and means that the actual bounds of the corresponding array argument are to be used as the bounds of the array parameter. For example: DECLARE A(0:5) FIXED BINARY; CALL P(A); . . . P: PROCEDURE(X); DECLARE X(*) FIXED BINARY; . . . During the call of P in the previous example, the bounds of X are (0:5), and any reference to X is a reference to A. The elements of an array are referenced using as many subscripts as the array has dimensions. For example: DECLARE A(-2:5,4,3) FIXED BINARY; In this example, a reference to A (-2 ,1,1) is a reference to the element in the first column of the first row in the first plane. A reference to A (3,2,1) is a reference to the element in the first column of the second row in the sixth plane. A subscript of an array must be an integer valued expression. The use of fixed-point fractions or floating-point values as subscripts results in an error message from the Compiler. However, such values can be converted to integer values by use of the TRUNC, CEIL, FLOOR, or ROUND built-in functions.
Each subscript must lie within the range specified by its corresponding lower and upper bound. Unless subscript range checking has been requested, the Compiler does not produce code to check the range of subscript values. If checking is requested, any subscript that exceeds its range results in a signal of the ERROR condition. Subscripted references to array elements can be used in any context that permits a variable reference. A cross-section of an array may be referenced by using an asterisk as a subscript. The asterisk refers to the entire range of the corresponding dimension (lower bound through upper bound). In the previous example, a reference to A (*,1,1), refers to the first-row, first-column elements in all eight planes. A reference to A ( *, *,*), refers to all 96 elements of the array. Array cross-sections may be transmitted in stream or record I/O, passed as arguments, and assigned to other arrays of the same size and shape. Parent topic: Data Types Related information Storage Classes
2.13. Structures
A structure is a hierarchically ordered set of values that may be of different data types. The immediate components of a structure are called members of the structure. A structure that is itself a member of another structure is called a substructure. A structure that is not a substructure is called a major structure. The hierarchical organization of a structure is specified by using level-numbers, as shown in the following example: DECLARE 2 2 2 1 S, A FIXED B FLOAT T, 3 P 3 Q
In this example, S is a major structure, also called a level-one structure. All major structures must have a level-number of 1. The members of S are A, B, and T. T is a substructure with members P and Q. Members normally have a level-number that is 1 greater than their containing structure; however, they may be given any level-number that is greater than the level-number of their containing structure and less than the level-numbers they contain. For example: DECLARE 1 S, 20 A FIXED 20 B FLOAT 20 T, 30 P 30 Q
The structure shown in this example is equivalent to the structure shown in the example immediately preceding it. An entire structure may be transmitted in stream or record I/O, passed as an argument, or assigned to another
structure of identical size and shape and having members of corresponding identical data types, but no conversions or calculations can be performed on entire structures. If a structure contains one or more members with a variable size, place all such members at the end of the structure following all the members with a fixed size. This placement improves the addressing of the fixed size members. Members of structures can be referenced in any context that permits a reference to a variable. If a member's name is not otherwise declared in the same scope (that is, in the same block or containing block), the member may be referenced by its name alone. The name of a member must be unique within its immediately containing structure, but may be used as the name of members of other structures or as the name of a nonmember. If a member's name has been used for more than one object, each reference to the member must be sufficiently qualified by the names of its containing structures to uniquely identify the intended member. In a qualified reference, the names used are listed in their hierarchical order, separated by periods. For example: DECLARE DECLARE A FIXED BINARY; 1 S, 2 A FLOAT BINARY, 2 T, 3 A POINTER;
In this example, a reference to A is a reference to the fixed-point variable. A reference to S.A is a reference to the floating-point variable. A reference to T.A or S.T.A is a reference to the pointer variable. Use of the major structure name as a qualifier is recommended. It is also advisable to avoid using the same member name more than once anywhere within the major structure or any contained structures. For more information, see the section Reference Resolution in the chapter References. A structure may have the UNION attribute applied to it, which causes all immediate members of that structure to occupy the same memory locations. For more information, see the chapter Declarations and Attributes. Parent topic: Data Types Related information Reference Resolution Declarations and Attributes
In this example, S is an array of 5 structures. Each structure contains a fixed- point member followed by an array of 4 floating-point values, followed by an array of 3 substructures. Each substructure contains a pointer variable followed by
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (106 of 166) [16-03-2013 17:31:34]
an array of 6 character-string variables. The entire structure contains 5 occurrences of A, 20 occurrences of B, 15 occurrences of T, 15 occurrences of P, and 90 occurrences of Q. Each member of a structure array is itself an array because there exist as many instances of the member as there are elements in the structure array. If a member is an array in its own right because it has its own dimension information (as do B, T, and Q in the previous example), the array inherits the additional dimensions from its containing structures. For instance, in the previous example, Q is a three-dimensional array whose bounds are (5,3,6). Any member of a dimensioned structure is an array and must be referenced using a subscript for each of its dimensions. The subscripts may be written anywhere within the structure-qualified reference, but it is preferable to write each subscript immediately following the name to which it applies. Using the previous example to illustrate this recommended programming practice:
is a reference to the Kth element of A is equivalent to B (K, J) is equivalent to S.T.Q (K, J, I) or S.T(K,J) .Q(I) or S(K,J, I) .T.Q,
It is not possible to use an asterisk to reference an entire extent (cross section) of a structure array. Members of dimensioned structures can be used only as arrays in stream I/O and as arguments to array parameters whose bounds have been specified as asterisks. They cannot be assigned, used in record I/O, used in ADDR or DEFINED, or passed to parameters with constant bounds. Subscripted references to members of dimensioned structures can be used in any context that permits a variable reference. Parent topic: Data Types Send feedback about this topic
Parent topic: Data Types Related information Open PL/I User's Guide
3. Storage Classes
Introduction Automatic Storage Static Storage Based Variables Controlled Variables Defined Variables Parameter Storage Class Storage Sharing
Parent topic: Open PL/I Language Reference Manual Send feedback about this topic
3.1. Introduction
Every variable has a storage class that determines how and when storage is allocated for it. A variable's storage class specifically determines whether storage will be allocated for it at compile time or dynamically during program execution. Storage classes are declared for all variables, except those used as parameters, using one of the following attributes:
If no storage class is specified for a variable declared in a procedure, other than a parameter variable, the default is AUTOMATIC. If a variable is declared outside the scope of all external procedures in a source module, the default storage class is STATIC. A parameter shares storage with its argument. As such, the storage class is ultimately determined by that of the associated argument. For convenience, a parameter may be considered to have a distinct "parameter" storage class. A variable's storage size is determined by its extents. A string variable's extent is its declared length. An array variable's extents are determined from the number of its dimensions and the range of its subscript bounds. The extents of both types of variables are evaluated when storage is allocated for the variable. The permitted forms for extents differ for each storage class and are described during the discussions of each storage class. Parent topic: Storage Classes Send feedback about this topic
variable to initialize the variable. Extents of automatic character string and array variables may be specified as integer valued expressions, provided these do not contain references to other non-static variables declared in the same block. Extent expressions for these automatic variables are evaluated each time the containing block is activated. The extent expression values are saved in the stack frame and effectively fix the size of the automatic variable for that block activation. Subsequent assignment to a variable used as an extent does not affect the size of the associated automatic variable. For example: DECLARE STRING_SIZE FIXED; . . . COPY: BEGIN; DECLARE TEXT CHARACTER(STRING_SIZE); When the BEGIN block in this example is activated, the extent of TEXT is evaluated. The variable is allocated storage depending on the value of STRING_SIZE, which must be a valid integer value. For example: DECLARE A(N) FIXED; . . . N = 10; /* WILL NOT AFFECT THE SIZE OF ARRAY A */ In this example, the size of A is determined upon entry to the containing block by evaluating N and storing its value in the stack frame. The assignment to N does not change the size of A. Upon entry to the block, N must have a correct value and must not be a non-static variable declared in this block. Use of the HBOUND built-in function within this block activation would return the original value of N that was saved in the stack frame. Parent topic: Storage Classes Related information INITIAL HBOUND Function
An external static variable is known in its containing block and in all contained blocks, except those blocks in which the same name is redeclared. However, all declarations of the same name that have the EXTERNAL attribute, including those in separate modules of the program, share the same storage and must specify identical attributes, including any initial values. External static variables are known and shared by all program modules in a manner similar to the common variables of FORTRAN, except that each external static variable is shared independently of others. Parent topic: Storage Classes Related information INTERNAL EXTERNAL
The indiscriminate use of pointers to access the storage of other variables should be discouraged because of the possibilities of unexpected assignment side effects and because the excessive use of pointers makes a program hard to read. Please also note that no checking is performed to ensure that the based variable provides a data description compatible with the declaration of the reference storage. For instance, the statement P>Y = 10 might produce undesirable results if Y were declared as a data type incompatible with the data type of elements in X. For a discussion of storage sharing using based variables, see the section Storage Sharing. The ALLOCATE statement uses a based variable to allocate a block of storage that can later be accessed by a based variable together with the locator returned by the ALLOCATE statement. For example: DECLARE P POINTER; DECLARE X(C,N) CHAR BASED(P); N = 10; C = 10; ALLOCATE X SET(P); . . . P -> X(10,5) = 'A'; In the preceding example, the ALLOCATE statement allocates a storage block of sufficient size to hold a twodimensional array of 100 one-byte character values and assigns a pointer to that block of storage to P . P>X thereafter is a reference to that block of storage as an array of 100 one-byte character values. Based variables can be subscripted just like any other variable. Referring again to the previous example, the statement P> X (10,5) = ' A' assigns the character 'A' to the element in row 10 and column 5 of the array qualified by P. Since the pointer variable may also be an array, it too can be subscripted. For example: DECLARE P(3) POINTER; DECLARE X(10) FLOAT BASED; . . . ALLOCATE X SET(P(K)); In the preceding example, P (K)>X refers to the entire array of ten floating-point elements qualified by the Kth pointer element of P. Likewise, P (K) >X (J) refers to the Jth element of the floating-point array qualified by the Kth element of pointer array P. The ALLOCATE statement is the only context in which a based variable can be used without an explicit or implicit locator qualifier. In this context, the based variable is used to describe how much storage is to be allocated. Implicit locator qualification is a shorthand notation that can be used in cases where many of the references to a based variable use the same pointer. For example: DECLARE X(10) FLOAT BASED(P); DECLARE P POINTER; . . . ALLOCATE X SET(P); Because X was declared to be based on P in the previous example, unqualified references to X such as X (K) , X (5), or X are implicitly qualified by P and are equivalent to P>X (K) , P>X (5) , and P>X. Any explicit qualification, such as Q>X, may be used to temporarily override the implicit qualification and is unaffected by the specification of P in
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (112 of 166) [16-03-2013 17:31:34]
BASED (P) . The extents of a based variable may be specified as integer valued expressions. The extents are evaluated for each allocation of the variable and for each reference of the variable. The extents are not captured when storage is allocated by an ALLOCATE statement. The extent expression can reference variables declared in the same block, as long as those variables have a value before the based variable is referenced. Changing the value of a variable referenced by an extent expression changes the extent of the based variable. For example: DECLARE X(N) CHARACTER(1) BASED; N = 10; ALLOCATE X SET(P); . . . N = M; P->X(5) = 'A'; In this example, the ALLOCATE statement allocates an array of ten elements. The value of M must be greater than or equal to five and less than or equal to ten; otherwise, the reference to P>x (5) is invalid and may cause unpredictable results. A block of storage previously allocated by an ALLOCATE statement can be freed by a FREE statement. For example: FREE P->X; Once freed, the storage can no longer be accessed, and any attempt to use a pointer such as P that points to the block produces unpredictable results. Note: The storage obtained by an ALLOCATE statement is freed only by an explicit FREE. If a program continually allocates memory without freeing it, the program may run out of space at run-time. Used with the ALLOCATE statement, based variables are powerful tools for applications in which the size of arrays or strings is not known at block entry and must be determined at run-time. Based variable allocations also supply a means for the dynamic creation of graph structure nodes (which may be linked by pointers to produce list and tree structures). See the example of a based structure in the section Block Activation and Recursion. It is desirable to restrict the extent of based variables to constant values whenever possible to avoid unexpected side effects and to improve program readability. If the extent must be variable, it is preferable to avoid the use of extent expressions when declaring based variables for the same reasons. The size of the based variable is evaluated for each reference to the variable. Parent topic: Storage Classes Related information POINTER Function Storage Sharing Block Activation and Recursion
PUT SKIP LIST ('Print first item on the stack'); PUT SKIP LIST (STACK); /* Pop the last element on the stack. The stack is empty now. */ FREE STACK; CONTROLLED variables can be declared with asterisk (*) extents, and when such a variable is allocated, its extents can be made explicit by the use of the ALLOCATE statement with specified attributes. CONTROLLED variables can also be declared with explicit extents (constant or variable), and these explicit extents can be overridden by use of the ALLOCATE statement with specified attributes. It is also possible to specify attributes with asterisk extents in the ALLOCATE statement. This causes the extents to be copied from the corresponding extents used for the previous allocation of the same CONTROLLED variable. If an asterisk is specified in the ALLOCATE statement for one dimension of a variable, it must be specified for all dimensions of that variable.
If level numbers are specified, the first variable in the ALLOCATE statement must be specified with a level-num of 1 and be declared as a level-1 structure, and in this case, all members of the structure must be included in the ALLOCATE statement just as they appear in the declaration of the structure. Any bound, length, size, or initial value specified in the ALLOCATE statement overrides the corresponding attribute specified in the declaration of the variable. A bound, length, or size can be specified in the ALLOCATE statement with an asterisk, and, in this case, the bound, length, or size is taken from the current generation of that CONTROLLED variable. If a bound, length, size, or initial value specified in the ALLOCATE statement contains a reference to the variable being allocated, the reference is to the current generation of the variable. Evaluations of expressions for bounds, lengths, sizes, and initial values during the execution of the ALLOCATE statement are done according to the normal rules for PL/I references, and must be capable of logical execution (that is, without circularity). Evaluations depending on the existence of a prior generation of a variable require that that generation has previously been allocated. Controlled variables provide an easy way to implement a stack, because only the most recent generation is available to the program. The ALLOCATE statement is equivalent to a push operation and the FREE statement is equivalent to a pop operation. The ALLOCATION built-in function is used to determine the number of generations of a controlled variable that are available. Examples DECLARE 1 A CONTROLLED, 2 B CHAR(*), 2 C CHAR(20), 2 D(2) FIXED BIN(31), 2 E(4,4) CHAR(*), 2 F FIXED BIN(31); ... ALLOCATE 1 A, 2 B CHAR(12), 2 C, 2 D(6), 2 E CHAR(3), 2 F INIT(128); ... ALLOCATE 1 A, 2 B CHAR(12), 2 C CHAR(10), 2 D(D(1)), 2 E CHAR(3), 2 F; In this example, the structure A is first allocated with member B of length 12, with array member D with dimension (6) instead of the declared (2), array member E with its declared dimensions of (4,4) and element lengths of 3, and member F with an initial value of 128. The second generation of A is allocated with member C of length only 10 and with the dimension of array member D the value contained in the first generation of A.D(1). DECLARE X(*,*) CONTROLLED; ALLOCATE X(3,7); ALLOCATE X(*,*); In the second allocation of array X, the bounds are implicitly (3,7), as derived from the previous allocation. For CONTROLLED parameters, CONTROLLED must be explicitly stated in the parameter descriptor for the ENTRY declaration. This is required by the PL/I language specification. For example, if you compile and link together the following two procedures: t.pl1 TSTENTM: PROC OPTIONS(MAIN); DCL DCL N CHAR(10) CONTROLLED;
TSTENT ENTRY(CHAR(10));
t1.pl1 TSTENT: PROC(N); DCL N CHAR(10) CONTROLLED; PUT SKIP LIST ('N = ',N); RETURN; END; Upon execution you will get: *** Condition ERROR raised *** Unhandled condition SIGSEGV at PC=004011AE N = To avoid this, add the controlled attribute to the ENTRY declaration: DCL TSTENT ENTRY(CHAR(10)CTL);
For additional information on defined variables, see the section Storage Sharing, which discusses the rules for giving alternate descriptions of storage. Parent topic: Storage Classes Related information Storage Sharing
The VALUE attribute is an argument-passing attribute that indicates that the value and not the address of the parameter has been passed to the procedure. An array parameter with constant extents can be passed only those array arguments that have identical constant extents and an identical data type. A parameter structure can be passed only a structure or substructure of identical size, shape, and component data types. Array or structure arguments cannot be passed by value. The ANY attribute is an argument-passing attribute that specifies, for a parameter, that the corresponding argument can be of any data type. A procedure that has a character or bit-string parameter with a constant length may be called with string arguments of variable length or differing constant length. Since all such arguments are passed by value, they are effectively converted to the length of the parameter. For example: CALL P(A,(B)); In this example, A is passed by reference if it matches its corresponding parameter and is passed by value if it does not. B is always passed by value. If the argument is an expression, function reference, built-in function reference, constant, parenthetical variable reference, or a reference to a variable whose data type does not match that of the parameter, the argument is copied to a temporary block of storage in the caller's stack frame and is said to be passed by value. The value of the variable in the caller will not be modified if it is passed by value. Actually, the address of the temporary is passed, and the parameter shares the storage allocated to the temporary. The extents of a parameter can be either integer constants or asterisks (*). If the parameter's extents are integer constants, any argument to be passed by reference must have identical constant extents. If the parameter's extents are asterisks, its corresponding argument may have extents of any value. In the latter case, the extents of the parameter are those of its corresponding argument. For example: DECLARE A(10) FLOAT; DECLARE B(25) FLOAT; . . . CALL P(A); . . . CALL P(B); . . . P: PROCEDURE(X); DECLARE X(*) FLOAT; During the first call in this example, the extents of X are (1:10). During the second call, they are (1:25). Parent topic: Storage Classes Related information Value ANY
Structures can share storage with other structures only if they are equivalent, left-to-right, to the structure whose storage is being shared. Left-to-right equivalence means that the sharing structures must be valid descriptions of the left part of the storage being shared. To be a valid description of the left part of storage, the sharing structures must have identical members up to and including all members contained anywhere within the last level-two item being shared. If any part of a leveltwo item is to be shared, all of it must be shared. For example: DECLARE 1 2 2 3 3 2 S, A, B, C, D; E; DECLARE 1 2 2 3 3 T BASED, A, B, C, D; DECLARE 1 2 2 3 U BASED, A, B, C;
In this example, a reference to T.B.C is a valid reference to S.B.C, but a reference to U.B.C is not valid, because the declaration of U does not describe the entire level-two item S.B. A picture variable can share storage only with other picture variables that have identical pictures. As is the case for argument/parameter matching, the ALIGNED, UNALIGNED, and VARYING attributes and the declared length of a string variable are part of its data type and must match, unless the strings qualify for string overlay sharing. The base, scale, and precision of arithmetic variables must always match if they are to share storage. Parent topic: Storage Classes Related information Union
Parent topic: Open PL/I Language Reference Manual Send feedback about this topic
4.1. Introduction
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (120 of 166) [16-03-2013 17:31:34]
All variables in an Open PL/I program (except those under the control of the DEFAULT statement) must be declared. Each name, except the name of a built-in function, must be declared using a DECLARE statement (or if it is a label, by using the label as a statement prefix). Each declaration is associated with a scope or region of the program in which a reference to the associated name is valid. The scope of a declaration includes the block in which it is declared and all nested blocks, except those in which the name has been redeclared. Identifier attributes used in DECLARE statements are specified by either keyword or syntax. A name declared with the EXTERNAL attribute has the same scope rule as any other name, except that the object identified by that name is unique throughout the entire program. All declarations of a given name that have the EXTERNAL attribute identify the same object. Only files, static variables, and names of external procedures can have the EXTERNAL attribute. Files and procedures acquire the attribute by default, but static variables have internal scope unless they are explicitly declared with the EXTERNAL attribute. A given name cannot be declared more than once within the same block, unless it is declared as the name of a structure member. In that case, the name may be redeclared within the same block, provided no two members at the same level of the same structure have the same name. (See the section Scope.) Parent topic: Declarations and Attributes Related information Scope
The label prefix of a PROCEDURE or FORMAT statement cannot be sub- scripted; however, label prefixes attached to statements other than PROCEDURE or FORMAT may be subscripted by a single optionally signed integer constant. Within its scope, all occurrences of a given name used in this manner must be subscripted, and all such prefixes collectively constitute a declaration of the name as an array of statement labels. For example: GOTO CASE(K); CASE(1): . . . CASE(2): . . . CASE(3): . . . CASE(6): . . . In this example, CASE is declared as an array of statement labels whose bounds are (1:6) and whose fourth and fifth elements are undefined. Defining arrays with undefined elements is not recommended, as it produces unpredictable results. An array of statement labels cannot be used as an array value, but its elements can be used in any context that permits a statement label. Procedure names, format names, and statement labels cannot be declared in a DECLARE statement in the same block, except that the names may be used as the structure member names. Names of external procedures that are part of another program module must be declared by a DECLARE statement if they are to be referenced by the current program module. (For more information, see the section Modules.) Only external procedure names can be declared by a DECLARE statement. Parent topic: Declarations and Attributes Related information FORMAT Modules
Parent topic: Declarations and Attributes Send feedback about this topic
statement. For example: DECLARE 1 S 2 2 2 STATIC, A(5) FLOAT DECIMAL(7), B FIXED BINARY(15), C, 3 D POINTER, 3 E CHARACTER(10) INITIAL('ABC');
In this example, S is a static structure with members A, B, and C. C is a substructure with members D and E. Initial attributes can be given to elementary members of static structures, but not to structures themselves. Parent topic: Recommended Forms Send feedback about this topic
DECLARE 1 S STATIC, 2 A FIXED INITIAL(0), 2 B FLOAT INITIAL(0); Factored declarations, other than as shown in the recommended form (see the section Factored Declarations) are generally more difficult to read than their unfactored equivalents. If defactoring produces more than one level number for a given name, even if the level numbers are equal, the factored declaration is invalid and causes the Compiler to issue an error message. Specification of duplicate attributes containing more than a simple keyword is also invalid, even when the attributes are exact duplicates. Parent topic: DECLARE Statements Related information Factored Declarations
4.3.3. Defaults
If the attributes specified for a name in a DECLARE statement are incomplete, the missing attributes can be supplied either by the Compiler or by the user with the DEFAULT statement.
Specified
Missing
Supplied
fixed | float fixed | float binary | decimal binary | decimal internal | external
STATIC is supplied if EXTERNAL is specified without a storage class and the declared name is not an entry or file constant. AUTOMATIC is supplied if the name is the name of a nonparameter variable that is not a member of a structure and no storage class was specified. The default precision is supplied if precision is not specified for arithmetic data. For information on the Open PL/I default precisions, see your Open PL/I User's Guide. VARIABLE is supplied if a storage class, array bounds, or member's level number is specified with FILE or ENTRY. EXTERNAL is supplied if FILE or ENTRY is specified and VARIABLE is neither specified nor supplied under the previous rule. In this case, the named object is a constant rather than a variable. UNALIGNED is supplied for bit-string data; ALIGNED for all other types of data.
If no data type is specified, either explicitly or by the DEFAULT statement, the declaration is invalid and incomplete. The Compiler issues an error message and supplies a type of Fixed Binary(15) for names beginning with any of the letters I through N, and Float Decimal(6) for names beginning with any other alphabetic character. A declaration is inconsistent and invalid if it specifies more than one data type or more than one storage class. These are the valid data types:
Fixed Binary(p) Fixed Decimal(p[,q]) Float Binary(p) Float Decimal(p) Picture Character(n) [Varying] Bit(n)[Aligned] Pointer Offset Area Label Entry [returns][variable] File [variable] Builtin Structure
A declaration is also inconsistent and invalid if it violates the following attribute-specific restrictions:
A name declared with the BUILTIN attribute cannot have any other attribute. A name declared with the FILE or ENTRY attribute, but without the VARIABLE attribute, is a named constant, not a variable, and its scope is external. (Recall, however, that the presence of a storage class, an array bound, or a member's level-number causes the VARIABLE attribute to be supplied by default to declarations containing the ENTRY and FILE attributes.)
ALIGNED BIGENDIAN BINARY BIT CHARACTER DECIMAL FIXED FLOAT NATIVE NONNATIVE PICTURE REAL UNALIGNED VARYING
Data type attributes, which apply to program data not used for computation.
r r r r r r r r r r r
AREA CONDITION DIMENSION ENTRY EXCLUSIVE FILE LABEL LIKE OFFSET POINTER TYPE
Storage class and scope attributes, which control the allocation and storage use for a data variable and define the variable's scope.
r r r r r r r r r r r r r r
AUTOMATIC BASED CONTROLLED CONNECTED DEFINED EXTERNAL GLOBALDEF GLOBALREF INITIAL INTERNAL POSITION REFER STATIC UNION
File description attributes, which can be applied to file constants or may be used in OPEN statements (except ENVIRONMENT, which can be used only in the DECLARE statement).
r r r r r r r r r
Entry name attributes, which can be applied to identifiers of entry points. These include:
r r r r r r r r r
ANY VALUE
Note: File description attributes specified in a DECLARE statement apply to all openings of the file control block associated with the file constant. For further discussion of these attributes, see the sections Input and Output in the
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (130 of 166) [16-03-2013 17:31:34]
ALIGNED ANY AREA AUTOMATIC BASED BIGENDIAN BINARY BIT BUILTIN CHARACTER CONDITION CONNECTED CONTROLLED DECIMAL DEFINED DIMENSION DIRECT ENTRY ENVIRONMENT EXCLUSIVE EXTERNAL FILE FIXED FLOAT
GLOBALDEF GLOBALREF INITIAL INPUT INTERNAL IRREDUCIBLE KEYED LABEL LIKE NATIVE NONNATIVE OFFSET OPTIONS(DESCRIPTOR) OPTIONS(NODESCRIPTOR) OPTIONS(VARIABLE) OUTPUT PICTURE POINTER POSITION PRINT READONLY REAL RECORD REDUCIBLE REFER RETURNS
SEQUENTIAL STATIC STREAM TYPE UNALIGNED UNION UPDATE VALUE VARIABLE VARYING
Parent topic: Declarations and Attributes Related information Defaults Input and Output OPEN
4.4.1. ALIGNED
ALIGNED is a data type attribute that controls the storage boundary of data. ALIGNED is an optional part of the data type specification. Its presence allows the Compiler to align the data on an implementation-defined storage boundary, with the possible side effect that more bits or bytes of storage are used than specified by the declared length. Parent topic: Attributes of DECLARE Statements Related information ALIGNED and UNALIGNED Attributes Bit-String Data
4.4.2. ANY
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (133 of 166) [16-03-2013 17:31:34]
The ANY attribute specifies that the corresponding argument for a parameter can be of any data type. The ANY attribute is applicable only to the declaration of entry names and is valid only in a parameter descriptor. ANY is not valid as an attribute in a PROCEDURE or ENTRY statement. Parent topic: Attributes of DECLARE Statements Related information ENTRY
4.4.3. AREA
AREA is a non-computational data type attribute used to define a region of storage in which based variables can be allocated and freed. The format is: AREA[(exp[REFER(variable)])] or AREA(*) For a complete description of area data and the use of the AREA attribute, see the section Area Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Area Data
4.4.4. AUTOMATIC
Abbreviation: AUTO AUTOMATIC is a storage class attribute that specifies that the declared name is a variable that is allocated storage with each activation of its containing procedure or BEGIN block. The AUTOMATIC attribute is supplied by default to any name of a non-parameter variable that is not a member of a structure and that has no storage class. Parent topic: Attributes of DECLARE Statements Related information Automatic Storage
4.4.5. BASED
BASED is a storage class attribute that specifies that the declared name is a based variable. Its format is: BASED[(r)] In the optional form, r is a reference to a locator variable or a locator-valued function that serves as the default (implicit) locator qualifier for unqualified references to the name. Parent topic: Attributes of DECLARE Statements Related information Based Variables
4.4.6. BIGENDIAN
BIGENDIAN is a data type attribute (applying to Fixed Binary items only) that specifies the internal storage for a data item is MSB first (or MSB "left -to- right"). This attribute is applicable only to Little-Endian machine architectures (such as Intel). For Big-Endian architectures, this attribute is ignored. Example: dcl flag fixed bin (15) static initial (1) bigendian;
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.7. BINARY
Abbreviation: BIN BINARY is an arithmetic data type attribute that specifies that the base is binary. Its format is: BINARY[(p)] The precision p may be supplied with the BINARY attribute or with the FIXED or FLOAT attribute, but it cannot be specified twice. The precision p must be a positive integer. If no precision is specified, a default precision is supplied. For information on the default precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. If BINARY is specified without FIXED or FLOAT, FIXED is assumed. When used with FIXED, BINARY specifies integer arithmetic values that contain at least p bits. When used with FLOAT, BINARY specifies floating-point arithmetic values that have a mantissa that contains the
equivalent of at least p bits. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data
4.4.8. BIT
BIT is a bit-string data type attribute that identifies a variable as a bit-string variable. Its format is: BIT[(n)] Length n is an extent expression or integer constant, depending on the storage class of the declared name. The length n must be a non-negative integer constant or an expression that evaluates to a non-negative integer. A default length of 1 is supplied if no length is given. For more information on BIT, see the chapter Storage Classes and the section Bit-String Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Storage Classes Bit-String Data
4.4.9. BUILTIN
BUILTIN is an entry name attribute that indicates that the declared name is a built-in function. Unless an empty argument list is used in a reference to a built-in function having no parameters, the function must be declared with the BUILTIN attribute. BUILTIN can be used to redeclare a built-in function name that was declared as something else in an outer block. The declared name must be one of the names given in the chapter Open PL/I BuiltIns. Parent topic: Attributes of DECLARE Statements Related information Open PL/I BuiltIns Send feedback about this topic
4.4.10. CHARACTER
Abbreviation: CHAR CHARACTER is a character-string data type attribute that identifies a variable as a character-string variable. Its format is: CHARACTER[(n)] Length n is an extent expression or integer constant, depending on the storage class of the declared name. The length n must be a non-negative integer constant or an expression that evaluates to a non-negative integer. A default length of 1 is supplied if no length is specified. For a discussion of storage classes, see the chapter Storage Classes and the section Character-String Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Storage Classes Character-String Data
4.4.11. CONDITION
Abbreviation: COND CONDITION is an attribute that indicates that the declared name is a condition name. Its format is: CONDITION Condition names can be used only in ON, SIGNAL, or REVERT statements. The default scope of condition name is external. Note that a name that appears with the CONDITION condition in an ON, SIGNAL, or REVERT statement is contextually declared to be a condition name. Parent topic: Attributes of DECLARE Statements Related information ON
4.4.12. CONNECTED
Abbreviation: CONN The CONNECTED attribute may be used only for parameters. It cannot be specified for a member of a structure and it cannot be specified for CONTROLLED parameters. The CONNECTED attribute asserts that any argument passed to the parameter is in connected storage.
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.13. CONTROLLED
Abbreviation: CTL CONTROLLED is a storage class attribute that specifies a variable whose storage is dynamically allocated and freed in generations. Its format is: CONTROLLED
4.4.14. DECIMAL
Abbreviation: DEC DECIMAL is an arithmetic data type attribute that specifies that the base is decimal. Its format is: DECIMAL[(p[,q])] The precision p,q (q is optional and represents fractional digits) may be supplied with the DECIMAL attribute or with the FIXED or FLOAT attribute, but it cannot be specified twice. The precision p and the scale q (if specified) must be positive integers. If a precision or scale is not specified, a default is assumed. For more information on default precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. If DECIMAL is supplied without FIXED or FLOAT, FIXED is the default. If FIXED or FLOAT is specified without BINARY or DECIMAL, DECIMAL is the default. When used with FIXED, DECIMAL specifies fixed-point arithmetic values that contain at least p decimal digits. If q is specified, p minus q digits are integral digits and q digits are fractional digits. If q is omitted, q = 0 is assumed. These values are integers containing at most p decimal digits. When used with FLOAT, DECIMAL specifies floating-point arithmetic values whose mantissa contains the equivalent of at least p decimal digits. In this case, q cannot be specified. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data
4.4.15. DEFINED
Abbreviation: DEF DEFINED is a storage class attribute that specifies that the declared name is a defined variable that shares storage with a basis variable. Its format is: DEFINED(r) where r is the basis variable. Parent topic: Attributes of DECLARE Statements Related information Defined Variables
4.4.16. DIMENSION
Abbreviation: DIM DIMENSION is an attribute that specifies that a declared name is an array and defines the number and extent of its dimensions. Its format is: DIMENSION(b1[,b2]) Each b represents one bound pair, which specifies the number of elements in a single dimension of the array. Each bound pair specifies an optional lower bound (lb) and a requisite upper bound (hb) for that dimension. A bound pair can be specified as follows.
The asterisk format of a bound pair, when used to define a parameter for a procedure or function, specifies that both the upper and lower bound of this dimension are to be taken from the corresponding array argument. If one bound pair is specified as asterisks, all bound pairs must be specified as asterisks. This format specifies the minimum and maximum subscripts that can be used for the dimension. lb is an extent expression or optionally signed integer constant, depending on the storage class of the array, which specifies the lower bound of the dimension. Like lb, hb is either an extent expression or an optionally signed integer constant, depending on the storage class. It specifies the upper bound of the dimension. This format specifies only the upper bound of the dimension. The lower bound is assumed to be 1.
lb:hb
hb
DECLARE Y DIMENSION(5) FLOAT; In this example, both X and Y are arrays of five floating-point values. The DIMENSION attribute is normally written immediately after the variable's name and is written without the DIMENSION keyword. When specified with the FILE or ENTRY attributes, DIMENSION causes the associated name to become a variable rather than a named constant. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.17. DIRECT
DIRECT is a file description attribute that indicates that a file can be accessed nonsequentially, that is, by key or by relative record number. The DIRECT attribute may be given either in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.18. ENTRY
ENTRY is a data type attribute that declares a constant or variable whose value is an entry point, and describes the attributes of the parameters, if any, that are declared for the entry point. Its format is: ENTRY [([parameter-list])] where parameter-list is: ()|parameter-descriptor[,parameter-descriptor]... where parameter-descriptor is: attribute[attribute] ... |*|,|structure-descriptor where structure-descriptor is: 1 [attribute] ... ,level[attribute] ... [,level[attribute]] ... An arbitrary parameter-descriptor can be indicated by use of an asterisk ( * ) or by a blank parameter-descriptor position, as indicated by the commas. For example, ENTRY(FIXED BIN, , FLOAT /* Three parameters. The second is of any data type. */
ENTRY(FIXED BIN, * ,FLOAT)/* Three parameters. The second is of any data type. */ ENTRY(, , ,) /* Four parameters of any data type. */ ENTRY() /* No parameters allowed. */ ENTRY /* Any number of parameters is allowed. */ The ENTRY attribute without the RETURNS option has an implicit RETURNS data type. It is determined by the In rule. External entries with the implicit RETURNS can be called as functions or procedures. Open PL/I does not require that if any entry statement in a multiple entry procedure has a RETURNS option, then all entries must have one. ENTRY can be used with or without the VARIABLE attribute. Used without the VARIABLE attribute, the ENTRY attribute declares a constant that is the name of an external procedure. In this case, each p is a list of attributes that is either identical to the attributes specified for the corresponding parameter in the external procedure, or is ANY. For example: DECLARE E ENTRY(FIXED BINARY(15), POINTER); In this example, E refers to a procedure that accepts a fixed binary and a pointer argument. Used with the VARIABLE attribute, the ENTRY attribute specifies that the declared name is a variable of the data type entry, which can be assigned any procedure name. When the entry variable is called, it must hold an entry value that designates a PROCEDURE statement whose parameters have attributes that are identical (unless the attribute is ANY) to the corresponding attributes given by p1, p2, and so forth. Using the declaration for E from the previous example, a compatible procedure declaration would be as follows: E: PROCEDURE(X,Y); DECLARE X FIXED BINARY(15); DECLARE Y POINTER; If a PROCEDURE statement has one or more parameters that are structures, the ENTRY attribute used to declare the procedure name must have a set of attributes for each member of the structure, including all substructures, as shown in the following example: DECLARE E ENTRY(1,2 FIXED, 2 FLOAT, POINTER); In the previous example, E is a procedure having two parameters; the first parameter is a structure with two members, and the second parameter is a pointer. The parameter attributes given in the ENTRY attribute include the level numbers and attributes of all members, as well as the level number and attributes of the parameter structure. All string lengths or array bounds given in an ENTRY attribute must be exactly the same as those given in the parameters of the PROCEDURE statement. Programs that violate this rule may produce unpredictable results. The ENTRY attribute can be used with the ANY, OPTIONS(VARIABLE), RETURNS(returns_descriptor), and VALUE options according to the following format: DECLARE entry_nameENTRY[(parameter_descriptor[VALUE])] [OPTIONS(VARIABLE)] [RETURNS(returns_descriptor)]; The RETURNS attribute is required for entry points that are invoked by function references and is invalid for procedures invoked by CALL statements. Parameter descriptors are not allowed if the ENTRY attribute is within a RETURNS descriptor.
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (141 of 166) [16-03-2013 17:31:34]
The parameter descriptor lists attributes for each parameter and must include either the data type of the parameter or the attribute ANY. The VALUE attribute indicates that the corresponding argument is to be passed by immediate value. The OPTIONS(VARIABLE) option indicates that the specified external procedure can be invoked with a variable number of arguments. The following options can be specified as part of the OPTIONS(VARIABLE) attribute when declaring an ENTRY:
ASSEMBLER NOMAP [map-list] COBOL NOMAPIN [map-list] FORTRAN NOMAPOUT [map-list] INTER NOEXECOPS TASK RETCODE
The RETURNS(retums_descriptor) option gives the data type attributes of the function value returned for an entry invoked as a function reference. The VARIABLE attribute is not valid in a parameter descriptor or in a RETURNS descriptor. The VALUE attribute can be used in an ENTRY declaration in conjunction with the data types Fixed Binary, Pointer, Character, Aligned Bit, Entry, or Float Binary. For more information, see the section VALUE. If the ANY attribute is included as a parameter descriptor, the argument that corresponds to that parameter descriptor can be of any data type. If the argument is a variable, its address is passed to the called procedure. If the argument is a constant or an expression, a dummy argument is created and its address is passed to the called procedure. The following conversions take place when creating the dummy argument:
Bit(n) Aligned, where n is the length of the string Fixed Binary(31) Char(n), where n is the length of the string
For more information, see the chapter Storage Classes and your Open PL/I User's Guide. The OPTIONS(VARIABLE) attribute is used to indicate that it is valid for a discrepancy to exist between the number of parameter descriptors in the declaration of the procedure and the number of arguments in the argument list used to call the procedure. The following rules apply when using the OPTIONS(VARIABLE) option:
If a procedure is called with more arguments than there are parameter descriptors, the trailing arguments are passed using the attributes of the last parameter descriptor. In this case, use of at least one parameter descriptor is required. If a procedure is called with some arguments omitted, a null pointer is passed to the called routine in place of the missing argument. (The null pointer indicates an omitted argument.) An argument is considered to be omitted if two commas are found adjacent to one another in a call to a procedure, or if a comma comes after the left parenthesis or before the right parenthesis; that is, ( , a, ) indicates two missing arguments.
If a procedure is called with more arguments than there are parameter descriptors, and the trailing arguments are omitted (as indicated by adjacent commas), a null pointer is passed for each of the omitted arguments.
The following examples show how the ENTRY attribute can be used with the VALUE, ANY, OPTIONS(VARIABLE), and RETURNS(retums_descriptor) options. For a further description of these options, refer to each option by name within this chapter. The following example causes the value of A to be converted to Fixed Binary(31) and the immediate value (25) to be passed directly to P5, followed by an immediate value representing the address of A: DECLARE P5 ENTRY (FIXED BIN(31) VALUE, POINTER VALUE), A FIXED BIN(15), B POINTER; A = 25; B = ADDR (A); CALL P5(A,B); The following example illustrates the use of the ENTRY attribute with the OPTIONS( VARIABLE) and ANY options: DECLARE P1 ENTRY (FIXED BINARY(15), ANY) OPTIONS(VARIABLE), A FIXED BINARY(15), B FLOAT BINARY(23), C CHARACTER(1); CALL P1(A, B); CALL P1(A, C, B); In the previous example, the second parameter descriptor is declared as ANY. In the first call to P1, B, a Float Binary (23) variable is the second argument passed; in the second call to P1, C, a Char(1) variable is passed. In both calls, the variable is passed by reference. Since the OPTIONS(VARIABLE) attribute is used, the second call to P1 passes argument three, B, using the attribute for parameter descriptor two, ANY. In the second call, the variable B is passed by reference. The following example illustrates a procedure called with some arguments omitted. DECLARE P2 ENTRY (FIXED BINARY(15), FIXED BINARY(15), FIXED BINARY(15)) OPTIONS(VARIABLE), (A,B) FIXED BINARY(15); CALL P2(A, ,B); In the previous example, the arguments to be passed are A, a missing argument, and B. This configuration causes the address of A to be passed, followed by a null value, followed by the address of B. The following example illustrates a procedure called with more arguments than there are parameter descriptors: DECLARE P3 ENTRY (FIXED BINARY(15),FIXED BINARY(15)) OPTIONS(VARIABLE), (A,B) FIXED BINARY(15), C FLOAT BINARY(31); CALL P3 (A, B, ,);
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (143 of 166) [16-03-2013 17:31:34]
CALL P3 (A, B, C); In the previous example, the first call to P3 is declared with two parameter descriptors and called with four arguments, the last two being null. The addresses of the last two arguments will be represented by null values. The second call to P3 passes C as a Fixed Binary(15), since it is a trailing argument and is passed with the attribute of the last parameter descriptor. This configuration requires that C be converted from Float Binary to Fixed Binary, and that the address of the resulting temporary be passed. The following example illustrates constants and expressions being passed with the ANY option: DECLARE P4 ENTRY (ANY,ANY), ( A, B ) FIXED BINARY(15); CALL P4( 3, 'ABC'); CALL P4( '1'B, AB ); In the first call to P4, the constant 3 will be converted to Fixed Binary(31) and the address of the temporary variable containing the converted value will be passed as the first argument; the character-string constant 'ABC' will be converted to Character(3) and its temporary address passed as the second argument. In the second call to P4, the bitstring constant '1' B will be converted to Bit(1) Aligned, AB will be converted to Fixed Binary(31), and the respective addresses of the temporaries will be passed to P4. The following example illustrates the use of the RETURNS(retums_descriptor) option: DECLARE F ENTRY(FIXED) RETURNS(POINTER); DECLARE G ENTRY(FLOAT) RETURNS(CHARACTER(32)VARYING); In this example, F is declared as the name of a function procedure that returns pointer values. G is declared as the name of a function procedure that returns varying character-string values whose maximum length is 32 characters. Parent topic: Attributes of DECLARE Statements Related information Storage Classes
4.4.19. ENVIRONMENT
Abbreviation: ENV The ENVIRONMENT attribute and its options specify many record characteristics that are not part of the PL/I language. Its format is: ENVIRONMENT(optionslist) options-list can contain any of a number options specifying record characteristics. For example, ENVIRONMENT(VSAM KEYLOC(1) KEYLENGTH(12)); The ENVIRONMENT attribute is not supported for use with a STREAM file.
4.4.20. EXCLUSIVE
Abbreviation: EXCL The EXCLUSIVE attribute specifies that the records in a file can be locked when accessed by one process to prevent access by another process. When the EXCLUSIVE attribute is used, the entire file is locked. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.21. EXTERNAL
Abbreviation: EXT EXTERNAL is a scope attribute that specifies that the declared name has external scope. This means that all declarations of this name anywhere in the program that also have the EXTERNAL attribute identify the same object. The EXTERNAL attribute can be used only in the declaration of variables whose storage class is STATIC or CONTROLLED. (It can be redundantly specified for variables of storage classes GLOBALDEF and GLOBALREF, which are implicitly EXTERNAL STATIC.) If EXTERNAL is specified for a variable and no storage class attribute is specified, STATIC is supplied by default. Its format is: EXTERNAL[(global_name)] global_name is either a character-string constant or a %REPLACE name for a character string constant. global_name is used by the linker when references are made to the entry. Open PL/I makes no restrictions on the contents of global_name, but the underlying operating system may have restrictions. EXTERNAL must be specified when the entry is declared in another module. EXTERNAL(global_name) is specified as an option either on a PROCEDURE statement or on an ENTRY statement. By using the EXTERNAL(global_name) option, an alternative name can be specified for an external entry constant. Instead of the usual entry constant name, the alternative name (global_name) is used to invoke the procedure at the entry point. OZS: PROCEDURE; DECLARE PROC1 ENTRY; DECLARE ALSO_PROC1 ENTRY EXTERNAL('PROC1'); DECLARE PROC2 ENTRY EXTERNAL('ILL.EGAL'); CALL PROC1; CALL ALSO_PROC1; CALL PROC2; END OZS;
/*======== A SEPARATE MODULE ========*/ PROC1: PROCEDURE; PROC2: ENTRY EXTERNAL('ILL.EGAL'); END PROC1; In this example, the program declares explicitly the entry constants PROC1 and PROC2. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.22. FILE
FILE is a data type attribute. Used without the VARIABLE attribute, it specifies that the declared name is a file identifier having external scope and an associated file control block that can be used to perform I/O on files and devices known to the operating system. In this case, the EXTERNAL attribute and any of the file description attributes RECORD, STREAM, INPUT, OUTPUT, UPDATE, KEYED, DIRECT, SEQUENTIAL, and PRINT may also be specified. Any file description attributes specified in the declaration are merged with attributes supplied by the OPEN statement or attributes implied by the I/O statement that implicitly opens the file control block. Used with the VARIABLE attribute, FILE specifies that the declared name is a file variable that can be assigned file values. In this case, the file description attributes cannot be supplied because a file variable has no associated file control block until a file value is assigned to it. File description attributes are attributes of a file control block and are not attributes of a file value or file variable. Some attributes for a name declared implicitly can be determined from the context in which the name appears. These cases are called contextual declarations. A name that appears in a FILE option, or in an ON, SIGNAL, or REVERT statement for a condition that requires a file name, is given the FILE attribute. For example, OPEN FILE(F); WRITE FILE(W) FROM(BUF); READ FILE(R) INTO(BUF); CLOSE FILE(C); In all four above cases the names used with the FILE option will be implicitly declared as having File data type. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.23. FIXED
FIXED is an arithmetic data type attribute that defines a fixed-point arithmetic variable. Its format is: FIXED[(p[,q])]
The precision p,q (q is optional and represents fractional digits) may be supplied with this attribute or with the BINARY or DECIMAL attribute, but it cannot be specified twice. The precision p and the scale q (if specified) must be positive integers. If a precision or scale is not specified, a default is assumed. If FIXED is specified without BINARY or DECIMAL, DECIMAL is assumed. For details on precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. When used with BINARY, FIXED specifies integer arithmetic values that contain at least p bits. In this case, q must not be specified. When used with DECIMAL, FIXED specifies fixed-point arithmetic values that contain at least p decimal digits. If q is specified, p minus q digits are integral digits and q digits are fractional digits. If q is omitted, q = 0 is assumed. These values are integers containing at least p decimal digits. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data
4.4.24. FLOAT
FLOAT is an arithmetic data type attribute that defines a floating-point arithmetic value. Its format is: FLOAT[(p)] The precision p may be supplied with this attribute or with the BINARY or DECIMAL attribute, but it cannot be specified twice. The precision p must be a positive integer. If a precision is not specified, a default precision is assumed. for information on the Open PL/I default precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. If FLOAT is specified without BINARY or DECIMAL, DECIMAL is the default. If BINARY or DECIMAL is supplied without FIXED or FLOAT, FIXED is the default. When used with BINARY, FLOAT specifies floating-point arithmetic values whose mantissa contains the equivalent of at least p bits. When used with DECIMAL, FLOAT specifies floating-point arithmetic values whose mantissa contains the equivalent of at least p decimal digits. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data
4.4.25. GLOBALDEF
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (147 of 166) [16-03-2013 17:31:34]
GLOBALDEF is a storage class and scope attribute that declares an external variable or external file constant and causes storage to be allocated for the variable or constant. Its format is: GLOBALDEF [(name)] where name is an identifier that is accepted as legal syntax for compatibility with other Open PL/I extensions, but is ignored, having no effect. For variables, the GLOBALDEF attribute implies the EXTERNAL and STATIC attributes. For file constants, it implies the EXTERNAL attribute. A given variable or file constant may be declared with the GLOBALDEF attribute in only one procedure. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.26. GLOBALREF
GLOBALREF is a storage class and scope attribute that declares a global symbol, which is defined in an external procedure either with the GLOBALDEF attribute or, if the external procedure is written in another programming language, with its equivalent in that language. Its format is: GLOBALREF [(name)] where name is an identifier that is accepted as legal syntax for compatibility with other Open PL/I extensions, but is ignored, having no effect. The GLOBALREF attribute implies the EXTERNAL and STATIC attributes. A variable may be declared with the GLOBALREF attribute in as many procedures as desired. Unlike GLOBALDEF, GLOBALREF does not cause actual storage to be allocated for the external variable, but allows access to the storage that was allocated by some other external procedure. If GLOBALREF is present, any INITIAL attribute for the variable is ignored. P1: PROCEDURE; DECLARE XVAR FIXED BIN(15) GLOBALDEF; XVAR = 23; CALL P2; . . . P2: PROCEDURE; DECLARE XVAR FIXED BIN(15) GLOBALREF; IF XVAR > 0 THEN XVAR = 100; . . .
In this example, XVAR is declared with the GLOBALDEF attribute in procedure P1 and is assigned storage as a result. The value 23 is assigned to XVAR. Procedure P2 has declared XVAR with the GLOBALREF attribute and will access the same memory location allocated by P1 . Procedure P2 can test and/or change the value of XVAR. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (148 of 166) [16-03-2013 17:31:34]
4.4.27. INITIAL
Abbreviation: INIT INITIAL is a storage class attribute that specifies the initial value of a variable or member of a structure. The INITIAL attribute has two formats. The first specifies an initial constant, expression, or variable whose value is assigned to a variable when storage is allocated to it. The second format specifies that the CALL option invokes a procedure to perform initialization at allocation. The variable is initialized by assignment during the execution of the called routine, rather than by the routine being invoked as a function that returns a value to the point of invocation. The formats of the INITIAL attribute are: Format 1: INITIAL(item[,item]) where item is: *|constant|variable|expression|iteration-spec where iteration-spec is: (iteration-factor) iteration-item where iteration-item is: *|constant|variable|expression where iteration-factor is: *|expression where constant is: arithmetic-constant|bit-constant|character-constant| entry-constant1 label-constant Note: Open PL/I supports the ANS PL/I Subset G specification for the INITIAL attribute, not the full mainframe PL/ I specification. In the context of item or iteration-item, asterisk ( * ) specifies that the element is to be left uninitialized. In the context of iteration-factor, asterisk (* ) specifies that the entire array is to be initialized with the iteration-item. For static variables, any value specified in an INITIAL attribute is assigned at the time the program is first loaded into memory for execution. For automatic variables, which are allocated at each activation of the declaring block, any specified initial value is assigned at the time of each allocation. For based and controlled variables, which are allocated at the execution of ALLOCATE statements, any specified initial value is assigned at the time of each allocation.
The INITIAL attribute may not be used with variables of storage classes other than those mentioned above. Only constant values with no operations can be specified in the INITIAL attribute for static variables, with the following exceptions:
The NULL() built-in function can be used to initialize a static pointer variable. Expressions containing concatenated string constants can be used to initialize static string variables. For example: DECLARE STRING CHAR(5) STATIC INIT ('LIA' || 'NT');
Format 2: INITIAL CALL entry(arg[,arg]) The INITIAL call cannot be used to initialize static data.
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
TEST: PROCEDURE OPTIONS(MAIN); /* Initialize all elements of array TEN */ DECLARE TEN(10) FIXED BIN(15) INIT CALL INITIALIZE(ADDR(TEN),HBOUND(TEN,1)); INITIALIZE: PROCEDURE(P,DIM); DECLARE P DIM DECLARE I ARRAY(1000)
4.4.28. INPUT
INPUT is a file description attribute that specifies that a file will be used for input. The INPUT attribute may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. File description attributes specified in a DECLARE statement apply to all openings of the file control block associated with the file constant. Parent topic: Attributes of DECLARE Statements Related information Input and Output OPEN
4.4.29. INTERNAL
Abbreviation: INT INTERNAL is a scope attribute that limits the scope of a variable to the block in which it is defined. The INTERNAL attribute may be given with any storage class attribute or to parameters, but it has no significance
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (151 of 166) [16-03-2013 17:31:34]
since these variables always have internal scope. If STATIC is used without INTERNAL or EXTERNAL, INTERNAL is the default. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.30. IRREDUCIBLE
Abbreviation: IRRED IRREDUCIBLE is an attribute sometimes used by IBM mainframe PL/I programs. It is not needed by Open PL/I. It is simply parsed and otherwise ignored. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.31. KEYED
KEYED is a file description attribute that indicates that records in a specified file may be accessed randomly. The KEYED attribute implies the RECORD attribute. KEYED may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN
4.4.32. LABEL
LABEL is a data type attribute that specifies label values. When used in the declaration of a name, it specifies that the declared name is a label variable. When used in an ENTRY attribute, it specifies that the corresponding parameter is a label variable, and when used in a RETURNS attribute, it specifies that the procedure returns label values. For a discussion of label values, see the section Label Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Label Data
4.4.33. LIKE
LIKE specifies that the variable being declared has the same structure as the referenced variable. Its format is: LIKE reference where reference is a reference to a structure variable. The variable being declared must be a structure variable. LIKE causes it to have exactly the same members, in name and attributes, as the referenced structure variable. Only the level numbers are changed as needed to adapt to the variable being declared. In the following example, structure members are duplicated from one declaration to another by way of the LIKE attribute: DECLARE 1 TEMPLATE BASED, 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); DECLARE 1 EMPLOYEE_INFO(1000) LIKE TEMPLATE; Duplication of the members from TEMPLATE expands the declaration of EMPLOYEE_INFO, with the result that the declaration of EMPLOYEE_INFO is equivalent to: DECLARE 1 EMPLOYEE_INFO(1000), 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); The referenced variable can be a major or a minor structure. It may be qualified, but may not be pointer-qualified. The following restrictions apply to the referenced variable:
It must be known in the block containing the LIKE attribute specification. It cannot be subscripted. It cannot contain a REFER variable. Neither the referenced variable nor any of its substructures can be declared with the LIKE attribute. It cannot be a substructure of a structure declared with the LIKE attribute.
The function of the LIKE attribute is similar to that of the TYPE attribute . With LIKE, the storage class of the referenced structure is not carried over to the created structure (same as TYPE). However, neither are the alignment attributes and/or dimensions of the referenced variable carried over (unlike TYPE). Only the alignment and dimensions of substructures and elements of the referenced variable are carried over. Note: Because the UNALIGNED attribute is not carried forward with LIKE, two LIKE structures could have differing alignment characteristics and sizes because of structure mapping conventions.
4.4.34. NATIVE
NATIVE is a data type attribute (applying to Fixed Binary items only) that specifies the internal storage for the data item is LSB first (or MSB "right -to- left"). This attribute is applicable only to Little-Endian machine architectures (such as Intel), and is the default if not specified. For Big-endian architectures, this attribute is ignored. Example: dcl flag fixed bin (15) static initial (1) native;
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.35. NONNATIVE
NONNATIVE is equivalent to BIGENDIAN. Example: dcl flag fixed bin (15) static initial (1) nonnative;
4.4.36. OFFSET
The OFFSET attribute defines a locator data type used to specify the relative location of a based variable within an area. The format is: OFFSET[(areavariable)] For a complete description of offset data and the use of the OFFSET attribute, see the sections Offset Data and Area Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements
4.4.37. OPTIONS(DESCRIPTOR)
OPTIONS(DESCRIPTOR) is an entry name attribute. It specifies that argument descriptors will be passed to this entry by callers. This is the default for entry names. Argument descriptors are used to pass specific details about actual parameters in cases where parameter declarations contain CHAR(*) or DIMENSION(*) attributes. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.38. OPTIONS(NODESCRIPTOR)
OPTIONS(NODESCRIPTOR) is an entry name attribute. It specifies that argument descriptors will not be passed to this entry by callers. Argument descriptors are used to pass specific details about actual parameters in cases where parameter declarations contain CHAR(*) or DIMENSION(*) attributes. The OPTIONS(NODESCRIPTOR) attribute is normally used to suppress the generation and passing of the descriptor(s) to a non-PL/I procedure. Note: OPTIONS(ASM) and OPTIONS(COBOL) are equivalent to OPTIONS(NODESCRIPTOR).
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.39. OPTIONS(VARIABLE)
OPTIONS(VARIABLE) is an entry name attribute that indicates, for an ENTRY descriptor, that a specified external procedure can be invoked with a variable number of arguments; a discrepancy may exist between the number of parameter descriptors in the declaration of the procedure and the number of arguments in the argument list used to call the procedure. OPTIONS(VARIABLE) attribute is parsed and is otherwise ignored. It is an invalid attribute for a PROCEDURE or ENTRY statement, as opposed to the ENTRY attribute. Parent topic: Attributes of DECLARE Statements Related information ENTRY
4.4.40. OUTPUT
OUTPUT is a file description attribute that indicates that data should be written to, and not read from, the associated file or device. The OUTPUT attribute may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN
4.4.41. PICTURE
Abbreviation: PIC PICTURE is a data type attribute that specifies pictured values. Its format is: PICTURE'p' The picture 'p' contains an image of the data and specifies the editing to be performed each time a value is assigned to a pictured variable. It also governs the conversion of pictured values to fixed-point decimal values. For a discussion of pictured data and the picture characters, see the section Picture Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Picture Data
4.4.42. POINTER
Abbreviation: PTR POINTER is a data type attribute that specifies pointer values. A pointer value is the address of a variable and is discussed in the section Pointer Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Pointer Data
4.4.43. POSITION
Abbreviation: POS POSITION is an attribute that is used in conjunction with the DEFINED attribute. It specifies the bit or character within the basis variable at which the defined variable is to begin. Its format is: POSITION(expression) where expression is an integer expression that specifies the position relative to the start of the basis variable. The range of the expression is from 1 to n, where n is defined as: n = basis_length defined_length+1 where basis_length is the length of the basis variable in bits or characters and defined_length is the length of the defined variable in bits or characters. Both the defined variable and the basis variable must be fixed-length bit strings, fixed-length character strings, pictured variables, or aggregates containing any of these data types. In the following example, the two DO-groups accomplish the same purpose. The second makes use of the POSITION attribute: DECLARE X CHARACTER(200); DECLARE Y CHARACTER(1) DEF X POS(I); DO I = 1 to 200; IF SUBSTR(x,i,1) = '?' THEN CALL ERROR(); DO I = 1 to 200; IF Y = '?' THEN CALL ERROR();
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.44. PRINT
PRINT is a file description attribute used to declare a print file. PRINT may be given in the declaration of a file constant or in an OPEN statement, but it must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (157 of 166) [16-03-2013 17:31:34]
OPEN
4.4.45. READONLY
The READONLY attribute is parsed and is otherwise ignored. This is a compatibility feature to allow Open PL/I programs written for other systems to compile without error. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.46. REAL
REAL is an arithmetic data type attribute. It specifies that the associated variable is used for real numbers (that is, single-part numbers, as opposed to complex). Arithmetic variables are assumed to be REAL by default. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.47. RECORD
RECORD is a file description attribute that indicates that data in an input or output file is made up of separate records, and that the file will be processed by record I/O statements. RECORD may be given in the declaration of a file constant or may be given in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN
4.4.48. REDUCIBLE
Abbreviation: RED REDUCIBLE is an attribute sometimes used by IBM mainframe PL/I programs. It is not needed by Open PL/I. It is simply parsed and otherwise ignored. Parent topic: Attributes of DECLARE Statements
4.4.49. REFER
REFER is an attribute of a based structure that specifies that the value of one member is used to determine the amount of storage space allocated for another member of the same structure. Its format is: expressionREFER(variable) where expression is evaluated and converted to Fixed Binary (15) and is the initial extent when the based structure is allocated. Variables used in the expression being evaluated as operands must not belong to the member containing the REFER attribute. variable must be a variable contained by the structure being allocated and defined prior to the extent whose size it determines. For example: DECLARE 1 STRUC BASED(P), 2 I FIXED BINARY, 2 A CHARACTER(20 REFER(I)); Multiple REFER attributes are allowed in the declaration of a structure. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
4.4.50. RETURNS
RETURNS is an entry name attribute that specifies that the entry value designates a function procedure that returns a value of data type t, where t is a list of attributes that specify a data type. Its format is: RETURNS[(t)]; For example: DECLARE F ENTRY(FIXED) RETURNS(POINTER); DECLARE G ENTRY(FLOAT) RETURNS(CHARACTER(32)VARYING); In this example, F is declared as the name of a function procedure that returns pointer values. G is declared as the name of a function procedure that returns varying character-string values whose maximum length is 32 characters. Any string length given in a RETURNS attribute must be an integer constant. The only attributes that can be given in a RETURNS attribute are data type attributes. DIMENSION or level numbers cannot be given, because functions cannot return arrays or structures. Parent topic: Attributes of DECLARE Statements Related information ENTRY
4.4.51. SEQUENTIAL
Abbreviation: SEQL SEQUENTIAL is a file description attribute that indicates that records in the file will be accessed sequentially. SEQUENTIAL may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN
4.4.52. STATIC
STATIC is a storage class attribute that specifies that the storage for the declared variable is allocated by the Compiler and/or linker prior to program execution and remains allocated throughout program execution. The default attribute is AUTOMATIC. Parent topic: Attributes of DECLARE Statements Related information Static Storage
4.4.53. STREAM
STREAM is a file description attribute that indicates that the file consists of ASCII characters and will be processed using the GET and PUT statements. The STREAM attribute may be given in the declaration of a file constant or in an OPEN statement, but it cannot be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN
4.4.54. TYPE
The TYPE attribute allows a declaration to inherit structure members and attributes from another declaration. It has the following format, where reference is a reference to a variable: TYPE(reference) If, for example, a variable INTEGER is declared as fixed binary, another variable that needs to be declared as fixed binary can be declared as TYPE (INTEGER) instead. For example: DECLARE INTEGER DECLARE CODE FIXED BIN(31); TYPE(INTEGER); /* TYPE DEFINITION */ /* TYPED VARIABLE */
In this example, Open PL/I copies the attributes from INTEGER to CODE, which makes the declaration of CODE become the following: DECLARE CODE FIXED BIN(31);
In the previous example, INTEGER is referred to as a type definition and CODE is referred to as a typed variable. A type definition is a normal variable declaration. It can be given the based storage class, because storage will not be allocated for the type definition. In the following example, structure members are duplicated from one declaration to another by way of the TYPE attribute: DECLARE 1 TEMPLATE BASED, /* TYPE DEFINITION */ 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); DECLARE EMPLOYEE_INFO TYPE(TEMPLATE); /* TYPED VARIABLE */ Duplication of the members from TEMPLATE expands the declaration of EMPLOYEE_INFO, with the result that the declaration of EMPLOYEE_INFO is now: DECLARE 1 EMPLOYEE_INFO 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); The TYPE attribute can be used in any of the following locations:
Within a variable declaration. Within a parameter declaration. As a parameter description within the explicit declaration of an ENTRY constant or ENTRY variable. Within a RETURNS option of a PROCEDURE or ENTRY statement. As a RETURNS attribute of an ENTRY declaration.
/*----------- TYPE DEFINITION -----------*/ /* (LINE MAY ALSO BE USED AS A VARIABLE) */ DECLARE LINE CHAR(80) VARYING; /*---------------------------------------*/ /* VARIABLE DECLARATION */ DECLARE FORMAT_LINE TYPE(LINE); /* PARAMETER DECLARATION */ DECLARE PARAM TYPE(LINE); /* PARAMETER DESCRIPTOR */ DECLARE WRITE_LINE ENTRY(TYPE(LINE)); /* RETURNS OPTION IN PROCEDURE STATEMENT */ GET_LINE: PROC RETURNS(TYPE(LINE)); /* RETURNS OPTION IN ENTRY STATEMENT */ READ_LINE: ENTRY RETURNS(TYPE(LINE)); /* RETURNS ATTRIBUTE IN DECLARE STATEMENT */ DECLARE GET_LINE ENTRY RETURNS(TYPE(LINE)); A typed variable can inherit only the following attributes from its type definition (storage class is not inherited):
ALIGNED BINARY BIT CHARACTER DECIMAL ENTRY FILE FIXED FLOAT LABEL PICTURE OPTIONS POINTER RETURNS
UNALIGNED UNION VARIABLE VARYING string length arithmetic precision array dimensions.
TYPE Attribute Extensions TYPE and Extent Expressions Using the TYPE Attribute Examples of the TYPE Attribute
Parent topic: Attributes of DECLARE Statements Send feedback about this topic
When a typed variable (enclosed in parentheses) is used in an argument list (see the following example).
When a function reference used as an argument has a RETURNS value that is declared with the TYPE attribute (see the following example). DECLARE XARR(10) FIXED BIN(15) YYR TYPE( XARR ), RTE ENTRY( TYPE(XARR) ), FCA ENTRY RETURNS( TYPE(XARR) ); CALL RTE( (XARR) ); /* CASE 1 */ CALL RTE( (YYR) ); /* CASE 1 */ CALL RTE( (FCA()) ); /* CASE 2 */
The parameter in the called routine must have the same TYPE attribute as the argument. In the above example, RTE's parameter has the attribute TYPE (XARR) (see the third line). This TYPE attribute is the same TYPE attribute that is used by the arguments in the subsequent calls to RTE (see the last 3 lines). All extents in a type definition must have constant values when an aggregate variable is passed by value. For example, in the preceding program fragment, XARR. could not be declared as: DECLARE N FIXED BINARY(31) INIT(10); DECLARE XARR(N) FIXED BIN(15), . . . Dimensions (array bounds) can be specified on either the type definition or the typed variable, but not on both. For example, the following declaration of an array of arrays is invalid: DECLARE XXX(10) CHAR(80), /* VALID */ YYY TYPE( XXX ), /* VALID */ ZZZ(10) TYPE( XX ); /* INVALID -- ARRAY OF ARRAYS */
variables. In the following example, the variable array is declared in a different block from CHARX: /*--------------------------------------------------*/ START: PROCEDURE; DECLARE CHARX(N,N) CHAR( LENGTH(STRING) ) BASED, N FIXED BINARY(15), STRING CHAR(80) VARYING; . . . /*--------------------------------------------------*/ NEXT: PROCEDURE; DECLARE ARRAY TYPE(CHARX) BASED, N FIXED BINARY(15), STRING CHAR(80) VARYING; . . . END NEXT; /*--------------------------------------------------*/ . . . END START; /*--------------------------------------------------*/ In the preceding example, Open PL/I uses the declarations in procedure NEXT to evaluate the extent expressions of ARRAY. Declarations in the current block are always used to evaluate extent expressions, even for variables that have not been declared with the TYPE attribute. (In the preceding example, if procedure NEXT did not declare N and STRING, those variable declarations in procedure START would be used.) If the REFER option is used in a type definition, the following are true:
If the type definition is a structure that has the BASED attribute with a REFER option, the BASED attribute for the corresponding typed variable must be specified. For example, in the following program fragment, VAR1 is a type definition, and VAR2 is a corresponding typed variable. The BASED attribute and a REFER option are specified in the declaration of VAR1. Therefore, the BASED attribute must be specified in the VAR2 declaration. DECLARE N FIXED BIN(15); /* TYPE DEFINITION: */ DECLARE 1 VAR1 BASED, 2 SIZE FIXED BIN(15), 2 ITEMS( N REFER(VAR1.SIZE) ) CHAR(80); DECLARE VAR2 TYPE(VAR1) BASED; when expanded yields: DECLARE 1 VAR2 BASED, 2 SIZE FIXED BIN(15),
2 ITEMS (N REFER (VAR2.SIZE)) CHAR(80); A variable declared with a REFER extent cannot be used as a type definition. For example, in the previous program fragment, VAR1.ITEMS cannot b