Rzahgrpgcode
Rzahgrpgcode
23
ILE RPG Language Reference
Este manual de consulta proporciona información sobre el lenguaje RPG IV tal
como se implementa mediante el compilador ILE RPG con el sistema operativo
IBM® i.
- ILE RPG Language Reference
Tema principal:RPG
24
Rational Development Studio for i
ILE RPG Language Reference
7.1
SC09-2508-08
Note!Before using this information and the product it supports, be sure to read the
general information under Notices.
You can also send your comments by FAX (attention: RCF Coordinator), or you can
send your comments electronically to IBM. See "How to Send Your Comments" for a
description of the methods.
When you send information to IBM, you grant IBM a nonexclusive right to use or
distribute the information in any way it believes appropriate without incurring any
obligation to you.
25
About This Reference
This reference provides information about the RPG IV language as it is
implemented using the ILE RPG compiler with the IBM i® (IBM i®) operating
system, formerly Operating System/400® (OS/400®).
This reference covers:
- Basics of RPG IV:
- RPG IV character set
- RPG IV reserved words
- Compiler directives
- RPG IV program cycle
- Indicators
- Error Handling
- Subprocedures
- Definitions:
- Defining Data and Prototypes
- Data types and Data formats
- RPG IV specifications:
- Control
- File description
- Definition
- Input
- Calculation
- Output
- Procedure
- Ways to manipulate data or devices:
- Built-in Functions
- Expressions
- Operation Codes
26
Who Should Use This Reference
This reference is for programmers who are familiar with the RPG IV programming
language.
This reference provides a detailed description of the RPG IV language. It does not
provide information on how to use the ILE RPG compiler or how to convert RPG III
programs to ILE RPG. For information on those subjects, see the IBM Rational
Development Studio for i: ILE RPG Programmer's Guide.
Before using this reference, you should
- Know how to use applicable IBM i menus and displays or Control Language (CL)
commands.
- Have a firm understanding of Integrated Language Environment® as described in
detail in the ILE Concepts.
27
Prerequisite and Related Information
Use the iSeries Information Center as your starting point for looking up iSeries and
AS/400e technical information. You can access the Information Center in two ways:
- From the following Web site: http://www.ibm.com/systems/i/infocenter/
- From CD-ROMs that ship with your Operating System/400 order: i5/OS Information
Center CD.
The iSeries Information Center contains advisors and important topics such as CL
commands, system application programming interfaces (APIs), logical partitions,
clustering, Java ™ , TCP/IP, Web serving, and secured networks. It also includes
links to related IBM® Redbooks and Internet links to other IBM Web sites such as
the Technical Studio and the IBM home page.
For a list of related publications, see the Bibliography.
28
How to Send Your Comments
Your feedback is important in helping to provide the most accurate and high-quality
information. IBM welcomes any comments about this book or any other iSeries
documentation.
- If you prefer to send comments by mail, use the the following address: IBM Canada Ltd.
Laboratory
Information Development
If you are mailing a readers' comment form from a country other than the United
States, you can give the form to the local IBM branch office or IBM representative
for postage-paid mailing.
- If you prefer to send comments by FAX, use this number: 1–845–491–7727
- If you prefer to send comments electronically, use one of these e-mail addresses:
- Comments on books:
- [email protected]
- Comments on the iSeries Information Center:
- [email protected]
Be sure to include the following:
- The name of the book.
- The publication number of the book.
- The page number or topic to which your comment applies.
29
What's New
There have been several releases of RPG IV since the first V3R1 release. The
following is a list of enhancements made for each release since V3R1 to the current
release:
- What's New in this Release
- What's New in V6R1
- What's New in V5R4?
- What's New in V5R3?
- What's New in V5R2?
- What's New in V5R1?
- What's New in V4R4?
- What's New in V4R2?
- What's New in V3R7?
- What's New in V3R6/V3R2?
You can use this section to link to and learn about new RPG IV functions.
Note:
The information for this product is up-to-date with the V7R1 release of RPG IV. If
you are using a previous release of the compiler, you will need to determine what
functions are supported on your system. For example, if you are using a V5R1
system, the functions new to the V7R1 release will not be supported.
30
What's New in this Release
This section describes the enhancements made to ILE RPG in V7R1.
- Sort and search data structure arrays
- Data structure arrays can be sorted and searched using one of the subfields as
a key.
// Sort the custDs array by the amount_owing subfield
SORTA custDs(*).amount_owing;
SORTA(D) salary;
string1 = 'See NAME. See NAME run. Run NAME run.'; string2 = %ScanRpl('NAME' : 'Tom' :
string1);
- %LEN(varying : *MAX)
- The %LEN builtin function can be used to obtain the maximum number of
characters for a varying-length character, UCS-2 or Graphic field.
- Use ALIAS names in externally-described data structures
- Use the ALIAS keyword on a Definition specification to indicate that you want to
use the alternate names for the subfields of externally-described data
structures. Use the ALIAS keyword on a File specification to indicate that you
want to use the alternate names for LIKEREC data structures defined from the
records of the file.
A R CUSTREC A CUSTNM 25A ALIAS(CUSTOMER_NAME) A
31
- %PARMNUM built-in function
- The %PARMNUM(parameter_name) built-in function returns the ordinal
number of the parameter within the parameter list. It is especially important to
use this built-in function when a procedure is coded with the RTNPARM
keyword.
D pi D name 100a const varying D id
options(*nopass) /free
- Optional prototypes
- If a program or procedure is not called by another RPG module, it is optional to
specify the prototype. The prototype may be omitted for the following types of
programs and procedures:
- A program that is only intended to be used as an exit program or as the
command-processing program for a command
- A program that is only intended to be called from a different programming
language
- A procedure that is not exported from the module
- A procedure that is exported from the module but only intended to be called
from a different programming language
- Pass any type of string parameter
- Implicit conversion will be done for string parameters passed by value or by
read-only reference. For example, a procedure can be prototyped to have a
CONST UCS-2 parameter, and character expression can be passed as a
parameter on a call to the procedure. This enables you to write a single
procedure with the parameters and return value prototyped with the UCS-2
type. To call that procedure, you can pass any type of string parameter, and
assign the return value to any type of string variable. // The makeTitle procedure
= makeTitle(dbcsValue : 50);
33
Control specification ACTGRP(*STGMDL) *STGMDL is the new
keywords default for the
ACTGRP keyword
and command
parameter. If the
program uses the
teraspace storage
module, the
activation group is
QILETS. Otherwise it
is QILE.
Built-in functions %LEN(varying-field : Can now be used to
*MAX) obtain the maximum
number of characters
of a varying-length
field.
Operation codes SORTA(A | D) The SORTA
operation code now
allows the A and D
operation extenders
indicating whether
the array should be
sorted ascending (A)
or descending (D).
Table 2. New Language Elements Since V6R1
34
RTNPARM Specifies that the
return value for the
procedure should be
handled as a hidden
parameter
Built-in functions %PARMNUM Returns the ordinal
number of the
parameter in the
parameter list
%SCANRPL Scans for all
occurrences of a
value within a string
and replaces them
with another value
XML-INTO options datasubf Name a subfield that
will receive the text
data for an XML
element that also has
attributes
countprefix Specifies the prefix
for the names of the
additional subfields
that receive the
number of RPG array
elements or non-
array subfields set by
the XML-INTO
operation
35
What's New in V6R1
This section describes the enhancements made to ILE RPG in V6R1.
- THREAD(*CONCURRENT)
- When THREAD(*CONCURRENT) is specified on the Control specification of a
module, it provides ability to run concurrently in multiple threads:
- Multiple threads can run in the module at the same time.
- By default, static variables will be defined so that each thread will have its own
copy of the static variable.
- Individual variables can be defined to be shared by all threads using
STATIC(*ALLTHREAD).
- Individual procedures can be serialized so that only one thread can run them
at one time, by specifying SERIALIZE on the Procedure-Begin specification.
- Ability to define a main procedure which does not use the RPG cycle
- Using the MAIN keyword on the Control specification, a subprocedure can be
identified as the program entry procedure. This allows an RPG application to be
developed where none of the modules uses the RPG cycle.
- Files defined in subprocedures
- Files can be defined locally in subprocedures. I/O to local files can only be done
with data structures; I and O specifications are not allowed in subprocedures,
and the compiler does not generate I and O specifications for externally
described files. By default, the storage associated with local files is automatic;
the file is closed when the subprocedure returns. The STATIC keyword can be
used to indicate that the storage associated with the file is static, so that all
invocations of the subprocedure will use the same file, and if the file is open
when the subprocedure returns, it will remain open for the next call to the
subprocedure.
- Qualified record formats
- When a file is defined with the QUALIFIED keyword, the record formats must
be qualified by the file name, MYFILE.MYFMT. Qualified files do not have I and
O specifications generated by the compiler; I/O can only be done through data
structures.
- Files defined like other files
- Using the LIKEFILE keyword, a file can be defined to use the same settings as
another File specification, which is important when passing a file as a
parameter. If the file is externally-described, the QUALIFIED keyword is
implied. I/O to the new file can only be done through data structures.
- Files passed as parameters
- A prototyped parameter can be defined as a File parameter using the LIKEFILE
keyword. Any file related through the same LIKEFILE definition may be passed
as a parameter to the procedure. Within the called procedure or program, all
supported operations can be done on the file; I/O can only be done through
data structures.
- EXTDESC keyword and EXTFILE(*EXTDESC)
- The EXTDESC keyword identifies the file to be used by the compiler at compile
time to obtain the external decription of the file; the filename is specified as a
literal in one of the forms 'LIBNAME/FILENAME' or 'FILENAME'. This removes
the need to provide a compile-time override for the file.
The EXTFILE keyword is enhanced to allow the special value *EXTDESC,
36
indicating that the file specified by EXTDESC is also to be used at runtime.
- EXTNAME to specify the library for the externally-described data structure
- The EXTNAME keyword is enhanced to allow a literal to specify the library for
the external file. EXTNAME('LIBNAME/FILENAME') or EXTNAME('FILENAME')
are supported. This removes the need to provide a compile-time override for
the file.
- EXFMT allows a result data structure
- The EXFMT operation is enhanced to allow a data structure to be specified in
the result field. The data structure must be defined with usage type *ALL, either
as an externally-described data structure for the record format
(EXTNAME(file:fmt:*ALL), or using LIKEREC of the record format
(LIKEREC(fmt:*ALL).
- Larger limits for data structures, and character, UCS-2 and graphic variables
-
- Data structures can have a size up to 16,773,104.
- Character definitions can have a length up to 16,773,104. (The limit is 4 less
for variable length character definitions.)
- Character definitions can have a length up to 16,773,104. (The limit is 4 less
for variable length character definitions.)
- UCS-2 definitions can have a length up to 8,386,552 UCS-2 characters. (The
limit is 2 less for variable length UCS-2 definitions.)
- Graphic definitions can have a length up to 8,386,552 DBCS characters. (The
limit is 2 less for variable length graphic definitions.)
- The VARYING keyword allows a parameter of either 2 or 4 indicating the
number of bytes used to hold the length prefix.
- %ADDR(varying : *DATA)
- The %ADDR built-in function is enhanced to allow *DATA as the second
parameter to obtain the address of the data part of a variable length field.
- Larger limit for DIM and OCCURS
- An array or multiple-occurrence data structure can have up to 16,773,104
elements, provided that the total size is not greater than 16,773,104.
- Larger limits for character, UCS-2 and DBCS literals
-
- Character literals can now have a length up to 16380 characters.
- UCS-2 literals can now have a length up to 8190 UCS-2 characters.
- Graphic literals can now have a length up to 16379 DBCS characters.
- TEMPLATE keyword for files and definitions
- The TEMPLATE keyword can be coded for file and variable definitions to
indicate that the name will only be used with the LIKEFILE, LIKE, or LIKEDS
keyword to define other files or variables. Template definitions are useful when
defining types for prototyped calls, since the compiler only uses them at
compile time to help define other files and variables, and does not generate any
code related to them.
Template data structures can have the INZ keyword coded for the data
structure and its subfields, which will ease the use of INZ(*LIKEDS).
- Relaxation of some UCS-2 rules
- The compiler will perform some implicit conversion between character, UCS-2
and graphic values, making it unnecessary to code %CHAR, %UCS2 or
37
%GRAPH in many cases. This enhancement is also available through PTFs for
V5R3 and V5R4. Implicit conversion is now supported for
- Assignment using EVAL and EVALR.
- Comparison operations in expressions.
- Comparison using fixed form operations IFxx, DOUxx, DOWxx, WHxx,
CASxx, CABxx, COMP.
- Note that implicit conversion was already supported for the conversion
operations MOVE and MOVEL.
UCS-2 variables can now be initialized with character or graphic literals without
using the %UCS2 built-in function.
- Eliminate unused variables from the compiled object
- New values *UNREF and *NOUNREF are added to the OPTION keyword for
the CRTBNDRPG and CRTRPGMOD commands, and for the OPTION
keyword on the Control specification. The default is *UNREF. *NOUNREF
indicates that unreferenced variables should not be generated into the RPG
module. This can reduce program size, and if imported variables are not
referenced, it can reduce the time taken to bind a module to a program or
service program.
- PCML can now be stored in the module
- Program Call Markup Language (PCML) can now be stored in the module as
well as in a stream file. By using combinations of the PGMINFO command
parameter and/or the new PGMINFO keyword for the Control specification, the
RPG programmer can choose where the PCML information should go. If the
PCML information is placed in the module, it can later be retrieved using the
QBNRPII API. This enhancement is also available through PTFs for V5R4, but
only through the Control specification keyword.
Table 3. Changed Language Elements Since V5R4
40
What's New in V5R4?
The following list describes the enhancements made to ILE RPG in V5R4:
- New operation code EVAL-CORR
- EVAL-CORR{(EH)} ds1 = ds2
New operation code EVAL-CORR assigns data and null-indicators from the
subfields of the source data structure to the subfields of the target data
structure. The subfields that are assigned are the subfields that have the same
name and compatible data type in both data structures.
For example, if data structure DS1 has character subfields A, B, and C, and
data structure DS2 has character subfields B, C, and D, statement EVAL-
CORR DS1 = DS2; will assign data from subfields DS2.B and DS2.C to DS1.B
and DS1.C. Null-capable subfields in the target data structure that are affected
by the EVAL-CORR operation will also have their null-indicators assigned from
the null-indicators of the source data structure's subfields, or set to *OFF, if the
source subfield is not null-capable.
// DS1 subfields DS2 subfields
// s1 character s1 packed
// s2 character s2 character
// s3 numeric
// s4 date s4 date
// s5 character
// Other subfields either appear in only one data structure (S3 and S5)
EVAL-CORR makes it easier to use result data structures for I/O operations to
externally-described files and record formats, allowing the automatic transfer of
data between the data structures of different record formats, when the record
formats have differences in layout or minor differences in the types of the
subfields.
- New prototyped parameter option OPTIONS(*NULLIND)
-
When OPTIONS(*NULLIND) is specified for a parameter, the null-byte map is
passed with the parameter, giving the called procedure direct access to the
null-byte map of the caller's parameter.
- New builtin function %XML
- %XML (xmldocument { : options } )
The %XML builtin function describes an XML document and specifies options to
control how the document should be parsed. The xmldocument parameter can
be a character or UCS-2 expression, and the value may be an XML document
or the name of an IFS file containing an XML document. If the value of the
xmldocument parameter has the name of a file, the "doc=file" option must be
specified.
XML-INTO reads the data from an XML document in one of two ways:
- directly into a variable
- gradually into an array parameter that it passes to the procedure specified by
%HANDLER.
Various options may be specified to control the operation.
The first operand specifies the target of the parsed data. It can contain a
variable name or the % HANDLER built-in function.
The second operand contains the %XML builtin function specifying the source
of the XML document and any options to control how the document is parsed. It
can contain XML data or it can contain the location of the XML data. The doc
option is used to indicate what this operand specifies.
// Data structure "copyInfo" has two subfields, "from"
// <copyinfo>
// <from><name>MASTFILE</name><lib>CUSTLIB</lib></from>
42
// <to><name>MYFILE</name><lib>*LIBL</lib>
- Use the PREFIX keyword to remove characters from the beginning of field
names
- PREFIX('' : number_of_characters)
When an empty character literal (two single quotes specified with no intervening
characters) is specified as the first parameter of the PREFIX keyword for File
and Definition specifications, the specified number of characters is removed
from the field names. For example if a file has fields XRNAME, XRIDNUM, and
XRAMOUNT, specifying PREFIX('':2)on the File specification will cause the
internal field names to be NAME, IDNUM, and AMOUNT. If you have two files
whose subfields have the same names other than a file-specific prefix, you can
use this feature to remove the prefix from the names of the subfields of
externally-described data structures defined from those files. This would enable
you to use EVAL-CORR to assign the same-named subfields from one data
structure to the other. For example, if file FILE1 has a field F1NAME and file
FILE2 has a field F2NAME, and PREFIX('':2) is specified for externally-
described data structures DS1 for FILE1 and DS2 for FILE2, then the subfields
F1NAME and F2NAME will both become NAME. An EVAL-CORR operation
between data structures DS1 and DS2 will assign the NAME subfield.
- New values for the DEBUG keyword
- DEBUG { ( *INPUT *DUMP *XMLSAX *NO *YES ) }
The DEBUG keyword determines what debugging aids are generated into the
module. *NO and *YES are existing values. *INPUT, *DUMP and *XMLSAX
provide more granularity than *YES.
- *INPUT
- Fields that appear only on input specifications are read into the program
fields during input operations.
- *DUMP
- DUMP operations without the (A) extender are performed.
- *XMLSAX
- An array of SAX event names is generated into the module to be used
while debugging a SAX event handler.
- *NO
- Indicates that no debugging aids are to be generated into the module.
Specifying DEBUG(*NO) is the same as omitting the DEBUG keyword.
- *YES
- This value is kept for compatibility purposes. Specifying DEBUG(*YES) is
the same as specifying DEBUG without parameters, or DEBUG(*INPUT :
*DUMP).
- Syntax-checking for free-form calculations
-
In SEU, free-form statements are now checked for correct syntax.
- Improved debugging support for null-capable subfields of a qualified data
structure
43
- When debugging qualified data structures with null-capable subfields, the null-
indicators are now organized as a similar data structure with an indicator
subfield for every null-capable subfield. The name of the data structure is
_QRNU_NULL_data_structure_name, for example _QRNU_NULL_MYDS. If a
subfield of the data structure is itself a data structure with null-capable
subfields, the null- indicator data structure will similarly have a data structure
subfield with indicator subfields. For example, if data structure DS1 has null-
capable subfields DS1.FLD1, DS1.FLD2, and DS1.SUB.FLD3, you can display
all the null-indicators in the entire data structure using the debug instruction. ===>
EVAL _QRNU_NULL_DS
_QRNU_NULL_DS1.FLD1 = '1'
_QRNU_NULL_DS1.FLD2 = '0'
_QRNU_NULL_DS1.SUB.FLD3 = '1'
_QRNU_NULL_DS1.FLD2 = '0'
DSARR(1).FLD2 = 'abcde'
_QRNU_NULL_DSARR(1).FLD2 = '0'
44
Definition Indicates that the null
specification OPTIONS(*NULLIND indicator is passed
keywords ) with the parameter.
PREFIX('':2) An empty literal may
be specified as the
first parameter of the
PREFIX keyword,
allowing characters to
be removed from the
beginning of names.
Table 6. New Language Elements Since V5R3
45
What's New in V5R3?
The following list describes the enhancements made to ILE RPG in V5R3:
- New builtin function %SUBARR: New builtin function %SUBARR allows
assignment to a sub-array or returning a sub-array as a value.
Along with the existing %LOOKUP builtin function, this enhancements enables the
implementation of dynamically sized arrays with a varying number of elements.
%SUBARR(array : start) specifies array elements array(start) to the end of the
array
%SUBARR(array : start : num) specifies array elements array(start) to array(start +
num - 1)
Example:
// Copy part of an array to another array:
resultArr = %subarr(array1:start:num);
%subarr(Array1:x:y) = %subarr(Array2:m:n);
sorta %subarr(Array3:x:y);
sum = %xfoot(%subarr(Array4:x:y));
// now result = 'a-b-c'. All * - and . were trimmed from the ends of the data
%addr(data); proc (' xyz ' : ' @#$ ' : ' 123 ' : ' abc ' : ptr);
// parm3 = '123'
- Support for 63 digit packed and zoned decimal valuesPacked and zoned data
can be defined with up to 63 digits and 63 decimal positions. The previous limit
was 31 digits.
- Relaxation of the rules for using a result data structure for I/O to externally-
described files and record formats
- The result data structure for I/O to a record format may be an externally-
described data structure.
- A data structure may be specified in the result field for I/O to an externally-
described file name for operation codes CHAIN, READ, READE, READP and
READPE.
Examples:
1. The following program writes to a record format using from an externally-
described data structure. Foutfile o e k disk D
2. The following program reads from a multi-format logical file into data structure
INPUT which contains two overlapping subfields holding the fields of the
respective record formats. Flog if e k disk infds(infds)
D input ds qualified
dsply recname;
if recname = 'REC1';
// handle rec1
// handle rec2
Note that even with just one option, a terminating character is required. This
example uses the semicolon. 2. Specifying more than one option: If you also
want to set the os400.stdout option to a different value than the default, you could
set the environment variable to the following value:
'-Djava.version=1.4!-Dos400.stdout=file:mystdout.txt!'
This example uses the exclamation mark as the separator/terminator. Note: This
support is also available in V5R1 and V5R2 with PTFs. V5R1: SI10069, V5R2:
SI10101.
- QIBM_RPG_JAVA_EXCP_TRACE allows RPG users to get the exception trace
when an RPG call to a Java method ends with an exception This environment
variable can be set, changed, or removed at any time.
If this environment variable contains the value 'Y', then when a Java exception
occurs during a Java method call from RPG, or a called Java method throws an
exception to its caller, the Java trace for the exception will be printed. By default,
it will be printed to the screen, and may not be possible to read. To get it printed
to a file, set the Java option os400.stderr. (This would have to be done in a new
job; it could be done by setting the QIBM_RPG_JAVA_PROPERTIES
environment variable to
'-Dos400.stderr=file:stderr.txt;'
49
Language Unit Element Description
Built-in Functions %SUBARR(array:star Returns a section of
ting element the array, or allows a
{:number of section of the array to
elements}) be modified.
50
What's New in V5R2?
The following list describes the enhancements made to ILE RPG in V5R2:
- Conversion from character to numeric Built-in functions %DEC, %DECH, %INT,
%INTH, %UNS, %UNSH and %FLOAT are enhanced to allow character
parameters. For example, %DEC('-12345.67' : 7 : 2) returns the numeric value -
12345.67.
- Bitwise logical built-in functions %BITAND, %BITOR, %BITXOR and %BITNOT
allow direct bit manipulation within RPG expressions.
- Complex data structures Data structure definition is enhanced to allow arrays of
data structures and subfields of data structures defined with LIKEDS that are
themselves data structures. This allows the coding of complex structures such as
arrays of arrays, or arrays of structures containing subarrays of structures.
Example: family(f).child(i).hobbyInfo.pets(p).type = 'dog';
family(f).child(i).hobbyInfo.pets(p).name = 'Spot';
In addition, data structures can be defined the same as a record format, using the
new LIKEREC keyword.
- Enhanced externally-described data structures Externally-described data
structures can hold the programmer's choice of input, output, both, key or all fields.
Currently, externally-described data structures can only hold input fields.
- Enhancments to keyed I/O Programmers can specify search arguments in keyed
Input/Output operations in /FREE calculations in two new ways:
1. By specifying the search arguments (which can be expressions) in a list.
2. By specifying a data structure which contains the search arguments.
Examples: D custkeyDS e ds extname(custfile:*key)
/free
53
%KDS(data structure) Used in free-form keyed
operation codes CHAIN,
SETLL, SETGT, READE
and READPE, to indicate
that the keys for the
operation are in the data
structure.
54
What's New in V5R1?
The ILE RPG compiler is part of the IBM IBM Rational Development Studio for
System i product, which now includes the C/C++ and COBOL compilers, and the
Application Development ToolSet tools.
The major enhancements to RPG IV since V4R4 are easier interfacing with Java,
new built-in functions, free form calculation specifications, control of which file is
opened, qualified subfield names, and enhanced error handling.
The following list describes these enhancements:
- Improved support for calls between Java and ILE RPG using the Java Native
Interface (JNI):
- A new data type: Object
- A new definition specification keyword: CLASS
- The LIKE definition specification keyword has been extended to support objects.
- The EXTPROC definition specification keyword has been extended to support
Java procedures.
- New status codes.
- New built-in functions:
- Functions for converting a number into a duration that can be used in arithmetic
expressions: %MSECONDS, %SECONDS, %MINUTES, %HOURS, %DAYS,
%MONTHS, and %YEARS.
- The %DIFF function, for subtracting one date, time, or timestamp value from
another.
- Functions for converting a character string (or date or timestamp) into a date,
time, or timestamp: %DATE, %TIME, and %TIMESTAMP.
- The %SUBDT function, for extracting a subset of a date, time, or timestamp.
- Functions for allocating or reallocating storage: %ALLOC and %REALLOC.
- Functions for finding an element in an array: %LOOKUP, %LOOKUPGT,
%LOOKUPGE, %LOOKUPLT, and %LOOKUPLE.
- Functions for finding an element in a table: %TLOOKUP, %TLOOKUPGT,
%TLOOKUPGE, %TLOOKUPLT, and %TLOOKUPLE.
- Functions for verifying that a string contains only specified characters (or finding
the first or last exception to this rule): %CHECK and %CHECKR
- The %XLATE function, for translating a string based on a list of from-characters
and to-characters.
- The %OCCUR function, for getting or setting the current occurrence in a multiple-
occurrence data structure.
- The %SHTDN function, for determining if the operator has requested shutdown.
- The %SQRT function, for calculating the square root of a number.
- A new free-form syntax for calculation specifications. A block of free-form
calculation specifcations is delimited by the compiler directives /FREE and /END-
FREE
- You can specify the EXTFILE and EXTMBR keywords on the file specification to
control which external file is used when a file is opened.
- Support for qualified names in data structures:
- A new definition specification keyword: QUALIFIED. This keyword specifies that
subfield names will be qualified with the data structure name.
- A new definition specification keyword: LIKEDS. This keyword specifies that
subfields are replicated from another data structure. The subfield names will be
55
qualified with the new data structure name. LIKEDS is allowed for prototyped
parameters; it allows the parameter's subfields to be used directly in the called
procedure.
- The INZ definition specification keyword has been extended to allow a data
structure to be initialized based on its parent data structure.
- Enhanced error handling:
- Three new operation codes (MONITOR, ON-ERROR, and ENDMON) allow you
to define a group of operations with conditional error handling based on the status
code.
Other enhancements have been made to this release as well. These include:
- You can specify parentheses on a procedure call that has no parameters.
- You can specify that a procedure uses ILE C or ILE CL calling conventions, on the
EXTPROC definition specification keyword.
- The following /DEFINE names are predefined: *VnRnMn, *ILERPG,
*CRTBNDRPG, and *CRTRPGMOD.
- The search string in a %SCAN operation can now be longer than string being
searched. (The string will not be found, but this will no longer generate an error
condition.)
- The parameter to the DIM, OCCURS, and PERRCD keywords no longer needs to
be previously defined.
- The %PADDR built-in function can now take either a prototype name or an entry
point name as its argument.
- A new operation code, ELSEIF, combines the ELSE and IF operation codes
without requiring an additional ENDIF.
- The DUMP operation code now supports the A extender, which means that a
dump is always produced - even if DEBUG(*NO) was specified.
- A new directive, /INCLUDE, is equivalent to /COPY except that /INCLUDE is not
expanded by the SQL preprocessor. Included files cannot contain embedded SQL
or host variables.
- The OFLIND file-specification keyword can now take any indicator, including a
named indicator, as an argument.
- The LICOPT (licensed internal code options) keyword is now available on the
CRTRPGMOD and CRTBNDRPG commands.
- The PREFIX file description keyword can now take an uppercase character literal
as an argument. The literal can end in a period, which allows the file to be used
with qualified subfields.
- The PREFIX definition specification keyword can also take an uppercase character
literal as an argument. This literal cannot end in a period.
The following tables summarize the changed and new language elements, based on
the part of the language affected.
Table 11. Changed Language Elements Since V4R4
56
Built-in functions %CHAR(expression{:forma The optional second
t}) parameter specifies the
desired format for a date,
time, or timestamp. The
result uses the format and
separators of the specified
format, not the format and
separators of the input.
%PADDR(prototype-name) This function can now take
either a prototype name or
an entry point name as its
argument.
Definition specification EXTPROC(*JAVA:class- Specifies that a Java
keywords name:proc-name) method is called.
EXTPROC(*CL:proc- Specifies a procedure that
name) uses ILE CL conventions
for return values.
EXTPROC(*CWIDEN:proc Specifies a procedure that
-name) uses ILE C conventions
with parameter widening.
EXTPROC(*CNOWIDEN:p Specifies a procedure that
roc-name) uses ILE C conventions
without parameter
widening.
INZ(*LIKEDS) Specifies that a data
structure defined with the
LIKEDS keyword inherits
the initialization from its
parent data structure.
LIKE(object-name) Specifies that an object
has the same class as
another object.
PREFIX(character- Prefixes the subfields with
literal{:number}) the specified character
literal, optionally replacing
the specified number of
characters.
File specification keywords OFLIND(name) This keyword can now take
any named indicator as a
parameter.
PREFIX(character- Prefixes the subfields with
literal{:number}) the specified character
literal, optionally replacing
the specified number of
characters.
Operation codes DUMP (A) This operation code can
now take the A extender,
which causes a dump to be
produced even if
DEBUG(*NO) was
specified.
57
Table 12. New Language Elements Since V4R4
58
%DAYS(num) Converts the number to a
duration, in days.
%DIFF(op1:op2:unit) Calculates the difference
(duration) between two
date, time, or timestamp
values in the specified
units.
%HOURS(num) Converts the number to a
duration, in hours.
%LOOKUPxx(arg:array{:st Finds the specified
artindex {:numelems}}) argument, or the specified
type of near-match, in the
specified array.
%MINUTES(num) Converts the number to a
duration, in minutes.
%MONTHS(num) Converts the number to a
duration, in months.
%MSECONDS(num) Converts the number to a
duration, in microseconds.
%OCCUR(dsn-name) Sets or gets the current
position of a multiple-
occurrence data structure.
%REALLOC(pointer:numb Reallocates the specified
er) amount of storage for the
specified pointer.
%SECONDS(num) Converts the number to a
duration, in seconds.
%SHTDN Checks if the system
operator has requested
shutdown.
%SQRT(numeric- Calculates the square root
expression) of the specified number.
%SUBDT(value:unit) Extracts the specified
portion of a date, time, or
timestamp value.
%THIS Returns an Object value
that contains a reference to
the class instance on
whose behalf the native
method is being called.
%TIME(expression{:time- Converts the expression to
format}) a time.
%TIMESTAMP(expression Converts the expression to
{:*ISO|*ISO0}) a timestamp.
%TLOOKUP(arg:search- Finds the specified
table {:alt-table}) argument, or the specified
type of near-match, in the
specified table.
59
%XLATE(from:to:string{:st Translates the specified
artpos}) string, based on the from-
string and to-string.
%YEARS(num) Converts the number to a
duration, in years.
Operation codes MONITOR Begins a group of
operations with conditional
error handling.
ON-ERROR Performs conditional error
handling, based on the
status code.
ENDMON Ends a group of operations
with conditional error
handling.
ELSEIF Equivalent to an ELSE
operation code followed by
an IF operation code.
CRTBNDRPG and LICOPT(options) Specifies Licensed Internal
CRTRPGMOD keywords Code options.
60
What's New in V4R4?
The major enhancements to RPG IV since V4R2 are the support for running ILE
RPG modules safely in a threaded environment, the new 3-digit and 20-digit signed
and unsigned integer data types, and support for a new Universal Character Set
Version 2 (UCS-2) data type and for conversion between UCS-2 fields and graphic
or single-byte character fields.
The following list describes these enhancements:
- Support for calling ILE RPG procedures from a threaded application, such as
Domino® or Java™.
- The new control specification keyword THREAD(*SERIALIZE) identifies modules
that are enabled to run in a multithreaded environment. Access to procedures in
the module is serialized.
- Support for new 1-byte and 8-byte integer data types: 3I and 20I signed integer,
and 3U and 20U unsigned integer
- These new integer data types provide you with a greater range of integer values
and can also improve performance of integer computations, taking full advantage
of the 64-bit AS/400 RISC processor.
- The new 3U type allows you to more easily communicate with ILE C procedures
that have single-byte character (char) return types and parameters passed by
value.
- The new INTPREC control specification keyword allows you to specify 20-digit
precision for intermediate values of integer and unsigned binary arithmetic
operations in expressions.
- Built-in functions %DIV and %REM have been added to support integer division
and remainder operations.
- Support for new Universal Character Set Version 2 (UCS-2) or Unicode data type
- The UCS-2 (Unicode) character set can encode the characters for many written
languages. The field is a character field whose characters are two bytes long.
- By adding support for Unicode, a single application can now be developed for a
multinational corporation, minimizing the necessity to perform code page
conversion. The use of Unicode permits the processing of characters in multiple
scripts without loss of integrity.
- Support for conversions between UCS-2 fields and graphic or single-byte
character fields using the MOVE and MOVEL operations, and the new %UCS2
and %GRAPH built-in functions.
- Support for conversions between UCS-2 fields or graphic fields with different
Coded Character Set Identifiers (CCSIDs) using the EVAL, MOVE, and MOVEL
operations, and the new %UCS2 built-in function.
Other enhancements have been made to this release as well. These include:
- New parameters for the OPTION control specification keyword and on the create
commands:
- *SRCSTMT allows you to assign statement numbers for debugging from the
source IDs and SEU sequence numbers in the compiler listing. (The statement
number is used to identify errors in the compiler listing by the debugger, and to
identify the statement where a run-time error occurs.) *NOSRCSTMT specifies
that statement numbers are associated with the Line Numbers of the listing and
the numbers are assigned sequentially.
61
- Now you can choose not to generate breakpoints for input and output
specifications in the debug view with *NODEBUGIO. If this option is selected, a
STEP on a READ statement in the debugger will step to the next calculation,
rather than stepping through the input specifications.
- New special words for the INZ definition specification keyword:
- INZ(*EXTDFT) allows you to use the default values in the DDS for initializing
externally described data structure subfields.
- Character variables initialized by INZ(*USER) are initialized to the name of the
current user profile.
- The new %XFOOT built-in function sums all elements of a specified array
expression.
- The new EVALR operation code evaluates expressions and assigns the result to a
fixed-length character or graphic result. The assignment right-adjusts the data
within the result.
- The new FOR operation code performs an iterative loop and allows free-form
expressions for the initial, increment, and limit values.
- The new LEAVESR operation code can be used to exit from any point within a
subroutine.
- The new *NEXT parameter on the OVERLAY(name:*NEXT) keyword indicates that
a subfield overlays another subfield at the next available position.
- The new *START and *END values for the SETLL operation code position to the
beginning or end of the file.
- The ability to use hexadecimal literals with integer and unsigned integer fields in
initialization and free-form operations, such as EVAL, IF, etc.
- New control specification keyword OPENOPT{(*NOINZOFL | *INZOFL)} to indicate
whether the overflow indicators should be reset to *OFF when a file is opened.
- Ability to tolerate pointers in teraspace — a memory model that allows more than
16 megabytes of contiguous storage in one allocation.
The following tables summarize the changed and new language elements, based on
the part of the language affected.
Table 13. Changed Language Elements Since V4R2
62
Definition specification INZ(*EXTDFT) All externally described
keywords data structure subfields
can now be initialized to
the default values specified
in the DDS.
INZ(*USER) Any character field or
subfield can be initialized
to the name of the current
user profile.
OVERLAY(name:*NEXT) The special value *NEXT
indicates that the subfield
is to be positioned at the
next available position
within the overlayed field.
OPTIONS(*NOPASS The new
*OMIT *VARSIZE OPTIONS(*RIGHTADJ)
*STRING *RIGHTADJ) specified on a value or
constant parameter in a
function prototype
indicates that the
character, graphic, or
UCS-2 value passed as a
parameter is to be right
adjusted before being
passed on the procedure
call.
Definition specification 3 and 20 digits allowed for Added to the list of allowed
positions 33-39 (To I and U data types values for internal data
Position/Length) types to support 1-byte and
8-byte integer and
unsigned data.
Internal data type C (UCS-2 fixed or variable- Added to the list of allowed
length format) internal data types on the
definition specifications.
The UCS-2 (Unicode)
character set can encode
the characters for many
written languages. The
field is a character field
whose characters are two
bytes long.
Data format C (UCS-2 fixed or variable- UCS-2 format added to the
length format) list of allowed data formats
on the input and output
specifications for program
described files.
63
Command parameter OPTION *NOSRCSTMT,
*SRCSTMT,
*NODEBUGIO, and
*DEBUGIO have been
added to the OPTION
parameter on the
CRTBNDRPG and
CRTRPGMOD commands.
Table 14. New Language Elements Since V4R2
64
Built-in functions %DIV(n:m) Performs integer division
on the two operands n and
m; the result is the integer
portion of n/m. The
operands must be numeric
values with zero decimal
positions.
%GRAPH(char-expr | Converts to graphic data
graph-expr | UCS2-expr {: from single-byte character,
ccsid}) graphic, or UCS-2 data.
%REM(n:m) Performs the integer
remainder operation on
two operands n and m; the
result is the remainder of
n/m. The operands must
be numeric values with
zero decimal positions.
%UCS2(char-expr | graph- Converts to UCS-2 data
expr | UCS2-expr {: ccsid}) from single-byte character,
graphic, or UCS-2 data.
%XFOOT(array-expr) Produces the sum of all the
elements in the specified
numeric array expression.
Operation codes EVALR Evaluates an assignment
statement of the form
result=expression. The
result will be right-justified.
FOR Begins a group of
operations and indicates
the number of times the
group is to be processed.
The initial, increment, and
limit values can be free-
form expressions.
ENDFOR ENDFOR ends a group of
operations started by a
FOR operation.
LEAVESR Used to exit from
anywhere within a
subroutine.
65
What's New in V4R2?
The major enhancements to RPG IV since V3R7 are the support for variable-length
fields, several enhancements relating to indicators, and the ability to specify compile
options on the control specifications. These further improve the RPG product for
integration with the OS/400 operating system and ILE interlanguage communication.
The following list describes these enhancements:
- Support for variable-length fields This enhancement provides full support for
variable-length character and graphic fields. Using variable-length fields can
simplify many string handling tasks.
- Ability to use your own data structure for INDARA indicators Users can now access
logical data areas and associate an indicator data structure with each WORKSTN
and PRINTER file that uses INDARA, instead of using the *IN array for
communicating values to data management.
- Ability to use built-in functions instead of result indicators Built-in functions %EOF,
%EQUAL, %FOUND, and %OPEN have been added to query the results of
input/output operations. Built-in functions %ERROR and %STATUS, and the
operation code extender 'E' have been added for error handling.
- Compile options on the control specification Compile options, specified through the
CRTBNDRPG and CRTRPGMOD commands, can now be specified through the
control specification keywords. These compile options will be used on every
compile of the program.
In addition, the following new function has been added:
- Support for import and export of procedures and variables with mixed case names
- Ability to dynamically set the DECEDIT value at runtime
- Built-in functions %CHAR and %REPLACE have been added to make string
manipulation easier
- New support for externally defined *CMDY, *CDMY, and *LONGJUL date data
formats
- An extended range for century date formats
- Ability to define indicator variables
- Ability to specify the current data structure name as the parameter for the
OVERLAY keyword
- New status code 115 has been added to indicate variable-length field errors
- Support for application profiling
- Ability to handle packed-decimal data that is not valid when it is retrieved from files
using FIXNBR(*INPUTPACKED)
- Ability to specify the BNDDIR command parameter on the CRTRPGMOD
command.
The following tables summarize the changed and new language elements, based on
the part of the language affected.
Table 15. Changed Language Elements Since V3R7
67
ALWNULL(*NO | The ALWNULL keyword
*INPUTONLY | *USRCTL) specifies how you will use
records containing null-
capable fields from
externally described
database files.
AUT(*LIBRCRTAUT | *ALL The AUT keyword
| *CHANGE | *USE | specifies the authority
*EXCLUDE | given to users who do not
'authorization-list-name') have specific authority to
the object, who are not on
the authorization list, and
whose user group has no
specific authority to the
object.
BNDDIR( 'binding - The BNDDIR keyword
directory-name' {:'binding- specifies the list of binding
directory-name'...}) directories that are used in
symbol resolution.
CVTOPT(*{NO}DATETIME The CVTOPT keyword is
*{NO}GRAPHIC used to determine how the
*{NO}VARCHAR ILE RPG compiler handles
*{NO}VARGRAPHIC) date, time, timestamp,
graphic data types, and
variable-length data types
that are retrieved from
externally described
database files.
DFTACTGRP(*YES | *NO) The DFTACTGRP keyword
specifies the activation
group in which the created
program will run when it is
called.
ENBPFRCOL(*PEP | The ENBPFRCOL keyword
*ENTRYEXIT | *FULL) specifies whether
performance collection is
enabled.
FIXNBR(*{NO}ZONED The FIXNBR keyword
*{NO}INPUTPACKED) specifies whether decimal
data that is not valid is
fixed by the compiler.
GENLVL(number) The GENLVL keyword
controls the creation of the
object.
INDENT(*NONE | The INDENT keyword
'character-value') specifies whether
structured operations
should be indented in the
source listing for enhanced
readability.
68
LANGID(*JOBRUN | *JOB The LANGID keyword
| 'language-identifier') indicates which language
identifier is to be used
when the sort sequence is
*LANGIDUNQ or
*LANGIDSHR.
OPTIMIZE(*NONE | The OPTIMIZE keyword
*BASIC | *FULL) specifies the level of
optimization, if any, of the
object.
OPTION(*{NO}XREF The OPTION keyword
*{NO}GEN *{NO}SECLVL specifies the options to use
*{NO}SHOWCPY when the source member
*{NO}EXPDDS *{NO}EXT is compiled.
*{NO}SHOWSKP)
PRFDTA(*NOCOL | *COL) The PRFDTA keyword
specifies whether the
collection of profiling data
is enabled.
SRTSEQ(*HEX | *JOB | The SRTSEQ keyword
*JOBRUN | *LANGIDUNQ specifies the sort sequence
| *LANGIDSHR | 'sort- table that is to be used in
table-name') the ILE RPG source
program.
TEXT(*SRCMBRTXT | The TEXT keyword allows
*BLANK | 'description') you to enter text that briefly
describes the object and its
function.
TRUNCNBR(*YES | *NO) The TRUNCNBR keyword
specifies if the truncated
value is moved to the
result field or if an error is
generated when numeric
overflow occurs while
running the object.
USRPRF(*USER | The USRPRF keyword
*OWNER) specifies the user profile
that will run the created
program object.
File Description INDDS( The INDDS keyword lets
Specification keywords data_structure_name) you associate a data
structure name with the
INDARA indicators for a
workstation or printer file.
Definition specification VARYING Defines variable-length
keywords fields when specified on
character data or graphic
data.
Built-in functions %CHAR(graphic, date, Returns the value in a
time or timestamp character data type.
expression)
69
%EOF{file name} Returns '1' if the most
recent file input operation
or write to a subfile (for a
particular file, if specified)
ended in an end-of-file or
beginning-of-file condition;
otherwise, it returns '0'.
%EQUAL{file name} Returns '1' if the most
recent SETLL (for a
particular file, if specified)
or LOOKUP operation
found an exact match;
otherwise, it returns '0'.
%ERROR Returns '1' if the most
recent operation code with
extender 'E' specified
resulted in an error;
otherwise, it returns '0'.
%FOUND{file name} Returns '1' if the most
recent relevant operation
(for a particular file, if
specified) found a record
(CHAIN, DELETE, SETGT,
SETLL), an element
(LOOKUP), or a match
(CHECK, CHECKR and
SCAN); otherwise, it
returns '0'.
%OPEN(file name) Returns '1' if the specified
file is open and '0' if the
specified file is closed.
%REPLACE(replacement Returns the string
string: source string {:start produced by inserting a
position {:source length to replacement string into a
replace}}) source string, starting at
the start position and
replacing the specified
number of characters.
%STATUS{file name} If no program or file error
occurred since the most
recent operation code with
extender 'E' specified, it
returns 0. If an error
occurred, it returns the
most recent value set for
any program or file status.
If a file is specified, the
value returned is the most
recent status for that file.
70
Operation code Extender E Allows for error handling
using the %ERROR and
%STATUS built-in
functions on the CALLP
operation and all
operations that allow error
indicators.
New century formats *CMDY (cmm/dd/yy) To be used by the MOVE,
MOVEL, and TEST
operations.
*CDMY (cdd/mm/yy) To be used by the MOVE,
MOVEL, and TEST
operations.
New 4-digit year format *LONGJUL (yyyy/ddd) To be used by the MOVE,
MOVEL, and TEST
operations.
Command parameters PRFDTA The PRFDTA parameter
specifies whether the
collection of profiling data
is enabled.
BNDDIR The BNDDIR parameter
was previously only
allowed on the
CRTBNDRPG command
and not on the
CRTRPGMOD command,
now it is allowed on both
commands.
71
What's New in V3R7?
The major enhancements to RPG IV since V3R6 are the new support for database
null fields, and the ability to better control the precision of intermediate results in
expressions. Other enhancements include the addition of a floating point data type
and support for null-terminated strings. These further improve the RPG product for
integration with the OS/400 operating system and ILE interlanguage communication.
This means greater flexibility for developing applications.
The following is a list of these enhancements including a number of new built-in
functions and usability enhancements:
- Support for database null fields This enhancement allows users to process
database files which contain null-capable fields, by allowing these fields to be
tested for null and set to null.
- Expression intermediate result precision A new control specification keyword and
new operation code extenders on free-form expression specifications allow the
user better control over the precision of intermediate results.
- New floating point data type The new floating point data type has a much larger
range of values than other data types. The addition of this data type will improve
integration with the database and improve interlanguage communication in an ILE
environment, specifically with the C and C++ languages.
- Support for null terminated strings The new support for null terminated strings
improves interlanguage communication. It allows users full control over null
terminated data by allowing users to define and process null terminated strings,
and to conveniently pass character data as parameters to procedures which
expect null terminated strings.
- Pointer addition and subtraction Free-form expressions have been enhanced to
allow adding an offset to a pointer, subtracting an offset from a pointer, and
determining the difference between two pointers.
- Support for long names Names longer than 10 characters have been added to the
RPG language. Anything defined on the definition or procedure specifications can
have a long name and these names can be used anywhere where they fit within
the bounds of an entry. In addition, names referenced on any free-form
specification may be continued over multiple lines.
- New built-in functions A number of new built-in functions have been added to the
language which improve the following language facilities:
- editing (%EDITW, %EDITC, %EDITFLT)
- scanning strings (%SCAN)
- type conversions (%INT, %FLOAT, %DEC, %UNS)
- type conversions with half-adjust (%INTH, %DECH, %UNSH)
- precision of intermediate results for decimal expressions (%DEC)
- length and decimals of variables and expressions (%LEN, %DECPOS)
- absolute value (%ABS)
- set and test null-capable fields (%NULLIND)
- handle null terminated strings (%STR)
- Conditional compilation RPG IV has been extended to support conditional
compilation. This support will include the following:
- defining conditions (/DEFINE, /UNDEFINE),
- testing conditions (/IF, /ELSEIF, /ELSE, /ENDIF)
72
- stop reading current source file (/EOF)
- a new command option (DEFINE) to define up to 32 conditions on the
CRTBNDRPG and CRTRPGMOD commands.
- Date enhancements Several enhancements have been made to improve date
handling operations. The TIME operation code is extended to support Date, Time
or Timestamp fields in the result field. Moving dates or times from and to character
fields no longer requires separator characters. Moving UDATE and *DATE fields
no longer requires a format code to be specified. Date fields can be initialized to
the system (*SYS) or job (*JOB) date on the definition specifications.
- Character comparisons with alternate collating sequence Specific character
variables can be defined so that the alternate collating sequence is not used in
comparisons.
- Nested /COPY members You can now nest /COPY directives. That is, a /COPY
member may contain one (or more) /COPY directives which can contain further
/COPY directives and so on.
- Storage management You can now use the new storage management operation
codes to allocate, reallocate and deallocate storage dynamically.
- Status codes for storage management and float underflow errors. Two status
codes 425 and 426 have been added to indicate storage management errors.
Status code 104 was added to indicate that an intermediate float result is too small.
The following tables summarize the changed and new language elements, based on
the part of the language affected.
Table 17. Changed Language Elements Since V3R6
73
Data format F (Float format) Added to the list of allowed
data formats on the input
and output specifications
for program described files.
Table 18. New Language Elements Since V3R6
75
What's New in V3R6/V3R2?
The major enhancement to RPG IV since V3R1 is the ability to code a module with
more than one procedure. What does this mean? In a nutshell, it means that you
can code an module with one or more prototyped procedures, where the
procedures can have return values and run without the use of the RPG cycle.
Writing a module with multiple procedures enhances the kind of applications you
can create. Any application consists of a series of logical units that are conceived to
accomplish a particular task. In order to develop applications with the greatest
flexibility, it is important that each logical unit be as independent as possible.
Independent units are:
- Easier to write from the point of view of doing a specific task.
- Less likely to change any data objects other than the ones it is designed to
change.
- Easier to debug because the logic and data items are more localized.
- Maintained more readily since it is easier to isolate the part of the application that
needs changing.
The main benefit of coding a module with multiple procedures is greater control and
better efficiency in coding a modular application. This benefit is realized in several
ways. You can now:
- Call procedures and programs by using the same call operation and syntax.
- Define a prototype to provide a check at compile time of the call interface.
- Pass parameters by value or by reference.
- Define a procedure that will return a value and call the procedure within an
expression.
- Limit access to data items by defining local definitions of variables.
- Code a module that does not make use of the cycle.
- Call a procedure recursively.
The run-time behavior of the main procedure in a module is the same as that of a
V3R1 procedure. The run-time behavior of any subsequent procedures differs
somewhat from a V3R1 program, most notably in the areas of procedure end and
exception handling. These differences arise because there is no cycle code that is
generated for these procedures.
Other enhancements have been made to for this release as well. These include:
- Support for two new integer data types: signed integer (I), and unsigned integer
(U) The use of the integer data types provides you with a greater range of values
than the binary data type. Integer data types can also improve performance of
integer computations.
- *CYMD support for the MOVE, MOVEL, and TEST operations You can now use
the *CYMD date format in certain operations to work with system values that are
already in this data format.
- Ability to copyright your programs and modules by using the COPYRIGHT keyword
on the control specification The copyright information that is specified using this
keyword becomes part of the DSPMOD, DSPPGM, or DSPSRVPGM information.
- User control of record blocking using keyword BLOCK You can request record
blocking of DISK or SEQ files to be done even when SETLL, SETGT, or CHAIN
operations are used on the file. You can also request that blocking not be done.
Use of blocking in these cases may significantly improve runtime performance.
76
- Improved PREFIX capability Changes to the PREFIX keyword for either file-
description and definition specifications allow you to replace characters in the
existing field name with the prefix string.
- Status codes for trigger program errors Two status codes 1223 and 1224 have
been added to indicate trigger program errors.
The following tables summarize the changed and new language elements, based on
the part of the language affected.
Table 19. Changed Language Elements Since V3R1
77
EXTPROC(name) Indicates the external
name of the prototyped
procedure
OPDESC Indicates whether
operational descriptors are
to be passed for the
prototyped bound call
OPTIONS(*NOPASS Specifies various options
*OMIT *VARSIZE) for prototyped parameters
STATIC Specifies that the local
variable is to use static
storage
VALUE Specifies that the
prototyped parameter is to
be passed by value
Built-in functions %PARMS Returns the number of
parameters passed on a
call
Operation codes CALLP Calls a prototyped program
or procedure
Specification type Procedure specification Signals the beginning and
end of a subprocedure
definition
Definition type PR Signals the beginning of a
prototype definition
PI Signals the beginning of a
procedure interface
definition
blank in positions 24-25 Defines a prototyped
parameter
78
RPG IV Concepts
This section describes some of the basics of RPG IV:
- Symbolic names
- Compiler directives
- RPG IV program cycle
- Indicators
- Error Handling
- Subprocedures
- General file considerations
79
Chapter 1. Symbolic Names and Reserved Words
The valid character set for the RPG IV language consists of:
- The letters A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
- RPG IV accepts lowercase letters in symbolic names but translates them to
uppercase during compilation
- The numbers 0 1 2 3 4 5 6 7 8 9
- The characters + - * , . ' & / $ # : @ _ > < = ( ) %
- The blank character
Note:
The $, #, and @ may appear as different symbols on some codepages. For more
information, see the iSeries Information Center globalization topic.
80
Symbolic Names
A symbolic name is a name that uniquely identifies a specific entity in a program or
procedure. In the RPG IV language, symbolic names are used for the following:
- Arrays (see Array Names)
- Conditional compile names (see Conditional Compile Names)
- Data structures (see Data Structure Names)
- Exception output records (see EXCEPT Names)
- Fields (see Field Names)
- Key field lists (see KLIST Names)
- Labels (see Labels)
- Named constants (see Named Constants)
- Parameter lists (see PLIST Names)
- Prototype names (see Prototype Names)
- Record names (see Record Names)
- Subroutines (see Subroutine Names)
- Tables (see Table Names).
The following rules apply to all symbolic names except for deviations noted in the
description of each symbolic name:
- The first character of the name must be alphabetic. This includes the characters $,
#, and @.
- The remaining characters must be alphabetic or numeric. This includes the
underscore (_).
- The name must be left-adjusted in the entry on the specification form except in
fields which allow the name to float (definition specification, keyword fields, and the
extended factor 2 field).
- A symbolic name cannot be an RPG IV reserved word.
-
A symbolic name can be from 1 to 4096 characters. The practical limits are
determined by the size of the entry used for defining the name. A name that is up
to 15 characters can be specified in the Name entry of the definition or procedure
specification. For names longer than 15 characters, use a continuation
specification. For more information, see Chapter 11. About Specifications.
- A symbolic name must be unique within the procedure in which it is defined.
81
Array Names
The following additional rule applies to array names:
- An array name in a standalone field cannot begin with the letters TAB. Array
names may begin with TAB if they are either prototyped parameters or data
structures defined with the DIM keyword.
82
Conditional Compile Names
The symbolic names used for conditional compilation have no relationship to other
symbolic names. For example, if you define a file called MYFILE, you may later use
/DEFINE to define condition name MYFILE, and you may also use /UNDEFINE to
remove condition name MYFILE. This has no effect on the file name MYFILE.
Conditional compile names can be up to 50 characters long.
83
Data Structure Names
A data structure is an area in storage and is considered to be a character field.
84
EXCEPT Names
An EXCEPT name is a symbolic name assigned to an exception output record.
The following additional rule applies to EXCEPT names:
- The same EXCEPT name can be assigned to more than one output record.
85
Field Names
The following additional rules apply to field names:
- A field name can be defined more than once if each definition using that name has
the same data type, the same length, and the same number of decimal positions.
All definitions using the same name refer to a single field (that is, the same area in
storage). However, it can be defined only once on the definition specification.
- A field can be defined as a data structure subfield only once unless the data
structure is qualified (defined with QUALIFIED or LIKEDS). In this case, when the
subfield is used, it must be qualified (specified in the form dsname.subfieldname).
- A subfield name cannot be specified as the result field on an *ENTRY PLIST
parameter.
86
KLIST Names
A KLIST name is a symbolic name assigned to a list of key fields.
87
Labels
A label is a symbolic name that identifies a specific location in a program (for
example, the name assigned to a TAG or ENDSR operation).
88
Named Constants
A named constant is a symbolic name assigned to a constant.
89
PLIST Names
A PLIST name is a symbolic name assigned to a list of parameters.
90
Prototype Names
A prototype name is a symbolic name assigned to a prototype definition. This
name must be used when calling a prototyped procedure or program. A prototype
maybe explicitly specified, or it may be implicitly generated by the compiler from the
procedure interface when the procedure is defined in the same module as the call.
91
Record Names
A record name is a symbolic name assigned to a record format in an externally
described file. The following additional rules apply to record names in an RPG IV
program:
- If the file is qualified, due to the QUALIFIED or LIKEFILE keyword on the File
specification, the record name is specified as a qualified name in the form
FILENAME.FMTNAME. The record name must be unique within the other record
names of the file.
- If the file is not qualified, the record name is specified without qualification in the
form FMTNAME. If the file is a global file, the record name must be unique within
the other global names. If the file is a local file in a subprocedure, the record name
must be unique within the other local names. Note:
See RENAME(Ext_format:Int_format) for information on how to handle the
situation where the record name conflicts with other names in your RPG program.
92
Subroutine Names
The name is defined in factor 1 of the BEGSR (begin subroutine) operation.
93
Table Names
The following additional rules apply to table names:
- A table name can contain from 3 to 10 characters.
- A table name must begin with the letters TAB.
- A table cannot be defined in a subprocedure.
94
RPG IV Words with Special Functions/Reserved Words
The RPG IV reserved words listed below have special functions within a program.
- The following reserved words allow you to access the job date, or a portion of it, to
be used in the program:
- UDATE
- *DATE
- UMONTH
- *MONTH
- UYEAR
- *YEAR
- UDAY
- *DAY
- The following reserved words can be used for numbering the pages of a report, for
record sequence numbering, or to sequentially number output fields:
- PAGE
- PAGE1-PAGE7
- Figurative constants are implied literals that allow specifications without referring to
length:
- *BLANK/*BLANKS
- *ZERO/*ZEROS
- *HIVAL
- *LOVAL
- *NULL
- *ON
- *OFF
- *ALLX'x1..'
- *ALLG'oK1K2i'
- *ALL'X..'
- The following reserved words are used for positioning database files. *START
positions to beginning of file and *END positions to end of file.
- *END
- *START
- The following reserved words allow RPG IV indicators to be referred to as data:
- *IN
- *INxx
- The following are special words used with date and time:
- *CDMY
- *CMDY
- *CYMD
- *DMY
- *EUR
- *HMS
- *ISO
- *JIS
- *JOB
- *JOBRUN
- *JUL
95
- *LONGJUL
- *MDY
- *SYS
- *USA
- *YMD
- The following are special words used with translation:
- *ALTSEQ
- *EQUATE
- *FILE
- *FTRANS
- *PLACE allows repetitive placement of fields in an output record. (See *PLACE for
more information.)
- *ALL allows all fields that are defined for an externally described file to be written
on output. (See Rules for Figurative Constants for more information on *ALL)
-
The following are special words used within expressions:
- AND
- NOT
- OR Note:
NOT can only be used within expressions. It cannot be used as a name
anywhere in the source.
97
User Date Special Words
The user date special words (UDATE, *DATE, UMONTH, *MONTH, UDAY, *DAY,
UYEAR, *YEAR) allow the programmer to supply a date for the program at run time.
The user date special words access the job date that is specified in the job
description. The user dates can be written out at output time; UDATE and *DATE
can be written out using the Y edit code in the format specified by the control
specification.
See Rules for User Date for more information.
98
Rules for User Date
Remember the following rules when using the user date:
- UDATE, when specified in positions 30 through 43 of the output specifications,
prints a 6-character numeric date field. *DATE, when similarly specified, prints an
8-character (4-digit year portion) numeric date field. These special words can be
used in three different date formats:
- Month/day/year
- Year/month/day
- Day/month/year
Use the DATEDIT keyword on the control specification to specify the date formats
of UDATE and *DATE:
99
PAGE, PAGE1-PAGE7
PAGE is used to number the pages of a report, to serially number the output
records in a file, or to sequentially number output fields. It does not cause a page
eject.
The eight possible PAGE fields (PAGE, PAGE1, PAGE2, PAGE3, PAGE4, PAGE5,
PAGE6, and PAGE7) may be needed for numbering different types of output pages
or for numbering pages for different printer files.
PAGE fields can be specified in positions 30 through 43 of the output specifications
or in the input or calculation specifications.
See Rules for PAGE, PAGE1-PAGE7 for more information.
100
Rules for PAGE, PAGE1-PAGE7
Remember the following rules when using the PAGE fields:
- When a PAGE field is specified in the output specifications, without being defined
elsewhere, it is assumed to be a four-digit, numeric field with zero decimal
positions.
- Page numbering, unless otherwise specified, starts with 0001; and 1 is
automatically added for each new page.
- To start at a page number other than 1, set the value of the PAGE field to one less
than the starting page number. For example, if numbering starts with 24, enter a 23
in the PAGE field. The PAGE field can be of any length but must have zero
decimal positions (see Figure 1).
- Page numbering can be restarted at any point in a job. The following methods can
be used to reset the PAGE field:
- Specify blank-after (position 45 of the output specifications).
- Specify the PAGE field as the result field of an operation in the calculation
specifications.
- Specify an output indicator in the output field specifications (see Figure 2). When
the output indicator is on, the PAGE field will be reset to 1. Output indicators
cannot be used to control the printing of a PAGE field, because a PAGE field is
always written.
- Specify the PAGE field as an input field as shown in Figure 1.
- Leading zeros are automatically suppressed (Z edit code is assumed) when a
PAGE field is printed unless an edit code, edit word, or data format (P/B/L/R in
position 52) has been specified. Editing and the data format override the
suppression of leading zeros. When the PAGE field is defined in input and
calculation specifications, it is treated as a field name in the output specifications
and zero suppression is not automatic.
Figure 1. Page Record Description
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................
I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr....
IINPUT PG 50 1 CP I 2 5 0PAGE
OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+...........................
O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat
OPRINT H L1 01 O 15 PAGE 1 75
101
Chapter 2. Compiler Directives
The compiler directive statements /FREE... /END-FREE denote a free-form
calculation specification block. The compiler directive statements /TITLE, /EJECT,
/SPACE, /COPY, and /INCLUDE allow you to specify heading information for the
compiler listing, to control the spacing of the compiler listing, and to insert records
from other file members during a compile. The conditional compilation directive
statements /DEFINE, /UNDEFINE, /IF, /ELSEIF, /ELSE, /ENDIF, and /EOF allow
you to select or omit source records. The compiler directive statements must
precede any compile-time array or table records, translation records, and alternate
collating sequence records (that is, ** records).
- /FREE... /END-FREE (Positions 7-11)
- /TITLE (Positions 7-12)
- /EJECT (Positions 7-12)
- /SPACE (Positions 7-12)
- /COPY or /INCLUDE
- Nested /COPY or /INCLUDE
- Conditional Compilation Directives
- Defining Conditions
- /DEFINE (Positions 7-13)
- /UNDEFINE (Positions 7-15)
- Condition Expressions
- Testing Conditions
- /IF Condition-Expression (Positions 7-9)
- /ELSEIF Condition-Expression (Positions 7-13)
- /ELSE (Positions 7-11)
- /ENDIF (Positions 7-12)
- Rules for Testing Conditions
- The /EOF Directive
- /EOF (Positions 7-10)
102
/FREE... /END-FREE (Positions 7-11)
- Positions
- Entry
- 7-11
- /FREE or /END-FREE
- 12-80
- Blank
The /FREE compiler directive specifies the beginning of a free-form calculation
specifications block. /END-FREE specifies the end of the block. Positions 12
through 80 must be blank. The remaining positions may be used for comments. See
Free-Form Syntax for information on using free-form statements.
103
/TITLE (Positions 7-12)
Use the compiler directive /TITLE to specify heading information (such as security
classification or titles) that is to appear at the top of each page of the compiler
listing. The following entries are used for /TITLE:
- Positions
- Entry
- 7-12
- /TITLE
- 13
- Blank
- 14-100
- Title information
A program can contain more than one /TITLE statement. Each /TITLE statement
provides heading information for the compiler listing until another /TITLE statement
is encountered. A /TITLE statement must be the first RPG specification encountered
to print information on the first page of the compiler listing. The information specified
by the /TITLE statement is printed in addition to compiler heading information.
The /TITLE statement causes a skip to the next page before the title is printed. The
/TITLE statement is not printed on the compiler listing.
104
/EJECT (Positions 7-12)
- Positions
- Entry
- 7-12
- /EJECT
- 13-49
- Blank
- 50-100
- Comments
Enter /EJECT in positions 7 through 12 to indicate that subsequent specifications
are to begin on a new page of the compiler listing. Positions 13 through 49 of the
/EJECT statement must be blank. The remaining positions may be used for
comments. If the spool file is already at the top of a new page, /EJECT will not
advance to a new page. /EJECT is not printed on the compiler listing.
105
/SPACE (Positions 7-12)
Use the compiler directive /SPACE to control line spacing within the source
section of the compiler listing. The following entries are used for /SPACE:
- Positions
- Entry
- 7-12
- /SPACE
- 13
- Blank
- 14-16
- A positive integer value from 1 through 112 that defines the number of lines to
space on the compiler listing. The number must be left-adjusted.
- 17-49
- Blank
- 50-100
- Comments
If the number specified in positions 14 through 16 is greater 112, 112 will be used as
the /SPACE value. If the number specified in positions 14 through 16 is greater than
the number of lines remaining on the current page, subsequent specifications begin
at the top of the next page.
/SPACE is not printed on the compiler listing, but is replaced by the specified line
spacing. The line spacing caused by /SPACE is in addition to the two lines that are
skipped between specification types.
106
/COPY or /INCLUDE
The /COPY and /INCLUDE directives have the same purpose and the same
syntax, but are handled differently by the SQL precompiler. If your program does not
have embedded SQL, you can freely choose which directive to use. If your program
has embedded SQL, see Using /COPY, /INCLUDE in Source Files with Embedded
SQL for information about which directive to use.
The /COPY and /INCLUDE compiler directives cause records from other files to be
inserted, at the point where the directive occurs, with the file being compiled. The
inserted files may contain any valid specification including /COPY and /INCLUDE up
to the maximum nesting depth specified by the COPYNEST keyword (32 when not
specified).
The following is a restriction on the implementation of the /COPY and /INCLUDE
compiler directives when using the Program Verifier:
- /COPY or /INCLUDE of the main source member is not allowed. This will result in
an error message, indicating that it was unable to open /COPY or /INCLUDE file.
/COPY and /INCLUDE files can be either physical files or IFS files. To specify a
physical file, code your /COPY and /INCLUDE statement in the following way :
- /COPY or /INCLUDE followed by exactly one space followed by the file name or
path
- when specifying a physical file, the library, file, and member name, can be in one
of these formats: libraryname/filename,membername
filename,membername
membername
Figure 3 shows some examples of the /COPY and /INCLUDE directive statements.
107
Figure 3. Examples of the /COPY and /INCLUDE Compiler Directive Statements
C/COPY MBR1 1
I/INCLUDE SRCFIL,MBR2 2
O/COPY SRCLIB/SRCFIL,MBR3 3
dir1/dir2/file.rpg 7 O/COPY "ifs file containing blanks" 8 O/COPY 'ifs file containing blanks' 8
- 1
- Copies from member MBR1 in source file QRPGLESRC. The current library list
is used to search for file QRPGLESRC. If the file is not found in the library list,
the search will proceed to the IFS, looking for file MBR1, MBR1.rpgle or
MBR1.rpgleinc in the include search path. See the IBM Rational Development
Studio for i: ILE RPG Programmer's Guide for information on using IFS source
files.
- 2
- Copies from member MBR2 in file SRCFIL. The current library list is used to
search for file SRCFIL. Note that the comma is used to separate the file name
from the member name. If the file is not found in the library list, the search will
proceed to the IFS, looking for file SRCFIL, MBR1 in the include search path,
possibly with the .rpgle or .rpgleinc suffixes.
- 3
- Copies from member MBR3 in file SRCFIL in library SRCLIB or from the IFS file
SRCFIL, MBR3 in directory SRCLIB.
- 4
- Copies from member "MBR¬3" in file "SRC>3" in library "SRCLIB!"
- 5
- Copies from the IFS file file.rpg in directory /dir1/dir2.
- 6
- Copies from file, or file.rpgleinc or file.rpgle in directory /dir1/dir2
- 7
- Copies from the IFS file file.rpg in directory dir1/dir2, searching for directory
dir1/dir2 using the IFS search path.
- 8
- Copies from a file whose name contains blanks.
108
Results of the /COPY or /INCLUDE during Compile
During compilation, the specified file members are merged into the program at the
point where the /COPY or /INCLUDE statement occurs. All members will appear in
the COPY member table.
109
Nested /COPY or /INCLUDE
Nesting of /COPY and /INCLUDE directives is allowed. A /COPY or /INCLUDE
member may contain one or more /COPY or /INCLUDE directives (which in turn
may contain further /COPY or /INCLUDE directives and so on). The maximum depth
to which nesting can occur can be set using the COPYNEST control specification
keyword. The default maximum depth is 32.
TIPYou must ensure that your nested /COPY or /INCLUDE files do not include each
other infinitely. Use conditional compilation directives at the beginning of your
/COPY or /INCLUDE files to prevent the source lines from being used more than
once.
For an example of how to prevent multiple inclusion, see Figure 4.
110
Using /COPY, /INCLUDE in Source Files with Embedded SQL
The /COPY and /INCLUDE directives are identical except that they are handled
differently by the SQL precompiler.
The way the /COPY and /INCLUDE directives are handled by the SQL precompiler
is different depending on the RPG preprocessor options parameter (RPGPPOPT)
specified on the CRTSQLRPGI command. Refer to "Coding SQL statements in ILE
RPG applications" in the Embedded SQL Programming topic or the CRTSQLRPGI
command in the CL topic for more information.
For more information about these directives, see /COPY or /INCLUDE.
111
Conditional Compilation Directives
The conditional compilation directive statements allow you to conditionally include or
exclude sections of source code from the compile.
- Condition-names can be added or removed from a list of currently defined
conditions using the defining condition directives /DEFINE and /UNDEFINE.
- Condition expressions DEFINED(condition-name) and NOT DEFINED(condition-
name) are used within testing condition /IF groups.
- Testing condition directives, /IF, /ELSEIF, /ELSE and /ENDIF, control which source
lines are to be read by the compiler.
- The /EOF directive tells the compiler to ignore the rest of the source lines in the
current source member.
112
Defining Conditions
Condition-names can be added to or removed from a list of currently defined
conditions using the defining condition directives /DEFINE and /UNDEFINE.
113
/DEFINE (Positions 7-13)
The /DEFINE compiler directive defines conditions for conditional compilation. The
entries in the condition-name area are free-format (do not have to be left justified).
The following entries are used for /DEFINE:
- Positions
- Entry
- 7 - 13
- /DEFINE
- 14
- Blank
- 15 - 80
- condition-name
- 81 - 100
- Comments
The /DEFINE directive adds a condition-name to the list of currently defined
conditions. A subsequent /IF DEFINED(condition-name) would be true. A
subsequent /IF NOT DEFINED(condition-name) would be false.
Note:
The command parameter DEFINE can be used to predefine up to 32 conditions on
the CRTBNDRPG and CRTRPGMOD commands.
114
/UNDEFINE (Positions 7-15)
Use the /UNDEFINE directive to indicate that a condition is no longer defined. The
entries in the condition-name area are free-format (do not have to be left justified).
- Positions
- Entry
- 7 - 15
- /UNDEFINE
- 16
- Blank
- 17 - 80
- condition-name
- 81 - 100
- Comments
The /UNDEFINE directive removes a condition-name from the list of currently
defined conditions. A subsequent /IF DEFINED(condtion-name) would be false. A
subsequent /IF NOT DEFINED(condition-name) would be true.
Note:
Any conditions specified on the DEFINE parameter will be considered to be defined
when processing /IF and /ELSEIF directives. These conditions can be removed
using the /UNDEFINE directive.
115
Predefined Conditions
Several conditions are defined for you by the RPG compiler. These conditions
cannot be used with /DEFINE or /UNDEFINE. They can only be used with /IF and
/ELSEIF.
- Conditions Relating to the Environment
- Conditions Relating to the Command Being Used
- Conditions Relating to the Target Release
116
Conditions Relating to the Environment
- *ILERPG
- This condition is defined if your program is being compiled by the ILE RPG IV
compiler (the compiler described in this document). * This module is to be
To learn what conditions are available with another version of the RPG IV
compiler, consult the reference for the compiler. For example, for VisualAge
RPG see VisualAge RPG Language Reference.
117
Conditions Relating to the Command Being Used
- *CRTBNDRPG
- This condition is defined if your program is being compiled by the
CRTBNDRPG command, which creates a program. /IF DEFINED(*CRTBNDRPG) H
DFTACTGRP(*NO) /ENDIF
- *CRTRPGMOD
- This condition is defined if your program is being compiled by the
CRTRPGMOD command, which creates a module. * This code might appear in a
/ENDIF
118
Conditions Relating to the Target Release
- *VxRxMx
- This condition is defined if your program is being compiled for a version that is
greater than or equal to the release in the condition, starting with *V4R4M0
(Version 4 Release 4 Modification 0). Use this condition if you will run the same
program on different target releases, and want to take advantage of features
that are not available in every release. Support for this condition is available
starting with *V4R4M0 systems with the appropriate PTF installed.
/IF DEFINED(*V5R1M0)
I/INCLUDE SRCFIL,MBR2/ELSE
119
Condition Expressions
A condition expression has one of the following forms:
- DEFINED(condition-name)
- NOT DEFINED(condition-name)
The condition expression is free-format but cannot be continued to the next line.
120
Testing Conditions
Conditions are tested using /IF groups, consisting of an /IF directive, followed by
zero or more /ELSEIF directives, followed optionally by an /ELSE directive, followed
by an /ENDIF directive.
Any source lines except compile-time data, are valid between the directives of an /IF
group. This includes nested /IF groups.
Note:
There is no practical limit to the nesting level of /IF groups.
121
/IF Condition-Expression (Positions 7-9)
The /IF compiler directive is used to test a condition expression for conditional
compilation. The following entries are used for /IF:
- Positions
- Entry
-7-9
- /IF
- 10
- Blank
- 11 - 80
- Condition expression
- 81 - 100
- Comments
If the condition expression is true, source lines following the /IF directive are
selected to be read by the compiler. Otherwse, lines are excluded until the next
/ELSEIF, /ELSE or /ENDIF in the same /IF group.
122
/ELSEIF Condition-Expression (Positions 7-13)
The /ELSEIF compiler directive is used to test a condition expression within an /IF
or /ELSEIF group. The following entries are used for /ELSEIF:
- Positions
- Entry
- 7 - 13
- /ELSEIF
- 14
- Blank
- 15 - 80
- Condition expression
- 81 - 100
- Comments
If the previous /IF or /ELSEIF was not satisfied, and the condition expression is true,
then source lines following the /ELSEIF directive are selected to be read.
Otherwise, lines are excluded until the next /ELSEIF, /ELSE or /ENDIF in the same
/IF group is encountered.
123
/ELSE (Positions 7-11)
The /ELSE compiler directive is used to unconditionally select source lines to be
read following a failed /IF or /ELSEIF test. The following entries are used for /ELSE:
- Positions
- Entry
- 7 - 11
- /ELSE
- 12 - 80
- Blank
- 81 - 100
- Comments
If the previous /IF or /ELSEIF was not satisfied, source lines are selected until the
next /ENDIF.
If the previous /IF or /ELSEIF was satisfied, source lines are excluded until the next
/ENDIF.
124
/ENDIF (Positions 7-12)
The /ENDIF compiler directive is used to end the most recent /IF, /ELSEIF or
/ELSE group. The following entries are used for /ENDIF:
- Positions
- Entry
- 7 - 12
- /ENDIF
- 13 - 80
- Blank
- 81 - 100
- Comments
Following the /ENDIF directive, if the matching /IF directive was a selected line, lines
are unconditionally selected. Otherwise, the entire /IF group was not selected, so
lines continue to be not selected.
125
Rules for Testing Conditions
- /ELSEIF, and /ELSE are not valid outside an /IF group.
- An /IF group can contain at most one /ELSE directive. An /ELSEIF directive cannot
follow an /ELSE directive.
- /ENDIF is not valid outside an /IF, /ELSEIF or /ELSE group.
- Every /IF must be matched by a subsequent /ENDIF.
- All the directives associated with any one /IF group must be in the same source
file. It is not valid to have /IF in one file and the matching /ENDIF in another, even if
the second file is in a nested /COPY. However, a complete /IF group can be in a
nested /COPY.
126
The /EOF Directive
The /EOF directive tells the compiler to ignore the rest of the source lines in the
current source member.
127
/EOF (Positions 7-10)
The /EOF compiler directive is used to indicate that the compiler should consider
that end-of-file has been reached for the current source file. The following entries
are used for /EOF:
- Positions
- Entry
- 7 - 10
- /EOF
- 11 - 80
- Blank
- 81 - 100
- Comments
/EOF will end any active /IF group that became active during the reading of the
current source member. If the /EOF was in a /COPY file, then any conditions that
that were active when the /COPY directive was read will still be active.
Note:
If excluded lines are being printed on the listing, the source lines will continue to be
read and listed after /EOF, but the content of the lines will be completely ignored by
the compiler. No diagnostic messages will ever be issued after /EOF.
TIPUsing the /EOF directive will enhance compile-time performance when an entire
/COPY member is to be used only once, but may be copied in multiple times. (This
is not true if excluded lines are being printed).
*-----------------------------------------------------------------
2 ....
*-----------------------------------------------------------------
*-----------------------------------------------------------------
D ..... /ENDIF
The first time this /COPY member is read, XYZ_COPIED will not be defined, so the
/EOF will not be considered.
The second time this member is read, XYZ_COPIED is defined, so the /EOF is
processed. The /IF DEFINED(XYZ_COPIED) ( 3 ) is considered ended, and the file
is closed. However, the /IF DEFINED(READ_XYZ) ( 1 ) from the main source
member is still active until its own /ENDIF ( 2 ) is reached.
128
Handling of Directives by the RPG Preprocessor
The handling of compiler directives by the RPG preprocessor depends on the
options specified on the PPGENOPT parameter on the compile command. There
are several actions the preprocessor can take on a particular directive:
- The directive may be kept in the generated source file (indicated by "keep" in the
table below)
- The directive may be removed from the generated source file (indicated by
"remove" in the table below)
- The directive may be kept in the generated source file, but as a comment
(indicated by "comment" in the table below)
In general, with option *RMVCOMMENT, only the directives neccessary for
successful compilation are output to the generated source file. With option
NORMVCOMMENT, the directives not necessary for successful compilation of the
generated source file are converted into comments.
The following table summarizes how each directive is handled by the preprocessor
for the various PPGENOPT parameter values:
129
Chapter 3. Procedures and the Program Logic
Cycle
A procedure is a collection of statements that can be called and run.
There are three kinds of procedures in RPG: regular subprocedures, linear-main
procedures and cycle-main procedures. RPG source programs can be compiled into
one of three kinds of modules depending on the types of procedures present, and as
indicated by the presence of the NOMAIN or MAIN keyword on the Control
specification: Cycle, Nomain, or Linear-main modules.
The term "subprocedure" is used to denote both regular subprocedures and linear-
main procedures.
An RPG source program can be divided into these sections which contain
procedures:
- Main source section: The source lines from the first line in the source program up
to the first Procedure specification. In a cycle module, this section may contain
calculation specifications (standard or free-form) which make up a cycle-main
procedure. A cycle-main procedure is implied even if there are no calculation
specifications in this section. This kind of procedure does not have Procedure-
Begin and Procedure-End specifications to identify it. A cycle module may be
designed without sub-procedures, and thus have no separate Procedure section.
- Procedure section: Zero or one linear-main procedures, and one or more regular
sub-procedures, defined within the source program. Each procedure begins with a
Procedure-Begin specification, and ends with a Procedure-End specification.
The linear-main procedure is indicated by the use of the MAIN keyword on a
Control specification, making it a special kind of sub-procedure.
130
Subprocedure Definition
A subprocedure is a procedure defined after the main source section.
A subprocedure differs from a cycle-main procedure in several respects, the main
difference being that a subprocedure does not (and cannot) use the RPG cycle
while running.
A subprocedure may have a corresponding prototype in the definition specifications
of the main source section. If specified, the prototype is used by the compiler to call
the program or procedure correctly, and to ensure that the caller passes the correct
parameters. If not specified, the prototype is implicitly generated from the
procedure interface.
TIPAlthough it is optional to specify a prototype within the module that defines the
procedure, it should not be considered optional when it is exported from the
module, and the procedure will be called from other RPG modules. In this case, a
prototype should be specified in a copy file and copied into the module that defines
the subprocedure and into every module that calls the subprocedure.
*-------------------------------------------------------------
*-------------------------------------------------------------
- 1
- A Prototype which specifies the name, return value if any, and parameters if
any. Since the procedure is not exported from this module, it is optional to
specify the prototype.
- 2
- A Begin-Procedure specification (B in position 24 of a procedure specification)
- 3
- A Procedure-Interface definition, which specifies the return value and
parameters, if any. The procedure interface must match the corresponding
prototype. The procedure-interface definition is optional if the subprocedure
does not return a value and does not have any parameters that are passed to it.
If the prototype had not been specified, the procedure-interface definition
would be used by the compiler to implicitly define the prototype.
131
- 4
- Other definition specifications of variables, constants and prototypes needed by
the subprocedure. These definitions are local definitions.
- 5
- Any calculation specifications, standard or free-form, needed to perform the
task of the procedure. The calculations may refer to both local and global
definitions. Any subroutines included within the subprocedure are local. They
cannot be used outside of the subprocedure. If the subprocedure returns a
value, then the subprocedure must contain a RETURN operation.
- 6
- An End-Procedure specification (E in position 24 of a procedure specification)
Except for the procedure-interface definition, which may be placed anywhere within
the definition specifications, a subprocedure must be coded in the order shown
above.
No cycle code is generated for subprocedures. Consequently, you cannot code:
- Prerun-time and compile-time arrays and tables
- *DTAARA definitions
- Total calculations
The calculation specifications are processed only once and the procedure returns at
the end of the calculation specifications. See Subprocedure Calculations for more
information.
A subprocedure may be exported, meaning that procedures in other modules in the
program can call it. To indicate that it is to be exported, specify the keyword
EXPORT on the Procedure-Begin specification. If not specified, the subprocedure
can only be called from within the module.
132
Procedure Interface Definition
If a prototyped procedure has call parameters or a return value, then it must have a
procedure interface definition. If a prototype has been specified for the procedure,
the procedure interface definition is a repeat of the prototype information within
the definition of a procedure. Otherwise, the procedure interface definition is used to
implicitly define the prototype for the procedure. The procedure interface definition
is used to declare the entry parameters for the procedure and to ensure that the
internal definition of the procedure is consistent with the external definition (the
prototype).
You specify a procedure interface by placing PI in the Definition-Type entry
(positions 24-25). Any parameter definitions, indicated by blanks in positions 24-25,
must immediately follow the PI specification. The procedure interface definition ends
with the first definition specification with non-blanks in positions 24-25 or by a non-
definition specification.
For more information on procedure interface definitions, see Procedure Interface.
133
Return Values
A procedure that returns a value is essentially a user-defined function, similar to a
built-in function. To define a return value for a subprocedure, you must
1. Define the return value on both the prototype and procedure-interface definitions
of the subprocedure.
2. Code a RETURN operation with an expression in the extended-factor 2 field that
contains the value to be returned.
You define the length and the type of the return value on the procedure-interface
specification (the definition specification with PI in positions 24-25). The following
keywords are also allowed:
- DATFMT(fmt)
- The return value has the date format specified by the keyword.
- DIM(N)
- The return value is an array with N elements.
- LIKE(name)
- The return value is defined like the item specified by the keyword.
- LIKEDS(name)
- The return value is a data structure defined like the data structure specified by
the keyword.
- LIKEREC(name{,type})
- The return value is a data structure defined like the record name specified by
the keyword.
- PROCPTR
- The return value is a procedure pointer.
- TIMFMT(fmt)
- The return value has the time format specified by the keyword.
To return the value to the caller, you must code a RETURN operation with an
expression containing the return value. The expression in the extended-factor 2 field
is subject to the same rules as an expression with EVAL. The actual returned value
has the same role as the left-hand side of the EVAL expression, while the extended
factor 2 of the RETURN operation has the same role as the right-hand side. You
must ensure that a RETURN operation is performed if the subprocedure has a
return value defined; otherwise an exception is issued to the caller of the
subprocedure.
134
Scope of Definitions
Any items defined within a subprocedure are local to the subprocedure. If a local
item is defined with the same name as a global data item, then any references to
that name inside the subprocedure use the local definition.
However, keep in mind the following:
- Subroutine names and tag names are known only to the procedure in which they
are defined, even those defined in the cycle-main procedure.
- All fields specified on input and output specifications are global. When a
subprocedure uses input or output specifications (for example, while processing a
read operation), the global name is used even if there is a local variable of the
same name.
When using a global KLIST or PLIST in a subprocedure some of the fields may
have the same names as local fields. If this occurs, the global field is used. This may
cause problems when setting up a KLIST or PLIST prior to using it.
For example, consider the following source.
Figure 6. Scope of Key Fields Inside a Module * Main procedure definitions
D Fld1 S 1A D Fld2 S 1A
* Define a global key field list with 2 fields, Fld1 and Fld2
KFLD Fld2
* Subprocedure Section
P Subproc B D Fld2 S 1A
* local_kl has one global kfld (fld1) and one local (fld2)
KFLD Fld2
* field of that name. local_kl uses the local Fld2 and so the
135
Subprocedures and Subroutines
A subprocedure is similar to a subroutine, except that a subprocedure offers the
following improvements:
- You can pass parameters to a subprocedure, even passing by value. This means
that the parameters used to communicate with subprocedures do not have to be
modifiable. Parameters that are passed by reference, as they are with programs,
must be modifiable, and so may be less reliable.
- The parameters passed to a subprocedure and those received by it are checked at
compile time for consistency. This helps to reduce run-time errors, which can be
more costly.
- You can use a subprocedure like a built-in function in an expression. When used
in this way, they return a value to the caller. This basically allows you to custom-
define any operators you might need in an expression.
- Names defined in a subprocedure are not visible outside the subprocedure. This
means that there is less chance of the procedure inadvertently changing a item
that is shared by other procedures. Furthermore, the caller of the procedure does
not need to know as much about the items used inside the subprocedure.
- You can call the subprocedure from outside the module, if it is exported.
- You can call subprocedures recursively.
- Procedures are defined on a different specification type, namely, procedure
specifications. This different type helps you to immediately recognize that you are
dealing with a separate unit.
If you do not require the improvements offered by subprocedures, you may want to
use a subroutine because an EXSR operation is usually faster than a call to a
subprocedure.
136
Program Flow in RPG Modules: Cycle Versus Linear
The ILE RPG compiler supplies part of the logic for an RPG module. Depending on
the type of module you choose, this supplied logic will control a large or small part of
the control flow of your module. By default, an RPG module will include the full RPG
Cycle, which begins with the *INIT phase and ends with the *TERM phase. The
other two types of RPG modules do not include the full RPG Cycle; the only remnant
of the RPG cycle is the module initialization, which is similar to the *INIT phase. The
ILE RPG compiler supplies additional implicit logic that is separate from the RPG
cycle; for example, the implicit opening and closing of local files in subprocedures.
All ILE RPG modules can have one or more procedures.
The three types of RPG modules are distinguished by the nature of the main
procedure in the module.
A program or a service program can consist of multiple modules, each of which can
have an RPG main procedure. If an RPG module is selected to be the program-
entry module of a program, then you call the main procedure using a program call. If
an RPG module is not the program-entry module of a program, or if it is a module in
a service program, then you call its main procedure using a bound call. Calling a
main procedure through a bound call is only available for cycle-main procedures; if a
module contains a linear-main procedure and that module is not selected to be a
program-entry module, than that procedure cannot be called.
- A module with a cycle-main procedure
- The module contains a cycle-main procedure and zero or more subprocedures.
The cycle-main procedure includes the logic for the full RPG cycle. A cycle-
main procedure can be called through a bound call, or through a program call.
See Cycle Module and Program Cycle for more information.
- A module with a linear-main procedure
- The module contains a linear-main procedure and zero or more ordinary
subprocedures. The linear-main procedure is identified by the MAIN keyword
on the Control specification. The main procedure itself is coded as a
subprocedure (with Procedure specifications). The linear-main procedure can
only be called through a program call; it cannot be called using a bound call.
Note:
Other than the way it is called, the linear-main procedure is considered to be a
subprocedure.
The module does not include the logic for the RPG cycle. See Linear Main
Module for more information.
- A module with no main procedure
- The NOMAIN keyword on the Control specification indicates that there is no
main procedure in the module. The module contains only subprocedures. The
module does not include the logic for the RPG cycle. This type of module
cannot be the program-entry module of a program, since it has no main
procedure.
See NOMAIN Module for more information.
137
Module Type Keyword Cycle Main Initialization Implicit
Features Procedure of global closing of
Allowed variables, global files
opening of and
files, and unlocking of
UDS data data areas
areas
Cycle-main Yes Implicitly When the When the
defined in first main
the main procedure in procedure
source the module ends with LR
section is called after on, or ends
the activation abnormally.
group is
created.Whe
n the main
procedure is
called, if the
main
procedure
previously
ended with
LR on, or
ended
abnormally.
Linear-main MAIN No Explicitly When the Never
defined with main
the MAIN procedure is
keyword and first called
Procedure after the
specification activation
s group is
created, or if
somehow a
sub-
procedure is
called first.
No main NOMAIN No None, When the Never
indicated by first
the presence procedure in
of the the module
NOMAIN is called after
keyword the activation
group is
created
138
Cycle Module
A cycle module has a cycle-main procedure which uses the RPG Program Cycle;
the procedure is implicitly specified in the main source section . (See Program Cycle
.) You do not need to code anything special to define the main procedure; it consists
of everything before the first Procedure specification. The parameters for the cycle-
main procedure can be coded using a procedure interface and an optional prototype
in the global Definition specifications, or using a *ENTRY PLIST in the cycle-main
procedure’s calculations.
The name of the cycle-main procedure must be the same as the name of the
module being created. You can either use this name for the prototype and
procedure interface, or specify this name in the EXTPROC keyword of the
prototype, or of the procedure interface, if the prototype is not specified.
Any procedure interface found in the global definitions is assumed to be the
procedure interface for the cycle-main procedure. If a prototype is specified, the
name is required for the procedure interface for the cycle-main procedure, and the
prototype with the matching name must precede the procedure interface in the
source.
In the following example, module CheckFile is created. Its cycle-main procedure has
three parameters:
1. A file name (input)
2. A library name (input)
3. An indicator indicating whether the file was found (output)
In this example, the procedure is intended to be called from another module, so a
prototype must be specified in a /COPY file.
/COPY file CHECKFILEC with the prototype for the cycle-main procedure:
D CheckFile PR D file 10a const D library 10a const
D found 1N
Module CheckFile:
/COPY CHECKFILEC D CheckFile PI D file 10a const D library
10a const D found 1N C ... code using parameters file, library and found
Using a *ENTRY PLIST, you would define the parameters this way:
D file S 10a const D library S 10a const D found S
You can also use a prototype and procedure interface to define your cycle-main
procedure as a program. In this case, you would specify the EXTPGM keyword for
the prototype. In this example, the program is intended to be called by other RPG
programs, so a prototype must be specified in a /COPY file.
/COPY file CHECKFILEC with the prototype for the program:
D CheckFile PR extpgm('CHECKFILE') D file 10a const D
In the module source, the procedure interface would be defined the same way.
In the following example, the program is not intended to be called by any other RPG
programs, so a prototype is not necessary. In this case, the EXTPGM keyword is
specified for the procedure interface. Since a prototype is not specified, a name is
not necessary for the procedure interface.
A procedure interface with the EXTPGM keyword:
139
F ... file specifications D PI extpgm('CUSTREPORT') D custfile
10a const D custlib 10a const ... code using the custfile and custlib
parameters
140
Use Caution Exporting Subprocedures in Cycle Modules
If a module contains both a cycle-main procedure and exported subprocedures, take
great care to ensure that the RPG cycle in the cycle-main procedure does not
adversely affect the global data, files, and data areas that the subprocedures are
using.
You must be aware of when files are opened and closed implicitly, when data areas
are locked and unlocked implicitly, and when global data is initialized or re-
initialized.
141
Potential Problem Situations
A cycle module having exported subprocedures introduces potential scenarios
where the cycle-main procedure initialization is performed at an unexpected time,
with the effect that has on files, data area locks, and global data then leading to
errors. An exported subprocedure can be called first in the module, from a
procedure outside the module, before the cycle-main procedure is called. If the
cycle-main procedure is then called, it will initialize at that time.
- If module initialization occurs because a subprocedure is the first procedure to be
called, and cycle-main procedure initialization occurs later, errors can occur if files
are already open or data areas are already locked.
- If a subprocedure calls the cycle-main procedure, global data may or may not be
reinitialized during the call, depending on the way the main procedure ended the
last time it was called. If the subprocedure is using any global data, this can cause
unexpected results.
- If the cycle-main procedure was last called and ended and implicitly closed the files
and unlocked the data areas, and an exported subroutine is then called from
outside the module, errors can occur if it expects those files to be open or data
areas to be locked.
142
Recommendations
Consider moving the cycle-main procedure logic into a subprocedure, and making
the module a NOMAIN module, or changing the cycle-main procedure to be a linear-
main procedure.
If you mix cycle-main procedures with exported subprocedures, ensure that your
cycle-main procedure is called first, before any subprocedures.
Do not allow cycle-main-procedure initialization to happen more than once, since
this would reinitialize your global data. The best way to prevent reinitialization is to
avoid using the LR indicator.
If you want to call your cycle-main procedure intermixed with your subprocedures,
you should declare all your files as USROPN and not use UDS data areas. Open
files and lock data areas as you need them, and close files and unlock data areas
when you no longer need them. You might consider having a subprocedure in the
module that will close any open files and unlock any locked data areas.
143
Linear Module
A module which specifies the MAIN or NOMAIN keyword on the Control
specification is compiled without incorporating the program cycle.
When the program cycle is not included in the module, you are restricted in terms of
what can be coded in the main source section. Specifically, you cannot code
specifications for:
- Primary and secondary files
- Heading, detail and total output
- Executable calculations, including the *INZSR Initialization subroutine
- *ENTRY PLIST
Instead you would code in the main source section:
- Full-procedural files
- Input specifications
- Definition specifications
- Declarative calculations such as DEFINE, KFLD, KLIST, PARM, and PLIST (but
not *ENTRY PLIST)
- Exception output
Caution: There is no implicit closing of global files or unlocking of data areas in a
linear module. These objects will remain open or locked until they are explicitly
closed or unlocked.
144
Linear Main Module
A module which has a program entry procedure but does not use the RPG Program
Cycle can be generated by specifying the MAIN keyword on the control
specification.
This type of module has one or more procedures, one of which is identified as the
main procedure. It does not allow specifications which relate to the RPG Program
Cycle.
See MAIN(main_procedure_name) for more information.
145
NOMAIN Module
You can code one or more subprocedures in a module without coding a main
procedure. Such a module is called a NOMAIN module, since it requires the
specification of the NOMAIN keyword on the control specification. No cycle code is
generated for the NOMAIN module.
TIPYou may want to consider converting all your Cycle modules to NOMAIN
modules except the ones that actually contain the program entry procedure for a
program, to reduce the individual size of those modules by eliminating the
unnecessary cycle code in each of those modules.
Note:
A module with NOMAIN specified will not have a program entry procedure.
Consequently you cannot use the CRTBNDRPG command to compile the source.
146
Module Initialization
Module initialization occurs when the first procedure (either the main procedure or a
subprocedure) is called.
A cycle module has an additional form of initialization which can occur repeatedly.
Cycle-main procedure initialization occurs when the cycle-main procedure is called
the first time. It also occurs on subsequent calls if the cycle-main procedure ended
abnormally or with LR on.
147
Initialization of Global Data
Global data in the module is initialized during module initialization and during cycle-
main procedure initialization.
For special concerns regarding initialization in cycle-main procedures, see Use
Caution Exporting Subprocedures in Cycle Modules.
148
RPG Cycle and other implicit Logic
The ILE RPG compiler supplies part of the logic for an RPG program.
- For a cycle-main procedure, the compiler supplies the program cycle; the program
cycle is also called the logic cycle or the RPG cycle
- For a subprocedure or linear-main procedure, the compiler supplies the
initialization and termination of the subprocedure.
149
Program Cycle
The ILE RPG compiler supplies part of the logic for an RPG program. For a cycle-
main procedure, the logic the compiler supplies is called the program cycle or logic
cycle. The program cycle is a series of ordered steps that the main procedure goes
through for each record read.
The information that you code on RPG IV specifications in your source program
need not explicitly specify when records should be read or written. The ILE RPG
compiler can supply the logical order for these operations when your source
program is compiled. Depending on the specifications you code, your program may
or may not use each step in the cycle.
Primary (identified by a P in position 18 of the file description specifications) and
secondary (identified by an S in position 18 of the file description specifications) files
indicate input is controlled by the program cycle. A full procedural file (identified by
an F in position 18 of the file description specifications) indicates that input is
controlled by program-specified calculation operations (for example, READ and
CHAIN).
To control the cycle, you can have:
- One primary file and, optionally, one or more secondary files
- Only full procedural files
- A combination of one primary file, optional secondary files, and one or more full
procedural files in which some of the input is controlled by the cycle, and other
input is controlled by the program.
- No files (for example, input can come from a parameter list or a data area data
structure).
Note:
No cycle code is generated for a module when MAIN or NOMAIN is specified on the
control specification. See Linear Module for more information.
150
General RPG IV Program Cycle
Figure 7 shows the specific steps in the general flow of the RPG IV program
cycle. A program cycle begins with step 1 and continues through step 7, then begins
again with step 1.
The first and last time a program goes through the RPG IV cycle differ somewhat
from the normal cycle. Before the first record is read the first time through the cycle,
the program resolves any parameters passed to it, writes the records conditioned by
the 1P (first page) indicator, does file and data initialization, and processes any
heading or detail output operations having no conditioning indicators or all negative
conditioning indicators. For example, heading lines printed before the first record is
read might consist of constant or page heading information or fields for reserved
words, such as PAGE and *DATE. In addition, the program bypasses total
calculations and total output steps on the first cycle.
During the last time a program goes through the cycle, when no more records are
available, the LR (last record) indicator and L1 through L9 (control level) indicators
are set on, and file and data area cleanup is done.
Figure 7. RPG IV Program Logic Cycle
- 1
- All heading and detail lines (H or D in position 17 of the output specifications)
are processed.
- 2
- The next input record is read and the record identifying and control level
indicators are set on.
- 3
- Total calculations are processed. They are conditioned by an L1 through L9 or
LR indicator, or an L0 entry.
- 4
- All total output lines are processed. (identified by a T in position 17 of the output
specifications).
- 5
- It is determined if the LR indicator is on. If it is on, the program is ended.
- 6
- The fields of the selected input records are moved from the record to a
processing area. Field indicators are set on.
- 7
151
- All detail calculations are processed (those not conditioned by control level
indicators in positions 7 and 8 of the calculation specifications) on the data from
the record read at the beginning of the cycle.
152
Detailed RPG IV Program Cycle
In General RPG IV Program Cycle, the basic RPG IV Logic Cycle was introduced.
The following figures provide a detailed explanation of the RPG IV Logic Cycle.
Figure 8. Detailed RPG IV Object Program Cycle
153
[ Top of Page | Previous Page | Next Page | Contents | Index ]
154
Detailed RPG IV Object Program Cycle
Figure 8 shows the specific steps in the detailed flow of the RPG IV program
cycle. The item numbers in the following description refer to the numbers in the
figure. Routines are flowcharted in Figure 11 and in Figure 9.
- 1
- The RT indicator is set off. If *ENTRY PLIST is specified the parameters are
resolved.
- 2
- RPG IV checks for the first invocation of the program. If it is the first invocation,
program initialization continues. If not, it moves the result field to factor 1 in the
PARM statements in *ENTRY PLIST and branches to step 5.
- 3
- The program is initialized at *INIT in the cycle. This process includes:
performing data structure and subfield initialization, setting user date fields;
opening global files; loading all data area data structures, arrays and tables;
moving the result field to factor 1 in the PARM statements in *ENTRY PLIST;
running the initialization subroutine *INZSR; and storing the structures and
variables for the RESET operation. Global files are opened in reverse order of
their specification on the File Description Specifications.
- 4
- Heading and detail lines (identified by an H or D in position 17 of the output
specifications) are written before the first record is read. Heading and detail
lines are always processed at the same time. If conditioning indicators are
specified, the proper indicator setting must be satisfied. If fetch overflow logic is
specified and the overflow indicator is on, the appropriate overflow lines are
written. File translation, if specified, is done for heading and detail lines and
overflow output. This step is the return point in the program if factor 2 of an
ENDSR operation contains the value *DETL.
- 5
- The halt indicators (H1 through H9) are tested. If all the halt indicators are off,
the program branches to step 8. Halt indicators can be set on anytime during
the program. This step is the return point in the program if factor 2 of an
ENDSR operation contains the value *GETIN.
- a.
- If any halt indicators are on, a message is issued to the user.
- b.
- If the response is to continue, the halt indicator is set off, and the program
returns to step 5. If the response is to cancel, the program goes to step 6.
- 6
- If the response is to cancel with a dump, the program goes to step 7; otherwise,
the program branches to step 36.
- 7
- The program issues a dump and branches to step 36 (abnormal ending).
- 8
- All record identifying, 1P (first page), and control level (L1 through L9)
indicators are set off. All overflow indicators (OA through OG, OV) are set off
unless they have been set on during preceding detail calculations or detail
output. Any other indicators that are on remain on.
155
- 9
- If the LR (last record) indicator is on, the program continues with step 10. If it is
not on, the program branches to step 11.
- 10
- The appropriate control level (L1 through L9) indicators are set on and the
program branches to step 29.
- 11
- If the RT indicator is on, the program continues with step 12; otherwise, the
program branches to step 14.
- 12
- Factor 2 is moved to the result field for the parameters of the *ENTRY PLIST.
- 13
- If the RT indicator is on (return code set to 0), the program returns to the caller.
- 14
- If a primary file is present in the program, the program continues with step 15;
otherwise, the program branches to step 29.
- 15
- During the first program cycle, the first record from the primary file and from
each secondary file in the program is read. File translation is done on the input
records. In other program cycles, a record is read from the last file processed.
If this file is processed by a record address file, the data in the record address
file defines the record to be retrieved. If lookahead fields are specified in the
last record processed, the record may already be in storage; therefore, no read
may be done at this time.
- 16
- If end of file has occurred on the file just read, the program branches to step 20.
Otherwise, the program continues with step 17.
- 17
- If a record has been read from the file, the record type and record sequence
(positions 17 through 20 of the input specifications) are determined.
- 18
- It is determined whether the record type is defined in the program, and if the
record sequence is correct. If the record type is undefined or the record
sequence is incorrect, the program continues with step 19; otherwise, the
program branches to step 20.
- 19
- The RPG IV exception/error handling routine receives control.
- 20
- It is determined whether a FORCE operation was processed on the previous
cycle. If a FORCE operation was processed, the program selects that file for
processing (step 21) and branches around the processing for match fields
(steps 22 and 23). The branch is processed because all records processed
with a FORCE operation are processed with the matching record (MR) indicator
off.
- 21
- If FORCE was issued on the previous cycle, the program selects the forced file
for processing after saving any match fields from the file just read. If the file
forced is at end of file, normal primary/secondary multifile logic selects the next
156
record for processing and the program branches to step 24.
- 22
- If match fields are specified, the program continues with step 23; otherwise, the
program branches to step 24.
- 23
- The match fields routine receives control. (For detailed information on the
match fields routine, see Match Fields Routine.)
- 24
- The LR (last record) indicator is set on when all records are processed from the
files that have an E specified in position 19 of the file description specifications
and all matching secondary records have been processed. If the LR indicator is
not set on, processing continues with step 26.
- 25
- The LR (last record) indicator is set on and all control level (L1 through L9)
indicators, and processing continues with step 29.
- 26
- The record identifying indicator is set on for the record selected for processing.
- 27
- It is determined whether the record selected for processing caused a control
break. A control break occurs when the value in the control fields of the record
being processed differs from the value of the control fields of the last record
processed. If a control break has not occurred, the program branches to step
29.
- 28
- When a control break occurs, the appropriate control level indicator (L1 through
L9) is set on. All lower level control indicators are set on. The program saves
the contents of the control fields for the next comparison.
- 29
- It is determined whether the total-time calculations and total-time output should
be done. Totals are always processed when the LR indicator is on. If no control
level is specified on the input specifications, totals are bypassed on the first
cycle and after the first cycle, totals are processed on every cycle. If control
levels are specified on the input specifications, totals are bypassed until after
the first record containing control fields has been processed.
- 30
- All total calculations conditioned by a control level entry (positions 7 and 8 of
the calculation specifications). are processed. This step is the return point in the
program if factor 2 of an ENDSR operation contains the value *TOTC.
- 31
- All total output is processed. If fetch overflow logic is specified and the overflow
indicator (OA through OG, OV) associated with the file is on, the overflow lines
are written. File translation, if specified, is done for all total output and overflow
lines. This step is the return point in the program if factor 2 of an ENDSR
operation contains the value *TOTL.
- 32
- If LR is on, the program continues with step 33; otherwise, the program
branches to step 41.
157
- 33
- The halt indicators (H1 through H9) are tested. If any halt indicators are on, the
program branches to step 36 (abnormal ending). If the halt indicators are off,
the program continues with step 34. If the RETURN operation code is used in
calculations, the program branches to step 33 after processing of that
operation.
- 34
- If LR is on, the program continues with step 35. If it is not on, the program
branches to step 38.
- 35
- RPG IV program writes all arrays or tables for which the TOFILE keyword has
been specified on the definition specification and writes all locked data area
data structures. Output arrays and tables are translated, if necessary.
- 36
- All open global files are closed. The RPG IV program also unlocks all data
areas that have been locked but not unlocked by the program. If factor 2 of an
ENDSR operation contains the value *CANCL, this step is the return point.
- 37
- The halt indicators (H1 through H9) are tested. If any halt indicators are on, the
program branches to step 39 (abnormal ending). If the halt indicators are off,
the program continues with step 38.
- 38
- The factor 2 fields are moved to the result fields on the PARMs of the *ENTRY
PLIST.
- 39
- The return code is set. 1 = LR on, 2 = error, 3 = halt.
- 40
- Control is returned to the caller.
Note:
Steps 32 through 40 constitute the normal ending routine. For an abnormal ending,
steps 34 through 35 are bypassed.
- 41
- It is determined whether any overflow indicators (OA through OG OV) are on. If
an overflow indicator is on, the program continues with step 42; otherwise, the
program branches to step 43.
- 42
- The overflow routine receives control. (For detailed information on the overflow
routine, see Overflow Routine.) This step is the return point in the program if
factor 2 of an ENDSR operation contains the value *OFL.
- 43
- The MR indicator is set on and remains on for the complete cycle that
processes the matching record if this is a multifile program and if the record to
be processed is a matching record. Otherwise, the MR indicator is set off.
- 44
158
- Data from the last record read is made available for processing. Field indicators
are set on, if specified.
- 45
- If lookahead fields are specified, the program continues with step 46; otherwise,
the program branches to step 47.
- 46
- The lookahead routine receives control. (For detailed information on the
lookahead routine, see Lookahead Routine.)
- 47
- Detail calculations are processed. This step is the return point in the program if
factor 2 of an ENDSR operation contains the value *DETC. The program
branches to step 4.
159
Initialization Subroutine
Refer to Figure 8 to see a detailed explanation of the RPG IV initialization
subroutine.
The initialization subroutine allows you to process calculation specifications before
1P output. A specific subroutine that is to be run at program initialization time can be
defined by specifying *INZSR in factor 1 of the subroutine's BEGSR operation. Only
one subroutine can be defined as an initialization subroutine. It is called at the end
of the program initialization step of the program cycle (that is, after data structures
and subfields are initialized, external indicators and user data fields are retrieved,
global files are opened, data area data structures, arrays, and tables are loaded,
and PARM result fields moved to factor 1 for *ENTRY PLIST). *INZSR may not be
specified as a file/program error/exception subroutine.
If a program ends with LR off, the initialization subroutine does not automatically run
during the next invocation of that program because the subroutine is part of the
initialization step of the program. However, if the initialization subroutine does not
complete before an exit is made from the program with LR off, the initialization
subroutine will be re-run at the next invocation of that program.
The initialization subroutine is like any other subroutine in the program, other than
being called at program initialization time. It may be called using the EXSR or
CASxx operations, and it may call other subroutines or other programs. Any
operation that is valid in a subroutine is valid in the initialization subroutine, with the
exception of the RESET operation. This is because the value used to reset a
variable is not defined until after the initialization subroutine is run.
Any changes made to a variable during the initialization subroutine affect the value
that the variable is set to on a subsequent RESET operation. Default values can be
defined for fields in record formats by, for example, setting them in the initialization
subroutine and then using RESET against the record format whenever the default
values are to be used. The initialization subroutine can also retrieve information
such as the current time for 1P output.
There is no *INZSR associated with subprocedures. If a subprocedure is the first
procedure called in a module, the *INZSR of the main procedure will not be run,
although other initialization of global data will be done. The *INZSR of the main
procedure will be run when the main procedure is called.
Figure 9. Detail Flow of RPG IV Match Fields, Overflow, and Lookahead Routines
160
[ Top of Page | Previous Page | Next Page | Contents | Index ]
161
Match Fields Routine
Figure 9 shows the specific steps in the RPG IV match fields routine. The item
numbers in the following descriptions refer to the numbers in the figure.
- 1
- If multifile processing is being used, processing continues with step 2;
otherwise, the program branches to step 3.
- 2
- The value of the match fields in the hold area is tested to determine which file is
to be processed next.
- 3
- The RPG IV program extracts the match fields from the match files and
processes sequence checking. If the match fields are in sequence, the
program branches to step 5.
- 4
- If the match fields are not in sequence, the RPG IV exception/error handling
routine receives control.
- 5
- The match fields are moved to the hold area for that file. A hold area is
provided for each file that has match fields. The next record is selected for
processing based on the value in the match fields.
162
Overflow Routine
Figure 9 shows the specific steps in the RPG IV overflow routine. The item
numbers in the following descriptions refer to the numbers in the figure.
- 1
- The RPG IV program determines whether the overflow lines were written
previously using the fetch overflow logic (step 30 in Figure 8). If the overflow
lines were written previously, the program branches to the specified return
point; otherwise, processing continues with step 2.
- 2
- All output lines conditioned with an overflow indicator are tested and written to
the conditioned overflow lines.
The fetch overflow routine allows you to alter the basic RPG IV overflow logic to
prevent printing over the perforation and to let you use as much of the page as
possible. During the regular program cycle, the RPG IV program checks only once,
immediately after total output, to see if the overflow indicator is on. When the fetch
overflow function is specified, the RPG IV program checks overflow on each line for
which fetch overflow is specified.
Specify fetch overflow with an F in position 18 of the output specifications on any
detail, total, or exception lines for a PRINTER file. The fetch overflow routine does
not automatically cause forms to advance to the next page.
During output, the conditioning indicators on an output line are tested to determine
whether the line is to be written. If the line is to be written and an F is specified in
position 18, the RPG IV program tests to determine whether the overflow indicator is
on. If the overflow indicator is on, the overflow routine is fetched and the following
operations occur:
- Only the overflow lines for the file with the fetch specified are checked for output.
- All total lines conditioned by the overflow indicator are written.
- Forms advance to a new page when a skip to a line number less than the line
number the printer is currently on is specified in a line conditioned by an overflow
indicator.
- Heading, detail, and exception lines conditioned by the overflow indicator are
written.
- The line that fetched the overflow routine is written.
- Any detail and total lines left to be written for that program cycle are written.
Position 18 of each OR line must contain an F if the overflow routine is to be used
for each record in the OR relationship. Fetch overflow cannot be used if an overflow
indicator is specified in positions 21 through 29 of the same specification line. If this
occurs, the overflow routine is not fetched.
Use the fetch overflow routine when there is not enough space left on the page to
print the remaining detail, total, exception, and heading lines conditioned by the
overflow indicator. To determine when to fetch the overflow routine, study all
possible overflow situations. By counting lines and spaces, you can calculate what
happens if overflow occurs on each detail, total, and exception line.
163
Lookahead Routine
Figure 9 shows the specific steps in the RPG IV lookahead routine. The item
numbers in the following descriptions refer to the numbers in the figure.
- 1
- The next record for the file being processed is read. However, if the file is a
combined or update file (identified by a C or U, respectively, in position 17 of
the file description specifications), the lookahead fields from the current record
being processed is extracted.
- 2
- The lookahead fields are extracted.
164
Ending a Program without a Primary File
If your program does not contain a primary file, you must specify a way for the
program to end:
- By setting the LR indicator on
- By setting the RT indicator on
- By setting an H1 through H9 indicator on
- By specifying the RETURN operation code
The LR, RT, H1 through H9 indicators, and the RETURN operation code, can be
used in conjunction with each other.
165
Program Control of File Processing
Specify a full procedural file (F in position 18 of the file description specifications)
to control all or partial input of a program. A full procedural file indicates that input is
controlled by program-specified calculation operations (for example, READ, CHAIN).
When both full procedural files and a primary file (P in position 18 of the file
description specifications) are specified in a program, some of the input is controlled
by the program, and other input is controlled by the cycle. Even if the program cycle
exists in your module, all the processing of a full-procedural file is done in your
calculations.
The file operation codes can be used for program control of input. These file
operation codes are discussed in File Operations.
Figure 10. Programmer Control of Input Operation within the Program-Cycle
166
167
[ Top of Page | Previous Page | Next Page | Contents | Index ]
168
RPG IV Exception/Error Handling Routine
Figure 11 shows the specific steps in the RPG IV exception/error handling routine.
The item numbers in the following description refer to the numbers in the figure.
- 1
- Set up the file information or procedure status data structure, if specified, with
status information.
- 2
- If the exception/error occurred on an operation code that has an indicator
specified in positions 73 and 74, the indicator is set on, and control returns to
the next sequential instruction in the calculations.
- 3
- If the appropriate exception/error subroutine (INFSR or *PSSR) is present in the
procedure, the procedure branches to step 13; otherwise, the procedure
continues with step 4.
- 4
- If the Status code is 1121-1126 (see File Status Codes), control returns to the
current instruction in the calculations. If not, the procedure continues with step
5.
- 5
- If the exception is a function check, the procedure continues with step 6. If not,
it branches to step 15.
- 6
- An inquiry message is issued to the requester. For an interactive job, the
message goes to the requester. For a batch job, the message goes to
QSYSOPR. If QSYSOPR is not in break mode, a default response is issued.
- 7
- If the user’s response is to cancel the procedure, the procedure continues with
step 8. If not, the procedure continues.
- 8
- If the user’s response is to cancel with a dump, the procedure continues with
step 9. If not, the procedure branches to step 10.
- 9
- A dump is issued.
- 10
- All global files are closed and data areas are unlocked
- 11
- The procedure is set so that it can be called again.
- 12
- The return code is set and the function check is percolated.
- 13
- Control passes to the exception/error subroutine (INFSR or *PSSR).
- 14
- If a return point is specified in factor 2 of the ENDSR operation for the
exception/error subroutine, the procedure goes to the specified return point. If
a return point is not specified, the procedure goes to step 4. If a field name is
specified in factor 2 of the ENDSR operation and the content is not one of the
RPG IV-defined return points (such as *GETIN or *DETC), the procedure goes
to step 6. No error is indicated, and the original error is handled as though the
169
factor 2 entry were blank.
- 15
- If no invocation handles the exception, then it is promoted to function check and
the procedure branches to step 5. Otherwise, depending on the action taken by
the handler, control resumes in this procedure either at step 10 or at the next
machine instruction after the point at which the exception occurred.
170
Subprocedure Calculations
No cycle code is generated for a subprocedure, and so you must code it
differently than you would code a cycle-main procedure. The subprocedure ends
when one of the following occurs:
- A RETURN operation is processed
- The last calculation in the body of the subprocedure is processed.
Figure 12 shows the normal processing steps for a subprocedure. Figure 13 shows
the exception/error handling sequence.
Figure 12. Normal Processing Sequence for a Subprocedure
- 1
171
- Taking the "No" branch means that another procedure has already been called
since the program was activated. You should ensure that you do not make any
incorrect assumptions about the state of files, data areas, etc., since another
procedure may have closed files, or unlocked data areas.
- 2
- If an entry parameter to the main procedure is RESET anywhere in the module,
this will cause an exception. If it is possible that a subprocedure will be called
before the main procedure, it is not advised to RESET any entry parameters for
the cycle-main procedure.
Figure 13. Exception/Error Handling Sequence for a Subprocedure
173
Implicit Opening of Files and Locking of Data Areas
UDS data areas and global files that do not have the USROPN keyword are opened
or locked implicitly during module initialization and during cycle-main-procedure
initialization. Static files in subprocedures that do not have the USROPN keyword
are opened implicitly the first time the subprocedure is called. Automatic files in
subprocedures that do not have the USROPN keyword are opened every time the
procedure is called.
174
Implicit Closing of Files and Unlocking of Data Areas
Global files that are open are closed implicitly, and data areas that are locked are
unlocked implicitly during cycle-main procedure termination, when the cycle-main
procedure ends abnormally or with LR on. Automatic files in subprocedures are
closed implicitly when the subprocedure ends normally or abnormally.
Caution: There is no implicit closing of static files in subprocedures. There is no
closing of global files or implicit unlocking of data areas in a linear module. These
objects will remain open or locked unless they are explicitly closed or unlocked.
175
Chapter 4. RPG IV Indicators
An indicator is a one byte character field which contains either '1' (on) or '0' (off). It
is generally used to indicate the result of an operation or to condition (control) the
processing of an operation.
The indicator format can be specified on the definition specifications to define
indicator variables. For a description of how to define character data in the indicator
format, see Character Format and Position 40 (Internal Data Type). This chapter
describes a special set of predefined RPG IV indicators (*INxx).
RPG IV indicators are defined either by an entry on a specification or by the RPG IV
program itself. The positions on the specification in which you define the indicator
determine how the indicator is used. An indicator that has been defined can then be
used to condition calculation and output operations.
The RPG IV program sets and resets certain indicators at specific times during the
program cycle. In addition, the state of most indicators can be changed by
calculation operations. All indicators except MR, 1P, KA through KN, and KP
through KY can be set on with the SETON operation code; all indicators except MR
and 1P can be set off with the SETOFF operation code.
This chapter is divided into the following topics:
- Indicators defined on the RPG IV specifications
- Indicators not defined on the RPG IV specifications
- Using indicators
- Indicators referred to as data.
176
Indicators Defined on RPG IV Specifications
You can specify the following indicators on the RPG IV specifications:
- Overflow indicator (the OFLIND keyword on the file description specifications).
- Record identifying indicator (positions 21 and 22 of the input specifications).
- Control level indicator (positions 63 and 64 of the input specifications).
- Field indicator (positions 69 through 74 of the input specifications).
- Resulting indicator (positions 71 through 76 of the calculation specifications).
- *IN array, *IN(xx) array element or *INxx field (See Indicators Referred to As Data
for a description of how an indicator is defined when used with one of these
reserved words.).
The defined indicator can then be used to condition operations in the program.
177
Overflow Indicators
An overflow indicator is defined by the OFLIND keyword on the file description
specifications. It is set on when the last line on a page has been printed or passed.
Valid indicators are *INOA through *INOG, *INOV, and *IN01 through *IN99. A
defined overflow indicator can then be used to condition calculation and output
operations. A description of the overflow indicator and fetch overflow logic is given in
Overflow Routine.
178
Record Identifying Indicators
A record identifying indicator is defined by an entry in positions 21 and 22 of the
input specifications and is set on when the corresponding record type is selected for
processing. That indicator can then be used to condition certain calculation and
output operations. Record identifying indicators do not have to be assigned in any
particular order.
The valid record identifying indicators are:
- 01-99
- H1-H9
- L1-L9
- LR
- U1-U8
- RT
For an externally described file, a record identifying indicator is optional, but, if you
specify it, it follows the same rules as for a program described file.
Generally, the indicators 01 through 99 are used as record identifying indicators.
However, the control level indicators (L1 through L9) and the last record indicator
(LR) can be used. If L1 through L9 are specified as record identifying indicators,
lower level indicators are not set on.
When you select a record type for processing, the corresponding record identifying
indicator is set on. All other record identifying indicators are off except when a file
operation code is used at detail and total calculation time to retrieve records from a
file (see below). The record identifying indicator is set on after the record is selected,
but before the input fields are moved to the input area. The record identifying
indicator for the new record is on during total time for the old record; therefore,
calculations processed at total time using the fields of the old record cannot be
conditioned by the record identifying indicator of the old record. You can set the
indicators off at any time in the program cycle; they are set off before the next
primary or secondary record is selected.
If you use a file operation code on the calculation specifications to retrieve a
record, the record identifying indicator is set on as soon as the record is retrieved
from the file. The record identifying indicator is not set off until the appropriate point
in the RPG IV cycle. (See Figure 10.) Therefore, it is possible to have several record
identifying indicators for the same file, as well as record-not-found indicators, set on
concurrently if several operations are issued to the same file within the same RPG
IV program cycle.
179
Rules for Assigning Record Identifying Indicators
When you assign record identifying indicators to records in a program described
file, remember the following:
- You can assign the same indicator to two or more different record types if the
same operation is to be processed on all record types. To do this, you specify the
record identifying indicator in positions 21 and 22, and specify the record
identification codes for the various record types in an OR relationship.
- You can associate a record identifying indicator with an AND relationship, but it
must appear on the first line of the group. Record identifying indicators cannot be
specified on AND lines.
- An undefined record (a record in a program described file that was not described
by a record identification code in positions 23 through 46) causes the program to
halt.
- A record identifying indicator can be specified as a record identifying indicator for
another record type, as a field indicator, or as a resulting indicator. No diagnostic
message is issued, but this use of indicators may cause erroneous results.
When you assign record identifying indicators to records in an externally described
file, remember the following:
- AND/OR relationships cannot be used with record format names; however, the
same record identifying indicator can be assigned to more than one record.
- The record format name, rather than the file name, must be specified in positions 7
through 16.
For an example of record identifying indicators, see Figure 14.
Figure 14. Examples of Record Identifying Indicators
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................
I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr....
IINPUT1 NS 01 1 CS I OR 1 CA I 1 25 FLD1
I NS 02 1 CX 2 CY 3 CZ I AND 4 CA I 1
15 FLDA I 16 20 FLDB
* 01 or 02.
I NS 95
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
IRcdname+++....Ri........................................................
180
[ Top of Page | Previous Page | Next Page | Contents | Index ]
181
Control Level Indicators (L1-L9)
A control level indicator is defined by an entry in positions 63 and 64 of the input
specifications, designating an input field as a control field. It can then be used to
condition calculation and output operations. The valid control level indicator entries
are L1 through L9.
A control level indicator designates an input field as a control field. When a control
field is read, the data in the control field is compared with the data in the same
control field from the previous record. If the data differs, a control break occurs, and
the control level indicator assigned to the control field is set on. You can then use
control level indicators to condition operations that are to be processed only when all
records with the same information in the control field have been read. Because the
indicators stay on for both total time and the first detail time, they can also be used
to condition total printing (last record of a control group) or detail printing (first record
in a control group). Control level indicators are set off before the next record is read.
A control break can occur after the first record containing a control field is read.
The control fields in this record are compared to an area in storage that contains
hexadecimal zeros. Because fields from two different records are not being
compared, total calculations and total output operations are bypassed for this cycle.
Control level indicators are ranked in order of importance with L1 being the lowest
and L9 the highest. All lower level indicators are set on when a higher level indicator
is set on as the result of a control break. However, the lower level indicators can be
used in the program only if they have been defined. For example, if L8 is set on by a
control break, L1 through L7 are also set on. The LR (last record) indicator is set on
when the input files are at end of file. LR is considered the highest level indicator
and forces L1 through L9 to be set on.
You can also define control level indicators as record identifying or resulting
indicators. When you use them in this manner, the status of the lower level
indicators is not changed when a higher level indicator is set on. For example, if L3
is used as a resulting indicator, the status of L2 and L1 would not change if L3 is set
on.
The importance of a control field in relation to other fields determines how you
assign control level indicators. For example, data that demands a subtotal should
have a lower control level indicator than data that needs a final total. A control field
containing department numbers should have a higher control level indicator than a
control field containing employee numbers if employees are to be grouped within
departments (see Figure 15).
182
Rules for Control Level Indicators
When you assign control level indicators, remember the following:
- You can specify control fields only for primary or secondary files.
- You cannot specify control fields for full procedural files; numeric input fields of
type binary, integer, unsigned or float; or look-ahead fields.
- You cannot use control level indicators when an array name is specified in
positions 49 through 62 of the input specifications; however, you can use control
level indicators with an array element. Control level indicators are not allowed for
null-capable fields.
- Control level compare operations are processed for records in the order in which
they are found, regardless of the file from which they come.
- If you use the same control level indicator in different record types or in different
files, the control fields associated with that control level indicator must be the same
length (see Figure 15) except for date, time, and timestamp fields which need only
match in type (that is, they can be different formats).
- The control level indicator field length is the length of a control level indicator in a
record. For example, if L1 has a field length of 10 bytes in a record, the control
level indicator field length for L1 is 10 positions. The control level indicator field
length for split control fields is the sum of the lengths of all fields associated with a
control level indicator in a record. If L2 has a split control field consisting of 3 fields
of length: 12 bytes, 2 bytes and 4 bytes; then the control level indicator field length
for L2 is 18 positions.
If multiple records use the same control level indicator, then the control level
indicator field length is the length of only one record, not the sum of all the lengths
of the records.
Within a program, the sum of the control level indicator field lengths of all control
level indicators cannot exceed 256 positions.
- Record positions in control fields assigned different control level indicators can
overlap in the same record type (see Figure 16). For record types that require
control or match fields, the total length of the control or match field must be less
than or equal to 256. For example, in Figure 16, 15 positions have been assigned
to control levels.
- Field names are ignored in control level operations. Therefore, fields from different
record types that have been assigned the same control level indicator can have the
same name.
- Control levels need not be written in any sequence. An L2 entry can appear before
L1. All lower level indicators need not be assigned.
- If different record types in a file do not have the same number of control fields,
unwanted control breaks can occur.
3 A DIVSON 1
A*
A* (ADDITIONAL FIELDS)
183
A*
3 A DIVSON 1
A*
A* (ADDITIONAL FIELDS)
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................
I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr....
IEMPREC 10 I EMPLNO L1 I
DIVSON L3 I DEPT L2
* The same control level indicators can be used for different record
* types. However, the control fields having the same indicators must
IEMPTIM 20 I EMPLNO L1 I
DEPT L2 I DIVSON L3
184
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................
I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr....
ISALES 01 I 1 2 L2FLD L2 I
3 5 L1FLD L1 I 6 8 AMT
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq..
C 01 SETON 11
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+...........................
O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat
OPRINTER D 01 1 1 O L2FLD 5 O
NAME 25 O D 02 1 O L1FLD
15 O AMT Z 15
OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+...........................
O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat O T L1N11
1 O L1TOT ZB 25 O 27 '*' O
T L2 1 O L2TOT ZB 25 O
28 '**' O T LR 1 O LRTOT ZB 25
Different record types normally contain the same number of control fields. However,
some applications require a different number of control fields in some records.
The salesman records contain only the L2 control field. The item records contain
both L1 and L2 control fields. With normal RPG IV coding, an unwanted control
break is created by the first item record following the salesman record. This is
recognized by an L1 control break immediately following the salesman record and
results in an asterisk being printed on the line below the salesman record.
- Numeric control fields are compared in zoned decimal format. Packed numeric
input fields lengths can be determined by the formula: d = 2n - 1
186
Where d = number of digits in the field and n = length of the input field. The
number of digits in a packed numeric field is always odd; therefore, when a packed
numeric field is compared with a zoned decimal numeric field, the zoned field must
have an odd length.
- When numeric control fields with decimal positions are compared to determine
whether a control break has occurred, they are always treated as if they had no
decimal positions. For instance, 3.46 is considered equal to 346.
- If you specify a field as numeric, only the positive numeric value determines
whether a control break has occurred; that is, a field is always considered to be
positive. For example, -5 is considered equal to +5.
- Date and time fields are converted to *ISO format before being compared
- Graphic data is compared by hexadecimal value
187
Split Control Field
A split control field is formed when you assign more than one field in an input
record the same control level indicator. For a program described file, the fields that
have the same control level indicator are combined by the program in the order
specified in the input specifications and treated as a single control field (see Figure
18). The first field defined is placed in the high-order (leftmost) position of the control
field, and the last field defined is placed in the low-order (rightmost) position of the
control field.
Figure 18. Split Control Fields*...1....+....2....+....3....+....4....+....5....+....6....+....7...
IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC................................
I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr....
IMASTER 01 I 28 31 CUSNO L4 I
15 20 ACCTNO L4 I 50 52 REGNO L4
For an externally described file, fields that have the same control level indicator are
combined in the order in which the fields are described in the data description
specifications (DDS), not in the order in which the fields are specified on the input
specifications. For example, if these fields are specified in DDS in the following
order:
- EMPNO
- DPTNO
- REGNO
and if these fields are specified with the same control level indicator in the following
order on the input specifications:
- REGNO L3
- DPTNO L3
- EMPNO L3
the fields are combined in the following order to form a split control field: EMPNO
DPTNO REGNO.
Some special rules for split control fields are:
- For one control level indicator, you can split a field in some record types and not in
others if the field names are different. However, the length of the field, whether split
or not, must be the same in all record types.
- You can vary the length of the portions of a split control field for different record
types if the field names are different. Howev