MainframeSupports
tip week 1/2014:

In this week I will show you a piece of code I typically use for scanning the PARM area used on the EXEC-card. Generally it is a big task to code a scanner for interpretation of a long text as for instance a program. How big a task highly depends on how advanced a syntax you want to scan. This scanner can interpret a syntax where each parameter in the PARM area is separated by a comma. You can use any other character as separator if you like. A parameter may be numeric or just a character string. A numeric parameter is translated into an integer variable (BINARY or DECIMAL).

I have implemented the code itself as a procedure in PLI without parameters. Therefore I hope it is easy to tranlate to COBOL if you need that instead. In the following example the first parameter is called maxRecords which is the maximum number of records I want the program to process. The second parameter is dlmChar which is a delimiter one character long (CHAR(1)) to be present in the records read by the program. The third parameter is fmtMethod which is a character string (CHAR(8) VAR) which controls the formatting of the records read depending on its value. These parameters are declared as a part of the sorrounding program and therefore not part of the tip. The input containing the values for the described parameters is the variable parm which is declared as a CHAR(100) VAR. The scanner code looks like this:

readParm: PROC;

DCL nextChar CHAR(1);
DCL nextPic PIC'9' DEF nextChar;
DCL invalidChar CHAR(1);
DCL posNo FIXED BIN(15);
DCL parmNo FIXED BIN(15);
DCL digitCount FIXED BIN(15);

maxRecords = 0;
dlmChar = '"';
fmtMethod = '';

digitCount = 0;
invalidChar = 'N';
nextChar = 'N';
parmNo = 1;
posNo = 0;
DO WHILE(posNo < length(parm));
  posNo = posNo + 1;
  nextChar = substr(parm, posNo, 1);
  IF nextChar = ','
  THEN DO;
    parmNo = parmNo + 1;
    invalidChar = 'N';
    digitCount = 0;
  END;
  ELSE
    SELECT(parmNo);
      WHEN(1)
        IF invalidChar = 'N'
        THEN
          IF verify(nextChar, '0123456789') = 0
          & digitCount < 9
          THEN DO;
            maxRecords = maxRecords * 10 + nextPic;
            digitCount = digitCount + 1;
          END;
          ELSE
            invalidChar = 'Y';
      WHEN(2)
        dlmChar = nextChar;
      WHEN(3)
        fmtMethod = fmtMethod !! nextChar;
      OTHERWISE
        ;
    END;
END;

END readParm;

The most complicated part is of course the interpretation of a numeric variable. Using the variable digitCount I control the largest number of digits the parameter must contain. There is no error handling in the scanner. When the first non-numeric digit is encountered the following characters are simply skipped until a comma occurs and changes the interpretation to the next parameter. If more than one character is present for the second parameter the last character is used. For the last parameter characters following the eighth digit are simply ignored. If more than two commas occurs in parm the remaining characters are also ignored.

The good thing about this scanner is that it is easy to add interpretation of new parameters and it is also easy to change the interpretation of each parameter. Default values for a CHAR(1) or a FIXED BIN(n) should be assigned before entering the WHILE loop. I will recommend that character strings more than one character long are declared as CHAR(n) VAR, initialised using '' and if the character string is still '' after the loop, you can assign the parameter a default value at this point.

Previous tip in english        Forrige danske tip        Tip list