Identification Division.
Program-ID. FIXNTEST.
Author. James C. Fairfield
Installation. JackRabbit Computer Systems
Date-Written. 12/15/07
*>
*> Converts, justifies, and tests a field up to 255 bytes long.
*>
Environment Division.
Configuration Section.
Special-Names.
Class LOWER-A is 'aƒ„…† ‘bc‡de‚ˆ‰Šfghi‹Œ¡jklmn¤o“”•¢pqrstu–—£vwxy˜z'
Class UPPER-A is 'AAŽ’BC€DEFGHIJKLMN¥O™PQRSTUšVWXYZ'
.
Data Division.
Working-Storage Section.
01 COPYRIGHT-2012 Pic X(64) Value 'Copyright 2012 James C. Fairfield All rights reserved.'.
01 COPYRIGHT-2008 Pic X(64) Value 'Copyright 2008 James C. Fairfield All rights reserved.'.
01 COPYRIGHT-2007 Pic X(64) Value 'Copyright 2007 James C. Fairfield All rights reserved.'.
01.
05 X1 Pic 9(04) Comp-5.
05 X2 Pic 9(04) Comp-5.
05 MX Pic 9(04) Comp-5.
05 MP Pic 9(04) Comp-5.
05 B1 Pic X(01).
05 B2 Pic X(01).
05 MIXED-AREA.
10 MA Pic X(01) occurs 999 times.
88 IS-LOWER Value 'a' thru 'z'.
88 IS-AN Value '0' thru '9' 'A' thru 'Z'.
05 redefines MIXED-AREA.
10 MN Pic X(01) occurs 999 times Comp-X.
05 SP-SIZE Pic 9(02) Comp-5.
05 SP-STR1 Pic X(04). *> Extra byte for comparison ease.
05 SP-STR2 Pic X(03).
05 LOWER-AREA Pic X(999).
05 UPPER-AREA Pic X(999).
*> 2- and 3-character Roman Numerals and Ordinals.
*> If a string ends with any valid 3-character Roman Numeral
*> combinations of "X", "V" and "I", the 3-character suffix will be
*> converted to upper case and all the letters in the preceding part of
*> the string will be converted to upper case via the standard logic.
01 SPECIAL-STRINGS.
05 Pic X(07) Value '2Ii II '.
05 Pic X(07) Value '3IiiIII'.
05 Pic X(07) Value '2Iv IV '.
05 Pic X(07) Value '2Vi VI '.
05 Pic X(07) Value '3ViiVII'.
05 Pic X(07) Value '2Ix IX '.
05 Pic X(07) Value '2Xi XI '.
05 Pic X(07) Value '3XiiXII'.
05 Pic X(07) Value '3XivXIV'.
05 Pic X(07) Value '2Xv XV '.
05 Pic X(07) Value '3XviXVI'.
05 Pic X(07) Value '3XixXIX'.
05 Pic X(07) Value '2Xx XX '.
05 Pic X(07) Value '3XxiXXI'.
05 Pic X(07) Value '3XxvXXV'.
05 Pic X(07) Value '3XxxXXX'.
05 Pic X(07) Value '3iiiIII'.
05 Pic X(07) Value '3viiVII'.
05 Pic X(07) Value '3xiiXII'.
05 Pic X(07) Value '3xivXIV'.
05 Pic X(07) Value '3xviXVI'.
05 Pic X(07) Value '3xixXIX'.
05 Pic X(07) Value '3xxiXXI'.
05 Pic X(07) Value '3xxvXXV'.
05 Pic X(07) Value '3xxxXXX'.
05 Pic X(07) Value '30Th0th'.
05 Pic X(07) Value '31St1st'.
05 Pic X(07) Value '32Nd2nd'.
05 Pic X(07) Value '33Rd3rd'.
05 Pic X(07) Value '34Th4th'.
05 Pic X(07) Value '35Th5th'.
05 Pic X(07) Value '36Th6th'.
05 Pic X(07) Value '37Th7th'.
05 Pic X(07) Value '38Th8th'.
05 Pic X(07) Value '39Th9th'.
05 Pic X(07) Value "2'S 's ".
01 redefines SPECIAL-STRINGS.
78 SS-OCC Value Length of SPECIAL-STRINGS / 7.
05 occurs SS-OCC times Indexed by SSX.
10 SS-SIZE Pic 9(01).
10 SS-STRING-1 Pic X(03).
10 SS-STRING-2 Pic X(03).
Copy STATETBL.WRK.
01 STATE-CODE-TEST-AREA.
05 Pic X(01) Value Space.
05 STATE-CODE-TEST-AREA-2.
10 TEST-STATE-CODE Pic X(02).
10 Pic X(01) Value Space.
Linkage Section.
01 WORK-FIELD Pic X(01).
Copy FIXNTEST.WRK.
Procedure Division using WORK-FIELD FIX-AND-TEST-FIELDS.
000-BEGIN.
Move FT-FIELD-LENGTH to MP
Move WORK-FIELD(1:MP) to UPPER-AREA
If UPPER-AREA = Space
Move 1 to Return-Code
Exit Program
End-If
Move UPPER-AREA to LOWER-AREA
Move UPPER-AREA to MIXED-AREA
Copy TOUPPERA Replacing TARGET by UPPER-AREA.
Copy TOLOWERA Replacing TARGET by LOWER-AREA.
Evaluate FT-CONVERT-TO-CASE
When 'U'
Move UPPER-AREA to MIXED-AREA
When 'X'
Move UPPER-AREA to MIXED-AREA
When 'L'
Move LOWER-AREA to MIXED-AREA
When 'M'
Perform 100-CONVERT-TO-MIXED
End-Evaluate
Move Space to UPPER-AREA
Evaluate FT-JUSTIFY
When 'L'
Perform 200-LEFT-JUSTIFY
When 'R'
Perform 300-RIGHT-JUSTIFY
When 'C'
Perform 400-CENTER
End-Evaluate
If FT-CONVERT-TO-CASE = 'X'
Perform 600-TEST-FOR-NON-ALPHANUMERIC
Else
If FT-CONVERT-TO-CASE not = Space
Perform 500-TEST-FOR-NON-ASCII
End-If
End-If
Move MIXED-AREA to WORK-FIELD(1:MP)
Exit Program
Stop Run
.
100-CONVERT-TO-MIXED.
If (MIXED-AREA = UPPER-AREA or LOWER-AREA) and UPPER-AREA not = LOWER-AREA
Move LOWER-AREA to MIXED-AREA
Perform Varying MX from MP by -1 Until MX < 1
If MA(MX) is LOWER-A
and (MX < 2 or MA(MX - 1) is not LOWER-A or MX < MP and IS-AN(MX + 1))
Copy TOUPPERA Replacing TARGET by MA(MX).
End-If
If MX < MP
*> Neither reconversion routine uses accented characters.
Perform 110-SPECIAL-RECONVERSION
Perform 120-STATE-CODE-RECONVERSION
End-If
End-Perform
End-If
.
110-SPECIAL-RECONVERSION.
*> Irish names starting with "Mc". "O'" requires no special processing.
If MA(MX) = Space
Exit Paragraph
End-If
If MX < MP - 1 and MIXED-AREA(MX:2) = "Mc" and IS-LOWER(MX + 2)
Subtract 32 from MN(MX + 2)
Exit Paragraph
End-If
*> Ordinal numbers 11th thru 13th, may have other digits in front, which are not significant.
If (MX = MP - 3 or MX < MP - 3 and not IS-AN(MX + 4))
and (MIXED-AREA(MX:4) = '11Th' or '12Th' or '13Th')
Move 't' to MA(MX + 2)
Exit Paragraph
End-If
*> Other special strings.
Perform Varying SSX from 1 by 1 Until SSX > SS-OCC
Move SS-SIZE(SSX) to SP-SIZE
*> The special string must be at the end
*> of the field or followed by a space.
Compute X1 = SP-SIZE + MX - 1
If X1 > MP
Exit Perform Cycle
End-If
Move SP-SIZE to X2
If X1 < MP
Add 1 to X2
End-If
Move SS-STRING-1(SSX) to SP-STR1
Move SS-STRING-2(SSX) to SP-STR2
If MIXED-AREA(MX:X2) = SP-STR1(1:X2)
Move SP-STR2 to MIXED-AREA(MX:SP-SIZE)
Exit Perform
End-If
End-Perform
.
120-STATE-CODE-RECONVERSION.
*> Special cases where the state code is at the beginning or end of the string are unlikely and probably not valid.
If MX < MP - 2 and MA(MX) = Space and MA(MX + 1) not = Space and MA(MX + 2) not = Space and MA(MX + 3) = Space
Move UPPER-AREA(MX + 1:2) to TEST-STATE-CODE
Search All STATE-TAB
When TEST-STATE-CODE = STATE-CODE(STATE-X)
Move TEST-STATE-CODE to MIXED-AREA(MX + 1:2)
End-Search
End-If
.
200-LEFT-JUSTIFY.
Move Space to UPPER-AREA
Move Space to B1
Move Zero to X1
Perform Varying MX from 1 by 1 Until MX > MP
Move MA(MX) to B2
If B2 not = Space or B1
Add 1 to X1
Move B2 to UPPER-AREA(X1:1)
Move B2 to B1
End-If
End-Perform
Move UPPER-AREA to MIXED-AREA
.
300-RIGHT-JUSTIFY.
Move Space to UPPER-AREA
Move Space to B1
Move MP to X1
Perform Varying MX from MP by -1 Until MX < 1
Move MA(MX) to B2
If B2 not = Space or B1
Move B2 to UPPER-AREA(X1:1)
Move B2 to B1
Subtract 1 from X1
End-If
End-Perform
Move UPPER-AREA to MIXED-AREA
.
400-CENTER.
Move Space to B1
Move Zero to X1
Perform Varying MX from 1 by 1 Until MX > MP
Move MA(MX) to B2
If B2 not = Space or B1
Add 1 to X1
Move B2 to UPPER-AREA(X1:1)
Move B2 to B1
End-If
End-Perform
If UPPER-AREA(X1:1) = Space
Subtract 1 from X1
End-If
Compute MX = (MP - X1) / 2 + 1
Move Space to MIXED-AREA
Move UPPER-AREA to MIXED-AREA(MX:X1)
.
500-TEST-FOR-NON-ASCII.
Move Zero to Return-Code
Perform Varying MX from 1 by 1 Until MX > MP
If MA(MX) < Space or > '~'
Exit Perform
End-If
End-Perform
If MX <= MP
Add 1 to MX
Move MX to Return-Code
End-If
.
600-TEST-FOR-NON-ALPHANUMERIC.
Move Zero to Return-Code
Perform Varying MX from 1 by 1 Until MX > MP
If not IS-AN(MX) and MA(MX) not = Space
Exit Perform
End-If
End-Perform
If MX <= MP
Add 1 to MX
Move MX to Return-Code
End-If
.