Controlling flow

173 Views


Controlling flow and communicating between programs and procedures

The Call Program (CALL), Call Bound Procedure (CALLPRC), and Return (RETURN) commands pass control back and forth between programs and procedures.

Each command has slightly different characteristics.

Information can be passed to called programs and procedures as parameters when control is passed.

Passing control to another program or procedure

To pass control to another program or procedure, you can select different options.

Using the Call Program command to pass control

The Call Program (CALL) command calls a program named on the command and passes control to it.

The CALL command has the following format:

CALL PGM(library-name/program-name) PARM(parameter-values)

The program name or library name may be a variable.

If the called program is in a library that is not on the library list, you must specify the qualified name of the program on the PGM parameter.

When the called program finishes running, control returns to the next command in the calling program.

The sequence of CALL commands in a set of programs calling each other is the call stack. For example, look at this series.

In this series, the call stack is as follows.

When PROGC finishes processing, control returns to PROGB at the command after the call to PROGC. Control is thus returned up the call stack. This occurs whether PROGC ends with a RETURN or an ENDPGM command.

A CL program can call itself.

Using the Call Bound Procedure command to pass control

The Call Bound Procedure (CALLPRC) command calls a procedure named on the command, and passes control to it.

The CALLPRC command has the following format:

CALLPRC PRC(procedure-name) PARM(parameter-values) RTNVAL(return-value-variable)

The procedure name may not be a variable. When the called procedure finishes running, control returns to the next command in the calling procedure.

The sequence of CALLPRC commands in a set of procedures calling each other is the call stack. For example, look at this series.

In this series, the call stack is as follows.

When PROGC finishes processing, control returns to PROGB at the command after the call to PROGC. Control is thus returned up the call stack. This occurs whether PROGC ends with a Return (RETURN) or an End Program (ENDPGM) command.
A CL procedure can call itself.

 

Using the Return command to pass control

The Return (RETURN) command in a CL procedure or original program model (OPM) program removes that procedure or OPM program from the call stack.

If the procedure containing the RETURN command was called by a Call Bound Procedure (CALLPRC) command, control is returned to the next sequential statement after that CALLPRC command in the calling program.

If a Monitor Message (MONMSG) command specifies an action that ends with a RETURN command, control is returned to the next sequential statement after the statement that called the procedure or program containing the MONMSG command.

The RETURN command has no parameters.

If you have a RETURN command in an initial program, the command entry display is shown. You may want to avoid this for security reasons.

Passing parameters

When you pass control to another program or procedure, you can also pass information to it for modification or use within the receiving program or procedure.

You can specify the information to be passed on the PARM parameter on the Call (CALL) command or the Call Bound Procedure (CALLPRC) command.

The characteristics and requirements for these commands are slightly different.

For instance, if PROGA contains the following command:

CALL PROGB PARM(&AREA)

then it calls PROGB and passes the value of &AREA to it. PROGB must start with the PGM command, which also must specify the parameter it is to receive:

PGM PARM(&AREA) /* PROGB */

For the Call (CALL) command or the Call Bound Procedure (CALLPRC) command, you must specify the parameters passed on the PARM parameter.

For example, if PROGA contains the following command:

CALL PROGB PARM(&A &B &C ABC)

it passes three variables and a character string, and if PROGB starts with:

PGM PARM(&C &B &A &D) /*PROGB*/

then the value of &A in PROGA is used for &C in PROGB, and so on; &D in PROGB is ABC. The order of the DCL statements in PROGB is unimportant.

Only the order in which the parameters are specified on the PGM statement determines what variables are passed.

The following is an example of a procedure or program that receives the value &VAR1:

PGM PARM(&VAR1) /*PGMA*/
DCL VAR1 *CHAR LEN(36)
.
.
.
ENDPGM

The CALL command or Call Bound Procedure (CALLPRC) command must specify 36 characters:

CALLPRC PGMA(ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJ)

The following example specifies the default lengths:

PGM PARM(&P1 &P2)
DCL VAR(&P1) TYPE(*CHAR) LEN(32)
DCL VAR(&P2) TYPE(*DEC) LEN(15 5)
IF (&P1 *EQ DATA) THEN(CALL MYPROG &P2)
ENDPGM

To call this program, you could specify:

CALL PROG (DATA 136)

The character string DATA is passed to &P1; the decimal value 136 is passed to &P2.

You can also specify the special value *OMIT for any parameter that you want to omit from the parameter list on the Call Bound Procedure (CALLPRC) command. If you specify *OMIT for a parameter, the calling program or procedure passes a null pointer.

 

Using the Call Program command to pass control to a called program

When the Call Program (CALL) command is issued by a CL procedure, each parameter value passed to the called program can be a character string constant, a numeric constant, a logical constant, or a CL variable.

A maximum of 255 parameters can be passed to the called program.

The values of the parameters are passed in the order in which they appear on the CALL command.

The names of the variables passed do not have to be the same as the names on the receiving parameter list.

The names of the variables receiving the values in the called program must be declared to the called program, but the order of the declare commands is not important.

If you need to pass a numeric constant to a program and the program is expecting a value with a length and precision other than 15 5, the constant can be coded in hexadecimal format.

The following CALL command shows how to pass the value 25.5 to a program variable that is declared as LEN(5 2):

CALL PGMA PARM(X'02550F')

In the following example, program A passes six parameters: one logical constant, three variables, one character constant, and one numeric constant.

PGM /* PROGRAM A */
DCL VAR(&B) TYPE(*CHAR)
DCL VAR(&C) TYPE(*DEC) LEN(15 5) VALUE(13.529)
DCL VAR(&D) TYPE(*CHAR) VALUE('1234.56')
CHGVAR VAR(&B) VALUE(ABCDEF)
CALL PGM(B) PARM('1' &B &C &D XYZ 2) /* Note blanks between parms */
.
.
.
ENDPGM
PGM PARM(&A &B &C &W &V &U) /* PROGRAM B */
DCL VAR(&A) TYPE(*LGL)
DCL VAR(&B) TYPE(*CHAR) LEN(4)
DCL VAR(&C) TYPE(*DEC)
 /* Default length (15 5) matches DCL LEN in program A */
DCL VAR(&W) TYPE(*CHAR)
DCL VAR(&V) TYPE(*CHAR)
DCL VAR(&U) TYPE(*DEC)
.
.
. ENDPGM

The logical constant '1' does not have to be declared in the calling program. It is declared as type logical and named &A in program B.

 

Common errors when calling programs and procedures

In passing values on a Call Program (CALL) command or a Call Bound Procedure (CALLPRC) command, you might encounter some errors. Some of these errors can be very difficult to debug, and some have serious consequences for program functions.

* When you use the Call Program (CALL) command, data type errors might occur.

* Common problems with decimal constants and character variables often occur.

It give errors when a character variable is declared longer than 32 characters.

In the following example, a quoted numeric value is passed to a program that expects a decimal value. A decimal data error (escape message MCH1202) occurs when variable &A is referred to in the called program (PGMA):

CALL PGMA PARM('123') /* CALLING PROGRAM */
PGM PARM(&A) /* PGMA */
DCL &A *DEC LEN(15 5) /* DEFAULT LENGTH */
.
.
.
IF (&A *GT 0) THEN(...) /* MCH1202 OCCURS HERE */

In the following example, a decimal value is passed to a program defining a character variable. Generally, this error does not cause runtime failures, but incorrect results are common:

CALL PGMB PARM(12345678) /* CALLING PROG */
PGM PARM(&A) /* PGMB */
DCL &A *CHAR 8
.
.
.
ENDPGM

Variable &A in PGMB has a value of hex 001234567800000F.

Generally, data can be passed from a logical (*LGL) variable to a character (*CHAR) variable, and vice versa, without error, so long as the value is expressed as '0' or '1'.

* When a decimal value is passed with incorrect decimal length and precision, errors might occur.

If a decimal value is passed with an incorrect decimal length and precision (either too long or too short), a decimal data error (MCH1202) occurs when the variable is referred to.

In the following examples, the numeric constant is passed as LEN(15 5), but is declared in the called procedure or program as LEN(5 2). Numeric constants are always passed as packed decimal (15 5).

CALL PGMA PARM(123) /* CALLING PROG */
PGM PARM(&A) /* PGMA */
DCL &A *DEC (5 2)
.
.
.
IF (&A *GT 0) THEN(...) /* MCH1202 OCCURS HERE */

If you need to pass a numeric constant to a procedure or program and the procedure or program is expecting a value with a length and precision other than 15 5, the constant can be coded in hexadecimal format. The following CALL command shows how to pass the value 25.5 to a program variable that is declared as LEN(5 2):

CALL PGMA PARM(X'02550F')

If a decimal value is passed with the correct length but with the wrong precision (number of decimal positions), the receiving procedure or program interprets the value incorrectly.

In the following example, the numeric constant value (with length (15 5)) passed to the procedure is handled as 25124.00.

PGM /* PGMA */
DCL &A *DEC (7 2)
CALL PGMB PARM(&A) /* (7 2) PASSED TO PGMB */
IF (&A *NE 0) THEN(...) /* *MCH1202 OCCURS HERE */
.
.
.
ENDPGM
PGM PARM(&A) /* PGMB */
DCL &A *DEC (5 2) /* WRONG LENGTH */
.
.
.
 CHGVAR &A (&B-&C) /* VALUE PLACED in &A */
RETURN
When control returns to program PGMA and &A is referred to, the error occurs.

* When you pass character values with incorrect length, errors might occur.

If you pass a character value longer than the declared character length of the receiving variable, the receiving procedure or program cannot access the excess length. In the following example, PGMB changes the variable that is passed to it to blanks.

Because the variable is declared with LEN(5), only 5 characters are changed to blanks in PGMB, but the remaining characters are still part of the value when referred to in PGMA

PGM /* PGMA */
DCL &A *CHAR 10
CHGVAR &A 'ABCDEFGHIJ'
CALL PGMB PARM(&A) /* PASS to PGMB */
.
.
.
IF (&A *EQ ' ') THEN(...) /* THIS TEST FAILS */
ENDPGM
PGM PARM(&A) /* PGMB */
DCL &A *CHAR 5 /* THIS LEN ERROR*/
CHGVAR &A ' ' /* 5 POSITIONS ONLY; OTHERS UNAFFECTED */
RETURN

In the following example, two 3-character constants are passed to the called program but A and B are of length 50.

A Value= ABC+29' '+DEF+15' '

B Value=DEF+7' '

CALL PGMA ('ABC' 'DEF') /* PASSING PROG */
PGM PARM(&A &B) /* PGMA */
DCL &A *CHAR 50 /* VALUE:ABC+29' '+DEF+15' ' */
DCL &B *CHAR 10 /* VALUE:DEF+7' ' */
CHGVAR VAR(&A) (' ') /* THIS ALSO BLANKS &B */
.
.
.
ENDPGM

In the following example, assume the two constants are adjacent in storage. Passing 3 character values but A is 5 and B is 3.

A VALUE:'ABC' + 'DE'

B VALUE:'DEF'

CALLPRC PRCA ('ABC' 'DEF') /* PASSING PROG */
PGM PARM(&A &B) /* *PRCA */
DCL &A *CHAR 5 /* VALUE:'ABC' + 'DE' */
DCL &B *CHAR 3 /* VALUE:'DEF' */
CHGVAR &A ' ' /* This also blanks the first two bytes of &B */
.
.
.
ENDPGM

 

Post Comments