# Compaq COBOL
User Manual

Previous | Contents | Index

# 12.7 Calling Non-COBOL Programs from Compaq COBOL

Because the Compaq COBOL compiler is part of a common language environment, a Compaq COBOL program can call a procedure written in another language available in this environment. This communication among high-level languages exists because these languages adhere to the OpenVMS Calling Standard or the Tru64 UNIX Calling Standard for Alpha Systems, as applicable, when generating a call to a procedure. Section 13.2 briefly describes the OpenVMS calling standard.

On OpenVMS Alpha, for more information, refer to the material on calling system routines in the OpenVMS Programming Concepts Manual, the OpenVMS RTL Library (LIB$) Manual, and the OpenVMS System Services Reference Manual. <>

## 12.7.1 Calling a Fortran Program

Calling a procedure written in Fortran allows you to take advantage of features of that language. Example 12-13 demonstrates how to call a non-COBOL program in the run unit.

Example 12-13 Calling a Fortran Program from a COBOL Program

    IDENTIFICATION DIVISION.
    PROGRAM-ID.   GETROOT.
    ****************************************************
    * This program accepts a value from the terminal,  *
    * calls the Fortran subroutine SQROOT, and passes  *
    * the value as a character string. Program         *
    * SQROOT returns the square root of the value.     *
    ****************************************************
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  INPUT-NUMBER.
        03  INTEGER       PIC 9(5).
        03  DEC-POINT     PIC X(1).
        03  DECIMAL       PIC 9(8).
    01  WORK-NUMBER.
        03  INTEGER       PIC 9(5).
        03  DECIMAL       PIC 9(8).
    01  WORK-NUMBER-A REDEFINES WORK-NUMBER  PIC 9(5)V9(8).
    01  DISPLAY-NUMBER    PIC ZZ,ZZ9.9999.
    PROCEDURE DIVISION.
    STARTER SECTION.
    SBEGIN.
       MOVE SPACES TO INPUT-NUMBER.
       DISPLAY "Enter number (with decimal point): "
         NO ADVANCING.
       ACCEPT INPUT-NUMBER.
       IF INPUT-NUMBER = SPACES
         GO TO ENDJOB.
       CALL "SQROOT" USING BY DESCRIPTOR INPUT-NUMBER.
       IF INPUT-NUMBER = ALL "*"
         DISPLAY "** INVALID ARGUMENT FOR SQUARE ROOT"
       ELSE
         DISPLAY "The square root is: " INPUT-NUMBER
         INSPECT INPUT-NUMBER
           REPLACING ALL " " BY "0"
         MOVE CORRESPONDING INPUT-NUMBER TO WORK-NUMBER
         WORK-NUMBER-A TO DISPLAY-NUMBER
         DISPLAY DISPLAY-NUMBER.
       GO TO SBEGIN.
    ENDJOB.
       STOP RUN.

Example 12-14 shows the Fortran program SQROOT called by the program in Example 12-13 and sample output from the programs' execution.

The SQROOT subroutine accepts a 14-character string and decodes it into a real variable (DECODE is analogous to an internal READ). It then calls the SQRT function in the statement that encodes the result into the 14-character argument.

Example 12-14 Fortran Subroutine SQROOT

          SUBROUTINE SQROOT(ARG)
          CHARACTER*14 ARG
          DECODE(14,10,ARG,ERR=20)VAL
    10    FORMAT(F12.6)
          IF(VAL.LT.0.)GO TO 20
          ENCODE(14,10,ARG)SQRT(VAL)
    999   RETURN
    20    ARG='**************'
          GO TO 999
          END

Sample Run of GETROOT (OpenVMS)

    $ RUN GETROOT [Return]
    Enter number (with decimal point): 25. [Return]
    The square root is:     5.000000
         5.0000
    Enter number (with decimal point): )HELLO [Return]
    ** INVALID ARGUMENT FOR SQUARE ROOT
    Enter number (with decimal point): 1000000. [Return]
    The square root is:  1000.000000
    1,000.0000
    Enter number (with decimal point): 2. [Return]
    The square root is:     1.414214
         1.4142
    Enter number (with decimal point): [Return]
    $                                                   <>

## 12.7.2 Calling a BASIC Program

The rich, yet easily accessed features of BASIC make that language a natural environment for development of short routines to be called from COBOL. Example 12-15 shows one example of a Compaq COBOL program that calls a BASIC program.

Example 12-15 Calling a BASIC Program from a COBOL Program

    IDENTIFICATION DIVISION.
    PROGRAM-ID.    APPL.
    ******************************************************
    * This  COBOL program accepts credit application     *
    * information and passes this information to a BASIC *
    * program that performs a credit analysis. Notice    *
    * that the data passed to the BASIC program is in    *
    * the standard binary format.                        *
    ******************************************************
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  APPLICATION-NUMBER   PIC 999.
    01  C-APPLICATION-NUMBER PIC 9(3) COMP.
    01  ANNUAL-SALARY        PIC 9(5).
    01  C-ANNUAL-SALARY      PIC 9(5) COMP.
    01  MORTGAGE-RENT        PIC 999.
    01  C-MORTGAGE-RENT      PIC 9(3) COMP.
    01  YEARS-EMPLOYED       PIC 99.
    01  C-YEARS-EMPLOYED     PIC 9(2) COMP.
    01  YEARS-AT-ADDRESS     PIC 99.
    01  C-YEARS-AT-ADDRESS   PIC 9(2) COMP.
    PROCEDURE DIVISION.
    010-BEGIN.
        DISPLAY "Enter 3 digit application number".
        ACCEPT APPLICATION-NUMBER.
        IF APPLICATION-NUMBER = 999
        DISPLAY "All applicants processed" STOP RUN.
        MOVE APPLICATION-NUMBER TO C-APPLICATION-NUMBER.
        DISPLAY "Enter 5 digit annual salary".
        ACCEPT ANNUAL-SALARY.
        MOVE ANNUAL-SALARY TO C-ANNUAL-SALARY.
        DISPLAY "Enter 3 digit mortgage/rent".
        ACCEPT MORTGAGE-RENT.
        MOVE MORTGAGE-RENT TO C-MORTGAGE-RENT.
        DISPLAY "Enter 2 digit years employed by current employer".
        ACCEPT YEARS-EMPLOYED.
        MOVE YEARS-EMPLOYED TO C-YEARS-EMPLOYED.
        DISPLAY "Enter 2 digit years at present address".
        ACCEPT YEARS-AT-ADDRESS.
        MOVE YEARS-AT-ADDRESS TO C-YEARS-AT-ADDRESS.
        CALL "APP" USING BY REFERENCE C-APPLICATION-NUMBER
        C-ANNUAL-SALARY C-MORTGAGE-RENT
        C-YEARS-EMPLOYED C-YEARS-AT-ADDRESS.
        GO TO 010-BEGIN.

Example 12_16 shows the BASIC program APP called in Example 12-15, and sample output from the program's execution.

Example 12-16 BASIC Program "APP" and Output Data

    10 SUB APP (A%,B%,C%,D%,E%)
    40 IF A% = 999 THEN 999
    50 IF B% => 26000 THEN 800
    60 IF B% => 18000 THEN 600
    70 IF B% > 15000 THEN 500
    80 IF B% => 10000 THEN 400
    90 GO TO 700
    400 IF E% < 4 THEN 800
    410 IF D% < 2 THEN 800
    420 GO TO 800
    500 IF E% < 4 THEN 700
    510 GO TO 800
    600 LET X% = B% / 12
    650 IF C% => X%/4 THEN 670
    660 GO TO 800
    670 IF E% => 4 THEN 800
    700 PRINT TAB(1);"APPLICANT NUMBER ";A%; " REJECTED"
    710 GO TO 999
    800 PRINT TAB(1);"APPLICANT NUMBER ";A%;" ACCEPTED"
    999 SUBEND

Sample Run of APPL

    $ RUN APPL
    Enter 3 digit application number
    376 [Return]
    Enter 5 digit annual salary
    35000 [Return]
    Enter 3 digit mortgage/rent
    461 [Return]
    Enter 2 digit years employed by current employer
    03 [Return]
    Enter 2 digit years at present address
    05 [Return]
    APPLICANT NUMBER  376  ACCEPTED
    Enter 3 digit application number
    999 [Return]
    All applicants processed

## 12.7.3 Calling a C Program

Calling a program or routine that is written in C allows you to take advantage of features of that language. Example 12-17 features a C routine that can be called from a COBOL program.

Example 12-17 has two global external variables, __Argc and **__Argv. Note that **__Argv[] has an extra level of indirection; it is a pointer to a pointer to an array.

Example 12-17 C Routine to Be Called from a COBOL Program

    /* crtn - c function to test use of argc and argv in c routines
     *   called from Compaq COBOL  */

    #include "cobfunc.h"
    #include <stdio.h>

    extern int _ _Argc;
    extern char **_ _Argv[];
    #define argc _ _Argc
    #define argv (*_ _Argv)

    void crtn()
    {
     int i;

     i = 0;
     for (i = 0; i < argc; i++) {
      printf("argv[%d] = %s\n", i, argv[i]);
     }
    }

Example 12-18 is a representation of how you can call a C program from your Compaq COBOL application. In this case, the C routine crtn (in Example 12-17) is called.

Example 12-18 Calling a C Program from a COBOL Program

           IDENTIFICATION DIVISION.
           PROGRAM-ID. CTEST.
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           .
           .
           .

           PROCEDURE DIVISION.
           MAIN SECTION.
           A001-MAIN.
           .
           .
           .
               CALL "crtn".
               EXIT PROGRAM.
           END PROGRAM CTEST.

For information on handling LIB$INITIALIZE when calling a C program, see Appendix B.

# 12.8 Special Considerations for Interprogram Communication

Certain situations require special consideration when your programs will communicate with other programs.

## 12.8.1 CALL and CANCEL Arguments

The CALL verb with a data item and the CANCEL verb with either a literal or a data item are implemented by a Run-Time Library routine that finds the appropriate program.

On Tru64 UNIX, these language features are implemented using `nlist` . Because of this implementation, the following items will not work on stripped images (for additional information on the `strip` command, refer to strip(1)):

- CALL data item
- CANCEL statement
- `cobcall` routine
- `cobcancel` routine
- `cobfunc` routine <>

On OpenVMS, these features are implemented by depositing information in compiler generated psects. <>

## 12.8.2 Calling OpenVMS Alpha Shareable Images (OpenVMS)

When calling a subprogram installed as a shareable image, the program name specified in the CALL statement can be either a literal or a data-name. The same is true for the CANCEL verb. For more information on shareable images refer to Compaq COBOL online help file and the OpenVMS Linker Utility Manual. <>

## 12.8.3 Calling Tru64 UNIX Shareable Objects (Tru64 UNIX)

When you call a subprogram contained in a shared object, the program name specified in the CALL statement must be a literal. The CANCEL verb cannot be applied to programs in shared objects. For more information on shared objects, refer to the Tru64 UNIX programming documentation.

## 12.8.4 Case Sensitivity on Tru64 UNIX

One difference between Tru64 UNIX and OpenVMS Alpha is case sensitivity. From program code creation, to your application internal operations, you must maintain an awareness of this issue when you consider porting COBOL source code between the platforms.

### 12.8.4.1 Linker Case Sensitivity

The linker on Tru64 UNIX is case sensitive. "JOB1" is not the same routine as "job1". However, COBOL is defined as a case insensitive language: CALL "job1" should invoke a routine whose PROGRAM-ID is JOB1. This is not true of case sensitive languages, such as C. The names option flag increases the flexibility of the Compaq COBOL compiler in communicating with case sensitive languages.

The names option has three values:

- lower---Forces all external data names, PROGRAM-ID names, and CALL literals to be lowercase. This is the default.
- upper---Forces all external data names, PROGRAM-ID names, and CALL literals to be uppercase.
- as_is---The case of literals used in CALL literals is taken as is. This is useful when you are calling subroutines with mixed case (for example, GetStatusRoutine). Data items defined with EXTERNAL will be treated as lowercase. PROGRAM-ID names will be treated as uppercase.

The names option flag does not apply to the CANCEL verb or to the CALL verb used with a data item. These language features are meaningful only when both the calling program and the called program are Compaq COBOL programs.

### 12.8.4.2 Calling C Programs from Compaq COBOL on Tru64 UNIX

Because lowercase is the names option default, the names upper option is only required to call C functions whose names contain uppercase letters, as described in Table 12-2.

Table 12-2 C Routine Called by Statement: CALL" Job1"
FLAG, option | Routine Called
--- | ---
`-names lowercase` /names=lower | job1() {}
`-names uppercase` /names=upper | JOB1() {}
`-names as_is` /names=as_is | Job1() {}

For example, a Compaq COBOL program must be compiled with the names upper option to be able to call a C program named JOB1.

### 12.8.4.3 Calling COBOL Programs from C on Tru64 UNIX

The lower and upper options to the `-names` flag and /names= option apply to the PROGRAM-ID as well as to the literals used with CALL literal. This makes it possible for C programs to call Compaq COBOL programs with either lowercase or uppercase names, as described in Table 12-3.

Table 12-3 C Invocation to Call COBOL PROGRAM-ID" Job2"
FLAG, option | Routine Called
--- | ---
`-names lowercase` /names=lower | job2();
`-names uppercase` /names=upper | JOB2();
`-names as_is` /names=as_is | not possible

The lower(case) and upper(case) options to the `-names` flag and /names= option preserve the semantics of calls among Compaq COBOL programs. However, the as_is option does not preserve these semantics. For example, the following code fragment will have different behavior if compiled with as_is.

    PROGRAM ID JOB1.
    CALL "Job2."
    END-PROGRAM JOB1.
    PROGRAM ID JOB2.
    END-PROGRAM JOB2.

With the lower(case) and upper(case) options on the `-names` flag and /names= option, the program JOB2 will be called by JOB1. However, with the as_is option, the linker will look to resolve a call to "Job2"---which in this case is just as different as if it were named job3, WORLD99, or any other routine name other than JOB2. <>

## 12.8.5 Additional Information

On OpenVMS, for more detailed information on system services and Run-Time Library routines, refer to the following manuals in the OpenVMS documentation set:

- Material on calling system routines in the OpenVMS Programming Concepts Manual
- OpenVMS RTL Library (LIB$) Manual
- OpenVMS System Services Reference Manual

The following OpenVMS documentation mentioned in this chapter may also be of interest:

- OpenVMS Calling Standard
- Guide to Creating OpenVMS Modular Procedures <>

For more detailed information on programming in the Tru64 UNIX environment, refer to the following manuals in the Tru64 UNIX documentation set:

- Programmer's Guide
- Assembly Language Programmer's Guide
- The Calling Standard

Refer to also the following:

- The man pages for information on system service routines in Tru64 UNIX.
- Reading an Indexed File from Other Languages on Tru64 UNIX section in Chapter 6 of this manual
- Compaq COBOL Reference Manual, CALL and CANCEL sections <>

# Chapter 13
Using Compaq COBOL in the Alpha or VAX Common Language Environment

The Compaq COBOL compiler is part of the common language environment. This environment defines certain calling procedures and guidelines that allow you to call programs written in different languages or prewritten system routines from Compaq COBOL. You can call the following routine types from Compaq COBOL:

- Subprograms written in other languages supported by Alpha or VAX
- Run-Time Library routines
- OpenVMS system services
- Tru64 UNIX library routines

On Tru64 UNIX, your Compaq COBOL programs can also call routines written in other languages, including system services routines on Tru64 UNIX. These calls must conform to the Tru64 UNIX Calling Standard for Alpha Systems.

For information on Tru64 UNIX, refer to the Tru64 UNIX operating system documentation. Alternatively, use the `man -k` command to search through the man pages for topics. For example, to find all routines containing the string "curses," enter the following command:

    %  man -k curses

The operating system will display information similar to the following:

    curses (3)              - Library that controls cursor movement and windowing
    curses_intro (3)        - Introduction to the curses routines which optimizes
                              terminal screen handling and updating
    restartterm (3)         - Restart terminal for curses application        <>

# 13.1 Routines, Procedures, and Functions

The terms routine, procedure, and function are used throughout this chapter. A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name) and optionally an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value, whereas a function is a routine that returns a value by assigning that value to the function's identifier. In COBOL, routines are also referred to as subprograms and called programs.

System routines are prewritten operating system routines that perform common tasks, such as finding the square root of a number or allocating virtual memory. You can call any system routine from your program, provided that COBOL supports the data structures required to call the routine. The system routines used most often are Run-Time Library routines and system services.

For more information on system routines on OpenVMS Alpha, refer to the OpenVMS RTL Library (LIB$) Manual and the OpenVMS System Services Reference Manual. <>

# 13.2 The OpenVMS Calling Standard (OpenVMS)

The OpenVMS Calling Standard and OpenVMS Programming Interfaces: Calling a System Routine (an archived manual still available on the documentation CD-ROM) describe the concepts used by all OpenVMS Alpha and VAX languages for invoking routines and passing data between them. The following attributes are specified by the OpenVMS Calling Standard:

- Register usage
- Stack usage
- Function value return
- Argument list

The following sections discuss these attributes in more detail. The OpenVMS Calling Standard also defines such attributes as the calling sequence, the argument data types and descriptor formats, condition handling, and stack unwinding. These attributes are discussed in detail in the OpenVMS Programming Concepts Manual.

## 13.2.1 Register and Stack Usage (Alpha)

The OpenVMS Alpha architecture provides 32 general purpose integer registers (R0-R31) and 32 floating-point registers (F0-F31), each 64 bits in length. The OpenVMS Programming Interfaces: Calling a System Routine defines the use of these registers, as listed in Table 13-1.

Table 13-1 OpenVMS Alpha Register Usage
Register | Use
--- | ---
R0 | Function value return register (see also F0, F1)
R1 | Conventional scratch register
R2-R15 | Conventional saved registers
R16-R21 | Argument registers, one register per argument, additional arguments are placed on the stack
R22-R24 | Conventional scratch registers
R25 | Argument information (AI); contains argument count and argument type
R26 | Return address (RA) register
R27 | Procedure value (PV) register
R28 | Volatile scratch register
R29 | Frame pointer (FP)
R30 | Stack pointer (SP)
R31 | Read As Zero/Sink (RZ) register
PC | Program counter
F0,F1 | Function value return registers for floating-point values (F1 is used if floating-point data exceeds 8 bytes)
F2-F9 | Conventional saved registers for floating-point values
F10-F15 | Conventional scratch registers for floating-point values
F16-F21 | Argument registers for floating-point values (one per argument, additional arguments are placed on the stack)
F22-F30 | Conventional scratch registers
F31 | Read As Zero/Sink (RZ) register

A stack is a LIFO (last-in/first-out) temporary storage area that the system allocates for every user process. The system keeps information about each routine call in the current image on the call stack. Then, each time you call a routine, the system creates a structure on the stack, defined as a stack frame and further discussed in the OpenVMS Calling Standard and the OpenVMS Programming Interfaces: Calling a System Routine.

Previous | Next | Contents | Index