Sometimes an application is simple enough to be coded as a single, self-sufficient program. In many cases, though, an application's solution will consist of several programs bound together. A run unit includes one or more object programs, and may include object programs from languages other than COBOL. The first COBOL program to be executed in the run unit is usually the main program. When a run unit consists of several, separately compiled programs that call each other, the programs must be able to communicate with each other. They need to transfer control and usually need to have access to common data. The following sections describe the methods that accomplish this.
Another method that can be used for inter-program communication is the nesting of COBOL programs. This allows all the required subprograms for an application to be contained within the main program and thereby require only a single compilation.
Transferring Control to Another Program
In the Procedure Division, a main program can call a subprogram, and a subprogram may itself call yet another subprogram. The program that calls another program is referred to as the calling program, and the program it calls is referred to as the called program.
The called COBOL program starts executing at the top of the Procedure Division. (It is possible to specify another entry point where execution begins, using the ENTRY label in the called program. However, this is not a recommended practice in a structured program.) When the called program processing is completed, the program can either transfer control back to the calling program or end the run unit.
A called program must not directly or indirectly execute its caller (such as program X calling program Y; program Y calling program Z; and program Z then calling program X). This is called a recursive call. If you attempt to execute a recursive call to a COBOL program, the run unit will terminate abnormally (abend).
In a non-ClCS environment, the calling program and all called programs must all be compiled with either the RESIDENT or the NORESIDENT compiler option, unless the MIXRES run-time option has been specified.
Main Programs and Subprograms
No specific source code statements or options identify a COBOL program to be a main program or a subprogram. Normally, the first COBOL program to begin executing in a run unit becomes the run unit's main program. All other COBOL programs in the run unit are subprograms. Whether a COBOL program is a main program or a subprogram can be significant for either of two reasons:
A subprogram may end with an EXIT PROGRAM, a GOBACK, or a STOP RUN statement. If the subprogram ends with an EXIT PROGRAM or a GOBACK statement, control returns to its immediate caller without ending the run unit. An implicit EXIT PROGRAM statement is generated if there is no next executable statement in a called program. If the subprogram ends with a STOP RUN statement, the effect is the same as it is in a main program—all COBOL programs in the run unit are terminated, and control returns to the caller of the main program. Unpredictable results will occur if a VS COBOL II program has been called by a non-COBOL program and performs a STOP RUN while running under COBTEST. The storage used for the run unit fields will be deleted by the non-COBOL program.
Passing Return Codes (RETURN-CODE Special Register)
You can use the RETURN-CODE special register to pass return codes from called programs to calling programs. We will see how this is implemented for separately compiled programs and nested programs. For separately compiled programs, the RETURN-CODE special register is used to pass return codes from a subprogram to a main program and from a main program to the system. When a COBOL program returns to its caller, the contents of its RETURN-CODE special register are stored into register 15. When control is returned to a COBOL program from a call, the contents of register 15 are stored into the calling program's RETURN-CODE special register. When a COBOL program returns control to the operating system, the RETURN-CODE special register contents are returned as a user return code.
For nested programs, the RETURN-CODJ special register is treated like a numeric data item declared with the GLOBAL attribute in the outermost program. Unlike separately compiled programs, when nested programs are invoked, the RETURN-CODE special register is not initialized to zero.
Calling the Programs
You may use several different methods to transfer control to another program. These include:
In a non-ClCS environment, calls to programs in other languages, including PL/I, FORTRAN, and OS/VS COBOL.Calls to nested programs allow you to create applications using structured programming techniques. They can also be used instead of PERFORM procedures to prevent unintentional modification of data items. Calls to nested programs can be made using either the CALL literal or CALL identifier statement.
A static call is used to invoke a separately compiled program that is link-edited into the same load module as the calling program. A dynamic call is used to invoke a separately compiled program that has been link-edited into a separate load module from the calling program. In this case, the subprogram module is loaded into storage the first time it is called.
In a non-CICS environment, COBOL programs and non-COBOL programs can call and be called by PL/I, FORTRAN, and assembler language programs.
Nested programs give you a method to create modular functions, for your application and maintain structured programming techniques. They can be used as PERFORM procedures with the additional ability to protect 'local' data items.
Nested programs allow for debugging a program before including it in the application. You can also compile your application with a single invocation of the compiler. A COBOL program may contain other COBOL programs. The contained programs may themselves contain yet other programs. A contained program may be directly or indirectly contained within a program.
There are several conventions that apply when using nested program structures:
A contained program may only be called by its directly containing program, unless the contained program is identified as COMMON in its Program-Id clause. In that case, the COMMON program may also be called by any program that is contained (directly or indirectly) within the same program as the COMMON program. Only contained programs can be COMMON. Recursive calls are not allowed.
The following figure shows the outline of a nested structure with some contained programs identified as COMMON (programs A12, A2 and A3—marked black on the side and letters in bold).
The following table describes the 'calling hierarchy' for the structure that is shown in the following figure. Notice that programs A12, A2, and A3 are identified as COMMON and the resulting differences in calls associated with them. Note that:
A Nested Structure with COMMON Programs
There are two classes of names within nested structures—local and global. The class will determine whether a name is known beyond the scope of the program that declares it. There is also a specific search sequence for locating the declaration of a name after it is referenced within a program.
Any item that is subordinate to a global item (including condition names and indexes) is automatically global. The same name may be declared with the Global clause multiple times, provided that each declaration occurs in a different program. Be aware that masking, or hiding, a name within a nested structure is possible by having the same name occur within different programs of the same containing structure. This could possibly cause some problems when a search for a name declaration is taking place.
When a name is referenced within a program, a search is made to locate the declaration for that name. The search begins within the program that contains the reference and continues 'outward' to containing programs until a match is found. The search follows this process:
You should note that the search is for a global 'name,' not for a particular type of object associated with the name, such as a data item or file connector. The search stops when any match is found, regardless of the type of object. If the object declared is of a different type than what was expected, an error condition exists.
Static and Dynamic Calls
The following discussion applies to separately compiled subprograms only, not to nested (contained) programs. When a subprogram is called, it may already be in main storage having been link-edited in the same load module with the calling program (static call). Or it may be loaded only at the time it is called (dynamic call). With dynamic loading, the called program is loaded only when it is needed. The link-edit process differs, depending on whether your program uses static calls or dynamic calls.
Performance Considerations of Static and Dynamic Calls
Dynamic calls take more processing than static calls. However, a dynamic call may use less total storage than a static call. Storage usage depends on whether:
Sharing Data Using the EXTERNAL Clause
Separately compiled programs (including programs within abatch sequence) may share data items by use of the EXTERNAL clause. EXTERNAL is specified on the 01-level data description in the Working-Storage section of a program, and the following rules apply:
Any COBOL program within the run unit, having the same data description for the item as the program containing the item, can access and process the data item. Remember that any program that has access to an EXTERNAL data item can change its value. Do not use this clause for data items you need to protect. EXTERNAL data records are allocated in storage below the 16-megabyte line and thus can be referenced by A MODE(24) subprograms.
Passing Data BY REFERENCE or BY CONTENT
Passing data BY REFERENCE means that the subprogram is referring to and processing the data items in the calling program's storage, rather than working on a copy of the data.
Passing data BY CONTENT means that the calling program is passing only the contents of the literal or identifier. With a CALL ... BY CONTENT, the called program cannot change the value of the literal or identifier in the calling program, even if it modifies the variable in which it received the literal or identifier.
Whether you pass data items BY REFERENCE or BY CONTENT depends on what you want your program to do with the data:
Data items in a calling program can be described in the Linkage Section of all the programs it calls directly or indirectly. In this case, storage for these items is allocated in the highest calling program. That is, program A calls program B, which calls program C. Data items in program A can be described in the Linkage Sections of programs B and C, and the one set of data can be made available to all three programs. Do not pass parameters allocated in storage 16 megabytes to AMODE(24) subprograms; use the DATA(24) option.
In the calling program, the common data items are described in the Data Division in the same manner as other data items in the Data Division. Unless they are in the Linkage Section, storage is allocated for these items in the calling program. If you reference data in a file, the file must be open when the data is referred to. Code the USING clause of the CALL statement to pass the items.
In the called program, common data items are described in the Linkage Section. Code the USING clause after the PROCEDURE-DIVISION header to receive the data items.
You must know what is being passed from the calling program and set up the Linkage Section in the called program to accept it. To the called program, it does not matter which clause of the CALL statement you use to pass the data (BY REFERENCE or BY CONTENT). In either case, the called program must describe the data it is receiving. It does this in the Linkage Section.
The number of data-names in the identifier list of a called program must not be greater than the number of data-names in the identifier list of the calling program. There is a one-to-one positional correspondence; that is, the first identifier of the calling program is passed to the first identifier of the called program, and so forth. The compiler makes no attempt to correspond data-names by name.
Grouping Data to Be Passed
Consider grouping all the data items you want to pass between programs and putting them under one level-01 item. If you do this, you can pass a single level-01 record between programs. To make the possibility of mismatched records even smaller, put the level-01 record in a copy library, and copy it in both programs. (That is, copy it in the Working-Storage Section of the calling program and in the Linkage Section of the called program.)
IBM Mainframe Related Interview Questions
|IBM Lotus Notes Interview Questions||IBM-CICS Interview Questions|
|COBOL Interview Questions||Linux Interview Questions|
|IBM-JCL Interview Questions||IBM Mainframe Interview Questions|
|IBM AIX Interview Questions||IBM WAS Administration Interview Questions|
|IBM Lotus Domino Interview Questions||IBM Integration Bus Interview Questions|
|Mainframe DB2 Interview Questions||Unix Production Support Interview Questions|
All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd
Wisdomjobs.com is one of the best job search sites in India.