The CALL statement causes control to be transferred to another program. For a discussion of how the runtime handles program
calls, see Calling Subprograms. See Working with Windows Technologies and
Working with C and C++ Programs for information about calling subroutines in DLLs and UNIX shared libraries.
Format 1
CALL [IN THREAD] program-name
[ HANDLE IN handle-1 ]
[ USING { [ BY {REFERENCE} ] {parameter} size-phrase ...} ...]
{CONTENT } {OMITTED }
{VALUE } {NULL }
[ {RETURNING} INTO return-val ]
{GIVING }
[ ON {EXCEPTION} statement-1 ]
{OVERFLOW }
[ NOT ON {EXCEPTION} statement-2 ]
{OVERFLOW }
[ END-CALL ]
Format 2
where
size-phrase is:
[WITH MEMORY SIZE {= } memory-size]
{IS}
Format 3
CALL PROGRAM program-name
[ USING {parameter} ... ]
[ ON {EXCEPTION} statement-1 ]
{OVERFLOW }
[ END-CALL ]
Format 4 (HP COBOL)
CALL { identifier-1 } [ USING { \\ } ... ]
{ [ INTRINSIC ] literal-1 } { @identifier-2 }
{ identifier-2 }
{ literal-2 }
{ \identifier-2\ }
{ \literal-2\ }
[ GIVING identifier-3 ]
[ ON {EXCEPTION} statement-1 ]
{OVERFLOW )
[ NOT ON {EXCEPTION} statement-2 ]
{OVERFLOW )
[ END-CALL ] ]
Syntax Rules
Note: For Syntax Rules and General Rules specific to Format 4, see
HP COBOL Conversions in
Transitioning to ACUCOBOL-GT.
- program-name is a nonnumeric literal or an alphanumeric data item.
- handle-1 must be a USAGE HANDLE or HANDLE OF THREAD data item.
- The NULL and OMITTED options are synonymous.
- memory-size is a numeric literal or data item.
- parameter is any non-level 88 data item or a literal. It may be subscripted and reference modified. It may be the SELECT name of an
open COBOL file.
- statement-1 and
statement-2 are imperative statements.
- EXCEPTION and OVERFLOW are equivalent.
- The NOT EXCEPTION phrase may not be used when the PROGRAM option is used.
- return-val must specify a numeric data item.
- RETURNING and GIVING are synonymous.
General Rules
- program-name specifies the name of the called program. The exact procedure for resolving this name into the name of a program to call
is described in File Name Interpretation.
- The THREAD option starts a new thread before calling the target program. The called program executes in the new thread. The
calling program continues to execute in parallel. When the called program exits, its thread is terminated.
- The HANDLE phrase stores the ID of the thread in
handle-1 immediately after the new thread starts. This occurs before the USING parameters are evaluated, so that it is possible to
pass handle-1 to the called program.
- The parameters' order of appearance in the USING phrases of the CALL verb, and the called program's Procedure Division header,
determine the correspondence between the data names used in the called and calling programs. This correspondence is established
by position, not by name.
- The SIZE phrase is used when the parameter in the USING phrase is a memory address (pointer to memory) and you need to specify
the size of the piece of memory that is located at that address. The SIZE phrase supports the calling of DLLs on the display
host by thin client applications..
- The BY phrase controls how parameters are passed to the called program. The default method is BY REFERENCE. This method causes
the address of the data item to be passed to the receiving program. This is the only method of passing data available in versions
of ACUCOBOL-GT prior to 2.0.
The BY CONTENT phrase is similar to BY REFERENCE, except that the address of a copy of the data item is sent. This has the
effect that any changes made to the parameter in the called program are not seen by the caller. Starting with Version 2.0,
literals passed as parameters are automatically passed BY CONTENT.
The BY VALUE method causes the contents of the data item to be passed to the receiving program (the actual data, not its address).
This may not be specified if the receiving program is a COBOL program (results are undefined in this case). This method is
typically used to pass numeric data to C subprograms. For optimal portability we recommend that parameters being passed by
this method be level 01 or 77 items described as SIGNED-INT, UNSIGNED-INT, SIGNED-SHORT, UNSIGNED-SHORT, SIGNED-LONG, UNSIGNED-LONG,
or POINTER.
When the name of an open COBOL file is given as a parameter, the operating system's file handle is passed. One possible reason
for doing this is to call an operating system function that allows the file to retrieve some information that is not available
through COBOL. Several special rules apply to this usage. See rules 30 through 35 below.
- The NULL and OMITTED options are synonymous. They allow you to skip a parameter in a USING phrase. The corresponding parameter
in the called program must not be referenced. If the called program is a C program, then a NULL value is passed to the corresponding
parameter.
- Index names referred to in the Linkage Section of the called program do not correspond to any index names in the calling program.
Index data items are always stored in the local memory of their programs.
- If the called program does not have the INITIAL attribute, then it is in its initial state the first time it is called, and
the first time it is called after a CANCEL verb has referred to it. On all other calls, the program is in the same state as
when it last exited.
- If the called program has the INITIAL attribute, it is in its initial state every time it is called.
- Files contained in the called program are not open whenever the called program is in its initial state. Otherwise, the status
and positioning of the contained files is the same as when the program last exited.
- If the ON EXCEPTION phrase is present and the called program cannot be initiated, statement-1 executes. If the called program
cannot be initiated when there is no EXCEPTION phrase, a runtime error occurs and the program halts. A program cannot be initiated
if program-name cannot be resolved using the rules described in Calling Subprograms.
- If the NOT ON EXCEPTION phrase is present and the called program is successfully initiated,
statement-2 executes when the called program returns.
- The ON EXCEPTION and NOT ON EXCEPTION phrases execute in the original (parent) thread. The parent thread suspends long enough
to determine whether or not the CALL will succeed. This allows it to determine whether to execute the EXCEPTION or NOT EXCEPTION
case.
- A called program's file state and data items are distinct for each thread that exists at the time of the call (including the
thread created by the CALL THREAD). Thus, if
thread-1 calls
program-a, and
thread-2 calls
program-a, there will be two copies of the data from
program-a in memory, one set for each thread. Threads created in the called program, or any of its subprograms, share the called program's
data and file state.
- The CALL PROGRAM verb is similar to the CHAIN verb. It causes the current run unit to terminate and initiates a new run unit.
However, USING parameters are passed to data items specified in Linkage, just as they are for a standard CALL verb.
Some (incorrect) usages of the CALL statement USING parameters from the Linkage section of the called program can result in
so-called "intermediate" runtime errors that call installed error procedures. There currently are two such related errors:
Use of a LINKAGE data item not passed by the caller, and
Passed USING item smaller than corresponding LINKAGE item. A passed USING item that is larger than the corresponding Linkage item does not generate an error.
Another runtime error can occur when the CALL statement attempts USING parameters of invalid structure or missing parameters.
That kind of error is announced as
Invalid or missing parameter, and it is also an "intermediate" type of runtime error that calls installed error procedures.
See Appendix I. Library Routines for detailed discussion of the runtime error and exit procedures.
- When a CALL PROGRAM verb succeeds, all program switches are set to their
off state. You can specify switches to be set
on in the CALL PROGRAM statement. You accomplish this by specifying the switch names immediately after the program name in the
statement. Each switch name must be alphabetic and must be preceded by a slash (/). For example, to turn on switches "A" and
"B" you could use this statement:
CALL PROGRAM "MYPROG/A/B" USING ...
- If the CALL PROGRAM verb cannot find the called program, and no EXCEPTION phrase has been specified, control passes to the
next executable statement.
- The CALL PROGRAM verb accepts the presence of routines whose name begins with a "#" sign. When one of these routines is specified,
the CALL PROGRAM statement is ignored. In ICOBOL, routines with these names are special-purpose system routines.
- If the RUN option is used, then
program-name refers to the main program of another run unit. This run unit is initiated and continues until it executes a STOP RUN. At
that point, control is returned to the next executable sentence in the calling program. Parameters are passed to the called
run unit in the same manner as specified for the CHAIN statement.
The called run unit is logically distinct from the calling run unit. It may call programs that are active in the calling unit
without generating an error. External areas are associated with a logical run unit, so that a new run unit does not have access
to external areas created by the calling run unit. Take care that file records locked by the calling run unit do not interfere
with the called run unit, because there will be no opportunity for the caller to release its records while the called unit
is active.
type-ahead is retained both when the new run unit is called and upon return from it.
The precise amount of memory required for the runtime varies by platform and is affected by configuration variables such as
V_BUFFERS and by any products or C routines you have linked in. When the CALL RUN executes, the memory associated with the new run
unit is allocated, and the old run unit (with its attendant memory) remains active. Memory allocated by the runtime for program
code is freed automatically at the STOP RUN in the called program. Memory used for open windows and V_BUFFERS is not freed
until the runtime exits. You should explicitly free any memory that you allocated with the
M$ALLOC (Dynamic Memory Routine) otherwise this memory is not freed until the runtime exits.
- A special register named RETURN-CODE is automatically created by the compiler and is shared by all programs of a run unit.
This special register is defined as:
77 RETURN-CODE SIGNED-LONG, EXTERNAL.
If you call a C program via the
direct interface, the return value of the C function is placed into this register. If you call the SYSTEM library routine, the status
of the call is placed into this register. The verbs EXIT, STOP, and GOBACK can also place a value into the RETURN-CODE register.
The compiler also creates an unsigned version of the return code called RETURN-UNSIGNED. It has the following implied definition:
77 RETURN-UNSIGNED
REDEFINES RETURN-CODE
UNSIGNED-LONG, EXTERNAL.
- If the RETURNING phrase is used, then the
return value of the called program is moved to
return-val. This is accomplished by the following rule:
- If
return-val is a signed data item, then the value of RETURN-CODE is moved to
return-val according to the rules of the MOVE statement.
- If
return-val is unsigned, then RETURN-UNSIGNED is moved instead.
- You should avoid using RETURN-CODE or RETURN-UNSIGNED for return-val. This is pointless because, after assigning a value to return-val, the CALL statement restores the previous value of RETURN-CODE.
- On Windows systems, if you CALL a DLL, the runtime assumes that the DLL returns a
long (at least 32 bits of data). This ensures that all of the data returned from the DLL is captured. However, in situations where
the DLL returns less than 32 bits of data (such as a DLL that returns a
short), some of the data might be random. To get the right size for the return value of DLLs, use the RETURNING phrase and set
the receiving variable to the same size as the DLL's return value. The easiest way to do this is to declare the receiving
variable to be the same type as the DLL's return type. For example, if the DLL
MYDLL returns an
int, you could do the following:
77 RETURN-VAL SIGNED-INT.
CALL "MYDLL" RETURNING RETURN-VAL.
- After
return-val is set, RETURN-CODE is set to the value it had immediately prior to the CALL statement. Thus the called program does not
affect the value of RETURN-CODE in the calling program.
- If the CALL statement fails with an exception, then
return-val is not updated.
- You may pass
floating-point data to subroutines normally with the CALL verb. Note that you may not pass a
floating-point item BY VALUE. This restriction exists for portability reasons (some machines pass
floating-point using a convention different from that used for integer items). You should pass floating-point items BY REFERENCE. This will
pass a pointer to the item, which the receiving routine can then retrieve by
de-referencing the pointer.
- A program may directly or indirectly call itself. A CALL statement that calls the active program (itself) is a recursive call.
For more information, see the
RECURSION configuration variable. For information on sharing data in recursively called programs (such as in the HP COBOL environment),
see the
RECURSION_DATA_GLOBAL configuration variable.
- Errors that occur as a result of the CALL statement USING parameters from the Linkage section of the called program belong
to an
intermediate type of runtime errors that call installed error procedures. There are two such errors:
Use of a LINKAGE data item not passed by the caller, and
Passed USING item smaller than corresponding LINKAGE item.
Passing File Handles
- For compatibility with HP COBOL, a file handle is automatically passed BY VALUE unless it is immediately preceded by a BY
REFERENCE or BY CONTENT specification. File handles passed to COBOL subroutines must be preceded with BY REFERENCE or BY CONTENT
because COBOL routines cannot take BY VALUE parameters.
- If the called subroutine is a COBOL routine, the handle passed is PIC S9(4) COMP-5. You can override this with the compiler
option
--fileIdSize=# where
# is either
2,
4, or
8 to specify the number of bytes you want in the passed integer.
- If the called subroutine is not COBOL, the handle is passed as a signed native integer using the host's default integer size.
- The file handle passed is the host file system's identifying value for the open file. For all current implementations, this
is the value returned by the C
open function. If the host file system does not have this information available, then
-1 is used instead. This can happen if the host system is not a file (e.g. Acu4GL for Oracle) or the host system does not provide
a way of obtaining the handle (e.g. C-ISAM interface). Files served by AcuServer® also use
-1 because there is no useful way to use a remote process' open file handle.
- For Vision files in the multi-file format (Version 5 and 4), the handle used is the handle of the first data segment (this
is the same file used when opening the file).
- It is best to avoid performing actual I/O on the file using this file handle because the COBOL file system will be unaware
of any state changes to the file and may perform incorrectly. It is possible to corrupt data this way.