The Call Subroutine (CALLSUBR) command is used in a CL procedure for passing control to a subroutine defined within the same procedure.
The Call Subroutine (CALLSUBR) command has two parameters: Subroutine (SUBR), which contains the name of the subroutine to which control is to be transferred to, and Return value (RTNVAL), which specifies the variable that will contain the return value from the called subroutine. See the following example:
CALLSUBR SUBR(mysubr) RTNVAL(&myrtnvar)
The subroutine mysubr must be defined in the procedure by the Subroutine (SUBR) parameter of a Subroutine (SUBR) command. The variable '&myrtnvar' must be defined as TYPE(*INT) LEN(4), and will contain the value from the Return value (RTNVAL) parameter of either a Return from Subroutine (RTNSUBR) or the End Subroutine (ENDSUBR) command found in subroutine 'mysubr'. If no RTNVAL parameter is defined, the return value from the subroutine is ignored.
The Call Subroutine (CALLSUBR) command may be placed anywhere within the procedure, including other subroutines, with the exception of a program-level Monitor Message (MONMSG) command. Each Call Subroutine (CALLSUBR) command, when run, places a return address onto the subroutine stack, and the size of the stack can be changed with the use of the Subroutine Stack (SUBRSTACK) parameter of the Declare Process Options (DCLPRCOPT) command. If a globally monitored message causes a GOTO command to be run, the subroutine stack will be reset by the next Call Subroutine (CALLSUBR) command that is run. See the following example:
PGM DCL VAR(&myrtnvar) TYPE(*INT) LEN(4) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(DUMP)) : CALLSUBR SUBR(SUBR1) RTNVAL(&myrtnvar) : DUMP: DMPCLPGM CALLSUBR SUBR(SUBR2) : SUBR SUBR(SUBR1) : SUBR SUBR(SUBR1) : ENDSUBR RTNVAL(12) : SUBR SUBR(SUBR2) : ENDSUBR ENDPGM
In this example, the first Call Subroutine (CALLSUBR) command will pass control to the subroutine SUBR1, and the return value of 12 will be placed into the variable &myrtnvar when control returns. If a message is monitored by the Monitor Message (MONMSG) command, the Goto (GOTO) command will be run and control will branch to label DUMP, the CL procedure will be dumped by DMPCLPGM, and the next CALLSUBR to subroutine SUBR2 will reset the subroutine stack.