Inside COBOL
by
SHAWN M. GORDON
PRESIDENT
S.M.GORDON & ASSOCIATES

As promised I am going to cover some nice pieces of COBOLI 85 and the 89 addendum to the ANSI standard. Don’t forget that I am making no attempt to show portable code, this may or may not work under a COBOL compilier other than the HP 3000 one, but I make no guarantees.

For starters let’s talk about the new Scope Terminators in COBOL 85. What these do is let you explicity end a function, the two most useful ones are END-IF and END-PERFORM, let’s talk about END-IF first.

In the old days of COBOL programming, you would sometimes have to come up with the most inventive IF..ELSE construct to make sure you code was evaluating and executing correctly. If it got to convoluted it started to become a matter of guess work and trial & error to see if what you wanted to happen was happening. Once you were relatively sure that it was going to work you were then stuck with a pretty unreadable piece of code.

Now along comes COBOL 85 with the END-IF statement to make things better. A simple example of how a nested IF with END-IF could help make things clearer with data base call’s

CALL "DBGET" USING BASE, SET, MODE.....
IF NOT DB-CALL-OK
   IF DB-RECORD-NOT-FOUND
      GO TO PARA-END
   END-IF
   CALL "DBEXPLAIN" USING DB-STATUS-AREA.
PARA-END.

While this example may not be any space saver, it does seem to flow a little easier through the brain. You can nest as much as you need, and
then just terminate the IF sections you need too. I don’t think this needs any more discussion since it is pretty obvious.

Next scope terminator that I want to cover is END-PERFORM. Since the creation of END-PERFORM we COBOL programmers now have the equivalent of a WHILE..DO, DO..WHILE, and FOR..NEXT loop all contained in the same logic structure. In other words, we now have an in-line perform;

PERFORM VARYING S1 FROM 1 BY 1 UNTIL S1 > 10
   DISPLAY S1
END-PERFORM.

or for those of your that use dummy paragraphs to increment a counter;

PERFORM VARYING S1 FROM 1 BY 1 UNTIL S1 = 10
   CONTINUE
END-PERFORM.

You can nest these as well if you want to. In my opinion, this does
wonder’s to help clarify code and code flow, no more jumping all through a source file to find the performed paragraphs. The control statement on the PERFORM is the same as it always was, you just don’t have to specify the paragraph to perform anymore.

My next favorite addition to COBOL is byte referencing of variables.
I got very used to this in BASIC, and was really surprised to find that it wasn’t in COBOL initially. The impact here is a reduction in the amount of REDEFINES you will have to do in WORKING-STORAGE. It is a good idea to document in your code what you are doing though. Here is an example of the old way, and the possible new way.

01 MY-DATE.
   03 MD-MM        PIC X(02)  VALUE SPACES.
   03              PIC X      VALUE "/".
   03 MD-DD        PIC X(02)  VALUE SPACES.
   03              PIC X      VALUE "/".
   03 MD-YY        PIC X(02)  VALUE SPACES.
*
 01 CURR-DATE.
    03 CD-YY       PIC X(02)  VALUE SPACES.
    03 CD-MM       PIC X(02)  VALUE SPACES.
    03 CD-DD       PIC X(02)  VALUE SPACES.
*
PROCEDURE DIVISION.
A1000-INIT.
    ACCEPT CURR-DATE FROM DATE.
    MOVE CD-YY   TO MD-MM.
    MOVE CD-MM   TO MD-DD.
    MOVE CD-DD   TO MD-YY.
    DISPLAY MY-DATE.

Now under COBOL 85 I could do it like this;

01 MY-DATE         PIC X(08)   VALUE SPACES.
01 CURR-DATE       PIC X(06)   VALUE SPACES.
*
PROCEDURE DIVISION.
A1000-INIT.
     ACCEPT CURR-DATE FROM DATE.
     MOVE "/"            TO MY-DATE(3:1)
                            MY-DATE(6:1).
     MOVE CURR-DATE(1:2) TO MY-DATE(7:2).
     MOVE CURR-DATE(3:2) TO MY-DATE(1:2).
     MOVE CURR-DATE(5:2) TO MY-DATE(4:2).
     DISPLAY MY-DATE.

Yes, realize that this isn't a great example of code, it is just 
used to illustrate how to use byte referencing.

My next favorit new thing is the EVALUATE command.  This is a CASE
statement, just like in C.

ACCEPT WS-OPTION.

EVALUATE WS-OPTION
   WHEN "01"  PERFORM PARA-01
   WHEN "02"  PERFORM PARA-02
   WHEN "03"  PERFORM PARA-03
   WHEN "XX"  STOP RUN.

As you can see this is a lot easier to read than a bunch of IF
statements. There are actually a lot of options that can be specified
in the EVALUATE statement, but now that you know the basics of it
you can look it up in your dusty copy of the COBOL manual.

I want to finish this part on COBOL 85 by telling you that there are
now scope terminators for almost every verb, as well as opposite
conditional verbs, i.e.,

READ FILE 
   AT END 
  DISPLAY '1' 
   NOT AT END
  DISPLAY '2'
END-READ.

So take a close look at your manual, you would be amazed at how useful
these things can be the more you use them.

This brings us to the neat features that have been added in the ANSI
89 addendum to the COBOL 85 standard. There is only one problem with
this, the 89 stuff is only available on MPE/iX 3.1 and later, so those
of you with Classic HP 3000’s are out of luck. It is important to
note that every other COBOL compiler in the world had this stuff
way before HP came out with it. There is also a lot of other functions
in COBOL that HP never implemented, like a SCREENS sections, a REPORT
section, and a COMMUNICATION section. I have only played with these
a little bit in Microfocus COBOL, but it would sure be great if HP
would give these features to us, especially given the sheer number of
COBOL programmers, and COBOL code on the HP. Ok, on to the new stuff.

My favorite function is the new one to allow you to do date arithmatic
(finally). This opens up all sorts of possibilities, and simplifies
everyone’s life. Here is a handy little sample that shows how you
can calculate the number of weeks between two dates (any dates that
are used inside this function must be specified as PIC 9(08)).

COMPUTE NUM-WEEKS ROUNDED =
       (FUNCTION INTEGER-OF-DATE (WS-START-DATE) -
        FUNCTION INTEGER-OF-DATE (WS-STOP-DATE)) / 7
ON SIZE ERROR
        MOVE ZEROES       TO NUM-WEEKS
END-COMPUTE

You can also use this methodology to check if an invalid date was
entered;

A1000-DATE.
ACCEPT WS-START-DATE.

COMPUTE NUM-START = 
        FUNCTION INTEGER-OF-DATE (WS-START-DATE)
ON SIZE ERROR
        DISPLAY 'Invalid date - try again'
        GO TO A1000-DATE.

This is MUCH easier than writing your own date parsing routines.

I am just touching the tip of the iceberg here with the ’89 stuff. There are all sorts of math libraries to sum tables, convert data types, get random values, case shifting (although you can do that easily through a macro). There is even a whole set of financial and statistical functions. You really need to check out Chapter 10 of the latest COBOL manual so you can see all the neat new stuff.

That’s enough for this month, I haven’t decided what I am going to do next month yet, so we are all going to get a surprise.