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,674 @@
*> ============================================================
*> 30-keybreak-other : 通话状态检测 (Call State Detect)
*> Input : FILE-IN.DAT Output: FILE-OUT.DAT + FILE-AUDIT.DAT
*> 2-level key detect, overflow, page control, hash totals,
*> error severity, call state, group min/max/avg, grand total
*> ============================================================
IDENTIFICATION DIVISION.
PROGRAM-ID. KeyBreakOther.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-IN
ASSIGN TO "FILE-IN.DAT"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-IN.
SELECT FILE-OUT
ASSIGN TO "FILE-OUT.DAT"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-OUT.
SELECT FILE-AUDIT
ASSIGN TO "FILE-AUDIT.DAT"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS FS-AUDIT.
DATA DIVISION.
FILE SECTION.
FD FILE-IN.
01 FILE-IN-REC.
05 IN-KEY PIC X(10).
05 IN-DATA PIC X(30).
FD FILE-OUT.
01 FILE-OUT-REC PIC X(120).
FD FILE-AUDIT.
01 FILE-AUDIT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-TELECOM-REC.
COPY "telecom/TEL-BILLING.cpy".
01 FS-IN PIC X(2).
01 FS-OUT PIC X(2).
01 FS-AUDIT PIC X(2).
01 WS-STATUS.
05 WS-EOF-FLAG PIC X VALUE 'N'.
88 WS-EOF VALUE 'Y' FALSE 'N'.
05 WS-FIRST-REC PIC X VALUE 'Y'.
88 WS-FIRST VALUE 'Y' FALSE 'N'.
01 WS-PREV-KEY PIC X(10).
01 WS-CURRENT-KEY PIC X(10).
01 WS-PREV-SUBKEY PIC X(5).
01 WS-CURRENT-SUBKEY PIC X(5).
01 WS-CALL-STATE PIC X(10) VALUE 'INITIAL'.
01 WS-DATE-TIME.
05 WS-DATE PIC X(10).
05 WS-TIME PIC X(10).
01 WS-TIMESTAMP PIC X(21).
01 WS-MARKER-LINE.
05 FILLER PIC X(20) VALUE '*** KEY CHANGE TO: '.
05 WS-MARKER-KEY PIC X(10).
05 FILLER PIC X(5) VALUE ' ***'.
05 FILLER PIC X(2) VALUE ' ['.
05 WS-MARKER-TS PIC X(21).
05 FILLER PIC X(2) VALUE '] '.
05 WS-MARKER-SEQ PIC Z(9)9.
01 WS-SUB-MARKER.
05 FILLER PIC X(20) VALUE '--- SUB KEY CHANGE: '.
05 WS-SUB-MARK-KEY PIC X(5).
05 FILLER PIC X(5) VALUE ' ---'.
05 FILLER PIC X(2) VALUE ' ['.
05 WS-SUB-MARK-TS PIC X(21).
05 FILLER PIC X(2) VALUE '] '.
05 WS-SUB-MARK-SEQ PIC Z(9)9.
01 WS-GROUP-HEADER.
05 FILLER PIC X(16) VALUE '>>> GROUP START: '.
05 WS-GH-KEY PIC X(10).
05 FILLER PIC X(2) VALUE ' ['.
05 WS-GH-TS PIC X(21).
05 FILLER PIC X(2) VALUE ']'.
01 WS-DATA-OUT.
05 OUT-KEY PIC X(10).
05 FILLER PIC X VALUE SPACE.
05 OUT-DATA PIC X(30).
05 FILLER PIC X(2) VALUE SPACE.
05 OUT-STATE PIC X(10).
01 WS-RECORDS-READ PIC 9(5) VALUE 0.
01 WS-RECORDS-WRITTEN PIC 9(5) VALUE 0.
01 WS-KEY-CHANGES PIC 9(5) VALUE 0.
01 WS-SUB-CHANGES PIC 9(5) VALUE 0.
01 WS-GROUPS-TOTAL PIC 9(5) VALUE 0.
01 WS-SUBGROUPS-TOTAL PIC 9(5) VALUE 0.
01 WS-MARKER-SEQ-NUM PIC 9(5) VALUE 0.
01 WS-GROUP-COUNT PIC 9(5) VALUE 0.
01 WS-GROUP-DUR PIC 9(10) VALUE 0.
01 WS-GROUP-MIN PIC 9(10) VALUE 9999999999.
01 WS-GROUP-MAX PIC 9(10) VALUE 0.
01 WS-GROUP-AVG PIC 9(10)V99.
01 WS-SUBGROUP-COUNT PIC 9(5) VALUE 0.
01 WS-SUBGROUP-DUR PIC 9(10) VALUE 0.
01 WS-SUBGROUP-MIN PIC 9(10) VALUE 9999999999.
01 WS-SUBGROUP-MAX PIC 9(10) VALUE 0.
01 WS-SUBGROUP-AVG PIC 9(10)V99.
01 WS-GRAND-COUNT PIC 9(7) VALUE 0.
01 WS-GRAND-DUR PIC 9(12) VALUE 0.
01 WS-GROUP-FOOTER.
05 FILLER PIC X(14) VALUE '<<< GROUP END:'.
05 WS-GF-KEY PIC X(10).
05 FILLER PIC X(6) VALUE ' CNT='.
05 WS-GF-COUNT PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' DUR='.
05 WS-GF-DUR PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' MIN='.
05 WS-GF-MIN PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' MAX='.
05 WS-GF-MAX PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' AVG='.
05 WS-GF-AVG PIC Z(9)9.99.
01 WS-SUBGROUP-FOOTER.
05 FILLER PIC X(16) VALUE '... SUB END:'.
05 WS-SGF-SUBKEY PIC X(5).
05 FILLER PIC X(6) VALUE ' CNT='.
05 WS-SGF-COUNT PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' DUR='.
05 WS-SGF-DUR PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' MIN='.
05 WS-SGF-MIN PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' MAX='.
05 WS-SGF-MAX PIC Z(9)9.
05 FILLER PIC X(5) VALUE ' AVG='.
05 WS-SGF-AVG PIC Z(9)9.99.
01 WS-GRAND-TOTAL-LINE.
05 FILLER PIC X(20) VALUE 'GRAND TOTAL: GROUPS='.
05 WS-GT-GROUPS PIC Z(9)9.
05 FILLER PIC X(6) VALUE ' RECS='.
05 WS-GT-RECS PIC Z(9)9.
05 FILLER PIC X(6) VALUE ' CHGS='.
05 WS-GT-CHGS PIC Z(9)9.
05 FILLER PIC X(6) VALUE ' SUB='.
05 WS-GT-SUB PIC Z(9)9.
05 FILLER PIC X(6) VALUE ' DUR='.
05 WS-GT-DUR PIC Z(11)9.
01 WS-PAGE-CONTROL.
05 WS-LINE-COUNT PIC 9(3) VALUE 0.
05 WS-PAGE-LENGTH PIC 9(3) VALUE 60.
05 WS-PAGE-NUM PIC 9(3) VALUE 1.
01 WS-PAGE-HEADER.
05 FILLER PIC X(6) VALUE 'PAGE '.
05 WS-PH-PAGE PIC Z(9)9.
05 FILLER PIC X(50) VALUE
' KEY BREAK DETECTION REPORT [TELECOM BILLING]'.
01 WS-OVERFLOW-FLAG PIC X VALUE 'N'.
88 WS-OVERFLOW VALUE 'Y' FALSE 'N'.
01 WS-MAX-TOTAL PIC 9(10) VALUE 9999999999.
01 WS-OVERFLOW-THRESH PIC 9(10) VALUE 9990000000.
01 WS-HASH-IN PIC 9(12) VALUE 0.
01 WS-HASH-OUT PIC 9(12) VALUE 0.
01 WS-HASH-VERIFIED PIC X(3) VALUE 'NO '.
88 WS-HASH-OK VALUE 'YES'.
01 WS-SEVERITY PIC X(10).
01 WS-ERROR-MSG PIC X(60).
01 WS-BATCH-TOTALS.
05 WS-ERROR-COUNT PIC 9(5) VALUE 0.
05 WS-WARN-COUNT PIC 9(5) VALUE 0.
01 WS-BATCH-ID PIC 9(5) VALUE 1.
01 WS-BATCH-DATE PIC X(10).
01 WS-BATCH-TIME PIC X(10).
01 WS-AUDIT-LINE.
05 AU-TIMESTAMP PIC X(21).
05 FILLER PIC X VALUE SPACE.
05 AU-TYPE PIC X(10).
05 FILLER PIC X VALUE SPACE.
05 AU-KEY PIC X(10).
05 FILLER PIC X VALUE SPACE.
05 AU-VALUE PIC Z(9)9.
05 FILLER PIC X VALUE SPACE.
05 AU-STATUS PIC X(20).
01 WS-TEMP-DUR PIC 9(10).
PROCEDURE DIVISION.
*> 1000-INIT-SECTION: initialize program state
1000-INIT-SECTION SECTION.
1000-INIT-PROC.
MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE
MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME
STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP
MOVE WS-DATE TO WS-BATCH-DATE
MOVE WS-TIME TO WS-BATCH-TIME
DISPLAY '[TIMESTAMP] ' WS-TIMESTAMP
DISPLAY '[STATUS ] KeyBreakOther STARTED'
DISPLAY '[BATCH ] ID=' WS-BATCH-ID
DISPLAY ' DATE=' WS-BATCH-DATE
DISPLAY ' TIME=' WS-BATCH-TIME
DISPLAY ' '
PERFORM 2000-OPEN-FILES-SECTION
.
*> 2000-OPEN-FILES-SECTION: open all files with status check
2000-OPEN-FILES-SECTION SECTION.
2000-OPEN-FILES-PROC.
DISPLAY '[FILE ] Opening FILE-IN.DAT...'
OPEN INPUT FILE-IN
IF FS-IN NOT = '00'
DISPLAY '[FATAL ] FILE-IN open failed FS=' FS-IN
STOP RUN
END-IF
DISPLAY '[OK ] FILE-IN opened, status=' FS-IN
DISPLAY '[FILE ] Opening FILE-OUT.DAT...'
OPEN OUTPUT FILE-OUT
IF FS-OUT NOT = '00'
DISPLAY '[FATAL ] FILE-OUT open failed FS=' FS-OUT
STOP RUN
END-IF
DISPLAY '[OK ] FILE-OUT opened, status=' FS-OUT
DISPLAY '[FILE ] Opening FILE-AUDIT.DAT...'
OPEN OUTPUT FILE-AUDIT
IF FS-AUDIT NOT = '00'
DISPLAY '[WARNING ] FILE-AUDIT open failed FS=' FS-AUDIT
MOVE 'WARNING' TO WS-SEVERITY
MOVE 'AUDIT file unavailable, continuing' TO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
ELSE
DISPLAY '[OK ] FILE-AUDIT opened, status=' FS-AUDIT
MOVE WS-TIMESTAMP TO AU-TIMESTAMP
MOVE 'START' TO AU-TYPE
MOVE 'BATCH' TO AU-KEY
MOVE WS-BATCH-ID TO AU-VALUE
MOVE 'OK' TO AU-STATUS
WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE
END-IF
DISPLAY ' '
PERFORM 3000-PROCESS-SECTION
.
*> 3000-PROCESS-SECTION: main processing loop
3000-PROCESS-SECTION SECTION.
3000-PROCESS-PROC.
DISPLAY '[PROCESS ] === KEY CHANGE DETECTION ==='
DISPLAY '[PROCESS ] Processing sorted FILE-IN records...'
DISPLAY ' '
PERFORM 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
3100-READ-INPUT-SECTION SECTION.
3100-READ-INPUT-PROC.
READ FILE-IN INTO FILE-IN-REC
AT END
SET WS-EOF TO TRUE
DISPLAY '[EOF ] FILE-IN end reached'
NOT AT END
ADD 1 TO WS-RECORDS-READ
IF FS-IN NOT = '00'
MOVE 'ERROR' TO WS-SEVERITY
STRING 'FILE-IN read FS=' FS-IN INTO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
END-IF
END-READ
.
*> 3200-VALIDATE-SECTION
3200-VALIDATE-SECTION SECTION.
3200-VALIDATE-PROC.
IF IN-KEY = SPACES
MOVE 'WARNING' TO WS-SEVERITY
MOVE 'Empty IN-KEY detected' TO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
END-IF
IF IN-DATA = SPACES
MOVE 'WARNING' TO WS-SEVERITY
MOVE 'Empty IN-DATA detected' TO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
END-IF
.
*> 3300-APPLY-RULES-SECTION: key-change + sub-key + stats + page ctl
3300-APPLY-RULES-SECTION SECTION.
3300-APPLY-RULES-PROC.
MOVE IN-KEY TO WS-CURRENT-KEY
MOVE IN-DATA (1:5) TO WS-CURRENT-SUBKEY
MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE
MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME
STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP
*> ORIGINAL LOGIC: Key change detection on IN-KEY
IF WS-FIRST
MOVE WS-CURRENT-KEY TO WS-PREV-KEY
MOVE WS-CURRENT-SUBKEY TO WS-PREV-SUBKEY
PERFORM WRITE-CHANGE-MARKER
PERFORM WRITE-SUB-MARKER
PERFORM WRITE-GROUP-HEADER
MOVE 'N' TO WS-FIRST-REC
MOVE 'ACTIVE' TO WS-CALL-STATE
ELSE
IF WS-CURRENT-KEY NOT = WS-PREV-KEY
MOVE 'ENDED' TO WS-CALL-STATE
PERFORM WRITE-GROUP-FOOTER
PERFORM WRITE-SUBGROUP-FOOTER
ADD 1 TO WS-KEY-CHANGES
MOVE WS-CURRENT-KEY TO WS-PREV-KEY
PERFORM WRITE-CHANGE-MARKER
MOVE WS-CURRENT-SUBKEY TO WS-PREV-SUBKEY
PERFORM WRITE-SUB-MARKER
PERFORM WRITE-GROUP-HEADER
PERFORM INIT-GROUP-ACCUM
PERFORM INIT-SUBGROUP-ACCUM
MOVE 'CHANGE' TO WS-CALL-STATE
ELSE
IF WS-CURRENT-SUBKEY NOT = WS-PREV-SUBKEY
PERFORM WRITE-SUBGROUP-FOOTER
ADD 1 TO WS-SUB-CHANGES
MOVE WS-CURRENT-SUBKEY TO WS-PREV-SUBKEY
PERFORM WRITE-SUB-MARKER
PERFORM INIT-SUBGROUP-ACCUM
MOVE 'CHANGE' TO WS-CALL-STATE
END-IF
END-IF
END-IF
*> Accumulate group statistics
ADD 1 TO WS-GROUP-COUNT
ADD 1 TO WS-SUBGROUP-COUNT
ADD 1 TO WS-GRAND-COUNT
ADD 1 TO WS-MARKER-SEQ-NUM
MOVE 100 TO WS-TEMP-DUR
IF IN-DATA (26:5) NOT = SPACES
COMPUTE WS-TEMP-DUR =
FUNCTION NUMVAL(IN-DATA (26:5))
IF WS-TEMP-DUR = 0
MOVE 100 TO WS-TEMP-DUR
END-IF
END-IF
ADD WS-TEMP-DUR TO WS-GROUP-DUR
ADD WS-TEMP-DUR TO WS-SUBGROUP-DUR
ADD WS-TEMP-DUR TO WS-GRAND-DUR
IF WS-TEMP-DUR < WS-GROUP-MIN
MOVE WS-TEMP-DUR TO WS-GROUP-MIN
END-IF
IF WS-TEMP-DUR > WS-GROUP-MAX
MOVE WS-TEMP-DUR TO WS-GROUP-MAX
END-IF
IF WS-TEMP-DUR < WS-SUBGROUP-MIN
MOVE WS-TEMP-DUR TO WS-SUBGROUP-MIN
END-IF
IF WS-TEMP-DUR > WS-SUBGROUP-MAX
MOVE WS-TEMP-DUR TO WS-SUBGROUP-MAX
END-IF
*> Hash total + overflow checks
COMPUTE WS-HASH-IN = WS-HASH-IN + WS-TEMP-DUR
IF WS-HASH-IN > WS-MAX-TOTAL
COMPUTE WS-HASH-IN = WS-HASH-IN - WS-MAX-TOTAL
SET WS-OVERFLOW TO TRUE
MOVE 'WARNING' TO WS-SEVERITY
MOVE 'Hash total overflow - wrapped' TO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
END-IF
IF WS-GROUP-DUR > WS-OVERFLOW-THRESH
SET WS-OVERFLOW TO TRUE
MOVE 'WARNING' TO WS-SEVERITY
STRING 'Group duration overflow KEY='
WS-PREV-KEY INTO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
END-IF
*> Page break control
ADD 1 TO WS-LINE-COUNT
IF WS-LINE-COUNT >= WS-PAGE-LENGTH
ADD 1 TO WS-PAGE-NUM
MOVE 0 TO WS-LINE-COUNT
PERFORM WRITE-PAGE-HEADER
END-IF
.
*> 3400-WRITE-OUTPUT-SECTION: data record + audit trail
3400-WRITE-OUTPUT-SECTION SECTION.
3400-WRITE-OUTPUT-PROC.
*> ORIGINAL: write key + data record
MOVE IN-KEY TO OUT-KEY
MOVE IN-DATA TO OUT-DATA
MOVE WS-CALL-STATE TO OUT-STATE
WRITE FILE-OUT-REC FROM WS-DATA-OUT
IF FS-OUT NOT = '00'
MOVE 'FATAL' TO WS-SEVERITY
STRING 'FILE-OUT write FS=' FS-OUT INTO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
END-IF
ADD 1 TO WS-RECORDS-WRITTEN
ADD 1 TO WS-HASH-OUT
MOVE WS-TIMESTAMP TO AU-TIMESTAMP
MOVE 'RECORD' TO AU-TYPE
MOVE IN-KEY TO AU-KEY
MOVE WS-RECORDS-READ TO AU-VALUE
MOVE 'OK' TO AU-STATUS
IF FS-AUDIT = '00'
WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE
END-IF
.
*> 4000-REPORT-SECTION: summary display and grand totals
4000-REPORT-SECTION SECTION.
4000-REPORT-PROC.
DISPLAY ' '
DISPLAY '=== SUMMARY ==='
DISPLAY ' Records read: ' WS-RECORDS-READ
DISPLAY ' Records written: ' WS-RECORDS-WRITTEN
DISPLAY ' Key changes: ' WS-KEY-CHANGES
DISPLAY ' Sub-key changes: ' WS-SUB-CHANGES
DISPLAY ' Groups total: ' WS-GROUPS-TOTAL
DISPLAY ' Sub-groups total:' WS-SUBGROUPS-TOTAL
DISPLAY ' Grand duration: ' WS-GRAND-DUR
DISPLAY ' Overflows: ' WS-OVERFLOW-FLAG
DISPLAY ' Page count: ' WS-PAGE-NUM
DISPLAY ' Hash input: ' WS-HASH-IN
DISPLAY ' Hash output: ' WS-HASH-OUT
IF WS-HASH-IN = WS-HASH-OUT
MOVE 'YES' TO WS-HASH-VERIFIED
DISPLAY ' HASH: VERIFICATION PASSED'
ELSE
DISPLAY ' HASH: VERIFICATION FAILED'
END-IF
IF WS-GRAND-COUNT NOT = WS-RECORDS-READ
MOVE 'ERROR' TO WS-SEVERITY
STRING 'GRAND TOTAL MISMATCH read='
WS-RECORDS-READ ' count=' WS-GRAND-COUNT
INTO WS-ERROR-MSG
PERFORM 6000-ERROR-HANDLE-SECTION
DISPLAY ' ** GRAND TOTAL VERIFY FAILED **'
ELSE
DISPLAY ' ** Grand total verified OK **'
END-IF
DISPLAY ' Output: FILE-OUT.DAT Audit: FILE-AUDIT.DAT'
.
*> 5000-AUDIT-SECTION: audit log finish
5000-AUDIT-SECTION SECTION.
5000-AUDIT-PROC.
MOVE WS-TIMESTAMP TO AU-TIMESTAMP
MOVE 'END' TO AU-TYPE
MOVE 'BATCH' TO AU-KEY
MOVE WS-BATCH-ID TO AU-VALUE
STRING 'REC=' WS-RECORDS-READ ' CHG=' WS-KEY-CHANGES
' SUB=' WS-SUB-CHANGES INTO AU-STATUS
IF FS-AUDIT = '00'
WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE
END-IF
DISPLAY ' '
DISPLAY '[AUDIT ] Batch=' WS-BATCH-ID
DISPLAY ' Recs=' WS-RECORDS-READ
DISPLAY ' Chgs=' WS-KEY-CHANGES
DISPLAY ' Sub =' WS-SUB-CHANGES
DISPLAY ' Err =' WS-ERROR-COUNT
DISPLAY ' Warn=' WS-WARN-COUNT
.
*> 6000-ERROR-HANDLE-SECTION: handle errors by severity
6000-ERROR-HANDLE-SECTION SECTION.
6000-ERROR-HANDLE-PROC.
DISPLAY '[TIMESTAMP] ' WS-TIMESTAMP
DISPLAY '[' WS-SEVERITY '] ' WS-ERROR-MSG
IF WS-SEVERITY = 'FATAL'
PERFORM 9000-EXIT-SECTION
STOP RUN
ELSE
IF WS-SEVERITY = 'ERROR'
ADD 1 TO WS-ERROR-COUNT
ELSE
IF WS-SEVERITY = 'WARNING'
ADD 1 TO WS-WARN-COUNT
END-IF
END-IF
END-IF
.
*> 9000-EXIT-SECTION: clean up and exit
9000-EXIT-SECTION SECTION.
9000-EXIT-PROC.
MOVE FUNCTION CURRENT-DATE (1:10) TO WS-DATE
MOVE FUNCTION CURRENT-DATE (12:8) TO WS-TIME
STRING WS-DATE ' ' WS-TIME INTO WS-TIMESTAMP
IF WS-RECORDS-READ > 0
PERFORM WRITE-GROUP-FOOTER
PERFORM WRITE-SUBGROUP-FOOTER
PERFORM WRITE-GRAND-TOTAL
END-IF
PERFORM 4000-REPORT-SECTION
PERFORM 5000-AUDIT-SECTION
CLOSE FILE-IN FILE-OUT
IF FS-AUDIT = '00'
CLOSE FILE-AUDIT
END-IF
DISPLAY ' '
DISPLAY '[TIMESTAMP] ' WS-TIMESTAMP
DISPLAY '[STATUS ] KeyBreakOther COMPLETED'
STOP RUN
.
*> WRITE-CHANGE-MARKER — ORIGINAL enhanced with timestamp+seq
WRITE-CHANGE-MARKER SECTION.
WRITE-CHANGE-MARKER-PROC.
ADD 1 TO WS-GROUPS-TOTAL
MOVE WS-PREV-KEY TO WS-MARKER-KEY
MOVE WS-TIMESTAMP TO WS-MARKER-TS
MOVE WS-MARKER-SEQ-NUM TO WS-MARKER-SEQ
WRITE FILE-OUT-REC FROM WS-MARKER-LINE
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Marker write FS=' FS-OUT
END-IF
DISPLAY '[CHANGE ] Key -> ''' WS-PREV-KEY
''' SEQ=' WS-MARKER-SEQ-NUM
.
*> WRITE-SUB-MARKER — sub-key change marker
WRITE-SUB-MARKER SECTION.
WRITE-SUB-MARKER-PROC.
ADD 1 TO WS-SUBGROUPS-TOTAL
MOVE WS-PREV-SUBKEY TO WS-SUB-MARK-KEY
MOVE WS-TIMESTAMP TO WS-SUB-MARK-TS
MOVE WS-MARKER-SEQ-NUM TO WS-SUB-MARK-SEQ
WRITE FILE-OUT-REC FROM WS-SUB-MARKER
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Sub-marker write FS=' FS-OUT
END-IF
DISPLAY '[SUBCHANGE] Sub-key -> ''' WS-PREV-SUBKEY
''' SEQ=' WS-MARKER-SEQ-NUM
.
*> WRITE-GROUP-HEADER
WRITE-GROUP-HEADER SECTION.
WRITE-GROUP-HEADER-PROC.
MOVE WS-PREV-KEY TO WS-GH-KEY
MOVE WS-TIMESTAMP TO WS-GH-TS
WRITE FILE-OUT-REC FROM WS-GROUP-HEADER
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Group-header write FS=' FS-OUT
END-IF
ADD 1 TO WS-LINE-COUNT
DISPLAY '[GROUP ] Start ''' WS-PREV-KEY ''''
.
*> WRITE-GROUP-FOOTER — end-of-group statistics
WRITE-GROUP-FOOTER SECTION.
WRITE-GROUP-FOOTER-PROC.
IF WS-GROUP-COUNT > 0
COMPUTE WS-GROUP-AVG =
WS-GROUP-DUR / WS-GROUP-COUNT
ELSE
MOVE 0 TO WS-GROUP-AVG
END-IF
MOVE WS-PREV-KEY TO WS-GF-KEY
MOVE WS-GROUP-COUNT TO WS-GF-COUNT
MOVE WS-GROUP-DUR TO WS-GF-DUR
MOVE WS-GROUP-MIN TO WS-GF-MIN
MOVE WS-GROUP-MAX TO WS-GF-MAX
MOVE WS-GROUP-AVG TO WS-GF-AVG
WRITE FILE-OUT-REC FROM WS-GROUP-FOOTER
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Group-footer write FS=' FS-OUT
END-IF
ADD 1 TO WS-LINE-COUNT
DISPLAY '[GROUP END] ''' WS-PREV-KEY ''''
' cnt=' WS-GROUP-COUNT ' dur=' WS-GROUP-DUR
IF FS-AUDIT = '00'
MOVE WS-TIMESTAMP TO AU-TIMESTAMP
MOVE 'GROUP ' TO AU-TYPE
MOVE WS-PREV-KEY TO AU-KEY
MOVE WS-GROUP-COUNT TO AU-VALUE
STRING 'DUR=' WS-GROUP-DUR INTO AU-STATUS
WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE
END-IF
.
*> WRITE-SUBGROUP-FOOTER — end-of-subgroup statistics
WRITE-SUBGROUP-FOOTER SECTION.
WRITE-SUBGROUP-FOOTER-PROC.
IF WS-SUBGROUP-COUNT > 0
COMPUTE WS-SUBGROUP-AVG =
WS-SUBGROUP-DUR / WS-SUBGROUP-COUNT
ELSE
MOVE 0 TO WS-SUBGROUP-AVG
END-IF
MOVE WS-PREV-SUBKEY TO WS-SGF-SUBKEY
MOVE WS-SUBGROUP-COUNT TO WS-SGF-COUNT
MOVE WS-SUBGROUP-DUR TO WS-SGF-DUR
MOVE WS-SUBGROUP-MIN TO WS-SGF-MIN
MOVE WS-SUBGROUP-MAX TO WS-SGF-MAX
MOVE WS-SUBGROUP-AVG TO WS-SGF-AVG
WRITE FILE-OUT-REC FROM WS-SUBGROUP-FOOTER
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Subgroup-footer write FS=' FS-OUT
END-IF
ADD 1 TO WS-LINE-COUNT
DISPLAY '[SUB END ] ''' WS-PREV-SUBKEY ''''
' cnt=' WS-SUBGROUP-COUNT ' dur=' WS-SUBGROUP-DUR
IF FS-AUDIT = '00'
MOVE WS-TIMESTAMP TO AU-TIMESTAMP
MOVE 'SUBGRP' TO AU-TYPE
MOVE WS-PREV-SUBKEY TO AU-KEY
MOVE WS-SUBGROUP-COUNT TO AU-VALUE
STRING 'DUR=' WS-SUBGROUP-DUR INTO AU-STATUS
WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE
END-IF
.
*> WRITE-PAGE-HEADER — page break marker
WRITE-PAGE-HEADER SECTION.
WRITE-PAGE-HEADER-PROC.
MOVE WS-PAGE-NUM TO WS-PH-PAGE
WRITE FILE-OUT-REC FROM WS-PAGE-HEADER
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Page-header write FS=' FS-OUT
END-IF
ADD 1 TO WS-LINE-COUNT
DISPLAY '[PAGE ] Page ' WS-PAGE-NUM
.
*> WRITE-GRAND-TOTAL
WRITE-GRAND-TOTAL SECTION.
WRITE-GRAND-TOTAL-PROC.
MOVE WS-GROUPS-TOTAL TO WS-GT-GROUPS
MOVE WS-RECORDS-READ TO WS-GT-RECS
MOVE WS-KEY-CHANGES TO WS-GT-CHGS
MOVE WS-SUB-CHANGES TO WS-GT-SUB
MOVE WS-GRAND-DUR TO WS-GT-DUR
WRITE FILE-OUT-REC FROM WS-GRAND-TOTAL-LINE
IF FS-OUT NOT = '00'
DISPLAY '[WARNING ] Grand-total write FS=' FS-OUT
END-IF
ADD 1 TO WS-LINE-COUNT
DISPLAY '[GRAND ] groups=' WS-GROUPS-TOTAL
' recs=' WS-RECORDS-READ
' chgs=' WS-KEY-CHANGES
' sub=' WS-SUB-CHANGES
' dur=' WS-GRAND-DUR
IF FS-AUDIT = '00'
MOVE WS-TIMESTAMP TO AU-TIMESTAMP
MOVE 'GRAND ' TO AU-TYPE
MOVE 'TOTAL' TO AU-KEY
MOVE WS-RECORDS-READ TO AU-VALUE
STRING 'DUR=' WS-GRAND-DUR INTO AU-STATUS
WRITE FILE-AUDIT-REC FROM WS-AUDIT-LINE
END-IF
.
*> INIT-GROUP-ACCUM
INIT-GROUP-ACCUM SECTION.
INIT-GROUP-ACCUM-PROC.
MOVE 0 TO WS-GROUP-COUNT
MOVE 0 TO WS-GROUP-DUR
MOVE 9999999999 TO WS-GROUP-MIN
MOVE 0 TO WS-GROUP-MAX
MOVE 0 TO WS-GROUP-AVG
MOVE 'N' TO WS-OVERFLOW-FLAG
.
*> INIT-SUBGROUP-ACCUM
INIT-SUBGROUP-ACCUM SECTION.
INIT-SUBGROUP-ACCUM-PROC.
MOVE 0 TO WS-SUBGROUP-COUNT
MOVE 0 TO WS-SUBGROUP-DUR
MOVE 9999999999 TO WS-SUBGROUP-MIN
MOVE 0 TO WS-SUBGROUP-MAX
MOVE 0 TO WS-SUBGROUP-AVG
.