A Solution to the Numeric Parameter Problem
May 19, 2004 Hey, Ted:
A common gripe I hear over and over again in midrange circles concerns the way numeric parameters of a CL CALL command are passed from the command line and from the CMD and RQSDTA parameters of the Submit Job (SBMJOB) command. I found a way around this problem.
A brief explanation of the problem seems in order. When a CALL command is executed within a CL program, variable parameters are passed as they are defined, but literals are passed with default formats.
- Character literals that are less than 32 characters are padded with blanks to a length of 32 characters.
- Trailing blanks are removed from character literals longer than 32 characters so that only significant characters are passed to the caller.
- Numeric literals are passed as if they were defined as 15-digit packed-decimal numbers with five decimal digits.
When CALL is executed from a command line or from within SBMJOB, all parameters are passed according to these rules. This results in screwy errors, like garbage in character fields and data decimal errors.
I faced this issue when I wanted to change a CL program to submit another program to batch, rather than call the program directly. At first I thought my only choice was to change the way the numeric parameters were defined in the called program. That is, I would have had to redefine the numeric parameters as 15,5. However, that would have been too much trouble, since the program is still called from other programs, and those calling programs also would have had to be modified to pass the parameters to the called program in the 15,5 format.
The method I found lets me have my cake and eat it, too. I was able to change the program to accept numeric parameters in their original formats or as 15,5 packed-decimal numbers. To illustrate, here is an RPG IV program that accepts one numeric parameter, defined as five digits with no decimal places.
FQSysPrt O F 132 Printer C *Entry PList C Parm TheNumber 5 0 C C Except PrintLine C Eval *InLR = *On OQSysPrt E PrintLine 1 O 'The number is ' O TheNumber J
This program can be called from RPG programs. It can be called from CL programs if the parameter is passed as a five-digit packed-decimal variable with zero decimal places. Calling it from a command line only works if you use a trick like passing a three-byte hexadecimal literal, a technique I use during development and testing but not in production.
Here is the revised source code. This version accepts the parameter in the original format, as well as in 15,5 format.
FQSysPrt O F 132 Printer D PNumber DS 8 D Number3 1 3P 0 D Byte3 3 3A D Number8 1 8P 5 D Byte8 8 8A D D TheNumber s 5P 0 C *Entry PList C Parm PNumber C C Select C When %BitAnd(Byte3:X'0F') = X'0D' OR C %BitAnd(Byte3:X'0F') = X'0F' C Eval TheNumber = Number3 C When %BitAnd(Byte8:X'0F') = X'0D' OR C %BitAnd(Byte8:X'0F') = X'0F' C Eval TheNumber = Number8 C Other * error: invalid parameter format C Eval TheNumber = -99999 C EndSl C C Except PrintLine C Eval *InLR = *On OQSysPrt E PrintLine 1 O 'The number is ' O TheNumber J
If the parameter is passed to this program in the original 5,0 format, the digit portion (rightmost four bits) of the third byte will contain a hexadecimal digit of D or F. If the parameter is passed in the 15,5 format, the eighth byte will contain hex D or F.
The %BITAND built-in function “ands” these bytes with hex 0F, which zeros out the zone (leftmost four bits) and leaves the digit portion intact. The resulting value is compared to hex D (the sign of a negative number) and hex F (the sign of a positive number) in order to determine which of the two formats the calling program used.
As a result, I did not have to change any callers of the program and was able to change the CALL in one program to SBMJOB. As a bonus, I can also run the program directly from the command line.
This illustration reminds me of a technique I have used in the System/36 environment. RPG II programs pass numeric parameters in zoned decimal format, while native programs pass them in packed decimal format. I have written RPG III and RPG IV programs that could accept either format.
Thanks for sharing this technique with readers of Four Hundred Guru, Dominic.