Note: the following was provided to me by AcuCORP Technical Support and was supposedly posted on comp.lang.cobol, though I don't find it there via Google search.
Using a æCÆ Main Program with ACUCOBOL-85
1. Introduction
ACUCOBOL-85 uses a runtime system to execute its compiled COBOL programs. This runtime system is a fully linked executable program and, as such, contains its own main routine. The runtime also assumes that the first program to run will be a COBOL program.
You may wish to replace the runtimeÆs own main routine with another. For example, you may wish to have a ôserverö program that waits for requests from clients and then calls COBOL subroutines to handle those requests. In this case, you might want to have your own æCÆ main routine that initiates the server and waits for client requests which it then dispatches.
This document describes how to replace the runtimeÆs main routine with your own. It also describes the effects in ACUCOBOL-85 when you do not have a COBOL main program (that is, when all of your COBOL programs are subprograms). This document assumes that you are familiar with the ACUCOBOL-85 æCÆ interface as described in Appendix C of the
ACUCOBOL-85 manual.
2. Creating the Runtime
The ACUCOBOL-85 runtime library (used to relink the runtime system) comes with its own main routine. The library contains this routine in a separate object module. To create a runtime system that has your own main routine, you simply add a routine called ômainö to your æCÆ source files and recreate the runtime. Since the linker uses your æCÆ object files before searching the library, your main routine will be used and the one in the library will not be linked.
To relink the runtime system, follow the instructions found in Appendix C of the ACUCOBOL-85 manual. On a UNIX machine, this consists of adding your source files to the ôSUBSö line of the provided ômakefileö and typing ômakeö. Other machines use slightly different techniques.
3. Initializing the Runtime
Prior to calling any COBOL programs from your æCÆ code, you must initialize the runtime. To do this call the following routine:
int
acu_initv( argc, argv )
int argc;
char *argv[];
You pass this routineÆs arguments in a format identical to those passed to the æCÆ main function. Argc should be the number of arguments passed in argv. It must be at least ô1ö. Argv is an array of the arguments. It must contain at least one argument in argv[0]. This should be a pointer to the name of the executable file û in other words, the same as argv[0] passed to your own main routine.
No other arguments are required. If you wish to pass additional arguments, format them in the same manner as a typical runcbl command line. Arguments to the runtime should come first, followed by the COBOL programÆs name, followed by any arguments to that COBOL program.
The COBOL programÆs name is used during initialization to determine the default title of any GUI-based window, but the program itself is not loaded or executed. Arguments to the COBOL program are not used by initialization and may be omitted. If you omit the COBOL program name, initialization will occur using the default name of ôcbl.outö.
Acu_initv calls the user-supplied routines exam_args (passing argc and argv) and Startup (passing the name of the COBOL program). These routines are normally empty, but may be modified by you. They can be found in the file ôsub.cö supplied with the runtime system.
Acu_initv returns the argument number of the COBOL program name in argv (or the value of argc if there isnÆt one). The runtimeÆs own main routine uses this to easily locate the name of the program to load. If there is an error during initialization, acu_initv does not return (it prints an error message and shuts down the process).
Acu_initv performs all of the initialization needed to run a COBOL program. This includes
Loading the COBOL configuration file, initializing the userÆs station and initializing each of
the available file systems.
3.1 Example
The following code might be used by a server routine that intends to use COBOL subroutnes to perform various file operations. In this scenario, no screen operations will be done from COBOL and, thus, we want to inhibit ACUCOBOLÆs default screen initialization. To do this, we must pass the ô-bö command-line option. Since the program will perform no screen operations, we do not care about the default window title and, thus, do not need to pass a COBOL program name.
int
main( argc, argv )
int argc;
char *argv[];
{
char *initv[2];
When calling a COBOL routine, you may either start a COBOL main program (which is what the runtime normally does), or you may just call COBOL subroutines.
4.1 Starting a COBOL Main Program
You may start a COBOL main program by calling the following routine:
void
acu_runmain( argc, argv, program_arg )
int argc;
char *argv[];
int program_arg;
This routine initiates a COBOL main program. It never returns. Argc and argv are main-style arguments. Typically, they are the same as the ones passed to acu_initv. Program_arg is the argument number (in argv) of the name of the COBOL program. If you omit the COBOL program name (defaulting to ôcbl.outö), then program_arg should be the same as argc. Any arguments in argv following program_arg are passed as CHAINING arguments to the COBOL program. Note that program_arg is usually the same as the return value from acu_initv.
The arguments in argv before program_arg are not actually used in acu_runmain. This form is simply used for calling convenience. As an example, the following is the entire text of the runtimes own main routine:
The ôreturn 0ö is never executed. It is there to eliminate warnings from some æCÆ compilers.
4.2 Calling COBOL Subroutines
If you wish to call COBOL subroutines directly from æCÆ, follow the instructions for using cobol function described in Appendix C of the ACUCOBOL-85 manual. You may use the cobol routine anytime after acu_initv has been called.
You do not need to start a COBOL main program to call COBOL subroutines. If you use a æCÆ main program, note that certain COBOL verbs can prevent you from returning from a called COBOL subroutine to your æCÆ main program. This is discussed in section 7 below.
4.3 Canceling a COBOL Subroutine
If you wish to simulate the COBOL CANCEL verb from æCÆ, you may do so by calling the following routine:
void
acu_cancel( program )
char *program;
You pass this routine the name of the program you wish to cancel. This should be identical to the string that you passed to the cobol function to call that program. Canceling a program releases the memory it occupies and resets its internal data to its initial state if you call the program again. Also, any files left open in the program are closed. If program does not match the name of any COBOL program in memory, then nothing happens when you call this routine.
5. Runtime Shutdown
You may halt the runtime from COBOL by executing a STOP RUN statement. If you do this, the runtime will terminate normally. Note that this will cal the user-supplied æCÆ routine called ôShutdownö found in ôsub.cö.
If you wish to halt the runtime from æCÆ, you should call the following routine:
void
acu_shutdown( place_cursor )
int place_cursor;
This routine will perform all the necessary exit handling needed by the runtime. It will insure that all COBOL files are closed and that the screen is returned to its normal operating state. After acu_shutdown returns, you should not call any COBOL subroutines again during this run.
If you pass a non-zero value in place_cursor, then the runtime will place the screenÆs cursor on the last line of the screen and scroll the screen one line. This is the normal behavior that you see when you execute a STO P RUN. If you pass a zero in place_cursor, then the cursor is not moved and the screen is not changed. Note that the place_cursor variable overrides any setting given by the ACUCOBOL configuration variable EXIT-CURSOR, which also controls the handling of the cursor at shutdown.
6. Example
Here is a complete æCÆ program that calls a single COBOL routine once passing it one argument. After the COBOL routine returns, it cancels that program and halts. While it is not necessary to cancel the program in this example, the code is shown for completeness.
data division.
linkage section.
77 hello-world pic x(11).
procedure division using hello-world.
main-logic.
display hello-world.
exit program.
7. Notes on COBOL Verbs
7.1 CALL and CALL RUN
You may use the CALL and CALL RUN verbs normally. You return from a CALL with EXIT PROGRAM and from a CALL RUN with STOP RUN. See the ACUCOBOL-85 manual for details about these verbs.
7.2 EXIT PROGRAM
You may also use the EXIT PROGRAM verb normally. Use EXIT PROGRAM to return from a COBOL subroutine to the æCÆ function that called it.
7.3 STOP RUN
As mentioned in a previous section, a STOP RUN will cause a runtime shutdown (except in the case where STOP RUN returns to a CALL RUN statement). If you need to control the shutdown in æCÆ (to perform clean-up for example), make certain that you do not code any STOP RUN statements. Alternatively, you can place any clean-up code you need in the ôShutdownö routine found in ôsub.cö. This routine is automatically executed during runtime shutdown.
7.4 CHAIN and CALL PROGRAM
Both the CHAIN and CALL PROGRAM verbs halt the current run unit and initiate a new run unit. Use these verbs with care as they prevent you from ever returning to your æCÆ main program. The reason is that the chained-to COBOL program is now treated as the start of a new run unit. Essentially, this means that it acts like a main program. Since it is treated like a main program, the EXIT PROGRAM verb is ignored in it. The only way to halt the program is with a STOP RUN (which halts the entire runtime) or with another chain.
If you do execute CHAIN or CALL PROGRAM, any æCÆ routines that are part of the calling stack leading to the first COBOL subroutine will be left in place. Although you cannot access these routines, their stack memory remains allocated. On the other hand, any æCÆ subroutines that are on the call stack after the first COBOL subroutine will be removed from the stack.
There is one case where you can still return to your æCÆ routine after executing a CHAIN. This case occurs when you use the CALL RUN verb to initiate a new run unit without halting the original. The new run unit can use CHAIN. When the new run unit finally executes a STOP RUN, control returns to the original run unit, which may still return to your æCÆ routine via an EXIT PROGRAM.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.