MODULE 11 · SUBPROGRAMS AND COPYBOOKS · 5/8

GOBACK, STOP RUN and RETURN-CODE

15 min30 XPExercise

Three ways to finish

  • GOBACK returns to whoever called this program. In a subprogram it resumes the caller after the CALL; in a main program it returns to the operating system, ending the job step.
  • STOP RUN ends the whole run unit: the main program and every subprogram it called. Control never goes back to the caller.
  • EXIT PROGRAM returns from a called program like GOBACK, but in a main program it does nothing at all and execution carries on with the next statement.
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ENDINGS.
       PROCEDURE DIVISION.
           DISPLAY "BEFORE"
           CALL "QUITTER"
           DISPLAY "AFTER QUITTER"
           CALL "EXITER"
           DISPLAY "AFTER EXITER"
           CALL "STOPPER"
           DISPLAY "AFTER STOPPER"
           GOBACK.
       IDENTIFICATION DIVISION.
       PROGRAM-ID. QUITTER.
       PROCEDURE DIVISION.
           DISPLAY "IN QUITTER"
           GOBACK.
       END PROGRAM QUITTER.
       IDENTIFICATION DIVISION.
       PROGRAM-ID. EXITER.
       PROCEDURE DIVISION.
           DISPLAY "IN EXITER"
           EXIT PROGRAM.
       END PROGRAM EXITER.
       IDENTIFICATION DIVISION.
       PROGRAM-ID. STOPPER.
       PROCEDURE DIVISION.
           DISPLAY "IN STOPPER"
           MOVE 8 TO RETURN-CODE
           STOP RUN.
       END PROGRAM STOPPER.
       END PROGRAM ENDINGS.
BEFORE
IN QUITTER
AFTER QUITTER
IN EXITER
AFTER EXITER
IN STOPPER

AFTER STOPPER never appears, and the job step ends with return code 8.

The practical rule: end every program with GOBACK. It does the right thing whether the program runs as a main program or is called, so the same code can be reused either way. A STOP RUN buried in a shared routine is a bug waiting for the day someone calls it from a batch driver.

RETURN-CODE

RETURN-CODE is a special register, a numeric field you don't declare. Subprograms use it to report an outcome, and the conventional values are the same as JCL condition codes:

RC Meaning
0 All good
4 Warning: processed, but look at it
8 Error: this item was rejected
12, 16 Severe: something is badly wrong

The subprogram does MOVE 8 TO RETURN-CODE before GOBACK; the caller reads RETURN-CODE after the CALL. There is only one RETURN-CODE, so save it in your own field straight away:

           CALL "CHKACCT" USING WS-ACCT-REC
           MOVE RETURN-CODE TO WS-RC

When the main program finishes, whatever is in RETURN-CODE becomes the job step's condition code, the RC you see in the job log and that later steps test with COND. That is how a batch program tells operations "I ran, but with warnings".

Two traps follow from there being only one register:

  • A subprogram that doesn't set RETURN-CODE passes back whatever was already there. In GnuCOBOL, if the previous call left 8, a routine that never touches RETURN-CODE also appears to return 8. Set it on every path, including MOVE 0 TO RETURN-CODE for success.
  • A main program that calls such routines can accidentally end with the last call's code. Set the step's final RC deliberately before GOBACK or STOP RUN.

On the job

Many shops pass a status field in the parameter list instead of, or as well as, RETURN-CODE: a two-character code plus a message, defined in the routine's interface copybook. Whatever the convention, check it after every CALL. Ignoring a routine's error return is one of the most common findings in code review.

Your task

ACCTVAL (the starter; don't change it) checks account records before the nightly update. For each record it calls CHKACCT, reads RETURN-CODE, prints OK, WARNING or ERROR, and finally sets the job step's return code to the worst result it saw.

Write CHKACCT as a nested program. It receives the whole record:

       01  LS-ACCT-REC.
           05  LS-ACCT-NO   PIC X(8).
           05  LS-STATUS    PIC X.
           05  LS-BALANCE   PIC 9(7)V99.

and sets RETURN-CODE by the first rule that matches:

Rule RC
account number is not all digits 8
status is neither A (active) nor C (closed) 8
status C and balance above zero 4
balance above 50000.00 4
anything else 0

For the input

05
10000001A000125000
1000X002A000010000
10000003C000000000
10000004C000000150
10000005A006000000

the output is below, and the program must end with return code 8:

10000001 OK
1000X002 ERROR
10000003 OK
10000004 WARNING
10000005 WARNING
OK 002 WARNING 002 ERROR 001

Check your understanding

1. A subprogram executes STOP RUN. What happens to its caller?
2. What does EXIT PROGRAM do in a main program?
3. Why copy RETURN-CODE into your own field straight after a CALL?
fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.