feat: add benchmark-programs — 58 telecom COBOL test programs
作为子目录纳入系统,与核心测试管道协同 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,1088 @@
|
||||
*> ============================================================
|
||||
*> 12-divide-100 : CDR数据100分割 (CDR 100-Split)
|
||||
*> Input : FILE-IN.DAT (CDR数据: 100件毎分割)
|
||||
*> Output: FILE-OUT-NN (100件毎の分割出力文件: FILE-OUT-01, 02...)
|
||||
*> Coverage: S-N005, S-N006, S-N007, S-R001, S-R002
|
||||
*>
|
||||
*> Extended: Phase 2 — error recovery, hash totals, audit trail,
|
||||
*> split statistics, boundary checks, CDR awareness,
|
||||
*> header/trailer records, file naming validation.
|
||||
*> ============================================================
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. Divide100.
|
||||
|
||||
ENVIRONMENT DIVISION.
|
||||
CONFIGURATION SECTION.
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
SELECT FILE-IN
|
||||
ASSIGN TO WS-IN-FILE
|
||||
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 AUDIT-REPORT
|
||||
ASSIGN TO "AUDIT-RPT.TXT"
|
||||
ORGANIZATION IS LINE SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-STATUS-AUDIT.
|
||||
|
||||
SELECT SPLIT-STATS
|
||||
ASSIGN TO "SPLIT-STATS.TXT"
|
||||
ORGANIZATION IS LINE SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-STATUS-STATS.
|
||||
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD FILE-IN.
|
||||
01 FILE-IN-REC.
|
||||
05 IN-RECORD PIC X(45).
|
||||
|
||||
FD FILE-OUT.
|
||||
01 FILE-OUT-REC.
|
||||
05 OUT-RECORD PIC X(45).
|
||||
|
||||
FD AUDIT-REPORT.
|
||||
01 AUDIT-REC PIC X(120).
|
||||
|
||||
FD SPLIT-STATS.
|
||||
01 STATS-REC PIC X(120).
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
01 WS-TELECOM-REC.
|
||||
COPY "telecom/TEL-INVOICE.cpy".
|
||||
|
||||
*> CDR record mapping
|
||||
01 WS-CDR-REC.
|
||||
COPY "telecom/TEL-CDR.cpy".
|
||||
|
||||
*> File status indicators
|
||||
01 WS-FILE-STATUS-IN PIC X(02).
|
||||
01 WS-FILE-STATUS-OUT PIC X(02).
|
||||
01 WS-FILE-STATUS-AUDIT PIC X(02).
|
||||
01 WS-FILE-STATUS-STATS PIC X(02).
|
||||
|
||||
*> EOF and control flags
|
||||
01 WS-STATUS.
|
||||
05 WS-EOF-FLAG PIC X VALUE 'N'.
|
||||
88 WS-EOF VALUE 'Y' FALSE 'N'.
|
||||
05 WS-READ-OK PIC X VALUE 'N'.
|
||||
88 WS-READ-SUCCESS VALUE 'Y' FALSE 'N'.
|
||||
05 WS-FIRST-RECORD PIC X VALUE 'Y'.
|
||||
88 WS-IS-FIRST-RECORD VALUE 'Y' FALSE 'N'.
|
||||
|
||||
*> Error severity levels
|
||||
01 WS-SEVERITY PIC X(07).
|
||||
88 WS-SEVERITY-WARNING VALUE 'WARNING'.
|
||||
88 WS-SEVERITY-ERROR VALUE 'ERROR'.
|
||||
88 WS-SEVERITY-FATAL VALUE 'FATAL'.
|
||||
|
||||
*> Open retry control
|
||||
01 WS-OPEN-RETRY.
|
||||
05 WS-OPEN-RETRY-COUNT PIC 9(02) VALUE 0.
|
||||
05 WS-OPEN-RETRY-MAX PIC 9(02) VALUE 3.
|
||||
05 WS-ALT-SUFFIX PIC X(04).
|
||||
88 WS-ALT-NONE VALUE 'NONE'.
|
||||
88 WS-ALT-BAK VALUE '.BAK'.
|
||||
88 WS-ALT-TMP VALUE '.TMP'.
|
||||
|
||||
*> File naming validation
|
||||
01 WS-FILE-NAME-CHECK.
|
||||
05 WS-FILE-NAME-VALID PIC X VALUE 'N'.
|
||||
88 WS-NAME-IS-VALID VALUE 'Y' FALSE 'N'.
|
||||
05 WS-FILE-NAME-PATTERN PIC X(30).
|
||||
05 WS-FILE-NAME-PREFIX PIC X(08) VALUE 'FILE-OUT'.
|
||||
05 WS-FILE-NAME-SUFFIX PIC X(04) VALUE '.DAT'.
|
||||
05 WS-FILE-NAME-SEQ-BEG PIC 9(02).
|
||||
05 WS-FILE-NAME-SEQ-END PIC 9(02).
|
||||
|
||||
*> Counters and accumulators
|
||||
01 WS-COUNTERS.
|
||||
05 WS-REC-COUNT PIC 9(05) VALUE 0.
|
||||
05 WS-FILE-NUM PIC 9(02) VALUE 0.
|
||||
05 WS-DIVISOR PIC 9(03) VALUE 100.
|
||||
05 WS-QUOTIENT PIC 9(05).
|
||||
05 WS-REMAINDER PIC 9(05).
|
||||
05 WS-WRITE-COUNT PIC 9(05) VALUE 0.
|
||||
05 WS-READ-COUNT PIC 9(05) VALUE 0.
|
||||
|
||||
*> Input file path (dynamic for retry support)
|
||||
01 WS-IN-FILE PIC X(30).
|
||||
|
||||
*> Output file path
|
||||
01 WS-OUT-FILE PIC X(30).
|
||||
01 WS-FILE-NUM-ED PIC 99.
|
||||
|
||||
*> Display formatting
|
||||
01 WS-DISPLAY-COUNT PIC Z(05)9.
|
||||
01 WS-DISPLAY-HASH PIC Z(09)9.
|
||||
01 WS-DISPLAY-STR.
|
||||
05 WS-DISPLAY-STR-TEXT PIC X(50).
|
||||
|
||||
*> Simulated timestamp for DISPLAY tracing
|
||||
01 WS-TIMESTAMP PIC X(21).
|
||||
01 WS-TIMESTAMP-OUT PIC X(26).
|
||||
|
||||
*> Hash temp for byte counting
|
||||
01 WS-HASH-TEMP PIC 9(10).
|
||||
|
||||
*> Hash totals for data integrity
|
||||
01 WS-HASH-TOTALS.
|
||||
05 WS-HASH-TOTAL-IN PIC 9(10) VALUE 0.
|
||||
05 WS-HASH-TOTAL-OUT PIC 9(10) VALUE 0.
|
||||
05 WS-HASH-TOTAL-VERIFY PIC 9(10) VALUE 0.
|
||||
05 WS-HASH-VERIFIED PIC X VALUE 'N'.
|
||||
88 WS-HASH-MATCH VALUE 'Y' FALSE 'N'.
|
||||
88 WS-HASH-MISMATCH VALUE 'N'.
|
||||
05 WS-HASH-SPLIT OCCURS 99 TIMES.
|
||||
10 WS-HASH-SPLIT-VAL PIC 9(10).
|
||||
|
||||
*> Split statistics
|
||||
01 WS-SPLIT-STATS.
|
||||
05 WS-SPLIT-REC-COUNT PIC 9(05) VALUE 0.
|
||||
05 WS-SPLIT-FILE-TOTAL PIC 9(02) VALUE 0.
|
||||
05 WS-SPLIT-MIN-RECS PIC 9(05) VALUE 99999.
|
||||
05 WS-SPLIT-MAX-RECS PIC 9(05) VALUE 0.
|
||||
05 WS-SPLIT-EMPTY-FLAG PIC X VALUE 'N'.
|
||||
88 WS-SPLIT-EMPTY VALUE 'Y' FALSE 'N'.
|
||||
05 WS-SPLIT-SINGLE-FLAG PIC X VALUE 'N'.
|
||||
88 WS-SPLIT-SINGLE VALUE 'Y' FALSE 'N'.
|
||||
|
||||
*> Boundary condition checks
|
||||
01 WS-BOUNDARY-FLAG.
|
||||
05 WS-BOUNDARY-EMPTY PIC X VALUE 'N'.
|
||||
88 WS-BOUNDARY-IS-EMPTY VALUE 'Y' FALSE 'N'.
|
||||
05 WS-BOUNDARY-EXACT-MULT PIC X VALUE 'N'.
|
||||
88 WS-BOUNDARY-IS-EXACT VALUE 'Y' FALSE 'N'.
|
||||
05 WS-BOUNDARY-SINGLE-REC PIC X VALUE 'N'.
|
||||
88 WS-BOUNDARY-IS-SINGLE VALUE 'Y' FALSE 'N'.
|
||||
05 WS-BOUNDARY-TRAILING PIC X VALUE 'N'.
|
||||
88 WS-BOUNDARY-HAS-TRAIL VALUE 'Y' FALSE 'N'.
|
||||
05 WS-BOUNDARY-MULTIPLIER PIC 9(05).
|
||||
|
||||
*> Trailing record handling
|
||||
01 WS-TRAILER-REC-COUNT PIC 9(05) VALUE 0.
|
||||
01 WS-TRAILER-RECORD.
|
||||
05 WS-TRAILER-TYPE PIC X(08) VALUE 'TRAILER'.
|
||||
05 WS-TRAILER-FILE PIC 9(02).
|
||||
05 WS-TRL-REC-COUNT PIC 9(05).
|
||||
05 FILLER PIC X(30) VALUE SPACES.
|
||||
|
||||
*> Header record for split files
|
||||
01 WS-HEADER-RECORD.
|
||||
05 WS-HDR-TYPE PIC X(08) VALUE 'HEADER'.
|
||||
05 WS-HDR-FILE PIC 9(02).
|
||||
05 WS-HDR-TIMESTAMP PIC X(12).
|
||||
05 WS-HDR-RESERVED PIC X(23).
|
||||
05 FILLER PIC X VALUE SPACE.
|
||||
|
||||
*> CDR-aware split header
|
||||
01 WS-CDR-HEADER.
|
||||
05 WS-CDR-HDR-TYPE PIC X(08) VALUE 'CDR-HDR'.
|
||||
05 WS-CDR-HDR-FILE PIC 9(02).
|
||||
05 WS-CDR-HDR-EXPECTED PIC 9(05).
|
||||
05 WS-CDR-HDR-RESERVED PIC X(30).
|
||||
|
||||
*> Audit report variables
|
||||
01 WS-AUDIT-LINE PIC X(120).
|
||||
01 WS-AUDIT-COUNT PIC 9(05) VALUE 0.
|
||||
|
||||
*> Batch control totals
|
||||
01 WS-BATCH-CTRL.
|
||||
05 WS-BATCH-START-TIME PIC 9(08).
|
||||
05 WS-BATCH-END-TIME PIC 9(08).
|
||||
05 WS-BATCH-TOTAL-FILES PIC 9(02) VALUE 0.
|
||||
05 WS-BATCH-TOTAL-RECS PIC 9(05) VALUE 0.
|
||||
05 WS-BATCH-ERROR-COUNT PIC 9(03) VALUE 0.
|
||||
05 WS-BATCH-WARN-COUNT PIC 9(03) VALUE 0.
|
||||
|
||||
*> File open retry state
|
||||
01 WS-RETRY-STATE.
|
||||
05 WS-RETRY-ATTEMPT PIC 9(02) VALUE 0.
|
||||
05 WS-RETRY-FILE-NAME PIC X(30).
|
||||
05 WS-RETRY-SUCCESS PIC X VALUE 'N'.
|
||||
88 WS-RETRY-OK VALUE 'Y' FALSE 'N'.
|
||||
|
||||
* ============================================================
|
||||
* PROCEDURE DIVISION
|
||||
* ============================================================
|
||||
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 6000-ERROR-HANDLE-SECTION
|
||||
PERFORM 9000-EXIT-SECTION
|
||||
STOP RUN.
|
||||
|
||||
*> ============================================================
|
||||
*> 1000-INIT-SECTION — Initialize all working variables
|
||||
*> ============================================================
|
||||
1000-INIT-SECTION SECTION.
|
||||
|
||||
1000-INIT.
|
||||
DISPLAY " "
|
||||
DISPLAY "=== Divide100 — Initialize ==="
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP
|
||||
DISPLAY "[" WS-TIMESTAMP "] Initializing program"
|
||||
|
||||
*> Zero counters
|
||||
MOVE 0 TO WS-REC-COUNT
|
||||
MOVE 0 TO WS-FILE-NUM
|
||||
MOVE 0 TO WS-READ-COUNT
|
||||
MOVE 0 TO WS-WRITE-COUNT
|
||||
MOVE 0 TO WS-TRAILER-REC-COUNT
|
||||
MOVE 0 TO WS-AUDIT-COUNT
|
||||
MOVE 0 TO WS-BATCH-ERROR-COUNT
|
||||
MOVE 0 TO WS-BATCH-WARN-COUNT
|
||||
MOVE 0 TO WS-OPEN-RETRY-COUNT
|
||||
MOVE 0 TO WS-HASH-TOTAL-IN
|
||||
MOVE 0 TO WS-HASH-TOTAL-OUT
|
||||
|
||||
*> Reset boundary flags
|
||||
MOVE 'N' TO WS-BOUNDARY-EMPTY
|
||||
MOVE 'N' TO WS-BOUNDARY-EXACT-MULT
|
||||
MOVE 'N' TO WS-BOUNDARY-SINGLE-REC
|
||||
MOVE 'N' TO WS-BOUNDARY-TRAILING
|
||||
MOVE 'Y' TO WS-FIRST-RECORD
|
||||
|
||||
*> Reset retry state
|
||||
MOVE 'NONE' TO WS-ALT-SUFFIX
|
||||
MOVE 0 TO WS-RETRY-ATTEMPT
|
||||
|
||||
*> Reset split stats
|
||||
MOVE 0 TO WS-SPLIT-REC-COUNT
|
||||
MOVE 0 TO WS-SPLIT-FILE-TOTAL
|
||||
MOVE 99999 TO WS-SPLIT-MIN-RECS
|
||||
MOVE 0 TO WS-SPLIT-MAX-RECS
|
||||
MOVE 'N' TO WS-SPLIT-EMPTY-FLAG
|
||||
MOVE 'N' TO WS-SPLIT-SINGLE-FLAG
|
||||
|
||||
DISPLAY "[" WS-TIMESTAMP "] Initialization complete"
|
||||
.
|
||||
|
||||
1000-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 2000-OPEN-FILES-SECTION — Open input and audit files
|
||||
*> ============================================================
|
||||
2000-OPEN-FILES-SECTION SECTION.
|
||||
|
||||
2000-OPEN-FILES.
|
||||
DISPLAY "[" WS-TIMESTAMP "] Opening files"
|
||||
|
||||
*> Open input file with retry logic
|
||||
MOVE 0 TO WS-RETRY-ATTEMPT
|
||||
MOVE 'N' TO WS-RETRY-SUCCESS
|
||||
MOVE "FILE-IN.DAT" TO WS-IN-FILE
|
||||
|
||||
PERFORM WITH TEST AFTER UNTIL WS-RETRY-OK
|
||||
OR WS-RETRY-ATTEMPT >= WS-OPEN-RETRY-MAX
|
||||
ADD 1 TO WS-RETRY-ATTEMPT
|
||||
OPEN INPUT FILE-IN
|
||||
IF WS-FILE-STATUS-IN NOT = '00'
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: FILE-IN open failed "
|
||||
"status=" WS-FILE-STATUS-IN
|
||||
" attempt=" WS-RETRY-ATTEMPT
|
||||
*> Try alternate file name
|
||||
IF WS-RETRY-ATTEMPT = 1
|
||||
MOVE '.BAK' TO WS-ALT-SUFFIX
|
||||
STRING "FILE-IN" WS-ALT-SUFFIX
|
||||
DELIMITED BY SIZE
|
||||
INTO WS-IN-FILE
|
||||
ELSE
|
||||
MOVE '.TMP' TO WS-ALT-SUFFIX
|
||||
STRING "FILE-IN" WS-ALT-SUFFIX
|
||||
DELIMITED BY SIZE
|
||||
INTO WS-IN-FILE
|
||||
END-IF
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Retrying with: " WS-IN-FILE
|
||||
ELSE
|
||||
MOVE WS-IN-FILE TO WS-RETRY-FILE-NAME
|
||||
MOVE 'Y' TO WS-RETRY-SUCCESS
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"FILE-IN opened: " WS-IN-FILE
|
||||
" (attempt " WS-RETRY-ATTEMPT ")"
|
||||
END-IF
|
||||
END-PERFORM
|
||||
|
||||
IF NOT WS-RETRY-OK
|
||||
MOVE 'FATAL' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"FATAL: Cannot open FILE-IN after "
|
||||
WS-OPEN-RETRY-MAX " attempts"
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
PERFORM 9000-EXIT-SECTION
|
||||
END-IF
|
||||
|
||||
*> Open audit report file
|
||||
OPEN OUTPUT AUDIT-REPORT
|
||||
IF WS-FILE-STATUS-AUDIT NOT = '00'
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: AUDIT-REPORT open failed "
|
||||
"status=" WS-FILE-STATUS-AUDIT
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"AUDIT-REPORT opened successfully"
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "*** AUDIT REPORT — Divide100 ***"
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
END-IF
|
||||
|
||||
*> Open split stats file
|
||||
OPEN OUTPUT SPLIT-STATS
|
||||
IF WS-FILE-STATUS-STATS NOT = '00'
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: SPLIT-STATS open failed "
|
||||
"status=" WS-FILE-STATUS-STATS
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"SPLIT-STATS opened successfully"
|
||||
MOVE SPACES TO STATS-REC
|
||||
STRING "*** SPLIT STATISTICS REPORT ***"
|
||||
DELIMITED BY SIZE
|
||||
INTO STATS-REC
|
||||
WRITE STATS-REC
|
||||
END-IF
|
||||
|
||||
*> Capture batch start time
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP
|
||||
.
|
||||
|
||||
2000-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 3000-PROCESS-SECTION — Main processing loop
|
||||
*> ============================================================
|
||||
3000-PROCESS-SECTION SECTION.
|
||||
|
||||
3000-PROCESS.
|
||||
DISPLAY "[" WS-TIMESTAMP "] Starting record processing"
|
||||
DISPLAY "=== 100-DIVISION PROCESSING ==="
|
||||
DISPLAY "Records per file: " WS-DIVISOR
|
||||
|
||||
*> Write audit header
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "=== 100-DIVISION PROCESSING ==="
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Records per file: " WS-DIVISOR
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
PERFORM VARYING WS-REC-COUNT FROM 1 BY 1
|
||||
UNTIL WS-EOF
|
||||
READ FILE-IN INTO FILE-IN-REC
|
||||
AT END
|
||||
SET WS-EOF TO TRUE
|
||||
IF WS-IS-FIRST-RECORD
|
||||
MOVE 'Y' TO WS-BOUNDARY-EMPTY
|
||||
MOVE 'WARNING' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"WARNING: Input file is empty"
|
||||
END-IF
|
||||
NOT AT END
|
||||
SET WS-READ-SUCCESS TO TRUE
|
||||
ADD 1 TO WS-READ-COUNT
|
||||
IF WS-IS-FIRST-RECORD
|
||||
MOVE 'N' TO WS-FIRST-RECORD
|
||||
END-IF
|
||||
PERFORM 3100-READ-INPUT-SECTION
|
||||
PERFORM 3200-VALIDATE-SECTION
|
||||
PERFORM 3300-APPLY-RULES-SECTION
|
||||
PERFORM 3400-WRITE-OUTPUT-SECTION
|
||||
END-READ
|
||||
|
||||
IF WS-FILE-STATUS-IN NOT = '00' AND NOT WS-EOF
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: FILE-IN read failed "
|
||||
"record=" WS-REC-COUNT
|
||||
" status=" WS-FILE-STATUS-IN
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
END-IF
|
||||
END-PERFORM
|
||||
|
||||
*> Boundary checks after processing
|
||||
IF WS-BOUNDARY-IS-EMPTY
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "WARNING: Input file was empty — "
|
||||
"no output files created"
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
ELSE
|
||||
DIVIDE WS-READ-COUNT BY WS-DIVISOR
|
||||
GIVING WS-BOUNDARY-MULTIPLIER
|
||||
REMAINDER WS-REMAINDER
|
||||
IF WS-REMAINDER = 0
|
||||
MOVE 'Y' TO WS-BOUNDARY-EXACT-MULT
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"NOTE: Exact multiple of divisor — "
|
||||
"no trailing records"
|
||||
ELSE
|
||||
MOVE 'Y' TO WS-BOUNDARY-TRAILING
|
||||
MOVE WS-REMAINDER TO WS-TRAILER-REC-COUNT
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"NOTE: " WS-TRAILER-REC-COUNT
|
||||
" trailing record(s) in last file"
|
||||
END-IF
|
||||
IF WS-READ-COUNT = 1
|
||||
MOVE 'Y' TO WS-BOUNDARY-SINGLE-REC
|
||||
END-IF
|
||||
END-IF
|
||||
|
||||
*> Close last output file if any were opened
|
||||
IF WS-FILE-NUM > 0
|
||||
PERFORM WRITE-TRAILER-RECORD
|
||||
CLOSE FILE-OUT
|
||||
IF WS-FILE-STATUS-OUT NOT = '00'
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: Close failed for "
|
||||
WS-OUT-FILE
|
||||
" status=" WS-FILE-STATUS-OUT
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Closed final file: " WS-OUT-FILE
|
||||
END-IF
|
||||
END-IF
|
||||
|
||||
MOVE WS-REC-COUNT TO WS-DISPLAY-COUNT
|
||||
DISPLAY " "
|
||||
DISPLAY "[" WS-TIMESTAMP "] Total records read: "
|
||||
WS-DISPLAY-COUNT
|
||||
DISPLAY "[" WS-TIMESTAMP "] Output files created: "
|
||||
WS-FILE-NUM
|
||||
.
|
||||
|
||||
3000-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 3100-READ-INPUT-SECTION — Input record processing
|
||||
*> ============================================================
|
||||
3100-READ-INPUT-SECTION SECTION.
|
||||
|
||||
3100-READ-INPUT.
|
||||
*> Accumulate hash total (sum of numeric representation
|
||||
*> of the input record bytes)
|
||||
PERFORM COMPUTE-INPUT-HASH
|
||||
|
||||
*> Classify record type based on known layouts
|
||||
MOVE IN-RECORD TO WS-TELECOM-REC
|
||||
MOVE IN-RECORD TO WS-CDR-REC
|
||||
|
||||
*> Check if record resembles a CDR by CDR-ID pattern
|
||||
IF CDR-ID (1:3) = 'CDR'
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Record " WS-REC-COUNT
|
||||
": CDR record detected: " CDR-ID
|
||||
ELSE
|
||||
IF INV-ID (1:3) = 'INV'
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Record " WS-REC-COUNT
|
||||
": Invoice record detected: " INV-ID
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Record " WS-REC-COUNT
|
||||
": Generic record"
|
||||
END-IF
|
||||
END-IF
|
||||
.
|
||||
|
||||
3100-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 3200-VALIDATE-SECTION — Validate input record
|
||||
*> ============================================================
|
||||
3200-VALIDATE-SECTION SECTION.
|
||||
|
||||
3200-VALIDATE.
|
||||
*> Validate output file naming convention before writing
|
||||
IF WS-FILE-NUM > 0
|
||||
MOVE WS-OUT-FILE TO WS-FILE-NAME-PATTERN
|
||||
IF WS-FILE-NAME-PATTERN (1:8) = WS-FILE-NAME-PREFIX
|
||||
MOVE 'Y' TO WS-FILE-NAME-VALID
|
||||
ELSE
|
||||
MOVE 'N' TO WS-FILE-NAME-VALID
|
||||
MOVE 'WARNING' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"WARNING: Unconventional file name: "
|
||||
WS-OUT-FILE
|
||||
ADD 1 TO WS-BATCH-WARN-COUNT
|
||||
END-IF
|
||||
END-IF
|
||||
.
|
||||
|
||||
3200-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 3300-APPLY-RULES-SECTION — Apply division rules
|
||||
*> ============================================================
|
||||
3300-APPLY-RULES-SECTION SECTION.
|
||||
|
||||
3300-APPLY-RULES.
|
||||
*> Use DIVIDE to determine file number
|
||||
*> === ORIGINAL LOGIC PRESERVED (unaltered) ===
|
||||
DIVIDE WS-REC-COUNT BY WS-DIVISOR
|
||||
GIVING WS-QUOTIENT REMAINDER WS-REMAINDER
|
||||
|
||||
*> If remainder = 1, start a new output file
|
||||
*> === ORIGINAL LOGIC PRESERVED (unaltered) ===
|
||||
IF WS-REMAINDER = 1
|
||||
IF WS-FILE-NUM > 0
|
||||
PERFORM WRITE-TRAILER-RECORD
|
||||
CLOSE FILE-OUT
|
||||
IF WS-FILE-STATUS-OUT NOT = '00'
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: Close failed for "
|
||||
WS-OUT-FILE
|
||||
" status=" WS-FILE-STATUS-OUT
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Closed: " WS-OUT-FILE
|
||||
END-IF
|
||||
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
|
||||
IF WS-FILE-STATUS-OUT NOT = '00'
|
||||
MOVE 'FATAL' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"FATAL: Cannot open " WS-OUT-FILE
|
||||
" status=" WS-FILE-STATUS-OUT
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
PERFORM 6000-ERROR-HANDLE-SECTION
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Opened: " WS-OUT-FILE
|
||||
PERFORM WRITE-HEADER-RECORD
|
||||
END-IF
|
||||
END-IF
|
||||
.
|
||||
|
||||
3300-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 3400-WRITE-OUTPUT-SECTION — Write record to output
|
||||
*> ============================================================
|
||||
3400-WRITE-OUTPUT-SECTION SECTION.
|
||||
|
||||
3400-WRITE-OUTPUT.
|
||||
*> Hash the output record before writing
|
||||
PERFORM COMPUTE-OUTPUT-HASH
|
||||
|
||||
*> Write record to current output file
|
||||
*> === ORIGINAL LOGIC PRESERVED (unaltered) ===
|
||||
MOVE IN-RECORD TO OUT-RECORD
|
||||
WRITE FILE-OUT-REC
|
||||
|
||||
IF WS-FILE-STATUS-OUT NOT = '00'
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: Write failed for record "
|
||||
WS-REC-COUNT
|
||||
" status=" WS-FILE-STATUS-OUT
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
ELSE
|
||||
ADD 1 TO WS-WRITE-COUNT
|
||||
ADD 1 TO WS-SPLIT-REC-COUNT
|
||||
ADD 1 TO WS-HASH-SPLIT-VAL (WS-FILE-NUM)
|
||||
END-IF
|
||||
.
|
||||
|
||||
3400-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 4000-REPORT-SECTION — Generate split statistics
|
||||
*> ============================================================
|
||||
4000-REPORT-SECTION SECTION.
|
||||
|
||||
4000-REPORT.
|
||||
DISPLAY " "
|
||||
DISPLAY "[" WS-TIMESTAMP "] === Split Statistics ==="
|
||||
DISPLAY "Total input records: " WS-READ-COUNT
|
||||
DISPLAY "Total output records: " WS-WRITE-COUNT
|
||||
DISPLAY "Output files created: " WS-FILE-NUM
|
||||
|
||||
*> Populate split stats
|
||||
MOVE WS-FILE-NUM TO WS-SPLIT-FILE-TOTAL
|
||||
IF WS-READ-COUNT = 0
|
||||
MOVE 'Y' TO WS-SPLIT-EMPTY-FLAG
|
||||
END-IF
|
||||
IF WS-READ-COUNT = 1
|
||||
MOVE 'Y' TO WS-SPLIT-SINGLE-FLAG
|
||||
END-IF
|
||||
|
||||
*> Build min/max split sizes
|
||||
PERFORM VARYING WS-FILE-NUM-ED FROM 1 BY 1
|
||||
UNTIL WS-FILE-NUM-ED > WS-FILE-NUM
|
||||
IF WS-HASH-SPLIT-VAL (WS-FILE-NUM-ED)
|
||||
< WS-SPLIT-MIN-RECS
|
||||
MOVE WS-HASH-SPLIT-VAL (WS-FILE-NUM-ED)
|
||||
TO WS-SPLIT-MIN-RECS
|
||||
END-IF
|
||||
IF WS-HASH-SPLIT-VAL (WS-FILE-NUM-ED)
|
||||
> WS-SPLIT-MAX-RECS
|
||||
MOVE WS-HASH-SPLIT-VAL (WS-FILE-NUM-ED)
|
||||
TO WS-SPLIT-MAX-RECS
|
||||
END-IF
|
||||
END-PERFORM
|
||||
|
||||
DISPLAY "Min records per split: " WS-SPLIT-MIN-RECS
|
||||
DISPLAY "Max records per split: " WS-SPLIT-MAX-RECS
|
||||
|
||||
*> Write detailed stats to SPLIT-STATS file
|
||||
MOVE SPACES TO STATS-REC
|
||||
STRING "SPLIT STATS: files=" WS-FILE-NUM
|
||||
" total-records=" WS-READ-COUNT
|
||||
" min=" WS-SPLIT-MIN-RECS
|
||||
" max=" WS-SPLIT-MAX-RECS
|
||||
DELIMITED BY SIZE
|
||||
INTO STATS-REC
|
||||
WRITE STATS-REC
|
||||
|
||||
*> Sequential output file inventory
|
||||
MOVE SPACES TO STATS-REC
|
||||
STRING "=== Split File Inventory ==="
|
||||
DELIMITED BY SIZE
|
||||
INTO STATS-REC
|
||||
WRITE STATS-REC
|
||||
|
||||
PERFORM VARYING WS-FILE-NUM-ED FROM 1 BY 1
|
||||
UNTIL WS-FILE-NUM-ED > WS-FILE-NUM
|
||||
MOVE SPACES TO STATS-REC
|
||||
STRING "FILE-OUT-"
|
||||
WS-FILE-NUM-ED
|
||||
".DAT: "
|
||||
WS-HASH-SPLIT-VAL (WS-FILE-NUM-ED)
|
||||
" records"
|
||||
DELIMITED BY SIZE
|
||||
INTO STATS-REC
|
||||
WRITE STATS-REC
|
||||
END-PERFORM
|
||||
|
||||
*> Boundary condition summary
|
||||
MOVE SPACES TO STATS-REC
|
||||
STRING "Boundary: EMPTY=" WS-BOUNDARY-EMPTY
|
||||
" EXACT-MULT=" WS-BOUNDARY-EXACT-MULT
|
||||
" SINGLE=" WS-BOUNDARY-SINGLE-REC
|
||||
" TRAILING=" WS-BOUNDARY-TRAILING
|
||||
" TRAIL-COUNT=" WS-TRAILER-REC-COUNT
|
||||
DELIMITED BY SIZE
|
||||
INTO STATS-REC
|
||||
WRITE STATS-REC
|
||||
.
|
||||
|
||||
4000-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 5000-AUDIT-SECTION — Hash verification and audit trail
|
||||
*> ============================================================
|
||||
5000-AUDIT-SECTION SECTION.
|
||||
|
||||
5000-AUDIT.
|
||||
DISPLAY " "
|
||||
DISPLAY "[" WS-TIMESTAMP "] === Audit Trail ==="
|
||||
|
||||
*> Display hash totals
|
||||
MOVE WS-HASH-TOTAL-IN TO WS-DISPLAY-HASH
|
||||
DISPLAY "Hash total (input): " WS-DISPLAY-HASH
|
||||
|
||||
MOVE WS-HASH-TOTAL-OUT TO WS-DISPLAY-HASH
|
||||
DISPLAY "Hash total (output): " WS-DISPLAY-HASH
|
||||
|
||||
*> Verify hash totals: input hash must equal sum of
|
||||
*> all split file hashes
|
||||
MOVE 0 TO WS-HASH-TOTAL-VERIFY
|
||||
PERFORM VARYING WS-FILE-NUM-ED FROM 1 BY 1
|
||||
UNTIL WS-FILE-NUM-ED > WS-FILE-NUM
|
||||
ADD WS-HASH-SPLIT-VAL (WS-FILE-NUM-ED)
|
||||
TO WS-HASH-TOTAL-VERIFY
|
||||
END-PERFORM
|
||||
|
||||
IF WS-HASH-TOTAL-IN = WS-HASH-TOTAL-VERIFY
|
||||
MOVE 'Y' TO WS-HASH-VERIFIED
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"PASS: Hash total verified OK"
|
||||
ELSE
|
||||
MOVE 'N' TO WS-HASH-VERIFIED
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"FAIL: Hash total mismatch!"
|
||||
DISPLAY " Input hash: " WS-HASH-TOTAL-IN
|
||||
DISPLAY " Sum of splits: " WS-HASH-TOTAL-VERIFY
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
END-IF
|
||||
|
||||
*> Verify output hash matches input hash
|
||||
IF WS-HASH-TOTAL-IN NOT = WS-HASH-TOTAL-OUT
|
||||
MOVE 'ERROR' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"FAIL: Output hash != Input hash!"
|
||||
ADD 1 TO WS-BATCH-ERROR-COUNT
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"PASS: Output hash matches input hash"
|
||||
END-IF
|
||||
|
||||
*> Write final audit records
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "=== Audit Summary ==="
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Total input records: " WS-READ-COUNT
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Total output records: " WS-WRITE-COUNT
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Output files created: " WS-FILE-NUM
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Hash total (input): " WS-HASH-TOTAL-IN
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Hash total (output): " WS-HASH-TOTAL-OUT
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
IF WS-HASH-MATCH
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Hash verification: PASS"
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
ELSE
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Hash verification: FAIL"
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
END-IF
|
||||
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Error count: " WS-BATCH-ERROR-COUNT
|
||||
" Warning count: " WS-BATCH-WARN-COUNT
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
*> Log batch completion
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "Batch completed at: " WS-TIMESTAMP
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Audit report written: " WS-AUDIT-COUNT " lines"
|
||||
.
|
||||
|
||||
5000-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 6000-ERROR-HANDLE-SECTION — Central error handler
|
||||
*> ============================================================
|
||||
6000-ERROR-HANDLE-SECTION SECTION.
|
||||
|
||||
6000-ERROR-HANDLE.
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"*** ERROR HANDLER INVOKED ***"
|
||||
|
||||
EVALUATE TRUE
|
||||
WHEN WS-SEVERITY-FATAL
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"FATAL: Aborting program"
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "FATAL ERROR — Batch aborted"
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
PERFORM 9000-EXIT-SECTION
|
||||
|
||||
WHEN WS-SEVERITY-ERROR
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR: Continuing with error"
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "ERROR: Continuing — "
|
||||
"error count=" WS-BATCH-ERROR-COUNT
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
WHEN WS-SEVERITY-WARNING
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"WARNING: Non-critical issue"
|
||||
MOVE SPACES TO AUDIT-REC
|
||||
STRING "WARNING issued — "
|
||||
"warn count=" WS-BATCH-WARN-COUNT
|
||||
DELIMITED BY SIZE
|
||||
INTO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
|
||||
WHEN OTHER
|
||||
CONTINUE
|
||||
END-EVALUATE
|
||||
.
|
||||
|
||||
6000-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> 9000-EXIT-SECTION — Program cleanup and exit
|
||||
*> ============================================================
|
||||
9000-EXIT-SECTION SECTION.
|
||||
|
||||
9000-EXIT.
|
||||
DISPLAY " "
|
||||
DISPLAY "[" WS-TIMESTAMP "] === Program Termination ==="
|
||||
|
||||
*> Close any open files safely
|
||||
CLOSE FILE-IN
|
||||
IF WS-FILE-STATUS-IN NOT = '00'
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"NOTE: FILE-IN close status="
|
||||
WS-FILE-STATUS-IN
|
||||
END-IF
|
||||
|
||||
CLOSE AUDIT-REPORT
|
||||
IF WS-FILE-STATUS-AUDIT NOT = '00'
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"NOTE: AUDIT-REPORT close status="
|
||||
WS-FILE-STATUS-AUDIT
|
||||
END-IF
|
||||
|
||||
CLOSE SPLIT-STATS
|
||||
IF WS-FILE-STATUS-STATS NOT = '00'
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"NOTE: SPLIT-STATS close status="
|
||||
WS-FILE-STATUS-STATS
|
||||
END-IF
|
||||
|
||||
*> Final summary display
|
||||
MOVE WS-REC-COUNT TO WS-DISPLAY-COUNT
|
||||
DISPLAY " "
|
||||
DISPLAY "=== FINAL SUMMARY ==="
|
||||
DISPLAY "Total records read: " WS-DISPLAY-COUNT
|
||||
DISPLAY "Output files created: " WS-FILE-NUM
|
||||
DISPLAY "Errors: " WS-BATCH-ERROR-COUNT
|
||||
DISPLAY "Warnings: " WS-BATCH-WARN-COUNT
|
||||
|
||||
IF WS-HASH-MATCH
|
||||
DISPLAY "Hash integrity: PASS"
|
||||
ELSE
|
||||
DISPLAY "Hash integrity: FAIL"
|
||||
END-IF
|
||||
|
||||
DISPLAY " "
|
||||
DISPLAY "=== Divide100 ended ==="
|
||||
STOP RUN
|
||||
.
|
||||
|
||||
*> ============================================================
|
||||
*> WRITE-HEADER-RECORD — Write header record to split file
|
||||
*> ============================================================
|
||||
WRITE-HEADER-RECORD SECTION.
|
||||
|
||||
WRITE-HDR.
|
||||
*> Write standard header
|
||||
MOVE SPACES TO WS-HEADER-RECORD
|
||||
MOVE 'HEADER' TO WS-HDR-TYPE
|
||||
MOVE WS-FILE-NUM TO WS-HDR-FILE
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-TIMESTAMP
|
||||
MOVE WS-TIMESTAMP (1:12) TO WS-HDR-TIMESTAMP
|
||||
MOVE WS-HEADER-RECORD TO OUT-RECORD
|
||||
WRITE FILE-OUT-REC
|
||||
IF WS-FILE-STATUS-OUT = '00'
|
||||
ADD 1 TO WS-WRITE-COUNT
|
||||
ADD 1 TO WS-HASH-SPLIT-VAL (WS-FILE-NUM)
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Header written to " WS-OUT-FILE
|
||||
ELSE
|
||||
MOVE 'WARNING' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"WARNING: Header write failed for "
|
||||
WS-OUT-FILE
|
||||
ADD 1 TO WS-BATCH-WARN-COUNT
|
||||
END-IF
|
||||
|
||||
*> Write CDR-aware header (second header line with metadata)
|
||||
MOVE SPACES TO WS-CDR-HEADER
|
||||
MOVE 'CDR-HDR' TO WS-CDR-HDR-TYPE
|
||||
MOVE WS-FILE-NUM TO WS-CDR-HDR-FILE
|
||||
MOVE 100 TO WS-CDR-HDR-EXPECTED
|
||||
MOVE WS-CDR-HEADER TO OUT-RECORD
|
||||
WRITE FILE-OUT-REC
|
||||
IF WS-FILE-STATUS-OUT = '00'
|
||||
ADD 1 TO WS-WRITE-COUNT
|
||||
ADD 1 TO WS-HASH-SPLIT-VAL (WS-FILE-NUM)
|
||||
ELSE
|
||||
MOVE 'WARNING' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"WARNING: CDR header write failed for "
|
||||
WS-OUT-FILE
|
||||
ADD 1 TO WS-BATCH-WARN-COUNT
|
||||
END-IF
|
||||
.
|
||||
|
||||
WRITE-HDR-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> WRITE-TRAILER-RECORD — Write trailer to closing split file
|
||||
*> ============================================================
|
||||
WRITE-TRAILER-RECORD SECTION.
|
||||
|
||||
WRITE-TRL.
|
||||
MOVE SPACES TO WS-TRAILER-RECORD
|
||||
MOVE 'TRAILER' TO WS-TRAILER-TYPE
|
||||
MOVE WS-FILE-NUM TO WS-TRAILER-FILE
|
||||
*> Count = current split count minus header records
|
||||
*> (we wrote 2 header records per file)
|
||||
IF WS-HASH-SPLIT-VAL (WS-FILE-NUM) > 2
|
||||
COMPUTE WS-TRL-REC-COUNT =
|
||||
WS-HASH-SPLIT-VAL (WS-FILE-NUM) - 2
|
||||
ELSE
|
||||
MOVE 0 TO WS-TRL-REC-COUNT
|
||||
END-IF
|
||||
MOVE WS-TRAILER-RECORD TO OUT-RECORD
|
||||
WRITE FILE-OUT-REC
|
||||
IF WS-FILE-STATUS-OUT = '00'
|
||||
ADD 1 TO WS-WRITE-COUNT
|
||||
ADD 1 TO WS-HASH-SPLIT-VAL (WS-FILE-NUM)
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"Trailer written to " WS-OUT-FILE
|
||||
" count=" WS-TRL-REC-COUNT
|
||||
ELSE
|
||||
MOVE 'WARNING' TO WS-SEVERITY
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"WARNING: Trailer write failed for "
|
||||
WS-OUT-FILE
|
||||
ADD 1 TO WS-BATCH-WARN-COUNT
|
||||
END-IF
|
||||
.
|
||||
|
||||
WRITE-TRL-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> WRITE-AUDIT-LINE — Write one line to audit report
|
||||
*> ============================================================
|
||||
WRITE-AUDIT-LINE SECTION.
|
||||
|
||||
WRITE-AUDIT.
|
||||
MOVE WS-AUDIT-LINE TO AUDIT-REC
|
||||
WRITE AUDIT-REC
|
||||
IF WS-FILE-STATUS-AUDIT = '00'
|
||||
ADD 1 TO WS-AUDIT-COUNT
|
||||
ELSE
|
||||
DISPLAY "[" WS-TIMESTAMP "] "
|
||||
"ERROR writing audit record"
|
||||
END-IF
|
||||
.
|
||||
|
||||
WRITE-AUDIT-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> COMPUTE-INPUT-HASH — Accumulate input hash total
|
||||
*> ============================================================
|
||||
COMPUTE-INPUT-HASH SECTION.
|
||||
|
||||
COMP-HASH-IN.
|
||||
*> Simple hash: sum the numeric values of each byte
|
||||
MOVE 0 TO WS-HASH-TEMP
|
||||
INSPECT IN-RECORD TALLYING WS-HASH-TEMP
|
||||
FOR CHARACTERS BEFORE INITIAL SPACE
|
||||
ADD WS-HASH-TEMP TO WS-HASH-TOTAL-IN
|
||||
.
|
||||
|
||||
COMP-HASH-IN-EXIT.
|
||||
EXIT.
|
||||
|
||||
*> ============================================================
|
||||
*> COMPUTE-OUTPUT-HASH — Accumulate output hash total
|
||||
*> ============================================================
|
||||
COMPUTE-OUTPUT-HASH SECTION.
|
||||
|
||||
COMP-HASH-OUT.
|
||||
*> Simple hash: sum the numeric values of each byte
|
||||
MOVE 0 TO WS-HASH-TEMP
|
||||
INSPECT OUT-RECORD TALLYING WS-HASH-TEMP
|
||||
FOR CHARACTERS BEFORE INITIAL SPACE
|
||||
ADD WS-HASH-TEMP TO WS-HASH-TOTAL-OUT
|
||||
.
|
||||
|
||||
COMP-HASH-OUT-EXIT.
|
||||
EXIT.
|
||||
Reference in New Issue
Block a user