HP 3000 Manuals

CALL Prototypes [ Micro Focus COBOL Language Reference - Additional Topics ] MPE/iX 5.0 Documentation


Micro Focus COBOL Language Reference - Additional Topics

CALL Prototypes 

The following program demonstrates the use of CALL prototypes.  Assume
that you have defined the following CALL prototype:

       identification division.
      program-id.  callsub is external.
      environment division.
      configuration section.
      special-names.
          call-convention 3 in some-language.
      data division.
      linkage section.
      01  x1         pic 9(4) comp-5.
      01  x2         pic xx.
      01  x3         pic 9(8).
      01  x7         pic x.
      procedure division some-language using by value     x1
     by reference x2
     by reference x3.
      entry "callsub2" using x2 delimited
     any
     x1.
      entry "printf" using x7 delimited
           any repeated.
      end program callsub.

If you had the following "real" source coded in the same source file as
the previous CALL prototype:

       identification division.
      program-id.  prog-1.
      data division.
      working-storage section.
      01  x1      pic 9(4) comp-5.
      01  x2.
          05      pic 9(4) comp-5.
          05      pic x(20).
      01  x3      pic 9(8).
      01  x4      pic 9(9) comp-5.
      01  x5      pic x.
      01  x6      pic x(20).
      procedure division.
      mainline.
          call "callsub" using x1 x2 x3

the preceding CALL statement would be equivalent to using:

        by value x1
       by reference x2
       by reference x3

The following examples show the results of different call statements:

Example 1 

           call "callsub" using x1 x2

The preceding CALL statement would generate an error since the number of
parameters is wrong.

Example 2 

           call other-language "callsub" using x1 x2 x3

The preceding CALL statement would generate an error since the
call-convention is wrong.

Example 3 

           call "callsub" using by reference x1 x2 x3

The preceding CALL statement would generate an error since x1 should be
passed by value.

Example 4 

           call "callsub" using 99 x2 x3

The preceding CALL statement would be equivalent to a call using:

        by value 99 size 2
       by reference x2
       by reference x3

Example 5 

           call "callsub" using x4 x2 x3

The preceding CALL statement would generate an error since x4 has the
wrong length.

Example 6 

           call "callsub" using x1 x5 x3

The preceding CALL statement would generate an error since x5 is too
small.

Example 7 

           call "printf" using "A long %1\n" x4

In the preceding CALL statement x4 is a parameter covered by ANY
REPEATED.

Example 8 

           call "callsub2" using "Hello" x2 x1

The preceding CALL statement is equivalent to:

           move "Hello" & x"00" to temp
          call "callsub2" using temp x2 x1

Example 9 

           call "callsub2" using x6 x2 x1

The preceding CALL statement is equivalent to:

           move x6 to temp
          move x"00" to temp (21:1)
          call "callsub2" using temp x2 x1

Example 10 

           call "callsub2" using x6 x2 x1 x4

The preceding CALL statement would generate an error as there are too
many parameters being passed.

Example of CALL Prototype Usage 

If a COBOL application programmer wants to call a C function from within
his COBOL application the following need to be done:

   *   The C function parameters need to be defined within the COBOL
       application.  This means the mapping of C data types to COBOL data
       types.

   *   The actual call to the C function must contain the correct number
       of parameters and each parameter must be of the correct type.

   *   Any strings of text that need to passed to a C function will need
       to be converted into a null terminated C string.

The use of COBOL TYPEDEFS and COBOL CALL prototypes may be used to
automate the above process.  This includes the automatic conversion of
text strings into null terminated C strings.  The following is an example
of how all this may be done.

Suppose I have a C function that I want to call.  Let us call it
my_C_function.  The following is a segment of C code that shows this
function:

      sample.c
     -----------------------------------------------------------------

     /*** start of source module sample.c ***/

     /*------------------------*/
     /*  Include Header Files  */
     /*------------------------*/

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

     /*-------------------*/
     /*  Sample Function  */
     /*-------------------*/
     int my_C_function (parm_1, parm_2, parm_3)
     num_type parm_1;
     unsigned char *parm_2;
     complex_type *parm_3;
     {
         int rtn_code = 0;

     printf(" my-C_function: invoked\n");

     printf(" my-C_function: parm_1 = %d\n", parm_1);

     if (parm_2 == NULL) {
     printf(" my_C_function: parm_2 = IS NULL\n", parm_2);
     rtn_code = -1;
         } else {
     printf(" my_C_function: parm_2 = %s\n", parm_2);
         }

     if (parm_3 == NULL ) {
     printf(" my_C_function: parm_3 = IS NULL\n", parm_3);
     rtn_code = -1;
         } else {
     printf(" my_C_function: parm_3\n");
     printf("   (num1) = d\n", parm_3->num1);
     printf("   (num2) = d\n", parm_3->num2);
         }

     printf(" my_C_function: completed\n");
         return(rtn_code);
     }

     /*** end of source module sample.c ***/
     -----------------------------------------------------------------

In this example we have three parameters for the C function:

   *   A typdef'ed value

   *   A C string

   *   A constructed data type

There is a header file that contains the C typedef definitions and also
the C function prototype.  It is as follows:

      sample.h
     -----------------------------------------------------------------
     /*** start of source module sample.h ***/

     #ifndef         SAMPLE
     #define         SAMPLE

     /*------------*/
     /*  Typedefs  */
     /*------------*/
     typedef int num_type;
     typedef struct {
     int num1;
     long num2;
     } complex_type;

     /*----------------------/*
     /*  Function Prototype  /*
     /*----------------------/*
     extern int my_C_function (
     num_type parm_1,
     unsigned char *parm_2,
     complex_type *parm_3
     );
     #endif          /* SAMPLE */
     /*** end of source module sample.h ***/
     -----------------------------------------------------------------

The first step is to convert the C typedefs and function prototypes into
COBOL TYPEDEFS and COBOL CALL prototypes.  This may be done using the
h2cpy  utility provided with Micro Focus COBOL.

      h2cpy sample.h

produces the following copybook as output:

      sample.cpy
     -----------------------------------------------------------------
      program-id. "c_typedefs" is external.
      77  char                   pic s9(2)  comp-5 is typedef.
      77  uns-char               pic  9(2)  comp-5 is typedef.
      77  short                  pic s9(4)  comp-5 is typedef.
      77  uns-short              pic  9(4)  comp-5 is typedef.
      77  int                    pic s9(9)  comp-5 is typedef.
      77  uns-int                pic  9(9)  comp-5 is typedef.
      77  long                   pic s9(9)  comp-5 is typedef.
      77  uns-long               pic  9(9)  comp-5 is typedef.
      77  d-l-float                         comp-2 is typedef.
      77  d-float                           comp-2 is typedef.
      77  float                             comp-1 is typedef.
      77  proc-pointer           procedure-pointer is typedef.
      77  data-pointer                     pointer is typedef.
      77  void                   pic  9(2)  comp-5 is typedef.
      01  num-type          is typedef       usage int.
      01 complex-type       is typedef.
          02 num1              usage int.
          02 num2              usage long.
      entry "my_C_function" using
      by value      int
      by reference  uns-char
      by reference  complex-type
          returning         int
          .
      end program "c-typedefs".
     -----------------------------------------------------------------

In the above we have:

   *   Level 77's that map all the basic C data types to COBOL TYPEDEFS.

   *   Level 01's that are TYPEDEFS that match the C typedefs in the
       header file

   *   An entry statement that acts as a COBOL CALL prototype for the C
       function

The following changes should be made to this file with a text editor.

   *   Remove the level 77 data items that are not needed

   *   Change the uns-char mapping to map to "pic x" instead of a numeric
       field.  If this is not done then an attempt to pass a PIC X field
       as a parameter would be rejected as not conforming to the
       prototype parameter specification.

   *   Add the keyword

            delimited

       beside

            uns-char

       in the CALL prototype.  This has the result of converting the TEXT
       string passed as a parameter into a null terminated C string at
       run time for the caller.

The result of the above editing is the following:

      sample.cpy
     -----------------------------------------------------------------
      program-id. "c_typedefs" is external.

      77  uns-char               pic x             is typedef.
      77  int                    pic s9(9)  comp-5 is typedef.
      77  long                   pic s9(9)  comp-5 is typedef.
      77  data-pointer                     pointer is typedef.

      01 num-type           is typedef       usage int.
      01 complex-type       is typedef.
          02 num1              usage int.
          02 num2              usage long.

      entry "my_C_function" using
      by value      int
      by reference  uns-char delimited
      by reference  complex-type
          returning         int
          .

      end program "c_typedefs".
     -----------------------------------------------------------------

The following is an example of the COBOL application that makes a call to
the my_C_function function.

      -----------------------------------------------------------------
      copy 'sample.cpy'.

      identification division.
      program-id.  prog.
      working-storage section.
      01  ws-parm-1                       usage num-type.
      01  ws-parm-2                       pic x(50)
         value "This is a PIC X string from COBOL".
      01  ws-parm-3                       usage comlex-type.
      01  ws-return-code                  usage int.

      procedure division.
      main-code section.
          display "prog: started"

          move 123     to ws-parm-1
          move 1       to num1 IN ws-parm-3
          move 2       to num2 IN ws-parm -3

          display " "
          display "prog: call 'my_C_function' with ALL parameters"
          call "my_C_function" using ws-parm-1
     ws-parm-2
     ws-parm-3
       returning ws-return-code
          end-call
          display "prog: 'my_C_function' return code = "
          ws-return-code

          display " "
          display "prog: call 'my_C_function' with NULL parameters"
          call "my_C_function" using 0
     OMITTED
     OMITTED
       returning ws-return-code
          end-call
          display "prog: 'my_C_function' return code = "
          ws-return-code

          display " "
          display "prog: completed"
          exit program
          stop run.
     -----------------------------------------------------------------

In the above example the following has been coded:

   *   The copyfile sample.cpy has been included as the first statement
       in the source.  This is the copybook that contains the COBOL
       TYPEDEFS and COBOL CALL prototypes.

       Typedefs and prototypes are defined as complete "EXTERNAL"
       programs.  They are placed before real source programs in a
       similar way to multi-program source files.

   *   The parameters for the C function have been defined in the
       Working-Storage Section using the COBOL TYPEDEFS.

   *   In this example two calls are made to the C function.  The
       following should be noted from this:

          *   BY REFERENCE/VALUE has not been specified.  The correct
              default is picked up from the prototype.

          *   The prototype will ensure that the correct number of
              parameters of the correct type has been specified.  If not,
              then the checker will flag an error at compile time.

          *   In the second call the special word OMITTED has been
              specified to pass a BY REFERENCE parameter as a NULL
              instead of a parameter value.

              This is required because it is not possible to just go BY
              VALUE 0 which would be flagged as invalid because BY
              REFERENCE is mandatory for that parameter.  OMITTED will
              pass a NULL instead of a pointer to the parameter being
              passed to the C function.

The following is the output that results when the specific example above
is run:

      -----------------------------------------------------------------
     %prog
     prog: started

     prog: call 'my_C_function' with ALL parameters
           my_C_function: invoked
           my_C_function: parm_1 = 123
           my_C_function: parm_2 = This is a PIC X string from COBOL
           my_C_function: parm_3
          (num1) = 1
          (num2) = 2
           my_C_function: completed
     prog: 'my_C_function' return code = +0000000000

     prog: call 'my_C_function' with NULL parameters
           my_C_function: invoked
           my_C_function: parm_1 = 0
           my_C_function: parm_2 = IS NULL
           my_C_function: parm_3 = IS NULL
           my_C_function: completed

     prog: 'my_C_function' return code = +0000000001

     prog: completed
     %
     -----------------------------------------------------------------

Calling and Setting a Procedure-Pointer 

      * Calling program:

     program-id. startup.
      working-storage section.
      01 start-point  usage procedure-pointer.
      procedure-division.
          set start-point to entry "menu"
          call "controller" using start-point
          display "End of run"
          stop run.

     entry "illegal"
     * Recursive calls invalid without local-storage section.
          stop run.
      end program startup.

     * Called program:

     program-id. controller.
      working-storage section.
      01 next-option  pic x.
      linkage section.
      01 current-proc usage procedure-pointer.
      procedure division using current-proc.
          perform until current-proc = NULL
      call current-proc returning next-option
     *        Note program-id must be called before any entry point
      evaluate next-option
       when "a"    set current-proc to entry "sub1"
       when other  set current-proc to NULL
      end evaluate
          end-perform
          exit program.
      end program controller.

     program-id. menu.
      working-storage section.
      01 exit-option  pic x.
      procedure division.
          display "In menu"
          move "a" to exit-option
          exit program returning exit-option.
     *    Note that the maximum size of returned value is 4 bytes

     entry "sub1"
          display "In sub1"
          exit program returning 1.

Call Returning a Dynamically Allocated Data Area from a Subprogram 

      * Calling program:

     program-id. calling.
      working-storage section.
      01 call-size   pic x(4) comp-5 value 64.
      linkage section.
      01 call-area   pic x.
      procedure division.
          call "sub2" using call-size
      returning address of call-area
          if address of call-area not = null
      display "Contents of new area: " call-area(1:call-size)
          end-if
          stop run.
     end program calling.

     * Called program:

     program-id. sub2.
      working-storage section.
      01 sub-pointer usage pointer.
      linkage section.
      01 link-size   pic x(4) comp-5.
      01 link-area   pic x.
      procedure division using link-size.
          call "CBL_ALLOC_MEM" using sub-pointer
     by value link-size
      0 size is 4
          if return-code = 0
      set address of link-area to sub-pointer
      move "Hello!" to link-area(1:call-size)
          else         set sub-pointer to null
          end-if
          exit program returning sub-pointer.

COPY (ANSI'68 or LANGLVL(1) Variation) 

The COPY statement's behavior is slightly modified when the OLDCOPY
directive is set.  This modification changes it from acting as defined by
the ANSI'74 and ANSI'85 standards to behaving as the old ANSI'68 standard
defined.  This modified behavior is also consistent with how OS/VS COBOL
and DOS/VS COBOL behave when the LANGLVL(1) compiler option is used on an
IBM mainframe.

When the OLDCOPY directive is set and a copy member is intended to
include an entire 01 level data description, both the COPY statement and
the copied description should be defined with an 01 level item.  However,
only the data name from the copying statement will be available to the
rest of the COBOL program.  For example:

Source-file Code.

       01   PRODUCT-CODE COPY COPYPROD.

Copy-file Code "COPYPROD":

       01   PROD-CD.
          05   ITEM-NAME      PIC X(30).
          05   ITEM-NUMBER    PIC X(5).

Resulting COBOL Code:

       01   PRODUCT-CODE.
          05   ITEM-NAME      PIC X(30).
          05   ITEM-NUMBER    PIC X(5).

COPY (Partial Word Replacement) 

The COPY statement in an ANSI'85 conforming compiler can be used to
modify parts of words in the copy member source.  It should be carefully
noted that this syntax only works when certain conventions (and special
characters) are used.  When using this technique, the programmer must set
up their copy members with the modifiable sections pre-established.  In
fact, once this technique is used, the copy members will NOT compile
cleanly when not replaced.  For example:

Source-file Code:

           copy Payroll
      replacing ==(TAG)== by ==Payroll==.

Copy-file Code:

       01  (TAG).
          05 (TAG)-Week      pic s99.
          05 (TAG)-Gross-Paypic s9(5)v99.
          05 (TAG)-Hours     pic s9(3)
        occurs 1 to 52 times
        depending on (TAG)-Week of (TAG).

Is treated as if it were coded as:

       01  Payroll.
          05 Payroll-Week      pic s99.
          05 Payroll-Gross-Paypic s9(5)v99.
          05 Payroll-Hours     pic s9(3)
         occurs 1 to 52 times
         depending on Payroll-Week of Payroll.

CRT Status Clause of the SPECIAL-NAMES Paragraph 

The CRT status clause of the SPECIAL-NAMES paragraph provides a data item
composed as follows:

   *   Status Key 1 - indicates the conditon that caused the termination
       of the ACCEPT operation

   *   Status Key 2 - further distinguishes between ACCEPT termination
       actions

   *   Status Key 3 - contains the raw keyboard code for the key that
       terminated the ACCEPT operation.

The following examples show how the CRT status-key should be coded and
referenced.

      ************************************************************
     *                                                          *
     *   The following shows how the special-names paragraph    *
     *   sets up both a cursor position field and a CRT status  *
     *   key field.                                             *
     *                                                          *
     ************************************************************

     special names.
          cursor is cursor-position
          crt status is crt-status.

     . . .

     working-storage section.
      01 cursor-position                    pic 9(4).

     ************************************************************
     *   The following group item defines the CRT status key    *
     *   field and establishes certain 78-level condition-names *
     *   associated with key fields.                            *
     *                                                          *
     *   Programs using these definitions should be compiled    *
     *   with NOIBMCOMP and MF to function as expected.         *
     *                                                          *
     ************************************************************

      01  crt-status.
          05 crt-status-1                   pic 9.
     88  terminate-key                    value 0.
     88  function-key                     value 1.
     88  adis-key                         value 2.
     88  status-1-error                   value 9.
         05  crt-status-2                   pic 99 comp-x.
     88  esc-key                          value 0.
     88  f1-key                           value 1.
     88  enter-key                        value 1.
     88  fun-key-num-user                 values 0 thru 127.
     88  fun-key-num-system               values 0 thru 26.
         05  crt-status-3                   pic 99 comp-x.
     88 raw-key-code                      values 0 thru 255.
           ...
      procedure-division.
           ...
     ************************************************************
     *                                                          *
     *   The following shows the procedural code that would     *
     *   evaluate the CRT status keys and direct processing     *
     *   accordingly.                                           *
     *                                                          *
     ************************************************************

          evaluate terminate-key also function-key also adis-key
           when true  also any  also any
      if esc-key
          evaluate crt-status-3
            when 0  perform raw-key-0
            when 1  perform raw-key-1
            when 2  perform raw-key-2
            when 3  perform raw-key-3
      ...
         end-evaluate
     else
         perform logic-for-terminator-key
     end-if

           when any  also true  also any
      evaluate crt-status-2
        when 1  perform user-function-1
        when 2  perform user-function-2
        when 3  perform user-function-3
        when 4  perform user-function-4
        when 5  perform user-function-5
          ...
      end-evaluate

            when any  also any  also true
      evaluate crt-status-2
        when 1 perform sys-function-1
        when 2 perform sys-function-2
        when 3 perform sys-function-3
        when 4 perform sys-function-4
        when 5 perform sys-function-5
           ...
         end-evaluate
          end-evaluate

$IF Statement (Conditional Compilation) 

The $IF statement can be used to "conditionally compile" portions of your
source code.  In the following example, if the program is compiled with
the directive,

      CONSTANT WHERE "PC"

then at compile time, the word "NO" will be displayed and the object code
will include an EVALUATE rather than a GO TO statement.

      $if WHERE = "PC"
          evaluate test-field
            when 5  perform test-a
          end-evaluate
     $if other-constant defined
     $display Program compiled with other-constant set
     $else
     $display NO
     $end
     $else
          go to test-a test-b depending on test-field
     $end

INSPECT Statement (Tallying, Replacing, and Converting) 

The INSPECT statement can be used to tally the number of occurrences of
specific character strings, to replace characters by other characters, or
to convert from one set of characters to another.  Setting the conditons
for these inspections can be quite complex.  The following examples
demonstrate some of the variations and uses of this verb.

In each of the following examples of the INSPECT statement, COUNT-n is
assumed to be zero immediately prior to execution of the statement.  The
results shown for each example, except the last, are the result of
executing the two successive INSPECT statements shown above them.

Example 1:.   

           inspect item tallying
      count-0 for all "AB", all "D"
      count-1 for all "BC"
      count-2 for leading "EF"
      count-3 for leading "B"
      count-4 for characters;

          inspect item replacing
      all "AB" by "XY", "D" by "X"
      all "BC" by "VW"
      leading "EF" by "TU"
      leading "B" by "S"
      first "G" by "R"
      first "G" by "P"
      characters by "Z"

---------------------------------------------------------------------------------------------------------
|                     |           |           |           |           |           |                     |
|  Intital Value of   |  COUNT-0  |  COUNT-1  |  COUNT-2  |  COUNT-3  |  COUNT-4  | Final Value of ITEM |
|        ITEM         |           |           |           |           |           |                     |
|                     |           |           |           |           |           |                     |
---------------------------------------------------------------------------------------------------------
|                     |           |           |           |           |           |                     |
| EFABDBCGABEFGG      |     3     |     1     |     1     |     0     |     5     | TUXYXVWRXYZZPZ      |
|                     |           |           |           |           |           |                     |
---------------------------------------------------------------------------------------------------------
|                     |           |           |           |           |           |                     |
| BABABC              |     2     |     0     |     0     |     1     |     1     | SXYXYZ              |
|                     |           |           |           |           |           |                     |
---------------------------------------------------------------------------------------------------------
|                     |           |           |           |           |           |                     |
| BBBC                |     0     |     1     |     0     |     2     |     0     | SSVW                |
|                     |           |           |           |           |           |                     |
---------------------------------------------------------------------------------------------------------

Example 2:.   

       inspect item tallying
      count-0 for characters
      count-1 for all "A";

          inspect item replacing
      characters by "Z"
      all "A" by "X"

-------------------------------------------------------------------------------------------------
|                       |                       |                       |                       |
| Intital Value of ITEM |        COUNT-0        |        COUNT-1        |  Final Value of ITEM  |
|                       |                       |                       |                       |
-------------------------------------------------------------------------------------------------
|                       |                       |                       |                       |
| BBB                   |           3           |           0           |          ZZZ          |
|                       |                       |                       |                       |
-------------------------------------------------------------------------------------------------
|                       |                       |                       |                       |
| ABA                   |           3           |           0           |          ZZZ          |
|                       |                       |                       |                       |
-------------------------------------------------------------------------------------------------

Example 3:.   

           inspect item tallying
      count-0 for all "AB" before "BC"
      count-1 for leading "B" after "D"
      count-2 for characters after "A" before "C"

          inspect item replacing
      all "AB" by "XY" before "BC"
      leading "B" by "W" after "D"
      first "E" by "V" after "D"
      characters by "Z" after "A" before "C"

-----------------------------------------------------------------------------------------------------
|                   |                   |                   |                   |                   |
| Intital Value of  |      COUNT-0      |      COUNT-1      |      COUNT-2      |  Final Value of   |
|       ITEM        |                   |                   |                   |       ITEM        |
|                   |                   |                   |                   |                   |
-----------------------------------------------------------------------------------------------------
|                   |                   |                   |                   |                   |
| BBEABDABABBCABEE  |         3         |         0         |         2         | BBEXUZXUXUZCABVE  |
|                   |                   |                   |                   |                   |
-----------------------------------------------------------------------------------------------------
|                   |                   |                   |                   |                   |
| ADDDDC            |         0         |         0         |         4         | AZZZZC            |
|                   |                   |                   |                   |                   |
-----------------------------------------------------------------------------------------------------
|                   |                   |                   |                   |                   |
| ADDDDA            |         0         |         0         |         5         | AZZZZZ            |
|                   |                   |                   |                   |                   |
-----------------------------------------------------------------------------------------------------
|                   |                   |                   |                   |                   |
| CDDDDC            |         0         |         0         |         0         | CDDDDC            |
|                   |                   |                   |                   |                   |
-----------------------------------------------------------------------------------------------------
|                   |                   |                   |                   |                   |
| BDBBBDB           |         0         |         3         |         0         | BDWWWDB           |
|                   |                   |                   |                   |                   |
-----------------------------------------------------------------------------------------------------

Example 4:.   

           inspect item tallying
      count-0 for all "AB" after "BA" before "BC";

          inspect item replacing
      all "AB" by "XY" after "BA" before "BC"

----------------------------------------------------------------------------------------------
|                              |                              |                              |
|    Intital Value of ITEM     |           COUNT-0            |     Final Value of ITEM      |
|                              |                              |                              |
----------------------------------------------------------------------------------------------
|                              |                              |                              |
| ABABABABC                    |              1               | ABABXYABC                    |
|                              |                              |                              |
----------------------------------------------------------------------------------------------

Example 5:.   

           inspect item converting
      "ABCD" to "XYZX" after quote before "#".

The above INSPECT is equivalent to the following INSPECT:

           inspect item replacing
      all "A" by "X" after quote before "#"
      all "B" by "Y" after quote before "#"
      all "C" by "Z" after quote before "#"
      all "D" by "X" after quote before "#".

---------------------------------------------------------------------------------------------
|                                             |                                             |
|            Intital Value of ITEM            |             Final Value of ITEM             |
|                                             |                                             |
---------------------------------------------------------------------------------------------
|                                             |                                             |
| AC"AEBDFBCD#AB"D                            | AC"XEYXFYZX#AB"D                            |
|                                             |                                             |
---------------------------------------------------------------------------------------------

NEXT Clause of CONSTANT-NAMES 

The NEXT clause of the constant-name format of a VALUE clause always
points to the offset at which the next byte of storage occurs after the
previous data declaration.  For example, given the following:

       01  x1                                pic x(10).
      01  x2 redefines x1    pic x.
          78  next-offset    value next.
      01  x3                         pic xx.

the value in next-offset will be the location of the second byte of x1 
and not the starting location of x3.

This also can cause confusion with OCCURS clauses.  For example, given
the following:

       01  group-item.
          05  tabl occurs 10 times.
          78  offset-a       value next.
      10 elem                        pic x.
          78  offset-b       value next.
          05  after-tabl             pic x(02).

offset-a will point to the offset at the start of the first occurrence of
elem while offset-b will point to the starting location of the second
occurrence of table element elem and not to the starting location of
after-tabl.  If you wanted to get the starting location of after-tabl,
you should recode your source as follows:

       01  group-item.
          05  dummy-item             pic x(10).
      78 offset-c                    value next.
          05  tabl redefines dummy-item
           occurs 10 times.
         78 offset-a         value next.
      10 elem                        pic x.
         78 offset-b         value next.
          05  after-tabl             pic x (02).

In this example, offset-c will point to the starting offset of 
after-tabl.

SORT Table Entries 

A table sort using KEYS in OCCURS clause for sequencing:

       working-storage section.
      01 group-item.
          05   tabl   occurs 10 times
          ascending elem-item2
          descending elem-item1.
       10 elem-item1 pic x.
       10 elem-item2 pic x.
          . . .
      procedure division.
          . . .
          sort tabl.
          if tabl (1) . . .

This is a simple sort in which the table is sorted in ascending order
using the key definitions in the OCCURS clause of data item Tabl to
determine the sequence, that is Elem-Item2 would be the major key
(ascending) and Elem-Item1 would be the secondary key (descending).

A table sort using the entire element for sequencing:

       working-storage section.
      01 group-item.
          05 tabl occurs 10 times
      10 elem-item1 pic x.
      10 elem-item2 pic x.
          . . .
      procedure division.
          . . .
          sort tabl ascending.
          if tabl (1) ...

This is a simple sort in which the table is sorted in ascending order
using each entire element of the table to determine the sequence.

A table sort with specified items for sequencing:

       working-storage section.
      01 group-item.
          05  tabl    occurs 10 times
          ascending elem-item3
          descending elem-item1.
      10 elem-item1 pic x.
      10 elem-item2 pic x.
      10 elem-item3 pic x.
          . . .
      procedure division.
          . . .
          sort tabl descending elem-item2 elem-item3
          if tabl (1) ...

This is a sort in which the table is sorted based on specified key data
items.  The major key would be Elem-Item2, even though it was not
specified as a KEY in the OCCURS clause.  The secondary key would be
Elem-Item3.  It would be treated as a DESCENDING key for this sort
because the DESCENDING (which is transitive across KEY data items)
specified in the SORT statement would take precedence over the ASCENDING
specified in the OCCURS clause.

A table sort for a nested table:

       working-storage section.
      01 group-item.
          05  tabl1   occurs 10 times
          indexed by t1-ind t2-ind.
      10  tabl2 occur 5 times.
          15 group1.
      20 elem-item1 pic x.
          15 group2.
      20 elem-item1 pic 9.
          . . .
      procedure division.
          . . .
          set t1-ind to 3
          sort tabl2 descending elem-item1 of group2
          if group1 (3 1) ...

This sorts only the third instance of Tabl2, that is Tabl2(3).  It uses
the qualified data-item, Elem-Item1 of Group2 as its key.  In normal
Procedure Division references, Elem-Item1 of Group2 would require two
levels of subscripting/indexing while in this reference it has none.
(Similarly, Tabl2 normally requires one level of subscripting, but cannot
be subscripted as data-name-2 in the SORT statement.  Instead it uses the
value of T1-Ind for determining which instance is to be sorted.)

Split Key 

If a program contained the following definition:

       01 rec.
          03 forename         pic X(10).
          03 personnel-no pic X(4).
          03 surname          pic X(15).

the syntax:

           record key is fullname =
      surname forename

would cause the COBOL system to treat

     fullname

as though it were an explicitly defined group item consisting of:

           03 surname         pic X(15).
          03 forename         pic X(10).

TYPEDEF - User Defined USAGE or Structure 

The compiler supports the following data descriptions:

       01 struct-1           TYPEDEF.
         05  part-1  pic x (20).
         05  part-2  pic x(10).
      01 USHORT      pic 9 (4)       comp-5 typedef.

which defines struct-1 and USHORT to be new usages that can be used as in
the following:

       01  a.
          05  b      struct-1.
          05  x      USHORT.

which would be interpreted as if it had been coded as:

       01  a.
          05  b.
      10  part-1     pic x(20).
      10  part-2     pic x(10).
          05  x              pic 9(4) comp-5.



MPE/iX 5.0 Documentation