Use the EXIT option to have the compiler accept user-supplied modules in place of SYSIN, SYSLIB (or copy library), and SYSPRINT.
When creating your EXIT module, ensure that the module is linked as a DLL module before you run it with the COBOL compiler. EXIT modules are invoked with the system linkage convention of the platform.
Default is: NOEXIT
Abbreviations are: EX(INX|NOINX,LIBX|NOLIBX,PRTX|NOPRTX,ADX|NOADX)
If you specify the EXIT option without providing at least one suboption (that is, you specify EXIT()), NOEXIT will be in effect. You can specify the suboptions in any order, separated by either commas or spaces. If you specify both the positive and negative form of a suboption (INEXIT|NOINEXT, LIBEXIT|NOLIBEXIT, PRTEXIT|NOPRTEXIT, or ADEXIT|NOADEXIT), the form specified last takes effect. If you specify the same suboption more than once, the suboption specified last takes effect.
For SYSADATA, the ADEXIT suboption provides a module that will be called for each SYSADATA record immediately after the record has been written out to the file.
No PROCESS: The EXIT option cannot be specified in a PROCESS(CBL) statement. You can specify it only by using the environment variable COBOPT, or as an option in the cob2 command.
The module names mod1, mod2, mod3, and mod4 can refer to the same module.
The suboptions 'str1', 'str2', 'str3', and 'str4' are character strings that are passed to the load module. These strings are optional; if you use them, they can be up to 64 characters in length and must be enclosed in single quotation marks. Any character is allowed, but included single quotation marks must be doubled, and lowercase characters are folded to uppercase.
If 'str1', 'str2', 'str3', or 'str4' is specified, the string is passed to the appropriate user-exit module with the following format, where LL is a halfword (on a halfword boundary) that contains the length of the string. The table shows the location of the character string in the parameter list.
| LL | string |
When an exit is used, the compiler provides a user-exit work area that can be used to save the address of storage allocated by the exit module. This allows the module to be reentrant.
The user-exit work area is 4 fullwords, residing on a fullword boundary, that is initialized to binary zeroes before the first exit routine is invoked. The address of the work area is passed to the exit module in a parameter list. After initialization, the compiler makes no further reference to the work area. So, you will need to establish your own conventions for using the work area if more than one exit is active during the compilation. For example, the INEXIT module uses the first word in the work area, the LIBEXIT module uses the second word, and the PRTEXIT module uses the third word.
Your EXIT modules should use standard linkage conventions between COBOL programs, between library routines, and between COBOL programs and library routines. You need to be aware of these conventions in order to trace the call chain correctly.
The following table shows the format of the parameter list used by the compiler to communicate with the exit module.
| Offset | Contains | Description of item |
|---|---|---|
| 00 | User-exit type | Halfword identifying which user
exit is to perform the operation.
1=INEXIT; 2=LIBEXIT; 3=PRTEXIT; 4=ADEXIT |
| 02 | Operation code | Halfword indicating the type of
operation.
0=OPEN; 1=CLOSE; 2=GET; 3=PUT; 4=FIND |
| 04 | Return code | Fullword, placed by the exit
module, indicating status of the requested operation.
0=Successful; 4=End-of-data; 12=Failed |
| 08 | Data length | Fullword, placed by the exit module, specifying the length of the record being returned by the GET operation. |
| 12 | Data or 'str2' | Data is a fullword, placed by the
exit module, that contains the address of the record in a user-owned
buffer, for the GET operation.
'str2' applies only to OPEN. The first halfword (on a halfword boundary) contains the length of the string; the string follows. |
| 16 | User-exit work area | 4-fullword work area provided by the compiler for use by user-exit module. |
| 32 | Text-name | Fullword that contains the address of a null-terminated string that contains the fully qualified text-name. Applies only to FIND. |
| 36 | User exit parameter string | Fullword that contains the address of a four-element array, each element of which is a structure that contains a 2-byte length field followed by a 64-character string that contains the exit parameter string. |
Only the second element of the parameter string array is used for LIBEXIT, to store the length of the LIBEXIT parameter string followed by the parameter string.
When INEXIT is specified, the compiler loads the exit module (mod1) during initialization, and invokes the module using the OPEN operation code (op code). This allows the module to prepare its source for processing and then pass the status of the OPEN request back to the compiler. Subsequently, each time the compiler requires a source statement, the exit module is invoked with the GET op code. The exit module then returns either the address and length of the next statement or the end-of-data indication (if no more source statements exist). When end-of-data is presented, the compiler invokes the exit module with the CLOSE op code so that the module can release any resources that are related to its input.
The compiler uses a parameter list to communicate with the exit module. The parameter list consists of 10 fullwords. The return code, data length, and data parameters are placed by the exit module for return to the compiler; and the other items are passed from the compiler to the exit module.
The table shows the contents of the parameter list and a description of each item.
When LIBEXIT is specified, the compiler loads the exit module (mod2) during initialization. Calls are made to the module by the compiler to obtain copybooks whenever COPY or BASIS statements are encountered.
Use LIB: If LIBEXIT is specified, the LIB compiler option must be in effect.
The first call invokes the module with an OPEN op code. This allows the module to prepare the specified library-name for processing. The OPEN op code is also issued the first time a new library-name is specified. The exit module returns the status of the OPEN request to the compiler by passing a return code.
When the exit invoked with the OPEN op code returns, the exit module is then invoked with a FIND op code. The exit module establishes positioning at the requested text-name (or basis-name) in the specified library-name. This becomes the “active copybook.” When positioning is complete, the exit module passes an appropriate return code to the compiler.
The compiler then invokes the exit module with a GET op code, and the exit module passes the compiler the length and address of the record to be copied from the active copybook. The GET operation is repeated until the end-of-data indicator is passed to the compiler.
When end-of-data is presented, the compiler will issue a CLOSE request so that the exit module can release any resources related to its input.
Nested COPY statements: Any record from the active copybook can contain a COPY statement. (However, nested COPY statements cannot contain the REPLACING phrase, and a COPY statement with the REPLACING phrase cannot contain nested COPY statements.) When a valid nested COPY statement is encountered, the compiler issues a request:
The compiler does not allow recursive calls to text-name. That is, a copybook can be named only once in a set of nested COPY statements until the end-of-data for that copybook is reached.
When the exit module receives the OPEN or FIND request, it should push its control information concerning the active copybook onto a stack and then complete the requested action (OPEN or FIND). The newly requested text-name (or basis-name) now becomes the active copybook.
Processing continues in the normal manner with a series of GET requests until the end-of-data indicator is passed to the compiler.
At end-of-data for the nested active copybook, the exit module should pop its control information from the stack. The next request from the compiler will be a FIND, so that the exit module can reestablish positioning at the previous active copybook.
The compiler now invokes the exit module with a GET request, and the exit module must pass the same record that was passed previously from this copybook. The compiler verifies that the same record was passed, and then the processing continues with GET requests until the end-of-data indicator is passed.
The table shows the contents of the parameter list used for LIBEXIT and a description of each item.
When PRTEXIT is specified, the compiler loads the exit module (mod3) during initialization. The exit module is used in place of the SYSPRINT data set.
The compiler invokes the module using the OPEN operation code (op code). This allows the module to prepare its output destination for processing and then pass the status of the OPEN request back to the compiler. Subsequently, each time the compiler has a line to be printed, the exit module is invoked with the PUT op code. The compiler supplies the address and length of the record that is to be printed, and the exit module returns the status of the PUT request to the compiler by a return code. The first byte of the record to be printed contains an ANSI printer control character.
Before the compilation is ended, the compiler invokes the exit module with the CLOSE op code so that the module can release any resources that are related to its output destination.
The table shows the contents of the parameter list used for PRTEXIT and a description of each item.
When ADEXIT is specified, the compiler loads the exit module (mod4) during initialization. The exit module is called for each record written to the SYSADATA data set.
The compiler invokes the module using the OPEN operation code (op code). This allows the module to prepare for processing and then pass the status of the OPEN request back to the compiler. Subsequently, each time the compiler has written a SYSADATA record, the exit module is invoked with the PUT op code. The compiler supplies the address and length of the SYSADATA record, and the exit module returns the status of the PUT request to the compiler by a return code.
Before the compilation is ended, the compiler invokes the exit module with the CLOSE op code so that the module can release any resources.
The table shows the contents of the parameter list used for ADEXIT and a description of each item.