*> ============================================================ *> 10-divide-50 : 请求书50分割 (Invoice 50-Split) *> Input : FILE-IN.DAT (请求书记录: 50件毎分割) *> Output: FILE-OUT-NN (50件毎の分割出力文件: FILE-OUT-01, 02...) *> Coverage: S-N001~N003, S-N006, S-N007, S-R001, S-R002 *> EXTENDED: Added file recovery, hash totals, boundary checks, *> split statistics, audit trail, inventory records, *> file status checking, error severity levels, *> header/trailer records, file-naming validation *> ============================================================ IDENTIFICATION DIVISION. PROGRAM-ID. Divide50. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT FILE-IN ASSIGN TO WS-FILE-IN-NAME ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-FILE-IN-STATUS. SELECT FILE-OUT ASSIGN TO WS-OUT-FILE ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-FILE-OUT-STATUS. SELECT FILE-AUDIT ASSIGN TO "AUDIT-OUT.DAT" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-FILE-AUDIT-STATUS. 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'. 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 50. 05 WS-QUOTIENT PIC 9(5). 05 WS-REMAINDER PIC 9(5). 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". *> ===== EXPANDED: Dynamic input file name ===== 01 WS-FILE-IN-NAME PIC X(30) VALUE "FILE-IN.DAT". *> ===== EXPANDED: File status fields ===== 01 WS-FILE-STATUS-VARS. 05 WS-FILE-IN-STATUS PIC X(2). 05 WS-FILE-OUT-STATUS PIC X(2). 05 WS-FILE-AUDIT-STATUS PIC X(2). *> ===== EXPANDED: Error handling with severity levels ===== 01 WS-ERROR-HANDLING. 05 WS-OPEN-RETRY-COUNT PIC 9(2) VALUE 0. 05 WS-OPEN-RETRY-MAX PIC 9(2) VALUE 3. 05 WS-ALT-SUFFIX PIC X(3) VALUE "ALT". 05 WS-ALT-OUT-FILE PIC X(30). 05 WS-SEVERITY PIC X(7). 88 WS-SEVERITY-WARNING VALUE 'WARNING'. 88 WS-SEVERITY-ERROR VALUE 'ERROR'. 88 WS-SEVERITY-FATAL VALUE 'FATAL'. *> ===== EXPANDED: File name validation flag ===== 01 WS-FILE-NAME-FLAGS. 05 WS-FILE-NAME-VALID PIC X VALUE 'Y'. 88 WS-FILE-NAME-OK VALUE 'Y' FALSE 'N'. 88 WS-FILE-NAME-BAD VALUE 'N'. 05 WS-NAME-CHAR-IDX PIC 9(2). 05 WS-NAME-CHAR-VAL PIC X(1). *> ===== EXPANDED: Hash totals for data integrity ===== 01 WS-HASH-TOTALS. 05 WS-HASH-TOTAL-IN PIC 9(12) VALUE 0. 05 WS-HASH-TOTAL-OUT PIC 9(12) VALUE 0. 05 WS-HASH-VERIFIED PIC X VALUE 'N'. 88 WS-HASH-MATCH VALUE 'Y' FALSE 'N'. *> ===== EXPANDED: Split statistics per output file ===== 01 WS-SPLIT-STATS. 05 WS-SPLIT-REC-COUNT PIC 9(5) VALUE 0. 05 WS-SPLIT-HASH-TOTAL PIC 9(12) VALUE 0. 05 WS-SPLIT-REC-MIN PIC X(30). 05 WS-SPLIT-REC-MAX PIC X(30). 05 WS-SPLIT-FIRST-REC PIC X(30). 05 WS-SPLIT-LAST-REC PIC X(30). *> ===== EXPANDED: Boundary condition flags ===== 01 WS-BOUNDARY-FLAG PIC X VALUE 'N'. 88 WS-BOUNDARY-EMPTY VALUE 'E'. 88 WS-BOUNDARY-SINGLE VALUE 'S'. 88 WS-BOUNDARY-EXACT VALUE 'X'. 88 WS-BOUNDARY-TRAILING VALUE 'T'. 01 WS-TRAILER-COUNT PIC 9(5) VALUE 0. *> ===== EXPANDED: Inventory table for output files ===== 01 WS-INVENTORY-TABLE. 05 WS-INVENTORY-ENTRIES PIC 9(2) VALUE 0. 05 WS-INVENTORY-ENTRY OCCURS 99 TIMES INDEXED BY WS-INV-IDX. 10 WS-INV-FILE-NUM PIC 9(2). 10 WS-INV-REC-COUNT PIC 9(5). 10 WS-INV-HASH-TOTAL PIC 9(12). *> ===== EXPANDED: Timestamp for display tracing ===== 01 WS-TIMESTAMP PIC X(14). *> ===== EXPANDED: Batch control totals ===== 01 WS-BATCH-CONTROLS. 05 WS-BATCH-TOTAL-RECS PIC 9(5) VALUE 0. *> ===== EXPANDED: Display edited fields ===== 01 WS-DISPLAY-EDITED. 05 WS-DISP-HASH-IN PIC Z(11)9. 05 WS-DISP-HASH-OUT PIC Z(11)9. 05 WS-DISP-SPLIT-COUNT PIC Z(9)9. 05 WS-DISP-SPLIT-HASH PIC Z(11)9. 05 WS-DISP-RETRY PIC Z9. 05 WS-DISP-TRAILER PIC Z(9)9. 05 WS-DISP-INV-RECS PIC Z(9)9. 05 WS-DISP-INV-HASH PIC Z(11)9. *> ===== EXPANDED: Hash computation work fields ===== 01 WS-HASH-WORK. 05 WS-HASH-VAL PIC 9(3). 05 WS-HASH-IDX PIC 9(2). 05 WS-HASH-ALLOC PIC 9(12). *> ===== EXPANDED: Inventory sum work fields ===== 01 WS-INVENTORY-SUM. 05 WS-INV-SUM-COUNT PIC 9(5) VALUE 0. 05 WS-INV-SUM-HASH PIC 9(12) VALUE 0. *> ===== EXPANDED: Audit report fields ===== 01 WS-AUDIT-LINE. 05 WS-AUDIT-TYPE PIC X(15). 05 WS-AUDIT-DATA PIC X(65). *> ===== EXPANDED: File name check constants ===== 01 WS-INVALID-CHARS. 05 WS-INVALID-CHAR PIC X(18) VALUE "!@#$%^&*()+=[]{}|;':<>?,/". PROCEDURE DIVISION. MAIN SECTION. MAIN-PROCEDURE. PERFORM 1000-INIT-SECTION PERFORM 2000-OPEN-FILES-SECTION PERFORM 3000-PROCESS-SECTION PERFORM 4000-REPORT-SECTION PERFORM 5000-AUDIT-SECTION PERFORM 9000-EXIT-SECTION STOP RUN. * 1000-INIT-SECTION. * 1000-INIT-PROC. MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "=== 50-DIVISION PROCESSING ===" DISPLAY "Records per file: " WS-DIVISOR DISPLAY "Init: " WS-TIMESTAMP DISPLAY " " INITIALIZE WS-FILE-STATUS-VARS WS-ERROR-HANDLING INITIALIZE WS-HASH-TOTALS WS-SPLIT-STATS INITIALIZE WS-BOUNDARY-FLAG WS-TRAILER-COUNT INITIALIZE WS-INVENTORY-TABLE WS-BATCH-CONTROLS INITIALIZE WS-INVENTORY-SUM WS-HASH-WORK MOVE "FILE-IN.DAT" TO WS-FILE-IN-NAME . * 2000-OPEN-FILES-SECTION. * 2000-OPEN-FILES-PROC. *> Open input file with status check OPEN INPUT FILE-IN MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP IF WS-FILE-IN-STATUS = "00" DISPLAY "[" WS-TIMESTAMP "] OPEN: FILE-IN.DAT OK" ELSE MOVE 'ERROR' TO WS-SEVERITY DISPLAY "[" WS-TIMESTAMP "] ERROR: FILE-IN open " "failed status=" WS-FILE-IN-STATUS MOVE "FILE-IN.ALT" TO WS-FILE-IN-NAME ADD 1 TO WS-OPEN-RETRY-COUNT OPEN INPUT FILE-IN IF WS-FILE-IN-STATUS = "00" DISPLAY "[" WS-TIMESTAMP "] OPEN: FILE-IN.ALT OK " "(retry=" WS-OPEN-RETRY-COUNT ")" ELSE MOVE 'FATAL' TO WS-SEVERITY DISPLAY "[" WS-TIMESTAMP "] FATAL: Cannot open " "FILE-IN after retry" PERFORM 6000-ERROR-HANDLE-SECTION END-IF END-IF OPEN OUTPUT FILE-AUDIT IF WS-FILE-AUDIT-STATUS = "00" DISPLAY "[" WS-TIMESTAMP "] OPEN: AUDIT-OUT.DAT OK" ELSE DISPLAY "[" WS-TIMESTAMP "] WARNING: AUDIT open " "failed status=" WS-FILE-AUDIT-STATUS END-IF MOVE "AUDIT-START" TO WS-AUDIT-TYPE STRING "Session started " WS-TIMESTAMP " divisor=" WS-DIVISOR " input=" WS-FILE-IN-NAME INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC . * 3000-PROCESS-SECTION. * 3000-PROCESS-PROC. MOVE "AUDIT-PROCESS" TO WS-AUDIT-TYPE STRING "Processing started, input=" WS-FILE-IN-NAME INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC 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 *> Close and finalize the last output file IF WS-FILE-NUM > 0 PERFORM 3500-FINALIZE-FILE-SECTION CLOSE FILE-OUT IF WS-FILE-OUT-STATUS NOT = "00" DISPLAY "WARNING: FILE-OUT close status=" WS-FILE-OUT-STATUS END-IF MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] Closed final file: " WS-OUT-FILE END-IF . * 3100-READ-INPUT-SECTION. * 3100-READ-INPUT-PROC. READ FILE-IN INTO FILE-IN-REC AT END SET WS-EOF TO TRUE NOT AT END ADD 1 TO WS-BATCH-TOTAL-RECS MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] Read record " WS-REC-COUNT END-READ IF WS-FILE-IN-STATUS NOT = "00" AND WS-FILE-IN-STATUS NOT = "10" MOVE 'ERROR' TO WS-SEVERITY DISPLAY "ERROR: FILE-IN read failed, status=" WS-FILE-IN-STATUS " at record " WS-REC-COUNT PERFORM 6000-ERROR-HANDLE-SECTION END-IF . * 3200-VALIDATE-SECTION. * 3200-VALIDATE-PROC. *> Check for empty record IF IN-RECORD = SPACES MOVE 'WARNING' TO WS-SEVERITY DISPLAY "WARNING: Record " WS-REC-COUNT " is empty" PERFORM 6000-ERROR-HANDLE-SECTION END-IF *> Compute input hash total contribution PERFORM VARYING WS-HASH-IDX FROM 1 BY 1 UNTIL WS-HASH-IDX > 30 COMPUTE WS-HASH-VAL = FUNCTION ORD( IN-RECORD(WS-HASH-IDX:1)) ADD WS-HASH-VAL TO WS-HASH-TOTAL-IN END-PERFORM . * 3300-APPLY-RULES-SECTION. * *> === ORIGINAL DIVIDE LOGIC — preserved intact === 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 PERFORM 3500-FINALIZE-FILE-SECTION CLOSE FILE-OUT IF WS-FILE-OUT-STATUS NOT = "00" DISPLAY "WARNING: Close status=" WS-FILE-OUT-STATUS END-IF MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] 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 PERFORM 3310-VALIDATE-FILE-NAME PERFORM 3320-OPEN-OUTPUT-WITH-RETRY PERFORM 3330-WRITE-SPLIT-HEADER END-IF . * 3310-VALIDATE-FILE-NAME. * 3310-VALIDATE-NAME-PROC. MOVE 'Y' TO WS-FILE-NAME-VALID *> Check for empty name IF WS-OUT-FILE = SPACES MOVE 'N' TO WS-FILE-NAME-VALID MOVE 'ERROR' TO WS-SEVERITY DISPLAY "ERROR: Empty output file name" PERFORM 6000-ERROR-HANDLE-SECTION EXIT PARAGRAPH END-IF *> Check for invalid characters in file name PERFORM VARYING WS-NAME-CHAR-IDX FROM 1 BY 1 UNTIL WS-NAME-CHAR-IDX > 30 OR WS-FILE-NAME-VALID = 'N' IF WS-OUT-FILE(WS-NAME-CHAR-IDX:1) = SPACE EXIT PERFORM END-IF MOVE WS-OUT-FILE(WS-NAME-CHAR-IDX:1) TO WS-NAME-CHAR-VAL MOVE 0 TO WS-HASH-ALLOC INSPECT WS-INVALID-CHARS TALLYING WS-HASH-ALLOC FOR ALL WS-NAME-CHAR-VAL IF WS-HASH-ALLOC > 0 MOVE 'N' TO WS-FILE-NAME-VALID MOVE 'ERROR' TO WS-SEVERITY DISPLAY "ERROR: Invalid char in file name '" WS-OUT-FILE "'" PERFORM 6000-ERROR-HANDLE-SECTION EXIT PARAGRAPH END-IF END-PERFORM . * 3320-OPEN-OUTPUT-WITH-RETRY. * 3320-RETRY-PROC. MOVE 0 TO WS-OPEN-RETRY-COUNT MOVE WS-OUT-FILE TO WS-ALT-OUT-FILE . 3320-RETRY-LOOP. OPEN OUTPUT FILE-OUT MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP IF WS-FILE-OUT-STATUS = "00" DISPLAY "[" WS-TIMESTAMP "] Opened: " WS-OUT-FILE ELSE ADD 1 TO WS-OPEN-RETRY-COUNT IF WS-OPEN-RETRY-COUNT <= WS-OPEN-RETRY-MAX DISPLAY "[" WS-TIMESTAMP "] RETRY " WS-OPEN-RETRY-COUNT ": " WS-OUT-FILE " status=" WS-FILE-OUT-STATUS STRING "FILE-OUT-" WS-FILE-NUM-ED "-" WS-ALT-SUFFIX ".DAT" DELIMITED BY SIZE INTO WS-OUT-FILE END-STRING GO TO 3320-RETRY-LOOP ELSE MOVE 'FATAL' TO WS-SEVERITY DISPLAY "[" WS-TIMESTAMP "] FATAL: " "Open failed after " WS-OPEN-RETRY-MAX " retries" PERFORM 6000-ERROR-HANDLE-SECTION END-IF END-IF . * 3330-WRITE-SPLIT-HEADER. * 3330-HEADER-PROC. *> Initialize split statistics for new output file MOVE 0 TO WS-SPLIT-REC-COUNT MOVE 0 TO WS-SPLIT-HASH-TOTAL MOVE SPACES TO WS-SPLIT-REC-MIN MOVE SPACES TO WS-SPLIT-REC-MAX MOVE SPACES TO WS-SPLIT-FIRST-REC MOVE SPACES TO WS-SPLIT-LAST-REC *> Write header record to output file MOVE SPACES TO FILE-OUT-REC STRING "HDR" WS-FILE-NUM-ED " SPLIT START" INTO OUT-RECORD END-STRING WRITE FILE-OUT-REC MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] Header: HDR" WS-FILE-NUM-ED " written to " WS-OUT-FILE . * 3400-WRITE-OUTPUT-SECTION. * *> === ORIGINAL WRITE LOGIC — preserved intact === 3400-WRITE-OUTPUT-PROC. MOVE IN-RECORD TO OUT-RECORD WRITE FILE-OUT-REC PERFORM 3410-UPDATE-SPLIT-STATS . * 3410-UPDATE-SPLIT-STATS. * 3410-STATS-PROC. ADD 1 TO WS-SPLIT-REC-COUNT *> Accumulate hash total for this split file PERFORM VARYING WS-HASH-IDX FROM 1 BY 1 UNTIL WS-HASH-IDX > 30 COMPUTE WS-HASH-VAL = FUNCTION ORD( OUT-RECORD(WS-HASH-IDX:1)) ADD WS-HASH-VAL TO WS-SPLIT-HASH-TOTAL ADD WS-HASH-VAL TO WS-HASH-TOTAL-OUT END-PERFORM *> Track min, max, first, last records per split IF WS-SPLIT-REC-COUNT = 1 MOVE IN-RECORD TO WS-SPLIT-REC-MIN MOVE IN-RECORD TO WS-SPLIT-REC-MAX MOVE IN-RECORD TO WS-SPLIT-FIRST-REC ELSE IF IN-RECORD < WS-SPLIT-REC-MIN MOVE IN-RECORD TO WS-SPLIT-REC-MIN END-IF IF IN-RECORD > WS-SPLIT-REC-MAX MOVE IN-RECORD TO WS-SPLIT-REC-MAX END-IF END-IF MOVE IN-RECORD TO WS-SPLIT-LAST-REC . * 3500-FINALIZE-FILE-SECTION. * *> Write trailer record and update inventory for closing file 3500-FINALIZE-PROC. MOVE SPACES TO FILE-OUT-REC MOVE WS-SPLIT-REC-COUNT TO WS-DISP-SPLIT-COUNT MOVE WS-SPLIT-HASH-TOTAL TO WS-DISP-SPLIT-HASH STRING "TRL" WS-FILE-NUM-ED " R=" WS-DISP-SPLIT-COUNT " H=" WS-DISP-SPLIT-HASH INTO OUT-RECORD END-STRING WRITE FILE-OUT-REC MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] Trailer: TRL" WS-FILE-NUM-ED " R=" WS-DISP-SPLIT-COUNT " H=" WS-DISP-SPLIT-HASH *> Update inventory table for this output file ADD 1 TO WS-INVENTORY-ENTRIES MOVE WS-FILE-NUM TO WS-INV-FILE-NUM(WS-INVENTORY-ENTRIES) MOVE WS-SPLIT-REC-COUNT TO WS-INV-REC-COUNT(WS-INVENTORY-ENTRIES) MOVE WS-SPLIT-HASH-TOTAL TO WS-INV-HASH-TOTAL(WS-INVENTORY-ENTRIES) *> Write inventory record to audit file MOVE "INVENTORY" TO WS-AUDIT-TYPE STRING "File=F" WS-FILE-NUM-ED " Recs=" WS-DISP-SPLIT-COUNT " Hash=" WS-DISP-SPLIT-HASH INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC . * 4000-REPORT-SECTION. * 4000-REPORT-PROC. MOVE WS-REC-COUNT TO WS-DISPLAY-COUNT DISPLAY " " DISPLAY "=== SPLIT REPORT ===" DISPLAY "Total records: " WS-DISPLAY-COUNT DISPLAY "Output files: " WS-FILE-NUM DISPLAY " " *> Boundary condition detection IF WS-BATCH-TOTAL-RECS = 0 SET WS-BOUNDARY-EMPTY TO TRUE DISPLAY "BOUNDARY: Empty input file" END-IF IF WS-BATCH-TOTAL-RECS = 1 SET WS-BOUNDARY-SINGLE TO TRUE DISPLAY "BOUNDARY: Single-record file" END-IF DIVIDE WS-BATCH-TOTAL-RECS BY WS-DIVISOR GIVING WS-QUOTIENT REMAINDER WS-REMAINDER IF WS-REMAINDER = 0 SET WS-BOUNDARY-EXACT TO TRUE DISPLAY "BOUNDARY: Exact multiple of " WS-DIVISOR ELSE SET WS-BOUNDARY-TRAILING TO TRUE MOVE WS-REMAINDER TO WS-TRAILER-COUNT MOVE WS-TRAILER-COUNT TO WS-DISP-TRAILER DISPLAY "BOUNDARY: Trailing records=" WS-DISP-TRAILER END-IF DISPLAY " " *> Hash total verification MOVE WS-HASH-TOTAL-IN TO WS-DISP-HASH-IN MOVE WS-HASH-TOTAL-OUT TO WS-DISP-HASH-OUT DISPLAY "Hash IN: " WS-DISP-HASH-IN DISPLAY "Hash OUT: " WS-DISP-HASH-OUT MOVE 0 TO WS-INV-SUM-HASH PERFORM VARYING WS-INV-SUM-COUNT FROM 1 BY 1 UNTIL WS-INV-SUM-COUNT > WS-INVENTORY-ENTRIES ADD WS-INV-HASH-TOTAL(WS-INV-SUM-COUNT) TO WS-INV-SUM-HASH END-PERFORM MOVE WS-INV-SUM-HASH TO WS-DISP-INV-HASH DISPLAY "Hash INV: " WS-DISP-INV-HASH IF WS-HASH-TOTAL-IN = WS-HASH-TOTAL-OUT AND WS-HASH-TOTAL-IN = WS-INV-SUM-HASH MOVE 'Y' TO WS-HASH-VERIFIED DISPLAY "HASH: VERIFIED" ELSE DISPLAY "HASH: MISMATCH!" END-IF DISPLAY " " *> Per-file inventory summary DISPLAY "-- Split File Inventory --" PERFORM VARYING WS-INV-SUM-COUNT FROM 1 BY 1 UNTIL WS-INV-SUM-COUNT > WS-INVENTORY-ENTRIES MOVE WS-INV-REC-COUNT(WS-INV-SUM-COUNT) TO WS-DISP-INV-RECS MOVE WS-INV-HASH-TOTAL(WS-INV-SUM-COUNT) TO WS-DISP-INV-HASH DISPLAY " F" WS-INV-FILE-NUM(WS-INV-SUM-COUNT) " recs=" WS-DISP-INV-RECS " hash=" WS-DISP-INV-HASH END-PERFORM . * 5000-AUDIT-SECTION. * 5000-AUDIT-PROC. MOVE "AUDIT-END" TO WS-AUDIT-TYPE STRING "Records=" WS-DISPLAY-COUNT " Files=" WS-FILE-NUM INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC IF WS-HASH-MATCH MOVE "HASH-VERIFIED" TO WS-AUDIT-TYPE ELSE MOVE "HASH-MISMATCH" TO WS-AUDIT-TYPE END-IF STRING "IN=" WS-DISP-HASH-IN " OUT=" WS-DISP-HASH-OUT INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC EVALUATE TRUE WHEN WS-BOUNDARY-EMPTY MOVE "BOUNDARY-EMPTY" TO WS-AUDIT-TYPE WHEN WS-BOUNDARY-SINGLE MOVE "BOUNDARY-SINGLE" TO WS-AUDIT-TYPE WHEN WS-BOUNDARY-EXACT MOVE "BOUNDARY-EXACT" TO WS-AUDIT-TYPE WHEN WS-BOUNDARY-TRAILING MOVE "BOUNDARY-TRAILING" TO WS-AUDIT-TYPE WHEN OTHER MOVE "BOUNDARY-NORMAL" TO WS-AUDIT-TYPE END-EVALUATE STRING "Records=" WS-DISPLAY-COUNT " Divisor=" WS-DIVISOR INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC PERFORM VARYING WS-INV-SUM-COUNT FROM 1 BY 1 UNTIL WS-INV-SUM-COUNT > WS-INVENTORY-ENTRIES MOVE WS-INV-FILE-NUM(WS-INV-SUM-COUNT) TO WS-FILE-NUM-ED MOVE WS-INV-REC-COUNT(WS-INV-SUM-COUNT) TO WS-DISP-INV-RECS MOVE WS-INV-HASH-TOTAL(WS-INV-SUM-COUNT) TO WS-DISP-INV-HASH STRING "FILE=FILE-OUT-" WS-FILE-NUM-ED ".DAT RECS=" WS-DISP-INV-RECS " HASH=" WS-DISP-INV-HASH INTO WS-AUDIT-DATA END-STRING MOVE "SPLIT-FILE" TO WS-AUDIT-TYPE MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC END-PERFORM MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] AUDIT: written" . * 6000-ERROR-HANDLE-SECTION. * 6000-ERROR-PROC. IF WS-SEVERITY = SPACES MOVE 'ERROR' TO WS-SEVERITY END-IF MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP DISPLAY "[" WS-TIMESTAMP "] " WS-SEVERITY IF WS-SEVERITY-FATAL DISPLAY "FATAL: Terminating at record " WS-REC-COUNT MOVE "FATAL-ERROR" TO WS-AUDIT-TYPE STRING "Fatal at record=" WS-REC-COUNT INTO WS-AUDIT-DATA END-STRING MOVE WS-AUDIT-LINE TO FILE-AUDIT-REC WRITE FILE-AUDIT-REC PERFORM 9000-EXIT-SECTION STOP RUN END-IF . * 9000-EXIT-SECTION. * 9000-EXIT-PROC. MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP CLOSE FILE-IN IF WS-FILE-IN-STATUS NOT = "00" DISPLAY "WARNING: FILE-IN close status=" WS-FILE-IN-STATUS END-IF CLOSE FILE-AUDIT IF WS-FILE-AUDIT-STATUS NOT = "00" AND WS-FILE-AUDIT-STATUS NOT = "42" DISPLAY "WARNING: AUDIT close status=" WS-FILE-AUDIT-STATUS END-IF DISPLAY "[" WS-TIMESTAMP "] Divide50 session ended" EXIT PROGRAM. .