Writing an edit routine on VM without LE

The QMF edit exit interface for PL/I in CMS consists of these parts:

Figure 167 shows the program structure of a PL/I edit exit routine in CMS.

Figure 167. Program structure of a PL/I edit exit routine without LE
QMF Main MOdule DSQQMF points to QMF Edit Exit Module DSQUEDIT Entry: DSQUXIP.
QMF Edit Exit Module which contains IBM-supplied QMF Control Programs DSQUXIP
 and DSQUPLI, and User edit exit program DSQUXDT via Standard PL/I call point
to QMF Main  Module via Return.

Example program DSQUXDTP

The IBM-supplied example edit exit program in PL/I, named DSQUXDTP, is located on the QMF production disk on CMS. The example program is heavily commented; it can be browsed online, printed, or modified to meet your needs. If you plan to use this example program, copy it to your program library and change its name to DSQUXDT. If you build your own routine instead, note that within the source is an %INCLUDE statement for DXEECSP, which is a member of DSQUSERE MACLIB on CMS. It is DXEECSP that defines the input fields, giving them the names we are using in this chapter. It is best to include this in your own edit routine.

How a PL/I edit routine interacts with QMF

Linkage begins with the PROCEDURE statement:

DSQUXDT:
         PROCEDURE(DXEECSF,ECSINPTF,ECSRSLTF) ...;

Passed through this statement are the control block (DXEECSF), the value to be formatted (ECSINPTF), and the storage set aside for the formatted result (ECSRSLTF). At this point, you can expect to find declarations defining DXEECSF as a structure, and defining ECSINPTF and ECSRSLTF as character strings. Instead, you find the statement:

DECLARE (DXEECSF,
         ECSINPTF,
         ECSRSLTF)
            BINARY FIXED, ...

which defines the three parameters as fullword integers. This is because the calling program itself, in order to avoid the overhead of locators and descriptors, represents the parameters in its call to DSQUXDT as fullword integers. QMF doesn't know in what language the calling program is written, so the parameters are passed in the same way as they are for Assembler.

In the sample program below, the actual parameter descriptions appear in the previously mentioned block of definitions comprising DXEECSP. The declaration for the control block begins with:

DECLARE
  1 DXEECSP BASED(ECSPTR)
.
.
.

The statements defining the other two parameters are:

DECLARE
  ECSINPT CHARACTER(32767)
          BASED(ECSINPTP), ... and
DECLARE
  ECSRSLT CHARACTER(32767)
          BASED(ECSRSLTP);

Thus, the parameters are defined as based storage. To complete the linkage, the pointers are set to the appropriate addresses at the start of the procedural logic section:

ECSPTR   = ADDR(DXEECSF);
ECSINPTP = ADDR(ECSINPTF);
ECSRSLTP = ADDR(ECSRSLTF);
 

The interface control block between QMF and the user edit interface DSQUXDT is DXEECS. It contains the user's edit code, identifies the source data and the target location for the edited result, and provides a scratchpad area for the user edit routine's use. This control block is persistent between calls to the user edit routine. The scratchpad area is not modified by QMF after the initial invocation of the exit routine.

Return control to QMF using a standard RETURN statement.

Compiling DSQUXDT and DSQUPLI

During the compile, QMF edit exit interface control block DXEECSP, located in DSQUSERE MACLIB on the QMF production disk on CMS must be available in a macro library. You need to make the macro libraries available to the PL/I compiler by issuing a CMS GLOBAL MACLIB command. For example:

GLOBAL MACLIB DSQUSERE PLICOMP

Compile both programs with no STAE or SPIE macros. To do this, add the following statement to your PL/I program:

DCL PLIXOPT CHAR(15) VAR INIT('NOSTAE,NOSPIE') STATIC EXTERNAL;

Compile DSQUPLI with the MAIN option. Your edit exit program DSQUXDT must not specify MAIN.

Creating your DSQUEDIT module file in PL/I

Before you can create your DSQUEDIT module file, ensure that you can access the IBM-supplied control module (DSQUXIP). DSQUXIP is located on the QMF production disk. You need to access this disk prior to creating the module file.

To create the DSQUEDIT module file, use the CMS LOAD and GENMOD commands:

  1. Load the text files that make up the DSQUEDIT module.

    The DSQUEDIT module must be relocatable. To be relocatable, the module must be loaded with RLD entries. You do this by specifying the RLDSAVE option on the CMS LOAD command. The entry point to the DSQUEDIT module must be DSQUXIP. PL/I text libraries must be made available by issuing a CMS GLOBAL TXTLIB command. Issue the following CMS commands:

       GLOBAL TXTLIB IBMLIB PLILIB
       LOAD DSQUXIP DSQUXDT DSQUPLI (RLDSAVE RESET DSQUXIP)

    You can run your edit routine in either 24-bit or 31-bit addressing mode. QMF manages address switching as required. You can specify 31-bit addressing on the CMS LOAD command. For example:

       GLOBAL TXTLIB IBMLIB PLILIB
       LOAD DSQUXIP DSQUXDT DSQUPLI
            (RLDSAVE RESET DSQUXIP AMODE 31 RMODE ANY)
  2. Generate the DSQUEDIT module.

    Issue the CMS GENMOD command to generate the DSQUEDIT module from the text files just loaded by the CMS LOAD command:

     GENMOD DSQUEDIT

Once the user edit routine is tested, it can replace the DSQUEDIT module file on the QMF production disk or user disk that is available when starting QMF. In order to use the PL/I user edit routine, the PL/I production disk and run-time libraries need to be available when you start QMF.

When running under ISPF and starting QMF using the PGM form of ISPSTART, the PL/I run-time load libraries must be specified using a CMS FILEDEF command for ISPLLIB. For guidelines and considerations about PL/I programs running in ISPF, see ISPF for VM Dialog Management Services and Examples

When running without ISPF, or running under ISPF and starting QMF using the program segment form of ISPSTART, the PL/I run-time load libraries must be specified using a CMS GLOBAL LOADLIB command.

For detailed information on how to compile and make run-time libraries available for PL/I, see the PL/I Programming Guide.

[ Previous Page | Next Page | Contents | Index ]