45
Jon Paris Jon.Paris @ Partner400.com www.Partner400.com www.SystemiDeveloper.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had changed over the years - well "You ain't seen nothin' yet!!" V7 brought with it a number of enhancements but the one that has made the biggest impact has undoubtedly been the introduction of free-form data and file definitions. Most of us have been making extensive use of Evals since they were first introduced with RPG IV in V3R1. Perhaps like us you have experienced frustration when forced to split a line because you had run out of space! Maybe you were even tempted to shorten that nice meaningful variable name to avoid having to use a second line! While you were contemplating this dilemma, you might have also noted the fact that there was a huge area of white space to the left of the Eval you couldn't use. V5R1 put an end to that frustration by introducing the notion of completely free-format logic specs. Coupled with a large number of new Built-In Functions (BIFs) this "New" RPG remains familiar, while offering some very powerful new capabilities. Then in V7.1 (with TR7) almost all the rest of the RPG language went free-format - with the addition of free-format replacements for H, F, D and P specs. In this session we will look at: How to code free format RPG logic How to replace operation codes that aren't supported in free format RPG The new BIFs that add power to the language New functions that only work in Free-form form logic How to use the free format replacements for H, F, D and P specs Notes © Partner400, 2017 What's New in RPG Lecture Notes: Page 1 of 45

What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Embed Size (px)

Citation preview

Page 1: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Jon Paris

Jon.Paris @ Partner400.com www.Partner400.com www.SystemiDeveloper.com

What' New in RPG Including the New

Free-Form Definitions.

If you thought that RPGIV had changed over the years - well "You ain't seen nothin' yet!!"

V7 brought with it a number of enhancements but the one that has made the biggest impact has undoubtedly been the introduction of free-form data and file definitions.

Most of us have been making extensive use of Evals since they were first introduced with RPG IV in V3R1. Perhaps like us you have experienced frustration when forced to split a line because you had run out of space! Maybe you were even tempted to shorten that nice meaningful variable name to avoid having to use a second line! While you were contemplating this dilemma, you might have also noted the fact that there was a huge area of white space to the left of the Eval you couldn't use.

V5R1 put an end to that frustration by introducing the notion of completely free-format logic specs. Coupled with a large number of new Built-In Functions (BIFs) this "New" RPG remains familiar, while offering some very powerful new capabilities.

Then in V7.1 (with TR7) almost all the rest of the RPG language went free-format - with the addition of free-format replacements for H, F, D and P specs. In this session we will look at:

How to code free format RPG logic ✦ How to replace operation codes that aren't supported in free format RPG ✦ The new BIFs that add power to the language ✦ New functions that only work in Free-form form logic

How to use the free format replacements for H, F, D and P specs

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 1 of 45

Page 2: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Data Definition and Usage Enhancements Sort and Search Data Structure Arrays Support For Alias Names

New Scan and Replace BIF Subprocedure related enhancements Prototypes are optional Performance improvements for large return values

Process Stored Procedure Result Sets And of course free-form file and data definitions!

V 7.1 RPG Enhancements

NotesWe don't have time to go into all of these features in depth but we have written articles on many of them and of course you can find more about any that I skip by checking out the V7 RPG manual in the Information Center.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 2 of 45

Page 3: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D products1 DS Dim(999) Qualified D productCode 5a D description 40a Varying D totalSales 9p 2 D qtyInStock 5p 0

SortA products1(*).totalSales;

SortA products1(*).description;

SortA(A) products1(*).totalSales; // Sort ascending sequence

SortA(D) products1(*).description; // Sort descending sequence

Sorting Data Structure ArraysData structure arrays can now be sorted • Using any of the subfields as the key

✦ But only a single subfield can be used - No direct support for sorting multi-dimensional arrays

• Asterisk (*) identifies the level at which the array is to be sorted SORTA can now have sequence specified • Using the Op-code extenders A(scending) or D(escending) • Can only be used when no sequence specified in the D-specs

NotesWith the advent of V5R2, it became possible to define Data Structure arrays. i.e. with a DIM keyword at the DS level. But at the time IBM did not provide any means by which such arrays could effectively be sorted. To do that you had to resort to using the qsort function. That shortcoming is removed in V7 and you can now sort on any subfield in the array. For example, given the DS array here, you can perform a sort on qtyInStock or totalSales or any of the other fields in the DS. As you can see from this code, the level of the array to be sorted is indicated by an asterisk (*) in the subscript position.

In the first example the DS array is sequenced on the totalSales values, and in the second the description. Another nice addition to the SORTA repertoire is that you can now specify whether the sort is to be in ascending or descending sequence. Previously this was determined by the ASCEND or DESCEND keyword on the array definition and SORTA used the defined sequence - which of course meant that without playing games (re-mapping the array via pointers etc.) any given array could only ever be in ascending _or_ descending order. Now the op-code extenders (A) and (D) can be used to specify the sequence in which the array is sorted.

The * is used to indicate the level at which the sorting should occur. Of course, in these examples, it's pretty obvious, since it's the only level where sorting is possible. But this sorting capability also works with nested Data Structures, so even very complicated structures can be sorted. The next chart shows you how.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 3 of 45

Page 4: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D products2 DS Dim(999) Qualified D productCode 5a D description 40a Varying D salesByMonth LikeDS(salesByMonth) D Dim(12) D qtyInStock 5p 0 D salesByMonth DS D monthNumber 3p 0 D sales 9p 2 D i S 5i 0 // Sort each entry in turn into sales value sequence For i = 1 to %elem(products2); SortA products2(i).salesByMonth(*).sales; EndFor; // Once individual entries have been sorted into sales value // sequence sort the whole array into product code sequence SortA products2(*).productCode;

Sorting Nested Data Structure ArraysAs noted earlier - no direct RPG support exists • But this is one way to do it

NotesEven nested arrays can be sorted as shown in the example below. In this case the inner array (i.e. the monthly sales values) is sorted into ascending sequence and then the outer array (i.e. the products) are sorted into product code sequence.

Of course, it doesn’t really matter which version of SORTA statement is done first - i.e., we could have sorted by ProductCode first, followed by the loop to sort the sales figures.

Note, however, that there is still no support to sort on 2 (or more) different subfields in a DS array, unless the 2 subfields are contiguous in the DS and in the “correct” sequence.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 4 of 45

Page 5: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D productInfo DS Dim(1000) D Qualified Ascend D productCode 5a D description 40a D unitPrice 5p 2 D qtyInStock 5p 0

D element S 5i 0

SortA productInfo(*).productCode; // Sort into product sequence

// Find product code A123C element = %LookUp( 'A123C': productInfo(*).productCode);

SortA productInfo(*).unitPrice; // Sort into price sequence

// Locate product with unit price of $50 element = %LookUp( 50.00: productInfo(*).unitPrice);

Searching DS Arrays%LOOKUP can now also search DS arrays • The same asterisk (*) notation is used to indicate the search level

Only the vanilla %LookUp is supported • Not the %LookUpGt etc. versions

Ensures that %Lookup uses

fast search

NotesTo be truly useful, any enhancement in sorting needs to be matched with corresponding advances in searching, and the RPG developers haven't let us down. They have enhanced the %LOOKUP BIF to allow for searching within DS arrays.

At this time only the "exact match" %LookUp is supported. Hopefully %LookUpGt and other members of the family will be supported in future releases. In the meantime you will have to write your own routine to do this.

Notice that I have specified the Ascend keyword against the array definition. When this is used %Lookup can use a binary search which is orders of magnitude faster than the conventional linear search that would otherwise be used.

BUT ... you _must_ make certain that the array is in ascending sequence on the lookup key or you will get a lot of false misses.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 5 of 45

Page 6: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

DDS for file CUSTFILE A R CUSTREC A CUSTNM 25A ALIAS(CUSTOMER_NAME) A CUSTAD 25A ALIAS(CUSTOMER_ADDRESS) A ID 10P 0

D custDs e ds ALIAS QUALIFIED D EXTNAME(custFile)

custDs.customer_name = 'John Smith'; custDs.customer_address = '123 Mockingbird Lane';

custDs.id = 12345;

Using ALIAS NamesALIAS names can be used in Externally-described data structures • By using the ALIAS keyword on the DS definition

ALIAS names can be used for file fields • Use the ALIAS keyword on the File specification

✦ Any LIKEREC or EXTNAME DS based on the file will use the ALIAS name

NotesFor many, many years going all the way back to the System/38, the database has supported the use of longer alias names as an alternative to the cryptic 10 character names that we normally use. Indeed many COBOL shops have always taken advantage of them. Usage of alias names has also increased in recent years with the growth in popularity of SQL. But during all this time RPGers were locked out of using these longer names as the language was tied to the old I and O specs and their limited field names.

When result field I/O was first introduced for externally described files - back in the V5R2 timeframe - we felt that this might herald the arrival of Alias names into RPG. Well it has taken a few releases, but it is finally here. As from V7.1 you can specify the ALIAS keyword when defining an externally described DS, or any DS defined with LIKEREC. When the ALIAS keyword is used, the compiler uses the longer alias name for the field rather than the short name. In cases where the alias name does not meet RPG naming standards, the compiler reverts to using the short name.

Note that you put the ALIAS keyword on the F spec if you choose to create the DS using LIKEREC. However, if you create the DS using EXTNAME, then use specify ALIAS on the DS description on the D spec.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 6 of 45

Page 7: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

dcl-f diskf usage(*update : *output); dcl-f prtf printer; dcl-ds diskDs extname('DISKF' : *all) end-ds; dcl-ds prtDs extname('PRTF' : *all) end-ds;

read diskfmt diskDs; write diskfmt diskDs; update diskfmt diskDs;

write prtfmt prtDs;

Simplified Rules for Data Structure I/OPrior to these changes it was hard to use DS I/O in some cases • For example when using READ and Write on the same file you had to have two

structures - one defined *Input and one *Output • Then use Eval-Corr to copy the data from one to the other

Now you can omit the type parameter and use the DS for all operations • Or specify *ALL which is perhaps a more obvious approach

✦ This was supported for WORKSTN files in V6

• The compiler determines which fields belong to the input set and which to the output

NotesData Structure I/O can be a very useful capability - but caused problems with Workstation files and any file where both input and output is required on the same file. These relaxed rules make life far simpler.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 7 of 45

Page 8: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

string1 = 'See &NAME. See &NAME run. Run &NAME run.';

string2 = %ScanRpl('NAME' : 'Forrest' : string1);

// string2 now contains 'See Forrest. See Forrest run. Run Forrest run.'

string3 = %ScanRpl(' ' : ' ' : string2); // Change double spaces to single

// string3 now contains 'See Forrest. See Forrest run. Run Forrest run.'

Scan and ReplaceNew built-in function %SCANRPL %SCANRPL ( scanFor : replaceWith : targetString ) • Replaces all occurrences of scanFor within the target string with the

contents of replaceWith ✦ Optional 4th & 5th parameters for scan-start-position and scan-length ✦ %SCANRPL( scanFor : replaceWith : target { : scan start { : scan length } )

Much simpler than having to code it the old way • i.e. a %SCAN and %REPLACE loop

✦ Or %Scan and %Subst or ...

NotesNote that in the example shown, replacing double spaces with a single space will only work on sets of double spaces on the first pass through the string. In other words, if there were 4 spaces in a row, the new string would still have 2 spaces. If there were 3 spaces initially there would still be 2 spaces after the replacement.

But %ScanRpl can be used with a null string as the replacement - does that help? Well it does but it creates the problem that if there were originally an even number of spaces then after the replacement there are none! Since we don't know exactly where the spaces originally were, we have no idea where to put the required space back in. Sometimes it seems you just can't win. But we have shown a possible solution on the next page - it looks odd - but it works.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 8 of 45

Page 9: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

d testString s 40a Inz('4 spc 7 spc 10+ spc ') d result s 40a Varying

/free

result = %ScanRpl( ' ': '<>': testString ); // replace each space with <> dsply ('Contents: ' + result );

result = %ScanRpl( '><': '': result ); // replace all >< with nothing

dsply ('Contents: ' + result );

result = %ScanRpl( '<>': ' ': result ); // replace remaining <> with space

dsply ('Contents: ' + result );

dsply ('Length of result is ' + %Char(%Len(result)));

Scan and Replace - ExampleThe code below will remove all instances of multiple spaces • And replace them with a single space

DSPLY op-codes allow you to see it happening step by step

NotesThis approach to the problem uses a rather strange looking sequence. It really does look "odd". For that reason I have included a number of displays so that you can see the change in the string as each phase progresses. I suspect there may be a better/shorter way of doing this but this one is fun anyway. If you decide to use it in a program PLEASE wrap it up in subprocedure or you will confuse the heck out of those who follow you!

Below you can see the displays produced:

DSPLY Contents: 4<>spc<><><><>5<>spc<><><><><>6<>spc<>

DSPLY Contents: 4<>spc<>5<>spc<>6<>spc<>

DSPLY Contents: 4 spc 5 spc 6 spc

DSPLY Length of result is 18

© Partner400, 2017 What's New in RPG Lecture Notes: Page 9 of 45

Page 10: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D CustResultSet S SQLType(RESULT_SET_LOCATOR)

Exec SQL Call CustomersByState( :InputState );

Exec SQL Associate Result Set Locator (:CustResultSet) with Procedure CustomersByState; Exec SQL Allocate C1 Cursor for Result Set :CustResultSet;

Exec SQL Fetch next from C1 into :CustData;

Processing Result Sets in RPGRPG stored procedures have always been able to return a result set • But we could not receive/process that result set in an RPG program

This new support may feel a bit "clunky" - But it works - You need to ... • Define a RESULT_SET_LOCATOR (defined on D spec) • Then ASSOCIATE the Result Set Locator with the Procedure • Then ALLOCATE the CURSOR for the result set

NotesIf this syntax seems convoluted to you, we agree. It seems that it shouldn't need to be this complicated.

But at least we can now receive and process result sets from a stored procedure in an RPG program. It was always incongruous that we could create the stored procedures that produced the result sets in RPG, but could not actually use those same stored procedures from an RPG program if we chose to.

Note that once you associate the result set locator and allocate the result set to a cursor, you can then simply fetch from that cursor as if it were a “normal” SQL cursor.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 10 of 45

Page 11: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Relaxed Prototype RequirementsPrior to 7.1, the compiler requires a Prototype when: • A subprocedure is compiled (even if called from a separate module) • A subprocedure is called (even if the subprocedure is in same module)

In 7.1+, Prototypes are optional in some specific cases • If the program or procedure is not called by another RPG module

✦ i.e. If not called from RPG, then the prototype will never be used

• Examples of optional prototypes include: ✦ A program that is only intended to be used as an exit program or as the command-

processing program for a command ✦ A program that is only intended to be called from a different (non-RPG) language ✦ A procedure that is not exported from the module (not callable externally) ✦ A procedure that is exported from the module but only intended to be called from a

different programming language

• In other words, if the compiler can get the parameter list from a PI in the same source member, the PR is optional

However, if you put the PR and the PI in the same source member, the compiler will validate the PR to ensure it is correct - Bonus!

NotesThe RPG compiler required prior to V7.1 that you have a PR in every source member where a PI for that procedure or program existed. The reason for this requirement was so that the compiler could validate that your PR was correct - i.e., that it matched your PI. This is good because if the PR matches, then all calls to that program or procedure will be validated by the compiler and parameter mismatches will be a thing of the past.

However, it was a bit painful that we had to put PRs in for cases where the PR would never be used by another RPGLE program - it was only called by CL or some other language that couldn’t use our prototype - likewise for internal subprocedures since the compiler could clearly get the parameter information directly from the PI, making the PR seem redundant.

You should still include the prototypes in any source members where external subprocedures are coded so that the compiler can check them for you. Use /Copy members for that purpose so that you can be sure that the version that was validated when compiling the subprocedures is the same one used by all the callers of those routines.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 11 of 45

Page 12: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

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');

New RTNPARM Prototype KeywordPerformance Boost for large return values • Converts the return value to a hidden parameter • Value reported by %PARMS( ) reflects the extra parameter

✦ But it will otherwise be "invisible" to RPG callers ✦ If calling from another language you will see the return value as the 1st parm

• Will improve performance when returning large values ✦ Especially very large varying values

Has a second unintended use • It allows subprocs with return values to be used by Java or stored

procedure ✦ Prior to this change you were limited to a 4 byte integer (10i)

D OptionalTest PI D Parm1 20A D Optional2 5P 0 Options(*NoPass)

D Parm2 S 5P 0 Inz(99999) // Check for optional parameter and use value if present If %ParmNum(Optional2) <= %Parms; Parm2 = Optional2; EndIf; If Parm2 .............

Better Support for Optional ParametersIn the past, checked %Parms for a hard-coded value • i.e., If %Parms > 1;

Now use %ParmNum( ) • Replaces hard-coded value for parm position • %ParmNum returns the sequence of the parameter in the parm list

In example below, %ParmNum(Optional2) returns 2 • i.e., Optional2 is the 2nd parameter declared in the PI

© Partner400, 2017 What's New in RPG Lecture Notes: Page 12 of 45

Page 13: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

V7 - TR7 Free Form EnhancementsEntire program can now be in free form - except I and O specs

§ No longer any need for /Free or /End-Free - Just leave columns 6 and 7 blank

New free form options for: § H-specs (CTL-OPT) § F-specs (DCL-F) § D-specs (DCL-xx)

- Where xx = C, DS, PARM**, PI, PR, S, or SUBF** • ** These are rarely going to be used

§ P-specs (DCL-PROC)

ctl-opt option(*srcstmt) dftactgrp(*No); dcl-ds employeeDS; firstName char(16) Inz('James'); lastname char(30) Inz('Joyce'); salary packed(7:2) Inz(12500); end-ds;

// Define printer file and associated DS dcl-f qprint printer(80); dcl-ds prtDs len(80) end-ds;

Not Technically a part of TR7 but was announced and released at

the same time

Completely free form logic brings RPG more in line with other modern programming languages, all of which use free format. This is important for attracting new developers coming into the marketplace.

Traditional fixed format RPG is far less attractive and gives RPG the undeserved appearance of an old-fashioned language not up to modern application tasks. RPG is a powerful and flexible language that many young developers come to prefer over other more popular language options for business applications.

But they must first be attracted to learn the language.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 13 of 45

Page 14: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

ctl-opt option(*srcstmt) dftactgrp(*No); dcl-ds employeeDS; firstName char(16) Inz('James'); lastname char(30) Inz('Joyce'); salary packed(7:2) Inz(12500); end-ds; dcl-f qprint printer(80);

dcl-ds prtDs len(80) end-ds;

....

Format of the new DeclarationsAll of the new declaration op-codes follow this basic format:

§ First the DCL-xx itself § Next the name of the item

- File, field, procedure, etc.

§ Followed by keywords related to other fixed form elements - e.g. File usage, field type and length

§ Then keywords from the old spec We will be looking at a more complete code sample on the

next chart

Fixed column entries

From original D-spec keyword area

end-ds can be on the same line as dcl-ds in this case.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 14 of 45

Page 15: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

ctl-opt option(*srcstmt) dftactgrp(*No); dcl-ds employeeDS; // Nice to be able to have comments here! firstName char(16) Inz('James'); lastname char(30) Inz('Joyce'); salary packed(7:2) Inz(12500); end-ds;

// Define printer file and associated DS dcl-f qprint printer(80); // This printer is program described dcl-ds prtDs len(80) end-ds;

dsply ('Hello to our new employee'); dsply ( %TrimR(firstName) + ' ' + lastName );

prtDs = 'The name of our new employee is ' + %TrimR(firstName) + ' ' + %TrimR(lastName) + ' his salary is $' + %Char(salary); write qprint prtds;

Simple Free Form ProgramFile definitions can be intermixed with data definitions

§ Named Constants, Data Structures, etc. Most new options have sensible defaults

§ Disk files default to input, Printers to output, Decimals to zero, etc. etc. End of line comments are now useful in definitions!

Note that the Printer is defined together with the DS that it uses for output

The idea of mixing file and data definitions will take some getting used to - but it makes sense.

After all it makes far more sense to define a set of variables, data structures and constants together with the file that they will be used with that to arbitrarily separate them as we had to before.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 15 of 45

Page 16: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

CTL-OPT - The New H-SpecDefaults to DftActGrp(*No) if any ILE specific options are used

§ i.e. ACTGRP, BNDDIR, or STGMDL - This is the first of many "sensible" defaults that are added by this support

Only other differences are: § Can start in any column from 8 onwards § Must be terminated with a semi-colon § Presence of CTL-OPT stops compiler from looking for H spec data area

No other differences between this and the current H-spec § Can occupy multiple lines § Multiple CTL-OPT can appear in program

H BndDir('UTILBNDDIR') Option(*SRCSTMT: *NODEBUGIO)

Ctl-Opt BndDir('UTILBNDDIR'); Ctl-Opt Option(*SRCSTMT: *NODEBUGIO);

// Can also be coded as:

Ctl-Opt BndDir('UTILBNDDIR') Option(*SRCSTMT: *NODEBUGIO);

Not that much has changed about the H spec since it was almost free format before.

Ctl-Opt replaces the H and the semi-colon is used at the end.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 16 of 45

Page 17: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

FCUSTMR0 UF A E K DISK USROPN

FREPORT O E PRINTER OFLIND(*IN96)

FSCREEN CF E WORKSTN

Dcl-F CUSTMR0 DISK Usage(*Update:*Delete:*Output) Keyed UsrOpn;

Dcl-F REPORT PRINTER(*EXT) OFLIND(*IN96);

Dcl-F SCREEN WORKSTN Usage(*Input:*Output);

Declaring Files In Free-FormFile Name listed first - followed by device type keyword (if any)

§ Device type defaults to DISK - i.e., a Database table Externally described is the default

§ File Keyword *EXT can optionally be specified as a parameter Program described files must specify their record length

§ e.g. PRINTER(132) for a program described printer file Defaults for USAGE are based on device type - more in a moment

§ *Input, *Output, *Update (implies *Input), *Delete (implies *Update) Add KEYED keyword for keyed database (disk) files

In the example here, we have defined 3 files - one is a keyed database table (aka file), a report, and an interactive screen.

This example does specify some features that are not required. For example, PRINTER(*EXT) defining an externally described printer did not need the *EXT parameter since externally defined is always the default. Also the USAGE(*Input:*Output) on the Screen file is the default usage value for a display file and could have been omitted. Note that Usage(*Output) is implied by default for the Report file.

The OFLIND keyword on the Report file is “Overflow Indicator” which can be used by the program to determine when to go to a new page on the report.

There are other keywords that can be used when declaring files. These are the most commonly used features of file declarations.

The File name is no longer limited to 10 characters as it was on the F spec. However, since file object names (externally on the system) are limited to 10 characters, that means if a longer name is used, then keyword ExtDesc must be coded to give the real external name for the file. A longer, more meaningful name for the file may be useful for making the logic more readable.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 17 of 45

Page 18: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

DCL-F - Helpful DefaultsFile name no longer limited to 10 characters

§ So meaningful file names can be used - EXTDESC is used to specify actual name when different from file name

Device type comes next followed by optional parameters § Device type can be omitted if using an externally described Disk file

- A sensible default

All defaults are based on device type § Usage(*Input) for DISK § Usage(*Output) for PRINTER § Usage(*Input : *Output) for WORKSTN

DCL-F InvoiceMaster ExtDesc('INVMAST'); // Defaults to Input Disk

DCL-F CustMaster Usage(*Update) Keyed; // Keyed Disk file

DCL-F qPrint Printer(132) OflInd(PageFull); // Program described

DCL-F MyDisplay WorkStn; // Workstation Usage(*Input : *Output)

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 18 of 45

Page 19: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D Address DS Dim(20) Qualified D Street1 30A D City 30 D State 2 D Zip 5S 0 D ZipPlus 4S 0 dcl-ds Address Dim(20) Qualified; Street1 char(30); City char(30); State char(2); Zip zoned(5); // Zero decimals assumed ZipPlus zoned(4:0); end-ds Address;

DCL-xx - The New D-Specxx = DS for Data structures

§ In most cases there must also be a matching END-DS xx = SUBF for DS subfields - Very Rarely Required

§ Code only if field name is a valid free-form op-code - Yes some strange people do use names like READ or SELECT as field names

xx = S for Stand-Alone fields xx = C for Named Constants

DS Name optional at end Must match DS name

END-DS may be omitted if DS is externally described or has no named subfields. It can even be on the same line as the DCL-DS in such cases, such as the following DS which is externally described based on a table (aka file) named PRODUCT.

dcl-ds product Ext end-ds;

Name of DS can be specified on end-ds and must match if present.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 19 of 45

Page 20: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

DCL-xx - The New D-Spec - Data TypesData types are spelled out instead of using a one character code

§ Chart below shows the most commonly used types § Length or format of item follows in parentheses when required

Simpler definition for some data types § VarChar avoids the need for the Varying keyword § Date, Time, Timestamp don't need separate DatFmt keyword § 0 (zero) decimals assumed for all numeric data types if not specified.

Data Type Free Keyword NotesA Char(len)A + Varying

Varchar(len)I Int(len) Decimals not specifiedU Uns(len) Decimals not specifiedP Packed(len:dec) 0 assumed if decimals not givenS Zoned (len:dec) 0 assumed if decimals not givenN IndD + DatFmt

Date(format)B BinDec

(len:dec)!! DO NOT USE !!

The following is a partial list of RPG data types represented as D-specs:

d packedNum s 7p 2

d zonedNum s 7s 2

d integer s 10i 0

d unsigned s 10u 0

d float s 8f

d character s 20a

d varyingChar s 20a Varying

d dateMDY s d DatFmt(*MDY)

d timeUSA s t TimFmt(*USA)

d indicator s n

d nastybinary s 9b 0

And here are their free form equivalents.

Dcl-S packedNum Packed(7:2);

Dcl-S zonedNum Zoned(7:2);

Dcl-S integer Int(10);

Dcl-S unsigned Uns(10);

Dcl-S float Float(8);

Dcl-S character Char(20);

Dcl-S varyingChar Varchar(20);

Dcl-S dateMDY Date(*MDY);

Dcl-S timeUSA Time(*USA);

Dcl-S indicator Ind;

Dcl-S nastybinary Bindec(9);

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 20 of 45

Page 21: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D MyDS DS D Address 32A D Street 15A Overlay(Address) D City 10A Overlay(Address: *Next) D State 2A Overlay(Address: *Next) D Zip 5A Overlay(Address: *Next) D LstOrdDate D DatFmt(*USA) D ASubfield 25A Varying

Dcl-DS MyDs; Address Char(32); Street Char(15) Overlay(Address); City Char(10) Overlay(Address:16); State Char(2) Overlay(Address:26); Zip Char(5) Overlay(Address:28); LstOrdDate Date(*USA); ASubfield Varchar(25); End-DS;

D-Spec DS ExampleThis shows how a fixed form DS would be converted to free-form • I have used my own personal preferences for alignment

✦ At least they were my preferences at the time I coded this example!

I like the idea of aligning the field type definitions even though it is not required. I don't however insist on placing them in a specific column. Rather I start them 2 characters after the end of the longest field name in the block. For me it works but you'll devise your own style - just be consistent and remember that readability is critical.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 21 of 45

Page 22: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

dcl-ds Customers Qualified; RecordCount Packed(3);

dcl-ds Customer Dim(99); // <<== Nested in Customers DS type Char(10); Contact Char(32); Company Char(32); discountCode Char(1);

dcl-ds Address; // <<== Nested in Customer DS Street Char(32); City Char(20); State Char(20); Zip Zoned(5); end-ds;

end-ds;

end-ds;

Latest DS Enhancement (V7.2 & V7.3)

RPG now allows you to directly code nested data structures • Much easier to create nested DS

✦ See the Notes page for the old fixed form version This is a huge improvement - And proof that RFEs work!

This field is:

Customers.Customer(i).Address.Zip

NotesThe latest updates to RPG are a huge help in defining data structures for use with XML-INTO as the new syntax supports the direct coding of nested structures as you can see on this chart.

Why do I say that it is "... proof that RFEs work!" ? Because I wrote the Request For Enhancement (RFE) that resulted in this change! This is how the same DS had to be coded prior to this latest update.

Dcl-Ds customers Qualified; recordCount Packed(3); customer LikeDS(customer_T) Dim(99); End-Ds;

Dcl-Ds customer_T Qualified Template; type Char(10); company Char(32); discountCode Char(1); address LikeDS(address_T); End-Ds;

Dcl-Ds address_T Template; street Char(32); city Char(24); state Char(2); zip Zoned(5); End-Ds;

© Partner400, 2017 What's New in RPG Lecture Notes: Page 22 of 45

Page 23: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Dcl-DS DayData; *n Char(9) inz('Monday'); *n Char(9) inz('Tuesday'); *n Char(9) inz('Wednesday'); *n Char(9) inz('Thursday'); *n Char(9) inz('Friday'); *n Char(9) inz('Saturday'); *n Char(9) inz('Sunday');

DayArray Char(9) Dim(7) Pos(1);

End-ds;

D-Spec - Unnamed Fields and OverlaysIn fixed form no field name was required • In free-form we must specifically inform the compiler

✦ Done by coding *N instead of a field name

In free-form we are not permitted to OVERLAY the DS name • IBM decided that it should never have been allowed so they stopped it • So we must use POS(1) instead

✦ POS(nn) can also be used for positioning any field within a DS ✦ For example when specifying specific fields in the PSDS

The RPG compiler team decided that too many people got confused when the OVERLAY keyword was used against the DS name. To help avoid this confusion, OVERLAY is now limited to subfields within the DS and you must use the POS keyword to reference the DS starting position.

This is effectively the same as using a start position on the old D-specs.

This is what the DS would have looked like in fixed-form.

D DayData DS D 9 Inz('Monday') D 9 Inz('Tuesday') D 9 Inz('Wednesday') D 9 Inz('Thursday') D 9 Inz('Friday') D 9 Inz('Saturday') D 9 Inz('Sunday')

D DayArray 9 Overlay(DayData) Dim(7)

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 23 of 45

Page 24: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D DateMDY S D DatFmt(*MDY-)

D array S 10a dim(10)

D CustomerInfo DS D CustomerName 50A Varying D CustomerBalance... D 7P 2

dcl-s DateMDY Date(*MDY-);

dcl-S array Char(10) Dim(10);

dcl-c Digits 7; dcl-c Decimals 2;

dcl-ds CustomerInfo; CustomerName VarChar(50); CustomerBalance Packed( Digits: Decimals); end-ds;

More on Data DefinitionConstants can be used in many more places • Including field length, decimal places, array dimensions - just about

anywhere you would use a literal Long names don’t require ellipsis … and a continuation line

Constants can be used for length definition. Makes it really easy to change all currency fields from say 7,2 to 9,2 !!!

Note that in the fixed format example here, it made no sense to define Digits and Decimals as constants since they could not be used to define the length and precision in fixed format D specs. However, in the new free format D specs, they can be used - as illustrated in the 2nd example.

Note that not only are the ellipsis not required for longer variable names - they are not allowed in most cases. Unless the actual variable name is continued on the next line, ellipsis should not be used, even if the data type and other related keywords are on the next line. If ellipsis are found, the compiler assumes the next line will contain part of the variable name.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 24 of 45

Page 25: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

D myDataArea ds DtaAra(JonsData) D lastRunDate d DatFmt(*USA) D lastSeqNum 5i 0 D lastInvNum 7p 0

Dcl-Ds myDataArea DtaAra(JonsData); // Wrong unless // JonsData is a constant

Dcl-Ds myDataArea DtaAra('JONSDATA'); lastRunDate Date(*USA); lastSeqNum Int(5); lastInvNum Packed(7); End-Ds;

Data Areas This is an area where you may trip up • D specs only allowed literals - constants were not allowed

✦ So quotation marks were not compulsory

• Now you will probably get a compiler error if you forget the quotes ✦ It will be looking for a constant named JonsData

• And of course you must specify the name all in upper case

This is one of a number of similar areas where previously the compiler only allowed a literal - so even if quotes were not used the compiler just assumed them and was quite happy.

This new support though allows for far more widespread use of constants and subsequently where literals are used they must _be_ literals - complete with quotes and the data in the right case.

With great power comes ...

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 25 of 45

Page 26: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Subprocedures, Prototypes and More

dcl-proc DayOfWeek Export;

dcl-pi *N Int(3) ExtProc(*DclCase); // Omit name - use *N placeholder InputDate Date(*USA) Value; end-pi;

dcl-s DayNumber int(3); // Do calcs leaving value in DayNumber Return DayNumber;

end-proc DayOfWeek;

DCL-PROC declares a subprocedure • Completed by an END-PROC

DCL-PI and DCL-PR define procedure interfaces and prototypes • Placeholder *N can be used if you don't want to type the name again • DCL-PARM is the optional equivalent of DCL-SUBF within PIs and PRs

✦ Only needed if name of parameter is the same as an RPG op-code

New option for EXTPROC - *DCLCASE • Means the real name is exactly the same as the procedure or prototype name

✦ Avoids having to retype the name when using mixed case procedure names

The biggest advantage of the new support is that you no longer have to flip in and out of fixed and free modes when coding subprocedures. No more /End-Free, P-specs, D-Specs, /Free, logic, /End-Free etc. It makes it all look much cleaner and removes a major source of mistakes (and frustration) for those learning RPG.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 26 of 45

Page 27: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Subprocedures, Prototypes and More

dcl-pr MyProgram; // Used to call 'MYPROGRAM' from non-ILE program

dcl-pr MyProgram ExtPgm; // Calls 'MYPROGRAM' from any program

dcl-pr DifferentName Extpgm('MYPROGRAM'); // Call 'MYPROGRAM using the // name DifferentName

EXTPGM keyword can be omitted • Providing that the program is non-ILE i.e. DFTACTGRP(*YES)

Program name can be omitted from EXTPGM • If the program name is the same as the prototype

EXTPGM('PROGNAME') • Parameter only needed when proto name is different from actual program

name

Once again the new support adds some sensible and useful defaults.

The more I use this stuff the more I love it!

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 27 of 45

Page 28: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Converting to Fully Free FormIBM does NOT supply a tool to do this

§ Even RDi's free-form converter has not been updated

Currently we know of three tools that are available § Linoma's RPG Toolbox (linomasoftware.com/products/rpgtoolbox)

- Which also does a great job of converting old-style fixed-form to free form - More in a moment

§ Arcad Transformer (arcadsoftware.com) - A far more all-embracing modernization tool - but more expensive

• Details at arcadsoftware.com/products/arcad-transformer-ibm-i-refactoring-tools/ - It can even refactor code to the extent of getting rid of GOTOs and other similar

ancient constructs.

§ Craig Rutledge's Free Tools (www.jcrcmds.com) - An addition to Craig's previous free-form conversion tools - Complete H, F and D spec conversion

We have been using Linoma's conversion tool since way back in the V3 days when RPG IV was first introduced. Over the years they have steadily added more and more functionality including the ability to apply "aggressive" conversion options that deal with converting various flavours of MOVE operations.

With the latest updates they also introduced a low-cost add on to the toolbox that works as a plug-in to RDi and does a great job of converting whole prong ams or just selected pieces.

Another nice feature, not related to free-form, is an indenting option that re-establishes correct indentation after you have changed the structure of an If, For, Dox, etc. block.

Arcad's tooling is more recent but much more all encompassing. I like what I have seen of it but have not had any long-term experience with the tool.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 28 of 45

Page 29: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Linoma's RPG ToolBox - Side By Side Comparison

Linoma's tool does a great job but ... § It tends to play it safe and includes a lot of extra keywords § I'm also not a fan of the way it aligns things - it doesn't!

- But they are looking at changing this and providing more formatting options

BeforeAfter

My biggest grouse with the Linoma tool is that it converts everything and that means it also adds a bunch of file declaration keywords that are not necessary. The first thing I do after running a conversion with the tool is to manually clean it up.

Their conversion of D-specs does not apply any alignment to the resulting code - just inserts a single blank between the components. For me the result looks messy so again I apply some manual clean up after conversion. An example on the next chart.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 29 of 45

Page 30: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Edited Version of Converted CodeI removed the superfluous file entries and applied my own alignment

style to the data declarations.

Here you can see that I have removed the superfluous keywords from the file declaration. I have also added some alignment to the data declarations.

Right now my basic alignment rule is that in any given group (i.e. DS, PR, PI, series of standalone fields, etc.) I insert two spaces between the longest data name in the group and its data type/length definition and then align all other entries in the group to that. You can see the effect in the chart.

Note that I don't try and make all the entries in all the groups align - that is just too much work and I don't find it necessary - but visually I do like the entries in a specific group to align.

Choose your own style - but try to make sure that everyone in the shop uses the same (or very similar) style.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 30 of 45

Page 31: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Time to Update Your EditorThis is what free-form coding looks like in SEU

§ IBM will NOT be enhancing SEU to handle these new definitions Time you moved up to a real editor - RDi

IBM has confirmed that SEU will not be updated to support this new functionality. In fact it was frozen as at V6 and supports none of the V7 functionality.

As a result a great many people have started doing what they should have done many years ago and moved their development to RDi. It fully supports the new free-form including excellent code-assist to help you remember the new formats.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 31 of 45

Page 32: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

"Gotchas" to Watch Out ForOVERLAY keyword cannot be used against DS name

§ Use POS(n) instead Names in EXTNAME, EXTFLD, and DTAARA

§ Must be in quotes and are case sensitive § Without quotes, they are treated as a variable or constant name

Ellipsis (...) for continuation only allowed when continuing a name § But not really needed anymore anyway

On F-Spec "U" enables update and delete § In free form *DELETE must be requested explicitly

End-DS, End-PR, End-PI are always required § But may appear on same line as DCL-xx in some cases

RDi's "Convert all to Free-Form" means only convert "all logic" § And will still generate /Free and /End-Free

I and O specs remain in fixed form § Probably forever

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 32 of 45

Page 33: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

The High PointsIntelligent defaults

§ For device type (Defaults to DISK) § Usage (Default based on device type) § Decimal places (Defaults to zero)

Constants can be used as keyword values § Including for lengths and decimal places

DFTACTGRP(*NO) is optional § If any other ILE keyword such as ACTGRP or BNDDIR is used

File and data declarations can be mixed § Even in fixed form

/Free and /End-Free no longer required

/Copy and other compiler directives no longer need to start in col 7

// style end of line comments can be used in data/file declarations

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 33 of 45

Page 34: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

V7.3 UpdatesNew Op-code • %SCANR (Scan reverse)

Works the same way as %SCAN • Except backwards!

✦ %SCANR(search argument : source string { : start position } { : length } )

• Start position specifies the beginning of the substring to be searched ✦ Assumed to be position 1 if not specified

• Length effectively defines a substring (i.e. from start for length) • %SCANR starts at the end of the (sub)string and searches backwards

until it finds a match or it reaches the start position The Length parameter was also added to %Scan

✦ %SCAN(search argument : source string { : start position { : length } } )

• Specifies the maximum length to search within the source string

IBM's Barbara Morris has supplied a number of examples of how to use this support - for example in the code below the file name is extracted from the full path name.

path = '/home/mydir/other/whatever/a.txt'; lastSlash = %SCANR('/' : path); if lastSlash = 0;

fileName = path; else; fileName = %subst(path : lastSlash + 1);

endif;

lastSlash = 27

fileName = 'a.txt'

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 34 of 45

Page 35: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

V7.3 Raised Parameter LimitsIncreased number of parameters for a bound call • i.e. CALLB or Subprocedure calls

Previous maximum was 399

New maximum is 16,382

I have never used even close to 399 so I find it hard to get excited • I'm sure IBM had a reason but I have no clue what it was

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 35 of 45

Page 36: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Read CustMaster;

If %nullInd( orderDate ); // Customer has never placed an order

V 7.3 Improved Null Indicator SupportSQL defined tables are appearing more frequently in our shops • And they commonly makes use of null capable fields

Specifying ALWNULL(*USRCTL) lets you handle null values in your code • As of V 7.3 that is now the default

A null value indicates the absence of data • Rather than the way we have done it in the past by using special values

✦ e.g. A zero in a "date" field indicated that there was no date. Zeros in the "last order number" indicated a new customer who had yet to place an order

• You should always test for null - the field value could be anything! When a null capable record is read the null indicators are also read • Prior to V 7.3 their value could only be tested using %NullInd (fieldName)

In addition to testing if the null flag is set before using a field's value, the programmer is also responsible for setting the null flag for any records being added to the database or if a value is being updated that was previously null.

For example when a customer places an order you might have logic like this:

orderDate = %date();

%nullind(orderDate) = *off; // set null flag off to indicate valid data

update custRec;

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 36 of 45

Page 37: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

dcl-s aNullCapableField nullind; // %NullInd must be use to test

dcl-s orderDate_is_null ind; dcl-s orderDate date nullind(orderDate_is_null);

If orderDate_is_null; // Customer has never placed an order

V 7.3 Better Null Indicator SupportNULLIND keyword associates an indicator with a field • In the example below orderDate_is_null is associated with field orderDate

Makes the testing of nullness much more obvious • For example instead of coding:

✦ If %nullInd (orderDate);

• I can now code: ✦ If orderDate_is_null;

• Much cleaner and simpler You can now define null capable fields within your program • Not just by bringing in external definitions

Being able to define your own null capable fields is a useful feature. Instead of having to use special values for a field you can now directly associate a flag with the field to indicate that there is no value.

For example - there may be a logical difference between a total being zero and there having been no values to add to the total. Prior to this support you would have had to have had a separate flag field to differentiate the two conditions - now you can specify that the field is null capable.

You can specify NULLIND by itself - in which case %NullInd( ... ) must be used to test the status. Or you can associate an indicator with the field as shown in the example.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 37 of 45

Page 38: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

dcl-ds custData likerec(custRec) nullind(custData_null); dcl-ds custData_null likerec(custRec : *null );

read custMaster custData;

if custData_null.lastOrder; // Customer has never ordered

V7.3 Enhancement to LikeDS for NullsNULLIND can also be used with Data Structures

LIKEREC ( recordName : *NULL ) • Defines a DS of null indicators for null capable fields in the record • Subfields have the same names as the corresponding fields

Also applies to EXTNAME • EXTNAME(file:*NULL)

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 38 of 45

Page 39: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

V7.3 New ON-EXIT SupportA great addition to the language for all those "clean up" tasks • For example when a subprocedure blows up with an error

Typical Clean-up Uses • Ensure that files are closed • Release any dynamic storage that you have allocated • Delete partial IFS files • Clean up spool files • Ensure that error is logged

Any code in the ON-EXIT section will always be executed • Whether the routine ends normally (i.e. with a RETURN operation) • Or because of an error (e.g. an uncaught divide by zero)

Full details can be found in the latest RPG IV Reference manual or in the RPG Cafe at:

ibm.biz/RPG_ON_EXIT_Section

These are the PTFs required to implement this support:

Release 7.2:

SI62949: RPG runtime

SI62955: TGTRLS(*CURRENT) compiler

Or, get DB2 PTF group SF99702 Level 14. These PTFs are part of that group PTF.

Release 7.3:

SI62950: RPG runtime

SI62957: TGTRLS(*CURRENT) compiler

SI62965: TGTRLS(*PRV) compiler

Or, get DB2 PTF group SF99703 Level 3. These PTFs are part of that group PTF.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 39 of 45

Page 40: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

V7.3 New ON-EXIT SupportAn optional Indicator variable can be specified • It will be set to true (*On) if the exit was due to an error • If the exit was normal then it will be false (*Off)

Must be coded at the end of the procedure • Cannot be used in the main line logic of a "Cycle Main" procedure

✦ i.e. A conventional RPG program that does not include the NOMAIN keyword

A RETURN operation can be included if required • This allows you to ensure that a return value is supplied

✦ Perhaps to indicate the error as shown in the following example

• Or even to override the value currently set to be returned ✦ Although I am not yet sure why I would want to do that

The exit type indicator on the operation is useful because it enables you to determine if the procedure is returning normally or because of an error. By testing it you can, for example, ensure that an appropriate value is returned from the procedure.

This support helps to round out the error handling built into RPG IV - there really is no reason any longer for any program to simply die with the green-screen-of-death when it is so easy to monitor and control errors.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 40 of 45

Page 41: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

dcl-proc AveragePrice1; dcl-pi AveragePrice1 packed(5:2); itemPrice packed(5:2) Dim(40); itemCount int(5); End-Pi;

dcl-s totalPrice packed(9:2) Inz; dcl-s averagePrice packed(5:2); dcl-s i int(3) Inz;

For i = 1 to itemCount; totalPrice += itemPrice(i); EndFor;

Monitor; averagePrice = totalPrice / itemCount;

On-Error; Return -1; // Return "impossible" average to indicate error

EndMon;

// No error triggered so return average price Return averagePrice;

Error Handling With MONITORMONITOR can be used to trap errors • But it can't trap all abnormal terminations

NotesThis example shows how a subprocedure can make use of the MONITOR operation to handle things like divide by zero. Since that is the primary intent of this particular error handling routine I would normally have coded it to monitor specifically for divide by zero but in this example just took the easy way out and had it trap for all errors.

But what if the addition of the prices to the totalPrice variable had exceeded it's capacity. Right now that can't happen because there are only 40 prices, and the total has a capacity 100 times larger than any individual price. But suppose that at some point in the future that somebody changes the procedure to accept 100 or 200 prices? Certainly it could occur then.

I've always been a fan of bullet proofing my code as much as possible, and this new support really helps in that regard. You'll see how it can be applied to this potential situation on the next chart.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 41 of 45

Page 42: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

dcl-proc AveragePrice2; dcl-pi AveragePrice2 packed(5:2); itemPrice packed(5:2) Dim(40); itemCount int(5); End-Pi;

dcl-s errorExit ind; dcl-s totalPrice packed(9:2) Inz; dcl-s averagePrice packed(5:2); dcl-s i int(3) Inz;

For i = 1 to itemCount; totalPrice += itemPrice(i); EndFor;

averagePrice = totalPrice / itemCount;

return averagePrice;

on-exit errorExit; If errorExit; // Problem reporting logic return -1'; // Return "impossible" average to indicate error

An Alternative Approach Using ON-EXIT

This will achieve the same results and handle ALL errors • Even those caused by external job termination

NotesNot only does this example handle the problem with the totalPrice variable overflowing, it will also capture any and all errors that occur during the running of the procedure no matter what the cause.

I'm not suggesting that ON-ERROR replaces the need for MONITOR - but it is a very useful addition as a "catch all" defence mechanism.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 42 of 45

Page 43: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Dcl-S Q1_Sales Packed(9:2); Dcl-S Q2_Sales Packed(9:2); Dcl-S Q3_Sales Packed(9:2); Dcl-S Q4_Sales Packed(9:2); Dcl-S bestQuarter Packed(9:2); Dcl-S worstQuarter Packed(9:2); Dcl-S array1 Int(4) Dim(20); Dcl-S array2 Int(8) Dim(50); Dcl-S resultArray Int(8) Dim( %Max( %Elem(array1): %Elem(array2)); bestQuarter = %Max( Q1_Sales: Q2_Sales: Q3_Sales: Q4_Sales ); worstQuarter = %Min( Q1_Sales: Q2_Sales: Q3_Sales: Q4_Sales );

Last But Not Least - Two New BIFs

%MAX and %MIN • Return the value of the highest / lowest item in a list

Can also be used in declarations! • e.g. to set the DIM of an array to the size of the largest in a list of arrays

NotesThese are among the latest RPG enhancements. They became available on March 30th via the PTFs listed here:

http://ibm.biz/spring_2017_rpg_enhancements

This release also includes the new nested data structure capabilities that I mentioned earlier.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 43 of 45

Page 44: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Want New Features in RPG ?RPG is now part of the RFE (Request for Enhancements) process. • You can submit requirements • You can vote on requirements that others have requested

Check out the current RFEs for the RPG compiler: ibm.biz/rpg_rfe

When searching or creating you may need to specify: • Brand: ............ Servers and Systems Software • Product family: Power Systems • Product: ......... IBM i • Component:.... Languages - RPG

To vote or submit an RFE you will need to have an IBM Id. • Just register with an email address and away you go !

NotesPlease, please, please participate in the process. Even if you don't have any ideas of your own vote for the ones that others have submitted to help IBM prioritize.

© Partner400, 2017 What's New in RPG Lecture Notes: Page 44 of 45

Page 45: What' New in RPG Including the New Free-Form · PDF fileJon Paris Jon.Paris @ Partner400.com What' New in RPG Including the New Free-Form Definitions. If you thought that RPGIV had

Resources

Articles by Jon Paris and Susan Gantner • Search for them from the IBM Systems Magazine site

✦ www.ibmsystemsmag.com/authors/Susan-Gantner/ ✦ www.ibmsystemsmag.com/authors/Jon-Paris/

Free-Format RPG IV: Third Edition ✦ by Jim Martin ✦ Published by MCPress (www.MC-store.com) ✦ Make sure to order the third edition - older versions do NOT contain the V7 free-form

additions

As noted on the chart - if buying Jim Martin's book make sure you get the third edition or later. The earlier versions do not include the V7 enhancements that we have been discussing in this session.

Notes

© Partner400, 2017 What's New in RPG Lecture Notes: Page 45 of 45