HP OpenVMS Systems Documentation

Content starts here

HP COBOL
User Manual


Previous Contents Index

12.5.2.3 Sharing USE Procedures

The USE statement specifies declarative procedures to handle input/output errors. It also can specify procedures to be executed before the program processes a specific report group.

More than one USE AFTER EXCEPTION procedure in any given program can apply to an input/output operation when there is one procedure for file name and another for the applicable open mode. In this case, only the procedure for file name executes. Figure 12-5 shows that FILE-NAME-PROBLEM SECTION executes.

Figure 12-5 Sharing USE Procedures


At run time, two special precedence rules apply for the selection of a declarative when programs are contained in other programs. In applying these two rules, only the first qualifying declarative is selected for execution. The order of precedence for the selection of a declarative follows:

Rule 1 ---The declarative that executes first is the declarative within the program containing the statement that caused the qualifying condition. In Figure 12-6, FILE-NAME-PROBLEM procedure executes.

Figure 12-6 Executing Declaratives with Contained Programs (Rule 1)



Rule 2 ---If a declarative is not found using Rule 1, the Run-Time System searches all programs directly or indirectly containing that program for a global use procedure. This search continues until the Run-Time System either: (1) finds an applicable USE GLOBAL declarative, or (2) finds the outermost containing program. Either condition terminates the search; the second condition terminates both the search and the run unit.

Figure 12-7 shows applicable USE GLOBAL declaratives found in a containing program before the outermost containing program. Note that the first OPEN goes to the mode-specific procedure in the USE-PROGRAM rather than the file-specific procedure in the MAINPROG-PROGRAM.

Figure 12-7 Executing Declaratives Within Contained Programs (Rule 2)


For information on the negative effect of USE procedures that reference LINKAGE SECTION items on compiler optimization, see Section 15.5.4.

12.5.2.4 Sharing Other Resources

Condition names, record names, and report names can also have the global attribute. Any program directly or indirectly contained within the program declaring the global name can reference the global name.

A condition name declared in a Data Description entry is global if the condition-variable it is associated with is a global name.

A record name is global if the GLOBAL clause is specified in the Record Description entry by which the record name is declared, or in the case of Record Description entries in the File Section, if the GLOBAL clause is specified in the File Description entry for the file name associated with the Record Description entry.

A report name is global if the GLOBAL clause is specified in the Report Description entry by which the report name is declared. In addition, if the Report Description entry contains the GLOBAL clause, the special registers LINE-COUNTER and PAGE-COUNTER are global names.

Because you cannot specify a Configuration Section for a program contained within another program, the following types of user-defined words are always global; that is, they are always accessible from within a contained program:

  • Alphabet-name
  • Class-name
  • Condition-name
  • Mnemonic-name
  • Symbolic-character

These user-defined words can be referenced by statements and entries either in the program that contains the Configuration Section or any program contained in that program.

12.6 Calling HP COBOL Programs from Other Languages (Alpha, I64)

The CALL and CANCEL verbs allow you to call and cancel HP COBOL programs (including routines and separately compiled program units) from within an HP COBOL program. The cobcall , cobcancel , and cobfunc RTL calls allow you to call and cancel those programs from programs written in other languages.

When you use cobcall , cobcancel , and cobfunc , the same considerations and results will be in effect as if you had used the CALL and CANCEL statements (see Section 12.1.2 and Section 12.3).

If you need both a CANCEL (to reinitialize data) and a CALL, you can code it with a single cobfunc call. cobfunc is essentially a jacket that calls cobcancel and cobcall .

Table 12-1 shows these calls and their basic differences.

Table 12-1 Calls to COBOL Programs (Alpha, I64)
RTL Call Function
cobcall Calls a COBOL program. Program variables remain in their last state.
cobcancel Cancels a COBOL program. Program variables are reset.
cobfunc Calls a COBOL program then cancels it. Program variables are reset on exit.

12.6.1 Calling COBOL Programs from C (Alpha, I64)

Using cobfunc.h as shown in Example 12-9, the C code in Example 12-8 demonstrates a program that calls a COBOL program with three arguments. In this example the COBOL program, CALLEDFROMC, expects two strings and an integer.

Example 12-8 Calling a COBOL Program from C (Alpha, I64)

#include <stdio.h>
#include "cobfunc.h"
extern int calledfromc();

main(int argc, char **argv)
{
  char *arg1="arg1_string";
  char *arg2="1234";
  int arg3 = 16587;
  int func_result;
  char *arglist[10];
#ifdef __osf__
  cob_init(argc, argv, NULL);
#endif
  arglist[0] = arg1;
  arglist[1] = arg2;
  arglist[2] = (char *) &arg3;

  func_result = cobfunc ("calledfromc", 3, arglist);
}

Example 12-9 could be used as an #include file for the cobfunc , cobcall , and cobcancel functions.

Example 12-9 C Include File cobfunc.h (Alpha, I64)

void cobcancel ( /* CANCEL the named COBOL routine */
    char *name
    );

int cobcall (   /* Call a COBOL program from a C routine */
    char *name, /* READ: name of the program */
    int argc,   /* READ: how many arguments */
    char **argv /* READ: array of pointers to the arguments */
    );

int cobfunc (   /* Call a COBOL program from a C routine, then CANCEL it */
    char *name, /* name of the program */
    int argc,   /* how many arguments */
    char **argv /* array of pointers to the arguments */
    );

#ifdef __osf__
void cob_init (                 /* init the RTL */
    int argc,                   /* argument count */
    char **argv,                /* arguments */
    char **envp                 /* environment variable pointers */
    );
#endif

Note that argv[0] is the first argument to pass and argv[n-1] is the nth. The maximum number of arguments supported is 254. <>

For Tru64 UNIX programs, if the main routine is written in C, it must call cob_init. (See Section 12.1.2, Calling Procedures.) The HP COBOL program expects its arguments by reference. <>

Example 12-10 COBOL Called Program "CALLEDFROMC" (Alpha, I64)

IDENTIFICATION DIVISION.
PROGRAM-ID. CALLEDFROMC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TEST-RESET PIC X(10) VALUE "OFF".
01 RETVAL PIC 9(5) COMP VALUE 357.
LINKAGE SECTION.
01 ARG1 PIC X(10).
01 ARG2 PIC 9(4).
01 ARG3 PIC 9(5) COMP.
PROCEDURE DIVISION USING ARG1 ARG2 ARG3 GIVING RETVAL.
P0.
        DISPLAY "In CALLEDFROMC".
        DISPLAY "test-reset is: " TEST-RESET
        MOVE "on" TO TEST-RESET.
        DISPLAY "arg1=" ARG1.
        DISPLAY "arg1=" ARG1 ", arg2=" ARG2 ", arg3=" ARG3 WITH CONVERSION.
END PROGRAM CALLEDFROMC.

Values Returned by cobcall and cobfunc (Alpha, I64)

The RTL calls cobcall and cobfunc can return a signed integer value from the GIVING clause of the COBOL program whose value is a longword integer (for example, PIC S9(9) COMP). The results of returning other values from the program called by cobcall or cobfunc are undefined.

Consider this example of the use of cobcall / cobfunc / cobcancel in a C program that uses cobcall , cobfunc , and cobcancel to call or cancel another COBOL program. Following is progc.c, the C program that calls the COBOL program:

Example 12-11 C Program Using cobcall, cobfunc, and cobcancel (Alpha, I64)

        /* File: progc.c */
        #include "stdlib.h"
        #include "stdio.h"                      /* printf */
        #include "string.h"                     /* strlen */

        #define NUMARGS  4                      /* up to 254 allowed */

        void    cobcancel(char *name);
        int     cobcall  (char *name, int argc, char **argv);
        int     cobfunc  (char *name, int argc, char **argv);

        void display(char *s, int r, int a);

        extern int progcob();                   /* COBOL returns int */

            void mainx(){
            int  retval = 0;                    /* progcob returns int */
            char *a_list[NUMARGS];              /* progcob needs 4 args */
            int arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4;

            a_list[0] = (char *) &arg1;         /* address of 1st arg */
            a_list[1] = (char *) &arg2;         /* address of 2nd arg */
            a_list[2] = (char *) &arg3;         /* address of 3rd arg */
            a_list[3] = (char *) &arg4;         /* address of 4th arg */

            display("[0] All the initialized values", retval, arg1);

            retval = cobcall("progcob", NUMARGS, a_list);
            display("[1] After calling cobcall:", retval, arg1);

            retval = cobfunc("progcob", NUMARGS, a_list);
            display("[2] After calling cobfunc:", retval, arg1);

            retval = cobcall("progcob", NUMARGS, a_list);
            display("[3] After calling cobcall again:", retval, arg1);

            cobcancel("progcob");
            display("[4] After calling cobcancel:", retval, arg1);

            retval = cobcall("progcob", NUMARGS, a_list);
            display("[5] After calling cobcall again:", retval, arg1);
        }

            void display(char *s, int r, int a){
            unsigned int i = 0;
            printf("\n%s\n", s);
            for (i = 0; i < strlen(s); i++) printf("=");
            printf("\n   retval = %d", r);
            printf("\n   arg1   = %d", a);
            printf("\n");
        }


Previous Next Contents Index