With every new release I go through all the "What's new for this release" section of IBM's KnowledgeCenter. For IBM i 7.4 and the CL programming language there is only one addition this release: %PARMS built in function. It appears to be identical to the %PARMS built in function in RPG. It is the way to determine how many parameters have been passed to a program or procedure, and from that stop the program from erroring if too few parameters are passed.

In the past I wrote about coping with to few parameters being passed to a CL program, but the new BiF is a lot neater and easier for someone else to understand.

As I said above %PARMS is available in RPG:

01 **free 02 ctl-opt main(Main) option(*nodebugio:*srcstmt) ; 03 dcl-pr Main extpgm('TESTRPG') ; 04 *n char(1) ; 05 *n char(1) ; 06 *n char(1) ; 07 end-pr ; 08 dcl-s P1 char(1) inz('*') ; 09 dcl-s P2 like(P1) inz('*') ; 10 dcl-s P3 like(P1) inz('*') ; 11 dcl-proc Main ; 12 dcl-pi *n ; 13 inP1 char(1) ; 14 inP2 char(1) ; 15 inP3 char(1) ; 16 end-pi ; 17 if (%parms = 3) ; 18 P3 = inP3 ; 19 endif ; 20 if (%parms >= 2) ; 21 P2 = inP2 ; 22 endif ; 23 if (%parms >= 1) ; 24 P1 = inP1 ; 25 endif ; 26 dsply (' ') ; 27 end-proc ;

Lines 3 – 7: As I am using a Main procedure, see line 2, I define the parameters passed to this program using the declare procedure statement. Three parameters are passed to this program, each one is a single character.

Lines 8 – 10: These three variables will receive the values of the passed parameters. Notice that they are all initialized with the value ' * '.

Lines 12 - 16: Procedure interface defining and giving names to the variables passed to this program.

Lines 17 – 19: If three parameters are passed to this program then the value in the input parameter inP3 is moved to the program variable P3 .

Lines 20 – 22: If two or more parameters are passed P2 is updated with the value from inP2 .

Lines 23 – 25: If one or more parameters are passed P1 is updated with the value from inP1 .

Line 26: I am using the DSPLY operation code so that I can see what the parameters P1 , P2 , and P3 contain.

Let me now call this program with various number of parameters.

01 CALL TESTRPG DSPLY 02 CALL TESTRPG '1' DSPLY <1> 03 CALL TESTRPG ('1' '2') DSPLY <1> <2> 04 CALL TESTRPG ('1' '2' '3') DSPLY <1> <2> <3>

Line 1: I have passed no parameters, therefore, P1 , P2 , and P3 contain the value I initialized them when I defined them.

Line 2: As only one parameter is passed, only P1 is changed.

Line 3: Two parameters are passed, and P1 and P2 are changed.

Line 4: Three parameters are passed, and all the program defined variables have been changed.

Let me now do the equivalent in CL:

01 PGM PARM(&IN_P1 &IN_P2 &IN_P3) 02 DCL VAR(&IN_P1) TYPE(*CHAR) LEN(1) 03 DCL VAR(&IN_P2) TYPE(*CHAR) LEN(1) 04 DCL VAR(&IN_P3) TYPE(*CHAR) LEN(1) 05 DCL VAR(&P1) TYPE(*CHAR) LEN(1) VALUE('*') 06 DCL VAR(&P2) TYPE(*CHAR) LEN(1) VALUE('*') 07 DCL VAR(&P3) TYPE(*CHAR) LEN(1) VALUE('*') 08 IF COND(%PARMS() = 3) THEN(CHGVAR VAR(&P3) VALUE(&IN_P3)) 09 IF COND(%PARMS() >= 2) THEN(CHGVAR VAR(&P2) VALUE(&IN_P2)) 10 IF COND(%PARMS() >= 1) THEN(CHGVAR VAR(&P1) VALUE(&IN_P1)) 11 SNDPGMMSG MSG(' ') 12 ENDPGM

Line 1: The parameters that can be received by this CL program.

Lines 2 – 4: Definitions of the passed parameters.

Lines 5 – 7: Definitions of the program's variables, all initialized with ' * '.

Line 8: If three parameters were passed to this program move the value in &IN_P3 to &P3 .

Line 9: If two or more parameters were passed to this program move the value in &IN_P2 to &P2 .

Line 10: And finally is one or more parameters were passed move the vale in &IN_P1 to &P1 .

Line 11: As I cannot use RPG's display operation code, I am using the Send Program Message command, SNDPGMMSG to send a message to the program's message queue instead.

What happens when I call this CL program?

01 CALL TESTCL 02 CALL TESTCL '1' <1> 03 CALL TESTCL ('1' '2') <1> <2> 04 CALL TESTCL ('1' '2' '3') <1> <2> <3>

The results are identical to those for the RPG program. If I pass less than three parameters the "extra" program variables still contain ' * '.

One thing I did find bizarre in the documentation was it said that if I compiled this to earlier releases, IBM i 7.3 and 7.2, I could copy the object to a partition with one of those releases and the program would still work!

Being a person who likes to test these kind of things I..

Created the program with the target release of IBM i 7.2:

CRTBNDCL PGM(MYLIB/TESTCL) SRCFILE(DEVSRC) TGTRLS(V7R2M0)

Saved for target release 7.2:

SAVOBJ OBJ(TESTCL) LIB(MYLIB) DEV(*SAVF) SAVF(MYSAVF) TGTRLS(V7R2M0)

Restored the program onto the 7.2 partition.

The documentation is correct, this program does work in a partition running on 7.2!

CALL TESTCL

You can learn more about this from the IBM website:

This article was written for IBM i 7.4 and 7.3 TR6.