In V5R1, ILE RPG (RPG IV) was given a facelift with the addition of a free-format coding option. This option allows you to write the calculation (C) specs of your program without following the rigid positioning requirements of a standard RPG program and, for that matter, without the C! What you end up with is a programming language that is like a mix between RPG and C with a dash of Java thrown in. In this article, I'll examine what you can and can't do in free-format ILE RPG and how to make the most of this great programming alternative.
/free Your Mind
If you are running OS/400 V5R1 or
higher, you already have what you need to use free-format ILE
RPG. That's because the free-format option has become part
of the language structure. A free-format block of code is
defined by using the /free and /end-free
compiler directives. This allows you to define some portions
of a program using free-format code and other portions using
standard ILE RPG code.
There are currently a few things that you can't do in
free-format. One example is defining a key list (KLIST) to be
used when chaining or reading from a file. The KLIST opcode
and corresponding KFLD opcodes must be defined using standard
ILE RPG C specs. It's also important to remember that the
file (F) specs, definition (D) specs, and output (O) specs
cannot be specified in free-format. The code shown in Figure 1
is a sample of free-format C specs.
|
Figure 1: This code is an example of free-format ILE RPG C
specs.
The free-format section of the code starts with the
/free compiler directive and ends with the
/end-free compiler directive. As for the code that
falls between these two directives, you'll notice some
things that look familiar and some things that may not. First
off, all free-format code must be specified between positions
8 and 80 on each line. You'll also notice that a semicolon
is used to identify the end of each the statement. This is
done to allow for statements to be longer than a single line.
The C is also gone from the calculation specs. Compiler
directives can be placed within free-format code, but it's
important to remember that they cannot appear on a line with
any operation codes. When using the /COPY or /INCLUDE compiler
directives to include code from another source file, the
compiler assumes that the copied code is in standard
fixed-format RPG. This means that any free-format copybook
source must begin and end with the /free and
/end-free compiler directives.
The Code
In some cases, the free-format
versions of the RPG opcodes may be coded differently from the
fixed-format RPG. The free-format version of the IF
statement works in pretty much the same way as the ILE RPG
IF statement. In free-format, however, the condition
portion of the statement is not limited to what can fit in the
extended factor 2 field. The free-format CHAIN statement is
used slightly differently from a standard ILE RPG
CHAIN. In free-format, the chain command is used, as
shown below:
In this sample, the E operation extender can be used to reset
the state of the %ERROR and %STATUS built-in functions (BIFs)
prior to performing a chain. The N operation extender is used
on an update-capable disk file to disable record locking for
this chain operation. Keyfield identifies either a single
field or a key list name containing the search key value as
would appear in factor 1 on a CHAIN in standard RPG. The
file-or-record-name identifies the file name or record name to
be chained to. This value would appear in factor 2 of a
standard RPG statement. The optional data-structure name can
be used with program-described files to place the record read
into the defined data structure.
As with all of the free-format operation codes, the
free-format CHAIN operation doesn't allow resulting
indicators to be used. The %error and %found BIFs should be
used in place of the resulting indicators for any file access
opcodes (Chain, Read, etc.) When using free-format code, the
eval and callp operations can be omitted. This means
that either of the following statements can be used to set the
value of the payment variable.
payment=(principal+interest) / term;
One circumstance where you will need to use the eval
opcode is when you want to use an operation extender,
such as the half-adjust extended (H), as shown below:
Just as with the eval opcode, the callp opcode
can be omitted when calling a prototyped procedure. The
free-format syntax allows for either of the lines of code
shown below:
procname();
As this example shows, you must specify empty parentheses if
no parameters are being passed. In addition to some other
opcodes, for obvious reasons, the RPG arithmetic operation
codes (ADD, SUB, MULT, DIV, MVR) are not supported in
free-format. These can be replaced by the mathematic operators
(+, -, *, /) along with the BIF %REM, which is used to replace
the move remainder (MVR) opcode. In addition to these, the
MOVE opcodes (MOVE, MOVEA, MOVEL) and COMP opcode are also not
supported in free-format. The table in Figure 2 contains a
list of the operations that are supported in free-format.
Free-Format Opcodes |
|||||
ACQ
|
DOW
|
ENDSR
|
IN
|
POST
|
SELECT
|
BEGSR
|
DSPLY
|
EVAL
|
ITER
|
READ
|
SETGT
|
CALLP
|
DUMP
|
EVALR
|
LEAVE
|
READC
|
SETLL
|
CHAIN
|
ELSE
|
EXCEPT
|
LEAVESR
|
READE
|
SORTA
|
CLEAR
|
ELSEIF
|
EXFMT
|
MONITOR
|
READP
|
TEST
|
CLOSE
|
ENDDO
|
EXSR
|
NEXT
|
READPE
|
UNLOCK
|
COMMIT
|
ENDFOR
|
FEOD
|
ON-ERROR
|
REL
|
UPDATE
|
DEALLOC
|
ENDIF
|
FOR
|
OPEN
|
RESET
|
WHEN
|
DELETE
|
ENDMON
|
FORCE
|
OTHER
|
RETURN
|
WRITE
|
DOU
|
ENDSL
|
IF
|
OUT
|
ROLBK
|
|
Figure 2: These opcodes are supported by free-format ILE
RPG.
It's important to remember that resulting indicator use is
not permitted in free-format. As with the chain example
earlier, most operation codes that have result indicators in
standard RPG can use a BIF in place of the result indicator.
When using the any of the READ opcodes, the %EOF and %ERROR
BIFs can be used in place of result indicators. Figure 3 shows
a sample of the free-format code using READE operation.
|
Figure 3: This example shows how to use the free-format ILE
READE opcode.
As with the chain opcode, the set low level key (setll)
and read equal key (reade) opcodes are both used in the
format:
This is actually the case with most of the ILE RPG opcodes
available in free-format. The exception would be any opcodes
that do not require one of the factors or the result field.
Operands, including subroutine names, can be longer than the
14-character limit of standard ILE RPG. Because there is now a
means by which to define a field within free-format, all field
definitions must be done outside of the free-format code,
using either standard RPG statements or D specifications. A
single statement can be continued to multiple lines by simply
omitting the semicolon character on all but the last line.
Figure 4 shows a sample of a multi-line statement.
|
Figure 4: Free-format ILE RPG statements can run over
multiple lines.
In this example, the value for the field TextDate is evaluated
using the %substr BIF within one statement that runs
over two lines of code. The evaluated value is then displayed
to the session console using the dsply opcode.
An important consideration when moving from standard RPG or
ILE RPG to free-format RPG is that conditioning indicators, as
shown in the example below, can't be used:
C KC RETURN
While the use of conditioning indicators is frowned upon by
many programmers, let's face it, you probably have a
program running somewhere on your system that still uses this
type of code. In free-format, this would be replaced by the
section of code shown here:
if *INKC;
*INLR = *ON;
return;
endif;
/end-free
This example replaces the conditioning indicator with an
if statement that checks the state of the indicator
*INKC, which indicates that the F3 key was pressed. While
using this technique would be preferred in any version of RPG,
in free-format it's absolutely required. This can be a
consideration if you're planning to convert old
applications to free-format.
Something Old, Something New
One nice thing about moving to the
free-format RPG is that you can actually combine standard RPG
statements with sections of free-format code. Figure 5 shows
an example of mixing free-format and fixed-format ILE RPG
code.
|
Figure 5: This sample combines free-format code with
standard ILE RPG code.
This example uses the MOVE opcode to put the contents of the
alphanumeric field DATEALPH into the numeric field DATENUM
using standard-format ILE RPG code. A free-format
if statement is then used along with a statement that
evaluates a new value for the field DATENUM. In this
example, you are also able to define the field length for
DATENUMwithin the fixed-format code. As I mentioned earlier,
this can't be done in free-format.
One of the advantages of being able to combine standard-format
ILE RPG with free-format is that you can slowly convert a
program to free-format, piece by piece. This allows you to
change portions of the code and then compile and test them.
This can make debugging problems with converted code much
easier.
As I mentioned earlier, any copybook source is assumed to be
fixed-format but can be identified as free-format using the
/free and /end-free directives at the beginning
and end of the copybook source. This allows you to maximize
the use of existing code segments that are stored in copybook
members while creating programs that use free-format code.
This also means that if you convert existing copybook members
to free-format code, standard ILE RPG programs that used the
old versions will be able to use the new free-format version
of the copybook by simply recompiling.
Another advantage to being able to combine standard ILE RPG
and free-format ILE RPG is that it will allow you to make use
of opcodes that are not supported in free-format, for example
GOTO and TAG. If your program requires the use of these
opcodes, other than redesigning the logic of your program,
there really is no good alternative. The sample code shown in
Figure 6 allows you to use the GOTO and TAG opcodes while
still making use of free-format code.
|
Figure 6: This example mixes standard ILE RPG with
free-format code.
While this example doesn't use "preferred"
programming techniques, it illustrates the point.
What Else Is in V5R1 RPG?
Another feature that was added into
ILE RPG in V5R1 that is not specific to free-format but does
complement the free-format code nicely is the ability to use
qualified field names with data structures. With this feature,
you can to define the same field name within two data
structures and reference the correct field in the same way
that you would in SQL, C, or Java. This is accomplished
through the use of two new keywords on the D specs. The
QUALIFIED keyword defines that a data structure will be
accessed using its qualified name. The LIKEDS(data
structure name) keyword allows you to define a new data
structure that has the same format as an existing data
structure. Figure 7 shows an example of how this would appear
in a program.
|
Figure 7: This sample code shows the use of qualified data
structures.
This example illustrates the ability to access the fields
within each of the data structures using the following
format:
In addition to qualified data structures, the elseif opcode is
an addition in V5R1 that, while not restricted to free-format,
extends the usefulness of free-format ILE RPG. The elseif
opcode allows you to reduce the number of nested if
statements within your program. This opcode allows you to
replace this code
if A=1 ;
A=2;
else;
if A=2;
A=3;
else;
if A=3;
A=4;
endif;
endif;
endif;
/end-free
with this much simpler code:
if A=1 ;
A=2;
elseif A=2;
A=3;
elseif A=3;
A=4;
endif;
/end-free
Not only does this method require fewer lines of code, but it
makes analyzing the code a much simpler process.
V5R2 Changes and Additions
As if what I've covered already
wasn't enough, in V5R2, IBM is offering even more
enhancements to free-format ILE RPG. Not the least of these
enhancements is the addition of the %KDS BIF. This function
can be used with file opcodes (chain, read, etc.) in place of
a key list, as shown below:
/free
chain %KDS(DSKEY) file;
In this example, DSKEY is a data structure defined using the
new LIKEREC keyword. This keyword allows you to create a data
structure based on a record format. In the example here, the
*KEY parameter is used to retrieve only the key field
information from the specified file. Partial keys can be used
by specifying a second parameter on the %KDS function that
defines the number of key fields to be used, as shown
here:
/free
chain %KDS(DSKEY: 2) file;
In this example, the first two key fields defined for the file
would be used to retrieve the record. Alternatively, in V5R2,
you can specify a list of fields in place of the key list name
or %KDS BIF as shown here:
chain (item: cust: store) file;
This example uses the three specified fields to retrieve the
desired data from the file. You can specify partial keys by
simply reducing the number of fields within the parentheses.
When using either of these techniques in free-format code,
another big change is that fields specified within the key
have to be only the same type, not the same length. This means
that if your file has a key field defined as a nine-position
numeric field with no decimal places, you can chain to that
file using a numeric field that is defined as 15 positions
with five decimals.
Here's another example: If a file's key field is a
10-character alpha field, the key field specified in
free-format could be a 12-character alpha field. You
can't, however, use a numeric field for a key that is
alpha or vice versa.
Another BIF that makes its debut in V5R2 is the %FIELDS BIF.
This function is used with the update opcode and allows you to
selectively update defined fields. The following example would
be used to only update the fields fldate and fltime when the
update operation is executed:
update file %fields(fldate:fltime);
Mathematical operators have also been enhanced in V5R2 with
the addition of +=, -=, *=, **= and /=. These operators can be
used to perform the desired arithmetic function on the result
field and another specified field or value. For example,
instead of using
you can now specify this:
In either of these examples, the value of count is replaced
with the value of count plus one. This method is similar to
the arithmetic functions used in C or Java.
In addition to these, the %DEC, DECH, %FLOAT, %INT, INTH,
%UNS, and %UNSH BIFs have been enhanced to allow the use of a
character field as the parameter for the functions. This means
that the example below is now acceptable:
IntVal=%INT('12345.76')
This enhancement makes it easier to translate a character
field to a numeric field.
Coloring Outside of the Lines
I hope I've helped to illustrate
how free-format ILE RPG can make your programming tasks a lot
easier. Once you've had a chance to try using free-format
code on your system, you'll see how much fun it can be to
color outside of the lines.
Mike Faust is the MIS Manager for
The Lehigh Group in Macungie, PA. He has nearly 15 years of
experience with midrange systems and personal computers. Be
sure to check out Mike's book The iSeries and
AS/400 Programmer's Guide to Cool Things from MC Press. Mike can be reached at
LATEST COMMENTS
MC Press Online