• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Data Structure Parameters in RPG Prototypes

    November 15, 2002 Hey, Ted

    Hey, Ted:

    Back in my RPG III (RPG/400) days, it was easy to define an entry parameter as a data structure.

    IPARM1      DS 
    I                                       1   8 ACTION 
    I                                       9  10 CODE   
    I                                      11  120RTNVAL 
    I* 
    C          *ENTRY    PLIST
    C                    PARM           PARM1
    

    I used this same method in RPG IV before I started prototyping entry parameters.

    D Parm1          DS 
    D  Action                1      8  
    D  Code                  9     10  
    D  RtnVal               11     12  0 
    I*  
    C     *entry       plist                        
    C                  parm                    Parm1
    

    Now I prototype entry parameters, as you described in the November 16, 2001 issue of Midrange Guru. Since the D-spec for a parameter must be blank in positions 24-25, and a data structure must have DS in positions 24-25, how can I include a data structure in a prototyped parameter list?

    — Lee

    You can do it, Lee. It just takes a little more work. With the help of Barbara Morris of IBM, I have come up with two methods.

    The first method is the only one I know of that will work on releases prior to V5R1. Besides declaring the prototype and procedure interface, you must define a data structure and a pointer to the data structure, as in the following code for called program DSPARM.

    D DSParm         pr                  extpgm('DSPARM')
    D  Parm1                             like(ParmData)
    D
    D DSParm         pi
    D  Parm1                             like(ParmData)
    D
    D ParmAddr       s               *
    D ParmData       ds                  based(ParmAddr)
    D   Action                      8
    D   Code                        2
    D   RtnVal                      2s 0
    D
    C                  eval      ParmAddr = %addr(Parm1)
    C     action       dsply                 
    C     code         dsply                 
    C     rtnval       dsply                 
    C                  eval      rtnval = 21 
    

    You must set the pointer to the address of the parameter so that manipulating the data structure manipulates the parameter. After the eval runs, anything you do to Action, Code, and RtnVal will take place within Parm1.

    The second method is for V5R1 or later. Use the LIKEDS keyword to define subfields for the parameter. You will have to qualify references to the parameter’s subfields by preceding each subfield name with the parameter name and a period. You no longer need the pointer.

    D ParmData       ds 
    D   Action                      8
    D   Code                        2 
    D   RtnVal                      2s 0
            D                                                       
    D DSParm         pr                  extpgm('DSPARM')
    D  Parm1                             likeds(ParmData)   
    D  
    D DSParm         pi 
    D  Parm1                             likeds(ParmData)   
    D 
    C    Parm1.action  dsply 
    C    Parm1.code    dsply 
    C    Parm1.rtnval  dsply
    C                   eval     Parm1.rtnval = 21          
    

    Data structure ParmData and its three subfields are not equivalent to the parameter. To access the parameter’s data, you must use the qualified subfields.

    If you like to place the prototype in a member of its own, as I do, include the data structure in the prototype so that calling programs also have access to the data structure’s definition. Here’s the copy member that contains the prototype.

    D ParmData       ds  
    D   Action                      8 
    D   Code                        2 
    D   RtnVal                      2s 0
    D   
    D DSParm         pr                  extpgm('DSPARM')
    D  Parm1                             likeds(ParmData) 
    D 
    

    Here’s the called program. It receives the data structure as Parm1 and qualifies the subfields.

    D/include prototypes,dsparm
    D                                                        
    D DSParm         pi 
    D  Parm1                             likeds(ParmData)   
    D 
    C    Parm1.action  dsply 
    C    Parm1.code    dsply 
    C    Parm1.rtnval  dsply 
    C                  eval      Parm1.rtnval = 21
    

    Here’s part of a calling program. MyDS is the data structure that is to be passed to the called program. Notice that all references to the subfields are qualified.

    D/include prototypes,dsparm 
    D 
    D MyDS           ds                  likeds(ParmData)
    D 
    C                  eval      MyDS.Action = 'READNEXT'
    C                  eval      MyDS.Code = '33'
    C                  eval      MyDS.RtnVal = *zero
    C                  callp     DSPARM (MyDS)
    C                  if        MyDS.rtnval = *zero
    

    Data structure ParmData is defined in both the calling and called programs, but is used only as a pattern. The real data is in MyDS in the caller and in Parm1 in the called program.

    In this example, the data structure that is being passed from one program to another is only twelve bytes long. However, if it were much longer, you might want to keep the compiler from allocating storage for the pattern data structure in the copy member. To prevent the allocation of storage, use the BASED keyword.

                                     
    D ParmData       ds                  based(typedefinition_dummy)             
    D   Action                      8  
    D   Code                        2
    D   RtnVal                      2s 0 
    D   
    D DSParm         pr                  extpgm('DSPARM')
    D  Parm1                             likeds(ParmData)
    D 
    

    Data structure ParmData is still defined in both the caller and called programs, but no storage is allocated for ParmData in either.

    The use of the BASED keyword also prevents programmers from using the pattern data structure as a working variable. Instead, programmers must define data structures that are to serve as working variables by using the LIKEDS keyword.

    Everything to this point works fine if there are no identifiers in the calling program that have the same names as those of the data structure subfields. To avoid such collisions, add the QUALIFIED keyword to the data structure definition in the prototype member.

    D ParmData       ds                  based(typedefinition_dummy)
    D                                    qualified 
    D   Action                      8  
    D   Code                        2  
    D   RtnVal                      2s 0 
    D  
    D DSParm         pr                  extpgm('DSPARMQ') 
    D  Parm1                             likeds(ParmData)
    D                                                                
    

    Here’s a calling program that declares a variable named ACTION. Because of the QUALIFIED keyword, this program has no trouble distinguishing between ACTION the standalone variable and ACTION the subfield.

    D/include prototypes,dsparm 
    D                                                        
    D MyDS           ds                  likeds(ParmData)
    D Action         s             24 
    D 
    C                  eval      Action = 'Go getum!'
    C                  eval      MyDS.Action = 'READNEXT'
    C                  eval      MyDS.Code = '33' 
    C                  eval      MyDS.RtnVal = *zero
    C                  callp     DSPARM (MyDS)
    C                  if        MyDS.rtnval <> *zero 
    

    Here’s a final example that Barbara gave me. This example uses two data structures as parameters.

    Here’s the prototype copybook member. The two pattern data structures have names that end with an underscore (_) and a lowercase letter t to remind programmers that these data structures serve as data types, not as real variables with allocated storage.

    D custInfo_t   ds               qualified based(typedummy)
    D  name                  100a   varying
    D  id_no                  10i 0
    D  addr                  100a   varying
    
    D partInfo_t   ds               qualified based(typedummy)
    D  name                  100a   varying
    D  id_no                  10i 0
    D  cost                   15p 3
    
    D buyOne       pr
    D  cust                         likeds(custInfo_t) const
    D  part                         likeds(partInfo_t) const
    D  num                    10i 0 value
    

    A caller of the procedure would use the data structure names as pseudo data types. All references to the subfields would be qualified.

     /copy prototypes,custtrans
    D theCust      ds               likeds(custInfo_t)
    D thePart      ds               likeds(partInfo_t)
    
     /free
          theCust.name = whatever;
          buyOne (theCust : thePart : num);
     /end-free
    

    Prototyping data structure parameters is more complex than the old RPG III method you used. However, I believe that the advantages of prototyping parameters are worth the extra effort.

    — Ted

    Sponsored By
    COMMON

    Get the IT training you need by attending COMMON Users Group’s Spring 2003 IT Education Conference and Expo, March 9 – 13, in Indianapolis.

    Choose from hundreds of sessions and labs covering the widest range of industry topics, including RPG IV, LPAR, WebSphere, and High Availability.

    COMMON is the best value in IT education, so don’t miss out!

    Click and visit www.common.org for details!

     

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 2002, mgo_rc, Number 88 -- November 15, Volume 2

    Sponsored by
    WorksRight Software

    Do you need area code information?
    Do you need ZIP Code information?
    Do you need ZIP+4 information?
    Do you need city name information?
    Do you need county information?
    Do you need a nearest dealer locator system?

    We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

    The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

    PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

    Just call us and we’ll arrange for 30 days FREE use of either ZIP/CITY or PER/ZIP4.

    WorksRight Software, Inc.
    Phone: 601-856-8337
    Fax: 601-856-9432
    Email: software@worksright.com
    Website: www.worksright.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Compiler Directives for RPG Programs and Modules Reader Feedback and Insights: Thanks for Qshell Tips

    One thought on “Data Structure Parameters in RPG Prototypes”

    • OlivierD says:
      May 31, 2022 at 9:09 am

      Hi, how to manage null capable field in a data structure used as parameters?
      Regards,
      Olivier.

      Reply

    Leave a Reply Cancel reply

MGO Volume: 2 Issue: 88

This Issue Sponsored By

    Table of Contents

    • Reader Feedback and Insights: Indicators in RPG II Programs
    • Access the Database from Qshell
    • Data Structure Parameters in RPG Prototypes

    Content archive

    • The Four Hundred
    • Four Hundred Stuff
    • Four Hundred Guru

    Recent Posts

    • Public Preview For Watson Code Assistant for i Available Soon
    • COMMON Youth Movement Continues at POWERUp 2025
    • IBM Preserves Memory Investments Across Power10 And Power11
    • Eradani Uses AI For New EDI And API Service
    • Picking Apart IBM’s $150 Billion In US Manufacturing And R&D
    • FAX/400 And CICS For i Are Dead. What Will IBM Kill Next?
    • Fresche Overhauls X-Analysis With Web UI, AI Smarts
    • Is It Time To Add The Rust Programming Language To IBM i?
    • Is IBM Going To Raise Prices On Power10 Expert Care?
    • IBM i PTF Guide, Volume 27, Number 20

    Subscribe

    To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

    Pages

    • About Us
    • Contact
    • Contributors
    • Four Hundred Monitor
    • IBM i PTF Guide
    • Media Kit
    • Subscribe

    Search

    Copyright © 2025 IT Jungle