*> Input: FILE-IN.DAT Output: FILE-OUT-NN.DAT, AUDIT-11.RPT *> Original DIVIDE + expansions: I/O recovery, hash totals, *> header/trailer recs, split stats, audit trail, boundary *> checks, trailing recs, naming validation, file inventory, *> error severity levels (WARNING/ERROR/FATAL) IDENTIFICATION DIVISION. PROGRAM-ID. Divide25. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT FILE-IN ASSIGN TO "FILE-IN.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-FILE-STATUS-IN. SELECT FILE-OUT ASSIGN TO WS-OUT-FILE ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-FILE-STATUS-OUT. SELECT FILE-AUDIT ASSIGN TO "AUDIT-11.RPT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-FILE-STATUS-AUD. DATA DIVISION. FILE SECTION. FD FILE-IN. 01 FILE-IN-REC. 05 IN-RECORD PIC X(30). FD FILE-OUT. 01 FILE-OUT-REC. 05 OUT-RECORD PIC X(30). FD FILE-AUDIT. 01 FILE-AUDIT-REC PIC X(80). WORKING-STORAGE SECTION. 01 WS-TELECOM-REC. COPY "telecom/TEL-INVOICE.cpy". 01 WS-STATUS. 05 WS-EOF-FLAG PIC X VALUE 'N'. 88 WS-EOF VALUE 'Y' FALSE 'N'. 05 WS-FILE-STATUS-IN PIC X(2). 05 WS-FILE-STATUS-OUT PIC X(2). 05 WS-FILE-STATUS-AUD PIC X(2). 01 WS-COUNTERS. 05 WS-REC-COUNT PIC 9(5) VALUE 0. 05 WS-FILE-NUM PIC 9(2) VALUE 0. 05 WS-DIVISOR PIC 9(2) VALUE 25. 05 WS-QUOTIENT PIC 9(5). 05 WS-REMAINDER PIC 9(5). 05 WS-REC-IN-FILE PIC 9(5) VALUE 0. 05 WS-TOTAL-RECS-WRITTEN PIC 9(5) VALUE 0. 01 WS-OUT-FILE PIC X(30). 01 WS-FILE-NUM-ED PIC 99. 01 WS-DISPLAY-COUNT PIC Z(9)9. 01 WS-INVOICE-REC. COPY "telecom/TEL-INVOICE.cpy". 01 WS-TIMESTAMP. 05 WS-TS-DATE PIC 9(8). 05 WS-TS-TIME PIC 9(8). 05 WS-TS-EDITED PIC X(19). 01 WS-OPEN-RETRY-COUNT PIC 9(2) VALUE 0. 01 WS-ALT-SUFFIX PIC X(4) VALUE ".ALT". 01 WS-OPEN-OK PIC X VALUE 'N'. 88 WS-OPEN-SUCCESS VALUE 'Y' FALSE 'N'. 88 WS-OPEN-FAILED VALUE 'N'. 01 WS-FILE-NAME-VALID PIC X VALUE 'Y'. 88 WS-FILE-NAME-OK VALUE 'Y' FALSE 'N'. 01 WS-HASH-TOTAL-IN PIC 9(9) VALUE 0. 01 WS-HASH-OUT-TABLE. 05 WS-HASH-OUT PIC 9(9) OCCURS 99. 01 WS-HASH-SUM-OUT PIC 9(9) VALUE 0. 01 WS-HASH-VERIFIED PIC X VALUE 'N'. 88 WS-HASH-VERIFIED-YES VALUE 'Y' FALSE 'N'. 01 WS-SPLIT-STATS. 05 WS-SPLIT-MIN-RECS PIC 9(5) VALUE 99999. 05 WS-SPLIT-MAX-RECS PIC 9(5) VALUE 0. 05 WS-SPLIT-TOTAL-FILES PIC 9(5) VALUE 0. 05 WS-SPLIT-TOTAL-RECS PIC 9(9) VALUE 0. 05 WS-SPLIT-AVG-RECS PIC 9(5) VALUE 0. 01 WS-BOUNDARY-FLAG PIC X. 88 WS-BOUNDARY-EMPTY VALUE 'E'. 88 WS-BOUNDARY-SINGLE VALUE 'S'. 88 WS-BOUNDARY-EXACT VALUE 'M'. 88 WS-BOUNDARY-NORMAL VALUE 'N'. 01 WS-TRAILER-COUNT PIC 9(5) VALUE 0. 01 WS-TRAILER-FLAG PIC X VALUE 'N'. 88 WS-TRAILER-WRITTEN VALUE 'Y' FALSE 'N'. 01 WS-TRAIL-RECS-LAST PIC 9(5) VALUE 0. 01 WS-SEVERITY PIC X(7). 88 WS-SEVERITY-WARN VALUE 'WARNING'. 88 WS-SEVERITY-ERR VALUE 'ERROR'. 88 WS-SEVERITY-FATAL VALUE 'FATAL'. 01 WS-ERROR-MSG PIC X(60). 01 WS-SPLIT-HEADER. 05 FILLER PIC X(6) VALUE 'HEADER'. 05 FILLER PIC X VALUE SPACE. 05 WS-HDR-FILE PIC 9(2). 05 FILLER PIC X VALUE SPACE. 05 WS-HDR-DATE PIC 9(8). 05 FILLER PIC X VALUE SPACE. 05 WS-HDR-TIME PIC 9(8). 05 FILLER PIC X VALUE SPACE. 05 WS-HDR-EXPREC PIC 9(5). 01 WS-SPLIT-TRAILER. 05 FILLER PIC X(7) VALUE 'TRAILER'. 05 FILLER PIC X VALUE SPACE. 05 WS-TRL-FILE PIC 9(2). 05 FILLER PIC X VALUE SPACE. 05 WS-TRL-COUNT PIC 9(5). 05 FILLER PIC X VALUE SPACE. 05 WS-TRL-HASH PIC 9(9). 01 WS-HASH-WORK. 05 WS-H-CHAR-IDX PIC 99. 05 WS-H-CHAR PIC X. 05 WS-H-SUM PIC 9(9). 05 WS-H-ORD PIC 9(3). 01 WS-INVENTORY-REC. 05 WS-INV-FILE PIC 9(2). 05 FILLER PIC X(3) VALUE SPACES. 05 WS-INV-RECS PIC 9(5). 05 FILLER PIC X(3) VALUE SPACES. 05 WS-INV-HASH PIC 9(9). 01 WS-REPORT-LINE PIC X(80). 01 WS-I PIC 99. 01 WS-NEXT-REM PIC 9(5). 01 WS-HASH-DISP PIC Z(9)9. PROCEDURE DIVISION. MAIN SECTION. MAIN-PROCEDURE. PERFORM 1000-INIT-SECTION PERFORM 2000-OPEN-FILES-SECTION *> === Original code: banner === DISPLAY "=== 25-DIVISION PROCESSING ===" DISPLAY "Records per file: " WS-DIVISOR *> === Original code: processing loop === PERFORM 3000-PROCESS-SECTION PERFORM 3500-TRAILING-HANDLE-SECTION PERFORM 4000-REPORT-SECTION PERFORM 5000-AUDIT-SECTION PERFORM 9000-EXIT-SECTION STOP RUN. *> ============================================================ *> 1000-INIT-SECTION *> ============================================================ 1000-INIT-SECTION. 1000-INIT-PROC. ACCEPT WS-TS-DATE FROM DATE YYYYMMDD ACCEPT WS-TS-TIME FROM TIME STRING WS-TS-DATE(1:4) '-' WS-TS-DATE(5:2) '-' WS-TS-DATE(7:2) ' ' WS-TS-TIME(1:2) ':' WS-TS-TIME(3:2) ':' WS-TS-TIME(5:2) INTO WS-TS-EDITED END-STRING DISPLAY "=== Divide25 v2 Started " WS-TS-EDITED " ===" MOVE 'N' TO WS-BOUNDARY-FLAG MOVE 0 TO WS-SPLIT-TOTAL-FILES WS-SPLIT-TOTAL-RECS MOVE 99999 TO WS-SPLIT-MIN-RECS MOVE 0 TO WS-SPLIT-MAX-RECS WS-TRAILER-COUNT MOVE 'N' TO WS-TRAILER-FLAG WS-HASH-VERIFIED MOVE 0 TO WS-TRAIL-RECS-LAST WS-HASH-TOTAL-IN MOVE 'Y' TO WS-FILE-NAME-VALID DISPLAY "1000-INIT: All counters zeroed" . *> ============================================================ *> 2000-OPEN-FILES-SECTION — Retry + alt fallback for input *> ============================================================ 2000-OPEN-FILES-SECTION. 2000-OPEN-FILES-PROC. MOVE 0 TO WS-OPEN-RETRY-COUNT MOVE 'N' TO WS-OPEN-OK PERFORM UNTIL WS-OPEN-SUCCESS OR WS-OPEN-RETRY-COUNT > 3 OPEN INPUT FILE-IN IF WS-FILE-STATUS-IN = '00' MOVE 'Y' TO WS-OPEN-OK DISPLAY "2000-OPEN: FILE-IN.DAT OK" ELSE ADD 1 TO WS-OPEN-RETRY-COUNT MOVE 'WARNING' TO WS-SEVERITY STRING "2000: FILE-IN retry " WS-OPEN-RETRY-COUNT " sts=" WS-FILE-STATUS-IN INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF END-PERFORM IF WS-OPEN-FAILED STRING "FILE-IN" WS-ALT-SUFFIX INTO WS-OUT-FILE END-STRING OPEN INPUT FILE-IN IF WS-FILE-STATUS-IN = '00' MOVE 'Y' TO WS-OPEN-OK DISPLAY "2000-OPEN: ALT file opened" ELSE MOVE 'FATAL' TO WS-SEVERITY STRING "2000: FILE-IN open failed all retry" INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION PERFORM 9000-EXIT-SECTION END-IF END-IF OPEN OUTPUT FILE-AUDIT IF WS-FILE-STATUS-AUD NOT = '00' MOVE 'FATAL' TO WS-SEVERITY STRING "2000: AUDIT open fail sts=" WS-FILE-STATUS-AUD INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION PERFORM 9000-EXIT-SECTION ELSE DISPLAY "2000-OPEN: AUDIT-11.RPT OK" STRING "*** Divide25 v2 START *** " WS-TS-EDITED INTO WS-REPORT-LINE WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE END-IF . *> ============================================================ *> 3000-PROCESS-SECTION — Read/validate/apply/write loop *> ============================================================ 3000-PROCESS-SECTION. 3000-PROCESS-PROC. PERFORM VARYING WS-REC-COUNT FROM 1 BY 1 UNTIL WS-EOF PERFORM 3100-READ-INPUT-SECTION IF NOT WS-EOF PERFORM 3200-VALIDATE-SECTION PERFORM 3300-APPLY-RULES-SECTION PERFORM 3400-WRITE-OUTPUT-SECTION END-IF END-PERFORM . *> ============================================================ *> 3100-READ-INPUT-SECTION — Read + FILE STATUS check *> ============================================================ 3100-READ-INPUT-SECTION. 3100-READ-INPUT-PROC. READ FILE-IN INTO FILE-IN-REC AT END SET WS-EOF TO TRUE DISPLAY "3100-READ: EOF at " WS-REC-COUNT NOT AT END IF WS-FILE-STATUS-IN NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING "3100: FILE-IN read err sts=" WS-FILE-STATUS-IN INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF END-READ . *> ============================================================ *> 3200-VALIDATE-SECTION — Hash sum + boundary detect *> ============================================================ 3200-VALIDATE-SECTION. 3200-VALIDATE-PROC. MOVE 0 TO WS-H-SUM PERFORM VARYING WS-H-CHAR-IDX FROM 1 BY 1 UNTIL WS-H-CHAR-IDX > 30 MOVE IN-RECORD(WS-H-CHAR-IDX:1) TO WS-H-CHAR IF WS-H-CHAR NOT = SPACE COMPUTE WS-H-ORD = FUNCTION ORD(WS-H-CHAR) ADD WS-H-ORD TO WS-H-SUM END-IF END-PERFORM ADD WS-H-SUM TO WS-HASH-TOTAL-IN IF WS-REC-COUNT = 1 MOVE 'S' TO WS-BOUNDARY-FLAG END-IF . *> ============================================================ *> 3300-APPLY-RULES-SECTION *> *** ORIGINAL DIVIDE LOGIC — PRESERVED VERBATIM *** *> ============================================================ 3300-APPLY-RULES-SECTION. 3300-APPLY-RULES-PROC. DIVIDE WS-REC-COUNT BY WS-DIVISOR GIVING WS-QUOTIENT REMAINDER WS-REMAINDER IF WS-REMAINDER = 1 IF WS-FILE-NUM > 0 CLOSE FILE-OUT DISPLAY " Closed: " WS-OUT-FILE END-IF ADD 1 TO WS-FILE-NUM MOVE WS-FILE-NUM TO WS-FILE-NUM-ED STRING "FILE-OUT-" DELIMITED BY SIZE WS-FILE-NUM-ED DELIMITED BY SIZE ".DAT" DELIMITED BY SIZE INTO WS-OUT-FILE OPEN OUTPUT FILE-OUT DISPLAY " Opened: " WS-OUT-FILE END-IF . *> ============================================================ *> 3400-WRITE-OUTPUT-SECTION — Header/data/trailer + hash *> ============================================================ 3400-WRITE-OUTPUT-SECTION. 3400-WRITE-OUTPUT-PROC. IF WS-REMAINDER = 1 MOVE WS-FILE-NUM TO WS-HDR-FILE MOVE WS-TS-DATE TO WS-HDR-DATE MOVE WS-TS-TIME TO WS-HDR-TIME MOVE WS-DIVISOR TO WS-HDR-EXPREC MOVE WS-SPLIT-HEADER TO FILE-OUT-REC WRITE FILE-OUT-REC IF WS-FILE-STATUS-OUT NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING "3400: HDR write fail file=" WS-FILE-NUM " sts=" WS-FILE-STATUS-OUT INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF MOVE 0 TO WS-REC-IN-FILE MOVE 0 TO WS-HASH-OUT(WS-FILE-NUM) MOVE 'N' TO WS-TRAILER-FLAG END-IF *> Write data record (original MOVE/WRITE preserved) MOVE IN-RECORD TO OUT-RECORD WRITE FILE-OUT-REC IF WS-FILE-STATUS-OUT NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING "3400: Write fail file=" WS-FILE-NUM " rec=" WS-REC-COUNT " sts=" WS-FILE-STATUS-OUT INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION ELSE ADD 1 TO WS-REC-IN-FILE ADD 1 TO WS-TOTAL-RECS-WRITTEN ADD WS-H-SUM TO WS-HASH-OUT(WS-FILE-NUM) END-IF *> Write trailer when next record starts new file COMPUTE WS-NEXT-REM = FUNCTION MOD(WS-REC-COUNT + 1, WS-DIVISOR) IF WS-NEXT-REM = 1 MOVE WS-FILE-NUM TO WS-TRL-FILE MOVE WS-REC-IN-FILE TO WS-TRL-COUNT MOVE WS-HASH-OUT(WS-FILE-NUM) TO WS-TRL-HASH MOVE WS-SPLIT-TRAILER TO FILE-OUT-REC WRITE FILE-OUT-REC IF WS-FILE-STATUS-OUT NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING "3400: TRL write fail file=" WS-FILE-NUM " sts=" WS-FILE-STATUS-OUT INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-TRAILER-COUNT MOVE 'Y' TO WS-TRAILER-FLAG ADD 1 TO WS-SPLIT-TOTAL-FILES ADD WS-REC-IN-FILE TO WS-SPLIT-TOTAL-RECS IF WS-REC-IN-FILE < WS-SPLIT-MIN-RECS MOVE WS-REC-IN-FILE TO WS-SPLIT-MIN-RECS END-IF IF WS-REC-IN-FILE > WS-SPLIT-MAX-RECS MOVE WS-REC-IN-FILE TO WS-SPLIT-MAX-RECS END-IF END-IF . *> ============================================================ *> 3500-TRAILING-HANDLE-SECTION — Last file trailer, *> boundary classification *> ============================================================ 3500-TRAILING-HANDLE-SECTION. 3500-TRAILING-HANDLE-PROC. IF WS-FILE-NUM > 0 IF WS-TRAILER-FLAG = 'N' MOVE WS-FILE-NUM TO WS-TRL-FILE MOVE WS-REC-IN-FILE TO WS-TRL-COUNT MOVE WS-HASH-OUT(WS-FILE-NUM) TO WS-TRL-HASH MOVE WS-SPLIT-TRAILER TO FILE-OUT-REC WRITE FILE-OUT-REC IF WS-FILE-STATUS-OUT NOT = '00' MOVE 'ERROR' TO WS-SEVERITY STRING "3500: TRL write fail last file" INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF ADD 1 TO WS-TRAILER-COUNT MOVE 'Y' TO WS-TRAILER-FLAG MOVE WS-REC-IN-FILE TO WS-TRAIL-RECS-LAST ADD 1 TO WS-SPLIT-TOTAL-FILES ADD WS-REC-IN-FILE TO WS-SPLIT-TOTAL-RECS IF WS-REC-IN-FILE < WS-SPLIT-MIN-RECS MOVE WS-REC-IN-FILE TO WS-SPLIT-MIN-RECS END-IF IF WS-REC-IN-FILE > WS-SPLIT-MAX-RECS MOVE WS-REC-IN-FILE TO WS-SPLIT-MAX-RECS END-IF DISPLAY "3500-TRAIL: Last trailer written" END-IF ELSE MOVE 'E' TO WS-BOUNDARY-FLAG DISPLAY "3500-TRAIL: Empty input file" END-IF IF WS-TOTAL-RECS-WRITTEN = 0 MOVE 'E' TO WS-BOUNDARY-FLAG END-IF IF WS-TOTAL-RECS-WRITTEN = 1 MOVE 'S' TO WS-BOUNDARY-FLAG DISPLAY "3500-TRAIL: Single-record file" END-IF IF WS-SPLIT-TOTAL-FILES > 1 IF WS-SPLIT-MIN-RECS = WS-SPLIT-MAX-RECS MOVE 'M' TO WS-BOUNDARY-FLAG DISPLAY "3500-TRAIL: Exact multiple split" END-IF END-IF . *> ============================================================ *> 4000-REPORT-SECTION — Display + audit file stats/inventory *> ============================================================ 4000-REPORT-SECTION. 4000-REPORT-PROC. DISPLAY " " DISPLAY "=== SPLIT STATISTICS REPORT ===" MOVE WS-REC-COUNT TO WS-DISPLAY-COUNT DISPLAY "Total records read: " WS-DISPLAY-COUNT DISPLAY "Total records written: " WS-TOTAL-RECS-WRITTEN DISPLAY "Output files created: " WS-FILE-NUM DISPLAY "Divisor: " WS-DIVISOR IF WS-SPLIT-TOTAL-FILES > 0 COMPUTE WS-SPLIT-AVG-RECS = WS-SPLIT-TOTAL-RECS / WS-SPLIT-TOTAL-FILES ELSE MOVE 0 TO WS-SPLIT-AVG-RECS END-IF DISPLAY "Split files counted: " WS-SPLIT-TOTAL-FILES DISPLAY "Min recs per file: " WS-SPLIT-MIN-RECS DISPLAY "Max recs per file: " WS-SPLIT-MAX-RECS DISPLAY "Avg recs per file: " WS-SPLIT-AVG-RECS DISPLAY "Trailer recs written: " WS-TRAILER-COUNT DISPLAY "Trailing recs last file: " WS-TRAIL-RECS-LAST DISPLAY "Boundary condition: " WS-BOUNDARY-FLAG STRING "*** SPLIT STATS *** Total=" WS-SPLIT-TOTAL-RECS " Files=" WS-SPLIT-TOTAL-FILES " Min=" WS-SPLIT-MIN-RECS " Max=" WS-SPLIT-MAX-RECS INTO WS-REPORT-LINE WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE IF WS-FILE-STATUS-AUD NOT = '00' MOVE 'WARNING' TO WS-SEVERITY STRING "4000: Audit write sts=" WS-FILE-STATUS-AUD INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF STRING "*** OUTPUT FILE INVENTORY ***" INTO WS-REPORT-LINE WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-FILE-NUM MOVE WS-I TO WS-INV-FILE IF WS-I < WS-FILE-NUM MOVE WS-DIVISOR TO WS-INV-RECS ELSE MOVE WS-REC-IN-FILE TO WS-INV-RECS END-IF MOVE WS-HASH-OUT(WS-I) TO WS-INV-HASH STRING "FILE " WS-INV-FILE " RECS=" WS-INV-RECS " HASH=" WS-INV-HASH INTO WS-REPORT-LINE WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE END-PERFORM . *> ============================================================ *> 5000-AUDIT-SECTION — Hash total verification *> ============================================================ 5000-AUDIT-SECTION. 5000-AUDIT-PROC. DISPLAY "=== HASH TOTAL VERIFICATION ===" MOVE 0 TO WS-HASH-SUM-OUT PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-FILE-NUM ADD WS-HASH-OUT(WS-I) TO WS-HASH-SUM-OUT END-PERFORM MOVE WS-HASH-TOTAL-IN TO WS-HASH-DISP DISPLAY "Input hash: " WS-HASH-DISP MOVE WS-HASH-SUM-OUT TO WS-HASH-DISP DISPLAY "Output hash: " WS-HASH-DISP DISPLAY "Files hashed: " WS-FILE-NUM IF WS-HASH-TOTAL-IN = WS-HASH-SUM-OUT MOVE 'Y' TO WS-HASH-VERIFIED DISPLAY "Hash verification: PASSED" STRING "*** HASH VERIFICATION PASSED ***" INTO WS-REPORT-LINE ELSE MOVE 'N' TO WS-HASH-VERIFIED DISPLAY "Hash verification: FAILED" MOVE 'ERROR' TO WS-SEVERITY STRING "5000: Hash mismatch IN=" WS-HASH-TOTAL-IN " OUT=" WS-HASH-SUM-OUT INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION STRING "*** HASH VERIFICATION FAILED ***" INTO WS-REPORT-LINE END-IF WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE . *> ============================================================ *> 6000-ERROR-HANDLE-SECTION — Log with severity level *> ============================================================ 6000-ERROR-HANDLE-SECTION. 6000-ERROR-HANDLE-PROC. DISPLAY "*** " WS-SEVERITY " *** " WS-ERROR-MSG STRING "*** " WS-SEVERITY " *** " WS-ERROR-MSG INTO WS-REPORT-LINE WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE IF WS-FILE-STATUS-AUD NOT = '00' DISPLAY "6000: Audit write also failed" END-IF IF WS-SEVERITY-FATAL DISPLAY "6000: FATAL — terminating" PERFORM 9000-EXIT-SECTION END-IF . *> ============================================================ *> 9000-EXIT-SECTION — Close files, original summary *> *** ORIGINAL CLOSE / DISPLAY LOGIC PRESERVED *** *> ============================================================ 9000-EXIT-SECTION. 9000-EXIT-PROC. ACCEPT WS-TS-TIME FROM TIME STRING WS-TS-TIME(1:2) ':' WS-TS-TIME(3:2) ':' WS-TS-TIME(5:2) INTO WS-TS-EDITED END-STRING IF WS-FILE-NUM > 0 CLOSE FILE-OUT IF WS-FILE-STATUS-OUT NOT = '00' MOVE 'WARNING' TO WS-SEVERITY STRING "9000: FILE-OUT close sts=" WS-FILE-STATUS-OUT INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF DISPLAY "Closed final file: " WS-OUT-FILE END-IF MOVE WS-REC-COUNT TO WS-DISPLAY-COUNT DISPLAY " " DISPLAY "Total records read: " WS-DISPLAY-COUNT DISPLAY "Output files created: " WS-FILE-NUM CLOSE FILE-IN IF WS-FILE-STATUS-IN NOT = '00' MOVE 'WARNING' TO WS-SEVERITY STRING "9000: FILE-IN close sts=" WS-FILE-STATUS-IN INTO WS-ERROR-MSG END-STRING PERFORM 6000-ERROR-HANDLE-SECTION END-IF STRING "*** Divide25 v2 END *** " WS-TS-EDITED INTO WS-REPORT-LINE WRITE FILE-AUDIT-REC FROM WS-REPORT-LINE CLOSE FILE-AUDIT DISPLAY " " DISPLAY "--- Boundary condition ---" EVALUATE TRUE WHEN WS-BOUNDARY-EMPTY DISPLAY " EMPTY FILE (0 records)" WHEN WS-BOUNDARY-SINGLE DISPLAY " SINGLE-RECORD FILE" WHEN WS-BOUNDARY-EXACT DISPLAY " EXACT MULTIPLE of " WS-DIVISOR WHEN WS-BOUNDARY-NORMAL DISPLAY " NORMAL (trailing partial batch)" WHEN OTHER DISPLAY " NOT DETERMINED" END-EVALUATE DISPLAY "--- Data Integrity ---" MOVE WS-HASH-TOTAL-IN TO WS-HASH-DISP DISPLAY " Input hash: " WS-HASH-DISP MOVE WS-HASH-SUM-OUT TO WS-HASH-DISP DISPLAY " Output hash: " WS-HASH-DISP IF WS-HASH-VERIFIED-YES DISPLAY " Integrity: PASSED" ELSE DISPLAY " Integrity: FAILED" END-IF DISPLAY " " DISPLAY "=== Divide25 v2 Ended at " WS-TS-EDITED " ===" STOP RUN.