• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Refactoring RPG – Indicators

    July 30, 2018 Ted Holt

    Occasionally I hear someone comment about how terrible indicators are. I don’t think they’re bad. Indicator-laden RPG helped me graduate debt-free with a computer science degree and housed, clothed, and fed my family for several years. I prefer to say that indicators were good for their time, but now we have better programming techniques that I much prefer to use.

    Refactoring code to reduce or even eliminate the use of predefined indicators (not indicator variables) can pay off big in benefits. The fewer indicators a program uses, the easier it tends to be to read, understand, modify, and debug that program. Let’s consider some ways to reduce indicator usage.

    But first, let me clarify some terminology. When I say RPG III, I mean not only the variety that ran on the System/38, but also the native variety commonly called RPG/400. When I say RPG IV, I mean the current version of RPG, which some people habitually call ILE RPG.

    1. Remove unused indicators.

    I hate to mention this, as it seems too obvious, but step number one is to identify and remove indicators that are set but never referenced. This is easily done, as the compiler listing points them out. Here’s a line that could come from an RPG II or RPG III program.

    C                     SETOF                     414243
    

    Here are pieces of the compiler listing.

      Indicator References:
             INDICATOR  REFERENCES (M=MODIFIED D=DEFINED)
             LR         200M
             41         100M 300
     * 7031  42         100M
             43         100M 400
    
    * QRG7031 Severity:  00   Number:    1                                
              Message . . . . :   The Name or indicator is not referenced.
    

    The compiler has flagged the unused 42 indicator with message ID QRG7031.

    1. When you change the setting of an indicator, do something with the indicator right then, not later.

    I heard this somewhere 30 or so years ago when I was working in a System/36 shop, and to quote Robert Frost, that has made all the difference. If you don’t remember anything else from this article, remember this sage bit of advice.

    In this code example, notice the use of indicator 21.

    C**                                             HILOEQ
    C           BALDUE    COMP 250.00               21  21
     . . . many lines omitted . . .
    C   21                EXSR CALCDT             
     . . . many lines omitted . . .
    C   21N22             MOVE 'Y'       LAST    1
     . . . many lines omitted . . .
    O               21                          34 '*'
    

    Indicator 21 calls a subroutine, conditions the assignment of a value to a variable, and prints an asterisk on a report when the balance due field is at least 250 dollars. Many lines, perhaps hundreds or even thousands, of calculations and output specs lie between the place where the indicator was set and the places where it is referenced.

    Here’s a better way:

    C           BALDUE    COMP 250.00               21  21
    C                     MOVE *BLANK    BSTAT   1        
    C   21                MOVE '*'       BSTAT
     . . . many lines omitted . . .
    C           BSTAT     IFEQ '*'
    C                     EXSR CALCDT                     
    C                     END
    . . . many lines omitted . . .
    C           BSTAT     IFEQ '*'
    C     N22             MOVE 'Y'       LAST    1        
    C                     END
    . . . many lines omitted . . .
    O                         BSTAT     34                
    

    The BSTAT variable takes over the function of indicator 21. As soon as the BSTAT variable is assigned a value, indicator 21 becomes irrelevant.

    From there it’s only one short step to removing the indicator entirely.

    C           BALDUE    IFGE 250.00
    C                     MOVE '*'       BSTAT
    C                     ELSE
    C                     MOVE *BLANK    BSTAT
    C                     ENDIF
    

    I used an O spec in this example, but this replacement technique applies equally to externally-described printer files and display files. Not this:

    A          R DETAIL                    SPACEB(1) 
     . . . lines omitted . . .
    A  21                                34'*'
    

    Instead, this:

    A          R DETAIL                    SPACEB(1)              
     . . . lines omitted . . .
    A            BSTAT          1A       34                       
    

    Use of this technique has allowed me to write many programs that used a single numbered indicator for every CHAIN, READ, READP, READE, READPE, READC, LOOKUP, etc.

    1. Convert to RPG IV if possible.

    The Convert RPG Source (CVTRPGSRC) command makes quick work of conversion from RPG III to RPG IV. Since RPG IV is the most powerful of all the RPG family members, it stands to reason that you have more indicator-replacement techniques at your disposal. Consider one of the most heavily-used op codes, the CHAIN operation.

    In RPG II and RPG III, you use a resulting indicator in the “HI” position to indicate a not-found condition.

     ***                                            HILOEQ
    C           VENDOR    CHAINAPVENDOR             75
    C           *IN75     IFEQ *OFF
    

    If you convert this program to RPG IV, you can use the %FOUND built-in function instead of an indicator.

    C     VENDOR        CHAIN     APVENDOR        
    C                   IF        %FOUND(APVENDOR)
    
    1. Sometimes you may have to refactor RPG II or III for a while before conversion to RPG IV becomes worthwhile.

    For instance, I’d prefer to work out a lot of conditioning indicators in RPG II or III, only because RPG IV only has room for one conditioning indicator in a C spec. That is, this:

    C   31 48N17 
    CANN55                MOVE 'X'       FACTR
    

    May be easier to refactor than this:

    C   31       
    CAN 48 
    CANN17 
    CANN55              MOVE      'X'           FACTR
    

    Or maybe not. Refactoring is a process, and there’s no one correct way to refactor a program. Many paths are equally valid.

    1. If you can’t eliminate an indicator, give it a self-documenting name. Instead of this:
    If *In25;
       // Process account charges
    EndIf;
    

    Try this:

    dcl-c validAccount_25      const(25);
    
    If *In(validAccount_25);
       // Process account charges
    EndIf;
    

    I don’t need to discuss this point, as Jon Paris has already covered the topic thoroughly in An Indicator By Any Other Name, from which I blatantly stole this example, and The New Basics: Indicators.

    1. RPG II does not allow you to treat indicators like data, as RPG III and IV do, but you can get close.

    Look at the use of indicator 33 in this code.

    C**                                             HILOEQ
    C           BCUSNO    CHAINCUST                 33
    C   33                MOVE . . .
    C   33                MOVE . . .
    C   33                EXSR SUBREF 
    C   33                MOVE . . .
    C  N33                Z-ADD. . .
    

    If SUBREF does not modify indicator 33, and none of the routines that SUBREF calls modifies indicator 33, and none of the routines that are called from routines that SUBREF calls modifies indicator 33, ad infinitum, then the following is equivalent.

    C**                                             HILOEQ
    C           BCUSNO    CHAINCUST                 33
    C                     MOVE '0'       #IN33   1
    C   33                MOVE '1'       #IN33
    C           #IN33     IFEQ '1'
    C                     MOVE . . .
    C                     MOVE . . .
    C                     EXSR SUBREF
    C                     MOVE . . .
    C                     ELSE
    C                     Z-ADD. . .
    C                     END
    

    While this is not stellar code by modern standards, it’s a step closer to the distant and eventual goal, which to me usually means modern free-form calculation specifications.

    I hope this gives you some techniques you can use to modernize the valuable code that runs your organization. Even more, I hope this article and my other refactoring articles give you hope that there are still many years of useful service in the software upon which the people in your organization depend for their livelihood.

    RELATED STORIES

    RDi and Refactoring

    Refactoring into Routines

    An Indicator By Any Other Name

    The New Basics: Indicators

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, FHG, Four Hundred Guru, Indicator, RPG, RPG II, RPG III, RPG IV

    Sponsored by
    Maxava

    Migrate IBM i with Confidence

    Tired of costly and risky migrations? Maxava Migrate Live minimizes disruption with seamless transitions. Upgrading to Power10 or cloud hosted system, Maxava has you covered!

    Learn More

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Mad Dog 21/21: Sacred Families Syncsort Unveils MFA, Bolsters IBM i Security Suites

    One thought on “Guru: Refactoring RPG – Indicators”

    • Hassan Farooqi says:
      August 8, 2018 at 3:35 pm

      Backward compatibility from hell, the main reason for screwups in RPG. That is why I want a clean version of RPG called RPG7 (or PLi or whatever) that accepts only code starting with **FREE ( minus the **FREE). More importantly, it should come with a free converter that can convert RPGII to **FREE.

      Reply

    Leave a Reply Cancel reply

TFH Volume: 28 Issue: 50

This Issue Sponsored By

  • T.L. Ashford
  • COMMON
  • Rocket Software
  • LUG
  • Manta Technologies

Table of Contents

  • IBM Readies Big Iron With “Cumulus” Power9 Chips
  • Syncsort Unveils MFA, Bolsters IBM i Security Suites
  • Guru: Refactoring RPG – Indicators
  • Mad Dog 21/21: Sacred Families
  • Introducing Four Hundred Guru Classic

Content archive

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

Recent Posts

  • POWERUp 2025 –Your Source For IBM i 7.6 Information
  • Maxava Consulting Services Does More Than HA/DR Project Management – A Lot More
  • Guru: Creating An SQL Stored Procedure That Returns A Result Set
  • As I See It: At Any Cost
  • IBM i PTF Guide, Volume 27, Number 19
  • IBM Unveils Manzan, A New Open Source Event Monitor For IBM i
  • Say Goodbye To Downtime: Update Your Database Without Taking Your Business Offline
  • i-Rays Brings Observability To IBM i Performance Problems
  • Another Non-TR “Technology Refresh” Happens With IBM i TR6
  • IBM i PTF Guide, Volume 27, Number 18

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