feat: add benchmark-programs — 58 telecom COBOL test programs
作为子目录纳入系统,与核心测试管道协同 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
*** AUDIT REPORT — Divide100 ***
|
||||
=== 100-DIVISION PROCESSING ===
|
||||
Records per file: 100
|
||||
=== Audit Summary ===
|
||||
Total input records: 00101
|
||||
Total output records: 00107
|
||||
Output files created: 02
|
||||
Hash total (input): 0000001010
|
||||
Hash total (output): 0000001004
|
||||
Hash verification: FAIL
|
||||
Error count: 002 Warning count: 000
|
||||
Batch completed at: 2026062216453475+0800
|
||||
ERROR: Continuing — error count=002
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
CDR-000001 86138001380 0000097
|
||||
CDR-000002 86138001381 0000134
|
||||
CDR-000003 86138001382 0000171
|
||||
CDR-000004 86138001383 0000208
|
||||
CDR-000005 86138001384 0000245
|
||||
CDR-000006 86138001385 0000282
|
||||
CDR-000007 86138001380 0000319
|
||||
CDR-000008 86138001381 0000356
|
||||
CDR-000009 86138001382 0000393
|
||||
CDR-000010 86138001383 0000430
|
||||
CDR-000011 86138001384 0000467
|
||||
CDR-000012 86138001385 0000504
|
||||
CDR-000013 86138001380 0000541
|
||||
CDR-000014 86138001381 0000578
|
||||
CDR-000015 86138001382 0000615
|
||||
CDR-000016 86138001383 0000652
|
||||
CDR-000017 86138001384 0000689
|
||||
CDR-000018 86138001385 0000726
|
||||
CDR-000019 86138001380 0000763
|
||||
CDR-000020 86138001381 0000800
|
||||
CDR-000021 86138001382 0000837
|
||||
CDR-000022 86138001383 0000874
|
||||
CDR-000023 86138001384 0000911
|
||||
CDR-000024 86138001385 0000948
|
||||
CDR-000025 86138001380 0000985
|
||||
CDR-000026 86138001381 0001022
|
||||
CDR-000027 86138001382 0001059
|
||||
CDR-000028 86138001383 0001096
|
||||
CDR-000029 86138001384 0001133
|
||||
CDR-000030 86138001385 0001170
|
||||
CDR-000031 86138001380 0001207
|
||||
CDR-000032 86138001381 0001244
|
||||
CDR-000033 86138001382 0001281
|
||||
CDR-000034 86138001383 0001318
|
||||
CDR-000035 86138001384 0001355
|
||||
CDR-000036 86138001385 0001392
|
||||
CDR-000037 86138001380 0001429
|
||||
CDR-000038 86138001381 0001466
|
||||
CDR-000039 86138001382 0001503
|
||||
CDR-000040 86138001383 0001540
|
||||
CDR-000041 86138001384 0001577
|
||||
CDR-000042 86138001385 0001614
|
||||
CDR-000043 86138001380 0001651
|
||||
CDR-000044 86138001381 0001688
|
||||
CDR-000045 86138001382 0001725
|
||||
CDR-000046 86138001383 0001762
|
||||
CDR-000047 86138001384 0001799
|
||||
CDR-000048 86138001385 0001836
|
||||
CDR-000049 86138001380 0001873
|
||||
CDR-000050 86138001381 0001910
|
||||
CDR-000051 86138001382 0001947
|
||||
CDR-000052 86138001383 0001984
|
||||
CDR-000053 86138001384 0002021
|
||||
CDR-000054 86138001385 0002058
|
||||
CDR-000055 86138001380 0002095
|
||||
CDR-000056 86138001381 0002132
|
||||
CDR-000057 86138001382 0002169
|
||||
CDR-000058 86138001383 0002206
|
||||
CDR-000059 86138001384 0002243
|
||||
CDR-000060 86138001385 0002280
|
||||
CDR-000061 86138001380 0002317
|
||||
CDR-000062 86138001381 0002354
|
||||
CDR-000063 86138001382 0002391
|
||||
CDR-000064 86138001383 0002428
|
||||
CDR-000065 86138001384 0002465
|
||||
CDR-000066 86138001385 0002502
|
||||
CDR-000067 86138001380 0002539
|
||||
CDR-000068 86138001381 0002576
|
||||
CDR-000069 86138001382 0002613
|
||||
CDR-000070 86138001383 0002650
|
||||
CDR-000071 86138001384 0002687
|
||||
CDR-000072 86138001385 0002724
|
||||
CDR-000073 86138001380 0002761
|
||||
CDR-000074 86138001381 0002798
|
||||
CDR-000075 86138001382 0002835
|
||||
CDR-000076 86138001383 0002872
|
||||
CDR-000077 86138001384 0002909
|
||||
CDR-000078 86138001385 0002946
|
||||
CDR-000079 86138001380 0002983
|
||||
CDR-000080 86138001381 0003020
|
||||
CDR-000081 86138001382 0003057
|
||||
CDR-000082 86138001383 0003094
|
||||
CDR-000083 86138001384 0003131
|
||||
CDR-000084 86138001385 0003168
|
||||
CDR-000085 86138001380 0003205
|
||||
CDR-000086 86138001381 0003242
|
||||
CDR-000087 86138001382 0003279
|
||||
CDR-000088 86138001383 0003316
|
||||
CDR-000089 86138001384 0003353
|
||||
CDR-000090 86138001385 0003390
|
||||
CDR-000091 86138001380 0003427
|
||||
CDR-000092 86138001381 0003464
|
||||
CDR-000093 86138001382 0003501
|
||||
CDR-000094 86138001383 0003538
|
||||
CDR-000095 86138001384 0003575
|
||||
CDR-000096 86138001385 0000072
|
||||
CDR-000097 86138001380 0000109
|
||||
CDR-000098 86138001381 0000146
|
||||
CDR-000099 86138001382 0000183
|
||||
CDR-000100 86138001383 0000220
|
||||
CDR-000101 86138001384 0000257
|
||||
@@ -0,0 +1,103 @@
|
||||
HEADER 01202606221645
|
||||
CDR-HDR 0100100
|
||||
CDR-000001 86138001380 0000097
|
||||
CDR-000002 86138001381 0000134
|
||||
CDR-000003 86138001382 0000171
|
||||
CDR-000004 86138001383 0000208
|
||||
CDR-000005 86138001384 0000245
|
||||
CDR-000006 86138001385 0000282
|
||||
CDR-000007 86138001380 0000319
|
||||
CDR-000008 86138001381 0000356
|
||||
CDR-000009 86138001382 0000393
|
||||
CDR-000010 86138001383 0000430
|
||||
CDR-000011 86138001384 0000467
|
||||
CDR-000012 86138001385 0000504
|
||||
CDR-000013 86138001380 0000541
|
||||
CDR-000014 86138001381 0000578
|
||||
CDR-000015 86138001382 0000615
|
||||
CDR-000016 86138001383 0000652
|
||||
CDR-000017 86138001384 0000689
|
||||
CDR-000018 86138001385 0000726
|
||||
CDR-000019 86138001380 0000763
|
||||
CDR-000020 86138001381 0000800
|
||||
CDR-000021 86138001382 0000837
|
||||
CDR-000022 86138001383 0000874
|
||||
CDR-000023 86138001384 0000911
|
||||
CDR-000024 86138001385 0000948
|
||||
CDR-000025 86138001380 0000985
|
||||
CDR-000026 86138001381 0001022
|
||||
CDR-000027 86138001382 0001059
|
||||
CDR-000028 86138001383 0001096
|
||||
CDR-000029 86138001384 0001133
|
||||
CDR-000030 86138001385 0001170
|
||||
CDR-000031 86138001380 0001207
|
||||
CDR-000032 86138001381 0001244
|
||||
CDR-000033 86138001382 0001281
|
||||
CDR-000034 86138001383 0001318
|
||||
CDR-000035 86138001384 0001355
|
||||
CDR-000036 86138001385 0001392
|
||||
CDR-000037 86138001380 0001429
|
||||
CDR-000038 86138001381 0001466
|
||||
CDR-000039 86138001382 0001503
|
||||
CDR-000040 86138001383 0001540
|
||||
CDR-000041 86138001384 0001577
|
||||
CDR-000042 86138001385 0001614
|
||||
CDR-000043 86138001380 0001651
|
||||
CDR-000044 86138001381 0001688
|
||||
CDR-000045 86138001382 0001725
|
||||
CDR-000046 86138001383 0001762
|
||||
CDR-000047 86138001384 0001799
|
||||
CDR-000048 86138001385 0001836
|
||||
CDR-000049 86138001380 0001873
|
||||
CDR-000050 86138001381 0001910
|
||||
CDR-000051 86138001382 0001947
|
||||
CDR-000052 86138001383 0001984
|
||||
CDR-000053 86138001384 0002021
|
||||
CDR-000054 86138001385 0002058
|
||||
CDR-000055 86138001380 0002095
|
||||
CDR-000056 86138001381 0002132
|
||||
CDR-000057 86138001382 0002169
|
||||
CDR-000058 86138001383 0002206
|
||||
CDR-000059 86138001384 0002243
|
||||
CDR-000060 86138001385 0002280
|
||||
CDR-000061 86138001380 0002317
|
||||
CDR-000062 86138001381 0002354
|
||||
CDR-000063 86138001382 0002391
|
||||
CDR-000064 86138001383 0002428
|
||||
CDR-000065 86138001384 0002465
|
||||
CDR-000066 86138001385 0002502
|
||||
CDR-000067 86138001380 0002539
|
||||
CDR-000068 86138001381 0002576
|
||||
CDR-000069 86138001382 0002613
|
||||
CDR-000070 86138001383 0002650
|
||||
CDR-000071 86138001384 0002687
|
||||
CDR-000072 86138001385 0002724
|
||||
CDR-000073 86138001380 0002761
|
||||
CDR-000074 86138001381 0002798
|
||||
CDR-000075 86138001382 0002835
|
||||
CDR-000076 86138001383 0002872
|
||||
CDR-000077 86138001384 0002909
|
||||
CDR-000078 86138001385 0002946
|
||||
CDR-000079 86138001380 0002983
|
||||
CDR-000080 86138001381 0003020
|
||||
CDR-000081 86138001382 0003057
|
||||
CDR-000082 86138001383 0003094
|
||||
CDR-000083 86138001384 0003131
|
||||
CDR-000084 86138001385 0003168
|
||||
CDR-000085 86138001380 0003205
|
||||
CDR-000086 86138001381 0003242
|
||||
CDR-000087 86138001382 0003279
|
||||
CDR-000088 86138001383 0003316
|
||||
CDR-000089 86138001384 0003353
|
||||
CDR-000090 86138001385 0003390
|
||||
CDR-000091 86138001380 0003427
|
||||
CDR-000092 86138001381 0003464
|
||||
CDR-000093 86138001382 0003501
|
||||
CDR-000094 86138001383 0003538
|
||||
CDR-000095 86138001384 0003575
|
||||
CDR-000096 86138001385 0000072
|
||||
CDR-000097 86138001380 0000109
|
||||
CDR-000098 86138001381 0000146
|
||||
CDR-000099 86138001382 0000183
|
||||
CDR-000100 86138001383 0000220
|
||||
TRAILER 0100100
|
||||
@@ -0,0 +1,4 @@
|
||||
HEADER 02202606221645
|
||||
CDR-HDR 0200100
|
||||
CDR-000101 86138001384 0000257
|
||||
TRAILER 0200001
|
||||
@@ -0,0 +1,34 @@
|
||||
# 12-divide-100 — 100-Division File Splitter
|
||||
|
||||
## 电信业务场景
|
||||
|
||||
CDR数据100分割。将CDR数据按100件一个批处理单位进行分割,供后续系统处理。
|
||||
|
||||
Demonstrates dividing input records into groups of 100:
|
||||
|
||||
- **PERFORM VARYING counter**: Track record numbers across the loop
|
||||
- **DIVIDE ... GIVING REMAINDER**: Calculate file number from record count
|
||||
- **Close-write cycle**: Close old file, open new file at each boundary
|
||||
- Tested at boundary conditions: 100 (exact), 101 (one extra), 99 (one short)
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `main-12-divide-100.cbl` | COBOL program (fixed format) |
|
||||
| `data-gen.sh` | Generate N test records (default 101) |
|
||||
| `run.sh` | Compile + run 3 test cases |
|
||||
|
||||
## Algorithm
|
||||
|
||||
```
|
||||
DIVIDE record-count BY 100 GIVING Q REMAINDER R
|
||||
IF R = 1 → open new FILE-OUT-NN
|
||||
Write record to current file
|
||||
```
|
||||
|
||||
## Output Files
|
||||
|
||||
- FILE-OUT-01.DAT: records 1-100
|
||||
- FILE-OUT-02.DAT: records 101-200
|
||||
- etc.
|
||||
@@ -0,0 +1,6 @@
|
||||
*** SPLIT STATISTICS REPORT ***
|
||||
SPLIT STATS: files=02 total-records=00101 min=00004 max=00103
|
||||
=== Split File Inventory ===
|
||||
FILE-OUT-01.DAT: 0000000103 records
|
||||
FILE-OUT-02.DAT: 0000000004 records
|
||||
Boundary: EMPTY=N EXACT-MULT=N SINGLE=N TRAILING=Y TRAIL-COUNT=00001
|
||||
@@ -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.
|
||||
@@ -0,0 +1,89 @@
|
||||
*> ============================================================
|
||||
*> main-divide-100 : CDR数据100分割 (CDR 100-Split)
|
||||
*> Input : FILE-IN (INPUT.DAT: CDR数据)
|
||||
*> Output: FILE-OUT (SPLIT-OUT: 100件毎分割)
|
||||
*> Coverage: S-N005, S-N006, S-N007, S-R001, S-R002
|
||||
*> ============================================================
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. DIVIDE-100.
|
||||
|
||||
ENVIRONMENT DIVISION.
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
SELECT FILE-IN ASSIGN TO "INPUT.DAT"
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FS.
|
||||
|
||||
SELECT FILE-OUT ASSIGN TO "SPLIT-OUT"
|
||||
ORGANIZATION IS SEQUENTIAL.
|
||||
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD FILE-IN RECORD CONTAINS 40 CHARACTERS.
|
||||
01 IN-REC.
|
||||
05 IN-KEY PIC X(10).
|
||||
05 IN-DATA PIC X(20).
|
||||
05 IN-AMT PIC 9(10).
|
||||
|
||||
FD FILE-OUT RECORD CONTAINS 40 CHARACTERS.
|
||||
01 OUT-REC PIC X(40).
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
01 WS-FS PIC X(2).
|
||||
01 WS-EOF PIC X(1) VALUE 'N'.
|
||||
88 WS-EOF-Y VALUE 'Y' FALSE 'N'.
|
||||
01 WS-COUNT PIC 9(10).
|
||||
01 WS-FILE-NUM PIC 9(2).
|
||||
01 WS-FILE-NAME PIC X(20).
|
||||
01 WS-TOTAL-IN PIC 9(10).
|
||||
01 WS-TOTAL-OUT PIC 9(10).
|
||||
01 WS-SPLIT-LIMIT PIC 9(5) VALUE 100.
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
MAIN.
|
||||
DISPLAY "DIVIDE-100: Starting 100-split"
|
||||
OPEN INPUT FILE-IN.
|
||||
MOVE 1 TO WS-FILE-NUM.
|
||||
MOVE 0 TO WS-COUNT.
|
||||
MOVE 0 TO WS-TOTAL-IN.
|
||||
PERFORM OPEN-NEXT-FILE.
|
||||
|
||||
PERFORM UNTIL WS-EOF-Y
|
||||
READ FILE-IN INTO IN-REC
|
||||
AT END SET WS-EOF-Y TO TRUE
|
||||
NOT AT END
|
||||
ADD 1 TO WS-TOTAL-IN WS-COUNT
|
||||
MOVE IN-REC TO OUT-REC
|
||||
WRITE OUT-REC
|
||||
ADD 1 TO WS-TOTAL-OUT
|
||||
IF WS-COUNT >= WS-SPLIT-LIMIT
|
||||
CLOSE FILE-OUT
|
||||
ADD 1 TO WS-FILE-NUM
|
||||
MOVE 0 TO WS-COUNT
|
||||
PERFORM OPEN-NEXT-FILE
|
||||
END-IF
|
||||
END-READ
|
||||
END-PERFORM.
|
||||
|
||||
CLOSE FILE-IN FILE-OUT.
|
||||
DISPLAY "DIVIDE-100: IN=" WS-TOTAL-IN
|
||||
" OUT=" WS-TOTAL-OUT " FILES=" WS-FILE-NUM
|
||||
IF WS-TOTAL-IN = WS-TOTAL-OUT
|
||||
DISPLAY "DIVIDE-100: PASS"
|
||||
STOP RUN RETURNING 0
|
||||
ELSE
|
||||
DISPLAY "DIVIDE-100: FAIL"
|
||||
STOP RUN RETURNING 1
|
||||
END-IF
|
||||
.
|
||||
|
||||
OPEN-NEXT-FILE.
|
||||
STRING "SPLIT100-" WS-FILE-NUM ".DAT"
|
||||
DELIMITED BY SIZE INTO WS-FILE-NAME
|
||||
END-STRING
|
||||
CLOSE FILE-OUT
|
||||
OPEN OUTPUT FILE-OUT
|
||||
DISPLAY "OPEN: " WS-FILE-NAME
|
||||
.
|
||||
|
||||
END PROGRAM DIVIDE-100.
|
||||
Reference in New Issue
Block a user