Sc092507-ILE RPG Programmers Guide 7.1
Sc092507-ILE RPG Programmers Guide 7.1
Rational Development Studio for i
Note!
Before using this information and the product it supports, be sure to read the general information
under Notices on page 517.
| This edition applies to Version 7, Release 1, Modification Level 0, of IBM Rational Development Studio for ILE
| RPG Programmer's Guide (5770-WDS), and to all subsequent releases and modifications until otherwise indicated in
| new editions. This edition applies only to reduced instruction set computer (RISC) systems.
| This edition replaces SC09-2507-07.
IBM welcomes your comments. You can send your comments to:
IBM Canada Ltd. Laboratory
Information Development
8200 Warden Avenue
Markham, Ontario, Canada L6G 1C7
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.
Copyright IBM Corporation 1994, 2010.
US Government Users Restricted Rights Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
About This Guide . . . . . . . . . . ix
Who Should Use This Guide . . . . . . . . . ix
Prerequisite and Related Information . . . . . . ix
How to Send Your Comments . . . . . . . . x
What's New . . . . . . . . . . . . . . x
| What's New in this Release . . . . . . . . . xi
# What's New in V6R1 . . . . . . . . . . . xv
# What's New in V5R4?. . . . . . . . . . . xix
What's New in V5R3? . . . . . . . . . . xxiii
What's New in V5R2? . . . . . . . . . . xxviii
What's New in V5R1? . . . . . . . . . . xxx
What's New in V4R4? . . . . . . . . . . xxxv
What's New in V4R2? . . . . . . . . . . xxxix
What's New in V3R7? . . . . . . . . . . xliii
What's New in V3R6/V3R2? . . . . . . . . xlvii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
17
19
19
20
20
21
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
23
23
24
25
25
.
.
.
.
.
.
.
.
.
25
27
27
28
28
29
30
31
31
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
33
34
36
40
45
45
45
45
46
47
47
47
47
. .
File
. .
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
51
51
52
55
57
57
.
.
.
.
.
.
.
.
.
.
.
61
63
64
65
67
67
68
70
72
73
74
iii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
77
78
82
84
84
84
85
87
89
90
90
91
91
92
92
93
95
. 95
. 95
. 96
. 97
. 97
. 97
. 101
. 102
. 103
. 104
107
107
109
112
112
113
114
114
115
116
116
116
117
119
124
125
iv
. 133
|
|
|
|
|
|
|
#
#
|
|
#
#
#
#
#
#
#
#
Calling Programs . . . . . . . . . . .
Calling Procedures . . . . . . . . . .
The Call Stack . . . . . . . . . . . .
Recursive Calls . . . . . . . . . . . .
Parameter-Passing Considerations . . . . .
Using a Prototyped Call . . . . . . . . . .
Using the CALLP Operation . . . . . . .
Calling within an Expression . . . . . . .
Examples of Free-Form Call . . . . . . .
Passing Prototyped Parameters . . . . . . .
Parameter Passing Styles . . . . . . . .
Using Operational Descriptors. . . . . . .
Omitting Parameters . . . . . . . . . .
Checking for the Number of Passed Parameters
Passing Less Data Than Required . . . . .
Passing File Parameters . . . . . . . . .
Order of Evaluation . . . . . . . . . .
Interlanguage Calls . . . . . . . . . .
Interlanguage Calling Considerations . . . . .
Using the Fixed-Form Call Operations . . . . .
Examples of CALL and CALLB . . . . . .
Passing Parameters Using PARM and PLIST . .
Returning from a Called Program or Procedure . .
Returning from a Main Procedure . . . . .
Returning from a Subprocedure . . . . . .
Returning using ILE Bindable APIs . . . . .
Using Bindable APIs . . . . . . . . . . .
Examples of Using Bindable APIs . . . . .
Calling a Graphics Routine . . . . . . . . .
Calling Special Routines . . . . . . . . . .
Storage Model . . . . . . . . . . . . .
Considerations for the single-level storage
model . . . . . . . . . . . . . . .
Considerations for the teraspace storage model
Considerations for the inherit storage model
Recommendations for the storage model of
programs and service programs . . . . . .
Multithreading Considerations . . . . . . .
Running Concurrently in Multiple Threads . .
Running Serialized in Multiple Threads . . .
Activation Group Considerations for the
THREAD keyword . . . . . . . . . .
Storage that is Shared Among Multiple Threads
How to Avoid Deadlock Between Modules . .
All-Thread Static Variables . . . . . . . .
When to use a serialized procedure . . . . .
When a serialized procedure does not provide
sufficient protection . . . . . . . . . .
Difficulty of manually synchronizing access to
shared resources . . . . . . . . . . .
Using thread-related APIs . . . . . . . .
134
134
135
136
138
139
140
140
141
141
142
144
146
147
152
153
153
154
155
155
156
157
158
158
161
161
162
163
163
164
164
164
165
165
165
165
166
167
167
167
168
169
169
171
171
172
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
185
185
191
191
191
195
200
202
202
205
207
216
217
223
.
.
.
.
.
.
.
.
.
.
230
230
232
233
234
235
235
236
237
238
. 239
. 239
.
.
.
.
.
240
240
241
242
243
. 244
. 246
. 247
. 249
. 250
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
252
253
253
253
254
256
256
257
258
259
260
263
265
266
266
267
268
.
.
.
.
.
.
.
.
269
269
270
270
270
271
272
273
274
. 275
. 277
. 278
. 279
. 279
.
.
.
.
.
.
.
.
285
288
290
291
291
291
294
294
. 294
. 295
. 297
.
.
.
.
305
306
306
312
. 315
.
.
.
.
.
.
. 319
. 320
. 320
329
331
331
Contents
332
332
333
334
334
334
. .
. .
. .
. .
I/O
. .
.
.
.
.
335
337
339
339
.
.
.
.
.
341
342
343
344
345
346
347
. 347
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
349
349
349
350
350
350
353
355
356
356
358
359
360
360
361
366
368
370
371
373
374
375
376
377
378
379
379
380
vi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
390
390
390
390
391
393
. 340
.
.
.
.
.
.
.
.
.
.
.
.
381
381
382
382
. .
in a
. .
. 385
. 388
395
. 395
. 395
. 397
. 398
. 398
. 399
. 402
. 403
.
.
.
.
.
.
404
405
405
406
406
406
. 409
. 410
410
. 412
. 413
. 414
. 415
. 417
. 424
. 425
. 426
. 428
. 432
. 433
434
. 437
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
445
445
446
447
450
.
.
.
.
.
.
.
.
.
.
.
.
.
451
451
453
453
453
454
455
459
459
460
460
461
461
.
.
.
.
.
.
.
.
462
462
462
462
465
465
467
469
470
470
471
474
476
.
.
.
.
.
.
.
.
.
.
.
.
.
.
477
478
481
496
499
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
502
502
504
509
510
510
510
511
512
513
514
515
515
516
Notices . . . . . . . . . . . . . . 517
Programming Interface Information .
Trademarks . . . . . . . . .
.
.
.
.
.
.
.
.
. 518
. 518
Bibliography . . . . . . . . . . . . 521
Index . . . . . . . . . . . . . . . 523
477
.
. 477
Contents
vii
viii
Handle exceptions
Define and process files
Access devices
Convert programs from an RPG III format to RPG IV format
Read compiler listings
ix
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:
|
v
v
v
v
v
v
v
What's
What's
What's
What's
What's
What's
What's
New
New
New
New
New
New
New
in
in
in
in
in
in
in
What's New
v What's New in V4R2? on page xxxix
v What's New in V3R7? on page xliii
v What's New in V3R6/V3R2? on page xlvii
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
// Search for an element in the custDs array where the
// account_status subfield is "K"
elem = %LOOKUP("K" : custDs(*).account_status);
%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
A
A
A
D custDs
R CUSTREC
CUSTNM
CUSTAD
ID
e ds
25A
25A
10P 0
ALIAS(CUSTOMER_NAME)
ALIAS(CUSTOMER_ADDRESS)
ALIAS
About This Guide
xi
What's New
|
|
|
|
|
QUALIFIED EXTNAME(custFile)
/free
custDs.customer_name = John Smith;
custDs.customer_address = 123 Mockingbird Lane;
custDs.id = 12345;
|
|
|
|
|
|
|
|
|
|
|
D getFileData
pr
a
varying len(1000000)
D
rtnparm
D
file
a
const varying len(500)
D data
S
a
varying len(1000)
/free
data = getFileData (/home/mydir/myfile.txt);
|
|
|
|
|
|
|
|
|
|
|
|
D
D
D
D
D
pi
name
id
errorInfo
100a
const varying
10i 0 value
likeds(errs_t)
options(*nopass)
/free
// Check if the "errorInfo" parameter was passed
if %parms >= %parmnum(errorInfo);
Optional prototypes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xii
What's New
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RPG modules and programs can be created to use the teraspace storage
model or to inherit the storage model of their caller. With the teraspace
storage model, the system limits regarding automatic storage are
significantly higher that for the single-level storage model. There are limits
for the amount of automatic storage for a single procedure and for the
total automatic storage of all the procedures on the call stack.
|
|
|
|
|
*TERASPACE
The program or module uses the teraspace storage model.
|
|
*SNGLVL
The program or module uses the single-level storage model.
|
|
*INHERIT
The program or module inherits the storage model of its caller.
|
|
|
|
The default value of the ACTGRP parameter and keyword is changed from
QILE to *STGMDL.
|
|
|
|
|
|
|
|
|
|
Note: The change to the ACTGRP parameter and keyword does not affect
the default way the activation group is assigned to the program. The
default value for the STGMDL parameter and keyword is *SNGLVL,
so when the ACTGRP parameter or keyword is not specified, the
activation group of the program will default to QILE as it did in
prior releases.
|
|
|
|
|
|
|
|
|
xiii
What's New
knows the encryption key. This enables you to send debuggable programs
to your customers without enabling your customers to see your source
code through the listing view. Use the DBGENCKEY parameter on the
CRTRPGMOD, CRTBNDRPG, or CRTSQLRPGI command.
|
|
|
|
|
Language Unit
Element
Description
|
|
|
|
|
|
|
|
Control specification
keywords
ACTGRP(*STGMDL)
|
|
|
|
Built-in functions
|
|
|
|
|
|
|
Operation codes
SORTA(A | D)
Language Unit
Element
Description
|
|
Control specification
keywords
STGMDL(*INHERIT |
*TERASPACE | *SNGLVL)
ALLOC(*STGMDL |
*TERASPACE | *SNGLVL)
|
|
|
|
|
|
|
|
|
ALIAS
|
|
|
|
Definition specification
keywords
ALIAS
RTNPARM
%PARMNUM
%SCANRPL
|
|
|
|
|
|
|
Built-in functions
|
|
|
|
xiv
What's New
|
Language Unit
Element
Description
|
|
|
|
XML-INTO options
datasubf
countprefix
|
|
|
|
|
|
|
|
|
#
THREAD(*CONCURRENT)
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
xv
What's New
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.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
Larger limits for data structures, and character, UCS-2 and graphic variables
v Data structures can have a size up to 16,773,104.
v Character definitions can have a length up to 16,773,104. (The limit is 4
less for variable length character definitions.)
v Character definitions can have a length up to 16,773,104. (The limit is 4
less for variable length character definitions.)
v 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.)
v Graphic definitions can have a length up to 8,386,552 DBCS characters.
(The limit is 2 less for variable length graphic definitions.)
v 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.
#
#
#
#
xvi
What's New
#
#
#
#
#
#
#
#
#
#
#
#
#
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).
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
xvii
What's New
#
Language Unit
Element
Description
#
#
#
Control specification
keywords
OPTION(*UNREF |
*NOUNREF)
THREAD(*CONCURRENT)
New parameter
*CONCURRENT allows
running concurrently in
multiple threads.
#
#
#
#
#
#
#
#
EXTFILE(*EXTDESC)
#
#
#
#
Built-in functions
%ADDR(varying-field :
*DATA)
#
#
Definition specification
keywords
DIM(16773104)
#
#
#
EXTNAME('LIB/FILE')
#
#
#
OCCURS(16773104)
A multiple-occurrence data
structure can have up to
16773104 elements.
#
#
#
VARYING{(2|4)}
#
#
#
#
#
Definition specifications
Length entry
#
#
#
#
Input specifications
Length entry
#
#
Calculation specifications
Length entry
#
#
#
Operation codes
Language Unit
Element
Description
|
|
Control specification
keywords
MAIN(subprocedure-name)
PGMINFO(*NO | *PCML { :
*MODULE } )
#
#
#
xviii
What's New
#
Language Unit
Element
Description
#
#
#
#
STATIC
#
#
#
#
QUALIFIED
#
#
#
LIKEFILE(filename)
#
#
#
TEMPLATE
#
#
#
#
#
#
#
STATIC(*ALLTHREAD)
#
#
LIKEFILE(filename)
#
#
#
TEMPLATE
#
#
#
LEN(length)
SERIALIZE
#
#
#
#
#
#
Definition specification
keywords
Procedure specification
keywords
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.
About This Guide
xix
What's New
// DS1 subfields
DS2 subfields
//
s1 character
s1 packed
//
s2 character
s2 character
//
s3 numeric
//
s4 date
s4 date
//
s5 character
EVAL-CORR ds1 = ds2;
// This EVAL-CORR operation is equivalent to the following EVAL operations
//
EVAL ds1.s2 = ds2.s2
//
EVAL ds1.s4 = ds2.s4
// Other subfields either appear in only one data structure (S3 and S5)
// or have incompatible types (S1).
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.
New builtin function %HANDLER
%HANDLER (handlingProcedure : communicationArea
XML-SAX initiates a SAX parse for the XML document specified by the %XML
builtin function. The XML-SAX operation begins by calling an XML parser
which begins to parse the document. When the parser discovers an event such
xx
What's New
as finding the start of an element, finding an attribute name, finding the end of
an element etc., the parser calls the eventHandler with parameters describing
the event. The commArea operand is a variable that is passed as a parameter to
the eventHandler providing a way for the XML-SAX operation code to
communicate with the handling procedure. When the eventHandler returns, the
parser continues to parse until it finds the next event and calls the eventHandler
again.
New operation code XML-INTO
XML-INTO{ (EH) } variable
%XML(xmlDoc { : options });
XML-INTO{ (EH) } %HANDLER(handler : commArea ) %XML(xmlDoc { : options });
XML-INTO reads the data from an XML document in one of two ways:
v directly into a variable
v 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"
// and "to". Each of these subfields has two subfields
// "name" and "lib".
// File cpyA.xml contains the following XML document
// <copyinfo>
//
<from><name>MASTFILE</name><lib>CUSTLIB</lib></from>
//
<to><name>MYFILE</name><lib>*LIBL</lib>
// <copyinfo>
xml-into copyInfo %XML(cpyA.xml : doc=file);
// After the XML-INTO operation, the following
// copyInfo.from .name = MASTFILE .lib = CUSTLIB
// copyInfo.to
.name = MYFILE
.lib = *LIBL
Use the PREFIX keyword to remove characters from the beginning of field
names
PREFIX( : number_of_characters)
xxi
What's New
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
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
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
> EVAL _QRNU_NULL_DS1
_QRNU_NULL_DS1.FLD1 = 1
_QRNU_NULL_DS1.FLD2 = 0
_QRNU_NULL_DS1.SUB.FLD3 = 1
===> EVAL _QRNU_NULL_DS.FLD2
_QRNU_NULL_DS1.FLD2 = 0
===> EVAL _QRNU_NULL_DS.FLD2 = 1
===> EVAL DSARR(1).FLD2
DSARR(1).FLD2 = abcde
===> EVAL _QRNU_NULL_DSARR(1).FLD2
_QRNU_NULL_DSARR(1).FLD2 = 0
xxii
What's New
If a module performs a keyed sequential input operation to a shared file and it
results in an EOF condition, and a different module sets the file cursor using a
positioning operation such as SETLL, a subsequent sequential input operation
by the first module may be successfully done. Before this change, the first RPG
module ignored the fact that the other module had repositioned the shared file.
This change in behaviour is available with PTFs for releases V5R2M0 (SI13932)
and V5R3M0 (SI14185).
Table 5. Changed Language Elements Since V5R3
Language Unit
Element
Description
Control specification
keywords
DEBUG(*INPUT|*DUMP
*XMLSAX|*NO|*YES)
PREFIX(:2)
Definition specification
keywords
OPTIONS(*NULLIND)
PREFIX(:2)
Element
Description
Built-in functions
%HANDLER(prototype:
parameter)
Specifies a handling
procedure for an event.
%XML(document{:options})
EVAL-CORR
XML-INTO
XML-SAX
Operation codes
xxiii
What's New
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);
// Copy part of an array to part of another array:
%subarr(Array1:x:y) = %subarr(Array2:m:n);
// Sort part of an array
sorta %subarr(Array3:x:y);
// Sum part of an array
sum = %xfoot(%subarr(Array4:x:y));
6p 0
d
datfmt(*jul)
// now numDdMmYy = 210803
xxiv
What's New
also valid for pointer parameters defined with OPTIONS(*STRING). With
OPTIONS(*STRING : *TRIM), the passed data will be trimmed even if a pointer
is passed on the call.
Example:
D
D
D
D
D
D
D
D
D
proc
parm1
parm2
parm3
parm4
parm5
ptr
data
fld1
pr
5a
5a
5a
*
*
*
10a
5a
s
s
s
const
const
const
value
value
options(*trim)
options(*trim : *rightadj)
varying options(*trim)
options(*string : *trim)
options(*string : *trim)
/free
data = rst + x00;
ptr = %addr(data);
proc ( xyz
// the called
//
parm1 =
//
parm2 =
//
parm3 =
//
parm4 =
//
parm5 =
: @#$
procedure
xyz
@#$
123
a pointer
a pointer
k disk
extname(outfile) prefix(O_)
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
D infds
ds
D
recname
D input
ds
D
rec1
D
rec2
/free
read log input;
dow not %eof(log);
dsply recname;
k disk
261
infds(infds)
270
qualified
likerec(rec1) overlay(input)
likerec(rec2) overlay(input)
xxv
What's New
if recname = REC1;
// handle rec1
elseif recname = REC2;
// handle rec2
endif;
read log input;
enddo;
*inlr = *on;
/end-free
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!
xxvi
What's New
source file rather than generating a program. The new source file will contain
the original source lines that are accepted by the conditional compilation
directives such as /DEFINE and /IF. It will also have the source lines from files
included by /COPY statements, and optionally it will have the source lines
included by /INCLUDE statements. The new source file will have the comments
from the original source file if PPGENOPT(*DFT) or
PPGENOPT(*NORMVCOMMENT) is specified.When the SQL precompiler is
called with a value other than *NONE for new parameter RPGPPOPT, the
precompiler will use this RPG preprocessor to handle /COPY, the conditional
compilation directives and possibly the /INCLUDE directive. This will allow
SQLRPGLE source to have nested /COPY statements, and conditionally used
statements.
Table 7. Changed Language Elements Since V5R2
Language Unit
Element
Description
Control specification
keywords
CCSID(*GRAPH:parameter|
*UCS2:number|
*CHAR:*JOBRUN)
Built-in Functions
%DEC(expression {format})
%TRIM(expression:expression)
Definition
Specification
Keywords
OPTIONS(*TRIM)
Definition
Specifications
Input specifications
Length entry
Allow an externally-described
data structure to be specified
in the result field when Factor
2 is the name of an
externally-described record
format.
SORTA operation
Calculation
specifications
xxvii
What's New
Table 8. New Language Elements Since V5R2
Language Unit
Element
Description
Built-in Functions
%SUBARR(array:starting
element {:number of
elements})
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.
v 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.
v 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
CHAIN (keyA : keyB : key3) custrec;
CHAIN %KDS(custkeyDS) custrec;
xxviii
What's New
Supports packed and zoned numeric data with up to 31 digits and decimal
places. This is the maximum length supported by DDS. Only 30 digits and
decimal places were supported prior to V5R2.
v Performance option for FEOD
The FEOD operation is enhanced by supporting an extender N which indicates
that the operation should simply write out the blocked buffers locally, without
forcing a costly write to disk.
v Enhanced data area access
The DTAARA keyword is enhanced to allow the name and library of the data
area to be determined at runtime
v New assignment operators
The new assignment operators +=, -=, *=, /=, **= allow a variable to be modified
based on its old value in a more concise manner.
Example: totals(current_customer) += count;
Element
Description
Built-in functions
%DEC(expression)
%DECH(expression)
%FLOAT(expression)
%INT(expression)
%INTH(expression)
%UNS(expression)
%UNSH(expression)
Definition
specification
keywords
Definition
Specifications
DTAARA({*VAR:}data-area-name)
DIM
LIKEDS
EXTNAME(filename{:extrecname}
{:*ALL|*INPUT|*OUTPUT|*KEY}
)
xxix
What's New
Table 9. Changed Language Elements Since V5R1 (continued)
Language Unit
Element
Description
Operation codes
UPDATE
FEOD
Calculation
specifications
Element
Description
Expressions
Assignment Operators += -= *= /=
**=
Control Specification
Keywords
DECPREC(30|31)
Definition specification
keywords
LIKEREC(intrecname{:*ALL|
*INPUT|*OUTPUT|*KEY})
Built-in functions
%BITAND(expression : expression)
%BITNOT(expression)
%BITOR(expression : expression)
%BITXOR(expression : expression)
%FIELDS(name{:name...})
%KDS(data structure)
xxx
What's New
v 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.
v 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.
v 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
v You can specify the EXTFILE and EXTMBR keywords on the file specification to
control which external file is used when a file is opened.
v 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 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.
v Enhanced error handling:
xxxi
What's New
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:
v You can specify parentheses on a procedure call that has no parameters.
v You can specify that a procedure uses ILE C or ILE CL calling conventions, on
the EXTPROC definition specification keyword.
v The following /DEFINE names are predefined: *VnRnMn, *ILERPG,
*CRTBNDRPG, and *CRTRPGMOD.
v 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.)
v The parameter to the DIM, OCCURS, and PERRCD keywords no longer needs
to be previously defined.
v The %PADDR built-in function can now take either a prototype name or an
entry point name as its argument.
v A new operation code, ELSEIF, combines the ELSE and IF operation codes
without requiring an additional ENDIF.
v The DUMP operation code now supports the A extender, which means that a
dump is always produced - even if DEBUG(*NO) was specified.
v 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.
v The OFLIND file-specification keyword can now take any indicator, including a
named indicator, as an argument.
v The LICOPT (licensed internal code options) keyword is now available on the
CRTRPGMOD and CRTBNDRPG commands.
v 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.
v 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
Language Unit
Element
Description
Built-in functions
%CHAR(expression{:format})
%PADDR(prototype-name)
xxxii
What's New
Table 11. Changed Language Elements Since V4R4 (continued)
Language Unit
Element
Description
Definition specification
keywords
EXTPROC(*JAVA:class-name:procname)
EXTPROC(*CL:proc-name)
EXTPROC(*CWIDEN:proc-name)
EXTPROC(*CNOWIDEN:proc-name)
INZ(*LIKEDS)
LIKE(object-name)
PREFIX(character-literal{:number})
OFLIND(name)
PREFIX(character-literal{:number})
DUMP (A)
File specification
keywords
Operation codes
Element
Description
Data types
Object
Compiler directives
/INCLUDE
CLASS(*JAVA:class-name)
LIKEDS(dsname)
QUALIFIED
EXTFILE(filename)
EXTMBR(membername)
Definition specification
keywords
File specification
keywords
xxxiii
What's New
Table 12. New Language Elements Since V4R4 (continued)
Language Unit
Element
Description
Built-in functions
%ALLOC(num)
%CHECK(comparator:base{:start})
%CHECKR(comparator:base{:start})
%DATE(expression{:date-format})
%DAYS(num)
%DIFF(op1:op2:unit)
%HOURS(num)
%LOOKUPxx(arg:array{:startindex
{:numelems}})
%MINUTES(num)
%MONTHS(num)
%MSECONDS(num)
%OCCUR(dsn-name)
%REALLOC(pointer:number)
%SECONDS(num)
%SHTDN
%SQRT(numeric-expression)
%SUBDT(value:unit)
%THIS
%TIME(expression{:time-format})
%TIMESTAMP(expression
{:*ISO|*ISO0})
%TLOOKUP(arg:search-table
{:alt-table})
%XLATE(from:to:string{:startpos})
%YEARS(num)
xxxiv
What's New
Table 12. New Language Elements Since V4R4 (continued)
Language Unit
Element
Description
Operation codes
MONITOR
ON-ERROR
ENDMON
ELSEIF
CRTBNDRPG and
LICOPT(options)
CRTRPGMOD keywords
xxxv
What's New
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:
v 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.
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.
v 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.
v The new %XFOOT built-in function sums all elements of a specified array
expression.
v 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.
v The new FOR operation code performs an iterative loop and allows free-form
expressions for the initial, increment, and limit values.
v The new LEAVESR operation code can be used to exit from any point within a
subroutine.
v The new *NEXT parameter on the OVERLAY(name:*NEXT) keyword indicates
that a subfield overlays another subfield at the next available position.
v The new *START and *END values for the SETLL operation code position to the
beginning or end of the file.
v The ability to use hexadecimal literals with integer and unsigned integer fields
in initialization and free-form operations, such as EVAL, IF, etc.
v New control specification keyword OPENOPT{(*NOINZOFL | *INZOFL)} to
indicate whether the overflow indicators should be reset to *OFF when a file is
opened.
v 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.
xxxvi
What's New
Table 13. Changed Language Elements Since V4R2
Language Unit
Element
Description
Control
specification
keywords
OPTION(*{NO}SRCSTMT)
OPTION(*{NO}DEBUGIO)
*{NO}DEBUGIO, determines if
breakpoints are generated for input
and output specifications.
INZ(*EXTDFT)
INZ(*USER)
OVERLAY(name:*NEXT)
OPTIONS(*NOPASS *OMIT
*VARSIZE *STRING
*RIGHTADJ)
Definition
specification
positions 33-39 (To
Position/Length)
C (UCS-2 fixed or
variable-length format)
Data format
C (UCS-2 fixed or
variable-length format)
Command
parameter
OPTION
*NOSRCSTMT, *SRCSTMT,
*NODEBUGIO, and *DEBUGIO have
been added to the OPTION parameter
on the CRTBNDRPG and
CRTRPGMOD commands.
Definition
specification
keywords
xxxvii
What's New
Table 14. New Language Elements Since V4R2
xxxviii
Language Unit
Element
Description
Control
specification
keywords
INTPREC(10 | 20)
OPENOPT{(*NOINZOFL |
*INZOFL)}
THREAD(*SERIALIZE)
Definition
specification
keywords
CCSID(number | *DFT)
Built-in functions
%DIV(n:m)
%GRAPH(char-expr |
graph-expr | UCS2-expr {:
ccsid})
%REM(n:m)
%UCS2(char-expr |
graph-expr | UCS2-expr {:
ccsid})
%XFOOT(array-expr)
What's New
Table 14. New Language Elements Since V4R2 (continued)
Language Unit
Element
Description
Operation codes
EVALR
FOR
ENDFOR
LEAVESR
xxxix
What's New
v Ability to define indicator variables
v Ability to specify the current data structure name as the parameter for the
OVERLAY keyword
v New status code 115 has been added to indicate variable-length field errors
v Support for application profiling
v Ability to handle packed-decimal data that is not valid when it is retrieved from
files using FIXNBR(*INPUTPACKED)
v 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
Language Unit
Element
Description
Control
specification
keywords
DECEDIT(*JOBRUN |
'value')
Definition
specification
keywords
Extended century
format
EXPORT {(external_name)}
IMPORT {(external_name)}
OVERLAY(name{:pos})
*CYMD (cyy/mm/dd)
xl
N (Indicator format)
Data format
N (Indicator format)
Data Attribute
*VAR
What's New
Table 15. Changed Language Elements Since V3R7 (continued)
Language Unit
Element
Description
Command
parameter
FIXNBR
New
Description
Control
specification
keywords
ACTGRP(*NEW | *CALLER
| 'activation- group-name')
ALWNULL(*NO |
*INPUTONLY | *USRCTL)
AUT(*LIBRCRTAUT | *ALL
| *CHANGE | *USE |
*EXCLUDE |
'authorization-list-name')
BNDDIR( 'binding
-directory-name' {:'bindingdirectory-name'...})
CVTOPT(*{NO}DATETIME
*{NO}GRAPHIC
*{NO}VARCHAR
*{NO}VARGRAPHIC)
DFTACTGRP(*YES | *NO)
ENBPFRCOL(*PEP |
*ENTRYEXIT | *FULL)
FIXNBR(*{NO}ZONED
*{NO}INPUTPACKED)
GENLVL(number)
INDENT(*NONE |
'character-value')
xli
What's New
Table 16. New Language Elements Since V3R7 (continued)
Language Unit
New
Description
xlii
OPTION(*{NO}XREF
*{NO}GEN *{NO}SECLVL
*{NO}SHOWCPY
*{NO}EXPDDS *{NO}EXT
*{NO}SHOWSKP)
PRFDTA(*NOCOL | *COL)
SRTSEQ(*HEX | *JOB |
*JOBRUN | *LANGIDUNQ
| *LANGIDSHR |
'sort-table-name')
TEXT(*SRCMBRTXT |
*BLANK | 'description')
TRUNCNBR(*YES | *NO)
USRPRF(*USER | *OWNER)
File Description
Specification
keywords
INDDS(
data_structure_name)
Definition
specification
keywords
VARYING
Built-in functions
%EOF{file name}
%EQUAL{file name}
%ERROR
What's New
Table 16. New Language Elements Since V3R7 (continued)
Language Unit
New
Description
%FOUND{file name}
%OPEN(file name)
%REPLACE(replacement
string: source string {:start
position {:source length to
replace}})
%STATUS{file name}
Operation code
Extender
New century
formats
*CMDY (cmm/dd/yy)
*CDMY (cdd/mm/yy)
*LONGJUL (yyyy/ddd)
Command
parameters
PRFDTA
BNDDIR
xliii
What's New
The following is a list of these enhancements including a number of new built-in
functions and usability enhancements:
v 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.
v 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.
v 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.
v 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.
v 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.
v 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.
v 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)
xliv
What's New
a new command option (DEFINE) to define up to 32 conditions on the
CRTBNDRPG and CRTRPGMOD commands.
v 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.
v Character comparisons with alternate collating sequence
Specific character variables can be defined so that the alternate collating
sequence is not used in comparisons.
v 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.
v Storage management
You can now use the new storage management operation codes to allocate,
reallocate and deallocate storage dynamically.
v 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
Language Unit
Element
Description
Definition
specification
keywords
ALIGN
OPTIONS(*NOPASS *OMIT
*VARSIZE *STRING)
Record address
type
F (Float format)
F (Float format)
Data format
F (Float format)
xlv
What's New
Table 18. New Language Elements Since V3R6
xlvi
Language Unit
New
Description
Control
specification
keywords
COPYNEST('1-2048')
EXPROPTS(*MAXDIGITS |
*RESDECPOS)
FLTDIV{(*NO | *YES)}
Definition
specification
keywords
ALTSEQ(*NONE)
Built-in functions
%ABS
%DECPOS
%EDITC
%EDITFLT
%EDITW
%FLOAT
%LEN
%NULLIND
%SCAN
What's New
Table 18. New Language Elements Since V3R6 (continued)
Language Unit
Operation code
Extenders
Operation codes
New
Description
%STR
ALLOC
DEALLOC
REALLOC
xlvii
What's New
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:
v 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.
v *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.
v 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.
v 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.
v 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.
v 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
Language Unit
Element
Description
File description
specification
keywords
PREFIX(prefix_string
{:nbr_of_char_ replaced})
Definition
specification
keywords
CONST{(constant)}
PREFIX(prefix_string
{:nbr_of_char_ replaced})
RETURN
Operation codes
xlviii
What's New
Table 20. New Language Elements Since V3R1
Language Unit
New
Description
Control
specification
keywords
COPYRIGHT('copyright
string')
EXTBININT{(*NO | *YES)}
NOMAIN
File description
specification
keywords
BLOCK(*YES |*NO)
Definition
specification
keywords
ALIGN
EXTPGM(name)
EXTPROC(name)
OPDESC
OPTIONS(*NOPASS *OMIT
*VARSIZE)
STATIC
VALUE
Built-in functions
%PARMS
Operation codes
CALLP
Specification type
Procedure specification
Definition type
PR
PI
xlix
What's New
li
4. In the Remote Systems view New Connection shows the various remote
system types you can connect to through the Remote Systems view.
5. Create a connection:
a. Expand iSeries under New Connection in the view, to open the Name
personal profile page. Accept the default profile value to open the
connection page.
b. Leave the Parent profile default value
c. Enter your host system name in the Host name field. The Connection name
field is automatically filled with the host name.
d. Leave the Verify host name check box selected.
e. Click Finish to create your connection.
You can define multiple connections to the same System i, but in addition, you can
include different configurations for the startup of your connection, such as saving
different user IDs and passwords, initial library lists, for example. After you create
a connection to a System i, you can easily connect and disconnect.
For more information see the topic Configuring a connection to a remote system in the
online help in the client product. See also Configuring a connection to a System i and
connecting to a System i in the tutorials.
Tips:
v When creating a connection, use the default profile name. The default
profile can be used to share connections with others, and to use filter
pools. (For more information about filter pools, see the topic Remote System
Explorer filters, filter pools, and filter pool references in the online help in the
client product.)
v When specifying Host name, you can either specify the IP address, or the
fully qualified name (if necessary).
v The Verify host name check box ensures that you can actually connect to
the System i you have specified. To ensure that you have all necessary
lii
liii
The view that a connection is in is called the Remote Systems view. It works much
like Windows File Explorer. You drill down by clicking the plus (+) to gain
access to desired items. For example, expand the *LIBL filter to see all the libraries
in the library list, then expand a file to see all its members (much like option 12 in
PDM).
Filters
Expanding a subsystem results in a list of filters for that subsystem. Filters are
names of lists of items that you can specify, reuse, and share. Filters filter out items
that you are not currently interested in. When creating filters, you can use generic
values, and have as many filters as you want or need. Filters can be created for
each subsystem, so you can have filters for IFS files, local files, System i objects, for
example.
Tips:
v You can always drill down within a filter if the item is a container (a
library and a file are examples of containers)
v You can specify multiple levels of generic values, for example you could
specify library BOB, file QRPG* member A*, when you create your filter.
v Pay close attention to the page where you specify the filter name. On this
page you choose whether or not you want the filter to be only for the
specified connection, or to appear in all connections. You can also specify
a profile, if you want to share your filters with others.
Since filters are names which are stored with your connection in RSE, all filters
persist between sessions.
Filter strings
When first created, a filter contains only one filter string. By modifying the
properties of a filter, you can add additional filter strings. Filter strings provide the
ability to generate more complex lists. By using multiple filter strings in a filter,
you can list members in different files, and even in different libraries in a single
named filter.
Tips:
v Filters must contain the same types of items. For example, it is not
possible to list objects and members in the same filter.
v Group items into a filter by project or application. For example, add filter
strings so that you can see the DDS members in the same list as your RPG
and COBOL files.
v For more information about filters, see the topic Filtering members in the
online help in the client product. See also Introducing filters in the tutorials.
Searching
There are two ways to search in RSE:
1. From the Search menu option (then selecting System i)
2. From the Find String action in the Remote Systems view and System i Table
view
RSE allows you to search filters, not just libraries, files, and members. This means
that you can search with very flexible search patterns. For example, you could
liv
search all the members in the file QRPGLESRC in library MYLIB and the members A*
in the files PRJA* in library PROJECT by invoking the Find string action on the filter
that contained those filter strings.
Search results appear in the Remote Search view, and the view has a history of
searches. You see the list of all the search results in one place, allowing you to
open whichever member you want first, and using whichever match in the
member you decide. The Remote Search view allows you to manage the resulting
list, by letting you remove members and matches from the list through the pop-up
menu.
Tips:
v Double-click the member name in the Remote Search view to open a
member in the Remote Systems LPEX Editor on page lxiii for editing
and to be positioned to the match selected.
v The pop-up in the Remote Search view has a list of options similar to the
System i Table view.
v Double-click on the Remote Search tab to maximize the view to the full
workbench window. This will allow you to see more matches at one time.
v Expand or collapse matched members to quickly zero in on the matches
that are important to you.
lv
v See the topic Searching for text strings on the System i in the online help in
the client product. See also Searching multiple files in the tutorials.
Comparing RSE to PDM
The following table compares the RSE features described in this topic to equivalent
or similar features in PDM.
Table 21.
In RSE
In PDM
Create a connection
Not available
All search results are available in the Remote Search results and members are available
Search view
one at a time in the order that the matches
are found
lvi
See User actions, and the topic Manipulating items in the Remote System Explorer in
the online help in the client product. See also Viewing and accessing objects in the
Remote System Explorer in the tutorials.
lvii
You can modify which columns appear in the System i Table view. You can choose
to hide or show any individual column. You can type a character to bring up the
Position To dialog. This dialog allows you to quickly scroll to your desired item.
Tips:
v Click on column headings to sort by that column.
v Use the Show in Table View to show filter contents in the System i Table
view.
v Collapse the command line for a clean screen and the ability to see more
items.
v Double-click on the System i Table view tab, to maximize the view to the
full workbench. You will then be able to see more items in one screen.
v Use filters to generate complicated lists, use the Work with submenu to
get access to infrequently used or simple lists.
System i Table view actions
Like the Remote Systems view, the System i Table view has actions that can be
invoked on items in it. As in the Remote Systems view, access to the action is
provided through a pop-up menu from clicking with the right mouse button. In
the pop-up from the System i Table view, you will see a list of actions with their
PDM option number to make the menu feel more familiar. Use the User actions
menu to create and add your own actions. User actions added either in the Table
or Remote Systems view, appear in the User Actions menu in both views.
lviii
Tips:
v Use the Show in Table action from inside the System i Table view to go
from a list of libraries to a list of objects.
v Double-click a member to open it in Remote Systems LPEX Editor on
page lxiii in edit mode.
v Click on the item name to open an edit cell in the Table view directly to
quickly rename an item. The Description column, and member type
column are also edit enabled, and allow you to quickly change the values
in those columns.
v Access an object's properties by selecting the Properties menu item in the
pop-up menu in the System i Table view or Remote Systems view.
v See Managing objects in the System i Table view in the online help in the
client product. See also Viewing and accessing objects in the Remote Systems
Explorer in the tutorials.
User actions
User actions allow you to extend the System i Table view and the Remote Systems
view with the action that you use. You can create your own action, where you will
be able to prompt the command to run, and to define how a command is executed.
Note: RSE has three command modes:
1. Normal: RSE jobs run in batch, so even though the mode is normal
(meaning in this case immediate), you still cannot run interactive
commands like STRPDM
2. Batch: Commands are submitted to a new batch job
3. Interactive: Commands are run interactively in a STRRSESVR job
When creating actions use the Insert variable button to see the list of available
variables. Actions are very customizable and you can:
v Specify if the action should refresh the Remote Systems view or System i Table
view after running
v Specify whether or not the command should be called once for each selected
object, or once for all the objects. This gives greater flexibility than PDM. For
Using the application development tools in the client product
lix
example, in RSE you could define a Save Object action, which would allow you
to select several objects and when invoked, would generate a single command to
save all of the selected objects to one save file.
v Actions can be refined so that they are only displayed for appropriate types.
There are several types predefined, but user types can be easily added to the list.
For example, this allows you to have an action for only *PGM objects, or only
RPGLE members.
v Selective prompts can be used when defining the CL command to run for the
action.
One of the advantages of RSE user actions is that they can be named, which makes
them easier to use and remember. (For more information, see the topic Managing
user actions (user options) in the online help in the client product. See also Creating a
user action in the tutorials.
Command line
The System i Table view contains a command line.
You can use the command line to run any command, or in the System i Table view,
to specify additional parameters for PDM options. The results of any commands
are displayed in the messages field. You can use familiar PDM keys:
v F9 to retrieve the last command
v F4 to prompt a command
The Show Log button can be used to view the System i Commands Log view.
lx
lxi
Compile actions are different from other actions: The results of the command itself
appear in the System i Commands Log, but for commands which support events
files, errors generated by the compiler are displayed in the Error List view. For
more information about event files, see the topic Events File format in the online
help in the client product.
Tips:
v Additional command execution preferences are available in the Window >
Preferences > Remote Systems > System i > Command Execution
preference page
v Compile commands use the same defaults as the host
v The compile actions remembers the last used compile command by
member type
v Add your own compile commands and specify the source types that they
should apply to, or refine existing compile commands, by modifying the
properties and the CL command parameters
v The default is to compile in batch, use the Command Execution
preferences to specify additional SBMJOB parameters, or to switch to normal
execution (note that this is technically not interactive, because, as
previously mentioned, RSE jobs run in batch)
v See the Compiling your programs topic in the online help in the client
product. See also Verifying and compiling source in the tutorials.
Comparing the System i Table view to PDM
The following table compares the features of the System i Table view described in
this topic to equivalent or similar features in PDM.
lxii
Table 22.
In the System i Table view
In PDM
Not applicable
Option 8
F16
Not applicable
Not available
F20
F18
lxiii
Note that the prefix area contains the sequence numbers of the member. The prefix
area in Remote Systems LPEX Editor supports SEU commands (for example, CC, B,
A, LL).
Also note that for many source types, an Outline view appears. The Outline view
displays the outline of your source and can be used to navigate within your
source.
Tips:
v By default the Date area does not appear in the editor. If you want the
date to appear all the time, you need to set the preference in Window >
Preferences > Remote Systems > Remote Systems LPEX Editor. You can
turn on the date area for a single session through the Source menu in the
pop-up in the editor view.
v While you can use X, XX, Xn to exclude lines, a + appears which allows you
to easily peek at and hide excluded lines.
v In addition to excluded lines, use the Filter menu in the pop-up menu in
the editor view to show comments, control statements, for example. Each
language has its own list of items that it can display in the filter menu.
v The pop-up menu in the editor view only shows appropriate items
depending on source type being edited, cursor position within the source,
and whether or not there is text selected.
v You can use the pop-up menu or Ctrl+2 to split the current editor view to
work with different parts of the same member. Up to 5 splits are allowed.
lxiv
Help (F1 in the Remote Systems LPEX Editor) is not just available for errors, but
for source too. Pressing F1 for context-sensitive help opens the reference manual at
the topic for the code you are editing. For example, when you press F1 on an ILE
RPG operation code, the help for that operation code opens in the help browser.
Reference manuals are also accessible through the Source menu in the Remote
Systems LPEX Editor. This reduces the requirement for printed manuals.
lxv
F4 allows you to prompt when editing in the Remote Systems LPEX Editor. For
languages other than CL, the Prompt view opens and allows you to modify your
source. For CL, a window opens with your prompt. F1 context-sensitive help is
available from all prompts.
For more information, see the topic Editing RPG, COBOL, CL, C, C++, and DDS
members in the online help in the client product. See also Editing source in the
tutorials.
Verifiers and System i Error List view
lxvi
Syntax checking ensures that there are no errors on the line that you type, but the
Remote Systems LPEX Editor provides an additional check, called the Verifier. A
verifier does the same syntax checking and semantic checking that the compiler
does, without generating an object. This means that if you try to use an undeclared
variable, the verifier will let you know.
The verifier function is available for COBOL, RPG and DDS from the Source menu,
or by pressing Ctrl+Shift+V. Use the Source menu to verify with prompt and
specify additional options.
Any errors detected by a verify will appear in the System i Error List view, exactly
as those from a compile.
The System i Error List view allows you to insert the errors into the editor view by
double-clicking. Use the F1 key to get help for errors, and use the View menu to
filter errors that you dont want to see (for example, perhaps you want to ignore
informational messages). The menu can also be used to dictate whether or not, and
how, error messages are inserted into the editor view.
To cleanup any inserted errors, from the editor you can use Ctrl+F5 to refresh the
list. The refresh action:
v Removes any syntax, verifier, or compile errors
v Clears any excluded lines
Or you can use the Remove messages menu option from the Source menu.
The System i Error List view can also be used as a To Do list. As you modify lines,
they are either marked with an X to indicate that the line has been deleted, or with
a check mark, to indicate that an error has been addressed. Only another verify
will ensure that the errors have truly been fixed.
Using the verifier has the following advantages:
v You can ensure a clean compile before actually compiling. This can be important
for machines where compiling must only occur on off-peak times.
v If you are working offline, you can ensure that you are working with source that
will compile when you reconnect to your System i.
Using the application development tools in the client product
lxvii
The System i Error List view (whether being used for compile results or verify) has
several advantages as well:
v There is no need to switch between a spooled file and the source, or have two
emulators open, as both are visible simultaneously, and you can have all the
errors inserted into the source.
v When used as a To Do list, it is easy to ensure that all errors are addressed.
There is no need to fix an error, recompile, fix another, and so on, until all errors
are addressed.
v When an error occurs in a /COPY or a /INCLUDE member in RPG, or a Copy book
in COBOL, double-clicking the error opens that member quickly for you and
inserts the errors, as with the primary source member.
v F1 help for errors helps you fix the error quickly without using a reference
manual.
v Using the preferences you can hide any messages you dont want to look at
(such as informational or warning messages), making it easier to ensure that you
address important errors quickly.
v For more information, see the topic Verifying and the topic The Error List view in
the online help in the client product. See also Verify the source in the tutorials.
Content assist, templates, and RPG wizards
The Remote Systems LPEX Editor has several functions which help you quickly
enter code.
Content assist (Ctrl+Space) will propose, display, and insert code completions at
the cursor position. Based on the previously typed characters, or in the case of
RPG, column position as well, invoking content assist presents you with possible
valid completions to the code you have already entered. For example, this can be
useful when you are unsure of the number of parameters required when calling a
procedure, or even the parameter types.
For more information, see the topic Content assist in the online help in the client
product.
Templates can be used to generate frequently used blocks of code. They can be
imported and exported, which means they can be shared. For example, if you have
a standard header that must be added to each program, or a standard interface,
you can define a template, and insert it by typing its name and then Ctrl+Space.
lxviii
For more information, see the topic Completing code with content assist and the topic
Templates in the online help in the client product. See also Verifying the source in the
tutorials.
Tip: The content assist function and Outline view in RPG is driven by the
information generated by a verify. This is what pulls in external information
like procedures found in a /COPY member, or fields and records from a
display file. It's important to refresh the Outline view at least once before
invoking content assist, or only limited content assist will be available.
There are three RPG wizards that can help you create code quickly:
v D Specification wizard
v Procedure wizard
v Java Method Call wizard
lxix
For more information, see the topic Creating an RPG Definition Specification in the
Remote Systems LPEX Editor in the online help in the client product.
Additional Remote Systems LPEX Editor parser action and preferences
Additional preferences and actions are available for the System i languages:
v Column Sensitive Editing: This function is useful for column-sensitive languages
like RPG and DDS. Normally in a windows application, inserting and deleting
text pushes the remaining text left or right, and for these languages results in a
syntax error. Enabling column sensitive editing limits insertion and deletion to
the columns specified for the language.
lxx
v Signatures: Available for RPG and DDS, enabling this feature automatically flags
each line with the specified signature. Note that modified lines in the Remote
Systems LPEX Editor have the date changed as in SEU, regardless of member
type.
v Automatic-uppercasing: Uppercases modified lines. Available for CL, DDS, RPG,
COBOL members
v Automatic-indent: Indents the cursor when enter is pressed on the following line
to help pretty-print your source. Available for CL, RPGLE.
v Automatic-formatting: Formats your source as you enter it, according to
specified preferences. Available for CL and free-form SQLRPGLE.
v Open/Browse /COPY member or Copy book: For RPG and COBOL languages,
you can open or browse members referred in the source through the pop-up in
the Editor menu.
v Show block nesting: Using Ctrl+Shift+O, or from the Source menu in the
pop-up menu, you can display an arrow indicating the nesting level at the
cursor location.
v Show fields: When a file is referenced in a program, you can use this menu
option from the pop-up menu to show the fields in the file in the System i Table
view. Available in RPG, COBOL, and CL.
v RPG actions:
Convert to free form (RPGLE)
Content assist, templates, and RPG wizards, are designed to speed up and improve
your editing experience.
Additional LPEX keys
In the Remote Systems LPEX Editor, most functions are available through menus
and keystrokes. Here is a list of additional keys you might find useful in LPEX:
Table 23.
Key combination
Description
Ctrl+Home
Ctrl+End
Ctrl+L
Alt+S
Split a line
Alt+J
Join a line
Alt+L
Select a line
Alt+R
Select a rectangle
Ctrl+W
Ctrl+Z
Undo
Ctrl+Y
Redo
Ctrl+S
Save
Ctrl+M
lxxi
Description
Ctrl+Shift+M
Find match
Printing
Like most Windows applications, printing can be done through the File > Print
menu option or by pressing Ctrl+P. This can be done while editing. Printing also
tokenizes the printed source, as long as you select the Tokenized checkbox.
Printing in the Remote Systems LPEX Editor prints to your Windows printer, not
the System i printer. Print options are available in Window >Preferences > LPEX
Editor > Print.
The following substitution variables are available for use in the header and footer:
v %p: page number
v %n: source name, base file name, or document name
v %f: full path file name or document name
v %d: date
v %t: time
Tips:
v To print to a host printer, add a user action in the Remote Systems view
and the System i Table view that invokes the STRSEU command with the
print option.
v Printing with tokenization is best done on a color printer
Find and replace in the Remote Systems LPEX Editor
In the Remote Systems LPEX Editor you can use Ctrl+F to open the Find function
in LPEX. The search function is very flexible. You can specify regular expressions
that allow you to search for a pattern. For example, if you specify this|that as the
lxxii
search string with the Regular expression check box selected, then the editor
searches for lines with this or that on them. You can use Ctrl+N or Shift+F4 to
find the next match.
Tips:
v Ensure column sensitive editing is enabled to make sure that replace does
not shift text inappropriately
v Click the All button to have all the lines that do not contain the search
string filtered out, so that you only see matching lines (they can easily be
shown again by clicking the + in front of the prefix area, or by pressing
Ctrl+W)
For more information, see the topic Finding and replacing text in the online help in
the client product. See also Finding and replacing text in the tutorials.
Compare a file in the Remote Systems LPEX Editor
Comparing members in the Remote Systems LPEX Editor requires you to open a
member in the editor. Once open, you can easily compare that member to another
by selecting the Compare button in the toolbar or through the Edit > Compare >
Compare file menu option.
Once the compare has been triggered, source appears merged with different lines
flagged in color. Pink is the color used for the source being compared to, and
yellow is the color for the opened source.
Unlike on the System i , where you have to flip between the spooled file and the
source opened in SEU, comparing in the Remote Systems LPEX Editor allows you
to continue to modify the member that was opened originally. Use Ctrl+Shift+N to
navigate to the next mismatch and Ctrl+Shift+P for the previous mismatch. If you
do modify source, you can use Ctrl+Shift+R to refresh the compare and finally
Edit > Compare >Clear to end.
lxxiii
Tips:
v Specify additional preferences in Window > Preferences > LPEX Editor >
Compare.
v Unlike other compare tools in eclipse, the Remote Systems LPEX Editor is
sequence number aware, and will not mismatch lines just because the
sequence number has been modified.
v For more information about comparing a file, see the topic Editing RPG,
COBOL, CL, C, C++, and DDS members in the online help in the client
product. See also Comparing file differences from the Remote Systems view in
the tutorials.
Compile from the Remote Systems LPEX Editor
When you have source open in the Remote Systems LPEX Editor, it's not
convenient to go to the Remote Systems view or System i Table view to issue a
compile. Instead you can use one of the following:
v Toolbar button (uses the last used compile command for the member type to
compile without prompt)
v Ctrl+Shift+C (uses the last used compile command for the member type to
compile without prompt)
v Compile menu (where you can choose to compile with and without prompts,
and select whichever compile command you want for the item). If you have not
saved prior to compiling, you are prompted to do so.
For more information, see the topic Compiling in the online help in the client
product. See also Compiling source remotely in the tutorials.
Comparing the Remote Systems LPEX Editor to SEU
The following table compares the features of the Remote Systems LPEX Editor
described in this topic to equivalent or similar features in SEU.
lxxiv
Table 24.
In the Remote Systems LPEX Editor
In SEU
Full screen mode for both edit and browse (double-click the
editor tab). However, many more lines are visible in Remote
Systems LPEX Editor in full screen than in SEU.
Not available
Prompter is available to
assist in code creation
Not available
lxxv
lxxvi
RPG IV Specifications
RPG code is written on a variety of specification forms, each with a specific set of
functions. Many of the entries which make up a specification type are
position-dependent. Each entry must start in a specific position depending on the
type of entry and the type of specification.
There are seven types of RPG IV specifications. Each specification type is optional.
Specifications must be entered into your source program in the order shown below.
Main source section:
1. Control specifications provide the compiler with information about generating
and running programs, such as the program name, date format, and use of
alternate collating sequence or file translation.
2. File description specifications describe all the files that your program uses.
3. Definition specifications describe the data used by the program.
4. Input specifications describe the input records and fields used by the program.
5. Calculation specifications describe the calculations done on the data and the
order of the calculations. Calculation specifications also control certain input
and output operations.
6. Output specifications describe the output records and fields used by the
program.
Subprocedure section:
1. Procedure specifications mark the beginning and end of the subprocedure,
indicate the subprocedure name, and whether it is exported.
2. Definition specifications describe the local data used by the subprocedure.
3. Calculation specifications describe the calculations done on both the global
and local data and the order of the calculations.
RPG IV Overview
Cycle Programming
When a system processes data, it must do the processing in a particular order. This
logical order is provided by:
v The ILE RPG compiler
v The program code
The logic the compiler supplies is called the program cycle. When you let the
compiler provide the logic for your programs, it is called cycle programming.
The program cycle is a series of steps that your program repeats until an
end-of-file condition is reached. Depending on the specifications you code, the
program may or may not use each step in the cycle.
If you want to have files controlled by the cycle, the information that you code on
RPG specifications in your source program need not specify when records for these
files are read. The compiler supplies the logical order for these operations, and
some output operations, when your source program is compiled.
If you do not want to have files controlled by the cycle, you must end your
program some other way, either by creating an end-of-file condition by setting on
the last record (LR) indicator, by creating a return condition by setting on the
return (RT) indicator, or by returning directly using the RETURN operation.
Note: No cycle code is generated for subprocedures or when MAIN or NOMAIN
is specified on the control specification. See
#
#
Figure 1 shows the specific steps in the general flow of the RPG program cycle.
Write
heading and
detail lines
Start
Perform
detail
calculations
Perform
total
calculations
Get input
record
No
Move fields
LR on
Write
total
output
Yes
End of
program
1
RPG IV Overview
2
RPG reads the next record and sets on the record identifying and control
level indicators.
3
4
5
6
The fields of the selected input records move from the record to a
processing area. RPG sets on field indicators.
7
Subprocedure logic
The general flow of a subprocedure is much simpler: the calculations of a
subprocedure are done once, and then the subprocedure returns. There is no cycle
code generated for a subprocedure.
Indicators
An indicator is a one-byte character field that is either set on ('1') or off ('0'). It is
generally used to indicate the result of an operation or to condition (control) the
processing of an operation. Indicators are like switches in the flow of the program
logic. They determine the path the program will take during processing,
depending on how they are set or used.
Indicators can be defined as variables on the definition specifications. You can also
use RPG IV indicators, which are defined either by an entry on a specification or
by the RPG IV program itself.
RPG IV Overview
Each RPG IV indicator has a two-character name (for example, LR, 01, H3), and is
referred to in some entries of some specifications just by the two-character name,
and in others by the special name *INxx where xx is the two-character name. You
can use several types of these indicators; each type signals something different. The
positions on the specification in which you define an indicator determine the use
of the indicator. Once you define an indicator in your program, it can limit or
control calculation and output operations.
Indicator variables can be used any place an indicator of the form *INxx may be
used with the exception of the OFLIND and EXTIND keywords on the file
description specifications.
An RPG program sets and resets certain indicators at specific times during the
program cycle. In addition, the state of indicators can be changed explicitly in
calculation operations.
Operation Codes
The RPG IV programming language allows you to do many different types of
operations on your data. Operation codes, entered on the calculation specifications,
indicate what operations will be done. For example, if you want to read a new
record, you could use the READ operation code. The following is a list of the types
of operations available.
v Arithmetic operations
v Array operations
v Bit operations
v Branching operations
v Call operations
v Compare operations
v Conversion operations
v Data-area operations
v Date operations
v Declarative operations
v Error-handling operations
v File operations
v Indicator-setting operations
v Information operations
v Initialization operations
v Memory management operations
v Move operations
v Move zone operations
v Result operations
v Size operations
v String operations
v Structured programming operations
v Subroutine operations
v Test operations
EMP_NAME
EMP_RATE
22
27
The second file, TRANSACT, tracks the number of hours each employee worked
for that week and any bonus that employee may have received. The figure below
shows the format of a transaction record:
TRN_REC
TRN_NUMBER
TRN_HOURS
TRN_BONUS
10
16
D Heading2
C
______ ________________ ______ _D
____ _______ __________
D CalcPay
PR
8P 2
D
Rate
5P 2 VALUE
D
Hours
10U 0 VALUE
D
Bonus
5P 2 VALUE
The output specifications describe what fields are to be written on the QSYSPRT
output:
v The Heading Lines that contain the constant string 'PAYROLL REGISTER' as
well as headings for the detail information will be printed if indicator 1P is on.
Indicator 1P is turned on by the ILE RPG program cycle during the first cycle.
v The Detail Lines are conditioned by the indicators 1P and 99. Detail Lines are
not printed at 1P time. The N99 will only allow the Detail lines to be printed if
indicator 99 is off, which indicates that the corresponding employee record has
been found. If the indicator 99 is on, then the employee number and the
constant string '** NOT ON EMPLOYEE FILE **' will be printed instead.
v The Total Line contains the constant string 'END OF LISTING'. It will be printed
during the last program cycle.
A Subprocedure
The subprocedure calculates the pay for the employee using the parameters passed
to it. The resulting value is returned to the caller using the RETURN statement.
The procedure specifications indicate the beginning and end of the procedure. The
definition specifications define the return type of the procedure, the parameters to
the procedure, and the local variable Overtime.
P CalcPay
D CalcPay
D
Rate
D
Hours
D
Bonus
D Overtime
B
PI
8P
5P
10U
5P
5P
2
2
0
2
2
VALUE
VALUE
VALUE
INZ(0)
/free
// Determine any overtime hours to be paid.
if Hours > 40;
Overtime = (Hours - 40) * Rate * 1.5;
Hours = 40;
endif;
// Calculate the total pay and return it to the caller.
return Rate * Hours + Bonus + Overtime;
/end-free
P CalcPay
E
10
*------------------------------------------------------------------------*
* Constant Declarations
*
*------------------------------------------------------------------------*
D Heading1
C
NUMBER NAME
RATE
HD
OURS BONUS
PAY
D Heading2
C
______ ________________ ______ _D
____ _______ __________
*------------------------------------------------------------------------*
* Prototype Definition for subprocedure CalcPay
*
*------------------------------------------------------------------------*
D CalcPay
PR
8P 2
D
Rate
5P 2 VALUE
D
Hours
10U 0 VALUE
D
Bonus
5P 2 VALUE
*------------------------------------------------------------------------*
* For each record in the transaction file (TRANSACT), if the employee
*
* is found, compute the employees pay and print the details.
*
*------------------------------------------------------------------------*
/free
chain trn_number emp_rec;
if %found(emp_rec);
pay = CalcPay (emp_rate: trn_hours: trn_bonus);
endif;
/end-free
*------------------------------------------------------------------------*
* Report Layout
*
* -- print the heading lines if 1P is on
*
* -- if the record is found (indicator 99 is off) print the payroll
*
*
details otherwise print an exception record
*
* -- print END OF LISTING when LR is on
*
*------------------------------------------------------------------------*
OQSYSPRT
H
1P
2 3
O
35 PAYROLL REGISTER
O
*DATE
Y
60
O
H
1P
2
O
60 Heading1
O
H
1P
2
O
60 Heading2
O
D
N1PN99
2
O
TRN_NUMBER
5
O
EMP_NAME
24
O
EMP_RATE
L
33
O
TRN_HOURS
L
40
O
TRN_BONUS
L
49
O
Pay
60 $
0.
O
D
N1P 99
2
O
TRN_NUMBER
5
O
35 ** NOT ON EMPLOYEE FILE **
O
T
LR
O
33 END OF LISTING
Figure 4. A Sample Payroll Calculation Program (Part 2 of 3)
11
Using IBM i
*------------------------------------------------------------------------*
* Subprocedure -- calculates overtime pay.
*
*------------------------------------------------------------------------*
P CalcPay
B
D CalcPay
PI
8P 2
D
Rate
5P 2 VALUE
D
Hours
10U 0 VALUE
D
Bonus
5P 2 VALUE
D Overtime
S
5P 2 INZ(0)
/free
// Determine any overtime hours to be paid.
if Hours > 40;
Overtime = (Hours - 40) * Rate * 1.5;
Hours = 40;
endif;
// Calculate the total pay and return it to the caller.
return Rate * Hours + Bonus + Overtime;
/end-free
P CalcPay
E
Figure 4. A Sample Payroll Calculation Program (Part 3 of 3)
Using IBM i
The operating system that controls all of your interactions with System i is called
the IBM i. From your workstation, IBM i allows you to:
v Sign on and sign off
v Interact with the displays
v Use the online help information
v
v
v
v
You can obtain a complete list of publications that discuss the IBM i system at the
i5/OS Information Center.
12
Using IBM i
Table 25. Commonly Used CL Commands
Action
Using System Menus
Calling
Compiling
Binding
Debugging
Creating Files
CL command
Result
GO MAIN
GO INFO
GO CMDRPG
GO CMDCRT
GO CMDxxx
CALL program-name
Runs a program
CRTxxxMOD
CRTBNDxxx
CRTPGM
CRTSRVPGM
UPDPGM
STRDBG
ENDDBG
CRTPRTF
CRTPF
CRTSRCPF
CRTLF
ILE RPG
ILE COBOL
ILE C/C++
Application Development ToolSet (ADTS)
Chapter 1. Overview of the RPG IV Programming Language
13
14
15
16
C++
BASIC (PRPQ)
FORTRAN
CL
PASCAL (PRPQ)
CL
COBOL
COBOL
PL/I (PRPQ)
RPG
RPG
Program creation
Program management
Program call
Source debugging
Bindable application program interfaces (APIs)
Each of the above areas is explained briefly in the following paragraphs and
discussed further in the following chapters.
Program Creation
In ILE, program creation consists of:
1. Compiling source code into modules
2. Binding (combining) one or more modules into a program object
You can create a program object much like you do in the OPM framework, with a
one-step process using the Create Bound RPG Program (CRTBNDRPG) command.
This command creates a temporary module which is then bound into a program
object. It also allows you to bind other objects through the use of a binding
directory.
Alternatively, you may create a program using separate commands for compilation
and binding. This two-step process allows you to reuse a module or update one
Copyright IBM Corp. 1994, 2010
17
RPG Module
(CRTRPGMOD)
ILE Program
(CRTBNDRPG)
ILE Program
(CRTPGM)
One-Step Process
Two-Step Process
Once a program is created you can update the program using the Update Program
(UPDPGM) or Update Service Program (UPDSRVPGM) commands. This is useful,
because it means you only need to have the new or changed module objects
available to update the program.
For more information on the one-step process, see Chapter 6, Creating a Program
with the CRTBNDRPG Command, on page 61. For more information on the
two-step process, see Chapter 7, Creating a Program with the CRTRPGMOD and
18
Program Management
ILE provides a common basis for:
v Managing program flow
v Sharing resources
v Using application program interfaces (APIs)
v Handling exceptions during a program's run time
It gives RPG users much better control over resources than was previously
possible.
ILE programs and service programs are activated into activation groups which are
specified at program-creation time. The process of getting a program or service
program ready to run is known as activation. Activation allocates resources within
a job so that one or more programs can run in that space. If the specified activation
group for a program does not exist when the program is called, then it is created
within the job to hold the program's activation.
An activation group is the key element governing an ILE application's resources
and behavior. For example, you can scope commitment-control operations to the
activation group level. You can also scope file overrides and shared open data
paths to the activation group of the running application. Finally, the behavior of a
program upon termination is also affected by the activation group in which the
program runs.
For more information on activation groups, see Managing Activation Groups on
page 114.
You can dynamically allocate storage for a run-time array using the bindable APIs
provided for all ILE programming languages. These APIs allow single- and
mixed-language applications to access a central set of storage management
functions and offer a storage model to languages that do not now provide one.
RPG offers some storage management capabilities using operation codes. For more
information on storage management, see Managing Dynamically-Allocated
Storage on page 117.
Program Call
In ILE, you can write applications in which ILE RPG programs and OPM RPG/400
programs continue to interrelate through the traditional use of dynamic program
calls. When using such calls, the calling program specifies the name of the called
program on a call statement. The called program's name is resolved to an address
at run time, just before the calling program passes control to the called program.
You can also write ILE applications that can interrelate with faster static calls.
Static calls involve calls between procedures. A procedure is a self-contained set of
code that performs a task and then returns to the caller. An ILE RPG module
consists of an optional main procedure followed by zero or more subprocedures.
Because the procedure names are resolved at bind time (that is, when you create
the program), static calls are faster than dynamic calls.
Static calls also allow
Chapter 2. RPG Programming in ILE
19
Operational descriptors
Omitted parameters
The passing of parameters by value
The use of return values
A greater number of parameters to be passed
Source Debugging
Use WebSphere Development Studio Client for System i. This is the recommended
method and documentation about debugging programs and appears in that
product's online help. With the integrated i5/OS debugger you can debug your
program running on the System i from a graphical user interface on your
workstation. You can also set breakpoints directly in your source before running
the debugger. The integrated i5/OS debugger client user interface also enables you
to control program execution. For example, you can run your program, set line,
watch, and service entry point breakpoints, step through program instructions,
examine variables, and examine the call stack. You can also debug multiple
applications, even if they are written in different languages, from a single debugger
window. Each session you debug is listed separately in the Debug view.
In ILE, you can perform source-level debugging on any single- or mixed-language
ILE application. The ILE source debugger also supports OPM programs. You can
control the flow of a program by using debug commands while the program is
running. You can set conditional and unconditional job or thread breakpoints prior
to running the program. After you call the program, you can then step through a
specified number of statements, and display or change variables. When a program
stops because of a breakpoint, a step command, or a run-time error, the pertinent
module is shown on the display at the point where the program stopped. At that
point, you can enter more debug commands.
For information on the debugger, refer to Chapter 12, Debugging Programs, on
page 229.
Bindable APIs
ILE offers a number of bindable APIs that can be used to supplement the function
currently offered by ILE RPG. The bindable APIs provide program calling and
activation capability, condition and storage management, math functions, and
dynamic screen management.
Some APIs that you may wish to consider using in an ILE RPG application
include:
v CEETREC Signal the Termination-Imminent Condition
v CEE4ABN Abnormal End
v CEECRHP Create your own heap
v CEEDSHP Discard your own heap
v CEEFRST Free Storage in your own heap
20
Multithreaded Applications
#
#
#
#
#
#
#
#
The RPG support for threads ensures that your static storage is handled in a
threadsafe way. However, you are responsible for other aspects of thread-safety for
your application. You must ensure that all the programs that your application uses
are threadsafe, that you manage any shared storage in a threadsafe way, and that
you only use those aspects of the system that are threadsafe.
Issue
THREAD(*CONCURRENT)
THREAD(*SERIALIZE)
#
#
#
#
#
#
#
Is source-modification
required to achieve
thread-safety (other than
coding the THREAD
keyword)?
No
#
#
#
#
#
#
#
#
#
#
#
Yes
No
#
#
#
#
#
#
#
#
#
#
Is there a risk of
bottlenecks?
#
#
Is thread-local storage
supported?
No
21
Issue
THREAD(*CONCURRENT)
THREAD(*SERIALIZE)
#
#
Yes
#
#
#
#
Yes
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
22
Method
Use the following general approach to create such a program:
1. Convert your source to RPG IV using the CVTRPGSRC command.
Be sure to convert all /COPY members that are used by the source you are
converting.
2. Create a program object using the CRTBNDRPG command, specifying
DFTACTGRP(*YES).
Specifying DFTACTGRP(*YES) means that the program object will run only in the
default activation group. (The default activation group is the activation group
where all OPM programs are run.) As a result, the program object will interact
well with OPM programs in the areas of override scoping, open scoping, and
RCLRSC.
When you use this approach you cannot make use of ILE static binding. This
means that you cannot code a bound procedure call in your source, nor can you
use the BNDDIR or ACTGRP parameters on the CRTBNDRPG command when
creating this program.
23
OPM-Compatible Application
been moved to ILE; the remaining programs are unchanged.
Job
Default Activation Group
*PGM(X)
OPM CL
*PGM(Y)
ILE RPG
*PGM(Z)
OPM RPG
Effect of ILE
The following deals with the effects of ILE on the way your application handles:
Program call
Data
Files
Errors
Related Information
24
Converting to RPG IV
OPM-Compatible Application
Exception handling differences
Differences between OPM and ILE RPG Exception
Handling on page 290
Method
Use the following general approach to create such a program:
1. If starting with RPG III source, convert your source to RPG IV using the
CVTRPGSRC command.
If converting, be sure to convert all /COPY members and any programs that
are called by the source you are converting. Also, if you are using CL to call the
program, you should also make sure that you are using ILE CL instead of OPM
CL.
2. Determine the activation group the program will run in.
You may want to name it after the application name, as in this example.
3. Identify the names of the binding directories, if any, to be used.
It is assumed with this approach that if you are using a binding directory, it is
one that is already created for you. For example, there may be a third-party
service program that you may want to bind to your source. Consequently, all
you need to know is the name of the binding directory.
4. Create an ILE program using CRTBNDRPG, specifying DFTACTGRP(*NO), the
activation group on the ACTGRP parameter, and the binding directory, if any,
on the BNDDIR parameter.
Note that if ACTGRP(*CALLER) is specified and this program is called by a
program running in the default activation group, then this program will behave
according to ILE semantics in the areas of override scoping, open scoping, and
RCLRSC.
The main drawback of this strategy is that you do not have a permanent module
object that you can later reuse to bind with other modules to create an ILE
program. Furthermore, any procedure calls must be to modules or service
programs that are identified in a binding directory. If you want to bind two or
more modules without using a binding directory when you create the program,
you need to use the third strategy.
25
*PGM(Y)
ILE RPG
*SRVPGM(Z)
Supplied Service
Program
Effect of ILE
The following deals with the effects of ILE on the way your program handles:
Program call
Data
26
Files
Errors
Related Information
Converting to RPG IV
Activation groups
RCLRSC
27
Method
Because this approach is the most flexible, it includes a number of ways in which
you might create an ILE application. The following list describes the main steps
that you may need to perform:
1. Create a module from each source member using the appropriate command, for
example, CRTRPGMOD for RPG source, CRTCLMOD for CL source, etc..
2. Determine the ILE characteristics for the application, for example:
v Determine which module will contain the procedure that will be the starting
point for the application. The module you choose as the entry module is the
first one that you want to get control. In an OPM application, this would be
the command processing program, or the program called because a menu
item was selected.
v Determine the activation group the application will run in. (Most likely you
will want to run in a named activation group, where the name is based on
the name of the application.)
v Determine the exports and imports to be used.
3. Determine if any of the modules will be bound together to create a service
program. If so, create the service programs using CRTSRVPGM.
4. Identify the names of the binding directories, if any, to be used.
It is assumed with this approach that if you are using a binding directory, it is
one that is already created for you. For example, there may be a third-party
service program that you may want to bind to your source. Consequently, all
you need to know is the name of the binding directory.
5. Bind the appropriate modules and service programs together using CRTPGM,
specifying values for the parameters based on the characteristics determined in
step 2.
An application created using this approach can run fully protected, that is, within
its own activation group. Furthermore, it can be updated easily through use of the
UPDPGM or UPDSRVPGM commands. With these commands you can add or
replace one or more modules without having to re-create the program object.
28
*PGM(Y)
RPG *MODULE(Y1)
RPG *MODULE(Y2)
RPG *MODULE(Y3)
RPG *MODULE(Y4)
The call from program X to program Y is a dynamic call. The calls among the
modules in program Y are static calls.
See Effect of ILE on page 26 for details on the effects of ILE on the way your
application handles calls, data, files and errors.
29
CL *MODULE(Y1)
RPG *MODULE(Y2)
C *MODULE(Y3)
RPG *MODULE(Y4)
The call from program Y to the OPM API is a dynamic call. The calls among the
modules in program Y are static calls.
See Effect of ILE on page 26 for details on the effects of ILE on the way your
application handles calls, data, files and errors.
30
RPG
*SRVPGM(Z)
C *MODULE(Z1)
CL *MODULE(Z2)
The calls from program X to service programs Y and Z are static calls.
See Effect of ILE on page 26 for details on the effects of ILE on the way your
application handles calls, data, files and errors.
Related Information
Two-step creation process
Activation groups
Exception Handling
Service programs
Updating a Program
A Strategy to Avoid
ILE provides many alternatives for creating programs and applications. However,
not all are equally good. In general, you should avoid a situation where an
application consisting of OPM and ILE programs is split across the OPM default
activation group and a named activation group. In other words, try to avoid the
scenario shown in Figure 11 on page 32.
31
A Strategy to Avoid
Job
Default Activation Group
*PGM(X)
CL
*SRVPGM(Z)
RPG
Figure 11. Scenario to Avoid. An application has a CL program in the OPM default activation
group and ILE programs in a named activation group.
When an application is split across the default activation group and any named
activation group, you are mixing OPM behavior with ILE behavior. For example,
programs in the default activation group may be expecting the ILE programs to
free their resources when the program ends. However, this will not occur until the
activation group ends.
Similarly, the scope of overrides and shared ODPs will be more difficult to manage
when an application is split between the default activation group and a named
one. By default, the scope for the named group will be at the activation group
level, but for the default activation group, it can be either call level or job level, not
activation group level.
Note: Calling an ILE program from the command line, or from an OPM program
that simply makes a call, is not a problem. The problems, which can all be
solved, stem from OPM programs and ILE programs using shared resources
such as overrides and commitment control, and from OPM programs trying
to using OPM commands such as RCLRSC which have no effect on
programs running in a named activation group.
32
An ILE RPG module consists of zero or more subprocedures and optionally, a main
procedure. A main procedure is a procedure that can be specified as the program
entry procedure (and so receive control when an ILE program is first called). A
cycle-main procedure can be defined in the main source section, which is the set of
H, F, D, I, C, and O specifications that begin a module; a linear-main procedure
can be specified in the subprocedure section and specially-designated with the
MAIN keyword on a Control specification. For additional information about
procedures and the program logic cycle, refer to the "WebSphere Development Studio
ILE RPG Reference".
A subprocedure is a procedure that is specified after the main source section. A
subprocedure differs from a main procedure primarily in that:
v Names that are defined within subprocedure are not accessible outside the
subprocedure.
v No cycle code is generated for the subprocedure.
v The call interface must be prototyped.
v Calls to subprocedures must be bound procedure calls.
#
#
#
33
*MODULE
Main
Source
Section
Cycle-Main
Procedure
H specifications
F specifications
D specifications - Data items visible
throughout module
I specifications
C specifications
O specifications
Subprocedure 1
P specification
D specifications - Data items visible only
to Subprocedure 1
C specifications - Can access local and
global data items
P specifications
Global
Scope
Local
Scope
Subprocedure 2
P specification
D specifications - Data items visible
only to Subprocedure 2
C specifications - Can access local and
global data items
P specifications
Local
Scope
#
#
#
As the picture suggests, you can now code subprocedures to handle particular
tasks. These tasks may be needed by the main procedures or by other modules in
the application. Furthermore, you can declare temporary data items in
subprocedures and not have to worry if you have declared them elsewhere in the
module.
Prototyped Calls
To call a subprocedure, you must use a prototyped call. You can also call any
program or procedure that is written in any language in this way. A prototyped
34
The prototype is used by the compiler to call the program or procedure correctly,
and to ensure that the caller passes the correct parameters. Figure 13 shows a
prototype for a procedure FmtCust, which formats various fields of a record into
readable form. It has two output parameters.
// Prototype for procedure FmtCust (Note the PR on definition
// specification.) It has two output parameters.
D FmtCust
PR
D Name
100A
D Address
100A
Figure 13. Prototype for FmtCust Procedure
|
|
|
|
|
|
If the procedure is coded in the same module as the call, specifying the prototype
is optional. If the prototype is not specified, the compiler will generate the
prototype from the procedure interface. However, if the procedure is exported and
it is also called from another RPG module or program, a prototype should be
specified in a copy file, and the copy file should be copied into both the calling
module and the module that is exporting the procedure.
If the program or procedure is prototyped, you call it with CALLP or within an
expression if you want to use the return value. You pass parameters in a list that
follows the name of the prototype, for example, name (parm1 : parm2 : ...).
Figure 15 on page 36 shows a call to FmtCust. Note that the names of the output
parameters, shown above in Figure 13, do not match those in the call statement.
The parameter names in a prototype are for documentation purposes only. The
prototype serves to describe the attributes of the call interface. The actual definition
35
CALLP
FmtCust(RPTNAME : RPTADDR)
Using prototyped calls you can call (with the same syntax):
v Programs that are on the system at run time
v Exported procedures in other modules or service programs that are bound in the
same program or service program
v Subprocedures in the same module
FmtCust calls FmtAddr to format the address. Because FmtCust wants to use the
return value, the call to FmtAddr is made in an expression. Figure 16 shows the
call.
//-------------------------------------------------------------// Call the FmtAddr procedure to handle the address
//-------------------------------------------------------------Address = FmtAddress (STREETNUM : STREETNAME :
CITY : STATE : ZIP);
Figure 16. Calling the FmtAddr Procedure
The use of procedures to return values, as in the above figure, allows you to write
any user-defined function you require. In addition, the use of a prototyped call
interface enables a number of options for parameter passing.
v Prototyped parameters can be passed in several ways: by reference, by value (for
procedures only), or by read-only reference. The default method for RPG is to
pass by reference. However, passing by value or by read-only reference gives
you more options for passing parameters.
v If the prototype indicates that it is allowed for a given parameter, you may be
able to do one or more of the following:
Pass *OMIT
Leave out a parameter entirely
Pass a shorter parameter than is specified (for character and graphic
parameters, and for array parameters)
36
FmtCust
Subprocedure to format
customer data into report form
TIP
When coding subprocedures that use global fields, you may want to establish
a naming convention that shows the item to be global. In this example, the
uppercase field names indicate DDS fields. Another option would be to prefix
'g_', or some other string to indicate global scope.
If the record is in arrears, the subprocedure returns '1' to the main procedure.
37
//-------------------------------------------------------------// InArrears
//
// Parameters: (none)
// Globals:
DUEDATE, AMOUNT, CurDate
//
// Returns:
1 if the customer is in arrears
//-------------------------------------------------------------P InArrears
B
1
D InArrears
PI
1A
2
// Local declarations
D DaysLate
S
10I 0
3
D DateDue
S
D
3
// Body of procedure
/free
DateDue = %date (DUEDATE: *ISO);
DaysLate = %diff (CurDate: DateDue: *d);
// The data in the input file comes from another type
// of computer, and the AMOUNTC field is a character
// string containing the numeric value. This string
// must be converted to the numeric AMOUNT field
// for printing.
AMOUNT = %dec(AMOUNTC : 31 : 9);
if DaysLate > 60 AND AMOUNT > 100.00;
return 1;
4
endif;
return 0;
4 5
/end-free
P InArrears
E
1
Figure 18. Source for Subprocedure InArrears
Figure 18 shows the main elements that are common to all subprocedures.
1
2
3
Any variables or prototypes that are used by the subprocedure are defined
after the procedure interface definition.
4
5
If the record is not in arrears, the subprocedure returns '0' to the main
procedure.
For all subprocedures, and also for a cycle-main procedure with prototyped entry
parameters, you need to define a procedure interface. A procedure interface
definition is a repeat of the prototype information, if the prototype was specified,
within the definition of a procedure. It is used to define the entry parameters for
the procedure. The procedure interface definition is also used to ensure that the
internal definition of the procedure is consistent with the external definition (the
prototype). When the prototype is not specified, the compiler generates the
prototype from the procedure interface, so the procedure interface definition
provides both the internal definition and the external definition. In the case of
InArrears, there are no entry parameters.
|
|
|
|
|
|
|
|
|
|
38
B
PI
100A
100A
/free
//-------------------------------------------------------------// CUSTNAME and CUSTNUM are formatted to look like this:
// A&P Electronics
(Customer number 157)
//-------------------------------------------------------------Name = CUSTNAME + + (Customer number
+ %char(CUSTNUM) + );
//-------------------------------------------------------------//
Call the FmtAddr procedure to handle the address
//-------------------------------------------------------------Address = FmtAddress (STREETNUM : STREETNAME :
CITY : STATE : ZIP);
/end-free
P FmtCust
E
Figure 19. Source for Subprocedure FmtCust
Finally, consider the last subprocedure of this application, FmtAddr. Notice that
FmtAddr does not appear in the ARRSRPT module, that is shown in Figure 17 on
page 37. We decided to place FmtAddr inside another module called FMTPROCS.
FMTPROCS is a utility module that will contain any conversion procedures that
other modules might need to use.
|
|
|
|
|
|
Figure 20 on page 40 shows the source of the module FMTPROCS. Since procedure
FmtAddr is called from another module, a prototype is required. So that the
prototype can be shared, we have placed the prototype into a /COPY file which is
copied into both the calling module, to provide information about how to call the
procedure, and into the module that defines the procedure, to ensure that the
prototype matches the procedure interface.
39
//=================================================================
// Source for module FMTPROCS. This module does not have a
// main procedure, as indicated by the keyword NOMAIN.
//=================================================================
H NOMAIN
//----------------------------------------------------------------// The prototype must be available to EACH module containing
// a prototyped procedure. The /COPY pulls in the prototype
// for FmtAddr.
//----------------------------------------------------------------D/COPY QRPGLESRC,FMTPROC_P
P FmtAddr
B
EXPORT
D FmtAddr
PI
100A
VARYING
D
streetNum
10I 0
CONST
D
streetName
50A
CONST
D
city
20A
CONST
D
state
15A
CONST
D
zip
5P 0
CONST
/free
//-------------------------------------------------------------// STREETNUM, STREETNAME, CITY, STATE, and ZIP are formatted to
// look like:
//
27 Garbanzo Avenue, Smallville IN 51423
//-------------------------------------------------------------return %char(streetNum) + + %trimr(streetName)
+ , + %trim(city) + + %trim(state)
+ + %editc(zip : X);
P FmtAddr
E
Figure 20. Source for module FMTPROCS, containing subprocedure FmtAddr.
40
//=================================================================
// Source for module ARRSRPT. Contains a cycle-main procedure and
// two subprocedures: InArrears and FmtCust.
//
// Related Module: CVTPROCS (CharToNum called by InArrears)
//=================================================================
//-------------------------------------------------------------// F I L E S
//
// CUSTFILE - contains customer information
// CUSTRPT - printer file (using format ARREARS)
//-------------------------------------------------------------FCUSTFILE IP
E
DISK
FCUSTRPT
O
E
PRINTER
*--------------------------------------------------------------*
* P R O T O T Y P E S
*--------------------------------------------------------------*
/COPY QRPGLE,FMTPROC_P
*--------------------------------------------------------------*
* InArrears returns 1 if the customer is in arrears
*--------------------------------------------------------------*
D InArrears
PR
1A
*--------------------------------------------------------------*
* FmtCust formats CUSTNAME, CUSTNUM, STREETNAME etc into
* readable forms
*--------------------------------------------------------------*
D FmtCust
PR
D Name
100A
D Address
100A
Figure 22. ILE RPG Complete Source for ARRSRPT Module (Part 1 of 3)
41
*--------------------------------------------------------------*
* G L O B A L
D E F I N I T I O N S
*--------------------------------------------------------------*
D CurDate
S
D
ICUSTREC
01
*--------------------------------------------------------------*
* M A I N P R O C E D U R E
*--------------------------------------------------------------*
C
IF
InArrears() = 1
C
CALLP
FmtCust(RPTNAME : RPTADDR)
C
EVAL
RPTNUM = CUSTNUM
C
WRITE
ARREARS
C
ENDIF
C
*INZSR
BEGSR
C
MOVEL
UDATE
CurDate
C
ENDSR
*--------------------------------------------------------------*
* S U B P R O C E D U R E S
*--------------------------------------------------------------*
//-------------------------------------------------------------// InArrears
//
// Parameters: (none)
// Globals:
DUEDATE, AMOUNT, CurDate
//
// Returns: 1 if the customer is in arrears
//-------------------------------------------------------------P InArrears
B
D InArrears
PI
1A
// Local declarations
D DaysLate
S
10I 0
D DateDue
S
D
// Body of procedure
/free
DateDue = %date (DUEDATE: *ISO);
DaysLate = %diff (CurDate: DateDue: *d);
// The data in the input file comes from another type
// of computer, and the AMOUNTC field is a character
// string containing the numeric value. This string
// must be converted to the numeric AMOUNT field
// for printing.
AMOUNT = %dec(AMOUNTC : 31 : 9);
if DaysLate > 60 AND AMOUNT > 100.00;
return 1;
endif;
return 0;
/end-free
P InArrears
E
Figure 22. ILE RPG Complete Source for ARRSRPT Module (Part 2 of 3)
42
B
PI
100A
100A
/free
//-------------------------------------------------------------// CUSTNAME and CUSTNUM are formatted to look like this:
// A&P Electronics
(Customer number 157)
//-------------------------------------------------------------Name = CUSTNAME + + (Customer number
+ %char(CUSTNUM) + );
//-------------------------------------------------------------//
Call the FmtAddr procedure to handle the address
//-------------------------------------------------------------Address = FmtAddress (STREETNUM : STREETNAME :
CITY : STATE : ZIP);
/end-free
P FmtCust
E
Figure 22. ILE RPG Complete Source for ARRSRPT Module (Part 3 of 3)
43
Figure 24 and Figure 25 show the DDS source for the files CUSTFILE and
CUSTRPT respectively.
A*================================================================*
A* FILE NAME
: CUSTFILE
A* RELATED PGMS : ARRSRPT
A* DESCRIPTIONS : THIS IS THE PHYSICAL FILE CUSTFILE. IT HAS
A*
ONE RECORD FORMAT CALLED CUSTREC.
A*================================================================*
A* CUSTOMER MASTER FILE -- CUSTFILE
A
R CUSTREC
A
CUSTNUM
5 0
TEXT(CUSTOMER NUMBER)
A
CUSTNAME
20
TEXT(CUSTOMER NAME)
A
STREETNUM
5 0
TEXT(CUSTOMER ADDRESS)
A
STREETNAME
20
TEXT(CUSTOMER ADDRESS)
A
CITY
20
TEXT(CUSTOMER CITY)
A
STATE
2
TEXT(CUSTOMER STATE)
A
ZIP
5 0
TEXT(CUSTOMER ZIP CODE)
A
AMOUNTC
15
TEXT(AMOUNT OUTSTANDING)
A
DUEDATE
10
TEXT(DATE DUE)
Figure 24. DDS for CUSTFILE
A*================================================================*
A* FILE NAME
: CUSTRPT
A* RELATED PGMS : ARRSRPT
A* DESCRIPTIONS : THIS IS THE PRINTER FILE CUSTRPT. IT HAS
A*
ONE RECORD FORMAT CALLED ARREARS.
A*================================================================*
A
R ARREARS
A
2 6
A
Customer number:
A
RPTNUM
5 0
2 23
A
TEXT(CUSTOMER NUMBER)
A
RPTNAME
100A
3 10
A
TEXT(CUSTOMER NAME)
A
RPTADDR
100A
4 10
A
TEXT(CUSTOMER ADDRESS)
A
5 10Amount outstanding:
A
AMOUNT
10 2
5 35EDTWRD(
$0. )
A
TEXT(AMOUNT OUTSTANDING)
A
5 50Due date:
A
DUEDATE
10
5 60
A
TEXT(DATE DUE)
Figure 25. DDS for CUSTRPT
44
Coding Considerations
Coding Considerations
This section presents some considerations that you should be aware of before you
begin designing applications with multiple-procedure modules. The items are
grouped into the following categories:
v
v
v
v
General
Program Creation
Main Procedures
Subprocedures
General Considerations
v When coding a module with multiple procedures, you will want to make use of
/COPY files, primarily to contain any prototypes that your application may
require. If you are creating a service program, you will need to provide both the
service program and the prototypes, if any.
v Maintenance of the application means ensuring that each component is at the
most current level and that any changes do not affect the different pieces. You
may want to consider using a tool such as Application Development Manager to
maintain your applications.
For example, suppose that another programmer makes a change to the /COPY
file that contains the prototypes. When you request a rebuild of your
application, any module or program that makes use of the /COPY file will be
recompiled automatically. You will find out quickly if the changes to the /COPY
file affect the calls or procedure interfaces in your application. If there are
compilation errors, you can then decide whether to accept the change to
prototypes to avoid these errors, or whether to change the call interface.
Program Creation
v If you specify that a module does not have a main procedure then you cannot
use the CRTBNDRPG command to create the program. (A module does not have
a main procedure if the NOMAIN keyword is specified on a control
specification.) This is because the CRTBNDRPG command requires that the
module contain a program entry procedure and only a main procedure can be a
program entry procedure.
v Similarly, when using CRTPGM to create the program, keep in mind that a
NOMAIN module cannot be an entry module since it does not have a program
entry procedure.
v A program that is created to run in the default OPM activation group (by
specifying DFTACTGRP(*YES) on the CRTBNDRPG command) cannot contain
bound procedure calls.
You cannot define return values for a main procedure, nor can you specify that its
parameters be passed by value.
#
#
#
#
#
v Because the cycle-main procedure is the only procedure with a complete set of
specifications available (except the P specification), it should be used to set up
the environment of all procedures in the module.
v A cycle-main procedure is always exported, which means that other procedures
in the program can call the main procedure by using bound calls.
Chapter 4. Creating an Application Using Multiple Procedures
45
Coding Considerations
v The call interface of a cycle-main procedure can be defined in one of two ways:
1. Using a procedure interface and an optional prototype
2. Using an *ENTRY PLIST without a prototype
v The functionality of an *ENTRY PLIST is similar to a prototyped call interface.
However, a prototyped call interface is much more robust since it provides
parameter checking at compile time. If you prototype the main procedure, then
you specify how it is to be called by specifying either the EXTPROC or EXTPGM
keyword on the prototype definition. If EXTPGM is specified, then an external
program call is used; if EXTPROC is specified or if neither keyword is specified,
it will be called by using a procedure call.
#
|
#
#
#
#
#
#
#
#
Subprocedure Considerations
These considerations apply to ordinary subprocedures and linear-main procedures
except as otherwise noted.
v Any of the calculation operations may be coded in a subprocedure. However,
input and output specifications are not supported in subprocedures, so data
structure result fields must be used for file I/O operations to files defined locally
in the subprocedure. All data areas must be defined in the main source section,
although they can be used in a subprocedure.
v The control specification can only be coded in the main source section since it
controls the entire module.
v A subprocedure can be called recursively.Each recursive call causes a new
invocation of the procedure to be placed on the call stack. The new invocation
has new storage for all data items in automatic storage, and that storage is
unavailable to other invocations because it is local. (A data item that is defined
in a subprocedure uses automatic storage unless the STATIC keyword is
specified for the definition.)
The automatic storage that is associated with earlier invocations is unaffected by
later invocations. All invocations share the same static storage, so later
invocations can affect the value held by a variable in static storage.
Recursion can be a powerful programming technique when properly
understood.
v The run-time behavior of a subprocedure (including a linear-main procedure)
differs somewhat from that of a cycle-main procedure, because there is no cycle
code for the subprocedure.
When a subprocedure ends, any open local files in automatic storage are
closed. However, none of the termination activities, such as closing of global
files, occurs until the cycle-main procedure, if any, that are associated with the
subprocedure itself ends. If you want to ensure that your global files are
closed before the activation group ends, you can code a "cleanup"
subprocedure that is called both by the program entry procedure at
application-end, and by a cancel handler enabled for the program entry
procedure.
An alternative to using a cleanup procedure is to code the module so that
there is no implicit file opening or data area locking, and that within any
subprocedure, an open is matched by a close, an IN by an OUT, a CRT by a
DLT, and so on. This alternative should be strongly considered for a
cycle-module if it might have a subprocedure active when the cycle-main
procedure is not active.
Exception handling within a subprocedure differs from a cycle-main
procedure primarily because there is no default exception handler for
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
46
Coding Considerations
#
#
#
Main Procedures
Topic
See
Exception handling
Subprocedures
Topic
See
Defining
NOMAIN module
Exception handling
Procedure Specification
Procedure Interface
Subprocedure End
Prototyped Call
Topic
See
Free-form call
General Information
Passing parameters
Prototypes
47
48
Run programs
Pass parameters
Manage the run time
Call other programs or procedures
Use Rational Development Studio for i. This is the recommended method and
documentation about creating and running an ILE RPG application appears in that
product's online help.
See Using the application development tools in the client product for information
about getting started with the client tools.
Many Integrated Language Environment terms and concepts are discussed briefly
in the following pages. These terms and concepts are more fully discussed in ILE
Concepts.
49
50
51
12
80
20
Seq#/Date
Code
Comments
Since the system default for a source physical file is 92 characters, you should
explicitly specify a minimum record length of 112. If you specify a length less than
92 characters, the program may not compile since you may be truncating source
code.
For more information about creating libraries and source physical files, refer to the
ADTS for AS/400: Source Entry Utility manual and the ADTS/400: Programming
Development Manager manual.
52
Using SEU
3. To start an editing session and create source member EMPRPT type:
STRSEU SRCFILE(MYLIB/QRPGLESRC)
SRCMBR(EMPRPT)
TYPE(RPGLE) OPTION(2)
Entering OPTION(2) indicates that you want to start a session for a new
member. The STRSEU command creates a new member EMPRPT in file
QRPGLESRC in library MYLIB and starts an edit session.
The SEU Edit display appears as shown in Figure 27. Note that the screen is
automatically shifted so that position 6 is (for specification type) at the left
edge.
Columns . . . :
6 76
Edit
MYLIB/QRPGLESRC
SEU==> ___________________________________________________________
EMPRPT
FMT H HKeywords++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*************** Beginning of data *************************************
4. Type the following source in your SEU Edit display, using the following SEU
prefix commands to provide prompting:
v IPF for file description specifications
v IPD for definition specifications
v IPI for input specifications
v IPC for calculation specifications
v IPCX for calculation specifications with extended Factor 2
v IPO for output specifications
v IPP for output specifications continuation
v IPPR for procedure specifications
53
Using SEU
*===============================================================*
* MODULE NAME:
EMPRPT
* RELATED FILES: EMPMST
(PHYSICAL FILE)
*
QSYSPRT (PRINTER FILE)
* DESCRIPTION:
This program prints employee information
*
from the file EMPMST.
*===============================================================*
FQSYSPRT
O
F
80
PRINTER
FEMPMST
IP E
K DISK
D TYPE
S
8A
D EMPTYPE
PR
8A
D
CODE
1A
IEMPREC
01
C
EVAL
TYPE = EMPTYPE(ETYPE)
OPRINT
H
1P
2 6
O
50 EMPLOYEE INFORMATION
O
H
1P
O
12 NAME
O
34 SERIAL #
O
45 DEPT
O
56 TYPE
O
D
01
O
ENAME
20
O
ENUM
32
O
EDEPT
45
O
TYPE
60
* Procedure EMPTYPE returns a string representing the employee
*
type indicated by the parameter CODE.
P EMPTYPE
B
D EMPTYPE
PI
8A
D
CODE
1A
C
SELECT
C
WHEN
CODE = M
C
RETURN
Manager
C
WHEN
CODE = R
C
RETURN
Regular
C
OTHER
C
RETURN
Unknown
C
ENDSL
P EMPTYPE
E
Figure 28. Source for EMPRPT member
54
Using SEU
A*****************************************************************
A* DESCRIPTION: This is the DDS for the physical file EMPMST.
*
A*
It contains one record format called EMPREC.
*
A*
This file contains one record for each employee *
A*
of the company.
*
A*****************************************************************
A*
A
R EMPREC
A
ENUM
5 0
TEXT(EMPLOYEE NUMBER)
A
ENAME
20
TEXT(EMPLOYEE NAME)
A
ETYPE
1
TEXT(EMPLOYEE TYPE)
A
EDEPT
3 0
TEXT(EMPLOYEE DEPARTMENT)
A
ENHRS
3 1
TEXT(EMPLOYEE NORMAL WEEK HOURS)
A
K ENUM
Figure 29. DDS for EMPRPT
To create a program from this source use the CRTBNDRPG command, specifying
DFTACTGRP(*NO).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The DB2 UDB for iSeries database can be accessed from an ILE RPG program by
embedding SQL statements into your program source. Use the following rules to
enter your SQL statements:
v Enter your SQL statements on the Calculation specification in free form or in
fixed form
v In free form
You start your SQL statement using the delimiter "EXEC SQL".
The SQL statement can be placed on several lines. No continuation character
is required.
Use a semicolon to signal the end of your SQL statement.
v In fixed form
Start your SQL statements using the delimiter /EXEC SQL in positions 7-15
(with the / in position 7)
Use the continuation line delimiter (a + in position 7) to continue your
statements on any subsequent lines
Use the ending delimiter /END-EXEC in positions 7-15 (with the slash in
position 7) to signal the end of your SQL statements.
v You can start entering your SQL statements on the same line as the starting
delimiter
Note: SQL statements cannot go past position 80 in your program.
|
|
55
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
...+....1....+....2....+....3....+....4....+....5....+....6....+....7..
/FREE
X = Y + Z; // ILE RPG calculation operations
// The entire SQL statement is on one line
EXEC SQL INSERT INTO MYLIB/MYFILE (FLD1) VALUES(12);
// The SQL statement begins on the same line as
// EXEC SQL and then it is is split across several lines
EXEC SQL INSERT
INTO MYLIB/MYFILE
(FLD1) VALUE(12);
// The SQL statement begins on the line after
// EXEC SQL and then it is is split across several lines
EXEC SQL
INSERT INTO MYLIB/MYFILE
(FLD1) VALUE(12);
X = Y + Z; // ILE RPG calculation operations
/END-FREE
Figure 30. Free Form SQL Statements in an ILE RPG Program
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
...+....1....+....2....+....3....+....4....+....5....+....6....+....7..
* ILE RPG calculation operations
C
EVAL
X = Y + Z
* The entire SQL statement is on one line
C/EXEC SQL INSERT INTO MYLIB/MYFILE (FLD1) VALUES(12)
C/END-EXEC
* The SQL statement begins on the same line as
* EXEC SQL and then it is is split across several lines
C/EXEC SQL
INSERT
C+
INTO MYLIB/MYFILE
C+
(FLD1) VALUE(12)
C/END-EXEC
* The SQL statement begins on the line after
* EXEC SQL and then it is is split across several lines
C/EXEC SQL
C+
INSERT INTO MYLIB/MYFILE
C+
(FLD1) VALUE(12)
C/END-EXEC
* ILE RPG calculation operations
C
EVAL
X = Y + Z
C
Figure 31. Fixed Form SQL Statements in an ILE RPG Program
You must enter a separate command to process the SQL statements. For more
information, refer to the DB2 Universal Database for iSeries section of the Database
and File Systems category in the i5/OS Information Center at this Web site http://www.ibm.com/systems/i/infocenter/.
Refer to the ADTS for AS/400: Source Entry Utility manual for information about
how SEU handles SQL statement syntax checking.
56
Include files
The /COPY and /INCLUDE directives allow the specification of files in either the
QSYS file system or the IFS file system. In cases where the compiler cannot tell
which file system the directive refers to, the search will begin in the file system of
the file containing the /COPY directive.
When the compiler encounters a /COPY statement, the statement could refer to a
file in the IFS or in the QSYS file system. If the name begins with a slash or is
specified in single quotes, the name can only refer to a file in the IFS. A name in
the IFS can be specified in double quotes as well. Where only part of the name is
in double quotes, for example:
/copy "SOME-LIB"/QRPGLESRC,MBR
QSYS interpretation
/COPY MYMBR
FILE(*LIBL/QRPGLESRC)
MBR(MYMBR)
/COPY mymbr
FILE(*LIBL/QRPGLESRC)
MBR(MYMBR)
/COPY myfile,mymbr
FILE(*LIBL/MYFILE)
MBR(MYMBR)
myfile,mymbr or myfile,mymbr.suffix
(note that MYFILE,MYMBR is a valid
name in the IFS file system)
/COPY mylib/myfile,mymbr
FILE(MYLIB/MYFILE)
MBR(MYMBR)
/COPY "A/b",mymbr
FILE(*LIBL/"A/b")
MBR(MYMBR)
/COPY "A/B"
FILE(*LIBL/QRPGLESRC)
MBR("A/B")
A/B
57
QSYS interpretation
/COPY a b
FILE(*LIBL/QRPGLESRC)
MBR(A) (everything after a
blank is assumed to be a
comment)
a or a.suffix (everything
after a blank is assumed
to be a comment)
a b or a b.suffix
/COPY /home/mydir/myfile.rpg
/home/mydir/myfile.rpg
/COPY /QSYS.LIB/
L.LIB/F.FILE/M.MBR
/QSYS.LIB/L.LIB/F.FILE/
M.MBR (which is actually a
file in the QSYS file system,
but is considered to be an
IFS file by RPG)
Note: When searching for files in the IFS, if the file name does not contain a dot,
the RPG compiler will look for files with the following suffixes (in this
order):
1. no suffix (abc)
2. .rpgleinc (abc.rpgleinc)
3. .rpgle (abc.rpgle)
58
In IFS:
/COPY file.rpg
/home/auser/file.rpg
/driver/v5r2/inc/file.rpg
/driver/v5r1/inc/file.rpg
/home/auser/temp/file.rpg
/home/auser/src/file.rpg
In QSYS:
FILE(*LIBL/QRPGLESRC) MBR(FILE.RPG)
In QSYS:
/COPY file
In IFS:
FILE(*LIBL/QRPGLESRC) MBR(FILE)
/home/auser/file
/home/auser/file.rpgleinc
/home/auser/file.rpgle
/driver/v5r2/inc/file
/driver/v5r2/inc/file.rpgleinc
/driver/v5r2/inc/file.rpgle
/driver/v5r1/inc/file
/driver/v5r1/inc/file.rpgleinc
/driver/v5r1/inc/file.rpgle
/home/auser/temp/file
/home/auser/temp/file.rpgleinc
/home/auser/temp/file.rpgle
/home/auser/src/file
/home/auser/src/file.rpgleinc
/home/auser/src/file.rpgle
59
60
61
DBGENCKEY(*NONE) Specifies the encryption for the listing debug view for the program
OPTIMIZE(*NONE) Determines level of optimization, if any
REPLACE(*YES) Determines if program should replace existing program
BNDDIR(*NONE) Specifies the binding directory to be used for symbol resolution
USRPRF(*USER) Specifies the user profile that will run program
AUT(*LIBCRTAUT) Specifies type of authority for created program
TGTRLS(*CURRENT) Specifies the release level the object is to be run on
ENBPFRCOL(*PEP) Specifies whether performance collection is enabled
DEFINE(*NONE) Specifies condition names that are defined before the compilation
begins
PRFDTA(*NOCOL) Specifies the program profiling data attribute
62
ACTGRP(*STGMDL) Identifies the activation group in which the program should run
SRTSEQ(*HEX) Specifies the sort sequence table to be used.
LANGID(*JOBRUN) Used with SRTSEQ to specify the language identifier for sort
sequence
TRUNCNBR(*YES) Specifies the action to take when numeric overflow occurs for
packed-decimal, zoned-decimal, and binary fields in fixed-format
operations.
INFOSTMF(path) Used with PGMINFO, specifies the stream file in the IFS to receive
the PCML
PGMINFO(*NONE) *PCML indicates that PCML (Program Call Markup Language)
should be generated for the program; the second parameter indicates
whether it should be generated into a stream file or into the module.
LICOPT(options) Specifies Licensed Internal Code options.
See Appendix C, The Create Commands, on page 477 for the syntax diagram and
parameter descriptions of CRTBNDRPG.
63
The program will be created in the library MYLIB with the same name as the
source member on which it is based, namely, EMPRPT. Note that by default, it
will run in the default named activation group, QILE. This program object can
be debugged using a source view.
2. To debug the program type:
STRDBG EMPRPT
Figure 32 shows the screen which appears after entering the above command.
Program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
S
PR
8A
8A
1A
01
More...
Debug . . . _________________________________________________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
From this screen (the Display Module Source display) you can enter debug
commands to display or change field values and set breakpoints to control
program flow while debugging.
For more information on debugging see Chapter 12, Debugging Programs, on
page 229.
64
65
*------------------------------------------------------------------------*
* DESCRIPTION: This program creates a printed output of employees pay *
*
for the week.
*
*------------------------------------------------------------------------*
H DATEDIT(*DMY/)
*------------------------------------------------------------------------*
* File Definitions
*
*------------------------------------------------------------------------*
FTRANSACT IP
E
K DISK
FEMPLOYEE IF
E
K DISK
FQSYSPRT
O
F 80
PRINTER
*------------------------------------------------------------------------*
* Variable Declarations
*
*------------------------------------------------------------------------*
D Pay
S
8P 2
*------------------------------------------------------------------------*
* Constant Declarations
*
*------------------------------------------------------------------------*
D Heading1
C
NUMBER NAME
RATE
HD
OURS BONUS
PAY
D Heading2
C
______ ________________ ______ _D
____ _______ __________
*------------------------------------------------------------------------*
* For each record in the transaction file (TRANSACT), if the employee
*
* is found, compute the employees pay and print the details.
*
*------------------------------------------------------------------------*
C
TRN_NUMBER
CHAIN
EMP_REC
99
C
IF
NOT *IN99
C
EVAL (H) Pay = EMP_RATE * TRN_HOURS + TRN_BONUS
C
ENDIF
*------------------------------------------------------------------------*
* Report Layout
*
* -- print the heading lines if 1P is on
*
* -- if the record is found (indicator 99 is off) print the payroll
*
*
details otherwise print an exception record
*
* -- print END OF LISTING when LR is on
*
*------------------------------------------------------------------------*
OQSYSPRT
H
1P
2 3
O
35 PAYROLL REGISTER
O
*DATE
Y
60
O
H
1P
2
O
60 Heading1
O
H
1P
2
O
60 Heading2
O
D
N1PN99
2
O
TRN_NUMBER
5
O
EMP_NAME
24
O
EMP_RATE
L
33
O
TRN_HOURS
L
40
O
TRN_BONUS
L
49
O
Pay
60 $
0.
O
D
N1P 99
2
O
TRN_NUMBER
5
O
35 ** NOT ON EMPLOYEE FILE **
O
T
LR
O
33 END OF LISTING
Figure 33. A Sample Payroll Calculation Program
66
67
68
69
Line
Number
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
70
Src
Id
Seq
Number
003100
Src
Id
Seq
Number
000100
000200
In this example, FLD1 is defined like FLD2 with a length 5 bytes greater. Later,
FLD2 is defined as a date, which makes the length adjustment in the definition of
FLD1 invalid. Message RNF3479 is issued pointing at listing line 1. Note that the
SEU sequence number (000100) is also given, to aid you in finding the source line
in error more quickly. (The SEU sequence number can also be found at listing line
1).
71
72
73
74
Byte
Character '1' means the translator was not called because either
OPTION(*NOGEN) was specified on the CRTRPGMOD or
CRTBNDRPG command; or the compilation failed before the
translator was called.
6-10
11-12
13-14
15-20
21-26
Compile date
27-32
Compile time
33-100
101-110
111-120
121-130
131-140
141-150
151-160
161-170
171-180
181-329
335
336-340
341-345
346-379
380-384
385
386-390
391-395
396-400
75
76
#
#
#
#
#
#
#
#
#
An ILE RPG module consists of one or more procedures, and the file control blocks
and static storage used by all the procedures in the module. The procedures that
can make up an ILE RPG module are:
v an optional cycle-main procedure which consists of the set of H, F, D, I, C, and
O specifications that begin the source. The cycle-main procedure has its own LR
semantics and logic cycle; neither of which is affected by those of other ILE RPG
modules in the program.
v zero or more subprocedures, which are coded on P, D, and C specifications.
Subprocedures do not use the RPG cycle. A subprocedure may have local
storage that is available for use only by the subprocedure itself. One of the
subprocedures may be designated as a linear-main procedure, if a cycle-main
procedure is not coded.
The main procedure (if coded) can always be called by other modules in the
program. Subprocedures may be local to the module or exported. If they are local,
they can only be called by other procedures in the module; if they are exported
from the module, they can be called by any procedure in the program.
Module creation consists of compiling a source member, and, if that is successful,
creating a *MODULE object. The *MODULE object includes a list of imports and
exports referenced within the module. It also includes debug data if you request
this at compile time.
A module cannot be run by itself. You must bind one or more modules together to
create a program object (type *PGM) which can then be run. You can also bind one
77
DBGENCKEY(*NONE) Specifies the encryption for the listing debug view for the module
78
79
SRCFILE(MYLIB/QRPGLESRC)
The module will be created in the library MYLIB with the name specified in the
command, TRANSSVC. The source for the module is the source member
TRANSSVC in file QRPGLESRC in the library MYLIB.
You bind a module containing NOMAIN to another module using one of the
following commands:
a. CRTPGM command
b. CRTSRVPGM command
c. CRTBNDRPG command where the NOMAIN module is included in a
binding directory.
2. Once it is bound, this module object can be debugged using a statement view.
A compiler listing for the module is also produced.
3. Type one of the following CL commands to see the compiler listing.
v DSPJOB and then select option 4 (Display spooled files)
v WRKJOB
v WRKOUTQ queue-name
v WRKSPLF
80
*=================================================================*
* MODULE NAME:
TRANSSVC (Transaction Services)
* RELATED FILES: N/A
* RELATED SOURCE: TRANSRPT
* EXPORTED PROCEDURES: Trans_Inc -- calculates the income
*
for the transaction using the data in the fields in the
*
parameter list. It returns to the caller after all
*
the calculations are done.
*
*
Prod_Name -- retrieves the product name based on the
*
input parameter with the product number.
*=================================================================*
* This module contains only subprocedures; it is a NOMAIN module.
H NOMAIN
*-----------------------------------------------------------------* Pull in the prototypes from the /COPY member
*-----------------------------------------------------------------/COPY TRANSP
*-----------------------------------------------------------------* Subprocedure Trans_Inc
*-----------------------------------------------------------------P Trans_Inc
B
EXPORT
D Trans_Inc
PI
11P 2
D
ProdNum
10P 0
VALUE
D
Quantity
5P 0
VALUE
D
Discount
2P 2
VALUE
D Factor
S
5P 0
*
C
SELECT
C
WHEN
ProdNum = 1
C
EVAL
Factor = 1500
C
WHEN
ProdNum = 2
C
EVAL
Factor = 3500
C
WHEN
ProdNum = 5
C
EVAL
Factor = 20000
C
WHEN
ProdNum = 8
C
EVAL
Factor = 32000
C
WHEN
ProdNum = 12
C
EVAL
Factor = 64000
C
OTHER
C
EVAL
Factor = 0
C
ENDSL
C
RETURN
Factor * Quantity * (1 - Discount)
P Trans_Inc
E
Figure 37. Source for TRANSSVC member (Part 1 of 2)
81
11P
10P
5P
2P
2
0
0
2
VALUE
VALUE
VALUE
40A
10P 0
VALUE
SRCFILE(MYLIB/QRPGLESRC)
The module is created in the library MYLIB with the same name as the source file
on which it is based, namely, TRANSRPT. This module object can be debugged
using a source view. For information on the other views available, see Preparing a
Program for Debugging on page 232.
A compiler listing for the TRANSRPT module will be produced.
82
*=================================================================*
* MODULE NAME:
TRANSRPT
* RELATED FILES: TRNSDTA (PF)
* RELATED SOURCE: TRANSSVC (Transaction services)
* EXPORTED PROCEDURE: TRANSRPT
*
The procedure TRANSRPT reads every tranasction record
*
stored in the physical file TRNSDTA. It calls the
*
subprocedure Trans_Inc which performs calculations and
*
returns a value back. Then it calls Prod_Name to
*
to determine the product name. TRANSRPT then prints
*
the transaction record out.
*=================================================================*
FTRNSDTA
IP
E
DISK
FQSYSPRT
O
F
80
PRINTER
OFLIND(*INOF)
/COPY QRPGLE,TRANSP
* Define the readable version of the product name like the
* return value of the procedure Prod_Name
D
ProdName
S
30A
D
Income
S
10P 2
D
Total
S
+5
LIKE(Income)
*
ITRNSREC
01
* Calculate the income using subprocedure Trans_Inc
C
EVAL
Income = Trans_Inc(PROD : QTY : DISC)
C
EVAL
Total = Total + Income
* Find the name of the product
C
EVAL
ProdName = Prod_Name(PROD)
OQSYSPRT
H
1P
1
O
OR
OF
O
12 Product name
O
40 Quantity
O
54 Income
OQSYSPRT
H
1P
1
O
OR
OF
O
30 ----------+
O
----------+
O
----------
O
40 --------
O
60 ------------
OQSYSPRT
D
01
1
O
ProdName
30
O
QTY
1
40
O
Income
1
60
OQSYSPRT
T
LR
1
O
Total:
O
Total
1
Figure 39. Source for TRANSRPT module
The DDS for the file TRNSDTA is shown in Figure 40 on page 84. The /COPY
member is shown in Figure 38 on page 82.
83
A*****************************************************************
A* RELATED FILES: TRNSRPT
*
A* DESCRIPTION:
This is the physical file TRNSDTA. It has
*
A*
one record format called TRNSREC.
*
A*****************************************************************
A* PARTS TRANSACTION FILE -- TRNSDTA
A
R TRNSREC
A
PROD
10S 0
TEXT(Product)
A
QTY
5S 0
TEXT(Quantity)
A
DISCOUNT
2S 2
TEXT(Discount)
Figure 40. DDS for TRNSDTA
Additional Examples
For additional examples of creating modules, see:
v Sample Service Program on page 97, for an example of creating a module for a
service program.
v Binding to a Program on page 102. for an example of creating a module to be
used with a service program.
v Managing Your Own Heap Using ILE Bindable APIs on page 125, for an
example of creating a module for dynamically allocating storage for a run-time
array
v Sample Source for Debug Examples on page 279, for example of creating an
RPG and C module for use in a sample debug program.
In ILE RPG, the cycle-main procedure is the boundary for the scope of LR semantics
and the RPG cycle. The module is the boundary for the scope of open files.
#
#
#
#
#
#
In any ILE program, there may be several RPG cycles active; there is one RPG
cycle for each RPG module that has a cycle-main procedure. The cycles are
independent: setting on LR in one cycle-main procedure has no effect on the cycle
in another. An RPG module which has a linear-main procedure or has no main
procedure does not use the RPG cycle; nor will it effect the cycle in another
module.
Related CL Commands
The following CL commands can be used with modules:
v Display Module (DSPMOD)
v Change Module (CHGMOD)
v Delete Module (DLTMOD)
v Work with Modules (WRKMOD)
For further information on these commands see the CL and APIs section of the
Programming category in the i5/OS Information Center at this Web site http://www.ibm.com/systems/i/infocenter/.
84
85
Within a bound object, procedures can interrelate using static procedure calls.
These bound calls are faster than external calls. Therefore, an application consisting
86
87
Parameter(Default Value)
Identification
Program access
ENTMOD(*FIRST)
Binding
BNDSRVPGM(*NONE)
BNDDIR(*NONE)
Run time
ACTGRP(*NEW)
Miscellaneous
Once you have entered the CRTPGM command, the system performs the following
actions:
1. Copies listed modules into what will become the program object, and links any
service programs to the program object.
2. Identifies the module containing the program entry procedure, and locates the
first import in this module.
3. Checks the modules in the order in which they are listed, and matches the first
import with a module export.
4. Returns to the first module, and locates the next import.
5. Resolves all imports in the first module.
6. Continues to the next module, and resolves all imports.
7. Resolves all imports in each subsequent module until all of the imports have
been resolved.
8. If any imports cannot be resolved with an export, the binding process
terminates without creating a program object.
9. Once all the imports have been resolved, the binding process completes and the
program object is created.
88
The CRTPGM command creates a program object TRPT in the library MYLIB.
Note that TRANSRPT is listed first in the MODULE parameter. ENTMOD(*FIRST)
will find the first module with a program entry procedure. Since only one of the
two modules has a program entry procedure, they can be entered in either order.
The program TRPT will run in the named activation group TRPT. The program
runs in a named group to ensure that no other programs can affect its resources.
Figure 42 shows an output file created when TRPT is run.
Product name
-----------------------------Large
Super
Super Large
Super Jumbo
Incredibly Large Super Jumbo
***Unknown***
Total:
4,247,250.00
Quantity
-------245
15
0
123
15
12
Income
-----------330,750.00
52,500.00
.00
2,952,000.00
912,000.00
.00
Additional Examples
For additional examples of creating programs, see:
v Binding to a Program on page 102, for an example of binding a module and a
service program.
Chapter 7. Creating a Program with the CRTRPGMOD and CRTPGM Commands
89
Related CL Commands
The following CL commands can be used with programs:
v Change Program (CHGPGM)
v Delete Program (DLTPGM)
v Display Program (DSPPGM)
v Display Program References (DSPPGMREF)
v Update Program (UPDPGM)
v Work with Program (WRKPGM)
For further information on these commands, see the CL and APIs section of the
Programming category in the System i Information Center at this Web site http://www.ibm.com/systems/i/infocenter/.
*BASIC
*EXTENDED
*FULL
Cross-Reference Listing
Binding Statistics
The information in this listing can help you diagnose problems if the binding was
not successful, or give feedback about what the binder encountered in the process.
You may want to store the listing for an ILE program in the file where you store
the modules or the module source for a program. To copy this listing to a database
file, you can use the Copy Spool File (CPYSPLF) command.
Note: The CRTBNDRPG command will not create a binder listing. However, if any
binding errors occur during the binding phase, the errors will be noted in
your job log, and the compiler listing will include a message to this effect.
90
91
Removing Observability
Observability involves the kinds of data that can be stored with an object, and that
allow the object to be changed without recompiling the source. The addition of this
data increases the size of the object. Consequently, you may want to remove the
data in order to reduce object size. But once the data is removed, observability is
also removed. You must recompile the source and recreate the program to replace
the data. The types of data are:
Create Data
92
Profiling Data Represented by the *BLKORD and *PRCORD values. This data is
necessary to allow the system to re-apply block order and
procedure order profiling data.
Use the CHGPGM command or the CHGMOD command to remove some or all
the data from a program or module respectively. Removing all observability
reduces an object to its minimum size (without compression). It is not possible to
change the object in any way unless you re-create it. Therefore, ensure that you
have all source required to create the program or have a comparable program
object with CRTDATA. To re-create it, you must have authorization to access the
source code.
93
94
95
TIP
If you are planning a module with only subprocedures (that is, with a
module with keyword NOMAIN specified on the control specification) you
may want to create it as a service program. Only one copy of a service
program is needed on a system, and so you will need less storage for the
module.
Also, you can copyright your service programs using the COPYRIGHT
keyword on the control specification.
Binder language gives you control over the exports of a service program. This
control can be very useful if you want to:
v Mask certain service program procedures from service-program users
v Fix problems
v Enhance function
v Reduce the impact of changes to the users of an application.
See Sample Service Program on page 97 for an example of using binder
language to create a service program.
For information on binder language, masking exports, and other service program
concepts, see ILE Concepts.
Parameter(Default Value)
Identification
Program access
EXPORT(*SRCFILE)
SRCFILE(*LIBL/QSRVSRC)
SRCMBR(*SRVPGM)
96
Parameter(Default Value)
Binding
BNDSRVPGM(*NONE)
BNDDIR(*NONE)
Run time
ACTGRP(*CALLER)
Miscellaneous
See Creating the Service Program on page 101 for an example of using the
CRTSRVPGM command.
Related CL commands
The following CL commands are also used with service programs:
v
v
v
v
v
97
98
*=================================================================*
* CvtToHex - convert input string to hex output string
*=================================================================*
H COPYRIGHT((C) Copyright MyCompany 1995)
D/COPY RPGGUIDE/QRPGLE,CVTHEXPR
*-----------------------------------------------------------------*
* Main entry parameters
* 1. Input:
string
character(n)
* 2. Output: hex string
character(2 * n)
*-----------------------------------------------------------------*
D CvtToHex
PI
OPDESC
D
InString
16383
CONST OPTIONS(*VARSIZE)
D
HexString
32766
OPTIONS(*VARSIZE)
*-----------------------------------------------------------------*
* Prototype for CEEDOD (Retrieve operational descriptor)
*-----------------------------------------------------------------*
D CEEDOD
PR
D ParmNum
10I 0 CONST
D
10I 0
D
10I 0
D
10I 0
D
10I 0
D
10I 0
D
12A
OPTIONS(*OMIT)
* Parameters passed to CEEDOD
DescType
S
DataType
S
DescInfo1
S
DescInfo2
S
InLen
S
HexLen
S
D
D
D
D
D
D
10I
10I
10I
10I
10I
10I
0
0
0
0
0
0
*-----------------------------------------------------------------*
* Other fields used by the program
*
*-----------------------------------------------------------------*
D HexDigits
C
CONST(0123456789ABCDEF)
D IntDs
DS
D
IntNum
5I 0 INZ(0)
D
IntChar
1
OVERLAY(IntNum:2)
D HexDs
DS
D
HexC1
1
D
HexC2
1
D InChar
S
1
D Pos
S
5P 0
D HexPos
S
5P 0
99
*-----------------------------------------------------------------*
* Use the operational descriptors to determine the lengths of
*
* the parameters that were passed.
*
*-----------------------------------------------------------------*
C
CALLP
CEEDOD(1
: DescType : DataType
C
DescInfo1 : DescInfo2: Inlen
C
*OMIT)
C
CALLP
CEEDOD(2
: DescType : DataType
C
DescInfo1 : DescInfo2: HexLen
C
*OMIT)
*-----------------------------------------------------------------*
* Determine the length to handle (minimum of the input length
*
* and half of the hex length)
*
*-----------------------------------------------------------------*
C
IF
InLen > HexLen / 2
C
EVAL
InLen = HexLen / 2
C
ENDIF
*-----------------------------------------------------------------*
* For each character in the input string, convert to a 2-byte
*
* hexadecimal representation (for example, 5 --> F5)
*
*-----------------------------------------------------------------*
C
EVAL
HexPos = 1
C
DO
InLen
Pos
C
EVAL
InChar = %SUBST(InString : Pos :1)
C
EXSR
GetHex
C
EVAL
%SUBST(HexString : HexPos : 2) = HexDs
C
EVAL
HexPos = HexPos + 2
C
ENDDO
*-----------------------------------------------------------------*
* Done; return to caller.
*
*-----------------------------------------------------------------*
C
RETURN
*=================================================================*
* GetHex - subroutine to convert InChar to HexDs
*
*
*
* Use division by 16 to separate the two hexadecimal digits.
*
* The quotient is the first digit, the remainder is the second.
*
*=================================================================*
C
GetHex
BEGSR
C
EVAL
IntChar = InChar
C
IntNum
DIV
16
X1
5 0
C
MVR
X2
5 0
*-----------------------------------------------------------------*
* Use the hexadecimal digit (plus 1) to substring the list of
*
* hexadecimal characters 012...CDEF.
*
*-----------------------------------------------------------------*
C
EVAL
HexC1 = %SUBST(HexDigits:X1+1:1)
C
EVAL
HexC2 = %SUBST(HexDigits:X2+1:1)
C
ENDSR
Figure 43. Source for Service Program CvtToHex (Part 2 of 2)
100
:
:
:
:
*=================================================================*
* CvtToHex - convert input string to hex output string
*
* Parameters
* 1. Input:
string
character(n)
* 2. Output: hex string
character(2 * n)
*=================================================================*
D CvtToHex
PR
OPDESC
D
InString
16383
CONST OPTIONS(*VARSIZE)
D
HexString
32766
OPTIONS(*VARSIZE)
Figure 44. Source for /COPY Member with Prototype for CvtToHex
When designing this service program, it was decided to make use of binder
language to determine the interface, so that the program could be more easily
updated at a later date. Figure 45 shows the binder language needed to define the
exports of the service program CVTTOHEX. This source is used in the EXPORT,
SRCFILE and SRCMBR parameters of the CRTSRVPGM command.
STRPGMEXP SIGNATURE(CVTHEX)
EXPORT SYMBOL(CVTTOHEX)
ENDPGMEXP
Figure 45. Source for Binder Language for CvtToHex
2. Create the service program using the module CVTTOHEX and the binder
language shown in Figure 45.
CRTSRVPGM SRVPGM(MYLIB/CVTTOHEX) MODULE(*SRVPGM)
EXPORT(*SRCFILE) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(*SRVPGM)
The last three parameters in the above command identify the exports which the
service program will make available. In this case, it is based on the source
found in the member CVTTOHEX in the file QSRVSRC in the library MYLIB.
Note that a binding directory is not required here because all modules needed
to create the service program have been specified with the MODULE
parameter.
101
Binding to a Program
To complete the example, we will create an 'application' consisting of a program
CVTHEXPGM which is bound to the service program. It uses a seven-character
string which it passes to CVTTOHEX twice, once where the value of the hex string
is 10 (that is, convert 5 characters) and again where the value is 14, that is, the
actual length.
Note that the program CVTHEXPGM serves to show the use of the service
program CVTTOHEX. In a real application the caller of CVTTOHEX would have
another primary purpose other than testing CVTTOHEX. Furthermore, a service
program would normally be used by many other programs, or many times by a
few programs; otherwise the overhead of initial call does not justify making it into
a service program.
To create the application follow these steps:
1. Create the module from the source in Figure 46 on page 103, by entering:
CRTRPGMOD MODULE(MYLIB/CVTHEXPGM) SRCFILE(MYLIB/QRPGLESRC)
During the process of making CVTHEXPGM ready to run, the system verifies
that:
v The service program CVTTOHEX in library MYLIB can be found
v The public interface used by CVTHEXPGM when it was created is still valid
at run time.
If either of the above is not true, then an error message is issued.
The output of CVTHEXPGM is shown below. (The input string is 'ABC123*'.)
Result14++++++
Result10++
C1C2C3F1F2
C1C2C3F1F2F35C
102
10 character output
14 character output
*----------------------------------------------------------------*
* Program to test Service Program CVTTOHEX
*
*
*
* 1. Use a 7-character input string
*
* 2. Convert to a 10-character hex string (only the first five
*
*
input characters will be used because the result is too
*
*
small for the entire input string)
*
* 3. Convert to a 14-character hex string (all seven input
*
*
characters will be used because the result is long enough) *
*----------------------------------------------------------------*
FQSYSPRT
O
F
80
PRINTER
* Prototype for CvtToHex
D/COPY RPGGUIDE/QRPGLE,CVTHEXPR
D ResultDS
DS
D
Result14
1
14
D
Result10
1
10
D InString
S
7
D Comment
S
25
C
EVAL
InString = ABC123*
*----------------------------------------------------------------*
* Pass character string and the 10-character result field
*
* using a prototyped call. Operational descriptors are
*
* passed, as required by the called procedure CvtToHex.
*
*----------------------------------------------------------------*
C
EVAL
Comment = 10 character output
C
CLEAR
ResultDS
C
CALLP
CvtToHex(Instring : Result10)
C
EXCEPT
*----------------------------------------------------------------*
* Pass character string and the 14-character result field
*
* using a CALLB(D). The operation extender (D) will create
*
* operational descriptors for the passed parameters. CALLB
*
* is used here for comparison with the above CALLP.
*
*----------------------------------------------------------------*
C
EVAL
Comment = 14 character output
C
CLEAR
ResultDS
C
CALLB(D) CVTTOHEX
C
PARM
InString
C
PARM
Result14
C
EXCEPT
C
EVAL
*INLR = *ON
OQSYSPRT
O
OQSYSPRT
O
OQSYSPRT
O
O
1P
1P
Result14++++++
Result10++
E
ResultDS
Comment
+5
103
104
Create Program
5769WDS V5R2M0 020719
23:24:00
Program . . . . . . . . . . .
Library . . . . . . . . . .
Program entry procedure module
Library . . . . . . . . . .
Activation group . . . . . . .
Creation options . . . . . . .
Listing detail . . . . . . . .
Allow Update . . . . . . . . .
User profile . . . . . . . . .
Replace existing program . . .
Authority . . . . . . . . . .
Target release . . . . . . . .
Allow reinitialization . . . .
Text . . . . . . . . . . . . .
Module
Library
CVTHEXPGM MYLIB
Service
Program
Library
CVTTOHEX
MYLIB
Binding
Directory Library
*NONE
MYLIB/CVTHEXPGM
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
Module
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
. . . :
Library
ISERIES1
*NEW
*GEN
*NODUPPROC *NODUPVAR
*BASIC
*YES
*USER
*YES
*LIBCRTAUT
*CURRENT
*NO
*ENTMODTXT
Module
Library
*WARN
*RSLVREF
Module
Library
Service
Program
Library
Service
Program
Library
Service
Program
Library
Binding
Directory
Library
Binding
Directory
Library
Binding
Directory
Library
020719
MYLIB/CVTHEXPGM
Brief Summary Table
. : 1
Identifier
_QRNP_PEP_CVTHEXPGM
. : 0
. : 0
N D O F B R I E F S U M M A R Y
Create Program
020719
CVTHEXPGM
MYLIB
*FIRST
Create Program
5769WDS V5R2M0
23:24:00
Page
08/15/02
T A B L E
Page
08/15/02
Page
08/15/02
* * * * *
MYLIB/CVTHEXPGM
Binding Statistics
Symbol collection CPU time . . . . . . . . . . . . . . . . . :
.016
Symbol resolution CPU time . . . . . . . . . . . . . . . . . :
.004
Binding directory resolution CPU time . . . . . . . . . . . :
.175
Binder language compilation CPU time . . . . . . . . . . . . :
.000
Listing creation CPU time . . . . . . . . . . . . . . . . . :
.068
Program/service program creation CPU time . . . . . . . . . :
.234
Total CPU time . . . . . . . . . . . . . . . . . . . . . . . :
.995
Total elapsed time . . . . . . . . . . . . . . . . . . . . . :
3.531
* * * * * E N D O F B I N D I N G S T A T I S T I C S
*CPC5D07 - Program CVTHEXPGM created in library MYLIB.
* * * * * E N D O F C R E A T E P R O G R A M L I S T I N G
ISERIES1
ISERIES1
* * * * *
* * * * *
105
106
The program object specified must exist in a library and this library must be
contained in the library list *LIBL. You can also explicitly specify the library in the
CL CALL command as follows:
CALL MYLIB/EMPRPT
For further information about using the CL CALL command, see the CL and APIs
section of the Programming category in the i5/OS Information Center at this Web
site - http://www.ibm.com/systems/i/infocenter/.
Once you call your program, the IBM i system performs the instructions found in
the program.
107
You can also type the parameters without specifying any keywords:
CALL library/program-name (parameter-1 parameter-2 ... parameter-n)
When the CALL command is issued, the contents of the parameter passed by
the command is stored and the program parameter PSWORD points to its
location. The program then checks to see if the contents of PSWORD matches
the value stored in the program, ('HELLO'). In this case, the two values are the
same, and so the program continues to run.
*===============================================================*
* PROGRAM NAME:
EMPRPT2
*
* RELATED FILES: EMPMST
(PHYSICAL FILE)
*
*
PRINT
(PRINTER FILE)
*
* DESCRIPTION:
This program prints employee information
*
*
stored in the file EMPMST if the password
*
*
entered is correct.
*
*
Run the program by typing "CALL library name/ *
*
EMPRPT2 (PSWORD)" on the command line, where *
*
PSWORD is the password for this program.
*
*
The password for this program is HELLO.
*
*===============================================================*
FPRINT
O
F
80
PRINTER
FEMPMST
IP E
K DISK
IEMPREC
01
Figure 48. ILE RPG Program that Requires Parameters at Run Time (Part 1 of 2)
108
*-----------------------------------------------------------------*
* The entry parameter list is specified in this program.
*
* There is one parameter, called PSWORD, and it is a
*
* character field 5 characters long.
*
*-----------------------------------------------------------------*
C
*ENTRY
PLIST
C
PARM
PSWORD
5
*-----------------------------------------------------------------*
* The password for this program is HELLO. The field PSWORD
*
* is checked to see whether or not it contains HELLO.
*
* If it does not, the last record indicator (LR) and *IN99
*
* are set on. *IN99 controls the printing of messages.
*
*-----------------------------------------------------------------*
C
PSWORD
IFNE
HELLO
C
SETON
LR99
C
ENDIF
OPRINT
H
1P
2 6
O
50 EMPLOYEE INFORMATION
O
H
1P
O
12 NAME
O
34 SERIAL #
O
45 DEPT
O
56 TYPE
O
D
01N99
O
ENAME
20
O
ENUM
32
O
EDEPT
45
O
ETYPE
55
O
D
99
O
16 ***
O
40 Invalid Password Entered
O
43 ***
Figure 48. ILE RPG Program that Requires Parameters at Run Time (Part 2 of 2)
109
Selection or command
===> _________________________________________________________________________
_______________________________________________________________________________
F3=Exit
F4=Prompt F9=Retrieve F12=Cancel
F13=Information Assistant F16=AS/400 main menu
110
A
5 11Inquire
A
5 19into
A
5 24employee
A
5 33master
A
6 11Change
A
6 18employee
A
6 27master
A
7 11Add
A
7 15new
A
7 19employee
Figure 52 shows the source of the application menu illustrated in Figure 50 on page
110. The source member is called PAYROLQQ and has a source type of MNUCMD.
It was also created using SDA.
PAYROLQQ,1
0001 call RPGINQ
0002 call RPGCHG
0003 call RPGADD
Figure 52. Source for Menu Program
If the user enters 1, 2, or 3 from the application menu, the source in Figure 52 calls
the programs RPGINQ, RPGCHG, or RPGADD respectively.
111
When you run a program with ILE RPG procedures, run-time inquiry messages
may be generated. They occur when the default error handler is invoked for a
function check in a cycle-main procedure. See Exception Handling within a
Cycle-Main Procedure on page 288. The inquiry messages require a response
before the program continues running.
#
#
#
#
#
Note: Inquiry messages are never issued for subprocedures (including those
designated as linear-main procedures), since the default error handling for a
function check in a subprocedure causes the subprocedure to be cancelled,
causing the exception to percolate to the caller of the subprocedure. See
Exception Handling within Subprocedures.
#
#
#
#
If the caller of the subprocedure is an RPG procedure, the call will fail with status
00202, independent of the status code associated with the actual exception. If the
failed call causes an RPG cycle-main procedure to invoke its default handler,
inquiry message RNQ0202 will be issued.
You can add the inquiry messages to a system reply list to provide automatic
replies to the messages. The replies for these messages may be specified
individually or generally. This method of replying to inquiry messages is especially
suitable for batch programs, which would otherwise require an operator to issue
replies.
You can add the following ILE RPG inquiry messages to the system reply list:
112
RNQ0421
RNQ0425
RNQ0426
RNQ0431
RNQ0432
RNQ0450
RNQ0501
RNQ0502
RNQ0802
RNQ0803
RNQ0804
RNQ0805
RNQ0907
RNQ1011
RNQ1021
RNQ1022
RNQ1023
RNQ1024
RNQ1031
RNQ1041
RNQ1042
RNQ1051
RNQ1071
RNQ1201
RNQ1211
RNQ1215
RNQ1216
RNQ1217
RNQ1218
RNQ1221
RNQ1222
RNQ1231
RNQ1235
RNQ1241
RNQ1251
RNQ1255
RNQ1261
RNQ1271
RNQ1281
RNQ1282
RNQ1284
RNQ1285
RNQ1286
RNQ1287
RNQ1299
RNQ1331
RNQ9998
RNQ9999
where sequence-no is a number from 1-9999, which reflects where in the list the
entry is being added, and message-id is the message number you want to add.
Repeat this command for each message you want to add.
Use the Change Job (CHGJOB) command (or other CL job command) to indicate
that your job uses the reply list for inquiry messages. To do this, you should
specify *SYSRPYL for the Inquiry Message Reply (INQMSGRPY) attribute.
The reply list is only used when an inquiry message is sent by a job that has the
Inquiry Message Reply (INQMSGRPY) attribute specified as
INQMSGRPY(*SYSRPYL). The INQMSGRPY parameter occurs on the following CL
commands:
v Change Job (CHGJOB)
v Change Job Description (CHGJOBD)
v Create Job Description (CRTJOBD)
v Submit Job (SBMJOB).
You can also use the Work with Reply List Entry (WRKRPYLE) command to
change or remove entries in the system reply list. For details of the ADDRPYLE
and WRKRPYLE commands, see the CL and APIs section of the Programming
category in the i5/OS Information Center at this Web site - http://www.ibm.com/
systems/i/infocenter/.
113
114
115
116
Note: This means that if you have a service program that ran in the default
activation group and left files open, and a RCLRSC is issued, when you call
the service program again, the files will still appear to be open, so so any
I/O operations will result in an error.
For ILE programs associated with a named activation group, the RCLRSC
command has no effect. You must use the RCLACTGRP command to free resources
in a named activation group.
For more information on the RCLRSC command, refer to the CL and APIs section
of the Programming category in the i5/OS Information Center at this Web site http://www.ibm.com/systems/i/infocenter/. For more information on the
RCLRSC and activation groups, refer to ILE Concepts.
117
There are two types of heaps available on the system: a default heap and a
user-created heap. The RPG storage management operations use the default heap.
The following sections show how to use RPG storage management operations with
the default heap, and also how to create and use your own heap using the storage
management APIs. For more information on user-created heaps and other ILE
storage management concepts refer to ILE Concepts.
118
119
*-----------------------------------------------------------------*
* Prototypes for subprocedures in this module
*
*-----------------------------------------------------------------*
D AddName
PR
D
name_parm
40A
D Display
PR
D Free
PR
*-----------------------------------------------------------------*
* Each element in the list contains a pointer to the
*
* name and a pointer to the next element
*
*-----------------------------------------------------------------*
D elem
DS
BASED(elem@)
D
name@
*
D
next@
*
D
name_len
5U 0
D nameVal
S
40A
BASED(name@)
D elemSize
C
%SIZE(elem)
*-----------------------------------------------------------------*
* The first element in the list is in static storage.
*
* The name field of this element is not set to a value.
*
*-----------------------------------------------------------------*
D first
DS
D
*
INZ(*NULL)
D
*
INZ(*NULL)
D
5U 0 INZ(0)
*-----------------------------------------------------------------*
* This is the pointer to the current element.
*
* When elem@ is set to the address of <first>, the list is
*
* empty.
*
*-----------------------------------------------------------------*
D elem@
S
*
INZ(%ADDR(first))
*-----------------------------------------------------------------*
* Put 5 elements in the list
*
*-----------------------------------------------------------------*
C
DO
5
C
Name?
DSPLY
name
40
C
CALLP
AddName(name)
C
ENDDO
*-----------------------------------------------------------------*
* Display the list and then free it.
*
*-----------------------------------------------------------------*
C
CALLP
Display
C
CALLP
Free
C
EVAL
*INLR = 1
120
*-----------------------------------------------------------------*
* S U B P R O C E D U R E S
*
*-----------------------------------------------------------------*
*-----------------------------------------------------------------*
* AddName - add a name to the end of the list
*
*-----------------------------------------------------------------*
P AddName
B
D AddName
pi
D
name
40A
*-----------------------------------------------------------------*
* Allocate a new element for the array, pointed at by the
*
* next pointer of the current end of the list.
*
*
*
* Before:
*
*
*
* .-------------.
*
* |
|
*
* | name
*--->abc
*
* | name_len 3 |
*
* | next
*-------|||
*
* |
|
*
* -------------
*
*
*
*-----------------------------------------------------------------*
C
ALLOC
elemSize
next@
*-----------------------------------------------------------------*
*
*
* After: Note that the old element is still the current one
*
*
because elem@ is still pointing to the old element
*
*
*
* .-------------.
.--------------.
*
* |
|
.------>|
|
*
* | name
*--->abc
|
|
|
*
* | name_len 3 |
|
|
|
*
* | next
*----------
|
|
*
* |
|
|
|
*
* -------------
--------------
*
*
*
* Now set elem@ to point to the new element
*
*-----------------------------------------------------------------*
C
EVAL
elem@ = next@
Figure 54. Memory Management - Build a Linked List of Names (Part 2 of 5)
121
*-----------------------------------------------------------------*
*
*
* After: Now the names name@, name_len and next@ refer
*
*
to storage in the new element
*
*
*
* .-------------.
.--------------.
*
* |
|
.------>|
|
*
* |
*--->abc
|
| name
* |
*
* |
3 |
|
| name_len
|
*
* |
*----------
| next
* |
*
* |
|
|
|
*
* -------------
--------------
*
*
*
* Now set the values of the new element.
*
* The next pointer is set to *NULL to indicate that it is the
*
* end of the list.
*
*-----------------------------------------------------------------*
C
EVAL
next@ = *NULL
*-----------------------------------------------------------------*
* Save the length of the name (not counting trailing blanks)
*-----------------------------------------------------------------*
C
EVAL
name_len = %len(%trimr(name))
*-----------------------------------------------------------------*
* Storage is allocated for the name and then set to the value of
* the name.
*-----------------------------------------------------------------*
C
ALLOC
name_len
name@
C
EVAL
%SUBST(nameVal:1:name_len) = name
*-----------------------------------------------------------------*
*
*
* After:
*
*
*
* .-------------.
.--------------.
*
* |
|
.------>|
|
*
* |
*--->abc
|
| name
*--->newname
*
* |
3 |
|
| name_len nn |
*
* |
*----------
| next
*--->|||
*
* |
|
|
|
*
* -------------
--------------
*
*-----------------------------------------------------------------*
P AddName
E
Figure 54. Memory Management - Build a Linked List of Names (Part 3 of 5)
122
*-----------------------------------------------------------------*
* Display - display the list
*
*-----------------------------------------------------------------*
P Display
B
D saveElem@
S
*
D dspName
S
40A
*-----------------------------------------------------------------*
* Save the current elem pointer so the list can be restored after *
* being displayed and set the list pointer to the beginning of
*
* the list.
*
*-----------------------------------------------------------------*
C
EVAL
saveElem@ = elem@
C
EVAL
elem@ = %ADDR(first)
*-----------------------------------------------------------------*
* Loop through the elements of the list until the next pointer is *
* *NULL
*
*-----------------------------------------------------------------*
C
DOW
next@ <> *NULL
C
EVAL
elem@ = next@
C
EVAL
dspName = %SUBST(nameVal:1:name_len)
C
Name:
dsply
dspName
C
ENDDO
*-----------------------------------------------------------------*
* Restore the list pointer to its former place
*-----------------------------------------------------------------*
C
EVAL
elem@ = saveElem@
P Display
E
Figure 54. Memory Management - Build a Linked List of Names (Part 4 of 5)
123
*-----------------------------------------------------------------*
* Free - release the storage used by the list
*
*-----------------------------------------------------------------*
P Free
B
D prv@
S
*
*-----------------------------------------------------------------*
* Loop through the elements of the list until the next pointer is *
* *NULL, starting from the first real element in the list
*
*-----------------------------------------------------------------*
C
EVAL
elem@ = %ADDR(first)
C
EVAL
elem@ = next@
C
DOW
elem@ <> *NULL
*-----------------------------------------------------------------*
* Free the storage for name
*
*-----------------------------------------------------------------*
C
DEALLOC
name@
*-----------------------------------------------------------------*
* Save the pointer to current elem@
*-----------------------------------------------------------------*
C
EVAL
prv@ = elem@
*-----------------------------------------------------------------*
* Advance elem@ to the next element
*-----------------------------------------------------------------*
C
EVAL
elem@ = next@
*-----------------------------------------------------------------*
* Free the storage for the current element
*-----------------------------------------------------------------*
C
DEALLOC
prv@
C
ENDDO
*-----------------------------------------------------------------*
* Ready for a new list:
*-----------------------------------------------------------------*
C
EVAL
elem@ = %ADDR(first)
P Free
E
Figure 54. Memory Management - Build a Linked List of Names (Part 5 of 5)
124
*..1....+....2....+....3....+....4....+....5....+....6....+....7...+....
*-----------------------------------------------------------------*
* Heap Storage Misuse
*
*-----------------------------------------------------------------*
D Fld1
S
25A
BASED(Ptr1)
D Ptr1
S
*
/FREE
Ptr1 = %ALLOC(25);
DEALLOC Ptr1;
// After this point, Fld1 should not be accessed since the
// basing pointer Ptr1 no longer points to allocated storage.
SomePgm();
//
//
//
//
//
Fld1 = *ALLa;
/END-FREE
Figure 55. Heap Storage Misuse
125
DYNARRAY performs these actions using the three ILE bindable storage APIs,
CEECRHP (Create Heap), CEEGTST (Get Storage), and CEEDSHP (Discard Heap),
as well as the REALLOC operation code. For specific information about the storage
management bindable APIs, refer to the CL and APIs section of the Programming
category in the i5/OS Information Center at this Web site - http://www.ibm.com/
systems/i/infocenter/.
Figure 56 shows the /COPY file DYNARRI containing the prototypes for the
procedures in DYNARRAY. This /COPY file is used by the DYNARRAY module as
well as any other modules that call the procedures in DYNARRAY.
DYNARRAY has been defined for use with a (15,0) packed decimal array. It could
easily be converted to handle a character array simply by changing the definition
of DYNA_TYPE to a character field.
*=================================================================
* DYNARRAY :
Handle a (practically) unbounded run-time
*
Packed(15,0) array.
The DYNARRAY module contains
*
procedures to allocate the array, return or set
*
an array value and deallocate the array.
*=================================================================
D DYNA_TYPE
S
15P 0
D DYNA_INIT
PR
D DYNA_TERM
PR
D DYNA_SET
PR
D
Element
VALUE LIKE(DYNA_TYPE)
D
Index
5I 0
VALUE
D DYNA_GET
PR
LIKE(DYNA_TYPE)
D
Index
5I 0
VALUE
Figure 56. /COPY file DYNARRI containing prototypes for DYNARRAY module
Figure 57 on page 127 shows the beginning of module DYNARRAY containing the
Control specification, and Definition specifications.
126
*=================================================================
* DYNARRAY :
Handle a (practically) unbounded run-time
*
Packed(15,0) array.
This module contains
*
procedures to allocate the array, return or set
*
an array value and deallocate the array.
*=================================================================
H NOMAIN
*----------------------------------------------------------------* Prototypes for the procedures in this module.
*----------------------------------------------------------------/COPY DYNARRI
*----------------------------------------------------------------* Interface to the CEEGTST API (Get Heap Storage).
* 1) HeapId = Id of the heap.
* 2) Size
= Number of bytes to allocate
* 3) RetAddr= Return address of the allocated storage
* 4) *OMIT = The feedback parameter. Specifying *OMIT here
*
means that we will receive an exception from
*
the API if it cannot satisfy our request.
*
Since we do not monitor for it, the calling
*
procedure will receive the exception.
*----------------------------------------------------------------D CEEGTST
PR
D
HeapId
10I 0
CONST
D
Size
10I 0
CONST
D
RetAddr
*
D
Feedback
12A
OPTIONS(*OMIT)
*----------------------------------------------------------------* Interface to the CEECRHP API (Create Heap).
* 1) HeapId
= Id of the heap.
* 2) InitSize
= Initial size of the heap.
* 3) Incr
= Number of bytes to increment if heap must be
*
enlarged.
* 4) AllocStrat = Allocation strategy for this heap. We will
*
specify a value of 0 which allows the system
*
to choose the optimal strategy.
* 5) *OMIT
= The feedback parameter. Specifying *OMIT here
*
means that we will receive an exception from
*
the API if it cannot satisfy our request.
*
Since we do not monitor for it, the calling
*
procedure will receive the exception.
*----------------------------------------------------------------D CEECRHP
PR
D
HeapId
10I 0
D
InitSize
10I 0
CONST
D
Incr
10I 0
CONST
D
AllocStrat
10I 0
CONST
D
Feedback
12A
OPTIONS(*OMIT)
Figure 57. Global variables and local prototypes for DYNARRAY (Part 1 of 2)
127
128
*=================================================================
* DYNA_INIT: Initialize the array.
*
* Function: Create the heap and allocate an initial amount of
*
storage for the run time array.
*=================================================================
P DYNA_INIT
B
EXPORT
*----------------------------------------------------------------* Local variables.
*----------------------------------------------------------------D Size
S
10I 0
*
* Start with a pre-determined number of elements.
*
C
Z-ADD
INITALLOC
NumElems
*
* Determine the number of bytes needed for the array.
*
C
EVAL
Size = NumElems * %SIZE(DynArr)
*
* Create the heap
*
C
CALLP
CEECRHP(HeapId : Size : 0 : 0 : *OMIT)
*
*
*
*
*
*
*
C
*
* Initialize the storage for the array.
*
C
1
DO
NumElems
C
CLEAR
C
ENDDO
P DYNA_INIT
E
I
DynArr(I)
5 0
*=================================================================
* DYNA_TERM: Terminate array handling.
*
* Function: Delete the heap.
*=================================================================
P DYNA_TERM
B
EXPORT
C
CALLP
CEEDSHP(HeapId : *OMIT)
C
RESET
HeapVars
P DYNA_TERM
E
Figure 58. DYNARRAY Subprocedures (Part 1 of 4)
129
*=================================================================
* DYNA_SET: Set an array element.
*
* Function: Ensure the array is big enough for this element,
*
and set the element to the provided value.
*=================================================================
P DYNA_SET
B
EXPORT
*----------------------------------------------------------------* Input parameters for this procedure.
*----------------------------------------------------------------D DYNA_SET
PI
D
Element
VALUE LIKE(DYNA_TYPE)
D
Index
5I 0
VALUE
*----------------------------------------------------------------* Local variables.
*----------------------------------------------------------------D Size
S
10I 0
*----------------------------------------------------------------* If the user selects to add to the array, then first check
* if the array is large enough, if not then increase its
* size. Add the element.
*----------------------------------------------------------------C
Index
IFGT
NumElems
C
EXSR
REALLOC
C
ENDIF
C
EVAL
DynArr(Index) = Element
*=================================================================
* REALLOC: Reallocate storage subroutine
*
*
Function: Increase the size of the dynamic array
*
and initialize the new elements.
*=================================================================
C
REALLOC
BEGSR
*
*
*
C
NumElems
130
OldElems
5 0
*
*
*
*
*
*
C
C
C
C
C
NumElems
*
* Calculate the new size of the array
*
C
EVAL
Size = NumElems * %SIZE(DynArr)
*
* Reallocate the storage. The new storage has the same value
* as the old storage.
*
C
REALLOC
Size
DynArr@
*
* Initialize the new elements for the array.
*
C
1
ADD
OldElems
I
C
I
DO
NumElems
I
5 0
C
CLEAR
DynArr(I)
C
ENDDO
C
ENDSR
P DYNA_SET
E
Figure 58. DYNARRAY Subprocedures (Part 3 of 4)
*=================================================================
* DYNA_GET: Return an array element.
*
* Function: Return the current value of the array element if
*
the element is within the size of the array, or
*
the default value otherwise.
*=================================================================
P DYNA_GET
B
EXPORT
*----------------------------------------------------------------* Input parameters for this procedure.
*----------------------------------------------------------------D DYNA_GET
PI
LIKE(DYNA_TYPE)
D
Index
5I 0
VALUE
*----------------------------------------------------------------* Local variables.
*----------------------------------------------------------------D Element
S
LIKE(DYNA_TYPE) INZ
*----------------------------------------------------------------* If the element requested is within the current size of the
* array then return the elements current value. Otherwise
* the default (initialization) value can be used.
*----------------------------------------------------------------C
Index
IFLE
NumElems
C
EVAL
Element = DynArr(Index)
C
ENDIF
C
RETURN
Element
P DYNA_GET
E
Figure 58. DYNARRAY Subprocedures (Part 4 of 4)
131
The procedure can then be bound with other modules using CRTPGM or
CRTSRVPGM.
Figure 59 shows another module that tests the procedures in DYNARRAY.
*=================================================================
* DYNTEST: Test program for DYNARRAY module.
*=================================================================
/COPY EXAMPLES,DYNARRI
D X
S
LIKE(DYNA_TYPE)
* Initialize the array
C
CALLP
DYNA_INIT
* Set a few elements
C
CALLP
DYNA_SET (25 : 3)
C
CALLP
DYNA_SET (467252232 : 1)
C
CALLP
DYNA_SET (-2311 : 750)
* Retrieve a few elements
C
EVAL
X = DYNA_GET (750)
C
750
DSPLY
X
C
EVAL
X = DYNA_GET (8001)
C
8001
DSPLY
X
C
EVAL
X = DYNA_GET (2)
C
2
DSPLY
X
* Clean up
C
C
CALLP
SETON
DYNA_TERM
132
LR
133
Calling Programs
You can call OPM or ILE programs by using program calls. A program call is a call
that is made to a program object (*PGM). The called program's name is resolved to
an address at run time, just before the calling program passes control to the called
program for the first time. For this reason, program calls are often referred to as
dynamic calls.
Calls to an ILE program, an EPM program, or an OPM program are all examples
of program calls. A call to a non-bindable API is also an example of a program call.
You use the CALLP operation or both the CALL and PARM operations to make a
program call. If you use the CALL and PARM operations, then the compiler cannot
perform type checking on the parameters, which may result in run-time errors.
When an ILE program is called, the program entry procedure receives the program
parameters and is given initial control for the program. In addition, all procedures
within the program become available for procedure calls.
Calling Procedures
Unlike OPM programs, ILE programs are not limited to using program calls. ILE
programs can also use static procedure calls or procedure pointer calls to call other
procedures. Procedure calls are also referred to as bound calls.
A static procedure call is a call to an ILE procedure where the name of the
procedure is resolved to an address during binding hence, the term static. As a
result, run-time performance using static procedure calls is faster than run-time
performance using program calls. Static calls allow operational descriptors, omitted
parameters, and they extend the limit (to 399) on the number of parameters that
are passed.
Procedure pointer calls provide a way to call a procedure dynamically. For
example, you can pass a procedure pointer as a parameter to another procedure
which would then run the procedure that is specified in the passed parameter. You
can also manipulate arrays of procedure names or addresses to dynamically route
a procedure call to different procedures. If the called procedure is in the same
activation group, the cost of a procedure pointer call is almost identical to the cost
of a static procedure call.
Using either type of procedure call, you can call:
v A procedure in a separate module within the same ILE program or service
program.
v A procedure in a separate ILE service program.
Any procedure that can be called by using a static procedure call can also be called
through a procedure pointer.
134
Note: In a program call, the calls to the program entry procedure and the user
entry procedure (UEP) occur together, since the call to the UEP is automatic.
Chapter 10. Calling Programs and Procedures
135
Recursive Calls
#
#
#
#
#
#
#
#
#
#
#
Recursive calls are allowed for subprocedures. A recursive call is one where
procedure A calls itself or calls procedure B which then calls procedure A again.
Each recursive call causes a new invocation of the procedure to be placed on the
call stack. The new invocation has new storage for all data items in automatic
storage, and that storage is unavailable to other invocations because it is local. (A
data item that is defined in a subprocedure uses automatic storage unless the
STATIC keyword is specified for the definition.) Note also that the automatic
storage that is associated with earlier invocations is unaffected by later invocations.
The new invocation uses the same static storage as the previous invocation, both
the global static storage of the module, and the local static storage in the
procedure.
#
#
#
#
#
#
Recursive calls are also allowed for programs whose main procedure is a
linear-main procedure. A linear-main procedure can only be called through a
program call, so when a linear-main procedure calls itself recursively, the program
containing the linear-main procedure is called again. Otherwise, the behavior for a
linear-main procedure calling itself recursively is the same as for an ordinary
subprocedure calling itself recursively.
#
#
#
A cycle-main procedure that is on the call stack cannot be called until it returns to
its caller. Therefore, be careful not to call a procedure that might call an already
active cycle-main procedure.
Try to avoid situations that might inadvertently lead to recursive calls. For
example, suppose there are three modules, as shown in Figure 61.
136
So while subprocedures can be called recursively, if you are not aware that
recursion is occurring, you may exhaust system resources.
137
Attention!
Unconditional recursive calls can lead to infinite recursion which leads to
excessive use of system resources. Infinite recursion can be avoided with
proper programming. In general, a proper recursive procedure begins with a
test to determine if the desired result has been obtained. If it has been
obtained, then the recursive procedure returns to the most recent caller.
Parameter-Passing Considerations
When designing a call interface, you must make a number of decisions in terms of
how parameters will be passed. On the other hand, if you are the caller then most
of the decisions have already been made for you. The following lists some of the
parameter-passing considerations to keep in mind when you are designing a call
interface.
v Compile-time parameter checking
The call interface of a prototyped call is checked at compile time. This checking
ensures that:
the data types are correctly used
correct files are passed to file parameters
all required parameters are passed
*OMIT is only passed where it is allowed.
138
#
#
Prototyped
Not
Prototyped
See Page
Yes
Pass by reference
Yes
Pass by value
Yes (b)
142
Yes
142
Yes (b)
Yes (b)
144
Pass *OMIT
Yes
Yes (b)
146
Yes
Yes
146
Yes
Yes
147
Yes
152
Yes
Passing File
Parameters on
page 153
141
Yes
142
139
CALLP
In free-form calculations, you can omit CALLP if there are no operation extenders.
The free-form operation can use either of the following forms:
/free
callp name { (parm1 { :parm2 ...} ) };
name( {parm1 {:parm2 ... }} );
/end-free
|
|
|
The following example shows a call to a procedure Switch, which changes the state
of the indicator that is passed to it, in this case *IN10..
C
CALLP
Switch(*in10)
140
*
CVTCHR(15-124) returns -109
D CVTCHR
PR
31A
D
NUM
30P 0
VALUE
Figure 63. Prototype for CVTCHR
C
C
C
EVAL
STRING = Address: +
%TRIM(CVTCHR(StreetNum))
+ + StreetName
* If STREETNUM = 427 and STREETNAME = Mockingbird Lane, after the
* EVAL operation STRING = ADDRESS: 427 Mockingbird Lane
141
Passing by Reference
The default parameter passing style for ILE RPG is to pass by reference.
Consequently, you do not have to code any keywords on the parameter definition
to pass the parameter by reference. You should pass parameters by reference to a
procedure when you expect the callee to modify the field passed. You may also
want to pass by reference to improve run-time performance, for example, when
passing large character fields. Note also that parameters that are passed on external
program calls can only be passed by reference.
Passing by Value
With a prototyped procedure, you can pass a parameter by value instead of by
reference. When a parameter is passed by value, the compiler passes the actual
value to the called procedure.
When a parameter is passed by value, the called program or procedure can change
the value of the parameter, but the caller will never see the changed value.
To pass a parameter by value, specify the keyword VALUE on the parameter
definition in the prototype, as shown in the figures below.
Note: IBM i program calls require that parameters be passed by reference.
Consequently, you cannot pass a parameter by value to a program.
142
If the prototype requires an array of 4 elements, the passed parameter can be:
v An array with fewer than 4 elements. In this case, the remaining elements in the
received parameter will contain the default value for the type.
v An array with 4 elements. In this case, each element of the received parameter
will correspond to an element of the passed parameter.
v An array with more than 4 elements. In this case, some of the elements of the
passed array will not be passed to the received parameter.
v A non-array. In this case, each element of the received parameter will contain the
passed parameter value.
143
P DO_CALC
B
EXPORT
*------------------------------------------------------------* This procedure performs a function on the 3 numeric values
* passed to it as value parameters. It also returns a value.
*------------------------------------------------------------D DO_CALC
PI
10I 0
D
Term1
5I 0 VALUE
D
Term2
5I 0 VALUE
D
Term3
5I 0 VALUE
D Result
S
10I 0
C
EVAL
Result = Term1 ** 2 * 17
C
+ Term2
* 7
C
+ Term3
C
RETURN
Result * 45 + 23
P
E
Figure 66. Procedure Interface Definition for DO_CALC Procedure
The second parameter passed to CEETSTA can be any numeric field, a literal, a
built-in function, or expression.
144
145
Omitting Parameters
When calling a program or procedure, you may sometimes want to leave out a
parameter. It may be that it is not relevant to the called procedure. For example,
this situation might arise when you are calling the ILE bindable APIs. Another
reason might be that you are calling an older procedure that does not handle this
particular parameter. If you need to omit a parameter on a call, you have two
choices:
v Specify OPTIONS(*OMIT) and pass *OMIT
v Specify OPTIONS(*NOPASS) and do not pass the parameter.
The primary difference between the two methods has to do with how you check to
see if a parameter has been omitted. In either case, an omitted parameter cannot be
referenced by the called procedure; if it is, unpredictable results will occur. So if
the called procedure is designed to handle different numbers of parameters, you
will have to check for the number of parameters passed. If *OMIT is passed, it will
'count' as a parameter.
Passing *OMIT
You can pass *OMIT for a prototyped parameter if the called procedure is aware
that *OMIT might be passed. In other words, you can pass *OMIT if the keyword
OPTIONS(*OMIT) is specified on the corresponding parameter definition in the
prototype. When *OMIT is specified, the compiler will generate the necessary code
to indicate to the called procedure that the parameter has been omitted.
Note: *OMIT can only be specified for parameters passed by reference.
To determine if *OMIT has been passed to an ILE RPG procedure, use the %ADDR
built-in function to check the address of the parameter in question. If the address is
*NULL, then *OMIT has been passed. You can also use the CEETSTA (Check for
Omitted Argument) bindable API. (See Figure 67 on page 144 for a brief example.)
The following is a simple example of how *OMIT can be used. In this example, a
procedure calls the ILE bindable API CEEDOD in order to decompose an
operational descriptor. The CEEDOD API expects to receive seven parameters; yet
only six have been defined in the calling procedure. The last parameter of
CEEDOD (and of most bindable APIs) is the feedback code which can be used to
determine how the API ended. However, the calling procedure has been designed
to receive any error messages via an exception rather than this feedback code.
Consequently, on the call to CEEDOD, the procedure must indicate that the
parameter for the feedback code has been omitted.
See Sample Service Program on page 97 for an example of using *OMIT.
146
%PARMS does not take any parameters. The value returned by %PARMS also
includes any parameters for which *OMIT has been passed, and it also includes
the additional first parameter that handles the return value for a procedure that
has the RTNPARM keyword specified. For a cycle-main procedure, %PARMS
returns the same value as contained in the *PARMS field in a PSDS, although to
use the *PARMS field, you must also code the PSDS.
|
|
|
|
Using %PARMS
In this example, a procedure FMTADDR has been changed several times to allow
for a change in the address information for the employees of a company.
FMTADDR is called by three different procedures. The procedures differ only in
the number of parameters they use to process the employee information. That is,
new requirements for the FMTADDR have arisen, and to support them, new
parameters have been added. However, old procedures calling FMTADDR are still
supported and do not have to be changed or recompiled.
147
148
*=================================================================*
* FMTADDR - format an address
*
* Interface parameters
* 1. Address
character(70)
* 2. Street number packed(5,0)
* 3. Street name
character(20)
* 4. City
character(15)
(some callers do not pass)
* 5. Province
character(15)
(some callers do not pass)
*=================================================================*
* Pull in the prototype from the /COPY member
/COPY FMTADDRP
DFmtAddr
PI
D Address
70
D Street#
5 0 CONST
D Street
20
CONST
D P_City
15
OPTIONS(*NOPASS) CONST
D P_Province
15
OPTIONS(*NOPASS) CONST
*-----------------------------------------------------------------*
* Default values for parameters that might not be passed.
*-----------------------------------------------------------------*
D City
S
15
INZ(Toronto)
D Province
S
15
INZ(Ontario)
*-----------------------------------------------------------------*
* Check whether the province parameter was passed. If it was,
* replace the default with the parameter value.
*-----------------------------------------------------------------*
C
IF
%PARMS > 4
C
EVAL
Province = P_Province
C
ENDIF
*-----------------------------------------------------------------*
* Check whether the city parameter was passed. If it was,
*
* replace the default with the parameter value.
*
*-----------------------------------------------------------------*
C
IF
%PARMS > 3
C
EVAL
City = P_City
C
ENDIF
*-----------------------------------------------------------------*
* Set CStreet# to be character form of Street#
*
*-----------------------------------------------------------------*
C
EXSR
GetStreet#
*-----------------------------------------------------------------*
* Format the address as
Number Street, City, Province
*
*-----------------------------------------------------------------*
C
EVAL
ADDRESS = %TRIMR(CSTREET#) + +
C
%TRIMR(CITY) + , +
C
%TRIMR(PROVINCE)
C
RETURN
Figure 70. Source for procedure FMTADDR (Part 1 of 2)
149
*=================================================================*
* SUBROUTINE: GetStreet#
* Get the character form of the street number, left-adjusted
*
* and padded on the right with blanks.
*
*=================================================================*
C
GetStreet#
BEGSR
C
MOVEL
Street#
CStreet#
10
*-----------------------------------------------------------------*
* Find the first non-zero.
*
*-----------------------------------------------------------------*
C
0
CHECK
CStreet#
Non0
5 0
*-----------------------------------------------------------------*
* If there was a non-zero, substring the number starting at
*
* non-zero.
*
*-----------------------------------------------------------------*
C
IF
Non0 > 0
C
SUBST(P) CStreet#:Non0 CStreet#
*-----------------------------------------------------------------*
* If there was no non-zero, just use 0 as the street number.
*
*-----------------------------------------------------------------*
C
ELSE
C
MOVEL(P) 0
CStreet#
C
ENDIF
C
ENDSR
Figure 70. Source for procedure FMTADDR (Part 2 of 2)
*=================================================================*
* Prototype for FMTADDR - format an address
*=================================================================*
DFmtAddr
PR
D addr
70
D strno
5 0 CONST
D st
20
CONST
D cty
15
OPTIONS(*NOPASS) CONST
D prov
15
OPTIONS(*NOPASS) CONST
Figure 71. Source for /COPY member with Prototype for Procedure FMTADDR
Figure 72 on page 151 shows the source for the procedure PRTADDR. This
procedure serves to illustrate the use of FMTADDR. For convenience, the three
procedures which would each call FMTADDR are combined into this single
procedure. Also, for the purposes of the example, the data is program-described.
Since PRTADDR is 'three procedures-in-one', it must define three different address
data structures. Similarly, there are three parts in the calculation specifications, each
one corresponding to programs at each stage. After printing the address, the
procedure PRTADDR ends.
150
*=================================================================*
* PRTADDR - Print an address
*
Calls FmtAddr to format the address
*=================================================================*
FQSYSPRT
O
F
80
PRINTER
*-----------------------------------------------------------------*
* Prototype for FmtAddr
*-----------------------------------------------------------------*
DFmtAddr
PR
D addr
70
D strno
5 0
D st
20
D cty
15
OPTIONS(*NOPASS)
D prov
15
OPTIONS(*NOPASS)
DAddress
S
70
*-----------------------------------------------------------------*
* Stage1: Original address data structure.
* Only street and number are variable information.
*-----------------------------------------------------------------*
D Stage1
DS
D
Street#1
5P 0 DIM(2) CTDATA
D
StreetNam1
20
DIM(2) ALT(Street#1)
*-----------------------------------------------------------------*
* Stage2: Revised address data structure as city information
* now variable.
*-----------------------------------------------------------------*
D Stage2
DS
D
Street#2
5P 0 DIM(2) CTDATA
D
Addr2
35
DIM(2) ALT(Street#2)
D
StreetNam2
20
OVERLAY(Addr2:1)
D
City2
15
OVERLAY(Addr2:21)
*-----------------------------------------------------------------*
* Stage3: Revised address data structure as provincial
* information now variable.
*-----------------------------------------------------------------*
D Stage3
DS
D
Street#3
5P 0 DIM(2) CTDATA
D
Addr3
50
DIM(2) ALT(Street#3)
D
StreetNam3
20
OVERLAY(Addr3:1)
D
City3
15
OVERLAY(Addr3:21)
D
Province3
15
OVERLAY(Addr3:36)
*-----------------------------------------------------------------*
* Program 1- Use of FMTADDR before city parameter was added.
*-----------------------------------------------------------------*
C
DO
2
X
5 0
C
CALLP
FMTADDR (Address:Street#1(X):StreetNam1(X))
C
EXCEPT
C
ENDDO
Figure 72. Source for procedure PRTADDR (Part 1 of 2)
151
*-----------------------------------------------------------------*
* Program 2- Use of FMTADDR before province parameter was added.*
*-----------------------------------------------------------------*
C
DO
2
X
5 0
C
CALLP
FMTADDR (Address:Street#2(X):
C
StreetNam2(X):City2(X))
C
EXCEPT
C
ENDDO
*-----------------------------------------------------------------*
* Program 3 - Use of FMTADDR after province parameter was added.*
*-----------------------------------------------------------------*
C
DO
2
X
5 0
C
CALLP
FMTADDR (Address:Street#3(X):
C
StreetNam3(X):City3(X):Province3(X))
C
EXCEPT
C
ENDDO
C
SETON
LR
*-----------------------------------------------------------------*
* Print the address.
*
*-----------------------------------------------------------------*
OQSYSPRT
E
O
Address
**
00123Bumble Bee Drive
01243Hummingbird Lane
**
00003Cowslip Street
01150Eglinton Avenue
**
00012Jasper Avenue
00027Avenue Road
Toronto
North York
Edmonton
Sudbury
Alberta
Ontario
152
#
#
#
#
#
#
#
You can use the LIKEFILE keyword to indicate that a prototyped parameter is a
file. When make a call using the prototype, the file that you pass must either be
the file that was specified on the LIKEFILE parameter of the prototype, or it must
be a file that is related through LIKEFILE File-specification keywords to that file.
For example, if you specify LIKEFILE(MYFILE) on the prototype, and you have
another File specification that defines file OTHERFILE using LIKEFILE(MYFILE),
then you can pass either MYFILE or OTHERFILE on the call. See
#
#
#
For more information on file parameters and variables associated with files see the
chapter about general file considerations in the "WebSphere Development Studio
ILE RPG Reference."
Order of Evaluation
There is no guaranteed order for evaluation of parameters on a prototyped call.
This fact may be important when using parameters that cause side effects, as the
results may not be what you would expect.
A side effect occurs if the processing of the parameter changes:
v The value of a reference parameter
v The value of a global variable
v An external object, such as a file or data area
If a side effect occurs, then, if the parameter is used elsewhere in the parameter
list, then the value used for the parameter in one part of the list may not be the
same as the value used in another part. For example, consider this call statement.
CALLP
Assume that procA has all value parameters, and procB has a reference parameter.
Assume also that fld starts off with the value 3, and that procB modifies fld to be 5,
and returns 10. Depending on the order in which the parameters are evaluated,
procA will receive either 3, 10, and 5 or possibly, 3, 10, and 3. Or possibly, 5, 10,
and 3; or even 5, 10, and 5.
In short, it is important to be aware of the possibility of side effects occurring. In
particular, if you are providing an application for third-party use, where the end
user may not know the details of some of the procedures, it is important ensure
that the values of the passed parameters are the expected ones.
153
Interlanguage Calls
When passing or receiving data from a program or procedure written in another
language, it is important to know whether the other language supports the same
parameter passing methods and the same data types as ILE RPG. Table 37 shows
the different parameter passing methods allowed by ILE RPG and, where
applicable, how they would be coded in the other the ILE languages. The table
also includes the OPM RPG/400 compiler for comparison.
Table 37. RPG Parameter Passing Methods
Passing By Reference
ILE RPG prototype
D
D
C
proc
parm
PR
CALLP
1A
proc(fld)
ILE C
ILE COBOL
RPG non-prototyped
ILE CL
C
C
CALL
PARM
PROC
FLD
Passing By Value
ILE RPG prototype
D
D
C
proc
parm
PR
CALLP
1A
VALUE
proc(a)
ILE C
ILE COBOL
RPG non-prototyped
N/A
ILE CL
N/A
D
D
C
proc
parm
PR
CALLP
1A
proc(fld)
ILE C
ILE COBOL
N/A1
RPG non-prototyped
N/A
ILE CL
N/A
CONST
Notes:
1. Do not confuse passing by read-only reference with COBOL's passing BY CONTENT. In
RPG terms, to pass Fld1 by content, you would code:
C
PARM
Fld1
TEMP
Fld1 is protected from being changed, but TEMP is not. There is no expectation that the
parameter will not be changed.
For information on the data types supported by different HLLs, consult the
appropriate language manual.
154
4. RPG procedures can interact with ILE C/C++ procedures that use 8-byte
pointers. However, the ILE C/C++ procedures must use 16-byte pointers for
parameters. See the IBM Rational Development Studio for i: ILE C/C++ Compiler
Reference.
5. RPG file parameters prototyped with the LIKEFILE keyword are not
interchangeable with file parameters from other languages. For example, you
cannot pass an RPG file to a C function that is expecting a FILE or RFILE
parameter. Similarly, a C function cannot pass a FILE or RFILE parameter to an
RPG procedure if the RPG parameter was prototyped with the LIKEFILE
keyword.
155
156
Factor 1
Factor 2
In calling
procedure
Value transferred from Result Field Value placed in Result Field entry
entry upon return.
when call occurs.
In called
procedure
Value transferred from Result Field Value placed in Result Field entry
entry when call occurs.
upon return.
Note: The moves to either the factor 1 entry or the result-field entry occur only
when the called procedure returns normally to its caller. If an error occurs
while attempting to move data to either entry, then the move is not
completed.
If insufficient parameters are specified when calling a procedure, an error occurs
when an unresolved parameter is used by the called procedure. To avoid the error,
you can either:
v Check %PARMS to determine the number of parameters passed. For an example
using %PARMS, see Checking for the Number of Passed Parameters on page
147.
v Specify *OMIT in the result field of the PARM operations of the unpassed
parameters. The called procedure can then check to see if the parameter has
been omitted by checking to see if the parameter has value of *NULL, using
%ADDR(parameter) = *NULL. For more information, refer to Omitting
Parameters on page 146.
Keep in mind the following when specifying a PARM operation:
v One or more PARM operations must immediately follow a PLIST operation.
v One or more PARM operations can immediately follow a CALL or CALLB
operation.
v When a multiple occurrence data structure is specified in the Result field of a
PARM operation, all occurrences of the data structure are passed as a single
field.
v Factor 1 and the Result field of a PARM operation cannot contain a literal, a
look-ahead field, a named constant, or a user-date reserved word.
v The following rules apply to *OMIT for non-prototyped parameters:
157
#
#
158
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
A cycle-main procedure ends normally and control returns to the calling procedure
when the LR indicator is on and the H1 through H9 indicators are not on. The LR
indicator can be set on:
v implicitly, as when the last record is processed from a primary or secondary file
during the RPG program cycle
v The RT indicator is on, the H1 through H9 indicators are not on, and the LR
indicator is on.
#
#
#
#
#
#
#
#
On the next call to the cycle-main procedure, with the exception of exported
variables, a fresh copy is available for processing. (Exported variables are
initialized only once, when the program is first activated in an activation group.
They retain their last assigned value on a new call, even if LR was on for the
previous call. If you want to re-initialize them, you have to reset them manually.)
159
TIP
If you are accustomed to ending with LR on to cause storage to be released,
and you are running in a named (persistent) activation group, you may want
to consider returning without an end. The reasons are:
v The storage is not freed until the activation group ends so there is no
storage advantage to ending with LR on.
v Call performance is improved if the program is not re-initialized for each
call.
You would only want to do this if you did not need your program
re-initialized each time.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
A cycle-main procedure can return control to the calling procedure without ending
when none of the LR or H1 through H9 indicators are on and one of the following
occurs:
v The RETURN operation (with a blank factor 2) is processed.
v The RT indicator is on and control reaches the *GETIN part of the RPG cycle, in
which case control returns immediately to the calling procedure. (For further
information on the RT indicator, see the IBM Rational Development Studio for i:
ILE RPG Reference)
#
#
#
#
160
If you call a cycle-main procedure and it returns without ending, when you call
the procedure again, all fields, indicators, and files in the procedure will hold the
same values they did when you left the procedure. However, there are three
exceptions:
v This is not true if the program is running in a *NEW activation group, since the
activation group is deleted when the program returns. In that case, the next time
you call your program will be the same as if you had ended with LR on.
v If you are sharing files, the state of the file may be different from the state it
held when you left the procedure.
#
#
v If another procedure in the same module was called in between, then the results
are unpredictable.
You can use either the RETURN operation (with a blank factor 2) or the RT
indicator in conjunction with the LR indicator and the H1 through H9 indicators.
Be aware of the testing sequence in the RPG program cycle for the RETURN
operation, the RT indicator, and the H1 through H9 indicators. A return will cause
an end if the LR indicator or any of the halt indicators is on and either of the
following conditions is true:
v A RETURN operation is done
v The RT would cause a return without an end
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
If the module is a cycle module, and the main procedure is never called (and
therefore cannot end) then any files, data areas, etcetera, will not be closed. If you
think this might arise for a subprocedure, you should code a termination
procedure that gets called when the subprocedure ends. This is especially true if
the subprocedure is in a module with NOMAIN specified on the control
specification.
161
#
#
#
#
For more information on CEETREC and CEE4ABN, refer to the CL and APIs
section of the Programming category in the i5/OS Information Center at this Web
site - http://www.ibm.com/systems/i/infocenter/.
Source Debugger
Math functions
Call management
Operational descriptor access
You access ILE bindable APIs using the same call mechanisms used by ILE RPG to
call procedures, that is, the CALLP operation or the CALLB operation. If the API
returns a value and you want to use it, call the API in an expression. For the
information required to define a prototype for an API, see the description of the
API in the CL and APIs section of the Programming category in the i5/OS
Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/. Figure 74 on page 163 shows a sample 'call' to a bindable API.
162
D CEExxxx
D
parm1
D
...
C
PR
EXTPROC(CEExxxx)
...
CALLP
CALLB
PARM
PARM
...
PARM
PARM
CEExxxx
or
C
C
C
C
C
parm1
parm2
parmn
feedback
where
v CEExxxx is the name of the bindable API
v parm1, parm2, ... parmn are omissible or required parameters passed to or
returned from the called API.
v feedback is an omissible feedback code that indicates the result of the bindable
API.
Note: Bindable APIs cannot be used if DFTACTGRP(*YES) is specified on the
CRTBNDRPG command.
For more information on bindable APIs, refer to the CL and APIs section of the
Programming category in the i5/OS Information Center at this Web site http://www.ibm.com/systems/i/infocenter/.
163
Storage Model
|
|
|
|
The integrated language environment (ILE) offers two storage models, single-level
and teraspace. Modules, programs and service programs can be created to use one
of these storage models, or they can be created to inherit their caller's storage
model.
|
|
|
|
|
|
|
|
All the programs and service programs called into an activation group must use
the same storage model. If the first program or service program called into an
activation group uses the single-level storage model, then all other programs and
service programs in the same activation group must use either the single-level or
the inherit storage model. Simiarly, if the first program or service program called
into an activation group uses the teraspace storage model, then all other programs
and service programs in the same activation group must use either the teraspace or
the inherit storage model.
|
|
|
|
|
A program or service program may be created from modules that use the
single-level storage model and the inherit storage model, or from modules that use
the teraspace storage model and the inherit storage model. A program or service
program cannot be created from modules that use both the single-level storage
model and the teraspace storage model.
164
v There is a limitation of a total of 16MB automatic storage for all the procedures
on the call stack.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v Avoid creating teraspace storage model and single-level storage model programs
with the same activation group attribute. For example, assume that TERAPGM is
a teraspace storage model program and SLSPGM is a single-level storage model
program, and both TERAPGM and SLSPGM are compiled to use
ACTGRP(MYACTGRP). If TERAPGM is called first, then activation group
MYACTGRP would be created as a teraspace storage model activation group
and any attempt to call SLSPGM would fail due to a storage model mismatch.
Similarly, if SLSPGM is called first, then activation group MYACTGRP would be
created as a single-level storage model activation group and any attempt to call
TERAPGM would fail due to a storage model mismatch.
Multithreading Considerations
#
#
#
#
#
165
Multithreading Considerations
#
#
#
#
errors that are made when coding multithreaded applications; see common
multithreaded programming errors at: http://www.ibm.com/systems/infocenter/. Pay
special attention to the problems you may encounter using database files, and
using commitment control in a multithreaded environment.
#
#
#
#
#
#
One important issue for thread safety is the handling of static storage. There are
two ways of ensuring thread-safe handling of static storage in your ILE RPG
modules. You can have separate static storage for each thread by specifying
THREAD(*CONCURRENT), or you can limit access to the module to only one
thread at a time by specifying THREAD(*SERIALIZE). See Multithreaded
Applications on page 21 for a comparison of the two modes of thread-safety.
The remainder of this discussion assumes that you are familiar with these
concepts.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
CAUTION:
RPG does not provide any protection against two threads trying to change an
all-thread static variable at the same time, or against one thread trying to change
the variable while another thread is checking its value. See All-Thread Static
Variables on page 169 for more information.
#
#
#
#
#
#
If you want to ensure that some code is only used by one thread at a time, you can
place the code in a serialized procedure (SERIALIZE keyword on the
Procedure-Begin specification). Note that each serialized procedure has its own
serialization mechanism; one thread can be running in one serialized procedure
while another thread is running in a different serialized procedure in the same
module.
#
#
Another way to ensure that the code is only used by one thread at a time is to put
the code in a procedure to a thread-serialized module.
166
Multithreading Considerations
#
#
#
#
#
#
#
#
#
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
#
#
#
#
Two or more threads can access the same storage if any of the following are true:
#
#
v Data is based on a pointer where the pointer is available to more than one
module
v Files are created or overridden with SHARE(*YES). In this case, it is the feedback
areas that represent the shared storage. RPG always refers to the feedback areas
during file operations, so you should synchronize access to the file itself.
#
#
#
167
Multithreading Considerations
It is up to the programmer to handle thread safety for storage that is shared across
modules. This is done by adding logic in the application to synchronize access to
the storage. To synchronize access to this shared storage, you can do one or both of
the following:
v Structure the application such that the shared resources are not accessed
simultaneously from multiple threads.
v If you are going to access resources simultaneously from separate threads,
synchronize access using facilities such as semaphores or mutexes. For more
information, see Using thread-related APIs on page 172.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
thread-1
thread-2
MOD1
#
#
#
#
#
MOD2
PROC1
PROC3
CALLP PROC4
CALLP PROC2
PROC2
PROC4
This example shows how deadlock can occur if you try to access more than one
procedure in the same thread-serialized module at the same time.
To avoid the problem in the above example and ensure thread safe applications,
you can control the synchronization of modules using the techniques described in
Using thread-related APIs on page 172. Any callers of PROC1 or PROC3 for each
thread should do the following:
1. Restrict access to the modules for all threads except the current thread, always
in the same order (MOD1 then MOD2)
#
#
#
#
#
#
#
#
#
168
Multithreading Considerations
more than one procedure in the same module at the same time, but since it is only
available to the current thread, it is thread safe.
This method should also be used to synchronize access to shared storage.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
When you define a variable with the STATIC(*ALLTHREAD) keyword, you are
responsible for ensuring that the variable is used in a thread-safe way. Depending
on the scope of the variable and usage of the variable, you may need to have
additional variables to help synchonize access to the variables:
v If the variable is local to a serialized procedure, then only one thread can access
the variable at one time due to the serialization, so you do not need to add any
extra synchronization for it.
v If the variable is global to the module, and you can guarantee that it is changed
in only one place in your code, and you can further guarantee that the code that
changes the variable will run before any other thread can use the variable, then
you do not need to add any synchronization for the variable.
v Otherwise, you must add an additional variable to be used with a
synchronization technique such as a mutex or a semaphore. See information
about Threads at: http://www.ibm.com/systems/infocenter/ and in Using
thread-related APIs on page 172.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
v Whenever you work with the variable, you must first gain access to it, by
locking the semaphore or mutex; when you are finished working with the
variable, you must unlock the semaphore or mutex.
v If the variable is exported from the module, you must ensure that all modules
that import the variable can also use the the synchronization variable. You can
do this by exporting the synchronization variable, or by adding exported lock
and unlock procedures in your exporting module that can be called by any
module that needs to use the variable.
169
Multithreading Considerations
#
#
#
#
#
#
#
#
#
#
#
#
In the following example, a global all-thread static variable is loaded from a file
once, and all other uses in the application only refer to the value of the variable.
Recall that it is necessary to control access to an all-thread static variable if it might
be changed by multiple threads at the same time, or if one thread might be
changing the value while another thread is using the value. However, in the
special case of a variable that is changed only once in "first-time-only setup" code,
a serialized procedure is sufficient to control the access by multiple threads. All
threads call the first-time-only setup procedure, and the procedure itself uses a
local all-thread static variable to keep track of whether the setup has already been
done. No manual synchronization is required to control the access to a local
all-thread-static variable in a serialized procedure, because the procedure is
serialized to allow only one thread to be running the procedure at one time
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
170
Multithreading Considerations
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
If you have a global all-thread static variable, it may seem like a good idea to
control access to it by having serialized "get" and "set" procedures for the variable.
Unfortunately, this does not give adequate protection, because the procedures are
serialized independently, each having its own separate control mechanism. If one
thread is running the "get" procedure, another could be running the "set"
procedure at the same time.
#
#
If you want to use "get" and "set" procedures, you will need to add code to both
procedures to manually synchronize access to the variable.
#
#
#
#
#
An alternative is to combine both "get" and "set" in one get-set procedure. It could
have a separate parameter to indicate the required function, or it could have an
optional parameter, which if passed, would provide the "set" function; the "get"
function would always be provided since the procedure would always return a
value.
#
#
#
#
#
#
#
#
#
#
#
#
#
However, even using a single "get-set" procedure may not provide adequate
thread-safety for the variable. If you want to modify a variable using its previous
value, such as adding one to the variable, you might think that getting the value of
the variable, and then setting it to a new value in the same statement would work.
However, another thread might call the procedure between your two calls to the
procedure. Your second "set" call to the procedure would incorrectly overwrite the
value that had been set by the other thread.
#
#
#
#
If you need to perform more than one access to a variable without another thread
being able to get or set the variable while you are performing the operation, you
must use some manual synchronization to control all access to the variable. All
users of that variable must use the same synchronization mechanism.
#
#
#
#
#
#
#
#
#
// If myFld has the value 2 before this statement is run, the first call
// would return 2. The second call would set the value to 3. If another
// thread had set the value to 15 in between the calls, the second call
// should logically set it to 16, not to 3.
getSetMyFld
// second call to getSetMyFld, to set the value
(getSetMyFld() + 1);
// first call to getSetMyFld, to get the value
171
Multithreading Considerations
#
#
#
You can call system APIs to start threads and wait for threads to complete, and to
synchronize access to shared resources.
#
#
#
#
#
The following example creates several threads, and uses two different
synchronization techniques to control access to some shared variables. To fully
understand the examples, you should refer to the Multithreaded Applications at:
http://www.ibm.com/systems/infocenter/. The examples are similar to the C
examples that show how to use semaphores and mutexes.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
The sample programs must be run in a multithread-capable job. You can use
SBMJOB to call the programs, specifying ALWMLTTHD(*YES) to allow multiple
threads in the job:
v SBMJOB CMD(CALL MYLIB/THREADMTX) ALWMLTTHD(*YES)
v SBMJOB CMD(CALL MYLIB/THREADSEM) ALWMLTTHD(*YES)
172
Multithreading Considerations
#
/UNDEFINE LOG_ALL_RESULTS
#
H THREAD(*CONCURRENT) MAIN(threadMtx)
#
H BNDDIR(QC2LE)
#
/IF DEFINED(*CRTBNDRPG)
#
H DFTACTGRP(*NO)
#
/ENDIF
#
H OPTION(*SRCSTMT : *NOUNREF)
#
#
/COPY QSYSINC/QRPGLESRC,PTHREAD
#
D NUMTHREADS
C
3
#
#
D threadMtx
PR
EXTPGM(THREADMTX)
#
#
D mtxThread
PR
*
EXTPROC(mtxThread)
#
D
parm
*
VALUE
#
#
D handleThreads
PR
EXTPROC(handleThreads)
#
#
D checkResults
PR
EXTPROC(checkResults)
#
D
string
1000A VARYING CONST
#
D
val
10I 0 VALUE
#
#
D threadMsg
PR
EXTPROC(threadMsg)
#
D
string
1000A VARYING CONST
#
#
D print
PR
EXTPROC(print)
#
D
msg
1000A VARYING CONST
#
#
D CEETREC
PR
#
D
cel_rc_mod
10I 0 OPTIONS(*OMIT)
#
D
user_rc
10I 0 OPTIONS(*OMIT)
#
#
D sleep
PR
EXTPROC(*CWIDEN:sleep)
#
D
secs
10I 0 VALUE
#
#
D fmtThreadId
PR
17A
VARYING
#
#
# Figure 76. RPG source file THREADMTX (Part 1 of 5)
#
#
173
Multithreading Considerations
*------------------------------------------------------* Thread-scoped static variables (the STATIC keyword
* is implied because the definition is global)
*------------------------------------------------------D psds
SDS
D pgmName
10A
OVERLAY(psds : 334)
*------------------------------------------------------* Job-scoped static variables
*------------------------------------------------------* Shared data that will be protected by the mutex
D sharedData
S
10I 0 INZ(0)
D
STATIC(*ALLTHREAD)
D sharedData2
S
10I 0 INZ(0)
D
STATIC(*ALLTHREAD)
* A mutex to control the shared data
D mutex
DS
LIKEDS(pthread_mutex_t)
D
STATIC(*ALLTHREAD)
// Program entry
P threadMtx
/free
print (Enter
handleThreads
print (Exit
/end-free
P threadMtx
procedure
B
P handleThreads
D handleThreads
B
PI
D thread
D
D rc
D i
/free
DS
+ pgmName);
();
+ pgmName);
E
S
S
LIKEDS(pthread_t)
DIM(NUMTHREADS)
10I 0 INZ(0)
10I 0 INZ(0)
174
Multithreading Considerations
print (Test using a mutex);
// Initialize the mutex
mutex = PTHREAD_MUTEX_INITIALIZER;
print (Hold Mutex to prevent access to shared data);
rc = pthread_mutex_lock (mutex);
checkResults(pthread_mutex_lock() : rc);
print (Create/start threads);
for i = 1 to NUMTHREADS;
rc = pthread_create(thread(i) : *OMIT
: %paddr(mtxThread) : *NULL);
checkResults (pthread_create() : rc);
endfor;
print (Wait a bit until we are "done" with the shared data);
sleep(3);
print (Unlock shared data);
rc = pthread_mutex_unlock (mutex);
checkResults(pthread_mutex_unlock() : rc);
print (Wait for the threads to complete,
+ and release their resources);
for i = 1 to NUMTHREADS;
rc = pthread_join (thread(i) : *OMIT);
checkResults(pthread_join( + %char(i) + ) : rc);
endfor;
print (Clean up the mutex);
rc = pthread_mutex_destroy (mutex);
print ("handleThreads" completed);
return;
/end-free
P handleThreads
P mtxThread
D mtxThread
D
parm
E
B
PI
*
*
VALUE
175
Multithreading Considerations
D rc
D
/free
10I 0
threadMsg (Entered);
rc = pthread_mutex_lock (mutex);
checkResults (pthread_mutex_lock() : rc);
//********** Critical Section Begin *******************
threadMsg (Start critical section, holding lock);
// Access to shared data goes here
sharedData += 1;
sharedData2 -= 1;
threadMsg (End critical section, release lock);
//********** Critical Section End
*******************
rc = pthread_mutex_unlock (mutex);
checkResults (pthread_mutex_unlock() : rc);
return *NULL;
/end-free
P mtxThread
E
P checkResults
B
EXPORT
D checkResults
PI
D
string
1000A
VARYING CONST
D
val
10I 0 VALUE
D msg
S
1000A
VARYING
/FREE
if val <> 0;
print (string + failed with + %char(val));
CEETREC (*OMIT : *OMIT);
else;
/if defined(LOG_ALL_RESULTS)
print (string + completed normally with + %char(val));
/endif
endif;
/END-FREE
P checkResults
E
Figure 76. RPG source file THREADMTX (Part 4 of 5)
176
Multithreading Considerations
P threadMsg
B
EXPORT
D threadMsg
PI
D
string
1000A VARYING CONST
/FREE
print (Thread( + fmtThreadId() + ) + string);
/END-FREE
P threadMsg
E
P
D
D
D
D
D
D
D
print
print
msg
printf
template
string
dummy
NEWLINE
/free
printf (%s
/end-free
P print
B
PI
PR
EXPORT
1000A
*
*
*
*
VARYING CONST
EXTPROC(printf)
VALUE OPTIONS(*STRING)
VALUE OPTIONS(*STRING)
VALUE OPTIONS(*NOPASS)
x15
+ NEWLINE : msg);
E
P
D
D
D
D
D
D
D
D
D
fmtThreadId
B
EXPORT
fmtThreadId
PI
17A VARYING
pthreadId
DS
LIKEDS(pthread_id_np_t)
buf
S
1000A
sprintf
PR
*
EXTPROC(sprintf)
buf
* VALUE
template
*
VALUE OPTIONS(*STRING)
num1
10U 0 VALUE
num2
10U 0 VALUE
dummy
* OPTIONS(*NOPASS)
/FREE
pthreadId = pthread_getthreadid_np();
// get the hex form of the 2 parts of the thread-id
// in "buf", null-terminated
sprintf (%addr(buf)
: %.8x %.8x
: pthreadId.intId.hi
: pthreadId.intId.lo);
return %str(%addr(buf));
/END-FREE
P fmtThreadId
E
177
Multithreading Considerations
#
/UNDEFINE LOG_ALL_RESULTS
#
H THREAD(*CONCURRENT) MAIN(threadSem)
#
H BNDDIR(QC2LE)
#
/IF DEFINED(*CRTBNDRPG)
#
H DFTACTGRP(*NO)
#
/ENDIF
#
H OPTION(*SRCSTMT : *NOUNREF)
#
#
/COPY QSYSINC/QRPGLESRC,PTHREAD
#
/COPY QSYSINC/QRPGLESRC,SYSSEM
#
/COPY QSYSINC/QRPGLESRC,SYSSTAT
#
D NUMTHREADS
C
3
#
#
D threadSem
PR
EXTPGM(THREADSEM)
#
#
D semThreadParm_t...
#
D
DS
QUALIFIED TEMPLATE
#
D val
10I 0
#
D result
10I 0
#
D semThread
PR
*
EXTPROC(semThread)
#
D
parm
LIKEDS(semThreadParm_t)
#
#
D handleThreads
PR
EXTPROC(handleThreads)
#
#
D checkResults
PR
EXTPROC(checkResults)
#
D
string
1000A
VARYING CONST
#
D
val
10I 0 VALUE
#
#
D checkResultsErrno...
#
D
PR
EXTPROC(checkResultsErrno)
#
D
string
1000A
VARYING CONST
#
D
cond
N
VALUE
#
#
D threadMsg
PR
EXTPROC(threadMsg)
#
D
string
1000A
VARYING CONST
#
#
D print
PR
EXTPROC(print)
#
D
msg
1000A
VARYING CONST
#
#
# Figure 77. RPG program THREADSEM showing the use of a semaphore (Part 1 of 7)
#
#
178
Multithreading Considerations
D CEETREC
D
cel_rc_mod
D
user_rc
PR
D sleep
D
secs
PR
EXTPROC(*CWIDEN:sleep)
10I 0 VALUE
D fmtThreadId
PR
17A
10I 0 OPTIONS(*OMIT)
10I 0 OPTIONS(*OMIT)
VARYING
179
Multithreading Considerations
* Simple unlock operation. 0=which-semaphore, 1=increment, 0=noflags
* Will be set to { 0, 1, 0} in main procedure before threads are created
D unlockOperation...
D
DS
LIKEDS(struct_sembuf)
D
DIM(1)
D
STATIC(*ALLTHREAD)
// Program entry
P threadSem
/free
print (Enter
handleThreads
print (Exit
/end-free
P threadSem
procedure
B
P handleThreads
D handleThreads
B
PI
D
D
D
D
D
D
thread
DS
rc
i
parms
S
S
DS
+ pgmName);
();
+ pgmName);
E
LIKEDS(pthread_t)
DIM(NUMTHREADS)
10I 0 INZ(0)
10I 0 INZ(0)
LIKEDS(semThreadParm_t)
DIM(NUMTHREADS)
/free
print ("handleThreads" starting);
print (Test using a semaphore);
lockOperation(1).sem_num = 0;
lockOperation(1).sem_op = -1;
lockOperation(1).sem_flg = 0;
unlockOperation(1).sem_num = 0;
unlockOperation(1).sem_op = 1;
unlockOperation(1).sem_flg = 0;
Figure 77. RPG program THREADSEM showing the use of a semaphore (Part 3 of 7)
180
Multithreading Considerations
// Create a private semaphore set with 1
// semaphore that only I can use
semaphoreId = semget(IPC_PRIVATE : 1 : 0 + S_IRUSR + S_IWUSR);
checkResultsErrno (semget : semaphoreId >= 0);
// Set the semaphore count to 1.
// Simulate a mutex
rc = semctl(semaphoreId : 0 : CMD_SETVAL : 1);
checkResults(semctl(SETVAL) : rc);
print (Wait on semaphore to prevent access to shared data);
rc = semop(semaphoreId : lockOperation(1) : 1);
checkResultsErrno(main semop(lock): rc = 0);
parms(1).val = 5;
parms(2).val = -10;
parms(3).val = 421;
print (Create/start threads);
for i = 1 to NUMTHREADS;
rc = pthread_create(thread(i) : *OMIT
: %paddr(semThread) : %addr(parms(i)));
checkResults (pthread_create() : rc);
endfor;
print (Wait a bit until we are "done" with the shared data);
sleep (3);
print (Unlock shared data);
rc = semop (semaphoreId : unlockOperation(1) : 1);
checkResultsErrno (main semop(unlock) : rc = 0);
print (Wait for the threads to complete,
+ and release their resources);
for i = 1 to NUMTHREADS;
rc = pthread_join (thread(i) : *OMIT);
checkResults(pthread_join( + %char(i) + ) : rc);
endfor;
print (Clean up the semaphore);
rc = semctl(semaphoreId : 0 : IPC_RMID);
checkResults (semctl(removeID) : rc);
Figure 77. RPG program THREADSEM showing the use of a semaphore (Part 4 of 7)
181
Multithreading Considerations
print (Result(1) = + %char(parms(1).result));
print (Result(2) = + %char(parms(2).result));
print (Result(3) = + %char(parms(3).result));
print ("handleThreads" completed);
return;
/end-free
P handleThreads
P semThread
D semThread
D
parm
B
PI
D rc
D
/free
*
LIKEDS(semThreadParm_t)
10I 0
182
Multithreading Considerations
P semThread
P checkResults
B
EXPORT
D checkResults
PI
D
string
1000A VARYING CONST
D
val
10I 0 VALUE
D msg
S
1000A
VARYING
/FREE
if val <> 0;
print (string + failed with + %char(val));
CEETREC (*OMIT : *OMIT);
else;
/if defined(LOG_ALL_RESULTS)
print (string + completed normally with + %char(val));
/endif
endif;
/END-FREE
P checkResults
E
P
P
D
D
D
D
D
D
checkResultsErrno...
B
checkResultsErrno...
PI
string
1000A VARYING CONST
cond
N
VALUE
getErrnoPtr
PR
* EXTPROC(__errno)
errnoVal
S
10I 0 based(threadErrnoPtr)
/FREE
if not cond;
threadErrnoPtr = getErrnoPtr();
print (string + Errno( + %char(errnoVal) + ));
CEETREC (*OMIT : *OMIT);
else;
/if defined(LOG_ALL_RESULTS)
print (string + completed normally);
/endif
endif;
/END-FREE
P checkResultsErrno...
P
E
Figure 77. RPG program THREADSEM showing the use of a semaphore (Part 6 of 7)
183
Multithreading Considerations
P threadMsg
B
D threadMsg
PI
D
string
1000A
/FREE
print (Thread( + fmtThreadId()
/END-FREE
P threadMsg
E
P print
B
D print
PI
D
msg
1000A
D printf
PR
*
D
template
*
D
string
*
D
dummy
*
D NEWLINE
C
/free
printf (%s + NEWLINE : msg);
/end-free
P print
E
EXPORT
VARYING CONST
+ ) + string);
EXPORT
VARYING CONST
EXTPROC(printf)
VALUE OPTIONS(*STRING)
VALUE OPTIONS(*STRING)
VALUE OPTIONS(*NOPASS)
x15
P
D
D
D
D
D
D
D
D
D
fmtThreadId
B
EXPORT
fmtThreadId
PI
17A
VARYING
pthreadId
DS
LIKEDS(pthread_id_np_t)
buf
S
1000A
sprintf
PR
*
EXTPROC(sprintf)
buf
*
VALUE
template
*
VALUE OPTIONS(*STRING)
num1
10U 0 VALUE
num2
10U 0 VALUE
dummy
*
OPTIONS(*NOPASS)
/FREE
pthreadId = pthread_getthreadid_np();
// get the hex form of the 2 parts of the thread-id
// in "buf", null-terminated
sprintf (%addr(buf)
: %.8x %.8x
: pthreadId.intId.hi
: pthreadId.intId.lo);
return %str(%addr(buf));
/END-FREE
P fmtThreadId
E
# Figure 77. RPG program THREADSEM showing the use of a semaphore (Part 7 of 7)
#
184
#
#
#
#
#
#
#
#
#
#
#
#
#
#
You can use the XML-INTO and XML-SAX operation codes to process your XML
documents. For more information, see Processing XML Documents.
#
#
#
XML Toolkit for iSeries (5733XT1) allows your ILE RPG programs to create new
XML documents and parse existing ones. You can use XML as both a datastore and
I/O mechanism.
#
#
#
#
#
#
#
You can process XML documents from your RPG program by using the
XML-INTO or XML-SAX statements. These statements are the RPG language
interface to the high-speed XML parser. The parser currently being used by RPG is
a non-validating parser, although it checks XML documents for many
well-formedness errors. See the "XML Conformance" section in the "XML Reference
Material" appendix of the ILE COBOL Programmer's Guide for more information on
the XML parser.
#
#
The XML documents can be in a character or UCS-2 RPG variable, or they can be
in an Integrated File System file.
#
#
#
#
#
#
#
The parser is a SAX parser. A SAX parser operates by reading the XML document
character by character. Whenever it has located a fragment of the XML document,
such as an element name, or an attribute value, it calls back to a handling
procedure provided by the caller of the parser, passing it information about the
fragment of XML that it has found. For example, when the parser has found an
XML element name, it calls the handling procedure indicating that the "event" is a
"start element" event and passing it the name of the element.
#
#
#
#
#
The handling procedure processes the information and returns to the parser which
continues to read the XML document until it has enough information to call the
handling procedure with another event. This process repeats until the entire XML
document has been parsed, or until the handling procedure indicates that parsing
should end.
185
#
#
#
<email type="text">
<sendto>JohnDoe@there</sendto>
</email>
#
#
#
The following are the fragments of text that the parser would read, the events that
it would generate, and the data associated with each event. Note: The term
"whitespace" refers to end-of-line characters, tab characters and blanks.
##
Parsed text
Event
Event data
start document
start element
"email"
type=
attribute name
"type"
"text"
attribute value
"text"
>whitespace
element content
the whitespace
<sendto>
start element
"sendto"
JohnDoe@there
element content
"JohnDoe@there"
</sendto>
end element
"sendto"
whitespace
element content
the whitespace
</email>
end element
"email"
#
#
end document
The XML-SAX and XML-INTO operation codes allow you to use the XML parser.
1. The XML-SAX operation allows you to specify an event handling procedure to
handle every event that the parser generates. This is useful if you do not know
in advance what an XML document may contain.
For example, if you know that an XML document will contain an XML attribute
with the name type, and you want to know the value of this attribute, your
handling procedure can wait for the "attribute name" event to have a value of
"type". Then the next time the handler is called, it should be an "attribute
value" event, with the required data ("text" in the example above).
#
#
#
#
#
#
#
#
#
#
#
#
#
2. The XML-INTO operation allows you to read the contents of an XML document
directly into an RPG variable. This is useful if you know the format of the XML
document and you know that the names of the XML elements in the document
will be the same as the names you have given to your RPG variables.
#
#
#
#
#
#
#
#
#
#
#
#
For example, if you know that the XML document will always have the form of
the document above, you can define an RPG data structure with the name
"email", and with subfields "type" and "sendto". Then you can use the
XML-INTO operation to read the XML document directly into the data
structure. When the operation is complete, the "type" subfield would have the
value "text" and the "sendto" subfield would have the value "JohnDoe@there".
3. The XML-INTO operation also allows you to obtain the values of an unknown
number of repeated XML elements. You provide a handling procedure that
receives the values of a fixed number of elements each time the handling
procedure is called. This is useful if you know that the XML document will
contain a series of identical XML elements, but you don't know in advance how
many there will be.
#
#
#
#
The XML data is always returned by the parser in text form. If the data is known
to represent other data types such as numeric data, or date data, the XML-SAX
handling procedure must use conversion functions such as %INT or %DATE to
convert the data.
186
#
#
The XML-INTO operation will automatically convert the character data to the type
of the field or subfield specified as the receiver.
#
#
#
#
Both the XML-SAX and XML-INTO operations allow you to specify a series of
options that control the operation. The options are specified in a single character
expression in the form
#
#
Each operation has its own set of valid options. The options that are common to
both operation codes are
#
#
#
#
#
#
#
doc
#
#
#
#
#
#
#
ccsid
The "ccsid" option specifies the CCSID in which the XML parser will return
data. For the XML-SAX operation, you can specify any CCSID that the parser
supports. For the XML-INTO operation, you can only control whether the
parsing will be done in single-byte character or UCS-2. See the information in
the ILE RPG Reference for more information on the "ccsid" option for each of
these operation.
#
#
#
#
#
The following table shows the meaning of each parser error code:
#
#
#
#
XML
Parser
Error Code Description
#
#
The parser found an invalid character while scanning white space outside
element content.
#
#
The start and end tag names of an element did not match.
#
#
#
#
The parser found in element content the CDATA closing character sequence
']]>' without the matching opening character sequence '<![CDATA['.
#
#
10
The parser found in a comment the character sequence '--' (two hyphens) not
followed by '>'.
opt1=val1 opt2=val2
The "doc" option specifies whether the XML document that you provide to the
operation is the name of an Integrated File System file containing the
document, or the document itself. The default is "doc=string" indicating that
you have provided an actual XML document. You use the option "doc=file" to
indicate that you have provided the name of a file containing the actual XML
document.
If the XML parser detects an error in the XML document during parsing, message
RNX0351 will be issued. From the message, you can get the specific error code
associated with the error, as well as the offset in the document where the error was
discovered.
187
#
#
#
XML
Parser
Error Code Description
#
#
11
#
#
12
#
#
13
The parser found an invalid digit in a hexadecimal character reference (of the
form �, for example ັ).
#
#
14
The parser found an invalid digit in a decimal character reference (of the form
&#dddd;).
15
16
17
18
19
#
#
#
20
An element name was not specified correctly. The first character was not a
letter, '_', or ':', or the parser found an invalid character either in or following
the element name.
#
#
#
#
21
An attribute was not specified correctly. The first character of the attribute
name was not a letter, '_', or ':', or a character other than '=' was found
following the attribute name, or one of the delimiters of the value was not
correct, or an invalid character was found in or following the name.
22
An empty element tag was not terminated by a '>' following the '/'.
#
#
23
The element end tag was not specified correctly. The first character was not a
letter, '_', or ':', or the tag was not terminated by '>'.
#
#
24
#
#
#
#
25
A processing instruction target name was not specified correctly. The first
character of the processing instruction target name was not a letter, '_', or ':', or
the parser found an invalid character in or following the processing
instruction target name.
#
#
26
#
#
27
28
#
#
#
#
#
29
The 'version' in the XML declaration was not specified correctly. 'version' was
not followed by '=', or the value was missing or improperly delimited, or the
value specified a bad character, or the start and end delimiters did not match,
or the parser found an invalid character following the version information
value closing delimiter in the XML declaration.
#
#
30
#
#
#
#
#
#
31
188
#
#
#
XML
Parser
Error Code Description
#
#
32
#
#
#
#
#
33
The 'standalone' attribute in the XML declaration was not specified correctly.
'standalone' was not followed by a '=', or the value was either missing or
improperly delimited, or the value was neither 'yes' nor 'no', or the value
specified a bad character, or the start and end delimiters did not match, or the
parser found an invalid character following the closing delimiter.
#
#
34
The XML declaration was not terminated by the proper character sequence
'?>', or contained an invalid attribute.
#
#
35
The parser found the start of a document type declaration after the end of the
root element.
36
The parser found the start of an element after the end of the root element.
#
#
300
The parser reached the end of the document before the document was
complete.
#
#
301
#
#
302
The parser does not support the requested CCSID value or the first character
of the XML document was not '<'.
#
#
#
303
The document was too large for the parser to handle. The parser attempted to
parse the incomplete document, but the data at the end of the document was
necessary for the parsing to complete.
#
#
500-999
Internal error in the external parser. Please report the error to your service
representative.
#
#
#
1000119999
Internal error in the parser. Please report the error to your service
representative.
#
#
#
#
#
#
189
v The parser does not parse the DOCTYPE declaration. The text of the DOCTYPE
declaration is passed as the data value for the "DOCTYPE declaration" event.
v The parser does not support name spaces. It ignores the colons in XML element
and attribute names.
v The parser does not generate "start prefix mapping" and "end prefix mapping"
events. It ignores the colons in XML element and attribute names.
*
*
*
*
*
*
*
*
*
*
*
*
*
P
D
D
D
D
D
D
Parameters:
1. path
: a pointer to a null-terminated string containing
the path to the file to be written
2. dataPtr
: a pointer to the data to be written
3. dataLen
: the length of the data in bytes
4. dataCcsid : the CCSID of the data
5. fileCcsid : the desired CCSID of the file
Sample RPG coding:
ifsWrite (/home/mydir/temp.xml : xmlPtr : xmlLen : 37 : 37);
xml-into ds %xml(/home/mydir/temp.xml : doc=file);
To delete the file, use the system command
rmvlnk /home/mydir/temp.xml
Note: This module requires BNDDIR(QC2LE)
ifsWrite
B
EXPORT
ifsWrite
PI
path
*
VALUE OPTIONS(*STRING)
dataPtr
*
VALUE
dataLen
10I 0 VALUE
dataCcsid
10I 0 VALUE
fileCcsid
10I 0 VALUE
D
D
D
D
D
D
D
D
O_CREAT
O_TRUNC
O_WRONLY
O_RDWR
O_CCSID
O_TEXT_CREAT
O_TEXTDATA
O_SHARE_NONE
C
C
C
C
C
C
C
C
x00000008
x00000040
x00000002
x00000004
x00000020
x02000000
x01000000
x00080000
D
D
D
D
D
S_IRUSR
S_IROTH
S_IRGRP
S_IWUSR
S_IWOTH
C
C
C
C
C
x0100
x0004
x0020
x0080
x0002
190
D ssize_t
D size_t
S
S
10I 0
10U 0
D open
D
path
D
flag
D
mode
D
fileCcsid
D
dataCcsid
D writeFile
D
D
handle
D
data
D
len
D closeFile
D
handle
PR
10I
*
10I
10I
10I
10I
PR
10I
10I
0 EXTPROC(open)
VALUE OPTIONS(*STRING)
0 VALUE
0 VALUE
0 VALUE options(*nopass)
0 VALUE options(*nopass)
LIKE(ssize_t)
EXTPROC(write)
0 VALUE
VALUE
VALUE LIKE(size_t)
0 EXTPROC(close)
0 VALUE
D
D
D
D
S
S
S
S
10I
10I
10I
10I
0
0
0
0
oflag
omode
handle
rc
PR
10I
*
D sysErrno
PR
*
EXTPROC(__errno)
D errno
S
10I 0 BASED(pErrno)
/FREE
pErrno = sysErrno();
oflag = 0 + O_WRONLY + O_CREAT + O_TEXT_CREAT + O_TRUNC
+ O_CCSID + O_TEXTDATA + O_SHARE_NONE;
omode = 0 + S_IRUSR + S_IWUSR + S_IRGRP + S_IROTH;
handle = open(path : oflag : omode : fileCcsid : dataCcsid);
// insert error handling if handle is less than zero
rc = writeFile (handle : dataPtr : dataLen);
// insert error handling if rc is not zero
rc = closeFile (handle);
// insert error handling if rc is not zero
/END-FREE
P ifswrite
191
*JAVA identifies the object as a Java object. Class_name specifies the class of the
object. It must be a character literal or named constant, and the class name must be
fully qualified. The class name is case sensitive.
For example, to declare a field that will hold an object of type BigDecimal:
D bdnum
CLASS(*JAVA:java.math.BigDecimal)
CLASS(*JAVA:java.lang.String)
Note that both class names are fully qualified and that their case exactly matches
that of the Java class.
Fields of type O cannot be defined as subfields of data structures. It is possible to
have arrays of type O fields, but pre-runtime and compile-time tables and arrays
of type O are not allowed.
Both the class name and the method name must be character constants. The class
name must be a fully qualified Java class name and is case sensitive. The method
name must be the name of the method to be called, and is case sensitive.
Use *JAVA when creating a prototype for either a method written in Java or a
native method written in RPG. Use the STATIC keyword to indicate that a method
is static.
Java and RPG Definitions and Data Types: The data types of the parameters and
the returned value of the method are specified in the same way as they are when
prototyping a subprocedure, but the data types actually map to Java data types.
The following table shows the mappings of ILE RPG data types to and from Java
data types.
192
#
#
#
#
#
#
#
If you copy the JNI member in QSYSINC/QRPGLESRC, you can use LIKE to
define your RPG variables and parameters like definitions in that file. For example,
to define a variable like the Java "int" type, define it LIKE(jint). In the remainder of
the discussion about RPG and Java, any definitions defined with LIKE(jxxxx) are
assumed to have a /COPY for QSYSINC/QRPGLESRC,JNI in the module. See the
section Additional RPG Coding for Using Java on page 207 for more information
about using this /COPY file.
Table 39.
Java Data Type
RPG Definitions
boolean
indicator
integer
3I 0
character
1A
nA
1A DIM(x)
date
time
timestamp
short
2byte integer
5I 0
char
UCS-2 length=1
1C
char[]
nC
1C DIM(x)
int
4byte integer
10I 0
long
8byte integer
20I 0
float
4byte float
4F
double
8byte float
8F
any object
object
O CLASS(x)
any array
DIM(x)
byte
byte[]
Notes:
1. When a Java byte type is converted to or from a character (1A) data type,
ASCII conversion occurs. When a Java byte type is converted to or from an
integer (3I) data type, ASCII conversion does not occur.
2. For arrays of any type in Java, you can declare an array of the equivalent type
in RPG. However, note that you cannot use an array of character length greater
than 1 or UCS-2 length greater than 1 data types.
3. For UCS-2 length greater than 1 and character length greater than 1 data types,
the VARYING keyword is allowed. In general, it's recommended to use the
VARYING keyword, since Java byte[] and char[] cannot be declared with a
fixed length.
4. For RPG array data types, OPTIONS(*VARSIZE) should normally be coded for
array parameters, since Java arrays cannot be declared with a fixed length.
Zoned, Packed, Binary, and Unsigned data types are not available in Java. If you
pass a Zoned, Packed, Binary, or Unsigned field as a parameter, the compiler will
do the appropriate conversion, but this may result in truncation and/or loss of
precision.
193
When calling a method, the compiler will accept arrays as parameters only if the
parameter is prototyped using the DIM keyword.
If the return value or a parameter of a method is an object, you must provide the
class of the object by coding the CLASS keyword on the prototype. The class name
specified will be that of the object being returned or the parameter being passed.
(Use the EXTPROC keyword to specify the class of the method being called.)
If the method being called is a static method, then you must specify the STATIC
keyword on the prototype. If the method is a constructor, you must specify
*CONSTRUCTOR as the name of the method.
In Java, the following data types can only be passed by value:
boolean
byte
int
short
long
float
double
Parameters of these types must have the VALUE keyword specified for them on
the prototype.
Note that objects can only be passed by reference. The VALUE keyword cannot be
specified with type O. Since arrays are seen by Java as objects, parameters
mapping to arrays must also be passed by reference. This includes character and
byte arrays. The CONST keyword can be used.
Examples of Prototyping Java Methods: This section presents some examples of
prototyping Java methods.
Example 1: The Java Integer class contains a static method called toString, which
accepts an int parameter, and returns a String object. It is declared in Java as
follows:
static String
Integer.toString(int)
PR
EXTPROC(*JAVA:
java.lang.Integer:
toString)
CLASS(*JAVA:java.lang.String)
STATIC
10I 0 VALUE
The EXTPROC keyword identifies the method as a Java method. It also indicates
that the method name is 'toString', and that it is found in class 'java.lang.Integer'.
The O in column 40 and the CLASS keyword tell the compiler that the method
returns an object, and the class of that object is 'java.lang.String'.
The STATIC keyword indicates that the method is a static method, meaning that an
Integer object is not required to call the method.
The data type of the parameter is specified as 10I, which maps to the Java int data
type. Because the parameter is an int, it must be passed by value, and the VALUE
keyword is required.
194
Example 2: The Java Integer class contains a static method called getInteger, which
accepts String and Integer objects as parameters, and returns an Integer object. It is
declared in Java as follows:
static Integer Integer.getInteger(String, Integer)
PR
O
O
EXTPROC(*JAVA:
java.lang.Integer:
getInteger)
CLASS(*JAVA:java.lang.Integer)
STATIC
CLASS(*JAVA:java.lang.String) CONST
CLASS(*JAVA:java.lang.Integer) CONST
PR
5I 0 EXTPROC(*JAVA:
java.lang.Integer:
shortValue
The STATIC keyword is not specified because the method is not a static method.
The method takes no parameters, so none are coded. When you call this method,
you will specify the Integer instance as the first parameter. The returned value is
specified as 5I, which maps to the Java short data type.
Example 4: The Java Integer class contains a method called equals, which accepts
an Object as parameter and returns a boolean. It is declared in Java as follows:
boolean equals(Object)
PR
N
O
EXTPROC(*JAVA:
java.lang.Integer:
equals)
CLASS(*JAVA:java.lang.Object)
The returned value is specified as N, which maps to the Java boolean data type.
Because this is not a static method, a call to this method will have two parameters
with the instance parameter coded first.
195
1. Java methods can be called using existing operation codes CALLP (when no
return value is expected) and EVAL (when a return value is expected). When
your RPG procedure attempts to make call to a Java method, RPG will check to
see if the Java Virtual Machine (JVM) has been started. If not, RPG will start
the JVM for you. It is also possible to start JVM yourself using the JNI function
described in Creating the Java Virtual Machine (JVM) on page 211
2. If you are using your own classes (or any classes outside the normal java.xxx
classes), be sure to have your CLASSPATH environment variable setup before
you call any Java methods. When RPG starts up the JVM for you, it will add
the classes in your CLASSPATH environment variable to the standard
classpath, so when you use your own classes, Java will be able to find them.
Set the CLASSPATH environment variable interactively like this:
===>ADDENVVAR ENVVAR(CLASSPATH)
VALUE(/myclasses/:/xyzJava/classes/)
#
#
#
#
#
#
#
See Additional RPG Coding for Using Java on page 207 for more information
about the various JNI functions.
Example 1
In this example, the goal is to add two BigDecimal values together. In order to do
this, two BigDecimal objects must be instantiated by calling the constructor for the
BigDecimal class, fields must be declared to store the BigDecimal objects, and the
add() method in the BigDecimal class must be called.
196
Figure 79. RPG Code Example Calling BigDecimal Java Class (Part 1 of 2)
197
*
*
D bdnum1
S
O
CLASS(*JAVA:java.math.BigDecimal)
D bdnum2
S
O
CLASS(*JAVA:java.math.BigDecimal)
*
*
Since one of the constructors we are using requires a String object,
*
we will also need to construct one of those. Prototype the String
*
constructor that accepts a byte array as a parameter. It returns
*
a String object.
*
D makestring
PR
O
EXTPROC(*JAVA:
D
java.lang.String:
D
*CONSTRUCTOR)
D
bytes
30A
CONST VARYING
*
* Define a field to store the String object.
*
D string
S
O
CLASS(*JAVA:java.lang.String)
*
* Prototype the BigDecimal add method. It accepts a BigDecimal object
* as a parameter, and returns a BigDecimal object (the sum of the parameter
* and of the BigDecimal object used to make the call).
*
D add
PR
O
EXTPROC(*JAVA:
D
java.math.BigDecimal:
D
add)
D
CLASS(*JAVA:java.math.BigDecimal)
D
bd1
O
CLASS(*JAVA:java.math.BigDecimal)
D
CONST
*
* Define a field to store the sum. *
D sum
S
O
CLASS(*JAVA:java.math.BigDecimal)
D
D double
S
8F
INZ(1.1)
D fld1
S
10A
* Define a prototype to retrieve the String version of the BigDecimal
D getBdString
PR
O
CLASS(*JAVA:java.lang.String)
D
EXTPROC(*JAVA:
D
java.lang.BigDecimal:
D
toString)
* Define a prototype to retrieve the value of a String
D getBytes
PR
65535A
VARYING
D
EXTPROC(*JAVA:
D
java.lang.String:
D
getBytes)
* Define a variable to hold the value of a BigDecimal object
D bdVal
S
63P 5
Figure 79. RPG Code Example Calling BigDecimal Java Class (Part 2 of 2)
198
*
*
*
*
C
*
*
*
*
C
*
*
*
*
C
*
*
*
*
*
*
*
*
*
C
*
*
C
*
*
*
string = makestring(123456789012345678901234567890)
bdnum1 = bdcreate1(string)
bdnum2 = bdcreate2(double)
Figure 80.
Example 2
This example shows how to perform a TRIM in Java by using the trim() method as
an alternative to the ILE RPG %TRIM built-in function. The trim() method in the
String class is not a static method, so a String object is needed in order to call it.
#
#
#
#
#
#
#
#
#
#
199
str = makestring(fld)
str = trimstring(str)
fld = getBytes(str)
Static methods are called in the same way, except that an object is not required to
make a call. If the getBytes() method above was static, the call would look like the
example below.
C
EVAL
fld = getBytes()
If the method does not return a value, use the CALLP operation code.
Creating Objects
In order to call a non-static method, an object is required. The class of the object
must be the same as the class containing the method. You may already have an
object available, but you may sometimes need to instantiate a new object. You do
this by calling a class constructor. A class constructor is neither a static method nor
an instance method, and therefore it does not need an instance parameter. The
special method name *CONSTRUCTOR is used when prototyping a constructor.
For example, class BigDecimal has a constructor that accepts a float parameter.
This constructor would be prototyped as follows:
D bdcreate
D
D
D
dnum
PR
O
4F
EXTPROC(*JAVA:
java.math.BigDecimal:
*CONSTRUCTOR)
VALUE
Note that the parameter must be passed by value because it maps to the Java float
data type.
You would call this constructor like this:
D bd
S
D
/free
bd = bdcreate(5.2E9);
/end-free
CLASS(*JAVA:
java.math.BigDecimal)
The class of the returned object is the same as the class of the constructor itself, so
the CLASS keyword is redundant for a constructor, but it may be coded.
200
class Simple
{
static void method (void)
{
System.out.println ("Simple method");
}
}
package MyPkg;
class PkgClass
{
static void method (void)
{
System.out.println ("PkgClass method");
}
}
Figure 83.
D simpleMethod
D
D
D
D pkgMethod
D
D
D
PR
PR
EXTPROC(*JAVA
: Simple
: method)
STATIC
EXTPROC(*JAVA
: Pkg.PkgClass
: method)
STATIC
201
then you would add the environment variable using the following command:
ADDENVVAR ENVVAR(QIBM_RPG_JAVA_PROPERTIES)
VALUE(-Djava.version=1.4;-Dos400.stderr=file:stderr.txt;)
If the options string is not valid, Java may reject one of the options. Message
JVAB55A will appear in the joblog indicating which option was not valid. If this
happens, RPG will try to start the JVM again without any of the options, but still
including the java.class.path option if it came from the CLASSPATH environment
variable.
Some parameters and return values require conversion between the job CCSID and
the CCSID that Java uses for byte arrays. The file.encoding Java property is used
by RPG to obtain the CCSID that Java uses. Ensure that the file.encoding property
is set correctly for your job CCSID. You can allow Java to set the property
implicitly using attributes of your job, or you can set the property explicitly using
one of the mechanisms above. For example, you could add
'-Dfile.encoding=ISO8859_1' or '-Dfile.encoding=Cp948' to your
QIBM_RPG_JAVA_PROPERTIES environment variable. For more information about
the file.encoding property, see the IBM Developer Kit for Java topic in the
Information Center.
|
|
|
|
|
|
|
|
|
|
202
This will enable Java to find your native methods. Aside from adding *JAVA and
the class to the EXTPROC keyword for the prototype of a native method, you
write your native method like any subprocedure. Figure 85 is an example of a Java
class that calls a native method.
CAUTION:
If you are using environment variables to control how the JVM is started, you
must be sure that the environment variables exist in the job before any RPG
programs call Java methods. If you use ADDENVVAR LEVEL(*SYS), the
environment variable will be added at the system level, and by default, every
job will start with that environment variable set. If you do this, be sure that the
classpath includes all the directories containing the Java classes that may be
needed by any application on the system.
class MyClass
{
static
{
System.loadLibrary ("MYSRVPGM");
}
native boolean checkCust (byte custName[]);
void anotherMethod ()
{
boolean found;
// call the native method
found = checkCust (str.getBytes());
}
}
Figure 85. Java Class Calling a Native Method
D checkCust
D
D
D
custName
PR
N
100A
EXTPROC(*JAVA
: MyClass
: checkCust)
VARYING CONST
The native method itself is coded just like any subprocedure. Figure 87 is an
example of a native method coded in RPG.
P checkCust
B
D checkCust
PI
D
custName
/free
chain custName
return %found;
/end-free
P checkCust
E
EXPORT
N
100A
VARYING CONST
rec;
203
Java calls your service program from the default activation group. If your service
program is created with activation group *CALLER, it will run in the default
activation group. This can sometimes cause problems:
v If you are debugging your native methods, and you want to make a change to
the code, you will have to sign off and sign back on again before Java will see
the new version.
v If you are calling other procedures in the service program from other RPG code
that is not running in the default activation group, then you will not be able to
share any global variables between the "ordinary procedures" and the native
methods. This scenario can arise if a procedure in your RPG service program
sets up some global variables, and then calls a Java class which then calls a
native method in that service program. Those native methods will not see the
same data that the first procedure set up.
If you create any Java objects in your native methods, by default they will be
destroyed by Java when the native method returns. If you want the object to be
available after the native method returns (for example, if you want to use it from
another native method later), then you must tell Java that you want to make a
global reference, by calling the JNI wrapper procedure getNewGlobalRef . When
you are finished with the global reference, you will call JNI wrapper procedure
freeGlobalRef, so Java can reclaim the object. See Telling Java you want an object
to be permanent on page 209 and Telling Java you are finished with a permanent
object on page 210 for more information about these wrapper procedures.
If your RPG native method ends abnormally with an unhandled exception, the
RPG compiler will throw an exception to Java. The exception is of class
java.lang.Exception, and has the form RPG nnnnn, where nnnnn is the RPG status
code.
try
{
nativeMethod ();
}
catch (Exception exc)
{
...
}
204
Using String Objects in RPG: If you have a String object in your RPG code, you
can retrieve its length and contents using the code in Figure 88.
D
D
D
D
D
D
D
D
D
D
D
stringBytes
PR
100A
VARYING
EXTPROC(*JAVA
: java.lang.String
: getBytes)
stringLength
PR
like(jint)
EXTPROC(*JAVA
: java.lang.String
: length)
string
S
like(jstring)
len
S
like(jint)
data
S
100A
VARYING
/free
len = stringLength (string);
data = stringBytes (string);
if (len > %len(data));
error (Actual string was too long);
endif;
/end-free
Figure 88. Retrieving String object length and contents from Java
You can define the returned value from the getBytes method as character data of
any length, either varying or non-varying, choosing the length based on your own
knowledge of the length of data in the Java String. You can also define the return
value as a Date, Time or Timestamp, if you are sure that the String object will have
the correct format.
Alternately, you can retrieve the string value as a UCS-2 value, by calling the
getChars method instead of getBytes.
Signature
boolean
byte
char
short
int
long
float
205
Java type
Signature
double
any object
Lclass;
any array
[type
To see the list of valid signatures for the methods in the Java class, use the QSH
command
javap -s classname
where classname is specified with the package, for example java.lang.String. If the
class is not in the standard classpath, you can specify a classpath option for javap:
javap -s classname -classpath classlocation
By comparing the valid signatures for the method with the signature being used
by RPG for your method call, and working from the mapping tables, you should
be able to determine the error in your prototype.
It appears that this code is taking care to free the object, but in fact this code
creates two objects. The first object is created by the called to newString(), and the
second is created by the call to trim(). Here are two ways to correct this code
fragment:
1. By freeing several objects at once:
beginObjGroup();
strObject = newString (abcde);
strObject = trim (strObject);
data = getBytes (strObject);
endObjGroup();
206
The problem with this code is that a String object has been created for the
parameter, but it can never be freed by the RPG procedure. This problem can be
corrected by calling beginObjGroup() before the RPG code that calls Java and
calling endObjGroup() after, or by coding as follows:
tempObj = newString (12.2345);
bigDec = newBigDecimal (tempObj);
freeLocalRef (tempObj);
...
freeLocalRef (bigDec);
207
#
#
#
#
#
#
H thread(*serialize)
H nomain
H bnddir(QC2LE)
/define OS400_JVM_12
/copy qsysinc/qrpglesrc,jni
/copy JAVAUTIL
The following RPG wrappers for JNI functions are described. See Figure 94 on
page 214 below for a complete working example. See Figure 93 on page 213. for
the copy file containing the prototypes and constants for the wrapper functions.
v Telling Java to free several objects at once
v Telling Java you are finished with a temporary object on page 209
v Telling Java you want an object to be permanent on page 209
v Telling Java you are finished with a permanent object on page 210
v Creating the Java Virtual Machine (JVM) on page 211
v Obtaining the JNI environment pointer on page 211
208
#
#
#
#
#
#
#
#
#
#
if %parms() >= 2;
refObject = refObjectP;
endif;
newObject = PopLocalFrame (JNIENV_p : refObject);
if %parms() >= 3;
newObjectP = newObject;
endif;
return JNI_GROUP_ENDED;
/end-free
P endObjGroup
e
Note: You need the JNI environment pointer (described in Obtaining the JNI
environment pointer on page 211 below) to call this wrapper.
/*------------------------------------------------------*/
/* freeLocalRef
*/
/*------------------------------------------------------*/
P freeLocalRef...
P
B
EXPORT
D freeLocalRef...
D
PI
D
env
*
VALUE
D
localRef
O
CLASS(*JAVA
D
: java.lang.Object)
D
VALUE
/free
jniEnv_P = env;
DeleteLocalRef (env : localRef);
/end-free
P freeLocalRef...
P
E
Figure 89. Source Code for freeLocalRef
Note: You need the JNI environment pointer (described in Obtaining the JNI
environment pointer on page 211 below) to call this wrapper.
209
/*------------------------------------------------------*/
/* getNewGlobalRef
*/
/*------------------------------------------------------*/
P getNewGlobalRef...
P
B
EXPORT
D getNewGlobalRef...
D
PI
O
CLASS(*JAVA
D
: java.lang.Object)
D
env
*
VALUE
D
localRef
O
CLASS(*JAVA
D
: java.lang.Object)
D
VALUE
/free
jniEnv_P = env;
return NewGlobalRef (env : localRef);
/end-free
P getNewGlobalRef...
P
E
Figure 90. Source Code for getNewGlobalRef
Note: You need the JNI environment pointer (described in Obtaining the JNI
environment pointer on page 211 below) to call this wrapper.
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
/*------------------------------------------------------*/
/* freeGlobalRef
*/
/*------------------------------------------------------*/
P freeGlobalRef...
P
B
EXPORT
D freeGlobalRef...
D
PI
D
env
*
VALUE
D
globalRef
O
CLASS(*JAVA
D
: java.lang.Object)
D
VALUE
/free
jniEnv_P = env;
DeleteGlobalRef (env : globalRef);
/end-free
P freeGlobalRef...
P
E
Figure 91. Source Code for freeGlobalRef
210
Note: You need the JNI environment pointer (described in Obtaining the JNI
environment pointer below) to call this wrapper.
If the JVM has not already been created when your RPG code is ready to call a
Java method, RPG will create the JVM for you. See Controlling how the Java
Virtual Machine is set up on page 202for information on the ways you can control
the Java class path and other Java properties that will be set when the JVM is
started.
JNIEnv_P = getJniEnv();
211
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
attachArgs
env
jvm
nVms
rc
obj
ds
s
s
s
s
s
newInteger
pr
likeds(JavaVMAttachArgs)
inz(*null)
like(JavaVM_p) dim(1)
like(jsize)
10i 0
o
class(*java
: java.lang.Integer)
o
extproc(*java
: java.lang.Integer
: *constructor)
10i 0 value
value
/free
monitor;
// Get the current JVM
rc = JNI_GetCreatedJavaVMs(jvm : 1 : nVms);
if (rc <> 0);
// Some error occurred
return *null;
endif; if (nVms = 0);
// The JVM is not created yet. Call a Java
// method to get the RPG runtime to start the JVM
obj = newInteger(5);
// Try again to get the current JVM
rc = JNI_GetCreatedJavaVMs(jvm : 1 : nVms);
if (rc <> 0
or nVms = 0);
// Some error occurred
return *null;
endif;
endif;
// Attach to the JVM
JavaVM_P = jvm(1);
attachArgs = *allx00;
attachArgs.version = JNI_VERSION_1_2;
rc = AttachCurrentThread (jvm(1) : env
: %addr(attachArgs));
if (rc <> 0);
return *null;
endif;
212
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
213
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
Java class
class TestClass{
String name = "name not set";
TestClass (byte name[]) {
this.name = new String(name);
}
void setName (byte name[]) {
this.name = new String(name);
}
String getName () {
return this.name;
}
}
RPG program
H THREAD(*SERIALIZE)
H BNDDIR(JAVAUTIL)
// (JAVAUTIL is assumed to the binding directory that lists
// the service program containing the procedures described
// below)
/copy JAVAUTIL
// (JAVAUTIL is assumed to be the source member containing the
// prototypes for the procedures described below)
D TestClass
D StringClass
D newTest
D
D
name
C
C
PR
D getName
PR
O
25A
O
D
D
TestClass
java.lang.String
EXTPROC(*JAVA : TestClass
: *CONSTRUCTOR)
VARYING CONST
CLASS(*JAVA : StringClass)
extproc(*JAVA : TestClass
: getName)
D setName
D
D
newName
PR
D newString
D
D
value
PR
D nameValue
D
D
PR
D myTestObj
D myString
D env
/free
S
S
S
25A
O
65535A
25A
extproc(*JAVA : TestClass
: setName)
VARYING CONST
EXTPROC(*JAVA : StringClass
: *CONSTRUCTOR)
VARYING CONST
VARYING
extproc(*JAVA : StringClass
: getBytes)
LIKE(newTest)
LIKE(newString)
LIKE(getJniEnv)
214
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
env = getJniEnv();
// Set the beginning marker for an "object group"
// so that any objects created between now and the
// "end object group" can be freed all at once.
beginObjGroup (env);
// Create a Test object to work with
// We do not want this object to be freed with the
// other objects in the object group, so we make it
// a permanent object
myTestObj = newTest (RPG Dept);
myTestObj = getNewGlobalRef (env : myTestObj);
// Get the current "name" from the Test object
// This creates a local reference to the Name object
myString = getName (myTestObj);
dsply (nameValue(myString));
// Change the name
setName (myTestObj : RPG Department);
// Get the current "name" again. This will cause
// access to the previous local reference to the old name
// to be lost, making it impossible for this RPG
// program to explicitly free the object. If the object
// is never freed by this RPG program, Java could never
// do garbage-collection on it, even though the old String
// object is not needed any more. However, endObjGroup
// will free the old reference, allowing garbage collection
myString = getName (myTestObj);
dsply (nameValue(myString));
// End the object group. This will free all local
// references created since the previous beginObjGroup call.
// This includes the two references created by the calls
// to getName.
endObjGroup (env);
// Since the original Test object was made global, it can
// still be used.
setName (myTestObj : RPG Compiler Dept);
// The original Test object must be freed explicitly
// Note: An alternative way to handle this situation
//
would be to use nested object groups, removing
//
the need to create a global reference
//
beginObjGroup ------------.
//
create myTestObj
|
//
beginObjGroup ---------. |
//
...
| |
//
endObjGroup
--------- |
//
use myTestObj again
|
//
endObjGroup
------------
freeGlobalRef (env : myTestObj);
return;
/end-free
Figure 94. Using the wrappers for the JNI functions (Part 2 of 2)
215
Tip!
You may want to include this type of exception-handling code in your
versions of the JNI wrapper procedures above.
Additional Considerations
Common Runtime Errors
The compiler will not attempt to resolve classes at compile time. If a class cannot
be located at run time, a runtime error will occur. It will indicate that an
UnresolvedLinkException object was received from the Java environment.
The compiler does no type checking of parameters at compile time. If there is a
conflict between the prototype and the method being called, an error will be
received at run time.
Debugging Hints
A Java object is viewed as an object reference in RPG. This object reference is an
integer value, which behaves like a pointer. Normal object references are positive
values, assigned in increasing order from 1. Global references, which can be
created using JNI function NewGlobalRef , are negative values. These values are
assigned in increasing order from the smallest negative number (-2147483647).
Normally, these values are not visible within the RPG code. However, this
information may be useful when debugging RPG code.
216
EXTPROC(*JAVA
: java.lang.String
: *CONSTRUCTOR)
CONST VARYING
like(jstring)
If you want to create a string with UCS-2 data or graphic data, use this code:
D
D
D
D
D
D
D
newStringC
PR
EXTPROC(*JAVA
: java.lang.String
: *CONSTRUCTOR)
CONST VARYING
like(jstring)
value
16383C
string
S
graphicData
S
15G
ucs2Data
S
100C
/free
string = newStringC (%UCS2(graphicData));
...
string = newStringC (ucs2Data);
/end-free
217
#
#
#
#
#
#
#
#
#
#
#
#
/COPY JNI
objectId
methodId
string
parms
D
D
D
D
s
s
s
ds
like(jobject)
like(jmethodID)
like(jstring)
likeds(jvalue) dim(3)
/free
parms(1).i = 10;
// parameter 1 is
parms(2).l = refToInt(string); // parameter 2 is
parms(3).d = 2.5e3;
// parameter 3 is
CallVoidMethodA (JNIEnv_P : objectId : methodId :
/end-free
an int
an object
a double
parms);
Note that the pointer JNIEnv_P is defined in the JNI /COPY file.
QUALIFIED
BASED(jvalue_P)
LIKE(jint)
OVERLAY(jvalue:1)
The "l" subfield of the jvalue structure represents an Object reference, but RPG
does not support subfields of type Object. Since Object references are actually
4-byte integers, the "l" subfield of the "jvalue" data structure is defined as a 4-byte
integer rather than as an Object. To assign an RPG Object type to the jvalue.l
subfield, you must write a procedure and a "spoofing" prototype that will trick the
RPG compiler into treating an object reference as an integer. You create one
procedure that simply takes an integer parameter and returns an integer
(procedure "refIntConv" in the example below. Then you create two prototypes that
call this procedure using a procedure pointer; one procedure defines the return
type as type Object (procedure "intToRef" in the example below), and the other
procedure defines the parameter as type Object (procedure "refToInt" in the
example below). To convert between Object and Integer types, you call either
prototype refToInt or IntToRef.
#
#
#
#
#
#
#
#
#
#
#
#
#
218
*---------------------------------------------------------------* refIntConv_procptr:
*
This procedure pointer is set to the address of a
*
procedure that takes an integer parameter and returns
*
an integer.
*
Since an object refererence is actually an integer, we
*
can define prototypes that define either the return value
*
or the parameter as an object reference, to trick the RPG
*
compiler into allowing the Object reference to be passed
*
to or returned from the procedure.
*
Note: This type of trickery is not normally recommended,
*
but it is necessary in this case to circumvent the RPG
*
restriction against Object subfields.
*---------------------------------------------------------------D refIntConv_name...
D
c
refIntConv
D refIntConv_procptr...
D
s
*
procptr
D
inz(%paddr(refIntConv_name))
*---------------------------------------------------------------* refToInt - convert an object reference to an integer
*---------------------------------------------------------------D refToInt
pr
10i 0 extproc(refIntConv_procptr)
D
ref
o
class(*java:java.lang.Object)
D
value
*---------------------------------------------------------------* intToRef - convert an integer to an object reference
*---------------------------------------------------------------D intToRef
pr
o
class(*java:java.lang.Object)
D
extproc(refIntConv_procptr)
D
int
10i 0 value
Figure 96. /COPY JNICONV_PR with prototypes for spoofing procedures to convert between
Object and integer types
H NOMAIN
/COPY JNICONV_PR
*---------------------------------------------------------------* refIntConv is used with prototypes refToInt and intToRef
* to convert between Object and integer types in RPG.
* See JNICONV_PR for more details.
*---------------------------------------------------------------D refIntConv
pr
10i 0 extproc(refIntConv_name)
D
parm
10i 0 value
*---------------------------------------------------------------* The procedure simply returns its parameter.
*---------------------------------------------------------------P refIntConv
B
export
D refIntConv
pi
10i 0
D
parm
10i 0 value
/free
return parm;
/end-free
P refIntConv
E
Figure 97. Procedure to convert between Object and integer types
219
/copy QSYSINC/QRPGLESRC,JNI
/copy JNICONV_PR
D jvals
ds
likeds(jvalue) dim(5)
D myString
s
o
class(*java:java.lang.String)
D newString
pr
o
extproc(*java:java.lang.String
D
: *constructor)
D
val
100a
const varying
myString = newString(Hello);
// Set the myString reference in the first jvalue element
jvals(1).l = refToInt (myString);
. . .
// Set the myString reference from the second jvalue element
myString = intToRef(jvals(2).l);
. . .
return;
/free
#
#
#
#
#
Figure 99. Using JNI to Access Fields of Java Classes and Objects (Part 1 of 3)
220
D Rectangle
C
java.awt.Rectangle
D NewRectangle
PR
O
EXTPROC(*JAVA
D
: Rectangle
D
: *CONSTRUCTOR)
D
x
10I 0 VALUE
D
y
10I 0 VALUE
D
width
10I 0 VALUE
D
height
10I 0 VALUE
*-----------------------------------------------------------------* Constants with ASCII representations of Java names
*-----------------------------------------------------------------* One way to determine these values is to use %UCS2 to convert
* a character value to UCS-2, and display the result in hex
* in the debugger.
*
* The ASCII value is in every second byte of the UCS-2 characters.
*
*
For example, %UCS2(abc) = X006100620063
*
-- -- -*
The ASCII representation of abc is X616263
*-----------------------------------------------------------------D ASCII_I
C
x49
D ASCII_x
C
x78
D ASCII_y
C
x79
D ASCII_width
C
X7769647468
D ASCII_height
C
X686569676874
* Note that this is java/awt/Rectangle, not java.awt.Rectangle
* because the JNI uses slash as a separator.
D ASCII_Rectangle...
D
C
X6A6176612F6177742F52656D
374616E676C65
*-----------------------------------------------------------------* Cancel handling
*-----------------------------------------------------------------D EnableCanHdlr PR
EXTPROC(CEERTX)
D
Handler
*
CONST PROCPTR
D
CommArea
*
CONST OPTIONS(*OMIT)
D
Feedback
12A
OPTIONS(*OMIT)
D CanHdlr
PR
D
CommArea
*
CONST
*-----------------------------------------------------------------* Variables and procedures
*-----------------------------------------------------------------D rect
s
O
CLASS(*JAVA : Rectangle)
D x
S
10I 0
D y
S
10I 0
D rectClass
S
LIKE(jclass)
D fieldId
S
LIKE(jfieldID)
D msg
S
52A
D Cleanup
PR
*-----------------------------------------------------------------* Enable the cancel handler to ensure cleanup is done
*-----------------------------------------------------------------C
CALLP
EnableCanHdlr (%PADDR(CanHdlr)
C
: *OMIT : *OMIT)
*-----------------------------------------------------------------* Create a new rectangle with x,y co-ordinates (5, 15),
* width 100 and height 200.
*-----------------------------------------------------------------C
EVAL
rect = NewRectangle (5 : 15 : 100 : 200)
*-----------------------------------------------------------------* Prepare to call JNI functions to access the Rectangles fields
*-----------------------------------------------------------------Figure 99. Using JNI to Access Fields of Java Classes and Objects (Part 2 of 3)
221
C
C
C
EVAL
EVAL
JNIEnv_P = getJniEnv ()
rectClass = FindClass (JNIEnv_P
: ASCII_Rectangle)
*-----------------------------------------------------------------* Call JNI functions to retrieve the Rectangles width and height
*-----------------------------------------------------------------C
eval
fieldId = GetFieldID (JNIEnv_P
C
: rectClass
C
: ASCII_width
C
: ASCII_I)
C
eval
width = GetIntField (JNIEnv_P
C
: rect
C
: fieldId)
C
eval
fieldId = GetFieldID (JNIEnv_P
C
: rectClass
C
: ASCII_height
C
: ASCII_I)
C
eval
height = GetIntField (JNIEnv_P
C
: rect
C
: fieldId)
C
eval
msg = The rectangle has dimensions (
C
+ %trim(%editc(width : 1))
C
+ ,
C
+ %trim(%editc(height : 1))
C
+ )
C
msg
dsply
*-----------------------------------------------------------------* Call the Cleanup procedure
*-----------------------------------------------------------------C
callp
Cleanup()
C
eval
*INLR = 1
*-----------------------------------------------------------------* Cleanup. * - Free objects if necessary
*-----------------------------------------------------------------P Cleanup
B
C
if
rect <> *NULL and
C
JNIEnv_P <> *NULL
C
callp
DeleteLocalRef(JNIEnv_P : rect)
C
endif
C
eval
rect = *NULL
C
eval
JNIEnv_P = *NULL
P Cleanup
E
*-----------------------------------------------------------------* Cancel handler. Ensures that cleanup is done.
*-----------------------------------------------------------------P CanHdlr
B
D CanHdlr
PI
D
CommArea
*
CONST
C
callp
Cleanup()
P CanHdlr
E
Figure 99. Using JNI to Access Fields of Java Classes and Objects (Part 3 of 3)
Calling Java Methods Using the JNI Rather than RPG *JAVA
Prototypes
The first three parameters are always the same:
1. the JNI environment pointer
2. the object (for instance methods) or the class (for static methods)
3. the method
222
The method-specific parameters are coded after these three parameters, in one of
three different ways. For example, if the method does not return a value (the
return type is "void"),
CallVoidMethod:
Choose this way if you are going to call the same method many times,
since it makes the method very easy to call. This expects the parameters to
be passed normally. To call this JNI function, an RPG programmer would
copy the CallVoidMethod prototype from the JNI /COPY file, and code
additional parameters. These functions require at least one parameter to be
coded with OPTIONS(*NOPASS). If you don't want to make the method
parameters optional, add an extra dummy parameter with
OPTIONS(*NOPASS). For example, for the method
void mymethod (int len, String str);
CallMyMethod
env
obj
methodID
len
str
dummy
PR
1a
EXTPROC(*CWIDEN
: JNINativeInterface.
CallVoidMethod_P)
LIKE(JNIEnv_P) VALUE
LIKE(jobject) VALUE
LIKE(jmethodID) VALUE
LIKE(jint) VALUE
LIKE(jstring) CONST
OPTIONS (*NOPASS)
...
CallMyMethod (JNIEnv_P : objectId : methodId : 10 : string);
Figure 100. Sample RPG Code for Calling CallVoidMethod
CallVoidMethodA:
Choose this way if you do not want to create a separate prototype for
calling a method. This expects an array of jvalue structures, with each
element of the array holding one parameter. Figure 95 on page 218 above is
an example of this.
CallVoidMethodV:
Do not use this in RPG code. It expects a C construct that is extremely
awkward to code in RPG.
The actual function to call depends on the type of the return value. For example, if
the method returns an integer, you would use CallIntMethodA. To get the class
and methodID parameters for these functions, use the FindClass and GetMethodID
or GetStaticMethodID.
Note: When calling the JNI directly, the class names must be specified with a slash
(/) rather than a period (.) as the separator. For example, use
'java/lang/String' rather than 'java.lang.String'.
223
#
#
#
#
#
#
#
#
#
#
The ILE RPG compiler will generate PCML information for your ILE RPG program
or module when you specify the PGMINFO(*PCML) compiler parameter on your
command or Control specification. You can have the PCML information generated
into a stream file if you specify the *STMF or *ALL for the Location part of the
PGMINFO parameter on the command; you specify the name of the stream file in
the INFOSTMF command parameter. You can have the PCML information
generated directly into the module if you specify *MODULE or *ALL for the
Location part of the PGMINFO parameter on the command, or if you specify the
PGMINFO keyword on the Control specification; you can later retrieve the
information using the QBNRPII API.
#
#
#
#
For CRTBNDRPG, PCML is generated based on the contents of the *ENTRY PLIST
or the Procedure Interface of the main procedure. For CRTRPGMOD, PCML is also
generated based on the Procedure Interfaces of any exported subprocedures
(except Java native methods).
When you use CRTRPGMOD, and create a service program, you specify the
service program in your Java code using the setPath(String) method of the
ProgramCallDocument class. For example:
AS400 as400;
ProgramCallDocument pcd;
String path = "/QSYS.LIB/MYLIB.LIB/MYSRVPGM.SRVPGM";
as400 = new AS400 ();
pcd = new ProgramCallDocument (as400, "myModule");
pcd.setPath ("MYFUNCTION", path);
pcd.setValue ("MYFUNCTION.PARM1", "abc");
rc = pcd.callProgram("MYFUNCTION");
PCML Restrictions
The following are restrictions imposed by PCML regarding parameter and return
value types.
v The following data types are not supported by PCML:
Date
Time
Timestamp
Pointer
Procedure Pointer
1-Byte Integer
8-byte Unsigned Integer
v Return values and parameters passed by value can only be 4 byte integers (10i
0).
v Varying-length arrays, and data structures containing varying-length subfields
are not supported.
v When a data structure is used as a parameter for a *ENTRY PLIST, or a
prototyped parameter is defined with LIKEDS, some PCML restrictions apply:
The data structure may not have any overlapping subfields.
The subfields must be coded in order; that is, the start position of each
subfield must follow the end position of the previous subfield.
If there are gaps between the subfields, the generated PCML for the structure
will have subfields named "_unnamed_1", "_unnamed_2" etc, of type "char".
v RPG does not have the concept of output-only parameters. Any parameters that
do not have CONST or VALUE coded have a usage of "inputoutput". For
inputoutput parameters, the ProgramCallDocument class requires the input
224
values for the parameter to be set before the program can be called. If the
parameter is truly an output parameter, you should edit the PCML to change
"inputoutput" to "output".
The compile will fail if you generate PCML for a program or module that violates
one of the restrictions. The PCML will be generated, but it will contain error
messages as comments. For example, if you use a Date field as a parameter, the
PCML for that parameter might look like this:
<data name="DATE" type="
" length="10" usage="input" />
<!-- Error: unsupported data type -->
225
226
227
228
229
3. Set a breakpoint on one of the calculation lines by putting your cursor on the
line and pressing F6
4. Exit the DSPMODSRC screen with F12
5. ===> CALL QTEMP/PROOF
You will see the source again, with your breakpoint line highlighted .
6. Move your cursor over one of the variables in the program source (Definition,
Input, Calculation or Output Specifications) and press F11. The value of the
variable will appear at the bottom of the screen
7. Step through the rest of the program by pressing F10, or run to the end with
F12
8.
After setting breakpoints, you do not have to call the program directly. You can
start an application that will eventually call the program.
If you step through the whole program, it will step through the Input and Output
specifications. If you prefer to skip over Input and Output specifications, you can
specify OPTION(*NODEBUGIO) in your Header specification or when you
compile your program.
More details on these steps will be given in the rest of this chapter.
Debug Commands
Many debug commands are available for use with the ILE source . The debug
commands and their parameters are entered on the debug command line displayed
on the bottom of the Display Module Source and Evaluate Expression displays.
These commands can be entered in uppercase, lowercase, or mixed case.
230
Description
ATTR
BREAK
CLEAR
DISPLAY
EQUATE
EVAL
QUAL
SET
STEP
TBREAK
THREAD
WATCH
FIND
UP
DOWN
LEFT
RIGHT
231
BOTTOM
NEXT
PREVIOUS
HELP
The online help for the ILE source describes the debug commands, explains their
allowed abbreviations, and provides syntax diagrams for each command. It also
provides examples in each of the ILE languages of displaying and changing
variables using the source .
Follow these steps to access the online help information for ILE RPG:
1. Enter STRDBG library-name/program-name where program-name is any ILE
program with debug data in library library-name.
2. Enter DSPMODSRC to show the source view if this screen does not appear
following step 1.
3. Enter PF1 (Help)
4. Put your cursor on EVAL and press enter to bring up the EVAL command help.
5. Put your cursor on Expressions and press enter to bring up help for
expressions.
6. Put your cursor on RPG language and press enter to bring up RPG language
examples.
7. From the help panel which appears, you can select a number of topics
pertaining to RPG, such as displaying variables, displaying table, and
displaying multiple-occurrence data structures.
232
Debug Data
DBGVIEW Parameter
Value
None
No debug data
*NONE
Statement view
(default)
*STMT
*SOURCE
*COPY
Listing view
*LIST
All
*ALL
233
To create a root source view for a module DBGEX when using CRTRPGMOD,
type:
CRTRPGMOD MODULE(MYLIB/DBGEX) SRCFILE(MYLIB/QRPGLESRC)
TEXT(Entry module for program DEBUGEX)
DBGVIEW(*SOURCE)
234
You can encrypt the listing view so that the listing information cannot be viewed
during a debug session unless the person knows the encryption key. You specify
the encryption key using the DBGENCKEY parameter of the CRTBNDRPG,
CRTRPGMOD, or CRTSQLRPGI command. You specify the same key when
debugging the program to view the text of the listing view.
The compiler creates the listing view while the module object (*MODULE) is being
generated. The listing view is created by copying the text of the appropriate source
members into the module object. There is no dependency on the source members
upon which it is based, once the listing view is created.
For example, to create a listing view for a program TEST1 that contains expanded
DDS type:
CRTBNDRPG PGM(MYLIB/TEST1) SRCFILE(MYLIB/QRPGLESRC)
SRCMBR(TEST1) OUTPUT(*PRINT)
TEXT(ILE RPG/400 program TEST1)
OPTION(*EXPDDS) DBGVIEW(*LIST)
Specifying DBGVIEW(*LIST) for the DBGVIEW parameter and *EXPDDS for the
OPTION parameter on either create command creates a listing view with expanded
DDS for debugging the source for TEST1. Note that OUTPUT(*PRINT) and
OPTION(*EXPDDS) are both default values.
235
By default a compiler listing and a statement view are produced. Using a compiler
listing to obtain the statement numbers, you debug the program using the debug
commands.
If the default values for either create command have been changed, you must
explicitly specify DBGVIEW(*STMT) and OUTPUT(*PRINT).
236
STRDBG Example
To start a debug session for the sample debug program DEBUGEX and a called
OPM program RPGPGM, type:
STRDBG PGM(MYLIB/DEBUGEX MYLIB/RPGPGM) OPMSRC(*YES)
The Display Module Source display appears as shown in Figure 101 on page 238.
DEBUGEX consists of two modules, an RPG module DBGEX and a C module
cproc. See Sample Source for Debug Examples on page 279 for the source for
DBGEX, cproc, and RPGPGM.
If the entry module has a root source, COPY, or listing view, then the display will
show the source of the entry module of the first program. In this case, the program
was created using DBGVIEW(*ALL) and so the source for the main module,
DBGEX, is shown.
237
Program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*--------------------------------------------------------------* Define standalone fields for different ILE RPG data types.
More...
Debug . . . _________________________________________________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
3. The Set Debug Options display appears. On this display type Y (Yes) for the
OPM source debug support field, and press Enter to return to the Display Module
Source display.
238
239
AS400S1
Bottom
Command
===> ________________________________________________________________________
F3=Exit
F4=Prompt
F5=Refresh F9=Retrieve F12=Cancel
AS400S1
Selected
Bottom
Command
===> ________________________________________________________________________
F3=Exit
F4=Prompt
F5=Refresh F9=Retrieve F12=Cancel
240
The module object module-name is shown. The module object must exist in a
program object that has been added to the debug session.
For example, to change from the module DBGEX in Figure 101 on page 238 to the
module cproc using the Display module source option, follow these steps:
1. To work with modules type DSPMODSRC, and press Enter. The Display Module
Source display is shown.
2. Press F14 (Work with module list) to show the Work with Module List display.
Figure 104 on page 242 shows a sample display.
3. To select cproc, type 5 (Display module source) next to it and press Enter. Since
a root source view is available, it is shown, as in Figure 105 on page 242. If a
root source was not available, the first module object bound to the program
object with debug data is shown.
241
AS400S1
Selected
Bottom
Command
===> ________________________________________________________________________
F3=Exit
F4=Prompt
F5=Refresh F9=Retrieve F12=Cancel
Program:
1
2
3
4
5
6
7
8
9
10
11
12
13
Module:
CPROC
Bottom
Debug . . . _________________________________________________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
242
The current view is listed at the top of the window, and the other views that
are available are shown below. Each module in a program can have a different
set of views available, depending on the debug options used to create it.
Note: If a module is created with DBGVIEW(*ALL), the Select View window
will show three views available: root source, COPY, and listing. If the
module has no /COPY members, then the COPY view is identical to the
root source view.
3. Type a 1 next to the listing view, and press Enter. The Display Module Source
display appears showing the module with a listing view.
243
244
on the debug command line. The variable line-number is the line number in the
currently displayed view of the module object on which you want to set a
breakpoint.
To remove an unconditional job breakpoint using the CLEAR debug command,
type:
CLEAR line-number
on the debug command line. The variable line-number is the line number in the
currently displayed view of the module object from which you want to remove a
breakpoint. When a job breakpoint is cleared, it is also cleared for all threads.
on the debug command line where module-name is the name of the module that
you want to display.
3. To set an unconditional breakpoint on the first Calculation specification, place
the cursor on line 88.
4. Press F6 (Add/Clear breakpoint). If there is no breakpoint on the line 88, then
an unconditional breakpoint is set on that line, as shown in Figure 107 on page
246. If there is a breakpoint on the line, it is removed.
Note: Because we want the breakpoint on the first Calculation specification, we
could have placed the cursor on any line before the start of the
calculation specifications and the breakpoint would still have been
placed on line 88, since it is the first runnable statement.
245
Program:
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
5. After the breakpoint is set, press F3 (Exit) to leave the Display Module Source
display. The breakpoint is not removed.
6. Call the program. When a breakpoint is reached, the program stops and the
Display Module Source display is shown again, with the line containing the
breakpoint highlighted. At this point you can step through the program or
resume processing.
246
on the debug command line. The variable line-number is the line number in the
currently displayed view of the module object on which you want to set a
breakpoint and expression is the conditional expression that is evaluated when the
breakpoint is encountered. The relational operators supported for conditional
breakpoints are noted at the beginning of this section.
In non-numeric conditional breakpoint expressions, the shorter expression is
implicitly padded with blanks before the comparison is made. This implicit
padding occurs before any National Language Sort Sequence (NLSS) translation.
See National Language Sort Sequence (NLSS) on page 249 for more information
on NLSS.
Chapter 12. Debugging Programs
247
on the debug command line. The variable line-number is the line number in the
currently displayed view of the module object from which you want to remove a
breakpoint.
Library . . . :
Type . . . . . :
System:
MYLIB
*PGM
TORASD80
Bottom
Command
===> ________________________________________________________________________
F3=Exit
F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
Breakpoint added to line 127.
248
Program:
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
DEBUGEX
Module:
DBGEX
*--------------------------------------------------------------More...
Debug . . . break 128 when BigDate=1994-09-30______________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
Figure 109. Setting a Conditional Job Breakpoint Using the BREAK Command
249
Possible
Char-8
Notes:
1. Character literal is of the form 'abc'.
2. Hexadecimal literal is of the form X'hex digits'.
3. Graphic literal is of the form G'oK1K2i'. Shift-out is represented as o and shift-in is
represented as i.
on the debug command line. The variable procedure-name is the name of the
procedure in which you are setting the breakpoint. Since ILE RPG allows more
250
Seq
<--------------------- Source Specifications ----------------------------------------------><---- Comments ----> Statement
Number ....1....+....2....+<-------- 26 - 35 -------->....4....+....5....+....6....+....7....+....8....+....9....+...10 Number
S o u r c e L i s t i n g
000100 C
MOVE
123
BI_FLD1
000100
000200 C
SETON
LR---000200
* * * * * E N D O F S O U R C E * * * * *
In this example, a Statement View is used to set a breakpoint for the procedure
TEST. To set a breakpoint for the module with the *NOSRCSTMT listing, type:
BREAK TEST/2
To set a breakpoint for the module with the *SRCSTMT listing, type:
BREAK TEST/200
LR----' line.
Module:
TEST
Bottom
Debug . . . break TEST/2_____________________________________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
Breakpoint added to statement 2 of procedure TEST.
For all other debug views, the statement numbers can be used in addition to the
program line-numbers in the . For example, to set a breakpoint at the beginning of
subprocedure FmtCust in the Listing View below, type:
BREAK 34
Or
BREAK FmtCust/2600
251
B' line.
Figure 113. Setting a Breakpoint using Statement Numbers and a Listing View with
OPTION(*SRCSTMT)
To set a conditional job breakpoint using the BREAK debug command, type:
BREAK procedure-name/statement-number WHEN expression
on the debug command line. The variables procedure-name and statement-number are
the same as for unconditional breakpoints. The variable expression is the conditional
expression that is evaluated when the breakpoint is encountered.
To remove an unconditional or conditional breakpoint using the CLEAR debug
command, type:
CLEAR procedure-name/statement-number
252
on the debug command line. The breakpoints are removed from all of the modules
bound to the program.
Characteristics of Watches
You should know the following characteristics about watches before working with
them:
v Watches are monitored system-wide, with a maximum number of 256 watches
that can be active simultaneously. This number includes watches set by the
system.
Chapter 12. Debugging Programs
253
254
Address
080090506F027004
Length
4
Bottom
Command
===>____________________________________________________________________
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
The Work with Watch display shows all watches currently active in the debug
session. You can clear, and display watches from this display. When you select
Option 5 Display, the Display Watch window shown below displays
information about the currently active watch.
Work with Watch
..........................................................
:
Display Watch
:
:
:
: Watch Number ....: 1
:
: Address .........: 080090506F027004
:
: Length ..........: 4
:
: Number of Hits ..: 0
:
:
:
: Scope when watch was set:
:
:
Program/Library/Type:
PAYROLL
ABC
*PGM
:
:
:
:
Module...:
PAYROLL
:
:
Procedure:
PAYROLL
:
:
Variable.:
SALARY
:
:
:
: F12=Cancel
:
:
:
..........................................................
Bottom
Command
===>____________________________________________________________________
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
255
The scope of the expression variables in a watch is defined by the most recently
issued QUAL command.
v To set a watch condition and specify a watch length, type:
WATCH expression : watch length
on a debug command line. This command brings up the Display Debug Watches
display shown below.
Display Debug Watches
------------Job--------------MYJOBNAME1 MYUSERPRF1 123456
JOB4567890 PRF4567890 222222
JOB4567890 PRF4567890 222222
JOB
PROFILE
333333
SOMEJOB
SOMEPROFIL 444444
Bottom
Press Enter to continue
F3=Exit F5=Refresh
F12=Cancel
NUM
1
1
2
14
3
LENGTH
5
8
2
4
4
System:
ADDRESS
080090506F027004
09849403845A2C32
098494038456AA00
040689578309AF09
005498348048242A
Note: This display does not show watch conditions set by the system.
The watch number can be obtained from the Work With Watches display.
To clear all watches for your session, type:
CLEAR WATCH ALL
256
Program:
PAYROL
52 C
53 C
54 C
55 C
56 C
57 C
58 C
59 C
60 C
61 C
62 C
63 C
64 C
65 C
66 C
67 C
index = 1
index <= cnt
Pay_exmpt(index) = 1
SALARY = 40 * Pay_wage(index)
numexmpt = numexmpt + 1
SALARY = Pay_hours(index)*Pay_wage(index)
index = index + 1
More...
Debug . . . _________________________________________________________________
_______________________________________________________________________________
F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
Watch number 1 at line 65, variable: SALARY
v The line number of the statement where the change to the watch variable was
detected is highlighted. This is typically the first executable line following the
statement that changed the variable.
v A message indicates that the watch condition was satisfied.
Note: If a text view is not available, a blank Display Module Source display is
shown, with the same message as above in the message area.
The following programs cannot be added to the ILE debug environment:
257
258
on the debug command line, the next five statements of your program object are
run, then the program object is stopped again and the Display Module Source
display is shown.
When a call statement to another program or procedure is encountered in a debug
session, you can:
v Step over the call statement, or
v Step into the call statement.
A call statement for ILE RPG includes any of the following operations:
v CALL
v CALLB
v CALLP
v Any operation where there is an expression in the extended-factor 2 field, and
the expression contains a call to a procedure.
If you choose to step over the call statement, then you will stay inside the current
procedure. The call statement is processed as a single step and the cursor moves to
the next step after the call. Step over is the default step mode.
If you choose to step into the call statement, then each statement inside the call
statement is run as a single step. Depending on the number of steps specified, the
step command may end inside the call statement, in which case the source for the
call statement is shown in the Display Module Source display.
Note: You cannot step over or step into RPG subroutines. You can, however, step
over and into subprocedures.
259
on the debug command line, the next five statements of the program object are
run. If the third statement is a CALL operation to another program object, then
two statements of the calling program object are run and the first three statements
of the called program object are run.
In the example of DEBUGEX, if you enter STEP INTO (or press F22) while on the
EVAL operation that calls the procedure c_proc, then you would step into the C
module.
The STEP INTO command works with the CL CALL command as well. You can
take advantage of this to step through your program after calling it. After starting
the source , from the initial Display Module Source display, enter
STEP 1 INTO
This will set the step count to 1. Use the F12 key to return to the command line
and then call the program. The program will stop at the first statement with debug
data.
TIP
In order to display data immediately before or after a subprocedure is run,
place breakpoints on the procedure specifications that begin and end the
subprocedure.
260
Program:
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
*--------------------------------------------------------------* Call c_proc, which imports ExportFld from the main procedure.
More...
Debug . . . _________________________________________________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
Breakpoint at line 102.
Figure 119. Display Module Source display of DBGEX Before Stepping Into RPGPGM
5. Press F22 (Step into). One statement of the program runs, and then the Display
Module Source display of RPGPGM is shown, as in Figure 120 on page 262.
In this case, the first runnable statement of RPGPGM is processed (line 13) and
then the program stops.
Note: You cannot specify the number of statements to step through when you
use F22. Pressing F22 performs a single step.
261
Program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
*ENTRY
InputParm
4P 3
PLIST
PARM
DSPLY
SETON
InputParm
Bottom
Debug . . . _________________________________________________________________
_______________________________________________________________________________
F3=End program
F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume
F17=Watch variable F18=Work with watch F24=More keys
Step completed at line 13.
If the ILE source is not set to accept OPM programs, or if there is no debug data
available, then you will see a blank Display Module Source display with a message
indicating that the source is not available. (An OPM program has debug data if it
was compiled with OPTION(*SRCDBG) or OPTION(*LSTDBG).)
262
For complex qualified names, use the dot-qualification form of the name:
EVAL FAMILY.CHILD(2).PETS.PET(3).NAME
The scope of the fields used in the EVAL command can be defined by using the
QUAL command in languages such as ILE C. However, this command does not
currently apply to ILE RPG,
Note: You cannot display return values because there is no external name available
for use with the EVAL debug command.
The easiest way to display data or an expression is to use F11 (Display variable) on
the Display Module Source display. To display a field using F11 (Display variable),
place your cursor on the field that you want to display and press F11 (Display
variable). The current value of the field is shown on the message line at the bottom
of the Display Module Source display.
In cases where you are evaluating structures, records, or arrays, the message
returned when you press F11 (Display variable) may span several lines. Messages
that span several lines are shown on the Evaluate Expression display to show the
263
on the debug command line. The variable field-name is the name of the field, data
structure, or array that you want to display or evaluate. The value is shown on the
message line if the EVAL debug command is entered from the Display Module
Source display and the value can be shown on a single line. Otherwise, it is shown
on the Evaluate Expression display.
Figure 122 shows an example of using the EVAL debug command to display the
contents of a subfield LastName.
Program:
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Module: DBGEX
INZ(Jones
)
INZ(Fred
)
PR
1A
Figure 123 on page 265 shows the use of the EVAL command with different types
of RPG fields. The fields are based on the source in Figure 131 on page 280.
Additional examples are also provided in the source online help.
264
Scalar Fields
RPG Definition
> EVAL String
6A
INZ(ABCDEF)
STRING = ABCDEF
> EVAL Packed1D0
5P 2 INZ(-93.4)
PACKED1D0 = -093.40
> EVAL ZonedD3D2
3S 2 INZ(-3.21)
ZONEDD3D2 = -3.21
> EVAL Bin4D3
4B 3 INZ(-4.321)
BIN4D3 = -4.321
> EVAL Int3
3I 0 INZ(-128)
INT3 = -128
> EVAL Int5
5I 0 INZ(-2046)
INT5 = -2046
> EVAL Int10
10I 0 INZ(-31904)
INT10 = -31904
> EVAL Int20
20I 0 INZ(-463972)
INT20 = -463972
> EVAL Unsigned3
3U 0 INZ(128)
UNSIGNED3 = 128
> EVAL Unsigned5
5U 0 INZ(2046)
UNSIGNED5 = 2046
> EVAL Unsigned10
10U 0 INZ(31904)
UNSIGNED10 = 31904
> EVAL Unsigned20
20U 0 INZ(463972)
UNSIGNED20 = 463972
> EVAL DBCSString
3G
INZ(G~BBCCDD~)
DBCSSTRING = "BBCCDD"
> EVAL NullPtr
*
INZ(*NULL)
NULLPTR = SYP:*NULL
Based Fields
> EVAL String
6A
INZ(ABCDEF)
STRING = ABCDEF
> EVAL BasePtr
*
INZ(%ADDR(String))
BASEPTR = SPP:C01947001218
> EVAL BaseString
6A
BASED(BasePtr)
BASESTRING = ABCDEF
Date, Time, Timestamp Fields
> EVAL BigDate
D
INZ(D9999-12-31)
BIGDATE = 9999-12-31
> EVAL BigTime
T
INZ(T12.00.00)
BIGTIME = 12.00.00
> EVAL BigTstamp
Z
INZ(Z9999-12-31-12.00.00.000000
BIGTSTAMP = 9999-12-31-12.00.00.000000
Figure 123. Sample EVAL commands based on Module DBGEX
265
The variable field-name is the name of the array, the variable n is a number
representing the start of the range, and the variable m is a number representing the
end of the range.
Figure 124 shows the use of EVAL with the array in DBGEX.
> EVAL Arry
ARRY(1) = 1.23
ARRY(2) = 1.23
> EVAL Arry(2)
ARRY(2) = 1.23
> EVAL Arry(1..2)
ARRY(1) = 1.23
ARRY(2) = 1.23
3S 2 DIM(2) INZ(1.23)
** Display full array **
** Display second element **
** Display range of elements **
You can change the current element using the %INDEX built-in function. To
determine the value of the table index, enter the following command:
EVAL _QRNU_TABI_name
266
3
DIM(3) CTDATA
Compile-time data: **
** Show value at
aaa
current index
bbb
ccc
** Specify index 1 **
** Specify index 2 **
** Display value of current index **
** Specify the whole table **
For example, to display subfield NAME of qualified data structure INFO, type one
of the following:
EVAL NAME OF INFO
EVAL NAME OF INFO EVAL INFO.NAME
267
where the variable subfield-name is the name of the subfield you wish to display,
occurrence-index is the number of the array occurrence to display, and array-index is
the number of the element to display.
Figure 126 shows some examples of using EVAL with the the data structures
defined in DBGEX.
** Note that you can enter the data structure name or a subfield name. **
> EVAL DS3
TITLE OF DS3 = Mr.
5A
INZ(Mr. )
LASTNAME OF DS3 = Jones
10A
INZ(Jones
)
FIRSTNAME OF DS3 = Fred
10A
INZ(Fred
)
> EVAL LastName
LASTNAME = Jones
To display a data structure for which no subfields have been defined, you must
use the character display function of EVAL which is discussed below.
Displaying Indicators
Indicators are defined as 1-byte character fields. Except for indicators such as
*INLR, you can display indicators either as '*INxx' or '*IN(xx)'. Because the system
268
on the debug command line. The variable field-name is the name of the field that
you want to display in hexadecimal format. 'x' specifies that the field is to be
displayed in hexadecimal format. The variable number-of-bytes indicates the number
of bytes displayed. If no length is specified after the 'x', the size of the field is used
as the length. A minimum of 16 bytes is always displayed. If the length of the field
is less than 16 bytes, then the remaining space is filled with zeroes until the 16 byte
boundary is reached.
For example, the field String is defined as six-character string. To find out the
hexadecimal equivalent of the first 3 characters, you would enter:
EVAL String: x 3
Result:
00000
C1C2C3.. ........ ........ ........
- ABC.............
on the debug command line. The variable field-name is the name of the field that
you want to display in character format. 'c' specifies the number of characters to
display.
269
Result:
DS2:C 20 = aaaaaaaaaabbbbbbbbbb
If you want to see what a pointer is pointing to, you can use the EVAL command
with the :c or :x suffix. For example, if pointer field PTR1 is pointing to 10 bytes of
character data,
#
#
#
#
This would be especially useful when the data that the pointer addresses is not
stored in printable form, such as packed or binary data.
#
#
#
If you have a variable FLD1 based on basing pointer PTR1 that is itself based on a
pointer PTR2, you will not be able to evaluate FLD1 using a simple EVAL
command in the debugger.
#
#
Instead, you must explicitly give the debugger the chain of basing pointers:
#
#
#
#
#
#
#
#
#
#
#
you can use these commands in the debugger to display or change the values of
DATA1 and DATA2:
EVAL PTR1:c 10
EVAL PTR1:x 10
D
D
D
D
D
D
pPointers
pointers
p1
p2
data1
data2
S
DS
S
S
*
based(pPointers)
*
*
10A
10A
based(p1)
based(p2)
270
To determine the expression to specify in the debugger, you start from the end of
the expression with the value that you want to evaluate:
#
#
#
Then you move to the left and add the name that appears in the BASED keyword
for the definition of data1, which is p1:
#
#
#
Then you move to the left again and add the name that appears in the BASED
keyword for the definition of p1, which is pPointers:
#
#
#
#
The expression is complete when the pointer that you have specified was not
defined with the BASED keyword. In this case, pPointers is not defined as based,
so the debug expression is now complete.
data1
p1->data1
pPointers->p1->data1
*
5a
based(parmPtr)
Note: this method does not work well with data that has a hexadecimal
representation that does not resemble the natural representation, such as
packed, integer or UCS-2 data.
2. Use the debugger's "arrow" notation to explicitly specify the basing pointer.
This method can also be used to change the variable.
===> eval parmPtr->basedFld
===> eval parmPtr->basedFld = abcde
If a variable has more than two levels of basing pointer, the second method must
be used. For example, in the following program, variable "basedVal" has three
levels of basing pointer; it is based on pointer "p1" which is based on pointer "p2"
which is further based on pointer "p3". Variable "basedVal" cannot be evaluated in
the debugger using simply "EVAL basedVal".
271
D
D
D
D
D
D
D
D
D
C
C
C
C
storage
val
basedVal
p1
p2
p3
ptr1
ptr2
ptr3
s
s
s
s
s
s
s
s
s
eval
eval
eval
eval
5a
inz(abcde)
5a
5a
based(p1)
*
based(p2)
*
based(p3)
*
*
inz(%addr(storage))
*
inz(%addr(ptr1))
*
inz(%addr(ptr2))
p3 = ptr3
p2 = ptr2
p1 = ptr1
val = basedVal
Result:
_QRNU_NULL_FLD1 = 1
EVAL FLD1
Result:
FLD1 = abcde
If a data structure has null-capable subfields, the null indicators for all the
null-capable subfields of the data structure are themselves stored as subfields of
the data structure _QRNU_NULL_dsname.
If the data structure is not qualified, the null indicator data structure is not
qualified. The names of the null capable subfields are in the form
_QRNU_NULL_subfieldname.
For example, if qualified data structure DS1 has null-capable subfields FLD1 and
FLD2 and non-null-capable subfield FLD3, then the data structure
272
Result:
_QRNU_NULL_FLD1 OF _QRNU_NULL_DS1 = 1
_QRNU_NULL_FLD1 OF _QRNU_NULL_DS1 = 0
If the data structure is qualified, the null indicator data structure is qualified. The
names of the null capable subfields are the same as the names of the data structure
subfields.
For example, if qualified data structure DS2 has null-capable subfields F1 and F2
and non-null-capable subfield F3, then the data structure _QRNU_NULL_DS2
would have indicator subfields F1 and F2. To display all the null-capable subfields
of the data structure, use this debug command:
EVAL _QRNU_NULL_DS2
Result:
_QRNU_NULL_DS2.F1 = 0
_QRNU_NULL_DS2.F2 = 1
To display the null indicator of a variable, use the same EVAL expression in the
debugger as you would use to access the variable itself, replacing the outermost
name with _QRNU_NULL_name.
EVAL FLD1
EVAL _QRNU_NULL_FLD1
Result: abc
Result: 0
EVAL SUBF2
EVAL _QRNU_NULL_SUBF2
Result: 0
Result: 1
EVAL ARR(3)
EVAL _QRNU_NULL_ARR(3)
Result: 13
Result: 1
EVAL DS3.INFO(2).SUB4
EVAL _QRNU_NULL_DS3.INFO(2).SUB4
Result: xyz
Result: 0
273
To change the current index, you can use the %INDEX built-in function, where the
index is specified in parentheses following the function name. An example of
%INDEX is found in the table section of Figure 125 on page 267 and Figure 126 on
page 268.
Note: %INDEX will change the current index to the one specified. Therefore, any
source statements which refer to the table or multiple-occurrence data
structure subsequent to the EVAL statement may be operating with a
different index than expected.
Use the %VARS debug built-in function when the variable name conflicts with any
of the debug command names. For example, EVAL %VAR(EVAL) can be used to
evaluate a variable named EVAL, whereas EVAL EVAL would be a syntax error.
274
The third parameter passed to the event handler is a pointer to the data. See
Displaying Data Addressed by Pointers on page 270, using the value of the
fourth parameter to determine the length of the data, in bytes.
For an Exception event, the fifth parameter holds the error code related to the
parsing exception. See Processing XML Documents on page 185 for the meanings
of the error codes.
on the debug command line. field-name is the name of the variable that you want
to change and value is an identifier, literal, or constant value that you want to
assign to variable field-name. For example,
EVAL COUNTER=3
275
276
** Using %SUBSTR **
> EVAL BigDate
BIGDATE = 1994-10-23
> EVAL String=%SUBSTR(BigDate 1 4)
STRING=%SUBSTR(BIGDATE 1 4) = 1994
** Substring Target Length > Substring Source Length **
> EVAL string = 123456
STRING = 123456 = 123456
> EVAL LastName=Williamson
LASTNAME=Williamson = Williamson
> EVAL String = %SUBSTR(Lastname 1 8)
STRING = %SUBSTR(LASTNAME 1 8) = Willia
** Substring Target Length < Substring Source Length **
> EVAL TableA
TABLEA = aaa
> EVAL String
STRING = 123456
> EVAL String=%SUBSTR(TableA 1 4)
Substring extends beyond end of string.
** Error **
> EVAL String
STRING = 123456
Figure 129. Examples of Changing the Values of Fields based on DBGEX
277
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
> ATTR
TYPE
NullPtr
= PTR, LENGTH = 16 BYTES
ZonedD3D2
= ZONED(3,2), LENGTH = 3 BYTES
Bin4D3
= BINARY, LENGTH = 2 BYTES
Int3
= INTEGER, LENGTH = 1 BYTES
Int5
= INTEGER, LENGTH = 2 BYTES
Unsigned10
= CARDINAL, LENGTH = 4 BYTES
Unsigned20
= CARDINAL, LENGTH = 8 BYTES
Float4
= REAL, LENGTH = 4 BYTES
Float8
= REAL, LENGTH = 8 BYTES
Arry
= ARRAY, LENGTH = 6 BYTES
tablea
= FIXED LENGTH STRING, LENGTH =
tablea(2)
= FIXED LENGTH STRING, LENGTH =
BigDate
= FIXED LENGTH STRING, LENGTH =
DS1
= RECORD, LENGTH = 9 BYTES
SpcPtr
= PTR, LENGTH = 16 BYTES
String
= FIXED LENGTH STRING, LENGTH =
*IN02
= CHAR, LENGTH = 1 BYTES
DBCSString
= FIXED LENGTH STRING, LENGTH =
3 BYTES
3 BYTES
10 BYTES
6 BYTES
6 BYTES
on the debug command line. shorthand-name is the name that you want to equate
with a field, expression, or debug command, and definition is the field, expression,
or debug command that you are equating with the name.
For example, to define a shorthand name called DC which displays the contents of
a field called COUNTER, type:
EQUATE DC EVAL COUNTER
on the debug command line. Now, each time DC is typed on the debug command
line, the command EVAL COUNTER is performed.
278
on the debug command line. A list of the active names is shown on the Evaluate
Expression display.
The first module DBGEX is the entry module for this program. The program
will run in a new activation group (that is, *NEW) when it is called.
4. To create the called RPG program using the source in Figure 132 on page 283,
type:
279
We could have created RPGPGM to run in the OPM default activation group.
However, we decided to have it run in the same activation group as
DEBUGEX, and since DEBUGEX needs only a temporary activation group,
*NEW was chosen for both programs.
*=================================================================*
* DEBUGEX - Program designed to illustrate use of ILE source
*
debugger with ILE RPG source. Provides a
*
sample of different data types and data structures.
*
*
Can also be used to produce sample formatted dumps.
*=================================================================*
*-----------------------------------------------------------------*
* The DEBUG keyword enables the formatted dump facility.
*-----------------------------------------------------------------*
H DEBUG
*-----------------------------------------------------------------*
* Define standalone fields for different ILE RPG data types.
*-----------------------------------------------------------------*
D String
S
6A
INZ(ABCDEF)
D Packed1D0
S
5P 2 INZ(-93.4)
D ZonedD3D2
S
3S 2 INZ(-3.21)
D Bin4D3
S
4B 3 INZ(-4.321)
D Bin9D7
S
9B 7 INZ(98.7654321)
D DBCSString
S
3G
INZ(G"BBCCDD")
D UCS2String
S
5C
INZ(%UCS2(ucs-2))
D CharVarying
S
5A
INZ(abc) VARYING
D Int3
S
3I 0 INZ(-128)
D Int5
S
5I 0 INZ(-2046)
D Int10
S
10I 0 INZ(-31904)
D Int20
S
20I 0 INZ(-463972)
D Unsigned3
S
3U 0 INZ(128)
D Unsigned5
S
5U 0 INZ(2046)
D Unsigned10
S
10U 0 INZ(31904)
D Unsigned20
S
20U 0 INZ(463972)
D Float4
S
4f
INZ(7.2098)
D Float8
S
8f
INZ(-129.0978652)
D DBCSString
S
3G
INZ(G"BBCCDD")
Figure 131. Source for Module DBGEX (Part 1 of 4). DBGEX is the main module of the
program DEBUGEX.
280
*
D
D
D
D
D
Pointers
NullPtr
BasePtr
ProcPtr
BaseString
BaseOnNull
S
S
S
S
S
*
*
*
6A
10A
INZ(*NULL)
INZ(%ADDR(String))
ProcPtr INZ(%PADDR(c_proc))
BASED(BasePtr)
BASED(NullPtr)
*
D Spcptr
S
*
D SpcSiz
C
8
*
Date, Time, Timestamp
D BigDate
S
D
INZ(D9999-12-31)
D BigTime
S
T
INZ(T12.00.00)
D BigTstamp
S
Z
INZ(Z9999-12-31-12.00.00.000000)
*
Array
D Arry
S
3S 2 DIM(2) INZ(1.23)
*
Table
D TableA
S
3
DIM(3) CTDATA
*-----------------------------------------------------------------*
* Define different types of data structures.
*-----------------------------------------------------------------*
D DS1
DS
OCCURS(3)
D Fld1
5A
INZ(ABCDE)
D Fld1a
1A
DIM(5) OVERLAY(Fld1)
D Fld2
5B 2 INZ(123.45)
*
D DS2
DS
10
OCCURS(2)
*
D DS3
DS
D Title
5A
INZ(Mr. )
D LastName
10A
INZ(Jones
)
D FirstName
10A
INZ(Fred
)
D
D
D
D
D
D
D
D
D
D
D
D
D
QUALDS
DS
QUALIFIED
Id_Num
8S 0
Country
20A
DIM(10)
LIKE_QUALDS
DS
LIKEDS(QUALDS)
itemInfo
DS
QUALIFIED
ID_Num
10I 0
name
25A
items
DS
QUALIFIED
numItems
10I 0
item
LIKEDS(itemInfo) DIM(10)
cust
DS
QUALIFIED DIM(10)
name
50A
parts
LIKEDS(items)
*-----------------------------------------------------------------*
* Define prototypes for called procedures c_proc and switch
*-----------------------------------------------------------------*
D c_proc
PR
*
EXTPROC(c_proc)
D
size
10U 0 VALUE
D
inzval
1A
CONST
D Switch
PR
D
Parm
1A
*-----------------------------------------------------------------*
* Define parameters for non-prototyped call
*
PARM1 is used when calling RPGPROG program.
*-----------------------------------------------------------------*
D PARM1
S
4P 3 INZ(6.666)
D EXPORTFLD
S
6A
INZ(export) EXPORT
Figure 131. Source for Module DBGEX (Part 2 of 4). DBGEX is the main module of the
program DEBUGEX.
281
*=================================================================*
* Now the operation to modify values or call other objects.
*=================================================================*
*-----------------------------------------------------------------*
* Move as to the data structure DS2. After the move, the
* first occurrence of DS2 contains 10 character as.
*-----------------------------------------------------------------*
C
MOVE
*ALLa
DS2
*-----------------------------------------------------------------*
* Change the occurrence of DS2 to 2 and move bs to DS2,
* making the first 10 bytes as and the second 10 bytes bs.
*-----------------------------------------------------------------*
C
2
OCCUR
DS2
C
MOVE
*ALLb
DS2
*-----------------------------------------------------------------*
* Fld1a is an overlay field of Fld1. Since Fld1 is initialized
* to ABCDE, the value of Fld1a(1) is A. After the
* following MOVE operation, the value of Fld1a(1) is 1.
*-----------------------------------------------------------------*
C
MOVE
1
Fld1a(1)
*-----------------------------------------------------------------*
* Call the program RPGPGM, which is a separate program object.
*-----------------------------------------------------------------*
C
Plist1
PLIST
C
PARM
Parm1
C
CALL
RPGPGM
Plist1
*-----------------------------------------------------------------*
* Call c_proc, which imports ExportFld from the main procedure.
*-----------------------------------------------------------------*
C
EVAL
SpcPtr = c_proc(SpcSiz : P)
*-----------------------------------------------------------------*
* Call a local subprocedure Switch, which reverses the value of
* an indicator.
*-----------------------------------------------------------------*
C
EVAL
*IN10 = 0
C
CALLP
Switch(*in10)
Figure 131. Source for Module DBGEX (Part 3 of 4). DBGEX is the main module of the
program DEBUGEX.
282
*-----------------------------------------------------------------*
* After the following SETON operation, *IN02 = 1.
*-----------------------------------------------------------------*
C
SETON
020406
C
IF
*IN02 = 1
C
MOVE
1994-09-30 BigDate
C
ENDIF
*-----------------------------------------------------------------*
* Put a new value in the second cell of Arry.
*-----------------------------------------------------------------*
C
MOVE
4
Arry
*-----------------------------------------------------------------*
* Now start a formatted dump and return, by setting on LR.
*-----------------------------------------------------------------*
C
DUMP
C
SETON
LR
*=================================================================*
* Define the subprocedure Switch.
*=================================================================*
P Switch
B
D Switch
PI
D
Parm
1A
*-----------------------------------------------------------------*
* Define a local variable for debugging purposes.
*-----------------------------------------------------------------*
D Local
S
5A
INZ(aaaaa)
C
IF
Parm = 1
C
EVAL
Parm = 0
C
ELSE
C
EVAL
Parm = 1
C
ENDIF
P Switch
E
*=================================================================*
* Compile-time data section for Table.
*
*=================================================================*
**
aaa
bbb
ccc
Figure 131. Source for Module DBGEX (Part 4 of 4). DBGEX is the main module of the
program DEBUGEX.
*=================================================================*
* RPGPGM - Program called by DEBUGEX to illustrate the STEP
*
*
functions of the ILE source debugger.
*
*
*
* This program receives a parameter InputParm from DEBUGEX,
*
* displays it, then returns.
*
*=================================================================*
D InputParm
S
4P 3
C
*ENTRY
PLIST
C
PARM
InputParm
C
InputParm
DSPLY
C
SETON
LR
Figure 132. Source for OPM Program RPGPGM
283
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
extern char EXPORTFLD[6];
char *c_proc(unsigned int size, char *inzval)
{
char *ptr;
ptr = malloc(size);
memset(ptr, *inzval, size );
printf("import string: %6s.\n",EXPORTFLD);
return(ptr);
}
Figure 133. Source for C Procedure cproc. cproc is called by DBGEX.
284
285
*STATUS
*NOTIFY
Function Check
Indicates that one of the three previous exceptions occurred and
was not handled.
Exception messages are associated with call stack entries. Each call stack entry is in
turn associated with a list of exception handlers defined for that entry. (See The
Call Stack on page 135 for further discussion of a call stack.)
Figure 134 on page 287 shows a call stack where an OPM program calls an
ILEprogram consisting of several modules and therefore several procedures. Refer
to this figure in the discussions which follow.
In general, when an exception occurs, the handlers associated with the call stack
entry are given a chance to handle the exception. If the exception is not handled by
any of the handlers on the list then it is considered to be unhandled, at which
point the following default actions are taken for the unhandled exception:
1. If the exception is a function check, the call stack entry is removed from the
stack.
2. The exception is moved (percolated) to the previous call stack entry.
3. The exception handling process is restarted for this call stack entry.
The action of allowing the previous call stack entry to handle an exception is
referred to as percolation. Percolation continues until the exception is handled, or
until the control boundary is reached. A control boundary is a call stack entry for
which the immediately preceding call stack entry is in a different activation group
or is an OPM program. In Figure 134 on page 287 Procedure P1 is the control
boundary.
286
Call Stack
OPM
Program A
Activation
ILE
Proc. P1
Percolate
Unhandled
Exception
ILE
Proc. P2
Exception
Handlers
for P2
ILE
Proc. P3
exception
occurs
for P3
Pass 2
Call Stack
OPM
Program A
Sending
Terminating
Exception CEE9901
Activation
ILE
Proc. P1
Percolate
Function
Check
(CPF9999)
ILE
Proc. P2
Exception
Handlers
for P2
ILE
Proc. P3
exception
occurs
for P3
In OPM, the exception message is associated with the program which is active on
the call stack. If the exception is not handled by the associated exception handlers,
then a function check is sent to the same call stack entry which received the
287
#
#
#
#
#
#
When an exception occurs within a cycle-main procedure ILE RPG does the
following:
1. If an error indicator is present on the calculation specification and the exception
is one that is expected for that operation:
a. The indicator is set on
b. The exception is handled
c. Control resumes with the next ILE RPG operation.
288
#
#
#
#
#
#
#
#
289
reached, then the subprocedure will end abnormally and RNX9001 will be
signalled to the caller of the subprocedure.
v If there is no *PSSR and a function check occurs, the procedure is removed from
the call stack and the exception is percolated to the caller.
v Since an inquiry message is never issued for an error in a subprocedure, you do
not have access to the 'Retry' function available for some I/O errors. If you
expect record-lock errors in a subprocedure, you should code an error indicator
or an 'E' extender and check if the status is related to a record being locked.
#
#
Note that the PSDS and INFDS for global files have module scope. Both main
procedures and subprocedures can access them.
TIP
A *PSSR is local to the procedure in which it is coded; therefore, to have a
common error routine, you can code a procedure to handle the error and call
the procedure from each local *PSSR.
290
Nested Exceptions
Exceptions can be nested. A nested exception is an exception that occurs while
another exception is being handled. When this happens, the processing of the first
exception is temporarily suspended. Exception handling begins again with the
most recently generated exception.
Unhandled Exceptions
An unhandled exception is one that has not been handled by an exception handler
associated with the call stack entry that first received the exception. When an
exception is unhandled, one of the following actions occurs:
#
#
#
#
#
#
#
#
#
#
#
291
Percolate
Unhandled
Exception
Procedure PRC1
CALL PRC2
Procedure PRC2
-1 SUBST
RNX0100 issued
#
#
#
#
#
#
292
3. The CALL operation code in PRC1 does not have an error indicator coded.
4. No RPG exception handlers have been coded in PRC2. That is, there is no error
indicator, no active MONITOR group, and no *PSSR error subroutine.
5. PRC2 has a pointer address error.
When PGM1 calls PGM2, a pointer error occurs because the basing pointer is
defined as null. Consequently, MCH1306 is generated. A function check occurs
when PRC2 tries to percolate the exception past the control boundary. Figure 136
depicts this scenario and the events which occur.
PASS 1
Call Stack
Percolate
MCH3601
Procedure PRC1
CALL PRC2
Procedure PRC2
PASS 2
Call Stack
Percolate
CPF9999
Procedure PRC1
CALL PRC2
Procedure PRC2
293
Optimization Considerations
While running a *FULL optimized program, the optimizer may keep frequently
used values in machine registers and restore them to storage only at predefined
points during normal program processing. Exception handling may break this
normal processing and consequently program variables contained in registers may
not be returned to their assigned storage locations.
Specifically, variables may not contain their current values if an exception occurs
and you recover from it using one of:
v Monitor group
v *PSSR error subroutine
v INFSR error subroutine
v User-defined exception handler
v The Go ('G') option from an inquiry message.
v The Retry ('R') option from an inquiry message.
ILE RPG automatically defines indicators such that they contain their current
values even with full optimization. To ensure that the content of fields or data
structures contain their correct (current) values, specify the NOOPT keyword on
the appropriate Definition specification.
For more information on the NOOPT keyword, see IBM Rational Development Studio
for i: ILE RPG Reference. For more information on optimization, see Changing the
Optimization Level on page 92.
294
Note: If an error indicator or and 'E' extender is coded on an operation, but the
error which occurs is not related to the operation (for example, an
array-index error on a CHAIN operation), any error indicator or 'E' extender
would be ignored. The error would be treated like any other program error.
To enable the RPG error indicator handler, you specify an error indicator in
positions 73 and 74 for the operation codes listed in Table 42 (except for CALLP). If
an exception occurs on the operation, the indicator is set on, the appropriate data
structure (PSDS or INFDS) is updated, and control returns to the next sequential
instruction. You can then test the indicator to determine what action to take.
To enable the 'E' operation code extender handler, you specify an 'E' (or 'e') with
any of the operation codes in Table 42. Coding the 'E' extender affects the value
returned by the built-in functions %ERROR and %STATUS for exceptions. Before
the operation begins, the value returned by these built-in functions is set to zero. If
an exception occurs on the operation, the return values for these built-in functions
are updated accordingly, the appropriate data structure (PSDS or INFDS) is
updated, and control returns to the next sequential instruction. You can then use
these built-in functions to test the returned values and determine what action to
take.
Table 42. Operation Codes Allowing Extender 'E' or an Error Indicator in Positions 73-74
ACQ (e)
ADDDUR (e)
1
ALLOC (e)
CALL (e)
CHAIN (e n)
CHECK (e)
CALLB(d e)
CALLP (e m/r)
CHECKR (e)
CLOSE (e)
COMMIT (e)
DEALLOC(e/n)
DELETE (e)
DSPLY (e)
EXFMT (e)
EXTRCT (e)
FEOD (e)
IN (e)
NEXT (e)
OCCUR (e)
OPEN (e)
OUT (e)
POST (e)
READ (e n)
READC (e)
READE (e n)
READP (e n)
READPE (e n)
REALLOC (e)
REL (e)
RESET (e)
ROLBK (e)
SCAN (e)
SETGT (e)
SETLL (e)
SUBDUR (e)
SUBST (e p)
TEST (e d/t/z)
UNLOCK (e)
UPDATE (e)
WRITE (e)
XLATE (e p)
Notes:
1. CALLP (e m/r) is an extended Factor-2 operation code and cannot have an error
indictator. However, program status and error conditions can be determined by
specifying the 'e' extender with this operation code.
When you specify an error indicator or an 'E' extender on an operation code, you
can explicitly call a file error subroutine (INFSR) or a program error subroutine
(*PSSR) with the EXSR operation. If either INFSR or *PSSR is explicitly called by
the EXSR operation and Factor 2 of the ENDSR operation is blank or the field
specified has a value of blank, control returns to the next sequential instruction
following the EXSR operation.
295
If all the statements in the MONITOR block are processed without errors, control
passes to the statement following the ENDMON statement.
The MONITOR group can be specified anywhere in calculations. It can be nested
within IF, DO, SELECT, or other MONITOR groups. The IF, DO, and SELECT
groups can be nested within MONITOR groups.
If a MONITOR group is nested within another MONITOR group, the innermost
group is considered first when an error occurs. If that MONITOR group does not
handle the error condition, the next group is considered.
Level indicators can be used on the MONITOR operation, to indicate that the
MONITOR group is part of total calculations. For documentation purposes, you
can also specify a level indicator on an ON-ERROR or ENDMON operation but
this level indicator will be ignored.
Conditioning indicators can be used on the MONITOR statement. If they are not
satisfied, control passes immediately to the statement following the ENDMON
statement of the MONITOR group. Conditioning indicators cannot be used on
ON-ERROR operations individually.
If a MONITOR block contains a call to a subprocedure, and the subprocedure has
an error, the subprocedure's error handling will take precedence. For example, if
the subprocedure has a *PSSR subroutine, it will get called. The MONITOR group
containing the call will only be considered if the subprocedure fails to handle the
error and the call fails with the error-in-call status of 00202.
The MONITOR group does handle errors that occur in a subroutine. If the
subroutine contains its own MONITOR groups, they are considered first.
Branching operations are not allowed within a MONITOR block, but are allowed
within an ON-ERROR block.
A LEAVE or ITER operation within a MONITOR block applies to any active DO
group that contains the MONITOR block. A LEAVESR or RETURN operation
within a MONITOR block applies to any subroutine, subprocedure, or procedure
that contains the MONITOR block.
On each ON-ERROR statment, you specify which error conditions the ON-ERROR
group handles. You can specify any combination of the following, separated by
colons:
nnnnn
A status code
*PROGRAM
*FILE
*ALL
Status codes outside the range of 00100 to 09999, for example codes from 0 to 99,
are not monitored for. You cannot specify these values for an ON-ERROR group.
You also cannot specify any status codes that are not valid for the particular
version of the compiler being used.
296
If the same status code is covered by more than one ON-ERROR group, only the
first one is used. For this reason, you should specify special values such as *ALL
after the specific status codes.
Any errors that occur within an ON-ERROR group are not handled by the
MONITOR group. To handle errors, you can specify a MONITOR group within an
ON-ERROR group.
*
*
*
*
*
*
*
*
*
*
*
*
*
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
ENDIF
ON-ERROR
1211
... handle file-not-open
ON-ERROR
*FILE
... handle other file errors
ON-ERROR
00100 : 00121
... handle string error and array-index error
ON-ERROR
... handle all other errors
ENDMON
v You can control the point where processing resumes in a cycle-main procedure
by specifying a value in Factor 2 of the ENDSR operation of the subroutine. In a
subprocedure, factor 2 of the ENDSR must be blank. Use either a GOTO or a
RETURN operation prior to the ENDSR operation to prevent the subprocedure
from ending abnormally.
297
v If an error subroutine is called, the RPG error subroutine handler has already
handled the exception. Thus, the call to the error subroutine reflects a return to
program processing. If an exception occurs while the subroutine is running, the
subroutine is called again. The procedure will loop unless you code the
subroutine to avoid this problem.
To see how to code an error subroutine to avoid such a loop, see Avoiding a
Loop in an Error Subroutine on page 304.
A file error subroutine can handle errors in more than one file.
The following restrictions apply:
v If a file exception occurs during the start or end of a program, (for example, on
an implicit open at the start of the cycle) control passes to the ILE RPG default
exception handler, and not to the error subroutine handler. Consequently, the file
error subroutine will not be processed.
v If an error occurs that is not related to the operation (for example, an
array-index error on a CHAIN operation), then any INFSR error subroutine
would be ignored. The error would be treated like any other program error.
v An INFSR cannot handle errors in a global file used by a subprocedure.
To add a file error subroutine to your program, you do the following steps:
1. Enter the name of the subroutine after the keyword INFSR on a File
Description specification. The subroutine name can be *PSSR, which indicates
that the program error subroutine is given control for the exception on this file.
2. Optionally identify the file information data structure on a File Description
specification using the keyword INFDS.
3. Enter a BEGSR operation where the Factor 1 entry contains the same
subroutine name that is specified for the keyword INFSR.
4. Identify a return point, if any, and code it on the ENDSR operation in the
subroutine. For a discussion of the valid entries for Factor 2, see Specifying a
Return Point in the ENDSR Operation on page 305. A Factor 2 is not allowed
for a file error subroutine in a subprocedure.
#
#
#
#
5. Code the rest of the file error subroutine. While any of the ILE RPG compiler
operations can be used in the file error subroutine, it is not recommended that
you use I/O operations to the same file that got the error. The ENDSR
operation must be the last specification for the file error subroutine.
Figure 138 on page 299 shows an example of exception handling using an INFSR
error subroutine. The program TRNSUPDT is a simple inventory update program.
It uses a transaction file TRANSACT to update a master inventory file PRDMAS. If
an I/O error occurs, then the INFSR error subroutine is called. If it is a record lock
error, then the record is written to a backlog file. Otherwise, an inquiry message is
issued.
298
Note that the File specification for PRDMAS identifies both the INFDS and
identifies the INFSR to be associated with it.
The following is done for each record in the TRANSACT file:
1. The appropriate record in the product master file is located using the
transaction product number.
2. If the record is found, then the quantity of the inventory is updated.
3. If an error occurs on the UPDATE operation, then control is passed to the
INFSR error subroutine.
4. If the record is not found, then the product number is written to an error
report.
*=================================================================*
* TRNSUPDT: This program is a simple inventory update program.
*
* The transaction file (TRANSACT) is processed consecutively.
*
* The product number in the transaction is used as key to access *
* the master file (PRDMAS) randomly.
*
* 1. If the record is found, the quantity of the inventory will
*
*
be updated.
*
* 2. If the record is not found, an error will be printed on a
*
*
report.
*
* 3. If the record is currently locked, the transaction will be
*
*
written to a transaction back log file which will be
*
*
processed later.
*
* 4. Any other unexpected error will cause a runtime error
*
*
message.
*
*=================================================================*
*-----------------------------------------------------------------*
* Define the files:
*
*
1) PRDMAS
- Product master file
*
*
2) TRANSACT
- Transaction file
*
*
3) TRNBACKLG
- Transaction backlog file
*
*
2) PRINT
- Error report.
*
*-----------------------------------------------------------------*
FPRDMAS
UF
E
K DISK
F
INFSR(PrdInfsr)
F
INFDS(PrdInfds)
FTRANSACT IP
E
DISK
FTRNBACKLG O
E
DISK
FPRINT
O
F
80
PRINTER
*-----------------------------------------------------------------*
* Define the file information data structure for file PRDMAS.
*
* The *STATUS field is used to determine what action to take.
*
*-----------------------------------------------------------------*
D PrdInfds
DS
D PrdStatus
*STATUS
*-----------------------------------------------------------------*
* List of expected exceptions.
*
*-----------------------------------------------------------------*
D ErrRecLock
C
CONST(1218)
Figure 138. Example of File Exception Handling (Part 1 of 2)
299
*-----------------------------------------------------------------*
* Access the product master file using the transaction product
*
* number.
*
*-----------------------------------------------------------------*
C
TRNPRDNO
CHAIN
PRDREC
10
*-----------------------------------------------------------------*
* If the record is found, update the quantity in the master file. *
*-----------------------------------------------------------------*
C
IF
NOT *IN10
C
SUB
TRNQTY
PRDQTY
C
UPDATE
PRDREC
*-----------------------------------------------------------------*
* If the record is not found, write to the error report
*
*-----------------------------------------------------------------*
C
ELSE
C
EXCEPT
NOTFOUND
C
ENDIF
C
SETON
LR
*-----------------------------------------------------------------*
* Error handling routine.
*
*-----------------------------------------------------------------*
C
PrdInfsr
BEGSR
*-----------------------------------------------------------------*
* If the master record is currently locked, write the transaction *
* record to the back log file and skip to next transaction.
*
*-----------------------------------------------------------------*
C
PrdStatus
DSPLY
C
IF
(PrdStatus = ErrRecLock)
C
WRITE
TRNBREC
C
MOVE
*GETIN
ReturnPt
6
*-----------------------------------------------------------------*
* If unexpected error occurs, cause inquiry message to be issued. *
*-----------------------------------------------------------------*
C
ELSE
C
MOVE
*BLANK
ReturnPt
C
ENDIF
C
ENDSR
ReturnPt
*-----------------------------------------------------------------*
* Error report format.
*
*-----------------------------------------------------------------*
OPRINT
E
NOTFOUND
O
TRNPRDNO
O
29 NOT IN PRDMAS FILE
Figure 138. Example of File Exception Handling (Part 2 of 2)
300
301
*-----------------------------------------------------------------*
* Define relevant parts of program status data structure
*
*-----------------------------------------------------------------*
D Psds
SDS
D Loc
*ROUTINE
D Err
*STATUS
D Parms
*PARMS
D Name
*PROC
*-----------------------------------------------------------------*
* BODY OF CODE GOES HERE
* An error occurs when division by zero takes place.
* Control is passed to the *PSSR subroutine.
*-----------------------------------------------------------------*
*=================================================================*
* *PSSR: Error Subroutine for the main procedure. We check for a
*
division by zero error, by checking if the status is
*
102. If it is, we add 1 to the divisor and continue
*
by moving *GETIN to ReturnPt.
*=================================================================*
C
*PSSR
BEGSR
C
IF
Err = 102
C
ADD
1
Divisor
C
MOVE
*GETIN
ReturnPt
6
*-----------------------------------------------------------------*
*
An unexpected error has occurred, and so we move
*
*CANCL to ReturnPt to end the procedure.
*-----------------------------------------------------------------*
C
ELSE
C
MOVE
*CANCL
ReturnPt
C
ENDIF
C
ENDSR
ReturnPt
Figure 139. Example of *PSSR Subroutine in Cycle-Main Procedure
302
*-----------------------------------------------------------------*
* Start of subprocedure definition
*-----------------------------------------------------------------*
P SubProc
B
D SubProc
PI
5P 0
...
*-----------------------------------------------------------------*
* Body of code goes here including recovery code.
*-----------------------------------------------------------------*
C
TryAgain
TAG
C
X
DIV
Divisor
Result
C
Return
Result
*-----------------------------------------------------------------*
* An error occurs when division by zero takes place.
* Control is passed to the *PSSR subroutine.
*-----------------------------------------------------------------*
C
*PSSR
BEGSR
*-----------------------------------------------------------------*
* If this is a divide-by-zero error, add 1 to the divisor
* and try again
*-----------------------------------------------------------------*
C
IF
Err = 102
C
ADD
1
Divisor
C
GOTO
TryAgain
C
ENDIF
*-----------------------------------------------------------------*
* If control reaches ENDSR, the procedure will fail
*-----------------------------------------------------------------*
C
ENDSR
P
E
Figure 140. Example of Subprocedure *PSSR Subroutine with GOTO
*-----------------------------------------------------------------*
* Start of subprocedure definition
*-----------------------------------------------------------------*
P SubProc
B
D SubProc
PI
5P 0
...
*-----------------------------------------------------------------*
* Body of code goes here including division operation.
*-----------------------------------------------------------------*
C
X
DIV
Divisor
Result
C
Return
Result
*-----------------------------------------------------------------*
* An error occurs when division by zero takes place.
* Control is passed to the *PSSR subroutine.
*-----------------------------------------------------------------*
C
*PSSR
BEGSR
*-----------------------------------------------------------------*
* If this is a divide-by-zero error, return 0 from the subprocedure
*-----------------------------------------------------------------*
C
IF
Err = 102
C
RETURN
0
C
ENDIF
*-----------------------------------------------------------------*
* If control reaches ENDSR, the procedure will fail
*-----------------------------------------------------------------*
C
ENDSR
P
E
Figure 141. Example of Subprocedure *PSSR Subroutine with RETURN
303
*=================================================================*
* NOLOOP: Show how to avoid recursion in a *PSSR subroutine.
*
*=================================================================*
*-----------------------------------------------------------------*
* Array that will be used to cause an error
*
*-----------------------------------------------------------------*
D Arr1
S
10A
DIM(5)
*-----------------------------------------------------------------*
* Generate an array out of bounds error to pass control to *PSSR. *
*-----------------------------------------------------------------*
C
Z-ADD
-1
Neg1
5 0
C
MOVE
Arr1(Neg1)
Arr1(Neg1)
C
MOVE
*ON
*INLR
*=================================================================*
* *PSSR: Error Subroutine for the procedure. We use the
*
*
variable InPssr to detect recursion in the PSSR.
*
*
If we detect recursion, then we *CANCL the procedure.
*
*=================================================================*
C
*PSSR
BEGSR
C
IF
InPssr = 1
C
MOVE
*CANCL
ReturnPt
6
C
Z-ADD
0
InPssr
1 0
C
ELSE
C
Z-ADD
1
InPssr
*
*
*
We now generate another error in the PSSR to see
*
*
how the subroutine cancels the procedure.
*
*
*
C
MOVE
Arr1(Neg1)
Arr1(Neg1)
*
*
*
Note that the next two operations will not be
*
*
processed if Neg1 is still negative.
*
*
*
C
MOVE
*GETIN
ReturnPt
C
Z-ADD
0
InPssr
C
ENDIF
C
ENDSR
ReturnPt
Figure 142. Avoiding a Loop in an Error Subroutine
To create the program and start debugging it, using the source in Figure 142, type:
CRTBNDRPG PGM(MYLIB/NOLOOP) DBGVIEW(*SOURCE)
STRDBG PGM(MYLIB/NOLOOP)
304
Set a break point on the BEGSR line of the *PSSR subroutine so you can step
through the *PSSR subroutine.
When you call the program, the following occurs:
1. An exception occurs when the program tries to do a MOVE operation on an
array using a negative index. Control is passed to the *PSSR.
2. Since this is the first time through the *PSSR, the variable In_Pssr is not already
set on. To prevent a future loop, the variable In_Pssr is set on.
3. Processing continues within the *PSSR with the MOVE after the ELSE. Again,
an exception occurs and so processing of the *PSSR begins anew.
4. This time through, the variable In_Pssr is already set to 1. Since this indicates
that the subroutine is in a loop, the procedure is canceled by setting the
ReturnPt field to *CANCL.
5. The ENDSR operation receives control, and the procedure is canceled.
The approach used here to avoid looping can also be used within an INFSR error
subroutine.
#
#
#
#
Note: If the return points are specified as literals, they must be enclosed in
apostrophes and entered in uppercase (for example, *DETL, not *detl). If
they are specified in fields or array elements, the value must be left-adjusted
in the field or array element.
*DETL
*GETIN
*TOTC
*TOTL
*OFL
*DETC
*CANCL
#
#
#
#
Blanks
Return control to the ILE RPG default exception handler. This will
occur when Factor 2 is a value of blanks and when Factor 2 is not
specified. If the subroutine was called by the EXSR operation and
Factor 2 is blank, control returns to the next sequential instruction.
After the ENDSR operation of the INFSR or the *PSSR subroutine is run, the ILE
RPG compiler resets the field or array element specified in Factor 2 to blanks.
Because Factor 2 is set to blanks, you can specify the return point within the
subroutine that is best suited for the exception that occurred.
If this field contains blanks at the end of the subroutine, the ILE RPG default
exception handler receives control following the running of the subroutine, unless
the INFSR or the *PSSR subroutine was called by the EXSR operation. If the
305
subroutine was called by the EXSR operation and Factor 2 of the ENDSR operation
is blank, control returns to the next sequential instruction following the EXSR
operation.
Note: You cannot specify a factor 2 entry for an ENDSR in a subprocedure. If you
want to resume processing in the subprocedure, you have to use a GOTO
operation to a TAG in the body of the subprocedure. Alternatively, you can
code a RETURN operation in the *PSSR. The subprocedure will then return
to the caller.
For information on how to use ILE condition handlers, refer to ILE Concepts.
306
*=================================================================*
* RPGHDLR: RPG exception handling procedure.
*
*
This procedure does the following:
*
*
Handles the exception if it is the RPG
*
*
out of bounds error (RNX0100)
*
*
otherwise
*
*
percolates the exception
*
*
It also prints out what it has done.
*
*
*
* Note:
This is the exception handling procedure for the
*
*
SHOWERR procedure.
*
*=================================================================*
FQSYSPRT
O
F 132
PRINTER
D RPGHDLR
D Parm1
D Parm2
D Parm3
D Parm4
PR
LIKE(CondTok)
*
10I 0
LIKE(CondTok)
*-----------------------------------------------------------------*
* Procedure parameters
*
* 1. Input: Condition token structure
*
* 2. Input: Pointer to communication area containing
*
*
a. A pointer to the PSDS of the procedure being handled *
*
b. An indicator telling whether a string error is valid *
* 3. Output: Code identifying actions to be performed on the
*
*
exception
*
* 4. Output: New condition if we decide to promote the
*
*
condition. Since this handler only resumes and
*
*
percolates, we will ignore this parameter.
*
*-----------------------------------------------------------------*
D RPGHDLR
PI
D InCondTok
LIKE(CondTok)
D pCommArea
*
D Action
10I 0
D OutCondTok
LIKE(CondTok)
Figure 143. Source for Condition Handler for Out-of-Bounds Substring Error (Part 1 of 2)
307
D CondTok
D MsgSev
D MsgNo
D
D MsgPrefix
D MsgKey
DS
D CommArea
D
pPSDS
D
AllowError
DS
D PassedPSDS
D
ProcName
DS
BASED(pCondTok)
5I 0
2A
1A
3A
4A
BASED(pCommArea)
*
1N
BASED(pPSDS)
1
10
*
* Action codes are:
*
D Resume
C
D Percolate
C
10
20
*-----------------------------------------------------------------*
*
Point to the input condition token
*
*-----------------------------------------------------------------*
C
EVAL
pCondTok = %ADDR(InCondTok)
*-----------------------------------------------------------------*
*
If substring error, then handle else percolate.
*
*
Note that the message number value (MsgNo) is in hex.
*
*-----------------------------------------------------------------*
C
EXCEPT
C
IF
MsgPrefix = RNX AND
C
MsgNo
= X0100 AND
C
AllowError = 1
C
EXCEPT
Handling
C
EVAL
Action
= Resume
C
ELSE
C
EXCEPT
Perclating
C
EVAL
Action
= Percolate
C
ENDIF
C
RETURN
*=================================================================*
* Procedure Output
*
*=================================================================*
OQSYSPRT
E
O
HDLR: In Handler for
O
ProcName
OQSYSPRT
E
Handling
O
HDLR: Handling...
OQSYSPRT
E
Perclating
O
HDLR: Percolating...
Figure 143. Source for Condition Handler for Out-of-Bounds Substring Error (Part 2 of 2)
Figure 144 on page 310 shows the source for the procedure SHOWERR, in which
the condition handler RPGHDLR is registered.
The procedure parameters include a procedure pointer to RPGHDLR and a pointer
to the communication area which contains a pointer to the module's PSDS and an
indicator telling whether the out-of-bounds string error can be ignored. In
addition, it requires a definition for the error-prone array ARR1, and identification
of the parameter lists used by the ILE bindable APIs CEEHDLR and CEEHDLU.
The basic logic of the program is as follows:
308
309
*=================================================================*
* SHOWERR:
Show exception handling using a user-defined
*
*
exception handler.
*
*=================================================================*
FQSYSPRT
O
F 132
PRINTER
*-----------------------------------------------------------------*
* The following are the parameter definitions for the CEEHDLR
*
* API. The first is the procedure pointer to the
*
* procedure which will handle the exception. The second
*
* is a pointer to a communication area which will be passed
*
* to the exception handling procedure. In this example, this
*
* area will contain a pointer to the PSDS of this module, and
*
* an indicator telling whether an error is allowed.
*
*
*
* We should make sure this program (SHOWERR) does not ignore any *
* handled errors, so we will check the Error indicator after
*
* any operation that might cause an error that RPGHDLR will
*
* "allow". We will also check at the end of the program to make *
* sure we didnt miss any errors.
*
*-----------------------------------------------------------------*
D pConHdlr
S
*
PROCPTR
D
INZ(%paddr(RPGHDLR))
*-----------------------------------------------------------------*
* Communication area
*
*-----------------------------------------------------------------*
D CommArea
DS
NOOPT
D
pPsds
*
INZ(%ADDR(DSPsds))
D
AllowError
1N
INZ(0)
*-----------------------------------------------------------------*
* PSDS
*
*-----------------------------------------------------------------*
D DSPsds
SDS
NOOPT
D
ProcName
*PROC
*-----------------------------------------------------------------*
* Variables that will be used to cause errors
*
*-----------------------------------------------------------------*
D Arr1
S
10A
DIM(5)
D Num
S
5P 0
*-----------------------------------------------------------------*
* CEEHDLR Interface
*
*-----------------------------------------------------------------*
D CEEHDLR
PR
D
pConHdlr
*
PROCPTR
D
CommArea
*
CONST
D
Feedback
12A
OPTIONS(*OMIT)
*-----------------------------------------------------------------*
* CEEHDLU Interface
*
*-----------------------------------------------------------------*
D CEEHDLU
PR
D
pConHdlr
*
PROCPTR
D
Feedback
12A
OPTIONS(*OMIT)
Figure 144. Source for Registering a Condition Handler (Part 1 of 3)
310
*-----------------------------------------------------------------*
* Register the handler and generate errors
*
*-----------------------------------------------------------------*
C
EXSR
RegHndlr
*-----------------------------------------------------------------*
*
Generate a substring error
*
*
This is an "allowed" error for this example (RPGHDLR
*
*
handles the exception, allowing control to return to the
*
*
next instruction after the error).
*
*
RPGHDLR will not allow the error unless the "AllowError"
*
*
indicator is set on. This ensures that if, for example,
*
*
a SCAN operation is added to SHOWERR later, RPGHDLR will
*
*
not by default allow it to have an error.
*
*-----------------------------------------------------------------*
C
Z-ADD
-1
Num
C
EVAL
AllowError = 1
C
Num
SUBST
Hello
Examp
10
C
EVAL
AllowError = 0
*-----------------------------------------------------------------*
*
The exception was handled by the handler and control
*
*
resumes here.
*
*-----------------------------------------------------------------*
C
EXCEPT
ImBack
*-----------------------------------------------------------------*
*
Generate an array out of bounds error
*
*
This is not an "expected" error for this example.
*
*-----------------------------------------------------------------*
C
Z-ADD
-1
Num
C
MOVE
Arr1(Num)
Arr1(Num)
*-----------------------------------------------------------------*
*
The exception was not handled by the handler, so,
*
*
control does not return here. The exception is
*
*
percolated and control resumes in the *PSSR.
*
*-----------------------------------------------------------------*
*-----------------------------------------------------------------*
*
Deregister the handler
*
*
Note: If an exception occurs before the handler is
*
*
deregistered, it will be automatically deregistered
*
*
when the procedure is cancelled.
*
*-----------------------------------------------------------------*
C
EXSR
DeRegHndlr
C
SETON
LR
*=================================================================*
* RegHdlr - Call the API to register the Handler
*
*=================================================================*
C
RegHndlr
BEGSR
C
CALLP
CEEHDLR(pConHdlr : %ADDR(CommArea) : *OMIT)
C
ENDSR
*=================================================================*
* DeRegHndlr - Call the API to unregister the Handler
*
*=================================================================*
C
DeRegHndlr
BEGSR
C
CALLP
CEEHDLU(pConHdlr : *OMIT)
C
ENDSR
Figure 144. Source for Registering a Condition Handler (Part 2 of 3)
311
*=================================================================*
* *PSSR: Error Subroutine for the procedure
*
*=================================================================*
C
*PSSR
BEGSR
C
EXCEPT
InPssr
C
EXCEPT
Cancelling
C
ENDSR
*CANCL
*=================================================================*
* Procedure Output
*
*=================================================================*
OQSYSPRT
E
ImBack
O
Im Back
OQSYSPRT
E
InPssr
O
In PSSR
OQSYSPRT
E
Cancelling
O
Cancelling...
Figure 144. Source for Registering a Condition Handler (Part 3 of 3)
2. To create the procedure SHOWERR, using the source shown in Figure 144 on
page 310, type:
CRTRPGMOD MODULE(MYLIB/SHOWERR)
312
see the CL and APIs section of the Programming category in the System i
Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.
#
#
#
Figure 145 shows an example of enabling and coding a cancel handler for a
subprocedure. (Cancel handlers can also be enabled for cycle-main procedures in
the same way.)
*----------------------------------------------------------------* Define the prototype for the cancel handler. This procedure is
* a local procedure.
*----------------------------------------------------------------D CanHdlr
PR
D
pMsg
*
*----------------------------------------------------------------* Define the prototype for a subprocedure to enable the cancel
* handler.
*----------------------------------------------------------------D Enabler
PR
*----------------------------------------------------------------* Define the prototype for a subprocedure to call Enabler
*----------------------------------------------------------------D SubProc
PR
*----------------------------------------------------------------* Main procedure. Call SubProc three times.
*----------------------------------------------------------------C
CALLP
SubProc
C
CALLP
SubProc
C
CALLP
SubProc
C
SETON
LR
*----------------------------------------------------------------* Procedure SubProc. Call Enabler. Since this call will fail,
* define a local *PSSR subroutine to handle the error.
*----------------------------------------------------------------P SubProc
B
C
CALLP
Enabler
*----------------------------------------------------------------* The PSSR has a RETURN operation, so the call from the main
* procedure to SubProc will not fail.
*----------------------------------------------------------------C
*PSSR
BEGSR
C
Subproc PSSRDSPLY
C
RETURN
C
ENDSR
P SubProc
E
Figure 145. Enabling and Coding a Cancel Handler for a Subprocedure (Part 1 of 3)
313
314
The following is the output from program CANHDLR. Note that the *PSSR of the
procedure SubProc is called three times but the cancel handler is only called twice
because it was disabled before the third error.
DSPLY
DSPLY
DSPLY
DSPLY
DSPLY
Cancel Hdlr
Subproc PSSR
Cancel Hdlr
Subproc PSSR
Subproc PSSR
Divide by zero
String error
315
1. Ensure that the caller is in a different activation group from the ILE RPG
procedure.
2. Enable an ILE condition handler in the RPG procedure. In the handler, if the
message is one that you want to ignore, indicate that the message should be
handled. Otherwise, indicate that it should be percolated.
You could also make this handler more generic, and have it ignore all messages
with a severity of 0 (information) and 1 (warning).
Figure 147 shows an example of a ILE condition handler that ignores CPF4906.
*---------------------------------------------------------------* Handler definitions
*---------------------------------------------------------------D Action
S
10I 0
D Token
DS
D
MsgSev
5I 0
D
MsgNo
2A
D
1A
D
Prefix
3A
D
4A
*---------------------------------------------------------------* Actions
*---------------------------------------------------------------D Handle
C
10
D Percolate
C
20
*---------------------------------------------------------------* Severities
*---------------------------------------------------------------D Info
C
0
D Warning
C
1
D Error
C
2
D Severe
C
3
D Critical
C
4
C
*ENTRY
PLIST
C
PARM
Token
C
PARM
dummy
1
C
PARM
Action
*---------------------------------------------------------------* If this is CPF4906, handle the notify msg, otherwise percolate
*---------------------------------------------------------------C
IF
Prefix = CPF AND
C
MsgNo = X4906
C
EVAL
Action = Handle
C
ELSE
C
EVAL
Action = Percolate
C
ENDIF
C
RETURN
Figure 147. ILE Condition Handler that Ignores CPF4906
Figure 148 on page 317 shows how you would code the calculations if you
wanted to ignore all status and notify messages. Escape messages and function
checks have a severity of 2 (Error) or higher.
316
317
318
The dump information includes the global data associated with the module.
Depending on whether the cycle-main procedure is active, the global data may not
represent the values assigned during processing of the *INZSR. If a program
consists of more than one procedure, the information in the formatted dump also
reflects information about every procedure that is active at the time of the dump
request. If a procedure is not active, the values of variables in automatic storage
will not be valid. If a procedure has not been called yet, the static storage will not
be initialized yet. If a procedure has been called recursively, only the information
for the most recent invocation will be shown.
There are two occasions when dump data may not be available:
v If the program object was created with debug view *NONE. The dump will
contain only the PSDS, file information, and the *IN indicators.
v If a single variable or structure requires more than 16 MB of dump data. This
typically occurs with variables or structures that are larger than 5 MB.
If you do not want a user to be able to see the values of your program's variables
in a formatted dump, do one of the following:
v Ensure that debug data is not present in the program by removing observability.
v Give the user sufficient authority to run the program, but not to perform the
formatted dump. This can be done by giving *OBJOPR plus *EXECUTE
authority.
319
320
DBGEX2
TEST
MYLIB
DBGEX2
.. .
00202
.....
00000
......
00000088
RPGPGM
MCH
4431
A
B
C
D
E
F
......
MYUSERID
MYUSERID
..
002273
.
.
09/30/1995
*N/A*
*N/A*
.
123095
153438
...
0001
QRPGLESRC
MYLIB
DBGEX2
A
B
C
D
E
F
G
Information about the last file used in the program before an exception or
error occurred. In this case, no files were used.
H
Feedback Areas
321
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
:
:
:
:
:
:
:
:
:
QSYSPRT
YES
NO
00000
OPEN I
*INIT
*INIT
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
SP
QSYSPRT
QSYS
Q501383525
Q04079N002
QSPL
7
80
0
80
PRINTER
66
132
*N/A*
1
60
0
NO
NO
NO
1
NO
NO
Q04079N002
0
NO
1
1
*N
*N
02X
08X
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
:
:
:
:
:
:
:
:
:
:
:
:
0
0
0
0
00X
PRINTER FEEDBACK:
Current Line Number.
Current Page . . . .
Major Return Code. .
Minor Return Code. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
:
:
:
:
1
1
00
00
Output Buffer:
0000 00000000
0020 00000000
0040 00000000
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
00000000
00000000
00000000
00000000
00000000
00000000
0208X
*N
80
80
0
0
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
*
*
*
*
*
*
322
I
This is the file feedback section of the INFDS. Only fields applicable to the
file type are printed. The rest of the INFDS feedback sections are not
dumped, since they are only updated if they have been declared in the
program.
J
This is the file open feedback information for the file. For a description of
the fields, refer to the DB2 Universal Database for iSeries section of the
This is the common I/O feedback information for the file. For a description
of the fields, see the above Web site.
00001B00
00000000
003AC02B
003AC005
003AA024
00000000
F4F0F7F9
000000B0
00000380
A00119FF
CF001CB0
D0060120
00000000
D5F0F0F2
00000140
00000000
000006C0
00000000
01900000
E2D7D8E2
000001C6
06000000
00003033
00000000
00010000
E8E2D7D9
00000280
00000000
00000000
00000000
00000050
E3404040
000002C0
00000000
00000000
00000000
00000000
D8E2E8E2
*
*
*
*
*
*
*
*
*
*
*
&
*
SPQSYSPRT
QSYS*
Q04079N002QSPL
& *
E3404040
40400007
42008400
00000100
00000000
00450045
002F0030
00000000
00000000
D8E2E8E2
00500000
00000000
3C000000
00000000
00450045
00040005
00000000
00000000
40404040
D8F5F0F1
0000D5A4
0005E000
00010001
07A10045
5CD54040
00000000
00000000
4040D8F0
F3F8F3F5
00100000
5CD54040
5CD54040
00450045
40404040
00000001
4040
F4F0F7F9
F2F50000
00000008
40404040
40404040
00700045
40400208
C2200000
D5F0F0F2
00000000
00000000
40400001
40400000
00450045
00000000
00059A00
*SPQSYSPRT
QSYS
Q04079N002*
*QSPL
& Q501383525
*
* &
d
Nu
*
*
*N
*
*
*N
*
*
*
*
*N
*
*
B
*
*
*
00000000
40400000
00000000
00000000
00000000
00000000
00500000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000208
00000000
00000000
00000000
*
**N
*
*
*
00000000
00000000
00000000
00000000
00000000
00000000
*
* 0000
&
*
*
*
*
*
*
*
The common open data path and the feedback areas associated with the file are
included in the dump if you respond to an ILE RPG inquiry message with an F
option.
Data Information
323
324
DS1
OCCURRENCE(1)
FLD1
FLD1A
FLD2
OCCURRENCE(2)
FLD1
FLD1A
FLD2
OCCURRENCE(3)
FLD1
FLD1A
DS
OCCURS(3) R
CHAR(5)
CHAR(1)
(1)
(2)
(3)
(4)
(5)
BIN(5,2)
1BCDE
DIM(5)
1
B
C
D
E
123.45
CHAR(5)
CHAR(1)
(1)
(2)
(3)
(4)
(5)
BIN(5,2)
ABCDE
DIM(5)
A
B
C
D
E
123.45
F1C2C3C4C5X
F1X
C2X
C3X
C4X
C5X
00003039X
C1C2C3C4C5X
C1X
C2X
C3X
C4X
C5X
00003039X
CHAR(5)
ABCDE
C1C2C3C4C5X
CHAR(1)
DIM(5)
(1)
A
C1X
(2)
B
C2X
(3)
C
C3X
(4)
D
C4X
(5)
E
C5X
FLD2
BIN(5,2)
123.45
00003039X
DS2
CHAR(1O)
DIM(2)
S
(1)
aaaaaaaaaa
81818181818181818181X
(2)
bbbbbbbbbb
82828282828282828282X
DS3
DS
T
FIRSTNAME
CHAR(10)
Fred
C6998584404040404040X
LASTNAME
CHAR(10)
Jones
D1969585A24040404040X
TITLE
CHAR(5)
Mr.
D4994B4040X
EXPORTFLD
CHAR(6)
export
85A7979699A3X
FLDNULL
ZONED(3,1)
24.3
F2F4F3X
FLOAT1
FLT(4)
1.234500000000E+007 U
VALUE IN HEX
4B3C5EA8X
FLOAT2
FLT(8)
3.962745000000E+047
VALUE IN HEX
49D15A640A93FCFFX
INT10
INT(10)
-31904
FFFF8360X
INT5
INT(5)
-2046
F802X
NEG_INF
FLT(8)
-HUGE_VAL V
VALUE IN HEX
FFF0000000000000X
NOT_NUM
FLT(4)
*NaN
W
VALUE IN HEX
7FFFFFFFX
NULLPTR
POINTER
SYP:*NULL
PACKED1D0
PACKED(5,2)
-093.40
09340DX
PARM1
PACKED(4,3)
6.666
06666FX
POS_INF
FLT(8)
HUGE_VAL X
VALUE IN HEX
7FF0000000000000X
PROCPTR
POINTER
PRP:A00CA02EC200 Y
SPCPTR
POINTER
SPP:A026FA0100C0
SPCSIZ
BIN(9,0)
000000008.
00000008X
STRING
CHAR(6)
ABCDEF
C1C2C3C4C5C6X
TABLEA
CHAR(3)
DIM(3)
(1)
aaa
818181X
(2)
bbb
828282X
(3)
ccc
838383X
UNSIGNED10
UNS(10)
31904
00007CA0X
UNSIGNED5
UNS(5)
2046
07FEX
ZONEDD3D2
ZONED(3,2)
-3.21
F3F2D1X
Local variables for subprocedure SWITCH: Z
NAME
ATTRIBUTES
VALUE
_QRNL_PSTR_PARM
POINTER
SYP:*NULL
LOCAL
CHAR(5)
0000000000X
PARM
CHAR(1)
NOT ADDRESSABLE
* * * * * E N D O F R P G D U M P * * * * *
L
Optimization level
M
General indicators 1-99 and their current status ('1' is on, '0' is off). Note
that indicators *IN02, *IN04, and *IN06 were not yet set.
N
325
326
O
P
Internally defined fields which contain the null indicators for null-capable
fields.
Q
R
S
T
Data structure subfields are listed in alphabetical order, not in the order in
which they are defined. Gaps in the subfield definitions are not shown.
U
V
W
Stands for 'not a number' indicating that the value is not a valid
floating-point number.
X
Y
The attribute does not differentiate between basing and procedure pointer.
Z
The local data inside subprocedures is listed separately from the main
source section.
327
328
329
Note that it is the file name, not the device name (specified in positions 36 through
42) which points to the IBM i file description that contains the specifications for the
actual device.
The RPG device types correspond to the above file types as follows:
Table 43. Correlation of RPG Device Types with i5/OS File Types
RPG Device Type
DISK
PRINTER
printer files
WORKSTN
SEQ
SPECIAL
N/A
Figure 154 illustrates the association of the RPG file name FILEX, as coded in
Figure 153, with a system file description for a display file.
RPG program
File name = FILEX
Device = WORKSTN
FILEX
Device type =
DISPLAY
At compilation time, certain RPG operations are valid only for a specific RPG
device name. In this respect, the RPG operation is device dependent. One example
of device dependency is that the EXFMT operation code is valid only for a
WORKSTN device.
Other operation codes are device independent, meaning that they can be used with
any device type. For example, WRITE is a device-independent operation.
The SEQ Device
The device SEQ is an independent device type. Figure 155 on page 331 illustrates
the association of the RPG file name FILEY with a system file description for a
sequential device. When the program is run, the actual I/O device is specified in
the description of FILEY. For example, the device might be PRINTER.
330
RPG program
FILEY
File type =
DEVICE
Device type =
PRINTER
Although the file name and file type are coded in the RPG program, in many cases
you can change the type of file or the device used in a program without changing
the program. To find out how, see Overriding and Redirecting File Input and
Output on page 341.
Naming Files
On the i5/OS system, files are made up of members. These files are organized into
libraries. The convention for naming files is library-name/file-name.
#
#
#
#
#
#
#
#
In an ILE RPG program, the name used for a file within the source is specified in
positions 7 through 16 in file description specifications. File names can be up to ten
characters long and must be unique within their scope, global or local. The
EXTFILE keyword can be used to locate the file at runtime; if the EXTFILE
keyword is not specified, the same name is used at runtime to locate the file in the
library list. For an externally-described file, the EXTDESC keyword is used to
locate the file at compile time; if you want the same file to be used at runtime, you
can specify EXTFILE(*EXTDESC).
#
#
#
#
#
If you do not specify the EXTFILE keyword to locating the file at runtime, or you
do not specify the EXTDESC keyword to locate the file at compile time, you can
use a file override command to specify a particular name, library or member. See
Overriding and Redirecting File Input and Output on page 341 for more
information on file overrides.
v For a program-described file, you can use a data structure to hold the data for
your file operations, or for global files, you can code the descriptions of the
fields within the RPG source member on input and/or output specifications.
The description of the file to the operating system includes information about
where the data comes from and the length of the records in the file.
v For an externally described file, the compiler retrieves the description of the
fields from an external file-description which was created using DDS, IDDU, or
SQL commands. Therefore, you do not have to code the field descriptions on
input and/or output specifications within the RPG source member.
The external description includes information about where the data comes from,
such as the database or a specific device, and a description of each field and its
attributes. The file must exist and be accessible from the library list before you
compile your program.
Externally described files offer the following advantages:
331
#
#
#
#
#
At compile time, the compiler uses the data structure you have defined, or the
field descriptions in any input or/and output specifications that you coded for the
file. It does not retrieve the external descriptions.
RPG
Externally
Described File
(E in position 22)
i5/OS
i5/OS
i5/OS
Field-Level
Description of
a File
Record-Level
Description of
a File
Field-Level
Description of
a File
RPG
Program-Described
File (F in position
22) - The compiler
does not copy in
field-level description
RPG
Program-Described
File (F in position 22)
RPG
Externally
Described File
(E in position 22)
Figure 156. Typical Relationships between an RPG Program and Files on the i5/OS System
1
332
The program uses the field-level description of a file that is defined to the
operating system. An externally described file is identified by an E in
position 22 of the file description specifications. At compilation time, the
compiler copies in the external field-level description.
3
A file is described only at the record level to the operating system. The
fields in the record are described within the program; therefore, position 22
of the file description specifications must contain an F. This file does not
have to exist at compilation time.
4
A file name can be specified at compilation time (that is, coded in the RPG
source member), and a different file name can be specified at run time. The
E in position 22 of the file description specifications indicates that the
external description of the file is to be copied in at compilation time. At
run time, a file override command can be used so that a different file is
accessed by the program. To override a file at run time, you must make
sure that record names in both files are the same. The RPG program uses
the record-format name on the input/output operations, such as a READ
operation where it specifies what record type is expected. See Overriding
and Redirecting File Input and Output on page 341 for more information.
If your file is defined with the QUALIFIED keyword, the format names are
specified in the program in the form filename.formatname except when you are
specifying the format names in the keywords used to define the file. For example,
assume a file is named MYFILE in your program, and it has formats FMT1, FMT2
and FMT3. To rename FMT3 to NEWFMT3, you specify
RENAME(FMT3:NEWFMT3); to ignore FMT2, you specify IGNORE(FMT2). Within
your calculations, or when specifying the LIKEREC keyword, you use the qualified
form of the names, MYFILE.FMT1 and MYFILE.NEWFMT3.
#
#
#
333
#
#
Many of the functions that you can specify for externally described files (such as
the CHAIN operation) operate on either a file name or a record-format name. Each
file and unqualified record-format name in the program must be a unique
symbolic name. If your file is qualified, so that the record formats are specified in
the form filename.fmtname, the names of the formats do not have to be unique
within the program.
#
#
#
#
#
The RENAME keyword is generally used if the program contains two files which
have the same record-format names. In Figure 157, the record format
ITEMFORMAT in the externally described file ITMMSTL is renamed MSTITM for
use in this program. An alternate solution to the problem of having record formats
from different files with the same name is to define the files as qualified, using the
QUALIFIED keyword. The record formats of a qualified file are specified in the
form filename.formatname, so it does not matter if the format name is the same as
another name within the program.
#
#
#
#
#
#
#
#
334
For a global unqualified file, you can use the input specifications to override
certain information in the external description of an input file or to add RPG
functions to the external description. On the input specifications, you can:
v Assign record-identifying indicators to record formats as shown in Figure 160 on
page 336.
v Rename a field as shown in Figure 160 on page 336.
v Assign control-level indicators to fields as shown in Figure 160 on page 336.
v Assign match-field values to fields for matching record processing as shown in
Figure 161 on page 337.
v Assign field indicators as shown in Figure 161 on page 337.
You cannot use the input specifications to override field locations in an externally
described file. The fields in an externally described file are placed in the records in
335
1
2
3
336
1
2
Output specifications are optional for an externally described file; they are not
allowed for local files in subprocedures, or qualified files. RPG supports file
operation codes such as WRITE and UPDATE that use the external record-format
description to describe the output record without requiring output specifications
for the externally described file.
You can use output specification to control when the data is to be written, or to
specify selective fields that are to be written. The valid entries for the
field-description line for an externally described file are output indicators
(positions 21 - 29), field name (positions 30 - 43), and blank after (position 45). Edit
words and edit codes for fields written to an externally described file are specified
in the DDS for the file. Device-dependent functions such as fetch overflow
(position 18) or space/skip (positions 40 - 51) are not valid in an RPG program for
externally described files. The overflow indicator is not valid for externally
described files either. For a description of how to specify editing in the DDS, refer
to the DB2 Universal Database for iSeries section of the Database and File Systems
category in the i5/OS Information Center at this Web site - http://www.ibm.com/
systems/i/infocenter/.
If output specifications are used for an externally described file, the record-format
name is specified in positions 7 - 16 instead of the file name.
If all the fields in an externally described file are to be placed in the output record,
enter *ALL in positions 30 through 43 of the field-description line. If *ALL is
specified, you cannot specify other field description lines for that record.
Chapter 15. Defining Files
337
1
For an update file, all fields in the record are written to the externally
described record ITMREC using the current values in the program for all
fields in the record.
For the creation of a new record, all fields in the record are written to the
externally described record ITMREC using the current values in the
program for the fields in the record.
2
To update a record, the fields SLSNAM and COMRAT are written to the
externally described record SLSREC when indicator 30 is on. The field
BONUS is written to the SLSREC record when indicators 30 and 15 are on.
All other fields in the record are written with the values that were read.
To create a new record, the fields SLSNAM and COMRAT are written to
the externally described record SLSREC when indicator 30 is on. The field
BONUS is written when indicators 30 and 15 are on. All other fields in the
record are written as default values, which depend on their data type (for
example: a blank for character fields; zero for numeric fields).
338
Level Checking
HLL programs are dependent on receiving, at run time, an externally described file
whose format agrees with what was copied into the program at compilation time.
For this reason, the system provides a level-check function that ensures that the
format is the same.
The RPG compiler always provides the information required by level checking
when an externally described DISK, WORKSTN, or PRINTER file is used. The
level-check function can be requested on the create, change, and override file
commands. The default on the create file command is to request level checking.
Level checking occurs on a record-format basis when the file is opened unless you
specify LVLCHK(*NO) when you issue a file override command or create a file. If
the level-check values do not match, the program is notified of the error. The RPG
program then handles the OPEN error as described in Chapter 13, Handling
Exceptions, on page 285.
The RPG program does not provide level checking for program-described files or
for files using the devices SEQ or SPECIAL.
For more information on how to specify level checking, refer to the DB2 Universal
Database for iSeries section of the Database and File Systems category in the i5/OS
Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.
#
#
#
#
#
#
#
#
#
#
Program-described files are files whose records and fields are described on
input/output specifications in the program that uses the file. To use a
program-described file in an RPG program you must:
1. Identify the file(s) in the file description specifications.
2. If it is a global input file, describe the record and fields in the input
specifications. The file name in positions 7 through 16 in the input
specifications must be the same as the corresponding name entered in the file
specifications.
On the record-identification entries you indicate whether you want to perform
sequence checking of records within the file.
3. Enter the same file name as in step 1 in the FACTOR 2 field of those calculation
specifications which require it. For example, WRITE operations to a
program-described file require a data structure name in the result field.
4. If it is a global output file, describe the record and fields in the output
specifications. In addition, you specify how the output is to be printed. The file
name in positions 7 through 16 in the output specifications must be the same as
the corresponding name entered in the file specifications.
A program-described file must exist on the system, and be in your library list,
before the program can run. To create a file, use one of the Create File commands,
which can be found in the CL and APIs section of the Programming category in the
System i Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.
339
OPEN
OPEN
READ
By relative
record number
By key
Sequential
Previous
Next
Invited Device
340
READ, CHAIN
READ, READE, CHAIN, primary and
secondary file
READ
READP, READPE
READ, READE
READ
WRITE-READ
EXFMT
WRITE
By relative
record number
By key
Sequential
WRITE
WRITE, EXCEPT, primary and secondary file
WRITE, EXCEPT
FEOD
FEOD
UPDATE
By relative
record number
By key
DELETE
By relative
record number
By key
ACQUIRE
ACQ
RELEASE
REL
COMMIT
COMMIT
ROLLBACK
ROLBK
CLOSE
CLOSE, LR RETURN
FILEY
Compile
Time
File type =
PHYSICAL
RPG program
File name = FILEY
Device = DISK
Override Command:
OVRDBF FILE (FILEY) TOFILE (FILEA)
FILEA
Execution
Time
File type =
DEVICE
Device type =
DISKETTE
Diskette
341
342
Compile Time:
Override File
QTAPE to
File FMT1
FMT1
RPG program
File name = QTAPE
Format = E
Device = SEQ
Execution Time:
No Override
QTAPE
File type =
DEVICE
Device type =
TAPE
File Locking
The IBM i system allows a lock state (exclusive, exclusive allow read, shared for
update, shared no update, or shared for read) to be placed on a file used during
the execution of a job. Programs within a job are not affected by file lock states. A
file lock state applies only when a program in another job tries to use the file
concurrently. The file lock state can be allocated with the CL command ALCOBJ
(Allocate Object). For more information on allocating resources and lock states,
refer to the DB2 Universal Database for iSeries section of the Database and File Systems
category in the i5/OS Information Center at this Web site - http://www.ibm.com/
systems/i/infocenter/.
The IBM i system places the following lock states on database files when it opens
the files:
File Type
Lock State
Input
Update
Add
Output
The shared-for-read lock state allows another user to open the file with a lock state
of shared for read, shared for update, shared no update, or exclusive allow read,
but the user cannot specify the exclusive use of the file. The shared-for-update lock
state allows another user to open the file with shared-for-read or shared-for-update
lock state.
The RPG program places an exclusive-allow-read lock state on device files.
Another user can open the file with a shared-for-read lock state.
The lock state placed on the file by the RPG program can be changed if you use
the Allocate Object command.
343
Record Locking
Record Locking
When a record is read by a program, it is read in one of two modes: input or
update. If a program reads a record for update, a lock is placed on that record.
Another program cannot read the same record for update until the first program
releases that lock. If a program reads a record for input, no lock is placed on the
record. A record that is locked by one program can be read for input by another
program.
In RPG IV programs, you use an update file to read records for update. A record
read from a file with a type other than update can be read for inquiry only. By
default, any record that is read from an update file will be read for update. For
update files, you can specify that a record be read for input by using one of the
input operations CHAIN, READ, READE, READP, or READPE and specifying an
operation code extender (N) in the operation code field following the operation
code name.
When a record is locked by an RPG IV program, that lock remains until one of the
following occurs:
v the record is updated.
v the record is deleted.
v another record is read from the file (either for inquiry or update).
v a SETLL or SETGT operation is performed against the file
v an UNLOCK operation is performed against the file.
v an output operation defined by an output specification with no field names
included is performed against the file.
Note: An output operation that adds a record to a file does not result in a
record lock being released.
If your program reads a record for update and that record is locked through
another program in your job or through another job, your read operation will wait
until the record is unlocked (except in the case of shared files, see Sharing an
Open Data Path on page 345). If the wait time exceeds that specified on the
WAITRCD parameter of the file, an exception occurs. If your program does not
handle this exception (RNX1218) then the default error handler is given control
when a record lock timeout occurs, an RNQ1218 inquiry message will be issued.
One of the options listed for this message is to retry the operation on which the
timeout occurred. This will cause the operation on which the timeout occurred to
be re-issued, allowing the program to continue as if the record lock timeout had
not occurred. Note that if the file has an INFSR specified in which an I/O
operation is performed on the file before the default error handler is given control,
unexpected results can occur if the input operation that is retried is a sequential
operation, since the file cursor may have been modified.
Note: Subprocedures do not get inquiry message, and so this situation should be
handled by using an error indicator on the read operation and checking for
status 1218 following the read.
If no changes are required to a locked record, you can release it from its locked
state, without modifying the file cursor, by using the UNLOCK operation or by
processing output operations defined by output specifications with no field names
included. These output operations can be processed by EXCEPT output, detail
output, or total output.
344
Record Locking
(There are exceptions to these rules when operating under commitment control.
See Using Commitment Control on page 373 for more information.)
If you are sharing your files so that you can use them in different programs or
modules, consider passing the files between your programs and modules as
parameters instead. See Passing File Parameters on page 153.
The position of the current record is kept in the open data path for all programs
using the file. If you read a record in one program and then read a record in a
called program, the record retrieved by the second read depends on whether the
open data path is shared. If the open data path is shared, the position of the
current record in the called program is determined by the current position in the
calling program. If the open data path is not shared, each program has an
independent position for the current record.
If your program holds a record lock in a shared file and then calls a second
program that reads the shared file for update, you can release the first program's
lock by :
v performing a READ operation on the update file by the second program, or
v using the UNLOCK or the read-no-lock operations.
In ILE, shared files are scoped to either the job level or the activation group level.
Shared files that are scoped to the job level can be shared by any programs
running in any activation group within the job. Shared files that are scoped to the
activation group level can be shared only by the programs running in the same
activation group.
The default scope for shared files is the activation group. For job-level scope,
specify OVRSCOPE(*JOB) on the override command.
ILE RPG offers several enhancements in the area of shared ODPs. If a program or
procedure performs a read operation, another program or procedure can update
the record as long as SHARE(*YES) is specified for the file in question. In addition,
when using multiple-device files, if one program acquires a device, any other
program sharing the ODP can also use the acquired device. It is up to the
programmer to ensure that all data required to perform the update is available to
the called program.
If a program performs a sequential input operation, and it results in an end-of-file
condition, the normal operation is for any subsequent sequential input operation in
the same module to immediately result in an end-of-file condition without any
physical input request to the database. However, if the file is shared, the RPG
runtime will always send a physical input request to the database, and the input
operation will be successful if the file has been repositioned by a call to another
program or module using the shared file.
345
System
Open Options
INPUT
INPUT
OUTPUT
UPDATE
ADD
For additional information about sharing an open data path and activation group
versus job level scope, see the ILE Concepts manual.
Spooling
Spooling is a system function that puts data into a storage area to wait for
processing. The i5/OS system provides for the use of input and output spooling
functions. Each i5/OS file description contains a spool attribute that determines
whether spooling is used for the file at run time. The RPG program is not aware
that spooling is being used. The actual physical device from which a file is read or
to which a file is written is determined by the spool reader or the spool writer. For
more detailed information on spooling, refer to the DB2 Universal Database for
346
Spooling
iSeries section of the Database and File Systems category in the i5/OS Information
Center at this Web site - http://www.ibm.com/systems/i/infocenter/.
Output Spooling
Output spooling is valid for batch or interactive jobs. The description of the file
that is specified in the RPG program by the file name contains the specification for
spooling as shown in the following diagram:
Spooled
File
RPG program
QPRINT
SPOOL (*YES)
QUEUE (QPRINT)
Spooling
Queue
QPRINT
Execution Time
Start
Printer
writer
Start Printer
writer Time
Device
File override commands can be used at run time to override the spooling options
specified in the file description, such as the number of copies to be printed. In
addition, i5/OS spooling support allows you to redirect a file after the program
has run. You can direct the same printed output to a different device such as a
diskette.
347
SRTSEQ/ALTSEQ
You should decide whether to use SRTSEQ for your RPG program based on how
you want operations such as IFxx, COMP, and SORTA, to work on your character
data, not on what was specified when creating your files.
348
Database Files
Database files are objects of type *FILE on the i5/OS system. They can be either
physical or logical files and either externally described or program-described. You
access database files by associating the file name with the device DISK in positions
36 through 42 of the file description specifications.
Database files can be created by IBM i Create File commands. For more
information on describing and creating database files, refer to the DB2 Universal
Database for iSeries section of the Database and File Systems category in the i5/OS
Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.
349
Database Files
you to better manage your programs. The source member contains source
statements that the system uses to create program objects.
Access Path
The description of an externally described file contains the access path that
describes how records are to be retrieved from the file. Records can be retrieved
based on an arrival sequence (non-keyed) access path or on a keyed-sequence
access path.
The arrival sequence access path is based on the order in which the records are
stored in the file. Records are added to the file one after another.
For the keyed-sequence access path, the sequence of records in the file is based on
the contents of the key field that is defined in the DDS for the file. For example, in
the DDS shown in Figure 166 on page 351, CUST is defined as the key field. The
keyed-sequence access path is updated whenever records are added, deleted, or
when the contents of a key field change.
350
The sample DDS are for the customer master logical file CUSMSTL. The file
contains one record format CUSREC (customer master record). The data for this
file is contained in the physical file CUSMSTP, which is identified by the keyword
PFILE. The UNIQUE keyword is used to indicate that duplicate key values are not
allowed for this file. The CUST field is identified by a K in position 17 of the last
line as the key field for this record format.
The fields in this record format are listed in the order they are to appear in the
record. The attributes for the fields are obtained from the physical file CUSMSTP.
The physical file, in turn, refers to a field-reference file to obtain the attributes for
the fields. The field-reference file is shown in Figure 167 on page 352.
351
This example of a field-reference file shows the definitions of the fields that are
used by the CUSMSTL (customer master logical) file as shown in Figure 166 on
page 351. The field-reference file normally contains the definitions of fields that are
used by other files. The following text describes some of the entries for this
field-reference file.
352
1
2
The CHECK(MF) entry specifies that the field is a mandatory fill field
The ADDR and CITY fields share the same attributes that are specified for
the NAME field, as indicated by the REFFLD keyword.
4
The RANGE keyword, which is specified for the CUSTYP field, ensures
that the only valid numbers that can be entered into this field from a
display work station are 1 through 5.
5
The COLHDG keyword provides a column head for the field if it is used
by the Interactive Database Utilities (IDU).
6
The ARBAL field is edited by the J edit code, as indicated by the keyword
EDTCDE(J).
7
A text description (TEXT keyword) is provided for some fields. The TEXT
keyword is used for documentation purposes and appears in various
listings.
353
The search argument can only be a single field with attributes identical to field A
because field A is the only key field common to all record types.
Note: Null-capable key fields cannot be used with ALWNULL(*YES) or
ALWNULL(*INPUTONLY).
For an operation to a record name, the maximum number of fields that you can
specify in a search argument is equal to the total number of key fields valid for
that record type.
If the search argument consists of one or more fields, you can specify a KLIST, a
figurative constant, and in free-form calculations only, a list of expressions
(enclosed by parentheses) or a %KDS. If the search argument consists of only one
field, in addition to the above, you can also specify a literal or variable name.
To process null-valued keys, you can:
v code the search argument using KLIST, in which case the null indicator can be
specified in Factor 2 of the KFLD opcode
v code a null-capable field as the search argument in a list (enclosed by
parentheses)
v code a null-capable field in the data structure specified in %KDS
For the latter two, the current value of the %NULLIND() for the search argument
is used in the search.
The attributes of each field in the search argument must be identical to the
attributes of the corresponding field in the file or record key. The attributes include
the length, the data type and the number of decimal positions. The attributes are
listed in the key-field-information data table of the compiler listing. See the
example in Key Field Information on page 511. For search arguments in a list or
%KDS used in an I/O operation in free-form calculations, the search argument
only needs to match in type. Length and format may be different than the key
defined in the file.
In all these file operations (CHAIN, DELETE, READE, READPE, SETGT, and
SETLL), you can also specify a search argument that contains fewer than the total
number of fields valid for the file or record. Such a search argument refers to a
partial key.
354
klist2
KLIST
KFLD
KFLD
k1
k2
/free
CHAIN klist2 rec;
// KLIST with two KFLD entries
CHAIN %KDS(keys : 2) rec;
// %KDS with two keys
CHAIN (name : %char(id_no)) rec; // a list of two expressions
The rules for the specification of a search argument that refers to a partial key are
as follows:
v The search argument is composed of fields that correspond to the leftmost
(high-order) fields of the key for the file or record.
v Only the rightmost fields can be omitted from the list of keys for a search
argument that refers to a partial key. For example, if the total key for a file or
record is composed of key fields A, B, and C, the valid search arguments that
refer to a partial key are field A, and fields A and B.
v Each field in the search argument must be identical in attributes to the
corresponding key field in the file or record. For search arguments in a list or
%KDS used in an I/O operation in free-form calculations, the search argument
only needs to match in type. Length and format may be different than the key
defined in the file. The attributes include the length, data type, the number of
decimal positions, and format (for example, packed or zoned).
v A search argument cannot refer to a portion of a key field.
If a search argument refers to a partial key, the file is positioned at the first record
that satisfies the search argument or the record retrieved is the first record that
satisfies the search argument. For example, the SETGT and SETLL operations
position the file at the first record on the access path that satisfies the operation
and the search argument. The CHAIN operation retrieves the first record on the
access path that satisfies the search argument. The DELETE operation deletes the
first record on the access path that satisfies the search argument. The READE
operation retrieves the next record if the portion of the key of that record (or the
record of the specified type) on the access path matches the search argument. The
READPE operation retrieves the prior record if the portion of the key of that
record (or the record of the specified type) on the access path matches the search
argument. For more information on the above operation codes, see the IBM
Rational Development Studio for i: ILE RPG Reference.
355
Indexed File
An indexed file is a program-described DISK file whose access path is built on key
values. You must create the access path for an indexed file by using data
description specifications.
An indexed file is identified by an I in position 35 of the file description
specifications.
The key fields identify the records in an indexed file. You specify the length of the
key field in positions 29 through 33, the format of the key field in position 34, and
the starting location of the key field in the KEYLOC keyword of the file
description specifications.
356
You must use data description specifications to create the access path for a
program-described indexed file.
In the DDS for the record format FORMATA for the logical file ORDDTLL, the
field ORDER, which is five digits long, is defined as the key field, and is in packed
format. The definition of ORDER as the key field establishes the keyed access for
this file. Two other fields, FLDA and FLDB, describe the remaining positions in this
record as character fields.
The program-described input file ORDDTLL is described on the file description
specifications as an indexed file. Positions 29 through 33 must specify the number
of positions in the record required for the key field as defined in the DDS: three
positions. The KEYLOC keyword specifies position 15 as the starting position of
the key field in the record. Because the file is defined as program-described by the
F in position 22, the ILE RPG compiler does not retrieve the external field-level
description of the file at compilation time. Therefore, you must describe the fields
in the record on the input specifications.
357
In this example, the data description specifications define two key fields for the
record format FORMAT in the logical file ORDDTLL. For the two fields to be used
as a composite key for a program described indexed file, the key fields must be
contiguous in the record.
On the file description specifications, the length of the key field is defined as 10 in
positions 29 through 33 (the combined number of positions required for the
ORDER and ITEM fields). The starting position of the key field is described as 15
using the keyword KEYLOC (starting in position 44). The starting position must
specify the first position of the first key field.
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... *
FFilename++IPEASFRlen+LKlen+AIDevice+.Keywords+++++++++++++++++++++++++++++
FORDDTLL
IP
F 120
10AIDISK
KEYLOC(15)
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... *
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++
DKEY
DS
D K1
1
5
D K2
6
10
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... *
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....
C
MOVE
ORDER
K1
C
MOVE
ITEM
K2
C
KEY
CHAIN
ORDDTLL
99
Figure 170. (Part 2 of 2). Using Data Description Specifications to Define the Access Path
(Composite Key) for an Indexed File
When the DDS specifies a composite key, you must build a search argument in the
program to CHAIN to the file. (A KLIST cannot be used for a program-described
file.) One way is to create a data structure (using definition specifications) with
subfields equal to the key fields defined in the DDS. Then, in the calculations, set
the subfields equal to the value of the key fields, and use the data-structure name
as the search argument in the CHAIN operation.
In this example, the MOVE operations set the subfields K1 and K2 equal to the
value of ORDER and ITEM, respectively. The data-structure name (KEY) is then
used as the search argument in the CHAIN operation.
Sequential File
Sequential files are files where the order of the records in the file is based on the
order the records are placed in the file (that is, in arrival sequence). For example,
the tenth record placed in the file occupies the tenth record position.
358
Limits Records
For sequential-within-limits processing, the record-address file contains limits
records. A limits record contains the lowest record key and the highest record key
of the records in the file to be read.
The format of the limits records in the record-address file is as follows:
v The low key begins in position 1 of the record; the high key immediately follows
the low key. No blanks can appear between the keys.
v Each record in the record-address file can contain only one set of limits. The
record length must be greater than or equal to twice the length of the record key.
v The low key and the high key in the limits record must be the same length. The
length of the keys must be equal to the length of the key field of the file to be
processed.
v A blank entry equal in length to the record key field causes the ILE RPG
compiler to read the next record in the record-address file.
359
Limits
Processing
(Pos. 28)
Record
Address
Type
(Pos. 34)
File
Organization
(Pos. 35)
Blank
Blank
L
K
K
K
Blank
Blank
Blank
Blank
Blank
Blank
Sequentially
Blank
Randomly
Blank
A, D, G, P,
T, Z, or F
A, D, G, P,
T, Z, or F
A, D, G, P,
T, Z, or F
Blank
Blank
Blank
Blank
Blank
Blank
Blank
Blank
T
Blank
A, D, G, P,
T, Z, F, or
Blank
Blank
I
I
Without Keys
Randomly/consecutively
By record-address file
As record-address file
(relative record numbers)
As record-address limits file
Consecutive Processing
During consecutive processing, records are read in the order they appear in the
file.
360
Sequential-by-Key Processing
For the sequential-by-key method of processing, records are read from the file in
key sequence.
The sequential-by-key method of processing is valid for keyed files used as
primary, secondary, or full procedural files.
For output files and for input files that do not use random functions (such as
SETLL, SETGT, CHAIN, or ADD) and that have only one record format, the ILE
RPG compiler defaults to or operates as though SEQONLY(*YES) had been
specified on the CL command OVRDBF. (The ILE RPG compiler does not operate
as though SEQONLY(*YES) had been specified for update files.) SEQONLY(*YES)
allows multiple records to be placed in internal data management buffers; the
records are then passed to the ILE RPG compiler one at a time on input.
If, in the same job, two files use the same physical file, and one file is processed
sequentially and one is processed for random update, a record could be updated
that has already been placed in the buffer that is presented to the program. In this
case, when the record is processed from the sequential file, the record does not
reflect the updated data. To prevent this problem, use the CL command OVRDBF
and specify the option SEQONLY(*NO), which indicates that you do not want
multiple records transferred for a sequentially processed file.
For more information on sequential only processing, refer to the DB2 Universal
Database for iSeries section of the Database and File Systems category in the i5/OS
Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.
361
A*****************************************************************
A* DESCRIPTION: This is the DDS for the physical file TRWEEK.
*
A*
It contains one record format called RCWEEK.
*
A*
This file contains all weekly entries made to
*
A*
the time reporting system.
*
A*****************************************************************
A*
A
R RCWEEK
A
ENUM
5 0
TEXT(EMPLOYEE NUMBER)
A
WEEKNO
2 0
TEXT(WEEK NUMBER OF CURRENT YEAR)
A
EHWRK
4 1
TEXT(EMPLOYEE HOURS WORKED)
A
K ENUM
A
K WEEKNO
Figure 172. DDS for database file TRWEEK (physical file)
A*****************************************************************
A* RELATED FILES: EMPMST
(Physical File)
*
A*
TRWEEK
(Physical File)
*
A*
DESCRIPTION: This is the DDS for the logical file EMPL1.
*
A*
It contains two record formats called
*
A*
EMPREC and RCWEEK.
*
A*****************************************************************
A
R EMPREC
PFILE(EMPMST)
A
K ENUM
A*
A
R RCWEEK
PFILE(TRWEEK)
A
K ENUM
A
K WEEKNO
Figure 173. DDS for database file EMPL1 (logical file)
362
*****************************************************************
* PROGRAM NAME: YTDRPT1
*
* RELATED FILES: EMPL1
(Logical File)
*
*
PRINT
(Printer File)
*
*
DESCRIPTION: This program shows an example of processing
*
*
records using the sequential-by-key method.
*
*
This program prints out each employees
*
*
information and weekly hours worked.
*
*****************************************************************
FPRINT
O
F
80
PRINTER
FEMPL1
IP
E
K DISK
* A record-identifying indicator is assigned to each record; these
* record-identifying indicators are used to control processing for
* the different record types.
IEMPREC
01
I*
IRCWEEK
02
I*
*
*
*
*
*
*
*
*
C
C
C*
C
C
C
01
OPRINT
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
IF
SETON
ENDIF
H
12
ENUM
EMPNO
5 0
1P
6
40 EMPLOYEE WEEKLY WORKING
52 HOURS REPORT
01
1
12 EMPLOYEE:
32
ENAME
H
01
1
12 SERIAL #:
17
27 DEPT:
30
40 TYPE:
41
ENUM
EDEPT
ETYPE
H
01
1
20 WEEK #
50 HOURS WORKED
12
1
WEEKNO
EHWRK
18
45
363
*****************************************************************
* PROGRAM NAME: YTDRPT2
*
* RELATED FILES: EMPL1
(Logical File)
*
*
PRINT
(Printer File)
*
*
DESCRIPTION: This program shows an example of processing
*
*
records using the read operation code.
*
*
This program prints out each employees
*
*
information and weekly hours worked.
*
*****************************************************************
FPRINT
O
F
80
PRINTER
FEMPL1
IF E
K DISK
* The two records (EMPREC and RCWEEK) are contained in the same
* file, and a record-identifying indicator is assigned to each
* record. The record-identifying indicators are used to control
* processing for the different record types. No control levels
* or match fields can be specified for a full-procedural file.
IEMPREC
01
I*
IRCWEEK
02
I*
*
*
*
*
*
C
C
C
C*
C
C*
C
C
C
*
*
*
C
C
The READ operation code reads a record from the EMPL1 file. An
end-of-file indicator is specified in positions 58 and 59. If
the end-of-file indicator 99 is set on by the READ operation,
the program branches to the EOFEND tag and processes the end-offile routine.
99
SETOFF
READ
GOTO
EMPL1
EOFEND
12
01
MOVE
ENUM
IF
SETON
ENDIF
99
EMPNO
12
TAG
SETON
364
5 0
LR
OPRINT
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
O
1P
6
40 EMPLOYEE WEEKLY WORKING
52 HOURS REPORT
01
1
12 EMPLOYEE:
32
ENAME
H
01
1
12 SERIAL #:
17
27 DEPT:
30
40 TYPE:
41
ENUM
EDEPT
ETYPE
H
01
1
20 WEEK #
50 HOURS WORKED
12
1
WEEKNO
EHWRK
18
45
365
C
01
Z-ADD
0
TOTHRS
5 1
C
01
Z-ADD
0
TOTOVT
5 1
C
01
SETOFF
12
C*
C
MR
IF
(*IN02=1)
C
ADD
EHWRK
TOTHRS
C
EHWRK
SUB
ENHRS
OVTHRS
4 111
C
11
ADD
OVTHRS
TOTOVT
C
SETON
12
C
ENDIF
OPRINT
H
1P
2 6
O
50 YTD PAYROLL SUMMARY
O
D
01
1
O
12 EMPLOYEE:
O
ENAME
32
O
D
01
1
O
12 SERIAL #:
O
ENUM
17
O
27 DEPT:
O
EDEPT
30
O
40 TYPE:
O
ETYPE
41
O
D
02 MR
1
O
8 WEEK #
O
WEEKNO
10
O
32 HOURS WORKED =
O
EHWRK
3
38
* These 2 detail output lines are processed if *IN01 is on
* and no matching records found (that means no RCWEEK records
* for that employee found). Obviously, the total fields
* (TOTHRS and TOTOVT) are equal to zeros in this case.
O
D
01NMR
1
O
70 YTD HOURS WORKED =
O
TOTHRS
3
78
O
D
01NMR
1
O
70 YTD OVERTIME HOURS =
O
TOTHRS
3
78
*
*
*
*
O
O
O
O
O
O
O
O
01 12
LR 12
1
TOTHRS
T
OR
01 12
LR 12
1
TOTOVT
Random-by-Key Processing
For the random-by-key method of processing, a search argument that identifies the
key of the record to be read is specified in factor 1 of the calculation specifications
for the CHAIN operation. Figure 178 on page 368 shows an example of an
externally described DISK file being processed randomly by key. The specified
record can be read from the file either during detail calculations or during total
calculations.
366
367
*****************************************************************
* PROGRAM NAME: EMSTUPD
*
* RELATED FILES: EMPMST
(Physical File)
*
*
CHANGE
(Physical File)
*
*
DESCRIPTION: This program shows the processing of records *
*
using the random-by-key method. The CHAIN
*
*
operation code is used.
*
*
The physical file CHANGE contains all the
*
*
changes made to the EMPMST file. Its record *
*
format name is CHGREC. There may be some
*
*
fields in the CHGREC that are left blank,
*
*
in that case, no changes are made to those
*
*
fields.
*
*****************************************************************
FCHANGE
IP E
K DISK
FEMPMST
UF E
K DISK
* As each record is read from the primary input file, CHANGE,
* the employee number (ENUM) is used as the search argument
* to chain to the corresponding record in the EMPMST file.
* *IN03 will be set on if no corresponding record is found, which
* occurs when an invalid ENUM is entered into the CHGREC record.
C
ENUM
CHAIN
EMPREC
03
C
03
GOTO
NEXT
C
NNAME
IFNE
*BLANK
C
MOVE
NNAME
ENAME
C
ENDIF
C
NTYPE
IFNE
*BLANK
C
MOVE
NTYPE
ETYPE
C
ENDIF
C
NDEPT
IFNE
*ZERO
C
MOVE
NDEPT
EDEPT
C
ENDIF
C
NNHRS
IFNE
*ZERO
C
MOVE
NNHRS
ENHRS
C
ENDIF
C
UPDATE
EMPREC
C*
C
NEXT
TAG
Figure 178. Random-by-Key Processing of an Externally Described File
Sequential-within-Limits Processing
Sequential-within-limits processing by a record-address file is specified by an L in
position 28 of the file description specifications and is valid for a file with a keyed
access.
You can specify sequential-within-limits processing for an input or an update file
that is designated as a primary, secondary, or full-procedural file. The file can be
externally described or program-described (indexed). The file should have keys in
ascending sequence.
To process a file sequentially within limits from a record-address file, the program
reads:
v A limits record from the record-address file
v Records from the file being processed within limits with keys greater than or
equal to the low-record key and less than or equal to the high-record key in the
limits record. If the two limits supplied by the record-address file are equal, only
the records with the specified key are retrieved.
368
As EMPMST is processed within each set of limits, the corresponding records are printed. Processing of the EMPMST file is
complete when the record-address file LIMITS reaches end of file.
OPRINT
O
O
O
O
O
O
O
O
O
1P
1
12
22
45
56
01
SERIAL #
NAME
DEPT
TYPE
1
ENUM
ENAME
EDEPT
ETYPE
10
35
45
55
369
This program performs the same job as the previous program. The only difference
is that the physical file EMPMST is defined as an externally described file instead
of a program-described file.
*****************************************************************
* PROGRAM NAME: ESWLIM2
*
* RELATED FILES: EMPMST
(Physical File)
*
*
LIMITS
(Physical File)
*
*
PRINT
(Printer File)
*
*
DESCRIPTION: This program shows the processing of an
*
*
externally described file sequentially
*
*
within limits.
*
*
This program prints out information for the
*
*
employees whose employee numbers are within
*
*
the limits given in the file LIMITS.
*
*****************************************************************
FLIMITS
IR F
6
3 DISK
RAFDATA(EMPMST)
FEMPMST
IP E
L
K DISK
FPRINT
O
F
80
PRINTER
* Input Specifications are optional for an externally described
* file. Here, *IN01 is defined as the record-identifying
* indicator for the record-format EMPREC to control the
* processing of this record.
IEMPREC
01
OPRINT
O
O
O
O
O
O
O
O
O
O*
1P
1
12
22
45
56
01
SERIAL #
NAME
DEPT
TYPE
1
ENUM
ENAME
EDEPT
ETYPE
10
35
45
55
Relative-Record-Number Processing
Random input or update processing by relative record number applies to full
procedural files only. The desired record is accessed by the CHAIN operation code.
Relative record numbers identify the positions of the records relative to the
beginning of the file. For example, the relative record numbers of the first, fifth,
and seventh records are 1, 5, and 7, respectively.
370
18
P/S
P/S
P/S
20
A
L
342
26-35
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
371
P/S
P/S
P/S
Blank
Blank
A
L
L
A
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
K/A/P/G/
D/T/Z/F
Notes:
1. An L must be specified in position 28 to specify sequential-within-limits processing by a
record-address file for an input or an update file.
2. Externally described files require a K in position 34; program-described files require an
A,P,G,D,T,Z, or F in position 34 and an I in position 35.
3. An A in position 20 is not required for the initial loading of records into a new file. If A
is specified in position 20, ADD must be specified on the output specifications. The file
must have been created with the IBM i CREATE FILE command.
Table 48. Valid File Operations for Non-keyed Processing Methods (Sequential, Random by
Relative Record Number, and Consecutive)
File-Description
Specifications Positions
372
17
18
P/S
Blank
P/S
Blank
P/S
Blank
P/S
Blank
20
34
26-35
CLOSE, FEOD, FORCE
RECNO
RECNO
Blank
Blank
Blank
Blank
RECNO
Blank
RECNO
A/P/G/
D/T/Z/
F/
Blank1
Blank2
Blank
O
O
RECNO
Blank
RECNO
Blank
Blank
RECNO
Blank
Blank
Blank
Notes:
1. If position 34 is blank for a record-address-limits file, the format of the keys in the
record-address file is the same as the format of the keys in the file being processed.
2. A record-address file containing relative record numbers requires a T in position 35.
3. The RECNO field that contains the relative record number must be set prior to the WRITE
operation or if ADD is specified on the output specifications.
4. An A in position 20 is not required for the initial loading of the records into a new file;
however, if A is specified in position 20, ADD must be specified on output specifications.
The file must have been created with one of the IBM i file creation commands.
373
374
375
376
To operate your program (named REVISE) under commitment control, you issue
the commands:
1. STRCMTCTL LCKLVL(*ALL)
This command starts commitment control with the highest level of locking.
2. CALL REVISE
This command calls the program REVISE.
3. ENDCMTCTL
This command ends commitment control and causes an implicit Roll Back
operation.
377
378
DDM Files
ILE RPG programs access files on remote systems through distributed data
management (DDM). DDM allows application programs on one system to use files
stored on a remote system as database files. No special statements are required in
ILE RPG programs to support DDM files.
A DDM file is created by a user or program on a local (source) system. This file
(with object type *FILE) identifies a file that is kept on a remote (target) system.
The DDM file provides the information needed for a local system to locate a
remote system and to access the data in the source file. For more information
about using DDM and creating DDM files, refer to the DB2 Universal Database for
iSeries section of the Database and File Systems category in the i5/OS Information
Center at this Web site - http://www.ibm.com/systems/i/infocenter/.
379
DDM Files
In addition, if the sign of a numeric field is different from the system preferred
sign, the key comparison will also differ.
The first time that the key comparison is not done at the Data Management level
on a pre-V3R1 DDM file during the READE or READPE operation, EQ indicator
for SETLL, or during sequential-within-limits processing by a record address file,
an informational message (RNI2002) will be issued.
Note: The performance of I/O operations that have the possibility of not finding a
record (SETLL, CHAIN, SETGT, READE, READPE), will be slower than the
pre-Version 3 Release 1.0 equivalent.
380
CL
commands
RPG Device
Name
Printer Files
CRTPRTF
CHGPRTF
OVRPRTF
PRINTER
Tape Files
CRTTAPF
CHGTAPF
OVRTAPF
SEQ
Diskette Files
CRTDKTF
CHGDKTF
OVRDKTF
DISK
Display Files
CRTDSPF
CHGDSPF
OVRDSPF
WORKSTN
ICF Files
CRTICFF
CHGICFF
OVRICFF
WORKSTN
The device file contains the file description, which identifies the device to be used;
it does not contain data.
381
382
383
Output
Specifications
Positions 21-29
No entry
No entry
No entry
Entry
OFLIND (indicator)
No entry
OFLIND (indicator)
Entry
Action
384
385
Get a
Record
Detail
Output
Total
Output
With Fetch
Exception Output
Detail
Calc
Total
Calculations
Total
Calc
Normal Output
Detail
Output
Total
Output
Exception Output
Detail
Calc
0A
Print
0A
Total
Output
Total
Calc
0A
Print
0A
Overflow
Printing
T = Total
H = Heading
D = Detail
E = Exception
Detail
Calculations
0A
Print
0A
Heading
and
Detail
Output
0A
Print
0A
Set Off
Overflow
Indicators
Off
Off
Off
Off
Off
Off
Off
Off
386
A
When fetch overflow is not specified, the overflow lines print after total
output. No matter when overflow occurs (OA is on), the overflow indicator
OA remains on through overflow output time and is set off after heading
and detail output time.
B
When fetch overflow is specified, the overflow lines are written before the
output line for which fetch overflow was specified, if the overflow
indicator OA is on. When OA is set on, it remains on until after heading
The total lines with an F coded in position 18 can fetch the overflow routine. They
only do so if overflow is sensed prior to the printing of one of these lines. Before
Chapter 18. Accessing Externally Attached Devices
387
Subfield Contents
1-3
4-6
7-9
10-12
13-15
The OPM PRTCTL data structure must be defined on the Definition specifications
and must contain at least the following five subfields specified in the following
order:
Table 52. Layout of OPM PRTCTL Data Structure
388
Positions
Subfield Contents
3-4
5-6
7-9
On the file description specifications, the PRTCTL keyword is specified for the
PRINT file. The name of the associated data structure is LINE.
The LINE data structure is defined on the input specifications as having only those
subfields that are predefined for the PRTCTL data structure. The first four
subfields in positions 1 through 12 are used to supply space and skip information
that is generally specified in positions 40 through 51 of the output specifications.
The PRTCTL keyword allows you to change these specifications within the
program.
In this example, the value in the SpAfter subfield is changed to 3 when the value
in the CurLine (current line count value) subfield is equal to 10. (Assume that
indicator 01 was set on as a record identifying indicator.)
389
Database file
Diskette file
Printer file
Tape file.
The file name of the SEQ file in the file description specifications points to an
AS/400 file. The file description of the AS/400 file specifies the actual I/O device,
such as tape, printer or diskette.
You can also use the CL override commands, for example OVRDBF, OVRDKTF
and OVRTAPF, to specify the actual I/O device when the program is run.
390
18
26-35
P/S
CLOSE, FEOD
A SEQ device is specified for the PAYOTIME file. When the program is run, you
can use a IBM i override command to specify the actual device (such as printer,
tape, or diskette) to be associated with the file while the program is running. For
example, diskette can be specified for some program runs while printer can be
specified for others. The file description, pointed to by the file name, can specify
the actual device, in which case an override command need not be used.
391
The ILE RPG program has placed a record in the area defined by
the area parameter; the record is to be written out.
Status The status parameter is a one-position character field that indicates the
status of the user-written routine when control is returned to the ILE RPG
program. Status must contain one of the following return values when the
user-written routine returns control to the ILE RPG program:
Return Value
Description
0
The input file is at end of file, and no record has been returned. If
the file is an output file, this return value is an error.
Error
The error parameter is a five-digit zoned numeric field with zero decimal
positions. If the user-written routine detects an error, the error parameter
contains an indication or value representing the type of error. The value is
placed in the first five positions of location *RECORD in the INFDS when
the status parameter contains 2.
Area
The area parameter is a character field whose length is equal to the record
length associated with the SPECIAL file. This field is used to pass the
record to or receive the record from the ILE RPG program.
You can add additional parameters to the RPG-created parameter list. Specify the
keyword PLIST(parameter list name) on the file description specifications for the
SPECIAL file. See Figure 190 on page 393. Then use the PLIST operation in the
calculation specifications to define the additional parameters.
The user-written routine, specified by the keyword PGMNAME of the file
description specifications for the SPECIAL file, must contain an entry parameter
list that includes both the RPG-created parameters and the user-specified
parameters.
If the SPECIAL file is specified as a primary file, the user-specified parameters
must be initialized before the first primary read. You can initialize these
parameters with a factor 2 entry on the PARM statements or by the specification of
a compile-time array or an array element as a parameter.
392
18
26-35
P/S
CLOSE, FEOD
P/S
P/S
MOVEL
MOVE
WRITE
MOVE
WRITE
SETON
HELLO
1
EXCPTN
2
EXCPTN
FLD
FLD1
OUTBUF
FLD1
OUTBUF
1
1
LR
393
The I/O operations for the SPECIAL device are controlled by the user-written
program USERIO. The parameters specified for the programmer-defined
PLIST(SPCL) are added to the end of the RPG-created parameter list for the
SPECIAL device. The programmer-specified parameters can be accessed by the
user ILE RPG program and the user-written routine USERIO; whereas the
RPG-created parameter list can be accessed only by internal ILE RPG logic and the
user-written routine.
394
395
396
This display device file contains two record formats: PROMPT and RESPONSE.
1
The attributes for the fields in this file are defined in the DSTREF field
reference file.
2
The OVERLAY keyword is used so that both record formats can be used
on the same display.
3
4
The PUTRETAIN keyword allows the value that is entered in the ITEM
field to be kept in the display. In addition, the ITEM field is defined as an
input field by the I in position 38. ITEM is the only input field in these
record formats. All of the other fields in the record are output fields since
position 38 is blank for each of them.
5
6
The LOCK keyword prevents the work-station user from using the
keyboard when the RESPONSE record format is initially-displayed.
7
8
The line and position entries identify where the fields or constants are
written on the display.
397
398
Using Subfiles
Subfiles can be specified in the DDS for a display-device file to allow you to
handle multiple records of the same type on the display. (See Figure 193 on page
400.) A subfile is a group of records that is read from or written to a display-device
file. For example, a program reads records from a database file and creates a
subfile of output records. When the entire subfile has been written, the program
sends the entire subfile to the display device in one write operation. The
work-station user can change data or enter additional data in the subfile. The
program then reads the entire subfile from the display device into the program and
processes each record in the subfile individually.
Records that you want to be included in a subfile are specified in the DDS for the
file. The number of records that can be included in a subfile must also be specified
in the DDS. One file can contain more than one subfile, and up to 12 subfiles can
be active concurrently. Two subfiles can be displayed at the same time.
The DDS for a subfile consists of two record formats: a subfile-record format and a
subfile control-record format. The subfile-record format contains the field
information that is transferred to or from the display file under control of the
subfile control-record format. The subfile control-record format causes the physical
read, write, or control operations of a subfile to take place. Figure 194 on page 401
shows an example of the DDS for a subfile-record format, and Figure 195 on page
402 shows an example of the DDS for a subfile control-record format.
For a description of how to use subfile keywords, refer to the DB2 Universal
Database for iSeries section of the Database and File Systems category in the i5/OS
Information Center at this Web site - http://www.ibm.com/systems/i/infocenter/
..
399
Name
Address
City
State
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
To use a subfile for a display device file in an RPG program, you must specify the
SFILE keyword on a file description specification for the WORKSTN file. The
format of the SFILE keyword is SFILE(record format name:RECNO field name). The
WORKSTN file must be an externally-described file (E in position 22).
You must specify for the SFILE keyword the name of the subfile record format (not
the control-record format) and the name of the field that contains the relative
record number to be used in processing the subfile.
In an RPG program, relative record number processing is defined as part of the
SFILE definition. The SFILE definition implies a full-procedural update file with
ADD for the subfile. Therefore, the file operations that are valid for the subfile are
not dependent on the definition of the main WORKSTN file. That is, the
WORKSTN file can be defined as a primary file or a full-procedural file.
Use the CHAIN, READC, UPDATE, or WRITE operation codes with the subfile
record format to transfer data between the program and the subfile. Use the
READ, WRITE, or EXFMT operation codes with the subfile control-record format
to transfer data between the program and the display device or to process subfile
control operations.
Subfile processing follows the rules for relative-record-number processing. The
RPG program places the relative-record number of any record retrieved by a
READC operation into the field named in the second position of the SFILE
keyword. This field is also used to specify the record number that the RPG
program uses for WRITE operation to the subfile or for output operations that use
ADD. The RECNO field name specified for the SFILE keyword must be defined as
numeric with zero decimal positions. The field must have enough positions to
contain the largest record number for the file. (See the SFLSIZ keyword in the DB2
Universal Database for iSeries section of the Database and File Systems category in the
i5/OS Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.) The WRITE operation code and the ADD specification on the output
specifications require that a relative-record-number field be specified in the second
position of the SFILE keyword on the file description specification.
400
The data description specifications (DDS) for a subfile record format describe the
records in the subfile:
1
The attributes for the fields in the record format are contained in the field
reference file DSTREF as specified by the REF keyword.
2
3
The line and position entries define the location of the fields on the
display.
Use of Subfiles
Some typical ways you can make use of subfiles include:
v Display only. The work-station user reviews the display.
v Display with selection. The user requests more information about one of the
items on the display.
v Modification. The user changes one or more of the records.
v Input only, with no validity checking. A subfile is used for a data entry function.
v Input only, with validity checking. A subfile is used for a data entry function,
but the records are checked.
v Combination of tasks. A subfile can be used as a display with modification, plus
the input of new records.
The following figure shows an example of data description specifications for a
subfile control-record format. For an example of using a subfile in an RPG
program, see Search by Zip Code on page 424.
401
The subfile control-record format defines the attributes of the subfile, the search
input field, constants, and function keys. The keywords you can use indicate the
following:
v SFLCTL names the associated subfile (SUBFIL).
v SFLCLR indicates when the subfile should be cleared (when indicator 70 is off).
v SFLDSPCTL indicates when to display the subfile control record (when indicator
70 is on).
v SFLDSP indicates when to display the subfile (when indicator 71 is on).
v SFLSIZ indicates the total number of records to be included in the subfile (15).
v SFLPAG indicates the total number of records in a page (15).
v ROLLUP indicates that indicator 97 is set on in the program when the user
presses the Roll Up key.
v HELP allows the user to press the Help key for a displayed message that
describes the valid function keys.
v PUTRETAIN allows the value that is entered in the SRHCOD field to be kept in
the display.
In addition to the control information, the subfile control-record format also
defines the constants to be used as column headings for the subfile record format.
402
Output Specifications
On the output specifications, you must specify the WORKSTN file name in
positions 7 through 16. The format name, which is the name of the DDS record
format, is specified as a literal or named constant in positions 53 through 80 on the
succeeding field description line. K1 through K10 must be specified
(right-adjusted) in positions 47 through 51 on the line containing the format name.
The K identifies the entry as a length rather than an end position, and the number
indicates the length of the format name. For example, if the format name is
CUSPMT, the entry in positions 47 through 51 is K6. (Leading zeros following the
K are allowed.) The format name cannot be conditioned (indicators in positions 21
through 29 are not valid).
Output fields must be located in the output record in the same order as defined in
the DDS; however, the field names do not have to be the same. The end position
entries for the fields refer to the end position in the output record passed from the
RPG program to data management, and not to the location of the fields on the
screen.
To pass indicators on output, do one of the following:
v Specify the keyword INDARA in the DDS for the WORKSTN file. Do not use
the PASS(*NOIND) keyword on the file description specification and do not
specify the indicators on the output specifications. The program and file use a
separate indicator area to pass the indicators.
v Specify the PASS(*NOIND) keyword on the file description specification. Specify
the indicators in the output specifications as fields in the form *INxx. The
indicator fields must precede other fields in the output record, and they must
appear in the order specified by the WORKSTN file DDS. You can determine
this order from the DDS listing.
Input Specifications
The input specifications describe the record that the RPG program receives from
the display or ICF device. The WORKSTN file name must be specified in positions
7 through 16. Input fields must be located in the input record in the same sequence
as defined in the DDS; however, the field names do not have to be the same. The
field location entries refer to the location of the fields in the input record.
To receive indicators on input, do one of the following:
v Specify the keyword INDARA in the DDS for the WORKSTN file. Do not use
the PASS(*NOIND) keyword on the file description specification and do not
Chapter 19. Using WORKSTN Files
403
Calculation Specifications
The operation code READ is valid for a program-described WORKSTN file that is
defined as a combined, full-procedural file. See Table 55 on page 405. The file name
must be specified in factor 2 for this operation. A format must exist at the device
before any input operations can take place. This requirement can be satisfied on a
display device by conditioning an output record with 1P or by writing the first
format to the device in another program (for example, in the CL program). The
EXFMT operation is not valid for a program-described WORKSTN file. You can
also use the EXCEPT operation to write to a WORKSTN file.
Additional Considerations
When using a format name with a program-described WORKSTN file, you must
also consider the following:
v The name specified in positions 53 through 80 of the output specifications is
assumed to be the name of a record format in the DDS that was used to create
the file.
v If a Kn specification is present for an output record, it must also be used for any
other output records for that file. If a Kn specification is not used for all output
records to a file, a run-time error will occur.
Input File
For an input file, the input record, which is treated by the IBM i device support as
a single input field, is initialized to blanks when the file is opened. The cursor is
positioned at the beginning of the field, which is position 2 on the display.
404
Output File
For an output file, the IBM i device support treats the output record as a string of
characters to be sent to the display. Each output record is written as the next
sequential record in the file; that is, each record displayed overlays the previous
record displayed.
Combined File
For a combined file, the record, which is treated by the IBM i device support as a
single field, appears on the screen and is both the output record and the input
record. Device support initializes the input record to blanks, and the cursor is
placed in position 2.
For more information on program-described-display-device files, refer to the DB2
Universal Database for iSeries section of the Database and File Systems category in the
i5/OS Information Center at this Web site - http://www.ibm.com/systems/i/
infocenter/.
18
26-35
P/S
P/S
Blank
Notes:
1. The WRITE operation is not valid for a program-described file used with a format name.
2. If the EXFMT operation is used, the file must be externally described (an E in position 19
of the file description specifications).
3. For subfile record formats, the UPDATE, CHAIN, and READC operations are also valid.
The following further explains the EXFMT, READ, and WRITE operation codes
when used to process a WORKSTN file.
EXFMT Operation
The EXFMT operation is a combination of a WRITE followed by a READ to the
same record format (it corresponds to a data management WRITE-READ
operation). If you define a WORKSTN file on the file description specifications as a
full-procedural (F in position 18) combined file (C in position 17) that uses
externally-described data (E in position 22) the EXFMT (execute format) operation
code can be used to write and read from the display.
405
READ Operation
The READ operation is valid for a full-procedural combined file or a
full-procedural input file that uses externally-described data or program-described
data. The READ operation retrieves a record from the display. However, a format
must exist at the device before any input operations can occur. This requirement
can be satisfied on a display device by conditioning an output record with the 1P
indicator, by writing the first format to the device from another program, or, if the
read is by record-format name, by using the keyword INZRCD on the record
description in the DDS.
WRITE Operation
The WRITE operation writes a new record to a display and is valid for a combined
file or an output file. Output specifications and the EXCEPT operation can also be
used to write to a WORKSTN file. See the IBM Rational Development Studio for i:
ILE RPG Reference for a complete description of each of these operation codes.
Multiple-Device Files
Any RPG WORKSTN file with at least one of the keywords DEVID, SAVEIND,
MAXDEV(*FILE) or SAVEDS specified on the file description specification is a
multiple-device file. Through a multiple-device file, your program may access
more than one device.
The RPG program accesses devices through program devices, which are symbolic
mechanisms for directing operations to an actual device. When you create a file
(using the DDS and commands such as the create file commands), you consider
such things as which device is associated with a program device, whether or not a
file has a requesting program device, which record formats will be used to invite
devices to respond to a READ-by-file-name operation, and how long this READ
operation will wait for a response. For detailed information on the options and
requirements for creating a multiple-device file, see the chapter on display files in
the DB2 Universal Database for iSeries section of the Database and File Systems
category in the i5/OS Information Center at this Web site - http://www.ibm.com/
systems/i/infocenter/. You can also refer to information on ICF files in ICF
Programming manual.
With multiple-device files, you make particular use of the following operation
codes:
v In addition to opening a file, the OPEN operation implicitly acquires the device
you specify when you create the file.
v The ACQ (acquire) operation acquires any other devices for a multiple-device
file.
v The REL (release) operation releases a device from the file.
v The WRITE operation, when used with the DDS keyword INVITE, invites a
program device to respond to subsequent read-from-invited- program-devices
operations. See the section on inviting a program device in ICF Programming
manual.
v The READ operation either processes a read-from-invited-program-devices
operation or a read-from-one-program-device operation. When no NEXT
operation is in effect, a program-cycle-read or READ-by-file-name operation
waits for input from any of the devices that have been invited to respond
(read-from-invited-program-device). Other input and output operations,
including a READ-by-file-name after a NEXT operation, and a
READ-by-format-name, process a read-from-one-program-device operation using
406
Multiple-Device Files
the program device indicated in a special field. (The field is named in the
DEVID keyword of the file description specification lines.)
This device may be the device used on the last input operation, a device you
specify, or the requesting program device. See the sections on reading from
invited program devices and on reading from one program device in ICF
Programming manual.
v The NEXT operation specifies which device is to be used in the next
READ-by-file-name operation or program-cycle-read operation.
v The POST operation puts information in the INFDS information data structure.
The information may be about a specific device or about the file. (The POST
operation is not restricted to use with multiple-device files.)
See the IBM Rational Development Studio for i: ILE RPG Reference for details of the
RPG operation codes.
On the file description specification you can specify several keywords to control
the processing of multiple-device files.
v The MAXDEV keyword indicates whether it is a single or multiple device file.
Specify MAXDEV(*FILE) to process a multiple device file with the maximum
number of devices taken from the definition of the file being processed. Specify
MAXDEV(*ONLY) to process only one device.
v The DEVID keyword allows you to specify the name of a program device to
which input and output operations are directed.
When a read-from-one-program-device or WRITE operation is issued, the device
used for the operation is the device specified as the parameter to the DEVID
keyword. This field is initialized to blanks and is updated with the name of the
device from which the last successful input operation occurred. It can also be set
explicitly by moving a value to it. The ACQ operation code does not affect the
value of this field. If the DEVID keyword is not specified, the input operation is
performed against the device from which the last successful input operation
occurred. A blank device name is used if a read operation has not yet been
performed successfully from a device.
When a read-from-one-program device or WRITE operation is issued with a
blank device name, the RPG compiler implicitly uses the device name of the
requestor device for the program. If you call an RPG program interactively and
acquire an ICF device against which you want to perform one of these
operations, you must explicitly move the device name of the ICF device into the
field name specified with the DEVID keyword prior to performing the operation.
If this is not done, the device name used will either be blank (in which case the
interactive requestor device name is used), or the device name used is the one
from the last successful input operation. Once you have performed an I/O
operation to the ICF device, you do not need to modify the value again unless
an input operation completes successfully with a different device.
v The SAVEDS keyword indicates a data structure that is saved and restored for
each device acquired to a file. The SAVEIND keyword indicates a set of
indicators to be saved and restored for each device acquired to a file. Before an
input operation, the current set of indicators and data structure are saved. After
the input operation, the RPG compiler restores the indicators and data structure
for the device associated with the operation. This may be a different set of
indicators or data structure than was available before the input operation.
v The INFDS keyword specifies the file information data structure for the
WORKSTN file. The RPG *STATUS field and the major/minor return code for
407
Multiple-Device Files
the I/O operation can be accessed through this data structure. Particularly when
ICF is being used, both fields are useful for detecting errors that occurred during
I/O operations to multiple-device files.
Note: When specifying these control options, you must code the MAXDEV
option before the DEVID, SAVEIND or SAVEDS options.
408
Description
409
A*****************************************************************
A*
FILE NAME: CUSMST
*
A* RELATED PGMS: CUSMNT, SCHZIP, SCHNAM
*
A* RELATED FILES: CUSMSTL1, CUSMSTL2, CUSMSTL3 (LOGICAL FILES) *
A*
DESCRIPTION: THIS IS THE PHYSICAL FILE CUSMST. IT HAS
*
A*
ONE RECORD FORMAT CALLED CUSREC.
*
A*****************************************************************
A* CUSTOMER MASTER FILE -- CUSMST
A
R CUSREC
A
CUST
5 0
TEXT(CUSTOMER NUMBER)
A
NAME
20
TEXT(CUSTOMER NAME)
A
ADDR1
20
TEXT(CUSTOMER ADDRESS)
A
ADDR2
20
TEXT(CUSTOMER ADDRESS)
A
CITY
20
TEXT(CUSTOMER CITY)
A
STATE
2
TEXT(CUSTOMER STATE)
A
ZIP
5 0
TEXT(CUSTOMER ZIP CODE)
A
ARBAL
10 2
TEXT(ACCOUNTS RECEIVABLE BALANCE)
Figure 196. DDS for master database file CUSMST (physical file)
410
A*****************************************************************
A*
FILE NAME: MAINMENU
*
A* RELATED PGMS: CUSMAIN
*
A*
DESCRIPTION: THIS IS THE DISPLAY FILE MAINMENU. IT HAS 1
*
A*
RECORD FORMAT CALLED HDRSCN.
*
A*****************************************************************
A
DSPSIZ(24 80 *DS3)
A
CHGINPDFT(CS)
A
PRINT(QSYSPRT)
A
INDARA
A
R HDRSCN
A
CA03(03 END OF INQUIRY)
A
CA05(05 MAINTENANCE MODE)
A
CA06(06 SEARCH BY ZIP MODE)
A
CA07(07 SEARCH BY NAME MODE)
A
2 4TIME
A
DSPATR(HI)
A
2 28CUSTOMER MAIN INQUIRY
A
DSPATR(HI)
A
DSPATR(RI)
A
2 70DATE
A
EDTCDE(Y)
A
DSPATR(HI)
A
6 5Press one of the following
A
6 32PF keys.
A
8 22F3 End Job
A
9 22F5 Maintain Customer File
A
10 22F6 Search Customer by Zip Code
A
11 22F7 Search Customer by Name
Figure 197. DDS for display device file MAINMENU
411
cf
workstn indds(indicators)
// Prototype definitions:
D CustMaintain
pr
D SearchZip
pr
D SearchName
pr
// Field definitions:
D indicators
ds
D
exitKey
D
maintainKey
D
srchZipKey
D
srchCustKey
extproc(CUSMNT)
extproc(SCHZIP)
extproc(SCHNAM)
n
n
n
n
overlay(indicators:3)
overlay(indicators:5)
overlay(indicators:6)
overlay(indicators:7)
/free
// Keep looping until exit key is pressed
dow 1;
// Display main menu
exfmt hdrscn;
// Perform requested action
if exitKey;
// Exit program
leave;
elseif maintainKey;
// Maintain customer data
CustMaintain();
elseif srchZipKey;
// Search customer data on ZIP code
SearchZip();
elseif srchCustKey;
// Search customer data on customer name
SearchName();
endif;
enddo;
*inlr = *on;
/end-free
412
Note: The *FIRST option specifies that the first module in the list, CUSMAIN,
is selected as the program entry procedure.
3. Call the program by entering:
CALL MYPROG
22:30:05
9/30/94
End Job
Maintain Customer File
Search Customer by Zip Code
Search Customer by Name
File Maintenance
The following illustrates a maintenance program using the WORKSTN file. It
allows you to add, delete, update, and display records of the master customer file.
413
File Maintenance
The DDS for the database file used by this program describe one record format:
CMLREC1. Each field in the record format is described, and the CUST field is
identified as the key field for the record format.
414
File Maintenance
415
File Maintenance
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
R CSTINQ
MODE
8A
1
1
2
2
2
4
CUST
NAME
R
R
O
B
4
6
ADDR1
ADDR2
CITY
STATE
B 10
ZIP
B 10
04
04
04
04
04
04
MODE1
R CSTBLD
23
O 23
MODE
1
1
2
2
2
CUST
NAME
ADDR1
ADDR2
CITY
STATE
ZIP
4
4
6
6
7
7
8
8
9
9
10
10
10
10
23
The DDS for the MNTMENU display device file contains three record formats:
HDRSCN, CSTINQ, and CSTBLD. The HDRSCN record prompts for the customer
number and the mode of processing. The CSTINQ record is used for the Update,
416
File Maintenance
Delete, and Display modes. The fields are defined as output/input (B in position
38). The fields are protected when Display or Delete mode is selected
(DSPATR(PR)). The CSTBLD record provides only input fields (I in position 38) for
a new record.
The HDRSCN record format contains the constant 'Customer File Maintenance'.
The ERRMSG keyword defines the messages to be displayed if an error occurs.
The CA keywords define the function keys that can be used and associate the
function keys with indicators in the RPG program.
uf a e
cf
e
k disk
workstn indds(indicators)
// Field definitions:
D indicators
D
exitKey
D
disableInput
D
addKey
D
updateKey
D
deleteKey
D
displayKey
D
prevKey
D
custExists
D
custNotFound
ds
n
n
n
n
n
n
n
n
n
overlay(indicators:3)
overlay(indicators:4)
overlay(indicators:5)
overlay(indicators:6)
overlay(indicators:7)
overlay(indicators:8)
overlay(indicators:12)
overlay(indicators:51)
overlay(indicators:52)
CSTKEY
KLIST
KFLD
CUST
417
File Maintenance
//*****************************************************************
//
MAINLINE
*
//*****************************************************************
/free
mode = DISPLAY;
exfmt hdrscn;
// Loop until exit key is pressed
dow not exitKey;
exsr SetMaintenanceMode;
if cust <> 0;
if mode = ADD;
exsr AddSub;
elseif mode = UPDATE;
exsr UpdateSub;
elseif mode = DELETE;
exsr DeleteSub;
elseif mode = DISPLAY;
exsr InquirySub;
endif;
endif;
exfmt hdrscn;
custExists
= *off;
CustNotFound = *off;
enddo;
*inlr = *on;
Figure 202. Source for module CUSMNT (Part 2 of 5)
418
File Maintenance
//****************************************************************
//
SUBROUTINE - AddSub
*
//
PURPOSE
- Add new customer to file
*
//****************************************************************
begsr AddSub;
// Is customer number already in file?
chain CstKey cmlrec1;
if %found(cusmstl1);
// Customer number is already being used
custExists = *on;
leavesr;
endif;
// Initialize new customer data
custExists
= *off;
// turn off error messages
CustNotFound = *off;
name = *blank;
addr1 = *blank;
addr2 = *blank;
city = *blank;
state = *blank;
zip = 0;
// Prompt for updated data for this customer record
exfmt cstbld;
// If OK, add customer to the customer file
if not *in12;
write cmlrec1;
endif;
endsr; // end of subroutine AddSub
//****************************************************************
//
SUBROUTINE - UpdateSub
*
//
PURPOSE
- Update customer master record
*
//****************************************************************
begsr UpdateSub;
// Lookup customer number
chain cstkey cmlrec1;
if not %found(cusmstl1);
// Customer is not found in file
custNotFound = *on;
leavesr;
endif;
// Display information for this customer
disableInput = *off;
exfmt cstinq;
if not prevKey;
// Update information in file
update cmlrec1;
else;
// If we dont want to update, at least unlock
// the record.
unlock cusmstl1;
endif;
endsr; // end of subroutine UpdateSub;
Figure 202. Source for module CUSMNT (Part 3 of 5)
419
File Maintenance
//****************************************************************
//
SUBROUTINE - DeleteSub
*
//
PURPOSE
- Delete customer master record
*
//****************************************************************
begsr DeleteSub;
// Lookup customer number
chain cstkey cmlrec1;
if not %found(cusmstl1);
// Customer is not found in file
custNotFound = *on;
leavesr;
endif;
// Display information for this customer
disableInput = *on;
exfmt cstinq;
if not prevKey;
// Delete customer record
delete cmlrec1;
else;
// If we dont want to delete, at least unlock
// the record.
unlock cusmstl1;
endif;
endsr; // end of subroutine DeleteSub
//****************************************************************
//
SUBROUTINE - InquirySub
*
//
PURPOSE
- Display customer master record
*
//****************************************************************
begsr InquirySub;
// Lookup customer number
chain(n) cstkey cmlrec1; // dont lock record
if not %found(cusmstl1);
// Customer is not found in file
custNotFound = *on;
leavesr;
endif;
// Display information for this customer
disableInput = *on;
exfmt cstinq;
endsr; // end of subroutine InquirySub;
Figure 202. Source for module CUSMNT (Part 4 of 5)
420
File Maintenance
//****************************************************************
//
SUBROUTINE - SetMaintenanceMode
*
//
PURPOSE
- Set maintenance mode
*
//****************************************************************
begsr SetMaintenanceMode;
if addKey;
mode = ADD;
elseif updateKey;
mode = UPDATE;
elseif deleteKey;
mode = DELETE;
elseif displayKey;
mode = DISPLAY;
endif;
endsr; // end of subroutine SetMaintenanceMode
/end-free
Figure 202. Source for module CUSMNT (Part 5 of 5)
This program maintains a customer master file for additions, changes, and
deletions. The program can also be used for inquiry.
The program first sets the default (display) mode of processing and displays the
customer maintenance prompt screen. The workstation user can press F3, which
turns on indicator 03, to request end of job. Otherwise, to work with customer
information, the user enters a customer number and presses Enter. The user can
change the mode of processing by pressing F5 (ADD), F6 (UPDATE), F7 (DELETE),
or F8 (DISPLAY).
To add a new record to the file, the program uses the customer number as the
search argument to chain to the master file. If the record does not exist in the file,
the program displays the CSTBLD screen to allow the user to enter a new
customer record. If the record is already in the file, an error message is displayed.
The user can press F12, which sets on indicator 12, to cancel the add operation and
release the record. Otherwise, to proceed with the add operation, the user enters
information for the new customer record in the input fields and writes the new
record to the master file.
To update, delete, or display an existing record, the program uses the customer
number as the search argument to chain to the master file. If a record for that
customer exists in the file, the program displays the customer file inquiry screen
CSTINQ. If the record is not in the file, an error message is displayed. If the mode
of processing is display or delete, the input fields are protected from modification.
Otherwise, to proceed with the customer record, the user can enter new
information in the customer record input fields. The user can press F12, which sets
on indicator 12, to cancel the update or delete operation, and release the record.
Display mode automatically releases the record when Enter is pressed.
In Figure 203 on page 422, the workstation user responds to the prompt by
entering customer number 00007 to display the customer record.
421
File Maintenance
DISPLAY MODE
22:30:21
00007
F3 End Job
F5 Add
9/30/94
F6 Update
F7 Delete
F8 Display
Because the customer record for customer number 00007 exists in the Master File,
the data is displayed as show in Figure 204.
DISPLAY MODE
22:31:06
Customer:
9/30/94
Mikhail Yuri
1001 Bay Street
Suite 1702
Livonia
MI
11201
The workstation user responds to the add prompt by entering a new customer
number as shown in Figure 205 on page 423.
422
File Maintenance
ADD MODE
22:31:43
00012
F3 End Job
F5 Add
9/30/94
F6 Update
F7 Delete
F8 Display
9/30/94
JUDAH GOULD
2074 BATHURST AVENUE
YORKTOWN
NY
Zip 70068
423
File Maintenance
DELETE MODE
22:32:55
00011
F3 End Job
F5 Add
9/30/94
F6 Update
F7 Delete
F8 Display
00010
F3 End Job
F5 Add
9/30/94
F6 Update
F7 Delete
F8 Display
424
The DDS for the database file used by this program describe one record format:
CMLREC2. The logical file CUSMSTL2 keyed by zip code is based on the physical
file CUSMST, as indicated by the PFILE keyword. The record format created by the
logical file will include only those fields specified in the logical file DDS. All other
fields will be excluded.
425
426
427
5p 0
n
ds
n
n
n
n
n
overlay(indicators:3)
overlay(indicators:4)
overlay(indicators:55)
overlay(indicators:61)
overlay(indicators:95)
C
C
428
zip
//*******************************************************************
//
MAINLINE
*
//*******************************************************************
/free
// Write out initial menu
write foot1;
write head;
exfmt prompt;
// loop until PF03 is pressed
dow not exitKey;
setll cstkey cmlrec2;
recordFound = %equal(cusmstl2);
if recordFound;
exsr ProcessSubfile;
endif;
// Quit loop if PF03 was pressed in the subfile display
if exitKey;
leave;
endif;
// If PF04 was pressed, then redo search with the same
// zip code.
if restartKey;
iter;
endif;
// Prompt for new zip code.
if not recordFound;
// If we didnt find a zip code, dont write header
// and footer again
write foot1;
write head;
endif;
zipNotFound = not recordFound;
exfmt prompt;
enddo;
*inlr = *on;
429
//****************************************************************
//
SUBROUTINE - ProcessSubfile
*
//
PURPOSE
- Process subfile and display it
*
//****************************************************************
begsr ProcessSubfile;
// Keep looping while roll up key is pressed
dou not rollupKey;
// Do we have more information to add to subfile?
if not %eof(cusmstl2);
// Clear and fill subfile with customer data
exsr ClearSubfile;
exsr FillSubfile;
endif;
// Write out subfile and wait for response
write foot2;
exfmt subctl;
enddo;
endsr;
//****************************************************************
//
SUBROUTINE - FillSubfile
*
//
PURPOSE
- Fill subfile with customer records matching
*
//
specified zip code.
*
//****************************************************************
begsr FillSubfile;
// Loop through all customer records with specified zip code
recnum = 0;
dou %eof(szipmenu);
// Read next record with specified zip code
reade zip cmlrec2;
if %eof(cusmstl2);
// If no more records, were done
leavesr;
endif;
// Add information about this record to the subfile
recnum = recnum + 1;
write subfile;
enddo;
endsr; // end of subroutine FillSubfile;
//****************************************************************
//
SUBROUTINE - ClearSubfile
*
//
PURPOSE
- Clear subfile records
*
//****************************************************************
begsr ClearSubfile;
sflClear = *on;
write subctl;
sflClear = *off;
endsr;
/end-free
Figure 211. Source for module SCHZIP (Part 3 of 3)
430
431
22:34:38
9/30/94
ENTER - Continue
F3 - End Job
22:34:45
Zip Code
9/30/94
11201
Customer Name
Rick Coupland
Mikhail Yuri
Karyn Sanders
ENTER - Continue
A/R Balance
300.00
150.00
5.00
F3 - End Job
432
The DDS for the database file used in this program defines one record format
named CUSREC and identifies the NAME field as the key fields.
433
434
A
A
A
A
A
A
A
A
A
A
A
A
A
A 55
A N55
A N55
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
SRCNAM
R SUBFILE
SEL
1A
ZIP
CUST
NAME
R SUBCTL
R
R
R
O
O
O
SRCNAM
DSPATR(HI)
5 23REFFLD(NAME CUSMSTL3)
DSPATR(CS)
SFL
CHANGE(99 FIELD CHANGED)
9 8DSPATR(CS)
VALUES( X)
9 54
9 43
9 17
SFLCTL(SUBFILE)
SFLSIZ(0013)
SFLPAG(0013)
SFLCLR
SFLDSPCTL
SFLDSP
ROLLUP(95 ROLL UP)
OVERLAY
CF04(04 RESTART SEARCH NAME)
5 4Search Name
5 17REFFLD(NAME CUSMSTL3)
DSPATR(HI)
7 6Select
DSPATR(HI)
8 6 "X"
Customer Name
DSPATR(HI)
DSPATR(UL)
8 42 Number
Zip Code
DSPATR(HI)
DSPATR(UL)
R CUSDSP
CUST
5S 0O
NAME
20A
ADDR1
ADDR2
20A
20A
O
O
CITY
20A
STATE
2A
ZIP
5S 0O
ARBAL
10Y 2O
6
6
8
8
10
10
11
13
13
15
15
15
15
17
17
OVERLAY
25Customer
35DSPATR(HI)
25Name
35DSPATR(HI)
25Address
35DSPATR(HI)
35DSPATR(HI)
25City
35DSPATR(HI)
25State
35DSPATR(HI)
41Zip Code
50DSPATR(HI)
25A/R Balance
42DSPATR(HI)
EDTCDE(J)
The DDS for the SNAMMENU display device file contains seven record formats:
HEAD, FOOT1, FOOT2, PROMPT, SUBFILE, SUBCTL, and CUSDSP.
The PROMPT record format requests the user to enter a zip code and search name.
If no entry is made, the display starts at the beginning of the file. The user can
press F3, which sets on indicator 03, to end the program.
The SUBFILE record format must be defined immediately preceding the
subfile-control record format SUBCTL. The subfile-record format defined with the
keyword SFL, describes each field in the record, and specifies the location where
the first record is to appear on the display (here, on line 9).
435
436
//****************************************************************
// PROGRAM NAME:
SCHNAM
*
// RELATED FILES: CUSMSTL3 (LOGICAL FILE)
*
//
SNAMMENU (WORKSTN FILE)
*
// DESCRIPTION:
This program shows a customer master search
*
//
program using workstn subfile processing.
*
//
This program prompts the user for the customer*
//
name and uses it to position the cusmstl3
*
//
file by the setll operation. Then it displays *
//
the records using subfiles.
*
//
To fill another page, press the rollup key.
*
//
To display customer detail, enter X beside *
//
that customer and press enter.
*
//
To quit the program, press PF3.
*
//****************************************************************
Fcusmstl3
Fsnammenu
F
if
cf
e
e
k disk
workstn sfile(subfile:recnum)
indds(indicators)
// Field definitions:
D recnum
s
D indicators
D
exitKey
D
restartKey
D
sflClear
D
rollupKey
5p 0
ds
n
n
n
n
overlay(indicators:3)
overlay(indicators:4)
overlay(indicators:55)
overlay(indicators:95)
C
C
C
C
srcnam
name
437
//******************************************************************
//
MAINLINE
*
//******************************************************************
/free
write foot1;
write head;
exfmt prompt;
// loop until exit key is pressed
dow not exitKey;
setll cstkey cusrec;
exsr ProcessSubfile;
exsr DisplayCustomerDetail;
// If exit key pressed in subfile display, leave loop
if exitKey;
leave;
endif;
// If restart key pressed in subfile display, repeat loop
if restartKey;
iter;
endif;
write foot1;
write head;
exfmt prompt;
enddo;
*inlr = *on;
//*****************************************************************
// SUBROUTINE - ProcessSubfile
*
// PURPOSE
- Process subfile and display
*
//*****************************************************************
begsr ProcessSubfile;
// Keep looping while roll up key is pressed
dou not rollupKey;
// Do we have more information to add to subfile?
if not %eof(cusmstl3);
// Clear and fill subfile with customer data
exsr ClearSubfile;
exsr FillSubfile;
endif;
// Write out subfile and wait for response
write foot2;
exfmt subctl;
enddo;
endsr;
438
//******************************************************************
//
SUBROUTINE - FillSubfile
*
//
PURPOSE
- Fill subfile
*
//******************************************************************
begsr FillSubfile;
// Loop through all customer records with specified zip code
recnum = 0;
dou %eof(snammenu);
// Read next record with specified zip code
read cusrec;
if %eof(cusmstl3);
// If no more records, were done
leavesr;
endif;
// Add information about this record to the subfile
recnum = recnum + 1;
sel = *blank;
write subfile;
enddo;
endsr;
//****************************************************************
//
SUBROUTINE - ClearSubfile
*
//
PURPOSE
- Clear subfile records
*
//****************************************************************
begsr ClearSubfile;
sflClear = *on;
write subctl;
sflClear = *off;
endsr;
439
//*****************************************************************
// SUBROUTINE - DisplayCustomerDetail
*
// PURPOSE
- Display selected customer records
*
//*****************************************************************
begsr DisplayCustomerDetail;
// Loop through all changed record in subfile
readc subfile;
dow not %eof(snammenu);
// Restart the display of requested customer records
restartKey = *on;
// Lookup customer record and display it
chain zipkey cusrec;
exfmt cusdsp;
// If exit key pressed, exit loop
if exitKey;
leave;
endif;
readc subfile;
enddo;
endsr;
/end-free
Figure 216. Source for module SCHNAM (Part 4 of 4)
The file description specifications identify the disk file to be searched and the
display device file to be used (SNAMMENU). The SFILE keyword for the
WORKSTN file identifies the record format (SUBFILE) to be used as a subfile. The
relative-record-number field (RECNUM) specifies which record within the subfile
is being accessed.
The program displays the PROMPT record format and waits for the workstation
user's response. F3 sets on indicator 03, which controls the end of the program. The
name (NAME) is used as the key to position the CUSMSTL3 file by the SETLL
operation. Notice that the record format name CUSREC is used in the SETLL
operation instead of the file name CUSMSTL3.
The SFLPRC subroutine handles the processing for the subfile: clearing, filling, and
displaying. The subfile is prepared for additional requests in subroutine SFLCLR. If
indicator 55 is on, no action occurs on the display, but the main storage area for
the subfile records is cleared. The SFLFIL routine fills the subfile with records. A
record is read from the CUSMSTL3 file, the record count (RECNUM) is
incremented, and the record is written to the subfile. This subroutine is repeated
until either the subfile is full (indicator 21 on the WRITE operation) or end of file
occurs on the CUSMSTL3 file (indicator 71 on the READ operation). When the
subfile is full or end of file occurs, the subfile is written to the display by the
EXFMT operation by the subfile-control record control format. The user reviews
the display and decides:
v To end the program by pressing F3.
v To restart the subfile by pressing F4. The PROMPT record format is not
displayed, and the subfile is displayed starting over with the same name.
440
22:35:26
9/30/94
JUDAH GOULD
ENTER - Continue
F3 - End Job
22:35:43
Search Name
Select
"X"
X
9/30/94
JUDAH GOULD
Customer Name
JUDAH GOULD
JUDAH GOULD
ENTER - Continue
F3 - End Job
Number
00012
00209
Zip Code
70068
31088
F4 - Restart Name
The detailed information for the customer selected is shown in Figure 219 on page
442. At this point the user selects the appropriate function key to continue or end
441
23:39:48
Customer
00012
Name
JUDAH GOULD
Address
City
YORKTOWN
State
NY
A/R Balance
ENTER - Continue
F3 - End Job
9/30/94
F4 - Restart Name
Figure 219. 'Customer Search and Inquiry by Name' detailed information screen
442
Part 5. Appendixes
443
444
Compiling
1. If you specify CVTOPT(*NONE) in OPM RPG, all externally described fields
that are of a type or with attributes not supported by RPG will be ignored. If
you specify CVTOPT(*NONE) in ILE RPG, all externally described fields will
be brought into the program with the same type as specified in the external
description.
2. In RPG IV there is no dependency between DATEDIT and DECEDIT in the
control specification.
3. Regarding the ILE RPG create commands (CRTBNDRPG and CRTRPGMOD):
v The IGNDECERR parameter on the CRTRPGPGM command has been
replaced by the FIXNBR parameter on the ILE RPG create commands.
IGNDECDTA ignores any decimal data errors and continues with the next
machine instruction. In some cases, this can cause fields to be updated with
incorrect and sometimes unpredictable values. FIXNBR corrects the data in a
predictable manner before it is used.
v There is a new parameter, TRUNCNBR, for controlling whether numeric
overflow is allowed.
v There are no auto report features or commands in RPG IV.
v You cannot request an MI listing from the compiler.
4. In a compiler listing, line numbers start at 1 and increment by 1 for each line of
source or generated specifications, when the default OPTION(*NOSRCSTMT) is
specified. If OPTION(*SRCSTMT) is specified, sequence numbers are printed
instead of line numbers. Source IDs are numeric, that is, there are no more
AA000100 line numbers for /COPY members or expanded DDS.
5. RPG IV requires that all compiler directives appear before compile-time data,
including /TITLE. When RPG IV encounters a /TITLE directive, it will treat it
as data. (RPG III treats /TITLE specifications as compiler directives anywhere
in the source.)
The Conversion Aid will remove any /TITLE specifications it encounters in
compile-time data.
6. ILE RPG is more rigorous in detecting field overlap in data structures. For
some calculation operations involving overlapping operands, ILE RPG issues a
message while the OPM compiler does not.
7. In ILE RPG the word NOT cannot be used as a variable name. NOT is a special
word that is used as an operator in expressions.
8. At compile time, the source is read using the CCSID of the main source file,
while for OPM RPG, the source is read using the CCSID of the job.
Running
1. The FREE operation is not supported by RPG IV. See Unsupported RPG III
Features on page 470.
Copyright IBM Corp. 1994, 2010
445
#
#
#
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If *INLR was on when an OPM RPG program was cancelled, it will still be on
for the next call to the program and the RPG cycle will proceed to *TERM
without performing the *DETC part of the cycle.
8. If decimal-data errors occur during the initialization of a zoned-decimal or
packed-decimal subfield, then the reset values (those values use to restore the
subfield with the RESET operation) may not be valid. For example, it may be
that the subfield was not initialized, or that it was overlaid on another
initialized subfield of a different type. If a RESET operation is attempted for
that subfield, then in OPM RPG/400, a decimal-data error would occur.
However, a RESET to the same subfield in ILE RPG will complete successfully;
after the RESET, the subfield has the same invalid value. As a result, attempts
to use the value will get a decimal data error.
9. In ILE RPG, positions 254-263 of the program status data structure (PSDS)
contain the user name of the originating job. In OPM RPG, these positions
reflect the current user profile. The current user profile in ILE RPG can be
found in positions 358-367.
446
I/O
1. In ILE RPG you can read a record in a file opened for update, and created or
overridden with SHARE(*YES), and then update this locked record in another
program that has opened the same file for update.
2. If a program performs a sequential input operation, and it results in an
end-of-file condition, the normal operation is for any subsequent sequential
Appendix A. Behavioral Differences Between OPM RPG/400 and ILE RPG for AS/400
447
5.
6.
7.
8.
9.
10.
For example, in RPG III, if you define a file as an update file, then you must
have an UPDAT operation later in the program. This is no longer true in RPG
IV. However, your file definition still must be consistent with the I/O
operations present in the program. So if you have an UPDATE operation in
your source, the file must be defined as an update file.
ILE RPG will allow record blocking even if the COMMIT keyword is specified
on the file description specification.
In RPG IV, a file opened for update will also be opened as delete capable. You
do not need any DELETE operations to make it delete capable.
In RPG IV, you do not have to code an actual number for the number of
devices that will be used by a multiple-device file. If you specify
MAXDEV(*FILE) on a file description specification, then the number of save
areas created for SAVEDS and SAVEIND is based on the number of devices
that your file can handle. (The SAVEDS, SAVEIND, and MAXDEV keywords
on an RPG IV file description specification correspond to the SAVDS, IND,
and NUM options on a RPG III file description specification continuation line,
respectively.)
In ILE RPG, the total number of program devices that can be acquired by the
program cannot be different from the maximum number of devices defined in
the device file. OPM RPG/400 allows this through the NUM option.
In ILE RPG, the ACQ and REL operation codes can be used with single device
files.
In ILE RPG, the relative record number and key fields in the database-specific
feedback section of the INFDS are updated on each input operation when
doing blocked reads.
When a referential constraint error occurs in OPM RPG/400, the status code is
set to "01299" (I/O error). In ILE RPG, the status code is set to "01022",
"01222", or "01299", depending on the type of referential constraint error that
occurs:
v If data management is not able to allocate a record due to a referential
constraint error, a CPF502E notify message is issued. ILE RPG will set the
status code to "01222" and OPM RPG/400 will set the status code to
"01299".
If you have no error indicator, 'E' extender, or INFSR error subroutine, ILE
RPG will issue the RNQ1222 inquiry message, and OPM RPG/400 will
issue the RPG1299 inquiry message. The main difference between these two
messages is that RNQ1222 allows you to retry the operation.
v If data management detects a referential constraint error that has caused it
to issue either a CPF503A, CPF502D, or CPF502F notify message, ILE RPG
will set the status code to "01022" and OPM RPG/400 will set the status
code to "01299".
448
|
|
|
|
|
|
|
14. ILE RPG allows the To File and the From File specified for prerun-time arrays
and tables to be different. In OPM RPG, both file names must be the same; if
they are different the diagnostic message QRG3038 is issued.
15. When translation of a RAF-Controlled file is specified, the results using ILE
RPG may differ from OPM RPG/400, depending on the translation table. This
is due to the different sequence of operations. In OPM RPG/400 the sequence
is: retrieve record, translate and compare; in ILE RPG the sequence is:
translate, compare and retrieve record.
16. The RPG/400 compiler considers the DELET operation to be an output
operation. If an update-capable record format has a DELET operation and a
CLEAR or RESET operation, but no UPDAT operation, the RPG/400 compiler
will clear or reset the fields of the record format, but the ILE RPG compiler
will not clear or reset the fields. To have the ILE RPG compiler clear or reset
the fields, *ALL can be specified in Factor 2 of the operation, or an UPDATE
operation can be added to the program.
Appendix A. Behavioral Differences Between OPM RPG/400 and ILE RPG for AS/400
449
450
Conversion Overview
You convert source programs to the RPG IV source format by calling the
Conversion Aid through the CL command Convert RPG Source (CVTRPGSRC).
The Conversion Aid converts:
v A single member
v All members in a source physical file
v All members with a common member-name prefix in the same file
To minimize the likelihood of there being conversion problems, you can optionally
have the /COPY members included in the converted source code. For convenience
in reading the code, you can also optionally include specification templates in the
converted source code.
The Conversion Aid converts each source member on a line-by-line basis. After
each member conversion, it updates a log file on the status of the conversion if you
specified a log file on the command. You can also obtain a conversion report that
includes information such as conversion errors, /COPY statements, CALL
operations, and conversion status.
The Conversion Aid assumes that your source code is free of any compilation
errors. If this is the case, then it will successfully convert most of your source code.
In some cases, there may be a small amount of code that you may have to convert
manually. Some of these cases are identified by the Conversion Aid. Others are not
detected until you attempt to compile the converted source. To see which ones the
Conversion Aid can identify, you can run the Conversion Aid using the
unconverted member as input, and specify a conversion report but no output
member. For information on the types of coding that cannot be converted, see
Resolving Conversion Problems on page 469.
File Considerations
The Conversion Aid operates on file members. This section presents information
on different aspects of files that must be taken into consideration when using the
Conversion Aid.
451
Conversion Overview
Convert?
RPG
Yes
RPGLE
RPG38
Yes
RPGLE
RPT
Yes
RPGLE
RPT38
Yes
RPGLE
'blank'
Yes
RPGLE
RPG36
No
N/A
RPT36
No
N/A
SQLRPG
Yes
SQLRPGLE
No
N/A
If the source member type is 'blank', then the Conversion Aid will assume it has a
member type of RPG. If the source member type is blank for an auto report source
member, then you should assign the correct source member type (RPT or RPT38)
to the member before converting it. If you do, then the Conversion Aid will
automatically expand the auto report source member so that it can be converted
properly. The expansion is necessary since ILE RPG does not support auto report
source members.
For more information on converting auto report source members, see Converting
Auto Report Source Members on page 461.
80
20
Seq. No.
Code
Comments
If the converted source file has a record length less than 92 characters then an error
message will be issued and the conversion will stop. This is because the record
length is not long enough to contain the 80 characters allowed for source code and
so some code is likely to be lost.
452
Conversion Overview
The name of the converted source member(s) depends on whether you are
converting one or several members. If you are converting one member, the default
is to give the converted source member the same name as the unconverted
member. You can, of course, specify a different name for the output member. If you
are converting all source members in a file, or a group of them using a generic
name, then the members will automatically be given the same name as the
unconverted source members.
Note that specifying the file, library and member name for the converted output is
optional. If you do not specify any of these names, the converted output will be
placed in the file QRPGLESRC and have a member name the same as the
unconverted member name. (The library list will be searched for the file
QRPGLESRC.)
You must have object management, operational and add authority to the log file
that is accessed by the Conversion Aid.
For information on using the log file see Using the Log File on page 467.
453
Conversion Overview
v The Conversion Aid does not support converting RPG II source programs to the
RPG IV source format. However, you can use the RPG II to RPG III
Conversion Aid first and then the RPG III to RPG IV Conversion Aid.
v The Conversion Aid does not re-engineer source code, except where required
(for example, the number of conditioning indicators.)
v The Conversion Aid does not create files. The log file and the output file must
exist prior to running it.
454
Pgm: B,I
REXX: B,I
Exec
*LIBL/
CVTRPGSRC FROMFILE (
source-file-name
*CURLIB/
library-name/
FROMMBR (
source-file-member-name
*ALL
generic*-member-name
*LIBL/
QRPGLESRC
source-file-name
TOFILE (
*CURLIB/
library-name/
*NONE
455
TOMBR (
*FROMMBR
source-file-member-name
EXPCPY (
*NO
*YES
)
CVTRPT (
*YES
*NO
SECLVL (
*NO
*YES
INSRTPL (
*NO
*YES
*LIBL/
LOGFILE (
QRNCVTLG
log-file-name
*CURLIB/
library-name/
*NONE
LOGMBR (
*FIRST
*LAST
log-file-member-name
Notes:
1
The parameters and their possible values follow the syntax diagram. If you need
prompting, type CVTRPGSRC and press F4. The CVTRPGSRC screen appears, lists
the parameters, and supplies default values. For a description of a parameter on
the display, place your cursor on the parameter and press F1. Extended help for all
of the parameters is available by pressing F1 on any parameter and then pressing
F2.
FROMFILE
Specifies the name of the source file that contains the RPG III or RPG source
code to be converted and the library where the source file is stored. This is a
required parameter; there is no default file name.
source-file-name
Enter the name of the source file that contains the source member(s) to be
converted.
*LIBL
The system searches the library list to find the library where the source file
is stored.
*CURLIB
The current library is used to find the source file. If you have not specified
a current library, then the library QGPL is used.
library-name
Enter the name of the library where the source file is stored.
456
457
458
This will result in the conversion of the specified source member. The output will
be placed in the file QRPGLESRC in whichever library in the library list contains
this file. The /COPY members will not be expanded, no specification templates
will be inserted, and the conversion report will be produced. The log file
QRNCVTLG will be updated.
Note: The files QRPGLESRC and QRNCVTLG must already exist.
459
FROMFILE(OLDRPG/QRPGSRC)
FROMMBR(*ALL)
TOFILE(NEWRPG/QRPGLESRC)
TOMBR(*FROMMBR)
This command converts all of the source members in library OLDRPG in the
source physical file QRPGSRC. The new members are created in library NEWRPG
in the source physical file QRPGLESRC.
If you prefer to keep all source (DDS source, RPG source, etc.) in the same file, you
can still convert the RPG source members in one step, by specifying
FROMMBR(*ALL). The Conversion Aid will only convert members with a valid
RPG type (see Table 57 on page 452).
FROMFILE(OLDRPG/QRPGSRC)
FROMMBR(PAY*)
TOFILE(NEWRPG/QRPGLESRC)
TOMBR(*FROMMBR)
This command converts all of the source members in library OLDRPG in the
source physical file QRPGSRC. The new members are created in library NEWRPG
in the source physical file QRPGLESRC.
FROMFILE(OLDRPG/QRPGSRC)
FROMMBR(PAYROLL)
TOFILE(*NONE)
460
461
462
H
FFILE1
IF E
DISK
FQSYSPRT O
F
132
OF
LPRINTER
LQSYSPRT 60FL 56OL
E
ARR1
3
3 1
E
ARR2
3
3 1
IFORMAT1
I
OLDNAME
I* DATA STRUCTURE COMMENT
IDS1
DS
I
1
I* NAMED CONSTANT COMMENT
I
XYZ
C
I
4
C
ARR1,3
DSPLY
C
READ FORMAT1
C
NAME
DSPLY
C
SETON
C
EXCPTOUTPUT
OQSYSPRT E
01
OUTPUT
O
ARR2,3
10
TSTPGM
COMM1
COMM2
NAME
3 FIELD1
CONST1
6 ARR1
COMM3
01
LR
**
123
**
456
Figure 221. RPG III Source for TEST1
FROMFILE(MYLIB/QRPGSRC) FROMMBR(TEST1)
TOFILE(MYLIB/QRPGLESRC) INSRTPL(*YES)
463
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.....H*unctions+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comments+++++++++
H DFTNAME(TSTPGM)
.....F*ilename++IPEASFRlen+LKlen+AIDevice+.Functions++++++++++++++++++++++++++++Comments+++++++++
FFILE1
IF
E
DISK
COMM1
FQSYSPRT
O
F 132
PRINTER OFLIND(*INOF)
F
FORMLEN(60)
F
FORMOFL(56)
.....D*ame+++++++++++ETDsFrom+++To/L+++IDc.Functions++++++++++++++++++++++++++++Comments+++++++++
D ARR2
S
1
DIM(3) CTDATA PERRCD(3)
D* DATA STRUCTURE COMMENT
D DS1
DS
D FIELD1
1
3
D ARR1
4
6
D
DIM(3) CTDATA PERRCD(3)
COMM2
D* NAMED CONSTANT COMMENT
D CONST1
C
CONST(XYZ)
COMM3
.....I*ilename++SqNORiPos1+NCCPos2+NCCPos3+NCC..................................Comments+++++++++
.....I*.............Ext_field+Fmt+SPFrom+To+++DcField+++++++++L1M1FrP1MnZr......Comments+++++++++
IFORMAT1
I
OLDNAME
NAME
.....C*0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comments+++++++++
C
ARR1(3)
DSPLY
C
READ
FORMAT1
01
C
NAME
DSPLY
C
SETON
LR
C
EXCEPT
OUTPUT
OQSYSPRT
E
OUTPUT
01
O
ARR2(3)
10
**CTDATA ARR1
123
**CTDATA ARR2
456
v
v
v
v
v
464
The converted source contains specification templates for the new types, since
INSRTPL(*YES) was specified on CVTRPGSRC.
The control, file, and definition specifications are keyword-oriented. See lines 2,
4 - 7, and 9 - 16.
The ILE member has a new specification type, definition. It is used to define
standalone fields, arrays and named constants as well as data structures.
In this example,
ARR2 is defined as a standalone array (Line 9)
Data structure DS1 is defined as a data structure with two subfields FIELD1
and ARR1 (Lines 11 - 14)
Constant CONST1 is defined as a constant (Line 16)
The input (I) specifications are now used only to define records and fields of a
file. See Lines 19 - 20.
The extension (E) specifications have been eliminated. Arrays and tables are now
defined using definition specifications.
Record address file (RAF) entries on extension specifications have been replaced
by the keyword RAFDATA on the File Description specification.
The line counter specifications have been eliminated. They have been replaced
by the keywords FORMLEN and FORMOFL on the file description specification.
See Lines 6 and 7.
465
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
IBM
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
ILE RPG
ISERIES1
CVTRPGSRC
DAVE
QRPGSRC
MYLIB
REPORT
QRPGLESRC
MYLIB
*FROMMBR
*NONE
08/15/02 20:41:35
Page 1
*FIRST
*NO
*YES
*YES
*YES
The source section includes lines that have informational, warning, or error
messages associated with them. These lines have an asterisk (*) in column 1 for
ease of browsing in SEU. The message summary contains all three message types.
Two informational messages which may be of particular interest are:
v RNM0508 flags /COPY statements
v RNM0511 flags CALL operations
All /COPY members in an program must be converted in order for the
corresponding ILE RPG program to compile without errors. Similarly, you may
want to convert all members related by CALL at the same time. Use this part of
the report to assist you in identifying these members. Figure 224 shows the source
section for the sample conversion.
5769WDS V5R2M0 020719
From file . . . . .
To file. . . . . . .
Log file . . . . . .
Sequence
Number
000002
*RNM0511
000003
*RNM0508
000004
*RNM0506
RN
IBM ILE RPG
ISERIES1
08/15/02 20:41:35
Page
2
. . . . . . : MYLIB/QRPGSRC(REPORT)
. . . . . . : MYLIB/QRPGLESRC(REPORT)
. . . . . . : *NONE
C o n v e r s i o n
R e p o r t
<----------------------- Source Specifications ---------------------------><-------------- Comments --------------> Page
....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+...10....+...11....+...12 Line
C
CALL
PROG1
00 CALL operation code found.
C/COPY COPYCODE
00 /COPY compiler directive found.
C
FREE
PROG2
30 FREE operation code is not supported in RPG IV.
* * * * *
E N D
O F
S O U R C E
* * * * *
The message summary of the listing shows you the different messages that were
issued. If you specify SECLVL(*YES), second-level messages will appear in the
message summary. Figure 225 on page 467 shows the messages section for the
sample conversion, including second-level messages.
466
5769WDS V5R2M0
020719 RN
Msg id Sv Number
*RNM0508 00
1
*RNM0511 00
*RNM0506 30
* * * * *
08/15/02 20:41:35
Page
The final summary of the listing provides message and record statistics. A final
status message is also placed in the job log. Figure 226 shows the messages section
for the sample conversion.
F i n a l S u m m a r y
Message Totals:
Information (00) . . . . . . . :
2
Warning
(10) . . . . . . . :
0
Severe Error (30+) . . . . . . :
1
--------------------------------- ------Total . . . . . . . . . . . . . :
3
Source Totals:
Original Records Read . . . . . . :
3
Converted Records Written . . . . :
4
Highest Severity Message Issued . :
30
* * * * * E N D O F F I N A L S U M M A R Y * * * * *
* * * * * E N D O F C O N V E R S I O N * * * * *
467
468
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
R QRNCVTFM
LGCENT
1A
LGDATE
6A
LGTIME
6A
LGSYST
8A
LGUSER
10A
LGFRFL
10A
LGFRLB
10A
LGFRMR
10A
LGFRMT
10A
LGTOFL
10A
LGTOLB
10A
LGTOMR
10A
LGTOMT
10A
LGLGFL
10A
LGLGLB
10A
LGLGMR
10A
LGCEXP
1A
LGERRL
1A
LGSECL
1A
LGINSR
1A
LGSTAT
2A
LGMRDS
50A
COLHDG(CVT CENT)
TEXT(Conversion Century: 0-20th 1-+
21st)
COLHDG(CVT DATE)
TEXT(Conversion Date : format is Y+
YMMDD)
COLHDG(CVT TIME)
TEXT(Conversion Time : format is H+
HMMSS)
COLHDG(CVT SYST)
TEXT(Name of the system running co+
nversion)
COLHDG(CVT USER)
TEXT(User Profile name of the user+
running conversion)
COLHDG(FROM FILE)
TEXT(From File)
COLHDG(FROM LIB)
TEXT(From Library)
COLHDG(FROM MBR)
TEXT(From Member)
COLHDG(FMBR TYPE)
TEXT(From Member Type)
COLHDG(TO FILE)
TEXT(To File)
COLHDG(TO LIB)
TEXT(To Library)
COLHDG(TO MBR)
TEXT(To Member)
COLHDG(TMBR TYPE)
TEXT(To Member Type)
COLHDG(LOG FILE)
TEXT(Log File)
COLHDG(LOG LIB)
TEXT(Log Library)
COLHDG(LOG MBR)
TEXT(Log Member)
COLHDG(CPY EXP)
TEXT(Copy Member Expanded: Y=Yes, +
N=No)
COLHDG(CVT RPT)
TEXT(Conversion Report Printed: Y=+
Yes, N=No)
COLHDG(SEC LVL)
TEXT(Second Level Text Printed: Y=+
Yes, N=No)
COLHDG(INSR TPL)
TEXT(Template Inserted: Y=Yes, N=N+
o)
COLHDG(CVT STAT)
TEXT(Conversion Status)
COLHDG(MBR DESC)
TEXT(Member Description)
Figure 227. DDS for model log file QARNCVTLG in library QRPGLE
469
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
To replace the function of the FREE operation, you must first determine why the
FREE operation was being used.
v If the FREE operation was being used to ensure that the program would be
initialized on the next call to the program, change the called program so that it
may be called with a special parameter (or no parameter), indicating that it
should simply set on LR and return. Then, instead of coding the FREE
operation, call the program with the special "free" parameter.
* RPG III coding
C
C
...
C
...
C
C
CALL MYPGM
PARM
P1
FREE MYPGM
CALL MYPGM
PARM
P1
call
parm
...
470
MYPGM_var
p1
v If the FREE operation was being used to cause the program containing the FREE
operation to resolve to the program again on the next call to the program, then
you can change your calling program so that you call using a character variable;
to cause your called program to be resolved again, you must use the character
variable to call a different program at the point where you would do your FREE;
then when you use the character variable on the next CALL operation, the
system would perform the resolve to your program again. Create a very
quick-running program to be called for the "FREE" function, such as an ILE RPG
program that simply has a RETURN operation.
* RPG III coding
C
C
...
C
...
C
C
CALL MYPGM
PARM
P1
FREE MYPGM
CALL MYPGM
PARM
P1
21a
INZ(MYPGM)
MYPGM_var
p1
for the next call
MYPGM_var = MYLIB/FREEPGM
MYPGM_VAR
MYPGM_var
MYPGM_var
p1
To replace the function of the DEBUG operation, use an interactive debugger. For
information on program debugging see Chapter 12, Debugging Programs, on
page 229.
471
Merging Problems
Because of differences between the RPG III and RPG IV languages, the Conversion
Aid must reorder certain source statements. An example of this reordering is
shown in Example of Source Conversion on page 462 for the RPG III source
member TEST1. If you compare the placement of the data structure DS1 in
Figure 221 on page 463 and in Figure 222 on page 464, you can see that the data
structure DS1 was moved so that it precedes the record format FORMAT1.
Now suppose that the RPG III member TEST1 was split into two members, TEST2
and COPYDS1, where the data structure DS1 and the named constant CONST1 are
in a copy member COPYDS1. This copy member is included in source TEST2.
Figure 228 and Figure 229 show the source for TEST2 and COPYDS1 respectively.
H
FFILE1
IF E
DISK
FQSYSPRT O
F
132
OF
LPRINTER
LQSYSPRT 60FL 56OL
E
ARR1
3
3 1
E
ARR2
3
3 1
IFORMAT1
I
OLDNAME
/COPY COPYDS1
C
ARR1,3
DSPLY
C
READ FORMAT1
C
NAME
DSPLY
C
SETON
C
EXCPTOUTPUT
OQSYSPRT E
01
OUTPUT
O
ARR2,3
10
TSTPGM
COMM1
COMM2
NAME
01
LR
**
123
**
456
Figure 228. RPG III Source for TEST2
3 FIELD1
CONST1
6 ARR1
COMM3
In this situation, the Conversion Aid would convert both member TEST2 and the
copy member COPYDS1 correctly. However, when the copy member is included at
compile time, it will be inserted below FORMAT1, because this is where the
/COPY directive is located. As a result, all source lines in the copy member
COPYDS1 will get a "source record is out of sequence" error. In RPG IV, definition
specifications must precede input specifications.
Note that the Conversion Aid could not move the /COPY directive above
FORMAT1 because the contents of /COPY member are unknown.
There are two methods of correcting this type of problem:
472
Context-Sensitive Problems
In RPG III, there are occasions when it is impossible to determine the type of
specifications in a /COPY member without the context of the surrounding
specifications of the primary source member. There are two instances of this
problem:
v In data structure subfields or program-described file fields
I*
I*
I*
I*
I*
I*
I
I
Figure 230. RPG III /COPY file with input fields only
473
Remember that you have two ways of correcting these types of problems. Either
use the EXPCPY(*YES) option of the CVTRPGSRC command, or manually correct
the code after conversion.
474
A
A
A
R RECORD
CHARACTER
ARRAY
10
10
E
IDSONE
C
C
ARRAY
E DSEXTREC
CHAR
DSPLY
SETON
10
1
LR
Figure 234. RPG III source using external data structure with array
D ARRAY
D DSONE
C
CHAR
C
S
E DS
DIM(10)
EXTNAME(EXTREC)
DSPLY
SETON
LR
Figure 235. RPG IV source with two definitions for the array
D DSONE
D ARRAY
C
CHAR
C
E DS
E
EXTNAME(EXTREC)
DIM(10)
DSPLY
SETON
LR
Figure 236. Corrected RPG IV source with a single definition for the array
IDSONE
I
I I
C
C
E DSEXTREC
CHARACTER
XYZ
CHAR
DSPLY
SETON
CHAR
CHAR
LR
Figure 237. RPG III source with renamed and initialized external subfield
475
D DSONE
D CHAR
D CHAR
C
CHAR
C
E DS
E
E
EXTNAME(EXTREC)
EXTFLD(CHARACTER)
INZ(XYZ)
DSPLY
SETON
LR
Figure 238. RPG IV source with two definitions for renamed subfield
D DSONE
D CHAR
C
CHAR
C
E DS
E
EXTNAME(EXTREC)
EXTFLD(CHARACTER) INZ(XYZ)
DSPLY
SETON
LR
Run-time Differences
If you have prerun-time arrays that overlap in data structures, the order of loading
these arrays at run time may be different in RPG III and in RPG IV. This difference
in order can cause the data in the overlapping section to differ. The order in which
the arrays are loaded is the order in which they are encountered in the source. This
order may have changed when the arrays were been merged with the subfields
during conversion.
In general, you should avoid situations where an application consists of OPM and
ILE programs that are split across the OPM default activation group and a named
activation group. When spilt across these two activation groups, you are mixing
OPM behavior with ILE behavior and your results may be hard to predict. Refer to
Chapter 3, Program Creation Strategies, on page 23 or ILE Concepts for further
information.
476
Using CL Commands
Control Language (CL) commands, parameters, and keywords can be entered in
either uppercase or lowercase characters. In the syntax diagram they are shown in
uppercase (for example, PARAMETER, PREDEFINED-VALUE). Variables appear in
lowercase italic letters (for example, user-defined-value). Variables are user-defined
names or values.
user-defined-value
PREDEFINED-VALUE
Read the syntax diagram from left to right, and from top to bottom, following the
path of the line.
The symbol indicates the beginning of the syntax diagram.
The symbol indicates the end of the syntax diagram.
The symbol indicates that the statement syntax is continued on the next line.
The symbol indicates that a statement is continued from the previous line.
The () symbol indicates that the parameter or value must be entered in
parentheses.
Required parameters appear on the base line and must be entered. Optional
parameters appear below the base line and do not need to be entered. In the
following sample, you must enter REQUIRED-PARAMETER and a value for it, but
you do not need to enter OPTIONAL-PARAMETER or a value for it.
REQUIRED-PARAMETER (
PREDEFINED-VALUE
user-defined-value
477
OPTIONAL-PARAMETER (
PREDEFINED-VALUE
user-defined-value
Default values appear above the base line and do not need to be entered. They are
used when you do not specify a parameter. In the following sample, you can enter
DEFAULT-VALUE, OTHER-PREDEFINED-VALUE, or nothing. If you enter
nothing, DEFAULT-VALUE is assumed.
DEFAULT-VALUE
OTHER-PREDEFINED-VALUE
PARAMETER (
Optional values are indicated by a blank line. The blank line indicates that a value
from the first group (OPTIONAL-VALUE1, OPTIONAL-VALUE2, user-defined-value)
does not need to be entered. For example, based on the syntax below, you could
enter KEYWORD(REQUIRED-VALUE).
OPTIONAL-VALUE1
PARAMETER (
REQUIRED-VALUE
OPTIONAL-VALUE2
user-defined-value
Repeated values can be specified for some parameters. The comma (,) in the
following sample indicates that each user-defined-value must be separated by a
comma.
,
KEYWORD (
user-defined-value
CRTBNDRPG Command
The Create Bound RPG (CRTBNDRPG) command performs the combined tasks of
the Create RPG Module (CRTRPGMOD) and Create Program (CRTPGM)
commands by creating a temporary module object from the source code, and then
creating the program object. Once the program object is created, CRTBNDRPG
deletes the module object it created. The entire syntax diagram for the
CRTBNDRPG command is shown below.
Job: B,I
Pgm: B,I
REXX: B,I
Exec
CRTBNDRPG
*CURLIB/
PGM
*CTLSPEC
program-name
library-name/
*LIBL/
SRCFILE
(
*CURLIB/
library-name/
478
QRPGLESRC
source-file-name
CRTBNDRPG Command
SRCMBR
*PGM
source-file-member-name
SRCSTMF
source-stream-file-name
(1)
OUTPUT
*PRINT
*NONE
GENLVL
10
severity-level-value
TEXT
*SRCMBRTXT
*BLANK
'description'
*YES
*NO
DFTACTGRP (
OPTION
OPTION Details
)
DBGVIEW
*STMT
*SOURCE
*LIST
*COPY
*ALL
*NONE
DBGENCKEY
*NONE
character-value
OUTPUT
*PRINT
*NONE
OPTIMIZE
*NONE
*BASIC
*FULL
INDENT
*NONE
character-value
*NONE
CVTOPT
)
*DATETIME
*GRAPHIC
*VARCHAR
*VARGRAPHIC
SRTSEQ
*HEX
*JOB
*JOBRUN
*LANGIDUNQ
*LANGIDSHR
sort-table-name
*LIBL/
*CURLIB/
library-name/
LANGID
*JOBRUN
*JOB
language-identifier
REPLACE
*YES
*NO
USRPRF
*USER
*OWNER
AUT
*LIBCRTAUT
*ALL
*CHANGE
*USE
*EXCLUDE
authorization-list-name
TRUNCNBR
*YES
*NO
FIXNBR
*NONE
*ZONED
*INPUTPACKED
479
CRTBNDRPG Command
(
*SNGLVL
*TERASPACE
*INHERIT
TGTRLS
*CURRENT
*PRV
VxRxMx
ALWNULL
*NO
*INPUTONLY
*USRCTL
*YES
STGMDL
*NONE
BNDDIR
)
*LIBL/
binding-directory-name
*CURLIB/
*USRLIBL/
library-name/
ACTGRP
*STGMDL
*NEW
*CALLER
activation-group-name
ENBPFRCOL
*PEP
*ENTRYEXIT
*FULL
DEFINE
LICOPT
*NONE
condition-name
PRFDTA
*NOCOL
*COL
options
)
INCDIR
*NONE
directory
*NO
PGMINFO
*STMF
*MODULE
*ALL
*PCML
INFOSTMF
program-interface-stream-file-name
*NONE
PPGENOPT
)
*DFT
*RMVCOMMENT
*EXPINCLUDE
*NOSEQSRC
*NORMVCOMMENT
*NOEXPINCLUDE
*SEQSRC
*CURLIB
PPSRCSFILE (
output-source-file-name
library-name
PPSRCSMBR
480
*PGM
output-source-member-name
CRTBNDRPG Command
PPSRCSTMF
*SRCSTMF
output-stream-file-name
Notes:
1
OPTION Details:
*XREF
*GEN
*NOSECLVL
*SHOWCPY
*EXPDDS
*NOXREF
*NOGEN
*SECLVL
*NOSHOWCPY
*NOEXPDDS
*EXT
*NOSHOWSKP
*NOSRCSTMT
*DEBUGIO
*UNREF
*NOEXT
*SHOWSKP
*SRCSTMT
*NODEBUGIO
*NOUNREF
*NOEVENTF
*EVENTF
481
CRTBNDRPG Command
recommended source physical file length is 112 characters: 12 for the sequence
number and date, 80 for the code and 20 for the comments. This is the
maximum amount of source that is shown on the compiler listing.
QRPGLESRC
The default source file QRPGLESRC contains the ILE RPG source member
to be compiled.
source-file-name
Enter the name of the source file that contains the ILE RPG source member
to be compiled.
*LIBL
The system searches the library list to find the library where the source file
is stored. This is the default.
*CURLIB
The current library is used to find the source file. If you have not specified
a current library, QGPL is used.
library-name
Enter the name of the library where the source file is stored.
SRCMBR
Specifies the name of the member of the source file that contains the ILE RPG
source program to be compiled.
*PGM
Use the name specified by the PGM parameter as the source file member
name. The compiled program object will have the same name as the source
file member. If no program name is specified by the PGM parameter, the
command uses the first member created in or added to the source file as
the source member name.
source-file-member-name
Enter the name of the member that contains the ILE RPG source program.
SRCSTMF
Specifies the path name of the stream file containing the ILE RPG source code
to be compiled.
The path name can be either absolutely or relatively qualified. An absolute
path name starts with '/'; a relative path name starts with a character other
than '/'.
If absolutely-qualified, the path name is complete. If relatively-qualified, the
path name is completed by appending the job's current working directory to
the path name.
The SRCMBR and SRCFILE parameters cannot be specified with the SRCSTMF
parameter.
GENLVL
Controls the creation of the program object. The program object is created if all
errors encountered during compilation have a severity level less than or equal
to the generation severity level specified.
10 A program object will not be generated if you have messages with a
severity-level greater than 10.
severity-level-value
Enter a number, 0 through 20 inclusive. For errors greater than severity 20,
the program object will not be generated.
482
CRTBNDRPG Command
TEXT
Allows you to enter text that briefly describes the program and its function.
The text appears whenever program information is displayed.
*SRCMBRTXT
The text of the source member is used.
*BLANK
No text appears.
'description'
Enter the text that briefly describes the function of the source
specifications. The text can be a maximum of 50 characters and must be
enclosed in apostrophes. The apostrophes are not part of the 50-character
string. Apostrophes are not required if you are entering the text on the
prompt screen.
DFTACTGRP
Specifies whether the created program is intended to always run in the default
activation group.
*YES
When this program is called it will always run in the default activation
group. The default activation group is the activation group where all
original program model (OPM) programs are run.
Specifying DFTACTGRP(*YES) allows ILE RPG programs to behave like
OPM programs in the areas of override scoping, open scoping, and
RCLRSC.
ILE static binding is not available when a program is created with
DFTACTGRP(*YES). This means that you cannot use the BNDDIR or
ACTGRP parameters when creating this program. In addition, any call
operation in your source must call a program and not a procedure.
DFTACTGRP(*YES) is useful when attempting to move an application on a
program-by-program basis to ILE RPG.
*NO
The program is associated with the activation group specified by the
ACTGRP parameter. Static binding is allowed when *NO is specified.
If ACTGRP(*CALLER) is specified and this program is called by a program
running in the default activation group, then this program will behave
according to ILE semantics in the areas of file sharing, file scoping and
RCLRSC.
DFTACTGRP(*NO) is useful when you intend to take advantage of ILE
concepts; for example, running in a named activation group or binding to
a service program.
OPTION
Specifies the options to use when the source member is compiled. You can
specify any or all of the options in any order. Separate the options with one or
more blank spaces. If an option is specified more than once, the last one is
used.
*XREF
Produces a cross-reference listing (when appropriate) for the source
member.
*NOXREF
A cross-reference listing is not produced.
Appendix C. The Create Commands
483
CRTBNDRPG Command
*GEN
Create a program object if the highest severity level returned by the
compiler does not exceed the severity specified in the GENLVL option.
*NOGEN
Do not create a program object.
*NOSECLVL
Do not print second-level message text on the line following the first-level
message text.
*SECLVL
Print second-level message text on the line following the first-level
message text in the Message Summary section.
*SHOWCPY
Show source records of members included by the /COPY compiler
directive.
*NOSHOWCPY
Do not show source records of members included by the /COPY compiler
directive.
*EXPDDS
Show the expansion of externally described files in the listing and display
key field information.
*NOEXPDDS
Do not show the expansion of externally described files in the listing or
display key field information.
*EXT
Show the list of external procedures and fields referenced during the
compile on the listing.
*NOEXT
Do not show the list of external procedures and fields referenced during
the compilation on the listing.
*NOSHOWSKP
Do not show ignored statements in the source part of the listing. The
compiler ignores statements as a result of /IF, /ELSEIF or /ELSE
directives.
*SHOWSKP
Show all statements in the source part of the listing, regardless of whether
or not the compiler has skipped them.
*NOSRCSTMT
Line Numbers in the listing are assigned sequentially; these numbers are
used when debugging using statement numbers. Line Numbers are shown
on the left-most column of the listing. The source IDs and SEU Sequence
Numbers are shown on the two right-most columns of the listing.
*SRCSTMT
Statement numbers for debugging are generated using SEU sequence
numbers and source IDs as follows:
Statement_Number = source_ID * 1000000 + source_SEU_sequence_number
SEU Sequence Numbers are shown on the left-most column of the listing.
Statement Numbers are shown on the right-most column of the listing;
these numbers are used when debugging using statement numbers.
484
CRTBNDRPG Command
Note: When OPTION(*SRCSTMT) is specified, all sequence numbers in the
source files must contain valid numeric values. If there are duplicate
sequence numbers in the same source file, the behavior of the
debugger may be unpredictable and statement numbers for
diagnostic messages or cross reference entries may not be
meaningful.
*DEBUGIO
Generate breakpoints for all input and output specifications.
*NODEBUGIO
Do not generate breakpoints for input and output specifications.
#
#
*UNREF
Unreferenced data items are included in the compiled module.
#
#
#
#
#
#
#
*NOUNREF
Unreferenced data items are not included in the compiled module. This
reduces the amount of storage used, allowing a larger program to be
compiled. You cannot look at or assign to an unreferenced data item
during debugging when the *NOUNREF option is chosen. The
unreferenced data items still appear in the cross-reference listings produced
by specifying OPTION(*XREF).
*NOEVENTF
Do not create an Event File for use by CoOperative Development
Environment/400 (CODE/400). CODE/400 uses this file to provide error
feedback integrated with the CODE/400 editor. An Event File is normally
created when you create a module or program from within CODE/400.
*EVENTF
Create an Event File for use by CoOperative Development
Environment/400 (CODE/400). The Event File is created as a member in
file EVFEVENT in the library where the created module or program object
is to be stored. If the file EVFEVENT does not exist it is automatically
created. The Event File member name is the same as the name of the object
being created.
CODE/400 uses this file to provide error feedback integrated with the
CODE/400 editor. An Event File is normally created when you create a
module or program from within CODE/400.
DBGVIEW
Specifies which level of debugging is available for the compiled program
object, and which source views are available for source-level debugging.
*STMT
Allows the program object to be debugged using the Line Numbers or
Statement Numbers of the compiler listing. Line Numbers are shown on
the left-most column of the source section of the compiler listing when
OPTION(*NOSRCSTMT) is specified. Statement Numbers are shown on
the right-most column of the source section of the compiler listing when
OPTION(*SRCSTMT) is specified.
*SOURCE
Generates the source view for debugging the compiled program object.
This view is not available if the root source member is a DDM file. Also, if
changes are made to any source members after the compile and before
attempting to debug the program, the views for those source members
may not be usable.
485
CRTBNDRPG Command
*LIST
Generates the listing view for debugging the compiled program object. The
information contained in the listing view is dependent on whether
*SHOWCPY, *EXPDDS, and *SRCSTMT are specified for the OPTION
parameter.
Note: The listing view will not show any indentation that you may have
requested using the Indent option.
*COPY
Generates the source and copy views for debugging the compiled program
object. The source view for this option is the same source view generated
for the *SOURCE option. The copy view is a debug view which has all the
/COPY source members included. These views will not be available if the
root source member is a DDM file. Also, if changes are made to any source
members after the compile and before attempting to debug the program,
the views for those source members may not be usable.
*ALL
Generates the listing, source and copy views for debugging the compiled
program object. The information contained in the listing view is dependent
on whether *SHOWCPY, *EXPDDS, and *SRCSTMT are specified for the
OPTION parameter.
*NONE
Disables all of the debug options for debugging the compiled program
object.
|
|
|
DBGENCKEY
Specifies the encryption key to be used to encrypt program source that is
embedded in debug views.
|
|
*NONE
No encryption key is specified.
|
|
|
|
|
|
character-value
Specify the key to be used to encrypt program source that is embedded in
debug views stored in the module object. The length of the key can be
between 1 and 16 bytes. A key of length 1 to 15 bytes will be padded to 16
bytes with blanks for the encryption. Specifying a key of length zero is the
same as specifying *NONE.
|
|
|
|
|
|
If the key contains any characters which are not invariant over all code
pages, it will be up to the user to ensure that the target system uses the
same code page as the source system, otherwise the key may not match
and the decryption may fail. If the encryption key must be entered on
systems with differing code pages, it is recommended that the key be
made of characters which are invariant for all EBCDIC code pages.
OUTPUT
Specifies if a compiler listing is generated.
*PRINT
Produces a compiler listing, consisting of the ILE RPG program source and
all compile-time messages. The information contained in the listing is
dependent on whether *XREF, *SECLVL, *SHOWCPY, *EXPDDS, *EXT,
*SHOWSKP, and *SRCSTMT are specified for the OPTION parameter.
*NONE
Do not generate the compiler listing.
486
CRTBNDRPG Command
OPTIMIZE
Specifies the level of optimization, if any, of the program.
*NONE
Generated code is not optimized. This is the fastest in terms of translation
time. It allows you to display and modify variables while in debug mode.
*BASIC
Some optimization is performed on the generated code. This allows user
variables to be displayed but not modified while the program is in debug
mode.
*FULL
Optimization which generates the most efficient code. Translation time is
the longest. In debug mode, user variables may not be modified but may
be displayed although the presented values may not be current values.
INDENT
Specifies whether structured operations should be indented in the source
listing for enhanced readability. Also specifies the characters that are used to
mark the structured operation clauses.
Note: Any indentation that you request here will not be reflected in the listing
debug view that is created when you specify DBGVIEW(*LIST).
*NONE
Structured operations will not be indented in the source listing.
character-value
The source listing is indented for structured operation clauses. Alignment
of statements and clauses are marked using the characters you choose. You
can choose any character string up to 2 characters in length. If you want to
use a blank in your character string, you must enclose the string in single
quotation marks.
Note: The indentation may not appear as expected if there are errors in the
program.
CVTOPT
Specifies how the ILE RPG compiler handles date, time, timestamp, graphic
data types, and variable-length data types which are retrieved from externally
described database files.
*NONE
Ignores variable-length database data types and use the native RPG date,
time, timestamp and graphic data types.
*DATETIME
Specifies that date, time, and timestamp database data types are to be
declared as fixed-length character fields.
*GRAPHIC
Specifies that double-byte character set (DBCS) graphic data types are to be
declared as fixed-length character fields.
*VARCHAR
Specifies that variable-length character data types are to be declared as
fixed-length character fields.
*VARGRAPHIC
Specifies that variable-length double-byte character set (DBCS) graphic data
types are to be declared as fixed-length character fields.
Appendix C. The Create Commands
487
CRTBNDRPG Command
SRTSEQ
Specifies the sort sequence table that is to be used in the ILE RPG source
program.
*HEX
No sort sequence table is used.
*JOB
Use the SRTSEQ value for the job when the *PGM is created.
*JOBRUN
Use the SRTSEQ value for the job when the *PGM is run.
*LANGIDUNQ
Use a unique-weight table. This special value is used in conjunction with
the LANGID parameter to determine the proper sort sequence table.
*LANGIDSHR
Use a shared-weight table. This special value is used in conjunction with
the LANGID parameter to determine the proper sort sequence table.
sort-table-name
Enter the qualified name of the sort sequence table to be used with the
program.
*LIBL
The system searches the library list to find the library where the sort
sequence table is stored.
*CURLIB
The current library is used to find the sort sequence table. If you have not
specified a current library, QGPL is used.
library-name
Enter the name of the library where the sort sequence table is stored.
If you want to use the SRTSEQ and LANGID parameters to determine the
alternate collating sequence, you must also specify ALTSEQ(*EXT) on the
control specification.
LANGID
Specifies the language identifier to be used when the sort sequence is
*LANGIDUNQ and *LANGIDSHR. The LANGID parameter is used in
conjunction with the SRTSEQ parameter to select the sort sequence table.
*JOBRUN
Use the LANGID value associated with the job when the RPG program is
executed.
*JOB
Use the LANGID value associated with the job when the RPG program is
created.
language-identifier
Use the language identifier specified. (For example, FRA for French and
DEU for German.)
REPLACE
Specifies if a new program is created when a program of the same name
already exists in the specified (or implied) library. The intermediate module
created during the processing of the CRTBNDRPG command are not subject to
488
CRTBNDRPG Command
the REPLACE specifications, and have an implied REPLACE(*NO) against the
QTEMP library. The intermediate modules is deleted once the CRTBNDRPG
command has completed processing.
*YES
A new program is created in the specified library. The existing program of
the same name in the specified library is moved to library QRPLOBJ.
*NO
A new program is not created if a program of the same name already
exists in the specified library. The existing program is not replaced, a
message is displayed, and compilation stops.
USRPRF
Specifies the user profile that will run the created program object. The profile
of the program owner or the program user is used to run the program and to
control which objects can be used by the program (including the authority the
program has for each object). This parameter is not updated if the program
already exists. To change its value, you must delete the program and recompile
using the new value (or, if the constituent *MODULE objects exist, you may
choose to invoke the CRTPGM command).
*USER
The program runs under the user profile of the program's user.
*OWNER
The program runs under the user profile of both the program's user and
owner. The collective set of object authority in both user profiles are used
to find and access objects while the program is running. Any objects
created during the program are owned by the program's user.
AUT
Specifies the authority given to users who do not have specific authority to the
object, who are not on the authorization list, and whose user group has no
specific authority to the object. The authority can be altered for all users or for
specified users after the program is created with the CL commands Grant
Object Authority (GRTOBJAUT) or Revoke Object Authority (RVKOBJAUT).
For further information on these commands, see the CL and APIs section of the
Programming category in the i5/OS Information Center at this Web site http://www.ibm.com/systems/i/infocenter/.
*LIBCRTAUT
The public authority for the object is taken from the CRTAUT keyword of
the target library (the library that contains the object). The value is
determined when the object is created. If the CRTAUT value for the library
changes after the create, the new value will not affect any existing objects.
*ALL
Authority for all operations on the program object, except those limited to
the owner or controlled by authorization list management authority. The
user can control the program object's existence, specify this security for it,
change it, and perform basic functions on it, but cannot transfer its
ownership.
*CHANGE
Provides all data authority and the authority to perform all operations on
the program object except those limited to the owner or controlled by
object authority and object management authority. The user can change the
object and perform basic functions on it.
489
CRTBNDRPG Command
*USE
Provides object operational authority and read authority; that is, authority
for basic operations on the program object. The user is prevented from
changing the object.
*EXCLUDE
The user is prevented from accessing the object.
authorization-list name
Enter the name of an authorization list of users and authorities to which
the program is added. The program object will be secured by this
authorization list, and the public authority for the program object will be
set to *AUTL. The authorization list must exist on the system when the
CRTBNDRPG command is issued.
Note: Use the AUT parameter to reflect the security requirements of your
system. The security facilities available are described in detail in the
Security reference manual.
TRUNCNBR
Specifies if the truncated value is moved to the result field or an error is
generated when numeric overflow occurs while running the program.
Note: The TRUNCNBR option does not apply to calculations performed
within expressions. (Expressions are found in the Extended-Factor 2
field.) If overflow occurs for these calculations, an error will always
occur. In addition, overflow is always signalled for any operation where
the value that is assigned to an integer or unsigned field is out of range.
*YES
Ignore numeric overflow and move the truncated value to the result field.
*NO
When numeric overflow is detected, a run time error is generated with
error code RNX0103.
FIXNBR
Specifies whether decimal data that is not valid is fixed by the compiler.
*NONE
Indicates that decimal data that is not valid will result in decimal data
errors during run time if used.
*ZONED
Zoned-decimal data that is not valid will be fixed by the compiler on the
conversion to packed data. Blanks in numeric fields will be treated as
zeroes. Each decimal digit will be checked for validity. If a decimal digit is
not valid, it is replaced with zero. If a sign is not valid, the sign will be
forced to a positive sign code of hex 'F'. If the sign is valid, it will be
changed to either a positive sign hex 'F' or a negative sign hex 'D', as
appropriate. If the resulting packed data is not valid, it will not be fixed.
*INPUTPACKED
Indicates that if packed decimal data that is not valid is encountered while
processing input specifications, the internal variable will be set to zero.
TGTRLS
Specifies the release level of the operating system on which you intend to use
the object being created. In the examples given for the *CURRENT and *PRV
values, and when specifying the target-release value, the format VxRxMx is
490
CRTBNDRPG Command
used to specify the release, where Vx is the version, Rx is the release, and Mx
is the modification level. For example, V2R3M0 is version 2, release 3,
modification level 0.
Valid values for this parameter change every release. The possible values are:
*CURRENT
The object is to be used on the release of the operating system currently
running on your system. For example, if V2R3M5 is running on the
system, *CURRENT means that you intend to use the object on a system
with V2R3M5 installed. You can also use the object on a system with any
subsequent release of the operating system installed.
Note: If V2R3M5 is running on the system, and the object is to be used on
a system with V2R3M0 installed, specify TGTRLS(V2R3M0), not
TGTRLS(*CURRENT).
*PRV
The object is to be used on the previous release with modification level 0
of the operating system. For example, if V2R3M5 is running on your
system, *PRV means you intend to use the object on a system with
V2R2M0 installed. You can also use the object on a system with any
subsequent release of the operating system installed.
target-release
Specify the release in the format VxRxMx. You can use the object on a
system with the specified release or with any subsequent release of the
operating system installed.
Valid values depend on the current version, release, and modification level,
and they change with each new release. If you specify a target-release that is
earlier than the earliest release level supported by this command, an error
message is sent indicating the earliest supported release.
Note: The current version of the command may support options that are not
available in previous releases of the command. If the command is used
to create objects that are to be used on a previous release, it will be
processed by the compiler appropriate to that release, and any
unsupported options will not be recognized. The compiler will not
necessarily issue any warnings regarding options that it is unable to
process.
ALWNULL
Specifies how the ILE RPG module will be allowed to use records containing
null-capable fields from externally described database files.
*NO
Specifies that the ILE RPG module will not process records with null-value
fields from externally-described files. If you attempt to retrieve a record
containing null values, no data in the record is accessible to the ILE RPG
module and a data-mapping error occurs.
*INPUTONLY
Specifies that the ILE RPG module can successfully read records with
null-capable fields containing null values from externally-described
input-only database files. When a record containing null values is
retrieved, no data-mapping errors occur and the database default values
are placed into any fields that contain null values. The module cannot do
any of the following:
v use null-capable key fields
Appendix C. The Create Commands
491
CRTBNDRPG Command
v create or update records containing null-capable fields
v determine whether a null-capable field is actually null while the module
is running
v set a null-capable field to be null.
*USRCTL
Specifies that the ILE RPG module can read, write, and update records
with null values from externally-described database files. Records with null
keys can be retrieved using keyed operations. The module can determine
whether a null-capable field is actually null, and it can set a null-capable
field to be null for output or update. The programmer is responsible for
ensuring that fields containing null values are used correctly within the
module.
*YES
Same as *INPUTONLY.
|
|
STGMDL
Specifies the storage model attribute of the program.
|
|
|
|
|
*SNGLVL
The program is created with single-level storage model. When a
single-level storage model program is activated and run, it is supplied
single-level storage for automatic and static storage. A single-level storage
program runs only in a single-level storage activation group.
|
|
|
|
|
*TERASPACE
The program is created with teraspace storage model. When a teraspace
storage model program is activated and run, it is supplied teraspace
storage for automatic and static storage. A teraspace storage program runs
only in a teraspace storage activation group.
|
|
|
|
|
|
*INHERIT
The program is created with inherit storage model. When activated, the
program adopts the storage model of the activation group into which it is
activated. An equivalent view is that it inherits the storage model of its
caller. When the *INHERIT storage model is selected, *CALLER must be
specified for the Activation group (ACTGRP) parameter.
BNDDIR
Specifies the list of binding directories that are used in symbol resolution.
*NONE
No binding directory is specified.
binding-directory-name
Specify the name of the binding directory used in symbol resolution.
The directory name can be qualified with one of the following library
values:
*LIBL
The system searches the library list to find the library where the binding
directory is stored.
*CURLIB
The current library for the job is searched. If no library is specified as the
current library for the job, library QGPL is used.
*USRLIBL
Only the libraries in the user portion of the job's library list are searched.
492
CRTBNDRPG Command
library-name
Specify the name of the library to be searched.
ACTGRP
Specifies the activation group this program is associated with when it is called.
|
|
|
|
*STGMDL
If STGMDL(*TERASPACE) is specified, the program will be activated into
the QILETS activation group when it is called. Otherwise, this program
will be activated into the QILE activation group when it is called.
*NEW
When this program is called, it is activated into a new activation group.
*CALLER
When this program is called, it is activated into the caller's activation
group.
activation-group-name
Specify the name of the activation group to be used when this program is
called.
ENBPFRCOL
Specifies whether performance collection is enabled.
*PEP
Performance statistics are gathered on the entry and exit of the program
entry procedure only. This applies to the actual program-entry procedure
for a program, not to the main procedure of the modules within the
program. This is the default.
*NEW
When this program is called, it is activated into a new activation group.
*ENTRYEXIT
Performance statistics are gathered on the entry and exit of all procedures
of the program.
*FULL
Performance statistics are gathered on entry and exit of all procedures.
Also, statistics are gathered before and after each call to an external
procedure.
DEFINE
Specifies condition names that are defined before the compilation begins. Using
the parameter DEFINE(condition-name) is equivalent to coding the /DEFINE
condition-name directive on the first line of the source file.
*NONE
No condition names are defined. This is the default.
condition-name
Up to 32 condition names can be specified. Each name can be up to 50
characters long. The condition names will be considered to be defined at
the start of compilation.
PRFDTA
Specifies the program profiling data attribute for the program. Program
profiling is an advanced optimization technique used to reorder procedures
and code within the procedures based on statistical data (profiling data).
*NOCOL
This program is not enabled to collect profiling data. This is the default.
Appendix C. The Create Commands
493
CRTBNDRPG Command
*COL
The program is enabled to collect profiling data. *COL can be specified
only when the optimization level of the module is *FULL, and when
compiling with a target release of *CURRENT.
LICOPT
Specifies one or more Licensed Internal Code compile-time options. This
parameter allows individual compile-time options to be selected, and is
intended for the advanced programmer who understands the potential benefits
and drawbacks of each selected type of compiler option.
INCDIR
Specifies one or more directories to add to the search path used by the
compiler to find copy files.
The compiler will search the directories specified here if the relatively specified
copy files in the source program can not be resolved by looking in the current
directory.If the copy file cannot be found in the current directory or the
directories specified in the INCDIR parameter, the directories specified in the
RPGINCDIR environment variable will be searched, followed by the directory
containing the main source file.
*NONE
No directories are specified.
directory
Specify up to 32 directories in which to search for copy files.
#
#
#
#
PGMINFO Parameter:
This option specifies whether program interface information should be
generated and where it should be generated. Specify the option values in the
following order:
#
#
#
generate
Specifies whether program interface information should be generated. The
possible values are:
#
#
*NO
#
#
#
#
*PCML
Specifies that PCML (Program Call Markup Language) should be
generated. The generated PCML makes it easier for Java methods to
call the procedures in this RPG module, with less Java code.
#
#
#
location
Specifies the location for the generated program information if the generate
parameter is *PCML. The possible values are:
#
#
#
#
*STMF
Specifies that the program information should be generated into a
stream file. The name of a stream file that will contain the generated
information must be specified on the INFOSTMF option.
#
#
#
#
*MODULE
Specifies that the program information should be stored in the RPG
module. For CRTBNDRPG, a module is created as the first step before
creating a program.
#
#
*ALL
Specifies that the program information should be generated into a
494
CRTBNDRPG Command
stream file and also stored in the module. The name of a stream file
that will contain the generated information must be specified on the
INFOSTMF option.
#
#
#
INFOSTMF
Specifies the path name of the stream file to contain the generated program
interface information specifed on the PGMINFO option.
The path name can be either absolutely or relatively qualified. An absolute
path name starts with '/'; a relative path name starts with a character other
than '/'.
If absolutely-qualified, the path name is complete. If relatively-qualified, the
path name is completed by appending the job's current working directory to
the path name.
This parameter can only be specified when the PGMINFO parameter has a
value other than *NO.
PPGENOPT
Specifies the preprocessor generation options to use when the source code is
compiled.
The possible options are:
*NONE
Run the entire compiler against the source file. Do not copy the
preprocessor output to a file.
*DFT
Run the preprocessor against the input source. *RMVCOMMENT,
*EXPINCLUDE and *NOSEQSRC will be used as the options for
generating the preprocessor output. Use PPSRCFILE and PPSRCMBR to
specify an output source file and member, or PPSRCSTMF to specify a
stream file to contain the preprocessor output.
*RMVCOMMENT
Remove comments, blank lines, and most directives during preprocessing.
Retain only the RPG specifications and any directives necessary for the
correct interpretation of the specifications..
*NORMVCOMMENT
Preserve comments, blank lines and listing-control directives (for example
/EJECT, /TITLE) during preprocessing. Transform source-control directives
(for example /COPY, /IF) to comments during preprocessing.
*EXPINCLUDE
Expand /INCLUDE directives in the generated output file.
*NOEXPINCLUDE
/INCLUDE directives are placed unchanged in the generated output file.
Note: /COPY directives are always expanded
*SEQSRC
If PPSRCFILE is specified, the generated output member has sequential
sequence numbers, starting at 000001 and incremented by 000001.
*NOSEQSRC
If PPSRCFILE is specified, the generated output member has the same
sequence numbers as the original source read by the preprocessor
495
CRTBNDRPG Command
PPSRCFILE
Specifies the source file name and library for the preprocessor output.
source-file-name
Specify the name of the source file for the preprocessor output.
The possible library values are:
*CURLIB
The preprocessor output is created in the current library. If a job does
not have a current library, the preprocessor output file is created in the
QGPL library.
library-name
Specify the name of the library for the preprocessor output.
PPSRCMBR
Specifies the name of the source file member for the preprocessor output.
*PGM
The name supplied on the PGM parameter is used as the preprocessor
output member name.
member-name
Specify the name of the member for the preprocessor output.
PPSRCSTMF
Specifies the path name of the stream file for the preprocessor output.
*SRCSTMF
The path name supplied on the SRCSTMF parameter is used as the
preprocessor output path name. The file will have the extension '.i'.
'path-name'
Specify the path name for the preprocessor output stream file.
The path name can be either absolutely or relatively-qualified. An absolute
path name starts with '/'; a relative path name starts with a character other
than '/'.
If absolutely-qualified, the path name is complete. If relatively-qualified,
the path name is completed by appending the job's current working
directory to the path name.
CRTRPGMOD Command
The Create RPG Module (CRTRPGMOD) command compiles ILE RPG source code
to create a module object (*MODULE). The entire syntax diagram for the
CRTRPGMOD command is shown below.
Job: B,I
Pgm: B,I
REXX: B,I
Exec
CRTRPGMOD
*CURLIB/
MODULE
(
library-name/
496
*CTLSPEC
module-name
CRTRPGMOD Command
*LIBL/
SRCFILE
QRPGLESRC
source-file-name
*CURLIB/
library-name/
SRCMBR
*MODULE
source-file-member-name
SRCSTMF
source-stream-file-name
(1)
OUTPUT
*PRINT
*NONE
GENLVL
10
severity-level-value
TEXT
*SRCMBRTXT
*BLANK
'description'
OPTION
OPTION Details
*NONE
character-value
DBGVIEW
*STMT
*SOURCE
*LIST
*COPY
*ALL
*NONE
DBGENCKEY
OUTPUT
*PRINT
*NONE
*NONE
character-value
OPTIMIZE
*NONE
*BASIC
*FULL
INDENT
*NONE
CVTOPT
)
*DATETIME
*GRAPHIC
*VARCHAR
*VARGRAPHIC
SRTSEQ
*HEX
*JOB
*JOBRUN
*LANGIDUNQ
*LANGIDSHR
sort-table-name
*LIBL/
*CURLIB/
library-name/
LANGID
*JOBRUN
*JOB
language-identifier
REPLACE
*YES
*NO
AUT
*LIBCRTAUT
*ALL
*CHANGE
*USE
*EXCLUDE
authorization-list-name
TRUNCNBR
*YES
*NO
497
CRTRPGMOD Command
FIXNBR
*NONE
*ZONED
*INPUTPACKED
TGTRLS
*CURRENT
*PRV
VxRxMx
ALWNULL
*NO
*INPUTONLY
*USRCTL
*YES
STGMDL
*INHERIT
*SNGLVL
*TERASPACE
*NONE
BNDDIR
)
*LIBL/
binding-directory-name
*CURLIB/
library-name/
ENBPFRCOL
*PEP
*ENTRYEXIT
*FULL
DEFINE
*NONE
condition-name
PRFDTA
*NOCOL
*COL
LICOPT
options
INCDIR
*NONE
directory
*NO
PGMINFO
*STMF
*MODULE
*ALL
*PCML
INFOSTMF
program-interface-stream-file-name
*NONE
PPGENOPT
)
*DFT
*RMVCOMMENT
*EXPINCLUDE
*NOSEQSRC
*NORMVCOMMENT
*NOEXPINCLUDE
*SEQSRC
*CURLIB
PPSRCSFILE (
output-source-file-name
library-name
PPSRCSMBR
*MODULE
output-source-member-name
*SRCSTMF
output-stream-file-name
PPSRCSTMF
Notes:
1
498
CRTRPGMOD Command
OPTION Details:
*XREF
*GEN
*NOSECLVL
*SHOWCPY
*EXPDDS
*NOXREF
*NOGEN
*SECLVL
*NOSHOWCPY
*NOEXPDDS
*EXT
*NOSHOWSKP
*NOSRCSTMT
*DEBUGIO
*NOEVENTF
*NOEXT
*SHOWSKP
*SRCSTMT
*NODEBUGIO
*EVENTF
The meaning of the STGMDL parameter for the CRTRPGMOD command differs
from the meaning for the CRTBNDRPG command.
|
|
STGMDL
Specifies the type of storage to be used by the module.
|
|
|
|
|
|
|
*INHERIT
The module is created with inherit storage model. An inherit storage
model module can be bound into programs and service programs with a
storage model of single-level, teraspace or inherit. The type of storage used
for automatic and static storage for single-level and teraspace storage
model programs matches the storage model of the object. An inherit
storage model object will inherit the storage model of its caller.
|
|
|
|
|
*SNGLVL
The module is created with single-level storage model. A single level
storage model module can only be bound into programs and service
programs that use single level storage. These programs and service
programs use single-level storage for automatic and static storage.
|
|
|
|
|
*TERASPACE
The module is created with teraspace storage model. A teraspace storage
model module can only be bound into programs and service programs that
use teraspace storage. These programs and service programs use teraspace
storage for automatic and static storage.
A description of CRTRPGMOD is also available online. Enter the command name
on a command line, press PF4 (Prompt) and then press PF1 (Help) for any
parameter you want information on.
499
CRTRPGMOD Command
500
OPTION2
Description
Prologue
Source listing
Source specifications
/COPY members
*SHOWCPY
Skipped statements
*SHOWSKP
*EXPDDS
Generated specifications
Compile-time data
File translation
Arrays
Array records
Tables
Table records
*EXPDDS
Cross reference
*XREF
EVAL-CORR Summary
*XREF
External references
*EXT
Message summary
Second-level text
Final summary
*SECLVL
501
Compiler Listings
Table 59. Sections of the Compiler Listing (continued)
Listing Section1
Code generation errors
OPTION2
3
Description
Errors (if any) which occur during code generation
phase.
Binding section3
Notes:
1. The information contained in the listing section is dependent on whether *SRCSTMT or *NOSRCSTMT is
specified for the OPTION parameter. For details on how this information changes, see "*NOSRCSTMT Source
Heading" on page 508 and "*SRCSTMT Source Heading" on page 508. *SRCSTMT allows you to request that
the compiler use SEU sequence numbers and source IDs when generating statement numbers for debugging.
Otherwise, statement numbers are associated with the Line Numbers of the listing and the numbers are assigned
sequentially.
2. The OPTION column indicates what value to specify on the OPTION parameter to obtain this information. A
blank entry means that the information will always appear if OUTPUT(*PRINT) is specified.
3. The sections containing the code generation errors and binding errors appear only if there are errors. There is no
option to suppress these sections.
4. If OPTION(*XREF) is specified, the summary lists information about all subfields, whether or not they are
handled by the EVAL-CORR operation. If OPTION(*NOXREF) is specified, the summary lists only information
about subfields that are not handled by the EVAL-CORR operation. The EVAL-CORR summary section is not
printed if there are no EVAL-CORR operations.
Prologue
The prologue section summarizes the command parameters and their values as
they were processed by the CL command analyzer. If *CURLIB or *LIBL was
specified, the actual library name is listed. Also indicated in the prologue is the
effect of overrides. Figure 240 on page 503 illustrates how to interpret the Prologue
section of the listing for the program MYSRC, which was compiled using the
CRTBNDRPG command.
502
Compiler Listings
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
:
:
:
:
:
:
:
:
:
:
:
:
:
:
Debugging views . . . . .
Output . . . . . . . . . .
Optimization level . . . .
Source listing indentation
Type conversion options .
Sort sequence . . . . . .
Language identifier . . .
Replace program . . . . .
User profile . . . . . . .
Authority . . . . . . . .
Truncate numeric . . . . .
Fix numeric . . . . . . .
Target release . . . . . .
Allow null values . . . .
Binding directory . . . .
Library . . . . . . . .
Activation group . . . . .
Define condition names . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
.
.
.
.
.
:
:
:
:
:
:
Page 1
CRTBNDRPG
MYUSERID
MYSRC
2
MYLIB
Text specified on the Command
MYSRC
3
QRPGLESRC
4
MYLIB
37
Text specified on the Source Member
98/07/27 12:50:13
10
*NO
*XREF
*GEN
*SECLVL
*SHOWCPY
5
*EXPDDS
*EXT
*SHOWSKP
*NOSRCSTMT
*DEBUGIO
*NOEVENTF
*ALL
*PRINT
*NONE
| 6
*NONE
*HEX
*JOBRUN
*YES
*USER
*LIBCRTAUT
*YES
*ZONED
*INPUTPACKED
*CURRENT
*NO
BNDDIRA
BNDDIRB
CMDLIBA
CMDLIBB
CMDACTGRP
ABC 7
DEF
*PEP
*NOCOL
*PCML
/home/mydir/MYSRC.pcml
8
/projects/ABC Electronics Corporation/copy files/prototypes
/home/mydir
9
503
Compiler Listings
6Indentation Mark
The character used to mark structured operations in the source section of
the listing.
7Define condition names
Specifies the condition names that take effect before the source is read.
8
Specifies the IFS file that the PCML (Program Call Markup Language) is to
be written to.
9
Source Section
The source section shows records that comprise the ILE RPG source specifications.
The root source member records are always shown. If OPTION(*EXPDDS) is also
specified, then the source section shows records generated from externally
described files, and marks them with a '=' in the column beside the line number.
These records are not shown if *NOEXPDDS is specified. If OPTION(*SHOWCPY)
is specified, then it also shows the records from /COPY members specified in the
source, and marks them with a '+' in the column beside the line number. These
records are not shown if *NOSHOWCPY is specified.
The source section also shows the conditional compilation process. All lines with
/IF, /ELSEIF, /ELSE and /ENDIF directives and source lines selected by the /IF
groups are printed and given a listing line number. If OPTION(*SHOWSKP) is
specified, it shows all statements that have been excluded by the /IF, /ELSEIF, and
/ELSE directives, and marks them with a '-------' in the column beside the
statement. Line numbers in the listing are not incremented for excluded lines. All
skipped statements are printed exactly as specified, but are not interpreted in any
way. For example, an excluded statement with an /EJECT directive does not cause
a page break. Similarly, /SPACE, /TITLE, /COPY and /EOF compiler directives
are ignored if they are encountered in excluded lines. These statements are not
shown if the default OPTION(*NOSHOWSKP) is specified; instead a message is
printed giving the number of lines excluded.
The source section identifies any syntax errors in the source, and includes a
match-field table, when appropriate.
If OPTION(*NOSRCSTMT) is specified, line numbers are printed sequentially on
the left side of the listing to reflect the compiled source line numbers. Source IDs
and SEU sequence numbers are printed on the right side of the listing to identify
the source members and records respectively. For example, Figure 241 on page 505
shows a section of the listing with a /COPY statement in line 35. In the root source
member, the next line is a DOWEQ operation. In the listing, however, the DOWEQ
operation is on line 39. The three intervening lines shown in the listing are from
the /COPY source member.
504
Compiler Listings
Line
Number
34
35
Figure 243 on page 506 shows the entire source section for MYSRC with
OPTION(*NOSRCSTMT) specified.
505
Compiler Listings
506
Page
000100
000200
000300
000400
000500
000600
971104
000700
971104
000800
971104
000900
971104
971104
980727
980727
980727
001000
001100
001200
001300
001400
Compiler Listings
*--------------------------------------------------------------------------------------------* 4
* Data structure . . . . . . : DSEXT1
*
* Prefix . . . . . . . . . . : BI_ :
0
*
* External format . . . . . : REC1 : MYLIB/DSEXT1
*
* Format text . . . . . . . : Record format description
*
*--------------------------------------------------------------------------------------------*
1
1
1
1
1
1
5
15=D BI_FLD1
5A EXTFLD (FLD1)
FLD1 description
1000001
16=D
INZ (*BLANK)
1000002
17=D BI_FLD2
10A EXTFLD (FLD2)
FLD2 description
1000003
18=D
INZ (*BLANK)
1000004
19=D BI_FLD3
18A EXTFLD (FLD3)
FLD3 description
1000005
20=D
INZ (111)
1000006
21=IINREC
2000001
*--------------------------------------------------------------------------------------------*
2
* RPG record format . . . . : INREC
*
2
* External format . . . . . : INREC : MYLIB/INFILE
*
2
*--------------------------------------------------------------------------------------------*
2
22=I
A
1 25 FLDA
2000002
23=I
A 26 90 FLDB
2000003
24=I
13488 *VAR C 91 112 UCS2FLD
2000004
25=IREC1
3000001
*--------------------------------------------------------------------------------------------*
3
* RPG record format . . . . : REC1
*
3
* External format . . . . . : REC1 : MYLIB/KEYL6
*
3
*--------------------------------------------------------------------------------------------*
3
26=I
*ISO-D
1 10 FLD12
3000002
27=I
A 11 13 FLD13
3000003
28=I
A 14 17 FLD14
3000004
29=I
A 18 22 FLD15
3000005
30=I
13488
C 23 32 FLDC
3000006
31=I
13488 *VAR C 33 44 FLDCV
3000007
32=I
835
G 45 54 FLDG
3000008
33=IREC2
4000001
*--------------------------------------------------------------------------------------------*
4
* RPG record format . . . . : REC2
*
4
* External format . . . . . : REC2 : MYLIB/KEYL6
*
4
*--------------------------------------------------------------------------------------------*
4
34=I
*ISO-D
1 10 FLD22
4000002
35=I
A 11 13 FLD23
4000003
36=I
A 14 17 FLD24
4000004
37=I
A 18 22 FLD25
4000005
Line <--------------------- Source Specifications ----------------------------------------------><---- Comments ----> Src Seq
Number ....1....+....2....+<-------- 26 - 35 -------->....4....+....5....+....6....+....7....+....8....+....9....+...10 Id Number
38 C
MOVE
123
BI_FLD1
001500
39 C/COPY MYCPY
971104
001600
*--------------------------------------------------------------------------------------------* 6
* RPG member name . . . . . : MYCPY
*
5
* External name . . . . . . : MYLIB/QRPGLESRC(MYCPY)
*
5
* Last change . . . . . . . : 98/07/24 16:20:04
*
5
* Text description . . . . : Text specified on Copy Member
*
5
*--------------------------------------------------------------------------------------------*
7
40+C
Blue(1)
DSPLY
5000100
41+C
Green(4)
DSPLY
5000200
42+C
Red(2)
DSPLY
5000300
8
43 C
*in20
doweq
*OFF
001700
44 C
| READ
InRec
----20
001800
45 C
| if
NOT *in20
001900
46 C
FLDA
| | DSPLY
002000
47 C
| endif
002100
48 C
enddo
002200
49 C
write
outrec
002300
9
50 C
SETON
LR---002400
47 C/DEFINE ABC
971104
002500
51 C/IF DEFINED(ABC)
971104
002600
52 C
MOVEL
x
Y
10
002700
54 C
MOVEL
x
Z
10
002800
55 C/ELSE
971104
002900
10
------ C
MOVEL
Y
10
971104
003000
------ C
MOVEL
Z
10
971104
003100
56 C/ENDIF
971104
003200
507
Compiler Listings
Line <---------------------- Source Specifications ----------------------------><---- Comments ----> Do Page Change Src Seq
Number ....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+...10 Num Line Date
Id Number
57=OOUTREC
6000001
*--------------------------------------------------------------------------------------------*
6
* RPG record format . . . . : OUTREC
*
6
* External format . . . . . : OUTREC : MYLIB/OUTFILE
*
6
*--------------------------------------------------------------------------------------------*
6
58=O
FLDY
100A CHAR
100
6000002
59=O
FLDZ
132A CHAR
32
6000003
60=O
GRAPHFLD
156G GRPH
12 835
6000004
* * * * *
E N D O F S O U R C E * * * * *
508
Compiler Listings
2 Compiler Options in Effect
Identifies the compiler options in effect. Displayed when compile-option
keywords are specified on the control specification.
3 File/Record Information
Identifies the externally described file and the records it contains.
4 DDS Information
Identifies from which externally described file the field information is
extracted. Shows the prefix value, if specified. Shows the format record text
if specified in the DDS.
5 Generated Specifications
Shows the specifications generated from the DDS, indicated by '=' beside
the Line Number. Shows up to 50 characters of field text if it is specified in
the DDS. Shows the initial value as specified by the INZ keyword on the
definition specification. If INZ(*EXTDFT) is specified for externally
described data structure subfields, the DDS default value is displayed.
Default values that are too long to fit on one line are truncated and
suffixed with '...'.
6 /COPY Member Information
Identifies which /COPY member is used. Shows the member text, if any.
Shows the date and time of the last change to the member.
7 /COPY Member Records
Shows the records from the /COPY member, indicated by a '+' beside the
Line Number.
8 Indentation
Shows how structured operations appear when you request that they be
marked.
9 Indicator Usage
Shows position of unused indicators, when an indicator is used.
10 OPTION(*SHOWSKP) Usage
Shows two statements excluded by an /IF directive, indicated by a '-------'
beside the statements. If the OPTION(*NOSHOWSKP) was specified these
two statements would be replaced by: LINES EXCLUDED: 2.
Msg id
*RNF7066
*RNF7066
*RNF7086
A d d i t i o n
Sv Number Seq
00
8 000800
00
8 000800
00
60 000004
*RNF7086 00
* * * * *
a l D i a g n o s t i c M e s s a g e s
Message text
Record-Format REC1 not used for input or output.
Record-Format REC2 not used for input or output.
RPG handles blocking for file INFILE. INFDS is updated only
when blocks of data are transferred.
60 000004 RPG handles blocking for file OUTFILE. INFDS is updated
only when blocks of data are transferred.
E N D O F A D D I T I O N A L D I A G N O S T I C M E S S A G E S
* * * * *
509
Compiler Listings
If OPTION(*SRCSTMT) is specified, the messages will have only the statement
number shown. Figure 245 shows an example.
Msg id
*RNF7066
*RNF7066
*RNF7086
A d d i t i o n
Sv
Statement
00
000800
00
000800
00
6000004
*RNF7086 00
* * * * *
a l D i a g n o s t i c
M e s s a g e s
Message text
Record-Format REC1 not used for input or output.
Record-Format REC2 not used for input or output.
RPG handles blocking for file INFILE. INFDS is updated only
when blocks of data are transferred.
6000004 RPG handles blocking for file OUTFILE. INFDS is updated
only when blocks of data are transferred.
E N D O F A D D I T I O N A L D I A G N O S T I C M E S S A G E S
* * * * *
u t p u t B u f f e r
Field or Constant
FLDY
FLDZ
GRAPHFLD
O F O U T P U T
P o s i t i o n s
B U F F E R
P O S I T I O N
* * * *
/ C o p y M e m b e r s
<-------- External name -------> CCSID <- Last change ->
Library
File
Member
Date
Time
MYLIB
QRPGLESRC MYCPY
37 98/07/24 16:20:04
N D O F / C O P Y M E M B E R S * * * * *
Compile-Time Data
The Compile-Time Data section includes information on ALTSEQ or NLSS tables,
and on tables and arrays. In this example, there is an alternate collating sequence
and two arrays, as shown in Figure 248 on page 511.
510
Compiler Listings
C o m p i l e T i m e D a t a
61 **
*--------------------------------------------------------------------*
* Alternate Collating Sequence Table Data:
*
*--------------------------------------------------------------------*
62 ALTSEQ
1122ACAB4B7C36F83A657D73
Line <---------------------- Data Records -------------------------------------------------------------->
Number ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+...10
*--------------------------------------------------------------------*
* Alternate Collating Sequence Table:
*
* Number of characters with an altered sequence . . . . . . : 6 1 *
* 2 0_ 1_ 2_ 3_ 4_ 5_ 6_ 7_ 8_ 9_ A_ B_ C_ D_ E_ F_
*
* _0 . . . . . . . . . . . . . . . .
_0
*
* _1 . 22 3. . . . . . . . . . . . .
_1
*
* _2 . . . . . . . . . . . . . . . .
_2
*
* _3 . . . . . . . . . . . . . . . .
_3
*
* _4 . . . . . . . . . . . . . . . .
_4
*
* _5 . . . . . . . . . . . . . . . .
_5
*
* _6 . . . F8 . . . . . . . . . . . .
_6
*
* _7 . . . . . . . . . . . . . . . .
_7
*
* _8 . . . . . . . . . . . . . . . .
_8
*
* _9 . . . . . . . . . . . . . . . .
_9
*
* _A . . . 65 . . . . . . . . . . . .
_A
*
* _B . . . . 7C . . . . . . . . . . .
_B
*
* _C . . . . . . . . . . AB . . . . .
_C
*
* _D . . . . . . . 73 . . . . . . . .
_D
*
* _E . . . . . . . . . . . . . . . .
_E
*
* _F . . . . . . . . . . . . . . . .
_F
*
*
0_ 1_ 2_ 3_ 4_ 5_ 6_ 7_ 8_ 9_ A_ B_ C_ D_ E_ F_
*
*--------------------------------------------------------------------*
63 **
*--------------------------------------------------------------------*
* Array . . . : BLUE 4
Alternating Array . . . . : GREEN
*
*--------------------------------------------------------------------*
64 1234ZZ
65 ABCDYY
66 5432XX
67 EDCBWW
68 ABCDEF
69 **
*--------------------------------------------------------------------*
* Array . . . : RED
*
*--------------------------------------------------------------------*
70 3861
71 TJKL
* * * * *
E N D O F C O M P I L E T I M E D A T A * * * * *
971104
003300
971104
003400
Change Src Seq
Date
Id Number
971104
003500
971104
971104
971104
971104
0980728
971104
003600
003700
003800
003900
004000
00410
971104
971104
00420
00430
511
Compiler Listings
K e y F i e l d I n f o r m a t i o n
File
Internal
External
Record
field name field name Attributes
2 KEYL6
Common Keys:
DATE *ISO- 10
CHAR
3
REC1
FLD12
DATE *ISO- 10
FLD13
CHAR
3
FLD15
CHAR
5
FLDC
UCS2
5 13488
FLDCV
VUC2
5 13488
FLDG
GRPH
5 835
REC2
FLD22
DATE *ISO- 10
FLD23
CHAR
3
* * * * * E N D O F K E Y F I E L D I N F O R M A T I O N
* * * * *
Cross-Reference Table
The Cross-Reference table contains at least three lists:
v files and records
v global fields
v indicators
In addition, it contains the local fields that are used by each subprocedure. Use this
table to check where files, fields and indicators are used within the
module/program.
Note that the informational message RNF7031, which is issued when an identifier
is not referenced, will only appear in the cross-reference section of the listing and
in the message summary. It does not appear in the source section of the listing.
Names longer than 122 characters, will appear in the cross-reference section of the
listing split across multiple lines. The entire name will be printed with the
characters '...' at the end of the lines. If the final portion of the name is longer than
17 characters, the attributes and line numbers will be listed starting on the
following line. Figure 250 on page 513 shows an example for the module
TRANSRPT, which has two subprocedures.
In this example, the Cross-Reference table shows the line numbers for each
reference. If you specify OPTION(*SRCSTMT) instead of OPTION(*NOSRCSTMT),
the statement numbers will be displayed for each reference and the cross reference
listing can extend beyond the first 80 columns of the listing.
512
Compiler Listings
C r o s s R e f e r e n c e
File and Record References:
File
Device
References (D=Defined)
Record
CUSTFILE
DISK
8D
CUSTREC
0
44
*RNF7031 CUSTRPT
DISK
9D
ARREARS
0
60
79
Global Field References:
Field
Attributes
References (D=Defined M=Modified)
*INZSR
BEGSR
63D
AMOUNT
P(10,2)
56M
83
95
CITY
A(20)
53D
132
CURDATE
D(10*ISO-)
42D
64M
92
CUSTNAME
A(20)
50D
122
CUSTNUM
P(5,0)
49D
124
DUEDATE
A(10)
57M
84
91
EXTREMELY_LONG_PROCEDURE_NAME_THAT_REQUIRES_MORE_THAN_ONE_LINE_IN_THE_CROSS_REFERENCE_EVEN_THOUGH_THE_ENTIRE_LINE_UP_TO_.
COLUMN_132_IS_USED_TO_PRINT_THE_NAME...
I(5,0)
9D
PROTOTYPE
FMTCUST
PROTOTYPE
35D
59
113
114
134
INARREARS
A(1)
30D
58
85
86
PROTOTYPE
101
LONG_FLOAT
F(8)
7D
11M
12M
NUMTOCHAR
A(31)
22D
124
130
PROTOTYPE
RPTADDR
A(100)
59
82
RPTNAME
C(100)
59
81
CCSID(13488)
RPTNUM
P(5,0)
80
SHORT_FLOAT
F(4)
8D
10M
*RNF7031 STATE
A(2)
54D
STREETNAME
A(20)
52D
131
STREETNUM
P(5,0)
51D
130
THIS_NAME_IS_NOT_QUITE_SO_LONG...
A(5)
7D
UDATE
S(6,0)
64
*RNF7031 ZIP
P(5,0)
55D
INARREARS Field References:
Field
Attributes
References (D=Defined M=Modified)
DAYSLATE
I(10,0)
88D
92M
94
DATEDUE
D(10*ISO-)
89D
91M
92
FMTCUST Field References:
Field
Attributes
References (D=Defined M=Modified)
NAME
A(100)
115D
122M
BASED(_QRNL_PST+)
ADDRESS
A(100)
116D
130M
BASED(_QRNL_PST+)
Indicator References:
Indicator
References (D=Defined M=Modified)
*RNF7031 01
44D
* * * * * E N D O F C R O S S R E F E R E N C E * * * * *
EVAL-CORR Summary
When OPTION(*XREF) is specified, the EVAL-CORR summary lists every subfield
in either the source or the target data structure indicating
v whether the subfield is assigned
v the reason the source and target subfields are not considered to correspond, if
the subfield is not assigned
v for subfields that are assigned, additional information that may affect the
assignment such as a difference in the number of array elements or the
null-capability of the subfields
513
Compiler Listings
When OPTION(*NOXREF) is specified, the EVAL-CORR summary does not list
any information about corresponding subfields. It only lists the subfields that do
not correspond, with the reason that the subfields are not considered to
correspond.
EVAL-CORR summary 1
1
FLD1
FLD2
FLD3
4*RNF7349 FLD5
EVAL-CORR summary 2
FLD1
SUBDS 5
SUBF1
FLD2
*RNF7341 FLD3
13
28
14
19
24
2
514
Compiler Listings
E x t e r n a l R e f
Statically bound procedures:
Procedure
PROTOTYPED
PADDR_PROC
CALLB_PROC
Imported fields:
Field
Attributes
IMPORT_FLD
P(5,0)
Exported fields:
Field
Attributes
EXPORT_ARR(2)
A(5)
* * * * * E N D O F E X T E R N A L
e r e n c e s
References
2
4
6
Defined
3
Defined
2
R E F E R E N C E S
* * * * *
Message Summary
The message summary contains totals by severity of the errors that occurred. If
OPTION(*SECLVL) is specified, it also provides second-level message text.
Figure 253 shows an example.
M e s s a g e S u m m a r y
Msg id Sv Number Message text
*RNF7031 00
16 The name or indicator is not referenced.
Cause . . . . . : The field, subfield, TAG, data
structure, PLIST, KLIST, subroutine, indicator, or
prototype is defined in the program, but not referenced.
Recovery . . . :
Reference the item, or remove it from
the program. Compile again.
*RNF7066 00
2 Record-Format name of Externally-Described file is not used.
Cause . . . . . : There is a Record-Format name for an
Externally-Described File that is not used on a valid
input or output operation.
Recovery . . . : Use the Record-Format name of the
Externally-Described File for input or output, or specify
the name as a parameter for keyword IGNORE. Compile
again.
*RNF7086 00
2 RPG handles blocking for the file. INFDS is updated only when
blocks of data are transferred.
Cause . . . . . : RPG specifies MLTRCD(*YES) in the UFCB
(User-File-Control Block). Records are passed between RPG
and data management in blocks. Positions 241 through the
end of the INFDS (File-Information-Data Structure) are
updated only when a block of records is read or written.
Recovery . . . : If this information is needed after
each read or write of a record, specify the OVRDBF
command for the file with SEQONLY(*NO).
* * * * * E N D O F M E S S A G E S U M M A R Y * * * * *
Final Summary
The final summary section provides final message statistics and source statistics. It
also specifies the status of the compilation. Figure 254 on page 516 shows an
example.
515
Compiler Listings
F i n a l S u m m a r y
Message Totals:
Information (00) . . . . . . . :
20
Warning
(10) . . . . . . . :
0
Error
(20) . . . . . . . :
0
Severe Error (30+) . . . . . . :
0
--------------------------------- ------Total . . . . . . . . . . . . . :
20
Source Totals:
Records . . . . . . . . . . . . :
71
Specifications . . . . . . . . :
55
Data records . . . . . . . . . :
8
Comments . . . . . . . . . . . :
0
* * * * * E N D O F F I N A L S U M M A R Y * * * * *
Program MYSRC placed in library MYLIB. 00 highest severity. Created on 98/07/28 at 14:21:03.
* * * * * E N D O F C O M P I L A T I O N * * * * *
516
Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in
other countries. Consult your local IBM representative for information on the
products and services currently available in your area. Any reference to an IBM
product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product,
program, or service that does not infringe any IBM intellectual property right may
be used instead. However, it is the user's responsibility to evaluate and verify the
operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter
described in this document. The furnishing of this document does not grant you
any license to these patents. You can send license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.
For license inquiries regarding double-byte (DBCS) information, contact the IBM
Intellectual Property Department in your country or send inquiries, in writing, to:
Intellectual Property Licensing
Legal and Intellectual Property Law
IBM Japan, Ltd.
3-2-12, Roppongi, Minato-ku, Tokyo 106-8711
The following paragraph does not apply to the United Kingdom or any other
country where such provisions are inconsistent with local law:
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS
PUBLICATION AS IS WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS
FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or
implied warranties in certain transactions, therefore, this statement may not apply
to you.
This information could include technical inaccuracies or typographical errors.
Changes are periodically made to the information herein; these changes will be
incorporated in new editions of the publication. IBM may make improvements
and/or changes in the product(s) and/or the program(s) described in this
publication at any time without notice.
Any references in this information to non-IBM Web sites are provided for
convenience only and do not in any manner serve as an endorsement of those Web
sites. The materials at those Web sites are not part of the materials for this IBM
product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it
believes appropriate without incurring any obligation to you.
Copyright IBM Corp. 1994, 2010
517
Licensees of this program who wish to have information about it for the purpose
of enabling: (i) the exchange of information between independently created
programs and other programs (including this one) and (ii) the mutual use of the
information which has been exchanged, should contact:
IBM Canada Ltd. Laboratory
Information Development
8200 Warden Avenue
Markham, Ontario, Canada L6G 1C7
Such information may be available, subject to appropriate terms and conditions,
including in some cases, payment of a fee.
The licensed program described in this document and all licensed material
available for it are provided by IBM under terms of the IBM Customer Agreement,
IBM International Program License Agreement, IBM License Agreement for
Machine Code, or any equivalent agreement between us.
This information contains examples of data and reports used in daily business
operations. To illustrate them as completely as possible, the examples include the
names of individuals, companies, brands, and products. All of these names are
fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which
illustrate programming techniques on various operating platforms. You may copy,
modify, and distribute these sample programs in any form without payment to
IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating
platform for which the sample programs are written. These examples have not
been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or
imply reliability, serviceability, or function of these programs. The sample
programs are provided "AS IS", without warranty of any kind. IBM shall not be
liable for any damages arising out of your use of the sample programs.
Trademarks
IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of
International Business Machines Corp., registered in many jurisdictions worldwide.
Other product and service names might be trademarks of IBM or other companies.
A current list of IBM trademarks is available on the Web at Copyright and
trademark information at www.ibm.com/legal/copytrade.shtml.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of
Microsoft Corporation in the United States, other countries, or both.
518
UNIX is a registered trademark of The Open Group in the United States and other
countries.
Java and all Java-based trademarks and logos are trademarks of Sun Microsystems,
Inc. in the United States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of
others.
Notices
519
520
Bibliography
For additional information about topics related to
ILE RPG programming on the i5/OS system, refer
to the following IBM i5/OS publications:
v ADTS/400: Programming Development Manager,
SC09-1771-00, provides information about using
the Programming Development Manager
(PDM) to work with lists of libraries, objects,
members, and user-defined options to easily do
such operations as copy, delete, and rename.
Contains activities and reference material to
help the user learn PDM. The most commonly
used operations and function keys are
explained in detail using examples.
v ADTS for AS/400: Source Entry Utility,
SC09-2605-00, provides information about using
the Application Development ToolSet Source
Entry Utility (SEU) to create and edit source
members. The manual explains how to start
and end an SEU session and how to use the
many features of this full-screen text editor. The
manual contains examples to help both new
and experienced users accomplish various
editing tasks, from the simplest line commands
to using pre-defined prompts for high-level
languages and data formats.
v Application Display Programming, SC41-5715-02,
provides information about:
Using DDS to create and maintain displays
for applications;
Creating and working with display files on
the system;
Creating online help information;
Using UIM to define panels and dialogs for
an application;
Using panel groups, records, or documents
v Recovering your system, SC41-5304-10, provides
information about setting up and managing the
following:
Journaling, access path protection, and
commitment control
User auxiliary storage pools (ASPs)
Disk protection (device parity, mirrored, and
checksum)
Provides performance information about
backup media and save/restore operations.
Also includes advanced backup and recovery
topics, such as using save-while-active support,
521
522
Index
Special characters
/COPY statement
conversion problems 461, 471
COPY debug view 234
in a conversion report 466
table in compiler listing 510
using source files 57
*CALLER 115
*CANCL 305
*DETC 305
*DETL 305
*ENTRY PLIST 158
*EXTDFT
example 505
in compiler listing 509
*GETIN 305
*JOB
sort sequence, SRTSEQ 488
*JOBRUN
language identifier, LANGID 488
sort sequence, SRTSEQ 488
*NEW 115
*OFL 305
*OMIT 146
*TOTC 305
*TOTL 305
*USER
user profile, USRPRF 489
%ADDR (Get Address of Variable)
omitted parameters 146
%ADDR debug built-in 273
%ALLOC built-in function 119
%INDEX debug built-in 273
%PARMS (Return Number of Parameters)
checking for number of
parameters 147
%REALLOC built-in function 119
%SUBSTR debug built-in
changing values 275
examples 274
%VARS debug built-in 273
Numerics
01-99 indicators
displaying while debugging 268
in a sample formatted dump 325
A
abnormal program/procedure end 160
access path
example of 357
for externally described DISK
file 350
for indexed file 356
ACTGRP parameter
CRTBNDRPG command 62, 493
CRTPGM command 87
specifying 114
Copyright IBM Corp. 1994, 2010
AUT parameter
CRTBNDRPG command 62, 489
CRTRPGMOD command 78
authority to commands ix
auto report program
converting to ILE RPG 461
avoiding a loop in an error
subroutine 304
B
behavior of bound ILE RPG modules 84
behavioral differences between OPM
RPG/400 and ILE RPG 445
bibliography 521
bindable APIs
calling conventions 162
CEE4ABN 162
CEECRHP (Create Heap) 20, 126
CEECZST (Reallocate Storage) 21
CEEDSHP (Discard Heap) 20, 126
CEEFRST (Free Storage) 20
CEEGTST (Get Heap Storage) 21, 126
CEEHDLR (Register ILE Condition
Handler) 306
CEEHDLU (Unregister ILE Condition
Handler) 306
CEERTX (Register Call Stack Entry
Termination User Exit
Procedure) 312
CEETREC 161
CEETSTA (Check for Omitted
Argument) 146
CEEUTX (Call Stack Entry
Termination User Exit
Procedure) 312
Create Heap (CEECRHP) 20, 126
description 162
Discard Heap (CEEDSHP) 20, 126
Free Storage (CEEFRST) 20
Get Descriptive Information About a
String Argument (CEESGI) 145
Get Heap Storage (CEEGTST) 21, 126
overview 20
passing operational descriptors
to 144
Reallocate Storage (CEECZST) 21
Retrieve Operational Descriptor
Information (CEEDOD) 145
returning from a procedure 161
sample coding 162
binder language
example 101
reasons for using 95
binder listing
as maintenance resource 91
basic 104
creating 90
determining exports in service
program 95
sections of 90
523
binding
after modifying a module 91
definition 85
modules into a program 85
service program to a program 102
binding errors in compiler listing 516
binding multiple modules 89
blocking/unblocking records 355
BNDDIR parameter on CRTBNDRPG
CRTBNDRPG command 62, 492
CRTRPGMOD command 78
static binding 64
BREAK debug command
definition 231
example 248
using 245, 247, 251
breakpoints
conditional
setting and removing for job 247
setting and removing for
thread 252
removing all 253
setting and removing 243
setting using statement numbers 250
testing 244
unconditional
setting and removing for job 244
setting and removing for
thread 246
browsing a compiler listing using
SEU 72
built-in functions
%ADDR 146
C
calculation specifications
general description 3
program-described WORKSTN
file 404
CALL (call a program) operation code
in a conversion report 466
using 155
CALL CL command
example passing parameters 108
passing parameters 107
running a program 107
call operations
calling programs 155
DSPPGMREF 156
fixed-form call 155
free-form call 140
query names of called
procedures 156
special routines 164
using 140
call stack 135, 286
Call Stack Entry Termination User Exit
Procedure (CEEUTX) 312
CALLB (call a bound procedure)
operation code
calling programs 155
using 155
calling
Java from RPG 195
RPG from Java 202
calling a graphics routine 163
524
calling programs/procedures
abnormal program/procedure
end 160
call stack 135
calling bindable APIs 162
calling graphics 163
calling procedures 134
calling programs 134
calling special routines 164
fixed-form call 155
free-form call 140
interlanguage calls 154
normal program/procedure end 159
overview 133
parameter passing methods 142
recursive calls 136
returning from a called program or
procedure 158
returning values 140
returning without ending 160
static calls 134
using the CALL operation 155
using the CALLB operation 155
within ILE 19
CALLP (call a prototyped program or
procedure) operation code
using 140
cancel handler 285
CEERTX (Register Call Stack Entry
Termination User Exit
Procedure) 312
CEEUTX (Call Stack Entry
Termination User Exit
Procedure) 312
example 313
using 312
CCSIDs
indicated in compiler listing 508
CEE4ABN 162
CEECRHP (Create Heap) bindable
API 20, 126
CEECZST (Reallocate Storage) bindable
API 21
CEEDOD (Retrieve Operational
Descriptor Information) 98
example 146
operational descriptors 145
CEEDSHP (Discard Heap) bindable
API 20, 126
CEEFRST (Free Storage) bindable
API 20
CEEGTST (Get Heap Storage) bindable
API 21, 126
CEEHDLR (Register ILE Condition
Handler) 306
CEEHDLU (Unregister ILE Condition
Handler) 306
CEERTX (Register Call Stack Entry
Termination User Exit Procedure) 312
CEESGI (Get Descriptive Information
About a String Argument) 145
CEETREC 161
CEETSTA (Check for Omitted
Argument) 146
CEEUTX (Call Stack Entry Termination
User Exit Procedure) 312
525
D
data areas
RETURNCODE 74
data file, converting source from 462
data management operations 340
data structures
multiple-occurrence
displaying while debugging 267
subfields
conversion problems 474
displaying while debugging 267
using EVAL debug command 267
database data
updating while debugging 238
database file
data file 349
526
debugging (continued)
differences between ILE RPG and
OPM RPG/400 446
displaying attributes of 277
displaying data addressed by
pointers 270
displaying data and expressions 263
displaying fields as hexadecimal
values 269
displaying fields in character
format 269
displaying fields in UCS-2
format 270
displaying fields in variable-length
format 270
displaying indicators 268
displaying multiple-occurrence data
structures 267
displaying the contents of a table 266
displaying the contents of an
array 266
general discussion 229
National Language Support 279
NLSS considerations 249
obtaining a formatted dump 319
OPM program limit in debug
session 239
optimization effects 92, 230
overview 20
preparing a program 232
removing an object from a
session 239, 240
rules for assigning values using
EVAL 275
setting and removing
breakpoints 243
setting debug options 238
setting watch conditions 253
starting the source 236
stepping through 258
unexpected results 265
updating production files 238
viewing shorthand names 279
viewing source 240
decimal positions
input specifications
program-described WORKSTN
file 403
with external descriptions 335
decompressing an object 93
default activation group 23, 31, 115
running in 115
default exception handler, RPG 288
default heap 119
DEFINE parameter
CRTBNDRPG command 62, 493
CRTRPGMOD command 78
definition specifications
general description 3
deleting an activation group 116
description of parameters
CRTBNDRPG command 481
CRTRPGMOD command 499
CVTRPGSRC command 456
descriptors, operational
definition 144
example 98
DETAIL parameter
creating a binder listing 90
DETC 305
detecting errors in a program 229
DETL 305
device files
device dependence 329
device independence 329
DISK files 349
general discussion 381
multiple-device 406
PRINTER files 381
SEQ files 390
workstation files 395
device name, function of 330
devices
WORKSTN 395
DFTACTGRP parameter on CRTBNDRPG
CRTBNDRPG command 62
description 483
running in OPM default 115
using 61, 64, 65
diagnosing errors in a program 229
differences between OPM and ILE RPG
behavioral differences 445
exception handling 290
different views of a module 242
Discard Heap (CEEDSHP) bindable
API 20, 126
DISK file
externally described
access path 350
as program-described 332
examples 351
general description 350
record format specifications 350
file operation codes allowed
for keyed processing
methods 372
for non-keyed processing
methods 372
general description 349
processing methods
consecutive processing 360
overview 360
random-by-key processing 367
relative-record-number
processing 370
sequential-by-key processing 361
sequential-within-limits
processing 368
program-described
indexed file 356
processing 360
record-address file 359
sequential file 358
record-format specifications 350
DISPLAY debug command
definition 231
using 241
viewing shorthand names 279
Display Module (DSPMOD)
command 156
Display Module Source (DSPMODSRC)
command 238, 239, 240, 241
Display Program (DSPPGM) command
determining optimization level 92
E
edit source (STRSEU) command 52
eliminating errors in a program 229
ENBPFRCOL parameter
CRTBNDRPG command 62, 493
CRTRPGMOD command 78
End Debug (ENDDBG) command 236
ending a program or procedure
abnormal end 160
after system call 113
normal end 159
return overview 158
returning without ending 160
using bindable APIs 161
ending commitment control 374
ENDSR (end of subroutine) operation
code
specifying a return point 305
ENTMOD parameter 87
entry module 28
See program entry procedure (PEP)
environment
See Integrated Language Environment
(ILE)
EQUATE debug command
definition 231
example 278
using 278
equating a name with a field, expression,
or command 278
error indicators
specifying 294
error subroutines
avoiding a loop 304
for file errors 298
program 301
using 297
errors
See also exception
correcting compilation 70
correcting run-time 72
file 288
program 288
runtime, Java 216
when calling Java from RPG 205
escape messages
definition 286
unhandled 292
EVAL debug command
changing values 275
contents of a table 266
contents of an array 266
definition 231
displaying data structures 267
example 264, 276
in character format 269
in UCS-2 format 270
in variable-length format 270
indicators 268
rules for assigning values 275
using 263
event file for CODE/400 484
examples
compiling
binding multiple modules 89
OPM-compatible program 65
program for source debugging 63
program with static binding 64
sample binder listing 104
service program 97
converting to RPG IV
all members in a file 459
performing a trial conversion 460
sample conversion 462
some members in a file 460
debugging
adding a service program to a
session 239
changing field values 276
changing the debug view of a
module 242
displaying attributes of a
field 277
displaying data addressed by
pointers 270
displaying fields as hexadecimal
values 269
displaying fields in character
format 269
displaying fields in UCS-2
format 270
displaying fields in variable-length
format 270
displaying indicators 268
displaying multiple-occurrence
data structures 267
displaying the contents of a
table 266
displaying the contents of an
array 266
removing programs from a
session 240
setting a conditional
breakpoint 248
Index
527
examples (continued)
debugging (continued)
setting an unconditional
breakpoint 245
setting debug options 238
source for debug examples 279
using %SUBSTR to display field
values 274
viewing a different module in a
debug session 241
handling exceptions
*PSSR error subroutine 301
avoiding a loop in an error
subroutine 304
cancel handler 312
file error subroutine 298
unhandled escape message 292
unhandled function check 292
using a cancel handler 313
using a condition handler 306
I/O
data maintenance 413
inquiry by zip code and search on
name 432
inquiry program 410
subfile processing 424
interactive application 409
managing your own heap 125
module with multiple procedures 40
passing parameters using the CL
CALL command 108
program/procedure call
checking number of passed
parameters 147
using omitted parameters 98
sample ILE RPG program 6
subprocedures 37
creating a NOMAIN module 80
exception
monitoring during run time 114
nested, 291
exception handler
priority of 291
RPG-specific 288, 294
exception messages
percolation 286
types of 286
unexpectedly handled by CL
MONMSG 315
unhandled 291
exception/error handling
*PSSR error subroutine 301
avoiding a loop 304
cancel handler 312
condition handler 306
differences between ILE RPG and
OPM RPG/400 290, 446
error indicators 294
error/exception subroutine
overview 297
exceptions 216
file error/exception (INFSR)
subroutine 298
general considerations 290
MONITOR group 295
NOOPT keyword 294
optimization considerations 294
528
F
fetch overflow
general description 385
logic 385
field
changing the value while
debugging 275
displaying attributes of while
debugging 277
displaying while debugging
as hexadecimal values 269
in character format 269
in UCS-2 format 270
in variable-length format 270
using EVAL 263
equating with a name while
debugging 278
maintaining current values while
debugging 230
field-reference file, example of 351
file
device dependence 329
device independence 329
differences between ILE RPG and
OPM RPG/400 447
DISK 349
externally described 329
externally described disk 350
general considerations 329
indexed 356
locking 343
file (continued)
name
externally described 329
override 335
program-described 339
naming conventions 331
open options 345
override 335
PRINTER 381
processing charts
sequential file 391
SPECIAL file 393
WORKSTN file 406
program described 329, 339
redirection 330
SEQ 358, 390
sharing 345
valid keys 353
WORKSTN 395
file description specifications
commitment control 375
for externally described files 333
general description 3
file exception/error subroutine (INFSR)
description 298
example 298
specifications for 298
file exception/errors
definition 288
example 298
using an INFSR subroutine 298
file information data structure
example 298
using in an error subroutine 298
file locking 343
file operations
allowed with DISK file 372
allowed with PRINTER file 381
allowed with sequential file 391
allowed with SPECIAL file 392, 393
allowed with WORKSTN file 405
file overrides 335
example 342
general discussion 341, 371
indicated in compiler listing 503
file record length, conversion
considerations 452
file sharing 345
final summary in compiler listing 515
FIND debug command 231
FIXNBR parameter
CRTBNDRPG command 62, 490
CRTRPGMOD command 78
flowchart
fetch-overflow logic 385
format name 403
format of compiler listing, specifying 68
formatted dump 319
FREE (deactivate a program) operation
code 467
Free Storage (CEEFRST) bindable
API 20
freeing resources of ILE programs 116
FROMFILE parameter 456
FROMMBR parameter 457, 459
function check
definition 286
G
GDDM 163
generating a program
See compiling
GENLVL parameter
CRTBNDRPG command 62, 482
CRTRPGMOD command 78
Get Descriptive Information About a
String Argument (CEESGI) 145
Get Heap Storage (CEEGTST) bindable
API 21, 126
graphic format
graphic CCSID
indicated in compiler listing 508
NLSS debug considerations 249
rules for assigning values using
EVAL 275
graphic support 163
Graphical Data Display
Manager(GDDM) 163
H
halt (H1-H9) indicators
used to end a program/
procedure 159, 160
handling exceptions/errors
*PSSR error subroutine 301
avoiding a loop 304
cancel handler 312
condition handler 306
differences between ILE RPG and
OPM RPG/400 290, 446
error indicators 294
error/exception subroutine
overview 297
file error/exception (INFSR)
subroutine 298
general considerations 290
NOOPT keyword 294
optimization considerations 294
overview 285
percolation 286
RPG-specific 288
specifying a return point 305
types of 285
unhandled 291
using 'E' extender 294
heap
default heap 119
definition 117
example 125
help command key 398
hexadecimal values, displaying while
debugging 269
home command key 398
I
I/O differences between ILE RPG and
OPM RPG/400 447
ICF communications file 395
identifying an activation group 114
IGNORE keyword 334
ignoring record format 334
ILE
See Integrated Language Environment
(ILE)
ILE C
as ILE language 17
in advanced application 30
in mixed-language application 29
parameter passing method 154
source for module in debug
example 283
ILE CL
as ILE language 17
as module in ILE program 27
calling ILE RPG program 28
calling RPG program 25
in advanced application 30
in mixed-language application 29
parameter passing method 154
unexpectedly handling status and
notify exceptions 315
ILE COBOL
as ILE language 17
parameter passing method 154
ILE RPG
behavior of bound modules 84
behavioral differences between OPM
RPG/400 445
converting to 451
data management operations 340
device types supported 381
exception handling overview 288
logic chart 4
overview of RPG IV language 3
sample program 6
ILE source debugger
debug commands 230
description 230
starting 236
include source view, creating 234
INDENT parameter 235
CRTBNDRPG command 62, 486, 487
CRTRPGMOD command 78
indenting structured operations in the
compiler listing 69
indexed file
access path 356
general description 356
valid search arguments 357
indicators
as error indicators 294
displaying while debugging 268
error 294
function key (KA-KN, KP-KY)
with WORKSTN file 397
halt (H1-H9)
used to end a
program/procedure 159, 160
last record (LR)
general description 5
indicators (continued)
last record (LR) (continued)
used to end a
program/procedure 159, 160
overflow
examples 385
fetch overflow logic 385
general description 381
presence or absence of 383
relation to program cycle 385
setting of 385
with PRINTER file 381
return (RT)
used to end a
program/procedure 159, 160
using 5
input
file 404
input record
unblocking 355
input specifications
general description 3
inquiry messages
list of 112
replying to 112
inserting specification templates 462
INSRTPL parameter 458, 462
integer format
TRUNCNBR parameter 490
Integrated Language Environment (ILE)
effect on
OPM-compatible program 24
program using CRTBNDRPG 26
ending an ILE program 113
family of ILE compilers 17
interlanguage calling
considerations 155
interlanguage calls 154
internal structure of program 85
overview 17
program call 19
program creation 17
program creation strategies 23, 25, 27
program management 19
interlanguage calls 154
Intersystem Communications Function
(ICF) 395
J
Java
calling Java from RPG 195
calling Java methods 195
calling RPG from Java 202
calling RPG programs using
PCML 223
coding errors 205
Java Virtual Machine (JVM) 207
native methods 202
prototyping 192
runtime errors 216
JNI functions, wrappers for 207
Index
529
K
key
composite 354
for a record or a file 353
partial 354
key field information in compiler
listing 511
keyed processing 379
access path 350
indexed file 356
record-address limits file 359
sequential-within-limits 368
unexpected results 379
keyed-sequence access path 350
keywords
*OMIT 146
DDS 349
EXPORT 89
for continuation line 349
CLEAR 398
HELP 398
HOME 398
PRINT 398
ROLLDOWN 398
ROLLUP 398
for display device file
CLEAR 398
HELP 398
HOME 398
PRINT 398
ROLLDOWN 398
ROLLUP 398
NOOPT 92, 294
LANGID parameter
CRTBNDRPG command 62, 488
CRTRPGMOD command 78
languages, ILE 17
last record (LR) indicator
used to end a program/
procedure 159, 160
length of record in a file, conversion
considerations 452
level checking 339
library, creating 51
LICOPT parameter
CRTBNDRPG command 494
limitations of the XML parser 189
limits records 351
listing view, creating 235
listing, binder
as maintenance resource 91
basic 104
creating 90
determining exports in service
program 95
sections of 90
listing, compiler
additional diagnostic messages 71
browsing using SEU 72
coordinating listing options with
debug view options 72
correcting compilation errors 70
correcting run-time errors 72
530
main procedure
coding considerations 45
overview 33
returning from 158
scope of files 84
maintaining OPM compatibility 65, 116
managing activation groups 114
managing dynamically-allocated
storage 117
managing programs 19
managing run-time storage 117
managing the default heap using RPG
operations 119
manual code conversion 469
MCH3601 447
memory management operations
%ALLOC built-in function 119
%REALLOC built-in function 119
ALLOC (allocate storage) operation
code 119
DEALLOC (free storage) operation
code 119
REALLOC (reallocate storage with
new length) operation code 119
message summary in compiler
listing 515
messages
additional diagnostic 71
exception
example 292
messages (continued)
exception (continued)
types of 286
unhandled 291
in-line diagnostic 71
inquiry
replying to 112
migrating to ILE RPG
See converting to RPG IV
modifying a module 91
module
about 77
behavior of bound ILE RPG 84
binding into a program 85
binding multiple 89
changing optimization level 92
changing while debugging 241
creating 77
creating a NOMAIN module 80
CRTRPGMOD command 78
determining the entry module 87
different debug views 242
effect of debug data on size 233
information in dump listing 319
modifying and rebinding 91
overview of multiple-procedure
module 33
preparing for debugging 232
reducing size 93
related CL commands 84
relationship to program 85
removing observability 92
replacing in a program 91
viewing source while debugging 240
module creation
general discussion 77
using CRTRPGMOD 78
using CRTRPGMOD defaults 80
module observability 92
MODULE parameter 87
CRTBNDRPG command 481
CRTRPGMOD command 78
MONITOR group 295
MQSeries 191
multiple devices attached to application
program 376
multiple-device file
WORKSTN 406
N
named activation group 114
National Language Support (NLS) of
source debugger 279
nested exceptions 291
no debug data 233
NOMAIN module
coding considerations 45
creating 80
nonkeyed processing 371
NOOPT keyword
and handling exceptions 294
maintaining current values while
debugging 230
program optimization level 92
normal program/procedure end 159
NOT
Behavioral difference between ILE
RPG and RPG/400 445
null value support
displaying null-capable fields 272
O
observability 92
obtaining a compiler listing 67
obtaining conversion reports 461
OFL 305
omitted parameters 146
*OMIT 146
ON-ERROR group 295
one-step process of program creation 61
online information
for create commands 481
for ILE source 232
open data path
sharing 345
operation codes 405
allowed with DISK file 372
allowed with PRINTER file 381
allowed with sequential file 390
allowed with SPECIAL file 393
allowing 'E' extender 295
allowing error indicators 295
general discussion 6
operational descriptors
definition 144
example 98
OPM compatibility, maintaining 65, 116
OPM default activation group 23, 31
running in 115
optimization
definition 92
effect on fields when debugging 230
exception handling
considerations 294
level of
changing an object's 92
checking 92
OPTIMIZE parameter
CRTBNDRPG command 62, 487
CRTRPGMOD command 78
OPTION parameter
coordinating listing and debug view
options 235
coordinating with debug view
options 72
CRTBNDRPG command 62, 483
CRTRPGMOD command 78
using 67, 73
OPTIONS keyword
*NOPASS 146
*OMIT 146
order of evaluation
on prototyped call 153
output
specifications
program-described WORKSTN
file 403
output buffer positions, in compiler
listing 510
output file 405
OUTPUT parameter
CRTBNDRPG command 62, 486
CRTRPGMOD command 78
using 67
output record
blocking 355
output specifications
example 9
general description 3
program-described WORKSTN
file 403
with external descriptions 337
output spooling 347
overflow
indicators 383
page 382
overflow indicators
conditioning output 383
examples 385
fetch-overflow logic 385
general description 383
presence or absence of 383
relation to program cycle 385
setting of 385
with PRINTER file 381
overrides, file 335
example 342
general discussion 341, 371
indicated in compiler listing 503
overriding external description 335
P
page headings 68
page number, in PRINTER file 382
page overflow, in PRINTER file 382
parameter descriptions
CRTBNDRPG command 481
CRTRPGMOD command 499
CVTRPGSRC command 456
parameter list
created by PARM 158
identifying 138
rules for specifying 158
parameter table
CRTBNDRPG command 62
CRTRPGMOD command 78
CVTRPGSRC command 455
parameters
checking number passed 147
match data type requirements 144
omitted 146
operational descriptors 144
passing 138
passing using the CL CALL
command 107
specifying 157
PARM (identify parameters) operation
code 108
*OMIT 146
rules for specifying 157
using 157
partial key 354
parts of an ILE RPG program 6
passing file parameters 153
passing parameters
by read-only reference 142
531
procedure (continued)
stepping over 259
procedure pointer calls 134
processing methods
consecutive 360
for DISK file 360
nonkeyed 371
random-by-key 366
relative-record-number 370
sequential only 361, 371
sequential-by-key 361
sequential-within-limits 368
WORKSTN file 398, 405
processing XML documents 185
limitations of the XML parser 189
XML parser error codes 187
program
abnormal ending 160
advanced ILE 30
binding modules 85
calling 133, 134
calling using expressions 140
calling using the CALL
operation 155
calling using the CALLP
operation 140
changing 91
changing optimization level 92
changing while debugging 241
different debug views 242
effect of debug data on size 233
ending 113
entering source 51
entering SQL statements 55
example 6
freeing resources 116
internal structure 85
mixed-language 29
multiple-module
general creation strategy 27
normal ending 159
OPM-compatible
creation method 23
effect of ILE 24
example 23
program creation strategy 23, 31
passing parameters 138
preparing for debugging 232
program entry procedure 85
reducing size 93
related CL commands 90
removing observability 92
returning from 158
returning without ending 160
running 107
running from a menu-driven
application 109
running in the OPM default activation
group 115
running using a user-created
command 112
setting watch conditions 253
single-language 28
effect of ILE 26
stepping into 260
stepping over 259
stepping through 258
532
program (continued)
updating 91
viewing source while debugging 240
program activation 114
program creation
coding considerations 45
examples of 63, 64, 65, 89
OPM-compatible
creating 23
strategy to avoid 31
strategies for 23
CRTPGM command 87
ILE application using
CRTRPGMOD 27
OPM-compatible 23
strategy to avoid 31
using CRTBNDRPG 25
using CRTRPGMOD and
CRTPGM 77
using the one-step process 61
program cycle
commitment control 378
fetch overflow logic 385
general description 4
last cycle 5
program entry procedure (PEP)
and the call stack 135
definition 85
determining 87
program exception/error subroutine
description 301
example 301
program exception/errors
avoiding a loop 304
definition 288
example 301, 306
using a *PSSR subroutine 301
program management 19
program name
*FROMMBR parameter 458
program status data structure
example 157, 301
using in an error subroutine 301
program-described file
as DISK file 356
as WORKSTN file 402, 403, 404
definition 331
physical and logical files 349
valid search arguments 357
program/procedure call
abnormal program/procedure
end 160
call stack 135
calling bindable APIs 162
calling graphics 163
calling procedures 134
calling programs 134
calling special routines 164
fixed-form call 155
free-form call 140
interlanguage calls 154
normal program/procedure end 159
overview 133
parameter passing methods 142
recursive calls 136
returning from a called program or
procedure 158
Q
QUAL debug command
definition 231
ILE RPG 275
querying names of called
programs/procedures 156
R
random-by-key processing
example 367
general discussion 366
RCLACTGRP command
See Reclaim Activation Group
(RCLACTGRP) command
RCLRSC command
See Reclaim Resources (RCLRSC)
command
reading a record 406
reading next record
with WORKSTN subfile 400
REALLOC (reallocate storage with new
length) operation code 119
Reallocate Storage (CEECZST) bindable
API 21
rebinding 91
Reclaim Activation Group (RCLACTGRP)
command
deleting activation groups 116
named activation groups 114
Reclaim Resources (RCLRSC) command
ILE program 26
OPM-compatible program 24
to free storage 116
RECNO keyword
with relative-record-number
processing 370
record
limits 359
locking 344
releasing 344
valid keys 353
record address file
conversion problems 464, 473
relative-record number 359
sequential-within-limits 359
with limits records 359
with relative record numbers 359
record format
for a subfile 399
ignoring 334
renaming 334
specifications for externally described
file 350
record length of files, conversion
considerations 452
record locking 344
recursion
calling condition handlers 306
recursive calls 46, 136
redirection, file
definition 330
general description 330
reducing object size 93, 233
Register Call Stack Entry Termination
User Exit Procedure(CEERTX) 312
Register ILE Condition Handler
(CEEHDLR) API 306
relative-record number 359
relative-record-number processing 370
releasing a locked record 344
removing breakpoints
about 243
all 253
conditional job breakpoints 247
conditional thread breakpoints 252
unconditional job breakpoints 244
unconditional thread breakpoints 246
using statement numbers 250
removing objects from a debug
session 239
removing observability 92
RENAME keyword 334
renaming field names 334
renaming fields 334
renaming record-format names 334
REPLACE parameter
CRTBNDRPG command 62, 488
CRTRPGMOD command 78
replacing modules in a program 91
reply list of messages
adding to 112
changing 113
replying to run-time inquiry
messages 112
requirements of Conversion Aid 453
reserved words
*CANCL 305
*DETC 305
*DETL 305
*GETIN 305
S
sample programs
See examples
scope
of files 84
533
534
T
table
displaying while debugging 266
table of parameters
CRTBNDRPG command 62
CRTRPGMOD command 78
CVTRPGSRC command 455
tape file 358
TBREAK debug command
definition 231
using 246, 252
templates, inserting specification 462
teraspace 165
test library, using 238
testing breakpoints 244
TEXT parameter
CRTBNDRPG command 62, 483
CRTRPGMOD command 78
TGTRLS parameter
CRTBNDRPG command 62, 490
CRTRPGMOD command 78
THREAD debug command
definition 231
using 246
threaded applications
coding considerations 165
debugging 243
locking and unlocking
procedures 168
overview 21
TOFILE parameter 457, 460
TOMBR parameter 457, 459
TOTC 305
TOTL 305
trial conversion, performing 460
TRUNCNBR parameter
CRTBNDRPG command 62, 490
CRTRPGMOD command 78
two-step process of program creation 77
types of exception handlers 285
U
UCS-2 format
displaying while debugging 270
UCS-2 CCSID
indicated in compiler listing 508
UEP
See user entry procedure (UEP)
unblocking/blocking records 355
unconditional breakpoint
definition 243
setting 245
setting and removing for job 244
setting and removing for thread 246
using statement numbers 250
unhandled escape message 292
unhandled exceptions 291
unhandled function check 292
Unregister ILE Condition Handler
(CEEHDLU) API 306
unsigned integer format
TRUNCNBR parameter 490
Update Program (UPDPGM) command
using 91
updating a service program 103
UPDPGM command
See Update Program (UPDPGM)
command
user entry procedure (UEP)
and the call stack 135
role in program 85
user-created command, running an RPG
program 112
USRPRF parameter on CRTBNDRPG
CRTBNDRPG command 62, 489
V
valid file operations
SPECIAL file 393
valid keys
for file 353
for records 353
variable-length format
displaying while debugging 270
variable-length records 390
view, debug
changing while debugging 242
COPY source 234
default 236
definition 232
listing 235
root source 233
statement 236
viewing source while debugging 240
X
XML 185
processing XML documents 185
limitations of the XML parser 189
XML parser error codes 187
XML parser error codes 187
W
WATCH debug command
definition 231
example 257
setting conditions 253
Work with Reply List Entry (WRKRPLYE)
command
changing a system reply list 113
WORKSTN file
definition 395
examples 409
externally described
processing 398
externally-described 395
Index
535
536
Printed in U.S.A.
SC09-2507-08