feat: add benchmark-programs — 58 telecom COBOL test programs

作为子目录纳入系统,与核心测试管道协同

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NB-076
2026-06-25 09:53:21 +08:00
parent 50f9f0f52f
commit 94400d50d4
278 changed files with 44125 additions and 0 deletions
@@ -0,0 +1,696 @@
*> ============================================================
*> 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.
.