Document ID:        41936.1
Subject:            Cobol User Exits with Forms 4.5 on Unix
Last Modified:      23 Jan 97
Author:             SSLACK


Overview:
---------

Cobol user exits have been used widely in the past with Forms 3 and we have
encountered a few customers who are upgrading their application to Forms 4.5
and running into problems when trying to migrate Cobol User Exits.  The main
problem is that there are no example files distributed with Forms 4.5 of how to
do this.  With Forms 3 there used to be a directory
$ORACLE_HOME/forms3/lib/cobol which contained a sample user exit and a makefile.
  There is no equivalent with Forms 4.5 and this docuement attempts to make the
process of converting the standard makefile easier.

The information in this file is based on the modifications to an installation
of Forms 4.5.6.2 on HP-UX Version 9 under a 7.1.6 Oracle home, however the
instructions should be generic.

The Microfocus COBOL compiler version was 3.2.3.

Changes to the Makefile:
------------------------

The forms executable has to be built by calling the system linker from the
MicroFocus compiler and not from the C compiler.  This requires changes to the
file sqlforms45.mk in $ORACLE_HOME/forms45/lib.

1.  Ensure that the following entries are defined at the top of the makefile:

COB=cob
COBFLAGS=-C IBMCOMP -x

2.  Look at the definition of LD_FLAGS; in my version of the file this was:

LDFLAGS=-Wl -adefault -L $(LIBHOME)

3.  Modify the definition of EXITS to include your .o file (generated using the
procob.mk file) i.e.

EXITS=ue_xtb.o sample5.o

4.  Locate the rule for the user exits:  Note that under forms45 you only  need
to link the user exits into the forms runtime executable and that to test user
exits from forms you need to rename the generated executable (f45runmx) to the
standard executable name (f45runm).

For example - the (first part of) the definition for f45runx looks like:

f45runx: $(EXITS)
        @$(ECHO) $(CC) $(LDFLAGS) -o $@ \
        $(S0MAIN) \
        $(SSLIFCTAB) \
...

after modification this is:

f45runx: $(EXITS)
        @$(ECHO) $(COB) -Q "-adefault" -L$(LIBHOME) -o $@ \
        $(EXITS) \
        $(S0MAIN) \
        $(SSLIFCTAB) \

Note the following:
- the $(CC) is changed to $(COB) so that the cobol compiler is invoked.
- the -L linker flag is used in the same way it is with the C compiler but the -
adefault has to be passed to the linker using the -Q flag to the cobol compiler.
  This is where there may be different changes depending on the platform.
- there is a bug in sqlforms45.mk in that although it is dependent on the user
exits being linked in, the make rule does not actually include the user exits
on the link line - hence the additional $(EXITS) entry.

File Modifications:
-------------------

1.  The user exit lookup routine (ue_xtb.c) has to be modified so that the stub
for the cobol user exit is included.

The file (excluding comments at the top) looks like this after modification:

-----------

#ifndef UE
# include "ue.h"
#endif /* UE */

#include "ue_samp.h"

/* Define the user exit table */

exitr iapxtb[] =  {  /* Holds exit routine pointers */
     "CONCAT", CONCAT, XITCOB,
     (char *) 0, 0, 0         /* zero entry marks the end */
}; /* end iapxtb */

----------

Note:
  a.  That the name of the user exit when it is called from forms will be
      CONCAT (the first parameter in double quotes).
  b.  The name of the subprogram is CONCAT:  This is declared using the
      PROGRAM-ID.  CONCAT.
      statement in the cobol program and not by the name of the file.
  c.  The exit is defined as a COBOL one using COBXIT.

2.  The file ue_samp.h has to be changed to include the definition of
the user exit call i.e.

int CONCAT();

Final Checks:
-------------

1.  Make sure the the environment variable $COBDIR is defined
    (usually this is /opt/cobol/cobdir but check with your system
    administrator).

2.  Make sure that the cob executable is on your path
    (usually in /opt/cobol/bin but check with your system administrator).

Problems:
---------

The most common problem with cobol user exits is that the status code is not
returned to the form.  The process of passing back the return code is not
standard and will be achieved by one or more of the following methods.

1.  Move the value to the reserved MF Cobol variable RETURN-CODE.

2.  Use an extra parameter in the linkage section:
    RETURN-VALUE  PIC S9(09) COMP  (or COMP-5)
    Move the value to this variable before exiting the program.

3.  Use a normal working storage variable (e.g RETURN-STATUS declared
    as PIC S9(9) COMP (or COMP-5)).
    Move the variable to this value before exiting the program using
    the following syntax:
    EXIT PROGRAM GIVING RETURN-STATUS.  (This was the method I used).

If you attempt to call the user exit and get - user exit not found try:

1.  Altering the case of the name - e.g. USER_EXIT('uesamp'); instead of
    USER_EXIT('UESAMP'); or vice versa.

2.  Check that you have included the .o file on the link line (i.e. it is
    defined in EXITS).

3.  Check that the case of the module name in the ue_xtb file matches
    that of the PROGRAM-ID statement (consistently uppercase is good).