SUBR command and subroutines in a CL program or procedure

The Subroutine (SUBR) command is used in a CL program or procedure, along with the End Subroutine (ENDSUBR) command, to delimit the group of commands that define a subroutine.

The name of the subroutine, as used by the CALLSUBR command, is defined by the SUBR parameter on the SUBR command.

The first SUBR command that is encountered in a program or procedure also marks the end of the mainline of that program or procedure. All commands from this point forward, with the exception of the ENDPGM command, must be contained within a subroutine, in other words, between SUBR and ENDSUBR commands. The SUBR and ENDSUBR commands must be matched pairs, and subroutines cannot be nested. In other words, no SUBR SUBR ENDSUBR ENDSUBR nesting of subroutines is allowed.

Both the ENDSUBR and RTNSUBR commands can be used to exit a subroutine, and when processed, control is returned to the command immediately following the Call Subroutine (CALLSUBR) command that called the subroutine. Both commands have an optional RTNVAL parameter, which can be anything that can be stored in a CL variable of TYPE(*INT) and LEN(4). If no RTNVAL parameter is defined on the Return Subroutine (RTNSUBR) or ENDSUBR command, a value of zero is returned.

The following example is about the general structure of a CL procedure that contains a subroutine.

              PGM    
              DCLPRCOPT  SUBRSTACK(25)
              DCL        VAR(&RTNVAR) TYPE(*INT) LEN(4)        
			       :
              CALLSUBR   SUBR(SUBR1) RTNVAL(&RTNVAR)
			       :
              SUBR       SUBR(SUBR1)                            
			       :
              RTNSUBR    RTNVAL(-1)
			       :
              ENDSUBR                                                                                                         
              ENDPGM 

In this example, the Declare Processing Options (DCLPRCOPT) command was used to specify the size of the subroutine stack to be 25. The variable &RTNVAR is used to contain the return value from the subroutine. The CALLSUBR command will transfer control to the subroutine SUBR1, as defined by the SUBR command. If the RTNSUBR command is run, the value of &RTNVAR will be -1, if the ENDSUBR command is run, &RTNVAR will equal 0. If no RTNVAL parameter was defined on the CALLSUBR command, the return value from the subroutine would be ignored.