• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • The New Basics: Indicators

    September 19, 2012 Jon Paris

    The history of indicators pre-dates even the earliest versions of RPG and takes us all the way back to the old tabulating machines, perhaps even earlier depending on how broad a definition one uses. What is without doubt, though, is that indicators in the sense of *INnn and *INLR were introduced to the RPG language as a vehicle for translating those old tabulator board programs.

    RPG has grown a lot since those early days, and yet many people still write code using the old-style numbered indicators. LR? Well, we’re kind of stuck with that, but there hasn’t been a need to use numbered indicators in your RPG programs for a very, very long time. Not since V4R2 in fact, when named indicators were first introduced into the language. Of course, if you use program-described report files, you have little choice but to use the numbered indicators on the O-specs themselves, but in the calculations you do have a choice.

    I covered some indicator basics in a previous article An Indicator By Any Other Name. I strongly suggest you review that article as a refresher. This article picks up where we left off, having established the following points:

    *Indicators can be treated as an array. That is, *In55 and *In(55) reference the same indicator.

    *The compiler understands that an indicator (named or otherwise) is a Boolean and can be tested as such.

    /free
    If *In(55);
    . . .
    Endif
    /end-free
    

    The above code can also be presented this way:

    /free
    If Not *In55;
    . . .
    Endif
    /end-free 
    

    *Named constants can be used as array subscripts allowing names to be associated with indicators. For example, here’s one way to associate indicator 55 with a name: overCreditLimit_55.

    d overCreditLimit_55...
    d                 c                   const(55)
    
    /free 
        if *In(overCreditLimit_55);
    

    * A logical expression can be assigned to an indicator. For example, the following expression sets indicator 55 on or off depending on the true/false result of the test.

    /free
    *In(overCreditLimit_55) =
    ( orderTotal + currentBalance ) > creditLimit;
    

    Now Let’s Take The Next Step

    Indicators *In01 – *In99 are just a set of bytes in memory–consecutive bytes. So if we want to give names to all 99 indicators (or as many of them as we have used), we can do so by mapping the indicator array to a data structure of our own design. The following code demonstrates the basic idea. If pointers make you nervous, don’t worry. When used this way, you’ll never have to do anything with the pointer; the compiler does all the work for you. Here’s an example:

    d pIndicators     s               *   Inz(%Addr(*In))
    
    d indicatorNames  ds                  Based(pIndicators)
    d   newPage_01                    n
    d   endOfFile_02                  n
      // ...
    d  errorFlags                         Overlay(indicatorNames: 55)
    d    overCreditLimit_55...
    d                                 n   Overlay(errorFlags)
    d   invalidCustomer_56...
    d                                 n   Overlay(errorFlags: *Next) 
    d   badPartNumber_57...
    d                                 n   Overlay(errorFlags: *Next)
    

    Note that I defined the pointer first, followed by the indicator data structure. If I do it this way, it makes it easy for me to incorporate the basic setup in a /Copy member if I want to and then add my own application specific definitions to the data structure.

    This example also makes use of a group field (errorFlags), which makes it possible for me to turn on or off a group of indicators very easily.

    /free
       errorFlags = *Off;
     /end-free
    

    Another way to show this would be:

    /free
       errorFlags = *On;
     /end-free
    

    I never did like the old approach of using MOVEA for this purpose. I find this way far better.

    A similar approach can be used with indicators for a subfile, where a particular on/off combination is needed to display or clear the subfile. In this case I would use named constants with the appropriate “0” and “1” pattern to achieve the settings I needed. Here’s an example:

    D pIn             S               *   Inz(%Addr(*In))
    
    D indicatorArray  DS                  Based(pIn)
    
     // Input request indicators
    D   exit_3                        n   Overlay(indicatorArray: 3)
    D   sortPrCode_5                  n   Overlay(indicatorArray: 5)
    D   sortDesc_6                    n   Overlay(indicatorArray: 6)
    
     // Output control indicators
    D   sflControls_90_92...
    D                                3a   Overlay(indicatorArray: 90)
    
     // Constants to set subfile operations
    D   clearSfl      C                   '010'
    D   displaySfl    C                   '101'
    
     // Individual indicators shown for reference - not used in code
    D   sflDspCtl_90                  n   Overlay(indicatorArray: 90)
    D   sflClear_91                   n   Overlay(indicatorArray: 91)
    D   sflDsp_92                     n   Overlay(indicatorArray: 92)
    

    Now to set up the indicators to clear or display the subfile, I need only code a single line and, unlike MOVEA, what I am doing is very obvious. For example:

    sflControls_90_92 = ClearSfl;
    
    sflControls_90_92 = DisplaySfl;
    

    In fact, this is about the only time I ever use the old character style representations of indicator values.

    INDDS: The Architected Approach To Naming Indicators

    Back in V4R2 the RPG compiler folks decided that, in the absence of direct DDS support for indicator names. they should come up with an RPG-specific implementation. INDDS was the result. It stands for INDicator Data Structure and is simply added to the F-spec of the file (or files) that are to use the named data structure for their indicators. There are several important things to note about INDDS:

    • When INDDS is used for a file, there is no longer any connection between the indicators used by the file and the standard *IN series. The device will only use the indicators defined in the specified data structure.
    • Each file can specify its own unique data structure or a single data structure can be shared by multiple files.
    • INDDS can only be specified for files defined with the INDARA (Indicator Area) keyword. I had hoped that over the years this restriction would be removed, but luckily I did not hold my breath waiting.
    • Display files can be changed to use this keyword with no problems at all providing that you keep in mind that with INDARA files a CLEAR or RESET of a record format will not affect the indicators, only the data fields.

    That said, let’s use a simplified version of the previous example to see how the whole thing works:

    Example1  CF   E             WORKSTN INDDS(dispInds) 
    
      d dispInds        ds
        // ...
      d  errorFlags                         Overlay(dispInds: 55)
      d   overCreditLimit_55...
      d                                 n   Overlay(errorFlags)
      d   invalidCustomer_56...
      d                                 n   Overlay(errorFlags: *Next) 
      d   badPartNumber_57...
      d                                 n   Overlay(errorFlags: *Next)
    
         /Free
          Clear errorFlags;
           ...       
          overCreditLimit_55 
             = ( orderTotal + currentBalance ) > creditLimit;
    

    To me this is the cleanest approach and can be useful when the limit of 99 indicators per file gets in the way. If you need to have multiple files sharing some of the indicators, but don’t want to have them share the same data structure, this can be handled quite nicely using EVAL-CORR (Evaluate Corresponding).

    You just need to clone the relevant portions of (say) the display file data structure and add the keyword QUALIFIED to the new data structure definition. Then whenever you want to copy the state of the matching indicators from one data structure to the other you simply code an EVAL-CORR to copy them in the appropriate direction. The example below demonstrates this:

    d dispInds        ds
        // ...
      d  errorFlags                         Overlay(dispInds: 55)
      d   overCreditLimit_55...
      d                                 n   Overlay(errorFlags)
      d   invalidCustomer_56...
      d                                 n   Overlay(errorFlags: *Next) 
      d   badPartNumber_57...
      d                                 n   Overlay(errorFlags: *Next)
    
      d printInds       ds                  QUALIFIED
        // ...
      d  errorFlags                         Overlay(printInds: 55)
      d   overCreditLimit_55...
      d                                 n   Overlay(errorFlags)
      d   invalidCustomer_56...
      d                                 n   Overlay(errorFlags: *Next) 
      d   badPartNumber_57...
      d                                 n   Overlay(errorFlags: *Next)
    
        /Free
    
         Eval-Corr printInds = dispInds;
    

    It is important that you not change the names of the indicators or this won’t work. That’s the meaning of the “corresponding” part of the op-code. Only those fields with matching names and compatible data types will be copied.

    Hopefully I’ve helped to update your understanding of modern indicator usage. If there are any other basic aspects of modern RPG programming you would like to see covered in this series please let me know.

    Jon Paris is one of the world’s most knowledgeable experts on programming on the System i platform. Paris cut his teeth on the System/38 way back when, and in 1987 he joined IBM’s Toronto software lab to work on the COBOL compilers for the System/38 and System/36. He also worked on the creation of the COBOL/400 compilers for the original AS/400s back in 1988, and was one of the key developers behind RPG IV and the CODE/400 development tool. In 1998, he left IBM to start his own education and training firm, a job he does to this day with his wife, Susan Gantner–also an expert in System i programming. Paris and Gantner, along with Paul Tuohy and Skip Marchesani, are co-founders of System i Developer, which hosts the new RPG & DB2 Summit conference. Send your questions or comments for Jon to Ted Holt via the IT Jungle Contact page.

    RELATED STORY

    An Indicator By Any Other Name



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Computer Keyes

    Fax Directly from your IBM i

    KeyesFax is a full function automated IBM i fax system. Spooled files are burst by fax number and auto transmitted with overlays.  It combines both a send and receive facsimile processing system with a complete image package.

    The fax software will edit, send, receive, display, print, and track fax documents or images using any standard IBM i without additional expensive hardware, software or subscriptions.

    Computer Keyes has been developing Software Solutions since 1978!

    www.computerkeyes.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    Connectria Hosting:  Download the State of the i White Paper highlighting Connectria's IBM i Cloud
    Bytware:  Protect your IBM Power Systems from security threats. Download the IFS security bundle!
    looksoftware:  iBelieve New York. A free IBM i Community Event. September 27.

    IT Jungle Store Top Book Picks

    BACK IN STOCK: Easy Steps to Internet Programming for System i: List Price, $49.95

    The iSeries Express Web Implementer's Guide: List Price, $49.95
    The iSeries Pocket Database Guide: List Price, $59
    The iSeries Pocket SQL Guide: List Price, $59
    The iSeries Pocket WebFacing Primer: List Price, $39
    Migrating to WebSphere Express for iSeries: List Price, $49
    Getting Started with WebSphere Express for iSeries: List Price, $49
    The All-Everything Operating System: List Price, $35
    The Best Joomla! Tutorial Ever!: List Price, $19.95

    RJS Strikes Again Power7+ Systems Due To Launch October 3

    Leave a Reply Cancel reply

Volume 12, Number 23 -- September 19, 2012
THIS ISSUE SPONSORED BY:

WorksRight Software
Bytware
Tembo Application Generation

Table of Contents

  • The New Basics: Indicators
  • OSHA Changes To IBM Battery Handling Affect Cache Battery Replacement
  • Admin Alert: Eternal Users: A Common Problem With IBM i Batch Jobs

Content archive

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

Recent Posts

  • 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
  • Will The Turbulent Economy Downdraft IBM Systems Or Lift It?
  • How IBM Improved The Database With IBM i 7.6
  • Rocket Celebrates 35th Anniversary As Private Equity Owner Ponders Sale
  • 50 Acres And A Humanoid Robot With An AI Avatar
  • IBM i PTF Guide, Volume 27, Number 17

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