MainframeSupports
tip week 26/2004:

There are several things about PL/1, that could have been implemented much better. One of them is the way dynamic calling of other programs is done. Most installations using PL/1 is linking all the sub modules together, which often ends up by producing a big LOAD module. The migration procedures for PL/1 programs must also keep track of where sub modules are used in order to relink all the LOAD modules using a changed sub module.

You are able to circumvent all these problems by means of the fetch facility. In the newest release of PL/1 it is even possible to use a variable containing the name of the sub module, you want to call. COBOL has been able to do this for more than ten years and if you aren't ready for the newest PL/1 release yet, you can use the following assembler program called DYNLINK:

DYNLINK  CSECT
         SAVE   (14,12),,*
         LR     12,15
         USING  DYNLINK,12
         LR     11,13
         LA     13,SAVEAREA
         ST     11,4(13)
         ST     13,8(11)
         L      1,0(1)
         LH     2,0(1)
         LA     15,20
         CH     2,=H'8'
         BNE    UD
         LA     2,2(1)
         LA     1,PARAM
         LINK   EPLOC=(2)
UD       L      13,4(13)
         RETURN (14,12),RC=(15)
PARAM    DC     A(DUMMY)
DUMMY    DC     H'0'
         DS     0F
SAVEAREA DS     9D
         END

I am not good at assembler at all, so just beleave me when I tell you that this tiny program will work, but with some limitations. You cannot transfer any parameters via DYNLINK, and DYNLINK is not reentrant, which means that you cannot use is in any form of recursion. DYNLINK is able to pass the standard MVS return code (the contens of register 15) back to the caller.

You can use DYNLINK in the following way in a PL/1 program:

callany: PROC(parameter) OPTIONS(MAIN);

DCL parameter CHAR(100) VARYING;
DCL program_name CHAR(8) VARYING;
DCL dynlink EXTERNAL ENTRY OPTIONS(ASM INTER RETCODE);
DCL substr,pliretc,pliretv BUILTIN;

program_name = substr(parameter !! '        ', 1, 8);
CALL dynlink(program_name);
CALL pliretc(pliretv());

END callany;

If you execute CALLANY with EXEC PGM=CALLANY,PARM='/IEFBR14' it will activate IEFBR14. DYNLINK doesn't care about the kind of program it is calling as long as it is an executable LOAD module. CALLANY is therefore able to call an other PL/1 main program. DYNLINK is designed to receive a CHAR(8) VARYING parameter that must contain exactly eight characters. Otherwise it will return immediately with a return code of 20.

Previous tip in english        Sidste danske tip        Tip list