24
Wed, Apr
0 New Articles

V6R1 RPG Enhancements

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times
Here are the most important ones, IMHO.

 

Another year and another set of RPG enhancements. As always, the reactions range from "I'm not sure how that applies to me" to "This is downright intriguing."

 

As my teammate Jon Paris mentioned a couple of weeks ago, the IBM documentation we have seen to date seems to be placing a strange emphasis on which enhancements are most pertinent. But in fairness to IBM (now there is a novel thought), I think most of the documentation simply follows the order of RPG specifications. In this article, I will attempt to guide you through the enhancements in the order I think is most pertinent. Feel free to disagree.

Increased Sizes

The maximum amount of storage that can be occupied by a data structure, array, or standalone field is now 16M. Yes, the maximum size of a character field has increased from 64K to 16M (16,773,104 bytes to be exact).

 

This is an enhancement that is long overdue. More and more of our programs should be making use of memory, but we have been restricted by the 64K limit in RPG. This enhancement means that a whole lot of dynamic memory management procedures and pointer/user space procedures are about to disappear. It also means that operations such as XML-INTO are now more functional and less cumbersome to use.

 

 

(1)  D LongFld         S               a   Len(25000000)

(2)  D BigDS           DS              a   Len(60000000)

(3)  D BigArray1       S               a   Len(10000000)

     D                                     Dim(6)

(4)  D BigArray2       S              1a   Dim(50000000)

(5)  D BigVarying      S               a   Len(25000000) Varying(4)

     D DummyPtr        S               *

      /Free

(6)      DummyPtr = %Addr(BigVarying : *Data);

Figure 1: Use the LEN keyword to define a large length.

 

Figure 1 highlights some of the changes in relation to the definition of large variables (refer to the numbers above).

 

1.      Since only seven positions are available to specify the length of a field in the D spec, you use the LEN keyword to specify a length greater than 9,999,999.

2.      The LEN keyword may also be applied to a data structure.

3.      The LEN keyword may also be applied to an array.

4.      Larger variable sizes also mean you can have a larger number of elements in an array as long as the total storage for the array does not exceed 16M. The same applies to multiple-occurrence data structures.

5.      Varying-length fields now require 2 or 4 bytes to store the actual length of the field. A size of 2 is assumed if the specified length is between 1 and 65535; otherwise, a size of 4 is assumed. You can specify either VARYING(2) or VARYING(4) for definitions whose length is between 1 and 65535. For definitions whose length is greater than 65535, VARYING(4) is required.

6.      The %ADDR BIF has also been enhanced. The optional *DATA parameter may be specified so that %ADDR returns the address of the data portion of a variable-length field.

 

UCS-2 and Graphic fields can have a maximum length of 8M.

 

The maximum size of literals has also increased:

 

•        Character literals can now have a length of up to 16380 characters.

•        UCS-2 literals can now have a length of up to 8190 UCS-2 characters.

•        Graphic literals can now have a length of up to 16379 DBCS characters.

 

For those of you who program with different character sets in mind, some of the UCS-2 rules have been relaxed. To make it easier to change the data type of database fields to be UCS-2, the compiler has changed to allow any of the string types to be used in assignment and comparison operations without explicit conversion. The compiler performs any needed conversions implicitly. UCS-2 variables can now be initialized with character or graphic literals without using the %UCS2 built-in function. UCS-2 enhancements are available as PTFs back to V5R3.

 

Not that I'm greedy or anything but when can we have terabyte fields?

Files Defined in Subprocedures

Subprocedures have F-specs. Read that again: subprocedures have F-specs. This means that a file defined in a subprocedure is local to the subprocedure.

 

     P GetName         B

     FCustomer  IP   E           K Disk

     D GetName         PI            50a

     D   CusNo                       10a

     

     D GetCustRec      Ds                  LikeRec(CustomerR)

      /Free

          Chain Cusno Customer GetCustRec;

          Return GetCustRec.CustName;

      /End-free

     P                 E

Figure 2: Here's an example of a file defined in a subprocedure.

 

Figure 2 shows an example of a subprocedure that returns a Customer name. A few points are worth noting:

 

•        Input and output specifications are not generated for local files; therefore, all input and output must be done with result data structures (hence the definition of the GetCustRec data structure in Figure 2).

•        By default, files are automatically opened when the subprocedure is called and automatically closed when the subprocedure ends (either normally or abnormally). Of course, USROPN may be specified for a file so the opening and closing of the file are under your control in the subprocedure.

•        You can change the default opening and closing of the file by specifying the STATIC keyword on the F-spec. This means that the storage associated with the file is static and all invocations of the subprocedure will use the same file. If the file is open when the procedure returns, it will remain open for the next call to the procedure.

Templates

The TEMPLATE keyword allows you to define template data structures, standalone fields, and files.

 

Templates for Data Structures

 

The concept of a template for data structures is not new. Figure 3 shows the traditional way of defining and using a virtual template. The data structure Phone contains the definition of a phone number (complicated things, really); the data structure is based on a pointer (DummyPtr), which is never set, so it does not occupy any storage in the program. The data structures to be used in the program, HomePhone, CellPhone and WorkPhone, are all defined using LIKEDS(PHONE). Any required subfield initialization is performed in the program. The main problem with this method is that you have to initialize the subfields in the calculation code of the program.

 

 

     D Phone           DS                  Based(DummyPtr) Qualified

     D  CountryCode                   5i 0   

     D  NDDPrefix                     5   

     D  AreaCode                      5   

     D  Number                        9   

     D  Extension                     4   

     D  IDDPrefix                     5    

     D HomePhone       DS                  LikeDS(Phone)

     D CellPhone       DS                  LikeDS(Phone)

     D WorkPhone       DS                  LikeDS(Phone)

      /Free

         HomePhone.CountryCode = 353;

         CellPhone.CountryCode = 353;

         WorkPhone.CountryCode = 353;

Figure 3: This virtual template uses BASED and LIKEDS.

 

Figure 4 show the comparable structures (to Figure 3) being defined with the new TEMPLATE keyword. At first glance, they are fairly similar, the major difference being the use of the INT keyword on the DS definition of PHONE and the INZ(353) for the CountryCode subfield in Phone. The use of the INZ keyword with the template data structure means the same initialization may be applied to any dependent data structures (defined using LIKEDS) by specifying INZ(*LIKEDS).

 

 

     D Phone           DS                  Template Inz

     D  CountryCode                   5i 0 Inz(353) 

     D  NDDPrefix                     5  

     D  AreaCode                      5   

     D  Number                        9   

     D  Extension                     4   

     D  IDDPrefix                     5    

     D HomePhone       DS                  LikeDS(Phone)

     D                                     Inz(*LikeDS)

     D CellPhone       DS                  LikeDS(Phone)

     D                                     Inz(*LikeDS)

     D WorkPhone       DS                  LikeDS(Phone)

     D                                     Inz(*LikeDS)

Figure 4: Use the TEMPLATE keyword to define a data structure.

 

The TEMPLATE keyword may also be applied to a standalone field.

 

A definition defined with a TEMPLATE keyword may only be used as a parameter for the LIKE or LIKEDS keywords or the %SIZE, %LEN, %ELEM, or %DECPOS BIFs; it may not be used as a normal data structure or field.

 

Templates for Files

 

The TEMPLATE keyword may be specified for files. Files defined with the TEMPLATE keyword are not included in the program; the file definition is used only at compile time. The template file can only be used as a basis for defining other files later in the program using the new LIKEFILE keyword. The LIKEFILE keyword also allows you to pass a file as a parameter.

 

Let's look at an example:

 

 

(1)  FCustomer  IF   E           K Disk    Template              

     P GetCustomer     B

                    

     D GetCustomer     PI              N

(2)  D  customerFile                       LikeFile(Customer)

(3)  D  customerData                       LikeRec(CustomerR)

     D  customerKey                        Like(customerData.CustNo)

     D                                     Const

             

      /Free

(4)      Chain customerKey customerFile customerData;

         If %Found(customerFile); 

            If customerData.Status <> 'D';                

               Return *On;

            EndIf;

         EndIf;       

         Return *Off;                

      /End-Free

     P                 E

Figure 5: Here's a subprocedure to get a customer record.

 

Figure 5 shows a portion of a member containing a subprocedure (GetCustomer) that retrieves customer data. This member is compiled and placed in a service program. The main points to note are these (refer to the numbers above):

 

1.      The TEMPLATE keyword is specified for the customer file. This means that the File specification is for reference purposes only, and the file definition may not be used for processing.

2.      The LIKEFILE keyword identifies the first parameter as a file with the same characteristics as the Customer file.

3.      The second parameter is the customer record that will be returned by the subprocedure.

4.      The file parameter name is used to identify the file to be processed (i.e., customerFile not Customer). Since Input and Output specs are not generated for a template file or a file identified by LIKEFILE, you must use a result data structure for the CHAIN operation.

 

How do you call the GetCustomer subprocedure? Figure 6 shows a snippet of a program that performs a call. The file to be processed (CustFile) is simply passed as the first parameter. The format of the file CustFile must be the same as the Customer file.

 

     FCustFile  IF   E           K Disk                          

                                                             

     D custData        DS                  LikeRec(CustFileR)

                       

      /Free

         If GetCustomer(CustFile: CustFileR: 'THISCUST');

            // DO cool things with data

         EndIf;    

Figure 6: Call the GetCustomer subprocedure.

 

The LIKEFILE keyword may also be used on the F-specs. Figure 7 shows an example of two files (CurrCust and OldCust) being defined like the Customer file. The processing options (file type, record addition, record address type, device, etc.) and most (but not all) of the keywords are inherited.

 

     FCustomer  IF   E           K Disk    Template Block(*YES)             

     FCurrCust                             LikeFile(Customer)

     F                                     ExtFile('CURRLIB/CUSTFILE')

     FOldCust                              LikeFile(Customer)

     F                                     ExtFile('OLDLIB/CUSTFILE')

Figure 7: Using LIKEFILE on the File Specifications.

 

There are a few items to bear in mind when using LIKEFILE:

 

•       The parent file must be externally defined.

•       Files are implicitly qualified; therefore, resulting data structures are required for input and output operations.

•       The parent file must define any blocking requirements.

•       Not all keywords are inherited. These are keywords that must be unique for each file (e.g., INDDS, INFDS, INFSR, OFLIND).

•        Although the SFILE keyword may be inherited, you still need to define it for dependent files in order to specify a unique RRN field.              

Other File Enhancements

There are a few other file related enhancements worth having a look at.

 

(1)  FCustomer  IP   E           K Disk    ExtDesc('MYLIB/CUSTFILE')

(2)  F                                     ExtFile(*ExtDesc)

(3)  F                                     Qualified

     FScreens   CF   E             WorkStn

     D GetCustRec      Ds                  LikeRec(CustomerR)

(4)  D GetDetails    E Ds                  ExtName('MYLIB/SCREENS' :

     D                                             Screen1 : *ALL)

      /Free

(5)       Read Customer.CustomerR GetCustRec;

          If GetCustRec.Type = 1;

             Eval-Corr GetDetails = GetCustRec;

(6)          ExFmt Screen1 GetDetails;

          EndIf;

Figure 8: Note these other file enhancements.

 

Figure 8 shows some of the other file enhancements introduced in V6R1 (refer to the numbers above).

 

1.      You are aware that the EXTFILE keyword allows you to specify the file to be used when a program is called (a built-in override), but EXTFILE does not have any effect at compile time. The EXTDESC keyword allows you to specify the file definition to be referenced at compile time. This provides a means of handling SQL defined tables (where the file and format name are the same) other than renaming the record format.

2.      The EXTFILE keyword allows a special value of *EXTDESC, which means that the value specified for the EXTDESC keyword should be used by the EXTFILE. Basically, you are specifying the same value for both the EXTDESC (compile time) and EXTFILE (run time) keywords.

3.      The QUALIFIED keyword may be specified for files. This means that all references (except for the RENAME, INCLUDE, IGNORE, and SFILE file keywords) to record format names must be qualified with the file name.

4.      The file name specified on the EXTNAME keyword may be a character literal in any of the forms 'LIBRARY/FILE', 'FILE', or '*LIBL/FILE'.

5.      As with file specifications in subprocedures, Input and Output specifications are not generated for a qualified file (i.e., external fields from the file are not automatically defined as fields in the program and all I/O to the file must be done with result data structures).

6.      A data structure name may be specified as the result for an EXFMT operation. This eases the use of qualified data structures with display files. The *ALL value must be specified on the LIKREC or EXTNAME keyword for the data structure.

No Cycle RPG

If you have delved into the wonderful world of ILE, you are almost certain to have coded a module with the NOMAIN keyword in the control specifications. This means that the module only contains global definitions (F- and D-specs) and subprocedures and that the compiler does not place any RPG cycle code in the module since there is no mainline (a linear module). Since a NOMAIN module does not contain a Program Entry Procedure (PEP), it cannot be compiled as a callable program.

 

The introduction of the MAIN keyword on the control specification allows you to code a module that may be created as a program but does not contain the RPG cycle. The MAIN keyword allows you to specify the name of the subprocedure to be used as the PEP for the program. Figure 9 shows the code in a member named CUST001. The member is compiled using the CRTBNDRPG command. The MAIN keyword identifies the MaintainCustomer subprocedure as the PEP for the program.

 

     H Main(MaintainCustomer)

     D/Copy Prototypes

     P MaintainCustomer...

     P                 B

     D MaintainCustomer...

     D                 PI

      /Free

         // Lots of cool code

      /End-Free

     P                 E

Figure 9: This example shows how to use the MAIN keyword.

 

The other major difference is with the prototype for the subprocedure. Figure 10 shows the prototype (defined in the ProtoTypes member) for the MaintainCustomer subprocedure defined in Figure 9. Although the prototype is for a subprocedure, the EXTPGM keyword is used to identify the program in which the subprocedure is defined.

 

     D MaintainCustomer...

     D                 PR                  ExtPgm('CUST001')

Figure 10: Here's the prototype for a subprocedure identified on the MAIN keyword.

 

The ability to identify the PEP for a program also means that a program may be called recursively. This avails of the already available feature whereby subprocedures can be called recursively.

 

Threads

The threads enhancement is probably of little immediate benefit to most of us but will become increasingly important as RPG programs and subprocedures are remodeled to be used as Web services.

 

RPG can run safely in multiple threads, but each RPG module can be accessed by only one thread at a time. This means that in a services environment, RPG modules could be a potential bottleneck impacting performance and scalability. V6R1 introduces the option of having RPG modules run concurrently in multiple threads.

 

Specifying THREAD(*CONCURRENT) on the Control specification has these results:

 

•        Multiple threads can run in the module at the same time.

•        By default, static variables are defined so that each thread has its own copy of the static variable.

•        Individual variables can be shared by all threads using STATIC(*ALLTHREAD).

•        Specifying SERIALIZE on the Procedure- Begin specification means individual procedures can be serialized so that only one thread can run them at one time.

•        The total amount of static storage is greater because each thread has its own copy of the static storage.

Compile Options

Lastly, here are a couple of options you can take when you are creating modules or programs.

 

•       The OPTION keyword on the CRTBNDRPG and CRTRPGMOD commands (or in the control specification) may specify a value of *UNREF (the default) or *NOUNREF. *NOUNREF indicates that unreferenced variables should not be generated into the RPG module. This can reduce program size and can reduce the time taken to bind a module to a program or service program. This may be particularly useful in a multi-threading environment where static variables are defined for each thread.

•        The PGMINFO keyword on the CRTBNDRPG and CRTRPGMOD commands (or in the control specification) may specify that PCM information is to be stored in a file in the IFS (identified by the INFOSTMF parameter) and/or the module itself. The PCML information becomes part of the program or service program and may be retrieved using the QBNRPII API.

New Ways of Doing Things

Just when I am getting comfortable with the way I am programming, along comes IBM with new and improved ways of doing things. As with all enhancements, some of these will be of immediate use (larger variable sizes, files in subprocedures, templates), some will be of occasional use (passing files as parameters), and others are for the future (concurrent threads).

 

RPG is certainly doing a lot of kicking and screaming for a language that some say is dying. It won't go quietly.

Paul Tuohy

Paul Tuohy has worked in the development of IBM midrange applications since the 1970s. He has been IT manager for Kodak Ireland, Ltd., and technical director of Precision Software, Ltd., and is currently CEO of ComCon, a midrange consultancy company based in Dublin, Ireland. He has been teaching and lecturing since the mid-1980s. 

Paul is the author of Re-engineering RPG Legacy Applications, The Programmer's Guide to iSeries Navigator, and the self-teach course "iSeries Navigator for Programmers." He is one of the partners of System i Developer and, in addition to speaking at the renowned RPG & DB2 Summit, he is an award-winning speaker at COMMON and other conferences throughout the world.


MC Press books written by Paul Tuohy available now on the MC Press Bookstore.

The Programmer’s Guide to iSeries Navigator The Programmer’s Guide to iSeries Navigator
Get to know iSeries Navigator and all the powerful tools and interfaces that will expand your programming horizons.
List Price $74.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: