RPG has, since the beginning of time, supported a set of indicators — one byte characters that can be either *on or *off. These are popular but really shouldn’t be used any more. Being named *IN01 to *IN99 makes for indicators whose function is unclear and you are much better off using built in functions and explicitly defined fields.
There is an exception, of course. When dealing with display files, you have no choice but to use indicators to determine what keys have been pressed. Even here, though, it is a good idea to overlay the indicators with human readable field names.
This is how I do it:
* Global variables d IndicatorPtr s * inz(%addr(*in)) d ds based(IndicatorPtr) d iExit 3 3 d iRefresh 5 5 d iAdd 6 6 d iCancel 12 12 d iValidCmdKey 25 25 d iError 30 30 d iPageDown 26 26 d iSflInit 80 80 d iSflEnd 81 81 d iSflEmpty 82 82 d iSflPosCursor 83 83 d iSflDeleted 84 84 d iProtectKey 90 90 d iProtectData 91 91
So *IN03 is mapped to field iExit, *IN05 is mapped to field iRefresh, and so on.
With the indicators defined in this way, I can write code like this:
p Main b d Main pi /free // Identify the current program program = RtvProgram(); // Main processing loop dou iExit = *on; WorkWithMessageDescriptions(); enddo; return; /end-free p Main e
Note also that this Main procedure is not setting on the *LR indicator. This is because, in the header spec, I have a named main procedure:
h main(Main)
Using this tells the compiler that I am not using the RPG logic cycle and that processing should start with procedure Main. Not only does this allow me to abandon setting on *LR but also reduces a lot of the progeram’s overhead.