feat: add benchmark-programs — 58 telecom COBOL test programs
作为子目录纳入系统,与核心测试管道协同 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# 27-validation-halfwidth: Half-Width Character Validation
|
||||
|
||||
## 电信业务场景
|
||||
|
||||
电话号码格式校验。检查电话号码字段是否全为半角数字(0-9),检测全角字符混入和长度超出。
|
||||
|
||||
## Description
|
||||
|
||||
Reads FILE-IN and validates that each character in IN-TEXT is
|
||||
half-width (ASCII printable: X'20'-X'7E'). Validates length
|
||||
constraints: 20 or fewer half-width characters pass; more than 20
|
||||
is an error. Full-width characters or control characters cause
|
||||
rejection.
|
||||
|
||||
## Validation Rules
|
||||
|
||||
| Rule | Result | Error Code |
|
||||
|-----------------------------------|--------------|------------|
|
||||
| All characters X'20'-X'7E', <= 20 | PASS to GOOD | - |
|
||||
| Contains non-half-width character | FAIL to BAD | 01 |
|
||||
| All half-width but >20 chars | FAIL to BAD | 02 |
|
||||
|
||||
## Record Layout
|
||||
|
||||
### Input / Good Output (30 bytes)
|
||||
|
||||
| Field | Type | Length | Description |
|
||||
|--------|----------|--------|-------------|
|
||||
| TEXT | PIC X | 30 | Text to validate |
|
||||
|
||||
### Bad Output (32 bytes)
|
||||
|
||||
| Field | Type | Length | Description |
|
||||
|----------|----------|--------|----------------|
|
||||
| TEXT | PIC X | 30 | Original text |
|
||||
| ERR-CODE | PIC X | 2 | Error code |
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|-------------------------------|--------------------------------|
|
||||
| main-27-validation-halfwidth.cbl | Main COBOL program |
|
||||
| data-gen.sh | Generate test data |
|
||||
| run.sh | Compile, run, verify |
|
||||
| README.md | This file |
|
||||
|
||||
## Tests
|
||||
|
||||
| Test Case | Expected |
|
||||
|----------------------------------|-----------------------------|
|
||||
| 4 half-width chars | PASS to GOOD |
|
||||
| 10 half-width chars | PASS to GOOD |
|
||||
| 20 half-width chars (boundary) | PASS to GOOD |
|
||||
| 25 half-width chars (too long) | FAIL err 02 |
|
||||
| Mixed with full-width | FAIL err 01 |
|
||||
| Full-width only | FAIL err 01 |
|
||||
| Half-width + control char | FAIL err 01 |
|
||||
| All spaces (empty) | PASS to GOOD |
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
cd 27-validation-halfwidth
|
||||
bash data-gen.sh
|
||||
bash run.sh
|
||||
```
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
- Half-width check uses byte comparison against X'20'-X'7E'.
|
||||
- Full-width UTF-8 multi-byte characters have bytes > X'7E'
|
||||
and are detected as non-half-width.
|
||||
- Length is computed by trimming trailing spaces.
|
||||
- Only records meeting both conditions (half-width + <= 20 chars)
|
||||
are written to GOOD output.
|
||||
@@ -0,0 +1 @@
|
||||
=== AUDIT LOG === Program: ValidationHalfwidth Timestamp: 2026-06-22 16:35:27 Records read : 000000001 Records good : 000000001 Records bad : 000000000 Records skip : 000000000 Warnings : 000000001 Errors : 000000000 Hash total : 000000000000000 Rules: HALF-FORMAT-LENGTH-PREFIX Severity: W=Warning, E=Error Input : file-in.dat Output: file-out-good.dat Output: file-out-bad.dat Output: file-out-report.dat Output: file-out-audit.dat === END AUDIT ===
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
=== VALIDATION REPORT === Timestamp: 2026-06-22 16:35:27 Records read : 1 Records passed : 1 Records failed : 0 Records skipped : 0 Warnings issued : 1 Errors detected : 0 Total chars : 000000000000000 Total digits : 000000000000000 Hash total : 0 R1: Half-width check (X'20'-X'7E') R2: Character set (digits 0-9, leading +) R3: Length (mobile=11, landline=10-12) R4: Prefix lookup (China mobile/landline) === END OF REPORT ===
|
||||
@@ -0,0 +1,841 @@
|
||||
*> ============================================================
|
||||
*> 27-validation-halfwidth : Phone Number Validation
|
||||
*> Extended with SECTION structure, prefix validation,
|
||||
*> phone length rules, audit/report files, severity levels,
|
||||
*> batch control totals, FILE STATUS checks, DISPLAY tracing.
|
||||
*> Input : FILE-IN (file-in.dat)
|
||||
*> Output: FILE-OUT-GOOD, -BAD, -REPORT, -AUDIT
|
||||
*> Coverage: VF-N005, VF-N006, VF-A001, VF-A002, VF-R001
|
||||
*> VF-P001, VF-P002, VF-P003, VF-L001, VF-S001
|
||||
*> ============================================================
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. ValidationHalfwidth.
|
||||
*>
|
||||
ENVIRONMENT DIVISION.
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
SELECT FILE-IN ASSIGN TO 'file-in.dat'
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
ACCESS MODE IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-IN-STATUS.
|
||||
SELECT FILE-OUT-GOOD ASSIGN TO 'file-out-good.dat'
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-GOOD-STATUS.
|
||||
SELECT FILE-OUT-BAD ASSIGN TO 'file-out-bad.dat'
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-BAD-STATUS.
|
||||
SELECT FILE-OUT-REPORT
|
||||
ASSIGN TO 'file-out-report.dat'
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-REPORT-STATUS.
|
||||
SELECT FILE-OUT-AUDIT
|
||||
ASSIGN TO 'file-out-audit.dat'
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FILE-AUDIT-STATUS.
|
||||
*>
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD FILE-IN.
|
||||
01 IN-REC.
|
||||
05 IN-TEXT PIC X(30).
|
||||
*>
|
||||
FD FILE-OUT-GOOD.
|
||||
01 GOOD-REC.
|
||||
05 GOOD-TEXT PIC X(30).
|
||||
*>
|
||||
FD FILE-OUT-BAD.
|
||||
01 BAD-REC.
|
||||
05 BAD-TEXT PIC X(30).
|
||||
05 BAD-ERR-CODE PIC X(02).
|
||||
*>
|
||||
FD FILE-OUT-REPORT.
|
||||
01 REPORT-REC.
|
||||
05 REPORT-LINE PIC X(80).
|
||||
*>
|
||||
FD FILE-OUT-AUDIT.
|
||||
01 AUDIT-REC.
|
||||
05 AUDIT-LINE PIC X(80).
|
||||
*>
|
||||
WORKING-STORAGE SECTION.
|
||||
01 WS-TELECOM-REC.
|
||||
COPY "telecom/TEL-BILLING.cpy".
|
||||
*> File status fields
|
||||
01 WS-FILE-IN-STATUS PIC X(02).
|
||||
01 WS-FILE-GOOD-STATUS PIC X(02).
|
||||
01 WS-FILE-BAD-STATUS PIC X(02).
|
||||
01 WS-FILE-REPORT-STATUS PIC X(02).
|
||||
01 WS-FILE-AUDIT-STATUS PIC X(02).
|
||||
*> EOF and loop control
|
||||
01 WS-EOF PIC X(01) VALUE 'N'.
|
||||
88 WS-EOF-YES VALUE 'Y' FALSE 'N'.
|
||||
*> Record counts
|
||||
01 WS-TOTAL-READ PIC 9(09) VALUE ZERO.
|
||||
01 WS-GOOD-COUNT PIC 9(09) VALUE ZERO.
|
||||
01 WS-BAD-COUNT PIC 9(09) VALUE ZERO.
|
||||
01 WS-SKIP-COUNT PIC 9(09) VALUE ZERO.
|
||||
01 WS-WARN-COUNT PIC 9(09) VALUE ZERO.
|
||||
01 WS-ERROR-COUNT PIC 9(09) VALUE ZERO.
|
||||
*> Batch control totals
|
||||
01 WS-TOTAL-CHARS PIC 9(15) VALUE ZERO.
|
||||
01 WS-TOTAL-DIGITS PIC 9(15) VALUE ZERO.
|
||||
01 WS-HASH-TOTAL PIC 9(15) VALUE ZERO.
|
||||
*> Validation fields
|
||||
01 WS-IDX PIC 9(02).
|
||||
01 WS-CHAR PIC X(01).
|
||||
01 WS-ALL-HALF PIC X(01) VALUE 'Y'.
|
||||
88 WS-ALL-HALF-YES VALUE 'Y' FALSE 'N'.
|
||||
01 WS-TEXT-LEN PIC 9(02).
|
||||
*> Multiple validation results
|
||||
01 WS-VALID-RESULT.
|
||||
05 WS-V-FORMAT PIC X(01) VALUE 'P'.
|
||||
88 WS-V-FORMAT-PASS VALUE 'P'.
|
||||
88 WS-V-FORMAT-FAIL VALUE 'F'.
|
||||
05 WS-V-LENGTH PIC X(01) VALUE 'P'.
|
||||
88 WS-V-LENGTH-PASS VALUE 'P'.
|
||||
88 WS-V-LENGTH-FAIL VALUE 'F'.
|
||||
05 WS-V-PREFIX PIC X(01) VALUE 'P'.
|
||||
88 WS-V-PREFIX-PASS VALUE 'P'.
|
||||
88 WS-V-PREFIX-FAIL VALUE 'F'.
|
||||
05 WS-V-HALF PIC X(01) VALUE 'P'.
|
||||
88 WS-V-HALF-PASS VALUE 'P'.
|
||||
88 WS-V-HALF-FAIL VALUE 'F'.
|
||||
01 WS-V-FORMAT-ERR PIC X(02).
|
||||
01 WS-V-LENGTH-ERR PIC X(02).
|
||||
01 WS-V-PREFIX-ERR PIC X(02).
|
||||
01 WS-V-HALF-ERR PIC X(02).
|
||||
*> Error codes and severity
|
||||
01 WS-ERROR-CODE PIC X(02).
|
||||
01 WS-ERROR-SEVERITY PIC X(01).
|
||||
88 WS-SEVERITY-WARNING VALUE 'W'.
|
||||
88 WS-SEVERITY-ERROR VALUE 'E'.
|
||||
01 WS-ERROR-DETAIL PIC X(50).
|
||||
*> Half-width range constants
|
||||
01 WS-HW-LOWER PIC X(01) VALUE X'20'.
|
||||
01 WS-HW-UPPER PIC X(01) VALUE X'7E'.
|
||||
*> Phone number analysis
|
||||
01 WS-PHONE-TYPE PIC X(01).
|
||||
88 WS-PHONE-MOBILE VALUE 'M'.
|
||||
88 WS-PHONE-LANDLINE VALUE 'L'.
|
||||
88 WS-PHONE-UNKNOWN VALUE 'U'.
|
||||
01 WS-PHONE-DIGITS PIC X(30).
|
||||
01 WS-PHONE-DIGIT-COUNT PIC 9(02).
|
||||
01 WS-PREFIX-STR PIC X(06).
|
||||
01 WS-PREFIX-LEN PIC 9(02).
|
||||
01 WS-HAS-LEADING-PLUS PIC X(01) VALUE 'N'.
|
||||
88 WS-LEADING-PLUS-YES VALUE 'Y' FALSE 'N'.
|
||||
*>
|
||||
*> Known prefixes — China mobile (8613x, 8615x, 8618x)
|
||||
01 WS-MOBILE-PREFIX-TBL.
|
||||
05 FILLER PIC X(05) VALUE '86130'.
|
||||
05 FILLER PIC X(05) VALUE '86131'.
|
||||
05 FILLER PIC X(05) VALUE '86132'.
|
||||
05 FILLER PIC X(05) VALUE '86133'.
|
||||
05 FILLER PIC X(05) VALUE '86135'.
|
||||
05 FILLER PIC X(05) VALUE '86136'.
|
||||
05 FILLER PIC X(05) VALUE '86137'.
|
||||
05 FILLER PIC X(05) VALUE '86138'.
|
||||
05 FILLER PIC X(05) VALUE '86139'.
|
||||
05 FILLER PIC X(05) VALUE '86150'.
|
||||
05 FILLER PIC X(05) VALUE '86151'.
|
||||
05 FILLER PIC X(05) VALUE '86152'.
|
||||
05 FILLER PIC X(05) VALUE '86153'.
|
||||
05 FILLER PIC X(05) VALUE '86155'.
|
||||
05 FILLER PIC X(05) VALUE '86156'.
|
||||
05 FILLER PIC X(05) VALUE '86157'.
|
||||
05 FILLER PIC X(05) VALUE '86158'.
|
||||
05 FILLER PIC X(05) VALUE '86159'.
|
||||
05 FILLER PIC X(05) VALUE '86180'.
|
||||
05 FILLER PIC X(05) VALUE '86181'.
|
||||
05 FILLER PIC X(05) VALUE '86182'.
|
||||
05 FILLER PIC X(05) VALUE '86183'.
|
||||
05 FILLER PIC X(05) VALUE '86185'.
|
||||
05 FILLER PIC X(05) VALUE '86186'.
|
||||
05 FILLER PIC X(05) VALUE '86187'.
|
||||
05 FILLER PIC X(05) VALUE '86188'.
|
||||
05 FILLER PIC X(05) VALUE '86189'.
|
||||
01 WS-MOBILE-TABLE REDEFINES WS-MOBILE-PREFIX-TBL.
|
||||
05 WS-MOBILE-ITEM PIC X(05) OCCURS 27 TIMES.
|
||||
01 WS-MOBILE-PREFIX-COUNT PIC 9(02) VALUE 27.
|
||||
*>
|
||||
*> Known prefixes — China landline (city codes)
|
||||
01 WS-LL-PREFIX-TBL.
|
||||
05 FILLER PIC X(05) VALUE '86010'.
|
||||
05 FILLER PIC X(05) VALUE '86020'.
|
||||
05 FILLER PIC X(05) VALUE '86021'.
|
||||
05 FILLER PIC X(05) VALUE '86022'.
|
||||
05 FILLER PIC X(05) VALUE '86023'.
|
||||
05 FILLER PIC X(05) VALUE '86024'.
|
||||
05 FILLER PIC X(05) VALUE '86025'.
|
||||
05 FILLER PIC X(05) VALUE '86027'.
|
||||
05 FILLER PIC X(05) VALUE '86028'.
|
||||
05 FILLER PIC X(05) VALUE '86029'.
|
||||
05 FILLER PIC X(05) VALUE '86031'.
|
||||
05 FILLER PIC X(05) VALUE '86041'.
|
||||
05 FILLER PIC X(05) VALUE '86051'.
|
||||
05 FILLER PIC X(05) VALUE '86052'.
|
||||
05 FILLER PIC X(05) VALUE '86053'.
|
||||
05 FILLER PIC X(05) VALUE '86054'.
|
||||
05 FILLER PIC X(05) VALUE '86055'.
|
||||
05 FILLER PIC X(05) VALUE '86056'.
|
||||
05 FILLER PIC X(05) VALUE '86057'.
|
||||
05 FILLER PIC X(05) VALUE '86058'.
|
||||
05 FILLER PIC X(05) VALUE '86059'.
|
||||
05 FILLER PIC X(05) VALUE '86063'.
|
||||
05 FILLER PIC X(05) VALUE '86066'.
|
||||
05 FILLER PIC X(05) VALUE '86067'.
|
||||
05 FILLER PIC X(05) VALUE '86069'.
|
||||
05 FILLER PIC X(05) VALUE '86071'.
|
||||
05 FILLER PIC X(05) VALUE '86072'.
|
||||
05 FILLER PIC X(05) VALUE '86073'.
|
||||
05 FILLER PIC X(05) VALUE '86074'.
|
||||
05 FILLER PIC X(05) VALUE '86075'.
|
||||
05 FILLER PIC X(05) VALUE '86076'.
|
||||
05 FILLER PIC X(05) VALUE '86077'.
|
||||
05 FILLER PIC X(05) VALUE '86078'.
|
||||
05 FILLER PIC X(05) VALUE '86079'.
|
||||
05 FILLER PIC X(05) VALUE '86081'.
|
||||
05 FILLER PIC X(05) VALUE '86082'.
|
||||
05 FILLER PIC X(05) VALUE '86083'.
|
||||
05 FILLER PIC X(05) VALUE '86084'.
|
||||
05 FILLER PIC X(05) VALUE '86085'.
|
||||
05 FILLER PIC X(05) VALUE '86086'.
|
||||
05 FILLER PIC X(05) VALUE '86087'.
|
||||
05 FILLER PIC X(05) VALUE '86088'.
|
||||
05 FILLER PIC X(05) VALUE '86089'.
|
||||
05 FILLER PIC X(05) VALUE '86091'.
|
||||
05 FILLER PIC X(05) VALUE '86092'.
|
||||
05 FILLER PIC X(05) VALUE '86093'.
|
||||
05 FILLER PIC X(05) VALUE '86094'.
|
||||
05 FILLER PIC X(05) VALUE '86095'.
|
||||
05 FILLER PIC X(05) VALUE '86096'.
|
||||
05 FILLER PIC X(05) VALUE '86097'.
|
||||
05 FILLER PIC X(05) VALUE '86098'.
|
||||
05 FILLER PIC X(05) VALUE '86099'.
|
||||
01 WS-LL-TABLE REDEFINES WS-LL-PREFIX-TBL.
|
||||
05 WS-LL-ITEM PIC X(05) OCCURS 51 TIMES.
|
||||
01 WS-LL-PREFIX-COUNT PIC 9(02) VALUE 51.
|
||||
*>
|
||||
*> Timestamp and trace fields
|
||||
01 WS-CURRENT-TIME.
|
||||
05 WS-CURR-YEAR PIC X(04).
|
||||
05 WS-CURR-MONTH PIC X(02).
|
||||
05 WS-CURR-DAY PIC X(02).
|
||||
05 WS-CURR-HOUR PIC X(02).
|
||||
05 WS-CURR-MIN PIC X(02).
|
||||
05 WS-CURR-SEC PIC X(02).
|
||||
01 WS-TIMESTAMP PIC X(20).
|
||||
01 WS-TRACE-TS PIC X(20).
|
||||
*> Report editing fields
|
||||
01 WS-ED-PASS PIC Z(09)9.
|
||||
01 WS-ED-FAIL PIC Z(09)9.
|
||||
01 WS-ED-SKIP PIC Z(09)9.
|
||||
01 WS-ED-WARN PIC Z(09)9.
|
||||
01 WS-ED-ERROR PIC Z(09)9.
|
||||
01 WS-ED-TOTAL PIC Z(09)9.
|
||||
01 WS-ED-HASH PIC Z(14)9.
|
||||
*> Local variables
|
||||
01 WS-J PIC 9(02).
|
||||
01 WS-K PIC 9(02).
|
||||
*>
|
||||
*> ============================================================
|
||||
PROCEDURE DIVISION.
|
||||
*> ============================================================
|
||||
MAIN SECTION.
|
||||
MB-PROCESS.
|
||||
PERFORM 1000-INIT.
|
||||
PERFORM 2000-OPEN-FILES.
|
||||
PERFORM 3000-READ-INPUT
|
||||
UNTIL WS-EOF-YES.
|
||||
PERFORM 4000-REPORT.
|
||||
PERFORM 5000-AUDIT.
|
||||
PERFORM 9000-EXIT.
|
||||
STOP RUN.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 1000-INIT : Initialize counters, tables, batch timestamp
|
||||
*> ============================================================
|
||||
1000-INIT SECTION.
|
||||
I1000-START.
|
||||
DISPLAY 'ValidationHalfwidth: 1000-INIT starting...'.
|
||||
MOVE ZERO TO WS-TOTAL-READ
|
||||
WS-GOOD-COUNT
|
||||
WS-BAD-COUNT
|
||||
WS-SKIP-COUNT
|
||||
WS-WARN-COUNT
|
||||
WS-ERROR-COUNT
|
||||
WS-TOTAL-CHARS
|
||||
WS-TOTAL-DIGITS
|
||||
WS-HASH-TOTAL.
|
||||
MOVE 'N' TO WS-EOF.
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-TIME.
|
||||
STRING WS-CURR-YEAR '-' WS-CURR-MONTH '-'
|
||||
WS-CURR-DAY ' ' WS-CURR-HOUR ':'
|
||||
WS-CURR-MIN ':' WS-CURR-SEC
|
||||
INTO WS-TIMESTAMP.
|
||||
DISPLAY 'ValidationHalfwidth: Batch started at '
|
||||
WS-TIMESTAMP.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 2000-OPEN-FILES : Open all files with FILE STATUS checks
|
||||
*> ============================================================
|
||||
2000-OPEN-FILES SECTION.
|
||||
I2000-START.
|
||||
DISPLAY 'ValidationHalfwidth: 2000-OPEN-FILES starting...'.
|
||||
OPEN INPUT FILE-IN.
|
||||
IF WS-FILE-IN-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '10' TO WS-ERROR-CODE
|
||||
STRING 'FILE-IN open failed, status='
|
||||
WS-FILE-IN-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF.
|
||||
OPEN OUTPUT FILE-OUT-GOOD.
|
||||
IF WS-FILE-GOOD-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '11' TO WS-ERROR-CODE
|
||||
STRING 'FILE-OUT-GOOD open failed, status='
|
||||
WS-FILE-GOOD-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF.
|
||||
OPEN OUTPUT FILE-OUT-BAD.
|
||||
IF WS-FILE-BAD-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '12' TO WS-ERROR-CODE
|
||||
STRING 'FILE-OUT-BAD open failed, status='
|
||||
WS-FILE-BAD-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF.
|
||||
OPEN OUTPUT FILE-OUT-REPORT.
|
||||
IF WS-FILE-REPORT-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '13' TO WS-ERROR-CODE
|
||||
STRING 'FILE-OUT-REPORT open failed, status='
|
||||
WS-FILE-REPORT-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF.
|
||||
OPEN OUTPUT FILE-OUT-AUDIT.
|
||||
IF WS-FILE-AUDIT-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '14' TO WS-ERROR-CODE
|
||||
STRING 'FILE-OUT-AUDIT open failed, status='
|
||||
WS-FILE-AUDIT-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF.
|
||||
DISPLAY 'ValidationHalfwidth: All files opened OK'.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 3000-READ-INPUT : Read loop — read record and dispatch
|
||||
*> ============================================================
|
||||
3000-READ-INPUT SECTION.
|
||||
I3000-START.
|
||||
PERFORM 3100-VALIDATE-RECORD THRU I3100-EXIT.
|
||||
IF NOT WS-EOF-YES
|
||||
PERFORM 3200-PROCESS-RECORD
|
||||
PERFORM 3300-WRITE-OUTPUT
|
||||
END-IF.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 3100-VALIDATE-RECORD : Full validation pipeline
|
||||
*> R1: Half-width check
|
||||
*> R2: Character set (digits 0-9, optional leading +)
|
||||
*> R3: Length check (mobile=11, landline=10-12)
|
||||
*> R4: Prefix lookup (China mobile/landline)
|
||||
*> R5: Format rules for mobile vs landline
|
||||
*> ============================================================
|
||||
3100-VALIDATE-RECORD SECTION.
|
||||
I3100-START.
|
||||
MOVE 'P' TO WS-V-FORMAT WS-V-LENGTH WS-V-PREFIX WS-V-HALF.
|
||||
MOVE SPACES TO WS-V-FORMAT-ERR WS-V-LENGTH-ERR
|
||||
WS-V-PREFIX-ERR WS-V-HALF-ERR
|
||||
WS-ERROR-CODE WS-ERROR-DETAIL
|
||||
WS-PHONE-TYPE.
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-TIME.
|
||||
STRING WS-CURR-HOUR ':' WS-CURR-MIN ':'
|
||||
WS-CURR-SEC INTO WS-TRACE-TS.
|
||||
DISPLAY '3100-VALIDATE-RECORD: ['
|
||||
WS-TRACE-TS '] Processing: "'
|
||||
FUNCTION TRIM(IN-TEXT) '"'.
|
||||
READ FILE-IN
|
||||
AT END
|
||||
SET WS-EOF-YES TO TRUE
|
||||
DISPLAY '3100-VALIDATE-RECORD: EOF reached'
|
||||
EXIT PARAGRAPH
|
||||
NOT AT END
|
||||
DISPLAY '3100-VALIDATE-RECORD: Read OK status='
|
||||
WS-FILE-IN-STATUS
|
||||
END-READ.
|
||||
IF WS-EOF-YES
|
||||
EXIT
|
||||
END-IF.
|
||||
IF WS-FILE-IN-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '15' TO WS-ERROR-CODE
|
||||
STRING 'READ failed, status=' WS-FILE-IN-STATUS
|
||||
INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF.
|
||||
ADD 1 TO WS-TOTAL-READ.
|
||||
*>
|
||||
*> R1: Half-width check (original logic preserved)
|
||||
MOVE 'Y' TO WS-ALL-HALF.
|
||||
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 30
|
||||
MOVE IN-TEXT(WS-IDX:1) TO WS-CHAR
|
||||
IF WS-CHAR = SPACE
|
||||
CONTINUE
|
||||
ELSE
|
||||
IF WS-CHAR < WS-HW-LOWER
|
||||
MOVE 'N' TO WS-ALL-HALF
|
||||
END-IF
|
||||
IF WS-CHAR > WS-HW-UPPER
|
||||
MOVE 'N' TO WS-ALL-HALF
|
||||
END-IF
|
||||
END-IF
|
||||
END-PERFORM.
|
||||
IF NOT WS-ALL-HALF-YES
|
||||
MOVE 'F' TO WS-V-HALF
|
||||
MOVE '01' TO WS-V-HALF-ERR
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
DISPLAY '3100-VALIDATE-RECORD: HALF-WIDTH FAIL'
|
||||
END-IF.
|
||||
*>
|
||||
*> R2: Character set check — extract digits, allow leading +
|
||||
MOVE SPACES TO WS-PHONE-DIGITS.
|
||||
MOVE ZERO TO WS-PHONE-DIGIT-COUNT.
|
||||
MOVE 'N' TO WS-HAS-LEADING-PLUS.
|
||||
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 30
|
||||
MOVE IN-TEXT(WS-IDX:1) TO WS-CHAR
|
||||
IF WS-CHAR = SPACE
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
IF WS-IDX = 1 AND WS-CHAR = '+'
|
||||
MOVE 'Y' TO WS-HAS-LEADING-PLUS
|
||||
CONTINUE
|
||||
END-IF
|
||||
IF WS-CHAR >= '0' AND WS-CHAR <= '9'
|
||||
ADD 1 TO WS-PHONE-DIGIT-COUNT
|
||||
MOVE WS-CHAR TO
|
||||
WS-PHONE-DIGITS(WS-PHONE-DIGIT-COUNT:1)
|
||||
ELSE
|
||||
IF WS-CHAR NOT = SPACE
|
||||
MOVE 'F' TO WS-V-FORMAT
|
||||
MOVE '02' TO WS-V-FORMAT-ERR
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
END-IF
|
||||
END-IF
|
||||
END-PERFORM.
|
||||
ADD WS-PHONE-DIGIT-COUNT TO WS-TOTAL-DIGITS.
|
||||
ADD FUNCTION NUMVAL(WS-PHONE-DIGITS) TO WS-HASH-TOTAL
|
||||
ON SIZE ERROR
|
||||
ADD 1 TO WS-HASH-TOTAL
|
||||
END-ADD.
|
||||
*>
|
||||
*> R3: Determine phone type from prefix, validate length
|
||||
MOVE SPACES TO WS-PREFIX-STR.
|
||||
MOVE ZERO TO WS-PREFIX-LEN.
|
||||
IF WS-PHONE-DIGIT-COUNT >= 5
|
||||
MOVE WS-PHONE-DIGITS(1:5) TO WS-PREFIX-STR
|
||||
MOVE 5 TO WS-PREFIX-LEN
|
||||
END-IF.
|
||||
MOVE 'U' TO WS-PHONE-TYPE.
|
||||
IF WS-PREFIX-LEN = 5
|
||||
PERFORM VARYING WS-J FROM 1 BY 1
|
||||
UNTIL WS-J > WS-MOBILE-PREFIX-COUNT
|
||||
IF WS-PREFIX-STR = WS-MOBILE-ITEM(WS-J)
|
||||
MOVE 'M' TO WS-PHONE-TYPE
|
||||
DISPLAY '3100-VALIDATE-RECORD: Mobile prefix: '
|
||||
WS-PREFIX-STR
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
END-PERFORM
|
||||
IF WS-PHONE-TYPE = 'U'
|
||||
PERFORM VARYING WS-K FROM 1 BY 1
|
||||
UNTIL WS-K > WS-LL-PREFIX-COUNT
|
||||
IF WS-PREFIX-STR = WS-LL-ITEM(WS-K)
|
||||
MOVE 'L' TO WS-PHONE-TYPE
|
||||
DISPLAY '3100-VALIDATE-RECORD: Landline '
|
||||
'prefix: ' WS-PREFIX-STR
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
END-PERFORM
|
||||
END-IF
|
||||
END-IF.
|
||||
*>
|
||||
*> R4: Length validation per phone type
|
||||
EVALUATE TRUE
|
||||
WHEN WS-PHONE-MOBILE
|
||||
IF WS-PHONE-DIGIT-COUNT NOT = 11
|
||||
MOVE 'F' TO WS-V-LENGTH
|
||||
MOVE '03' TO WS-V-LENGTH-ERR
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
DISPLAY '3100-VALIDATE-RECORD: LENGTH FAIL '
|
||||
'mobile expected 11 got '
|
||||
WS-PHONE-DIGIT-COUNT
|
||||
END-IF
|
||||
WHEN WS-PHONE-LANDLINE
|
||||
IF WS-PHONE-DIGIT-COUNT < 10 OR
|
||||
WS-PHONE-DIGIT-COUNT > 12
|
||||
MOVE 'F' TO WS-V-LENGTH
|
||||
MOVE '04' TO WS-V-LENGTH-ERR
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
DISPLAY '3100-VALIDATE-RECORD: LENGTH FAIL '
|
||||
'landline expected 10-12 got '
|
||||
WS-PHONE-DIGIT-COUNT
|
||||
END-IF
|
||||
WHEN WS-PHONE-UNKNOWN
|
||||
MOVE 'W' TO WS-ERROR-SEVERITY
|
||||
MOVE '05' TO WS-V-PREFIX-ERR
|
||||
DISPLAY '3100-VALIDATE-RECORD: PREFIX UNKNOWN for "'
|
||||
FUNCTION TRIM(IN-TEXT) '"'
|
||||
IF WS-PHONE-DIGIT-COUNT > 0
|
||||
IF WS-PHONE-DIGIT-COUNT NOT >= 10 AND
|
||||
WS-PHONE-DIGIT-COUNT NOT <= 12
|
||||
MOVE 'F' TO WS-V-LENGTH
|
||||
MOVE '06' TO WS-V-LENGTH-ERR
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
END-IF
|
||||
END-IF
|
||||
END-EVALUATE.
|
||||
*>
|
||||
*> Compute content length — trim trailing spaces (original)
|
||||
MOVE 30 TO WS-TEXT-LEN.
|
||||
PERFORM VARYING WS-IDX FROM 30 BY -1 UNTIL WS-IDX = 0
|
||||
IF IN-TEXT(WS-IDX:1) = SPACE
|
||||
SUBTRACT 1 FROM WS-TEXT-LEN
|
||||
ELSE
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
END-PERFORM.
|
||||
ADD WS-TEXT-LEN TO WS-TOTAL-CHARS.
|
||||
*>
|
||||
*> Apply original validation rules (preserved)
|
||||
MOVE SPACES TO WS-ERROR-CODE.
|
||||
IF NOT WS-ALL-HALF-YES
|
||||
MOVE '01' TO WS-ERROR-CODE
|
||||
ELSE
|
||||
IF WS-TEXT-LEN > 20
|
||||
MOVE '02' TO WS-ERROR-CODE
|
||||
END-IF
|
||||
END-IF.
|
||||
*>
|
||||
*> Combine all rule results — priority: HALF > FORMAT > LENGTH
|
||||
IF WS-V-HALF-FAIL
|
||||
IF WS-ERROR-CODE = SPACES
|
||||
MOVE '01' TO WS-ERROR-CODE
|
||||
END-IF
|
||||
END-IF.
|
||||
IF WS-V-FORMAT-FAIL
|
||||
MOVE '07' TO WS-ERROR-CODE
|
||||
END-IF.
|
||||
IF WS-V-LENGTH-FAIL
|
||||
MOVE '08' TO WS-ERROR-CODE
|
||||
END-IF.
|
||||
IF WS-V-PREFIX-FAIL
|
||||
IF WS-ERROR-CODE = SPACES
|
||||
MOVE '09' TO WS-ERROR-CODE
|
||||
END-IF
|
||||
END-IF.
|
||||
IF WS-SEVERITY-ERROR
|
||||
ADD 1 TO WS-ERROR-COUNT
|
||||
END-IF.
|
||||
IF WS-SEVERITY-WARNING
|
||||
ADD 1 TO WS-WARN-COUNT
|
||||
END-IF.
|
||||
I3100-EXIT.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 3200-PROCESS-RECORD : Route to GOOD/BAD/SKIP
|
||||
*> ============================================================
|
||||
3200-PROCESS-RECORD SECTION.
|
||||
I3200-START.
|
||||
DISPLAY '3200-PROCESS-RECORD: error-code='
|
||||
WS-ERROR-CODE ' severity=' WS-ERROR-SEVERITY.
|
||||
EVALUATE TRUE
|
||||
WHEN WS-ERROR-CODE = SPACES
|
||||
ADD 1 TO WS-GOOD-COUNT
|
||||
DISPLAY '3200-PROCESS-RECORD: -> GOOD'
|
||||
WHEN WS-SEVERITY-WARNING
|
||||
ADD 1 TO WS-WARN-COUNT
|
||||
ADD 1 TO WS-GOOD-COUNT
|
||||
DISPLAY '3200-PROCESS-RECORD: -> GOOD (warn)'
|
||||
WHEN WS-SEVERITY-ERROR
|
||||
ADD 1 TO WS-ERROR-COUNT
|
||||
ADD 1 TO WS-BAD-COUNT
|
||||
DISPLAY '3200-PROCESS-RECORD: -> BAD code='
|
||||
WS-ERROR-CODE
|
||||
WHEN OTHER
|
||||
ADD 1 TO WS-SKIP-COUNT
|
||||
DISPLAY '3200-PROCESS-RECORD: -> SKIP'
|
||||
END-EVALUATE.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 3300-WRITE-OUTPUT : Write record to GOOD or BAD file
|
||||
*> ============================================================
|
||||
3300-WRITE-OUTPUT SECTION.
|
||||
I3300-START.
|
||||
IF WS-ERROR-CODE = SPACES
|
||||
MOVE IN-TEXT TO GOOD-TEXT
|
||||
WRITE GOOD-REC
|
||||
DISPLAY '3300-WRITE-OUTPUT: Wrote GOOD record'
|
||||
IF WS-FILE-GOOD-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '20' TO WS-ERROR-CODE
|
||||
STRING 'WRITE GOOD-REC failed, status='
|
||||
WS-FILE-GOOD-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF
|
||||
ELSE
|
||||
MOVE IN-TEXT TO BAD-TEXT
|
||||
MOVE WS-ERROR-CODE TO BAD-ERR-CODE
|
||||
WRITE BAD-REC
|
||||
DISPLAY '3300-WRITE-OUTPUT: Wrote BAD record code='
|
||||
WS-ERROR-CODE
|
||||
IF WS-FILE-BAD-STATUS NOT = '00'
|
||||
MOVE 'E' TO WS-ERROR-SEVERITY
|
||||
MOVE '21' TO WS-ERROR-CODE
|
||||
STRING 'WRITE BAD-REC failed, status='
|
||||
WS-FILE-BAD-STATUS INTO WS-ERROR-DETAIL
|
||||
PERFORM 6000-ERROR-HANDLE
|
||||
END-IF
|
||||
END-IF.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 4000-REPORT : Generate validation report
|
||||
*> ============================================================
|
||||
4000-REPORT SECTION.
|
||||
I4000-START.
|
||||
DISPLAY 'ValidationHalfwidth: 4000-REPORT starting...'.
|
||||
MOVE WS-GOOD-COUNT TO WS-ED-PASS.
|
||||
MOVE WS-BAD-COUNT TO WS-ED-FAIL.
|
||||
MOVE WS-SKIP-COUNT TO WS-ED-SKIP.
|
||||
MOVE WS-WARN-COUNT TO WS-ED-WARN.
|
||||
MOVE WS-ERROR-COUNT TO WS-ED-ERROR.
|
||||
MOVE WS-TOTAL-READ TO WS-ED-TOTAL.
|
||||
MOVE WS-HASH-TOTAL TO WS-ED-HASH.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING '=== VALIDATION REPORT ===' INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
IF WS-FILE-REPORT-STATUS NOT = '00'
|
||||
DISPLAY '4000-REPORT: WRITE header failed, status='
|
||||
WS-FILE-REPORT-STATUS
|
||||
END-IF.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Timestamp: ' WS-TIMESTAMP INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Records read : ' WS-ED-TOTAL INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Records passed : ' WS-ED-PASS INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Records failed : ' WS-ED-FAIL INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Records skipped : ' WS-ED-SKIP INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Warnings issued : ' WS-ED-WARN INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Errors detected : ' WS-ED-ERROR INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Total chars : ' WS-TOTAL-CHARS
|
||||
INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Total digits : ' WS-TOTAL-DIGITS
|
||||
INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'Hash total : ' WS-ED-HASH INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'R1: Half-width check (X''20''-X''7E'')'
|
||||
INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'R2: Character set (digits 0-9, leading +)'
|
||||
INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'R3: Length (mobile=11, landline=10-12)'
|
||||
INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING 'R4: Prefix lookup (China mobile/landline)'
|
||||
INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
MOVE SPACES TO REPORT-LINE.
|
||||
STRING '=== END OF REPORT ===' INTO REPORT-LINE.
|
||||
WRITE REPORT-REC.
|
||||
DISPLAY 'ValidationHalfwidth: 4000-REPORT complete'.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 5000-AUDIT : Write audit summary with timestamps
|
||||
*> ============================================================
|
||||
5000-AUDIT SECTION.
|
||||
I5000-START.
|
||||
DISPLAY 'ValidationHalfwidth: 5000-AUDIT starting...'.
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-TIME.
|
||||
STRING WS-CURR-YEAR '-' WS-CURR-MONTH '-'
|
||||
WS-CURR-DAY ' ' WS-CURR-HOUR ':'
|
||||
WS-CURR-MIN ':' WS-CURR-SEC
|
||||
INTO WS-TIMESTAMP.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING '=== AUDIT LOG ===' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
IF WS-FILE-AUDIT-STATUS NOT = '00'
|
||||
DISPLAY '5000-AUDIT: WRITE header failed, status='
|
||||
WS-FILE-AUDIT-STATUS
|
||||
END-IF.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Program: ValidationHalfwidth' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Timestamp: ' WS-TIMESTAMP INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Records read : ' WS-TOTAL-READ INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Records good : ' WS-GOOD-COUNT INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Records bad : ' WS-BAD-COUNT INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Records skip : ' WS-SKIP-COUNT INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Warnings : ' WS-WARN-COUNT INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Errors : ' WS-ERROR-COUNT INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Hash total : ' WS-HASH-TOTAL INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Rules: HALF-FORMAT-LENGTH-PREFIX'
|
||||
INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Severity: W=Warning, E=Error'
|
||||
INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Input : file-in.dat' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Output: file-out-good.dat' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Output: file-out-bad.dat' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Output: file-out-report.dat' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Output: file-out-audit.dat' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING '=== END AUDIT ===' INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
DISPLAY 'ValidationHalfwidth: 5000-AUDIT complete'.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 6000-ERROR-HANDLE : Centralized error handler
|
||||
*> WARNING: display and continue
|
||||
*> ERROR: display, close files, stop run
|
||||
*> ============================================================
|
||||
6000-ERROR-HANDLE SECTION.
|
||||
I6000-START.
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-TIME.
|
||||
STRING WS-CURR-HOUR ':' WS-CURR-MIN ':'
|
||||
WS-CURR-SEC INTO WS-TRACE-TS.
|
||||
EVALUATE TRUE
|
||||
WHEN WS-SEVERITY-WARNING
|
||||
DISPLAY '6000-ERROR-HANDLE: [' WS-TRACE-TS
|
||||
'] WARNING code=' WS-ERROR-CODE
|
||||
' ' WS-ERROR-DETAIL
|
||||
ADD 1 TO WS-WARN-COUNT
|
||||
WHEN WS-SEVERITY-ERROR
|
||||
DISPLAY '6000-ERROR-HANDLE: [' WS-TRACE-TS
|
||||
'] ** ERROR ** code=' WS-ERROR-CODE
|
||||
' ' WS-ERROR-DETAIL
|
||||
ADD 1 TO WS-ERROR-COUNT
|
||||
ADD 1 TO WS-BAD-COUNT
|
||||
DISPLAY 'ValidationHalfwidth: ABORTING'
|
||||
PERFORM 9000-EXIT
|
||||
WHEN OTHER
|
||||
DISPLAY '6000-ERROR-HANDLE: [' WS-TRACE-TS
|
||||
'] UNKNOWN severity=' WS-ERROR-SEVERITY
|
||||
END-EVALUATE.
|
||||
EXIT.
|
||||
*>
|
||||
*> ============================================================
|
||||
*> 9000-EXIT : Close files, display summary, stop run
|
||||
*> ============================================================
|
||||
9000-EXIT SECTION.
|
||||
I9000-START.
|
||||
DISPLAY 'ValidationHalfwidth: 9000-EXIT closing files...'.
|
||||
CLOSE FILE-IN.
|
||||
IF WS-FILE-IN-STATUS NOT = '00'
|
||||
DISPLAY 'CLOSE FILE-IN status=' WS-FILE-IN-STATUS
|
||||
END-IF.
|
||||
CLOSE FILE-OUT-GOOD.
|
||||
IF WS-FILE-GOOD-STATUS NOT = '00'
|
||||
DISPLAY 'CLOSE FILE-OUT-GOOD status='
|
||||
WS-FILE-GOOD-STATUS
|
||||
END-IF.
|
||||
CLOSE FILE-OUT-BAD.
|
||||
IF WS-FILE-BAD-STATUS NOT = '00'
|
||||
DISPLAY 'CLOSE FILE-OUT-BAD status='
|
||||
WS-FILE-BAD-STATUS
|
||||
END-IF.
|
||||
CLOSE FILE-OUT-REPORT.
|
||||
IF WS-FILE-REPORT-STATUS NOT = '00'
|
||||
DISPLAY 'CLOSE FILE-OUT-REPORT status='
|
||||
WS-FILE-REPORT-STATUS
|
||||
END-IF.
|
||||
CLOSE FILE-OUT-AUDIT.
|
||||
IF WS-FILE-AUDIT-STATUS NOT = '00'
|
||||
DISPLAY 'CLOSE FILE-OUT-AUDIT status='
|
||||
WS-FILE-AUDIT-STATUS
|
||||
END-IF.
|
||||
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-TIME.
|
||||
STRING WS-CURR-YEAR '-' WS-CURR-MONTH '-'
|
||||
WS-CURR-DAY ' ' WS-CURR-HOUR ':'
|
||||
WS-CURR-MIN ':' WS-CURR-SEC
|
||||
INTO WS-TIMESTAMP.
|
||||
DISPLAY ' '.
|
||||
DISPLAY '========================================'.
|
||||
DISPLAY 'ValidationHalfwidth: FINAL SUMMARY'.
|
||||
DISPLAY 'Batch ended: ' WS-TIMESTAMP.
|
||||
DISPLAY 'Records read : ' WS-TOTAL-READ.
|
||||
DISPLAY 'Records passed : ' WS-GOOD-COUNT.
|
||||
DISPLAY 'Records failed : ' WS-BAD-COUNT.
|
||||
DISPLAY 'Records skipped : ' WS-SKIP-COUNT.
|
||||
DISPLAY 'Warnings issued : ' WS-WARN-COUNT.
|
||||
DISPLAY 'Errors detected : ' WS-ERROR-COUNT.
|
||||
DISPLAY 'Total chars : ' WS-TOTAL-CHARS.
|
||||
DISPLAY 'Total digits : ' WS-TOTAL-DIGITS.
|
||||
DISPLAY 'Hash total : ' WS-HASH-TOTAL.
|
||||
DISPLAY '========================================'.
|
||||
MOVE SPACES TO AUDIT-LINE.
|
||||
STRING 'Batch ended: ' WS-TIMESTAMP INTO AUDIT-LINE.
|
||||
WRITE AUDIT-REC.
|
||||
DISPLAY 'ValidationHalfwidth: Done.'.
|
||||
STOP RUN.
|
||||
*>
|
||||
*> ============================================================
|
||||
END PROGRAM ValidationHalfwidth.
|
||||
@@ -0,0 +1,157 @@
|
||||
*> ============================================================
|
||||
*> main-validation-halfwidth : 电话号码校验 (Phone Validation)
|
||||
*> Input : FILE-IN (INPUT.DAT: 电话号码文字列)
|
||||
*> Output: FILE-PASS (PASS.DAT: 校验通过)
|
||||
*> Coverage: VF-N005, VF-N006, VF-A001, VF-A002, VF-R001
|
||||
*> ============================================================
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. VALIDATE-HALF.
|
||||
|
||||
ENVIRONMENT DIVISION.
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
SELECT FILE-IN ASSIGN TO "INPUT.DAT"
|
||||
ORGANIZATION IS SEQUENTIAL
|
||||
FILE STATUS IS WS-FS.
|
||||
|
||||
SELECT FILE-PASS ASSIGN TO "PASS.DAT"
|
||||
ORGANIZATION IS SEQUENTIAL.
|
||||
|
||||
SELECT FILE-FAIL ASSIGN TO "FAIL.DAT"
|
||||
ORGANIZATION IS SEQUENTIAL.
|
||||
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD FILE-IN RECORD CONTAINS 60 CHARACTERS.
|
||||
01 IN-RECORD.
|
||||
05 IN-ID PIC X(10).
|
||||
05 IN-HALF20 PIC X(20).
|
||||
05 IN-HALF4 PIC X(4).
|
||||
05 IN-CHECK-TYPE PIC X(1).
|
||||
05 IN-FILLER PIC X(25).
|
||||
|
||||
FD FILE-PASS RECORD CONTAINS 60 CHARACTERS.
|
||||
01 PASS-REC PIC X(60).
|
||||
|
||||
FD FILE-FAIL RECORD CONTAINS 80 CHARACTERS.
|
||||
01 FAIL-REC.
|
||||
05 FAIL-ID PIC X(10).
|
||||
05 FAIL-REASON PIC X(30).
|
||||
05 FAIL-DATA 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-READ-COUNT PIC 9(10).
|
||||
01 WS-PASS-COUNT PIC 9(10).
|
||||
01 WS-FAIL-COUNT PIC 9(10).
|
||||
01 WS-I PIC 9(2).
|
||||
01 WS-CHAR PIC X(1).
|
||||
01 WS-IS-HALF PIC X(1) VALUE 'Y'.
|
||||
88 WS-IS-HALF-Y VALUE 'Y' FALSE 'N'.
|
||||
01 WS-CHECK-20 PIC X(20).
|
||||
01 WS-CHECK-4 PIC X(4).
|
||||
01 WS-HALF-LOWER PIC X(26) VALUE 'abcdefghijklmnopqrstuvwxyz'.
|
||||
01 WS-HALF-UPPER PIC X(26) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
|
||||
01 WS-HALF-DIGIT PIC X(10) VALUE '0123456789'.
|
||||
01 WS-HALF-SYMBOL PIC X(33) VALUE ' !"#$%&''()*+,-./:;<=>?@[\]^_`{|}~'.
|
||||
|
||||
01 WS-TELECOM-REC.
|
||||
COPY "telecom/TEL-BILLING.cpy".
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
MAIN.
|
||||
DISPLAY "VALIDATE-HALF: Starting halfwidth validation"
|
||||
OPEN INPUT FILE-IN.
|
||||
OPEN OUTPUT FILE-PASS FILE-FAIL.
|
||||
|
||||
PERFORM UNTIL WS-EOF-Y
|
||||
READ FILE-IN INTO IN-RECORD
|
||||
AT END
|
||||
SET WS-EOF-Y TO TRUE
|
||||
NOT AT END
|
||||
ADD 1 TO WS-READ-COUNT
|
||||
MOVE IN-HALF20 TO WS-CHECK-20
|
||||
PERFORM CHECK-HALF20
|
||||
IF WS-IS-HALF-Y
|
||||
MOVE IN-HALF4 TO WS-CHECK-4
|
||||
PERFORM CHECK-HALF4
|
||||
END-IF
|
||||
IF WS-IS-HALF-Y
|
||||
ADD 1 TO WS-PASS-COUNT
|
||||
MOVE IN-RECORD TO PASS-REC
|
||||
WRITE PASS-REC
|
||||
DISPLAY "PASS: " IN-ID " - halfwidth OK"
|
||||
ELSE
|
||||
ADD 1 TO WS-FAIL-COUNT
|
||||
MOVE IN-ID TO FAIL-ID
|
||||
STRING "HALFWIDTH CHECK FAILED - data contains "
|
||||
"non-halfwidth characters"
|
||||
DELIMITED BY SIZE INTO FAIL-REASON
|
||||
END-STRING
|
||||
MOVE IN-HALF20 TO FAIL-DATA
|
||||
WRITE FAIL-REC
|
||||
DISPLAY "FAIL: " IN-ID " - non-halfwidth detected"
|
||||
END-IF
|
||||
END-READ
|
||||
END-PERFORM.
|
||||
|
||||
CLOSE FILE-IN FILE-PASS FILE-FAIL.
|
||||
|
||||
DISPLAY "VALIDATE-HALF: READ=" WS-READ-COUNT
|
||||
" PASS=" WS-PASS-COUNT " FAIL=" WS-FAIL-COUNT
|
||||
DISPLAY "VALIDATE-HALF: Total = READ (R001)"
|
||||
|
||||
IF WS-READ-COUNT = WS-PASS-COUNT + WS-FAIL-COUNT
|
||||
DISPLAY "VALIDATE-HALF: PASS"
|
||||
STOP RUN RETURNING 0
|
||||
ELSE
|
||||
DISPLAY "VALIDATE-HALF: FAIL - count mismatch"
|
||||
STOP RUN RETURNING 1
|
||||
END-IF
|
||||
.
|
||||
|
||||
CHECK-HALF20.
|
||||
SET WS-IS-HALF TO TRUE
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 20
|
||||
MOVE WS-CHECK-20(WS-I:1) TO WS-CHAR
|
||||
IF WS-CHAR = SPACE
|
||||
CONTINUE
|
||||
ELSE
|
||||
IF WS-CHAR >= 'a' AND <= 'z'
|
||||
CONTINUE
|
||||
ELSE IF WS-CHAR >= 'A' AND <= 'Z'
|
||||
CONTINUE
|
||||
ELSE IF WS-CHAR >= '0' AND <= '9'
|
||||
CONTINUE
|
||||
ELSE
|
||||
MOVE 'N' TO WS-IS-HALF
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
END-IF
|
||||
END-PERFORM
|
||||
.
|
||||
|
||||
CHECK-HALF4.
|
||||
SET WS-IS-HALF TO TRUE
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 4
|
||||
MOVE WS-CHECK-4(WS-I:1) TO WS-CHAR
|
||||
IF WS-CHAR = SPACE
|
||||
CONTINUE
|
||||
ELSE
|
||||
IF WS-CHAR >= 'a' AND <= 'z'
|
||||
CONTINUE
|
||||
ELSE IF WS-CHAR >= 'A' AND <= 'Z'
|
||||
CONTINUE
|
||||
ELSE IF WS-CHAR >= '0' AND <= '9'
|
||||
CONTINUE
|
||||
ELSE
|
||||
MOVE 'N' TO WS-IS-HALF
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
END-IF
|
||||
END-PERFORM
|
||||
.
|
||||
|
||||
END PROGRAM VALIDATE-HALF.
|
||||
Reference in New Issue
Block a user