COBOL is dynamic (depends)



Years ago for a project I had to deal with some messages that were something
like the following:

Field 1 - 4 alphanumeric characters
Field 2 - 2 numeric characters
Field 3 - either 16, or 33 or 49 characters in length, where if the first
character is a 'U' the length is 33, if the first character is a 'T' the
length is 49, otherwise the length is 16
Field 4 - 4 numeric characters
Field 5 - zero to 49 characters with the length being specified by field 4.
Field 6 - 1 character end of message delimiter ('!')

I ended up with a solution that, while it didn't make me happy, works and
isn't *too* complicated and ugly.

I saw this code again yesterday and thought that I should be able to make it
simpler, more flexible, and easier to understand.
So here's an example of how I would do it today.

PROGRAM-ID. DEPENDS.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 DATA-IN PIC X(80).
77 LEN-1 PIC S9(3) COMP-3.
77 LEN-2 PIC S9(3) COMP-3.
01 VC.
05 A PIC X(4).
05 B PIC X(2).
05 C.
10 PIC X OCCURS 0 TO 49
DEPENDING ON LEN-1.
05 D PIC 9(4).
05 E.
10 PIC X OCCURS 0 TO 49
DEPENDING ON LEN-2.
05 F PIC X.

PROCEDURE DIVISION.
PERFORM GET-VC
PERFORM UNTIL DATA-IN = LOW-VALUES
PERFORM PROCESS-VC
PERFORM GET-VC
END-PERFORM
GOBACK.

GET-VC.
MOVE LOW-VALUES TO DATA-IN
ACCEPT DATA-IN
.

PROCESS-VC.
MOVE 49 TO LEN-1
MOVE 49 TO LEN-2
MOVE DATA-IN TO VC
DISPLAY '**********' C(1:1)
EVALUATE C(1:1)
WHEN 'T'
MOVE 49 TO LEN-1
WHEN 'U'
MOVE 33 TO LEN-1
WHEN OTHER
MOVE 16 TO LEN-1
END-EVALUATE
MOVE D TO LEN-2
DISPLAY A B C D E F
DISPLAY A
DISPLAY B
DISPLAY C
DISPLAY D
DISPLAY E
DISPLAY F
.

END PROGRAM DEPENDS.

Here's three examples. (Word wrap will probably cause havoc, but hopefully
it will be understandable.)

Input:
ABCD990123456789ABCDEF00491234567890123456789012345678901234567890123456789!


Output:
**********0
ABCD990123456789ABCDEF00491234567890123456789012345678901234567890123456789!

ABCD
99
0123456789ABCDEF
0049
1234567890123456789012345678901234567890123456789
!

Input:
ABCD99U0123456789ABCDEFFEDCBA98765432100033123456789012345678901234567890123
!

Output:
**********U
ABCD99U0123456789ABCDEFFEDCBA98765432100033123456789012345678901234567890123
!
ABCD
99
U0123456789ABCDEFFEDCBA9876543210
0033
123456789012345678901234567890123
!

Input:
ABCD99T0123456789ABCDEFFEDCBA9876543210FFFFFFFFFFFFFFFF00161234567890123456!


Output:
**********T
ABCD99T0123456789ABCDEFFEDCBA9876543210FFFFFFFFFFFFFFFF00161234567890123456!

ABCD
99
T0123456789ABCDEFFEDCBA9876543210FFFFFFFFFFFFFFFF
0016
1234567890123456
!

I've got to say that I think it's a pretty elegant solution. Maybe is
absolutely obvious to everyone else, but hey I got there eventually! :-)

(Note to Roger While: OpenCobol does not like this program. I may take a
look at it someday. Or not. Probably fairly complicated to implement...)

To be honest, I have no idea how I'd do this in, say, C or Java, but I can't
imagine it would be any simpler.

Frank



---
Frank Swarbrick
Senior Developer/Analyst - Mainframe Applications
FirstBank Data Corporation - Lakewood, CO USA
.