The indicator is perhaps the most ignominious throwback to the original days of RPG, but the good news is that, with a little work, we can get rid of them.
The indicator data type isn't terrible in and of itself. This concept is known in other languages as a Boolean, a variable that can contain one of two values: true or false. The truly archaic part of the standard RPG logic is the support for an implicit array of 99 indicators, numbered 1–99, and the ability to refer to those using just the two digits. We'll review the most common uses of those indicators and the way we can get rid of them.
There's No Such Thing as a Bad Boolean
Really, the Boolean data type is a fundamental part of programming. It's the basic unit of all computer functions—from memory storage (bits) to the most basic building blocks of logic programming (AND, OR, and XOR). The ability to set a flag at one point in a program and test it later is critical, as is the ability to return a true or false value from a function.
The Boolean data type is used to handle all of the conditional logic in your program, either explicitly or implicitly. Explicitly, you may have a Boolean variable named done and your program mainline has a loop that reads dou done. Implicitly, you might have that same loop that says dou %eof(myfile), where the implicit value of %eof is a Boolean that says whether you have reached end-of-file or not. Every if, every conditional loop, every case statement—all of these are, at their core, implementations of Boolean logic.
Booleans Behaving Badly
That isn't meant to say that Booleans can't be abused, and the original RPG gave us one of the most egregious examples of such misuse. The language supported two types of indicators: specific two-character conditioning indicators and numbered, general-purpose indicators. Nearly all of the special-condition indicators have long since gone out of use except in RPG cycle programs.
I'm not going to argue the merits of creating cycle programs in today's programming environment, but the control-level indicators and matching-record indicators aren't useful outside of the cycle. Halt indicators have also long been deprecated by various other methods. The old OF (and OV, OA, OB, etc.) overflow indicators on printers can be replaced by newer named indicators, which we'll discuss in a moment. Command-key indicators can also be done away with, although they do require a little work (which we'll touch on shortly). In fact, except for the good old LR, there's really no use for any of the original special indicators, and even LR can be done away with for NOMAIN programs, although that's a slightly more involved discussion. But once we've dealt with those special-purpose indicators, we still have to deal with the real bad boys of Booleanville.
General Purpose Indicators 01 to 99
I know the history behind the indicator concept. It all centers on the whole idea of punched cards with columnar format and the ability to have conditioned lines of code both in your calculations and in your output specifications. Your calculations would set various indicators, which in turn would dictate the final form of the generated output. It could be as trivial as this:
C PIECES COMP 1 81
O PIECESZ 22
O 28 'PIECE'
O N81 29 'S'
Indicator 81 is reserved and is used to indicate (hence the name “indicator”) whether the variable PIECES has a value of 1 or not. If indicator 81 is on, PIECES has a value of 1; otherwise, it does not. The printer output is designed to put out a line that shows how many pieces (of whatever). However, in order to be grammatically correct, it will use the word PIECE if the value is one, and PIECES if it is any other amount.
The code is simple: compare PIECES to 1 and set indicator 81 on if that's the value. Later, we will output the S in PIECES if the value is anything other than 1. Nothing here is shocking except perhaps the decision to specify the indicators using a two-digit number. Well, the answer there is simple: real estate. By using two-digit numbers, RPG established a compromise between brevity and flexibility. With two-digit numbers, RPG could allow up to three conditions to be tested (along with the negative test using the "N" modifier) using only nine columns. In an 80-character punched card, that space savings was pretty significant. Of course, that led to code like this:
C 03N71 63
CAN 81N83 WSTOFO ADD WSFRFO FRTTOT 92
C 03N71 63
CAN 81N83N92 EXSR PRCFRT
There isn't an RPG programmer who hasn't at least seen this kind of code (and an awful lot of us have written some of it as well). Luckily, that sort of programming went by the wayside with the advent of the named indicator. Now we might see something more like this:
if pricing and inCurrentWarehouse;
FreightTotal = ToFreight + FromFreight;
if FreightTotal > 0;
So the good news is that, in most cases, we can get rid of those pesky indicators. The only part where we cannot is in the comunication with the outside world and, more specifically, in our display and printer files. Those take a bit more work.
Display File Indicators
Display file indicators work in both directions: the program can set an indicator that controls how the display file functions, and the display file can set an indicator in response to some user action. A single line from a display file can serve to illustrate both conditions:
A 32 CF16(16)
What this line says is to enable F16 only if indicator 32 is on, and if the user subsequently presses F16, turn indicator 16 on upon return to the program. Note that this technique is an alternate to the old Kx indicator (which in this case, would have been KQ—extra points for the person who knows why the 16th command key uses the 17th letter in the alphabet!).
Anyway, the problem is that you need to use not one but two numbered indicators: one to tell the display file to enable F16, and the other to tell the program that F16 was pressed. It is this last holdout that we're going to address right now. We do it using the INDARA keyword. INDARA tells the system to use a special indicator area when communicating with the display file rather than using the standard RPG general-purpose indicators. Coding the display file is pretty simple:
That's it. It's a file-level keyword, so it goes right at the top of the display file DDS as one of the first lines before you even begin to define the records in the display. In the RPG program, identifying that you're using INDARA is pretty simple as well: just add a keyword to your display file specification.
dcl-f MYDISP workstn indds(dsInds);
The INDDS keyword tells the compiler to use the the data structure named dsInds when passing indicators back and forth between the display file and the program. The only final trick is to define the data structure itself. I usually do it something like this:
dcl-ds dsInds len(99);
// Command keys - array and specific keys
F16 ind pos(16);
// Panel Control
enableF16 ind pos(32);
That's all there is to it. I've defined two indicators, one at position 16 and one at position 32. These correspond with numbered indicators 16 and 32, respectively. I would do something like this for any other indicators. That then leads to code like this:
enableF16 = *on;
This code is executed if a post is allowed. It's set up to allow the user to verify whether or not to post data. The enableF16 flag is what makes F16 available to the user. The screen is then displayed, and the user can execute the post by hitting F16, which upon return to the program will set the F16 variable to true. That flag can be checked; in this case if the flag is on, a post function is called.
This is just the introduction to the concept of the indicator area. In another article, I'll explain techniques I use to allow a standard design of the data structure to handle a fairly wide variety of situations, from subfiles to error handling. Enjoy saying bon voyage to your old-school indicators!