@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             FTN221
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                            ISSUE 10~
~V9 -1
~P
~V9 1
~YFTN221
~S1~M~OFORTRAN 77 I/O LIBRARY IMPLEMENTATION DESCRIPTION~
~S1~M~OSection 22~
~S1~OSection 22.  Format Specification Processing~
~S1~O1.1  General Description~
~BThis section of the library processes Fortran Formats at compile
time and run-time. At compile time the Format given in a Format
statement is passed by the compiler to the library for analysis.
The Format is itemised into the Format tables, maintained by the
library and the compiler informed if the Format was valid. At
run-time Format in byte vectors are similarly processed.
~BThis section may be compiled as a separate library from the rest of
the input/output procedures for use at compile time, if the machine
environment makes this necessary.~
~S1~O2.  Interfaces~
~S1~O2.1  Section Interfaces Used~
~BNone.
~S1~O2.2  Section Interface~
~
Library Procedures:~
   FIO.FORMAT~
   FIO.C.FORMAT~
~S1~O3.  Implementation~
~S1~O3.1.  Outline of Operation.~
~BThe routine FIO.FORMAT performs the major operation of itemising
and validating Format specifications. The Format is processed one
character at a time, from the opening parenthesis to the matching
closing parenthesis. Each character is first masked by one of four
possible masks and the result used as the selector in one large
switch statement.~
~BWhen called at compile time when Hollerith strings have been
itemised. Format of itemised Hollerith is~
~3
~
~Mbyte 0 - warning character for itemised Hollerith~
~Nnext 'n' bytes - the characters for the itemised Hollerith~
~Nlast byte - zero.~
~
Character strings are itemised in a similar manner.~
~BA switch is used at 4 points during format recognition.~
~T# 6
~
1.
~IInitial field descriptor characters~
~I/ : ) F E D G I A L ( T S B '  //~
~I01 .... 9 repeat count, scale factor, n of nX or nH~
~I+ - scale factor~
~IItemised Holleriths character~
~
2.
~IPermitted characters after a non scale factor count (i.e.
repeat count, n of nX or nH)~
~IF E D G I A L H X (~
~
3.
~IPermitted characters after a scale factor~
~I/ : , ) F E D G  //~
~
4.
~IAfter a field descriptor~
~I/ : , )  //~
~0
~BA single switch is used at all four points, therefore characters
when valid transfer control to the same processing point.~
~3
~Q 27
~
~
Switch controls are~
~
 0    /   //~
 1    :~
 2    ,~
 3    )~
 4    F~
 5    E~
 6    D~
 7    Faulty characters~
 8    I~
 9    A~
10    L~
11    H~
12    X~
13    (~
14    G~
15    S~
16    B~
17    T~
18    01 .... 9~
19    +~
20    -~
21    itemised Hollerith~
22    '~
~T# 8
~Q 11
~
~
  1.
~ISwitch values for initial characters are in bits 0-4 of
CH.CNTRL1.~
~
  2.
~ISwitch values for characters after a non scale factor count are
in bits 0-3 of CH.CNTRL2.~
~
  3.
~ISwitch values for characters after a scale factor are in bits
4-7 of CH.CNTRL2.~
~
  4.
~ISwitch values for characters after a field descriptor are in
bits 5-7 of CH.CNTRL1.~
~0
~BThe format builds up the itemised format in the Format table.
The index of the end of this Format in the table is returned
as the result of the recognition if the Format was valid,
if the format was invalid the position in the itemised line of
the faulty part is returned as a negative number.
~S1~O3.2  Data Structures~
~S1~O3.2.1  Format Table~
~3
~Q 23
~
DESCRIPTOR            Entry~
  I                      1   W    d/1~
  A                      2   W/0~
  L                      3   W~
  E or D                 4   W    d    e/0~
  F                      5   W    d      0~
  G                      6   W    d    e/0~
Hollerith/Apostrophe     0   n    index into char const table~
Start Format            -1   0~
End Format              -2   repeat address~
Start Group             -3   n(rep cnt -1)~
End Group               -4   repeat address~
Repeat Count            -5   n (repeat count -1)~
Scale factor            -6   n~
   X                    -7   n~
   B                    -8   1/0 BN/BZ~
   /                    -9~
   S                   -10   1/0 SP/SS~
   :                   -11~
   TR                  -12   n~
   TL                  -13   n~
   T                   -14   n~
~0
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                FTN221
~F
@TITLE FTN22(1,11)
@COL 1S-2R-7R-9F
@FLOW 1-2-7-9
@BOX 1.0
FORMAT SPECIFICATION SECTION
@BOX 2.0
MODULE HEADING
@BOX 7.0
PROCEDURES IN MODULE
   FTN21.1:FIO.FORMAT
   FTN22.2:FIO.C.FORMAT
@BOX 9.0
END
@BOX 2.1
;MODULE (FIO.FORMAT,FIO.C.FORMAT) ;
@BOX 7.1
;L.SPEC FIO.C.FORMAT(ADDR[$LO8], ADDR[$IN16], ADDR[$LO8]) /$IN16
;P.SPEC FIO.FORMAT(ADDR [$LO8], ADDR[$IN16], ADDR[$LO8], $IN, $IN) /$IN
#FTN22.1
#FTN22.2
@BOX 9.1
;*END
@END
@TITLE FTN22.1(1,6)
@COL 1S-2R-3R-4T-5R-6R-7R-8R-9R-10R
@COL 11R-12C-13F
@ROW 11-4
@FLOW 1-2-3-4N-5-6-7-8-9-10
@FLOW 4Y-11-12-13
@BOX 1.0
FORMAT(SOURCE)
ANALYSE  FORMAT
@BOX 2.0
SKIP BLANKS
@BOX 3.0
INITIALISE
MAKE START FORMAT
ENTRY
REMEMBER FORMAT
ADDR
@BOX 4.0
CH NE (
@BOX 5.0
NEXT ITEM
@BOX 6.0
RESET
ITEM INFO
@BOX 7.0
SWITCH ON CHAR
@BOX 8.0
DIGIT,+,-             :2.1.1
I A L                 :2.1.2
F E D G!              :2.1.3
' ,ITEMISED HOLL      :2.1.4
T S B                 :2.1.5
/ : , //              :2.1.6
( )                   :2.1.7
FAULTY CHAR           :2.1
@BOX 9.0
OTHER ACTIONS
nX ,nH      :2.1.8
SEPARATOR   :2.1.9
@BOX 10.0
SUBROUTINES
READ.INT    :2.1.10
@BOX 11.0
ALL FAULTY
CHARS
@BOX 12.0
FALSE
@BOX 13.0
RETURN
FAULT
@BOX 1.1
;PROC FIO.FORMAT(LINE,FMT.TBL,CHAR.CONST.TBL,HOLL,COMP)
#FTN22.1.0
@BOX 2.1
;-1 => SS
;WHILE LINE^[1+>SS] = SPACE.L DO OD
@BOX 3.1
;0 => GRP.F.P => CHAR.CONST.PTR => FMT.ST => F.P
;-1 => FMT.TBL^[F.P]
;0 => FMT.TBL^[F.P+1] => FMT.NEST
; 2 +> F.P
@BOX 4.1
;IF LINE^[1+>SS-1] /= '(
@BOX 5.1
;NEXT.ITEM:
@BOX 6.1
;1 => CNT
@BOX 7.1
;CH.CNTRL1[LINE^[1+>SS-1]] & %1F => FD.I
;RESELECT:
SWITCH FD.I \
     SLASH,
     COLON,
     COMMA,
     RIGHT,
     F.SW,
     E.SW,
     D.SW,
     FALSE,
     I.SW,
     A.SW,
     L.SW,
     H.SW,
     X.SW,
     LEFT,
     G.SW,
     S.SW,
     B.SW,
     T.SW,
     DIGITS,
     PLUS,
     MINUS,
     I.HOLL,
     PRIME
@BOX 8.1
#FTN22.1.1
#FTN22.1.2
#FTN22.1.3
#FTN22.1.4
#FTN22.1.5
#FTN22.1.6
#FTN22.1.7
@BOX 9.1
#FTN22.1.8
#FTN22.1.9
@BOX 10.1
#FTN22.1.10
@BOX 11.1
@BOX 12.1
;FALSE:
@BOX 13.1
;0-SS => FIO.FORMAT
END
@END


@TITLE FTN22.1.0(1,11)
@COL 1S
@FLOW 1
@BOX 1.0
FORMAT DECLARATIONS
@BOX 1.1
;-> START
;G.FALSE>: -> FALSE
;P.SPEC FIO.READ.INT($IN)/$IN
; LITERAL/$LO8 SPACE.L = ' ,NL = %0A,FMT.NEST.LIMIT = 16
;INTEGER SS,CNT,FD.I,SIGN,CH,FMT.ST,I,F.P,FMT.NEST
;INTEGER W,D,M,E,FD,C.P,C,GRP.F.P,NO,CHAR.CONST.PTR
; $IN [FMT.NEST.LIMIT] FMT.STACK
;DATAVEC CH.CNTRL1($LO8)
%E7 %00 %E7[14] %F5[2] %E7[14]
%42 %E7[6] %F6
%ED %63 %E7 %F3 %47 %F4 %E7 %00
%F2[8]
%F2 %F2 %21 %E7[5]
%E7 %E9 %F0 %E7 %E6 %E5 %E4 %EE
%E7 %E8 %E7 %E7 %EA %E7 %E7 %E7
%E7 %E7 %E7 %EF %F1 %E7 %E7 %E7
%E7[8]
%E7[32]
%E7[15] %E7
END
;DATAVEC CH.CNTRL2($LO8)
%77[32]
%22 %77[6] %77 :: @@@ BCT 08/12/82
%7D %37 %77 %77 %27 %77 %77 %07
%77[8]
%77 %77 %17 %77[5]
%77 %79 %77 %77 %66 %55 %44 %EE
%7B %78 %77 %77 %7A %77 %77 %77
%77 %77 %77 %77 %77 %77 %77 %77
%7C %77[7]
%77[32]
%E7[16]
END
;DATAVEC FD.NO($IN)
-9 -11 %FFF2 %FFF3 5 %104 4 %FFFF 1 2 3 0 -7 %FFFD %106 -10 -8 -14
END
:: / : SPACE   )   F   E  D FAULT I A L H  X   (     G   S   B  T
; START :
@END
@TITLE FTN22.1.1(1,6)
@COL 7T-8R-9R-20T-21R-22T-10R
@COL 1S-2R-3R-4T-5T-6R-23C
@COL 11R-12R-13R-14R-15C
@ROW 5-7
@ROW 11-1
@ROW 6-15
@ROW 10-23
@FLOW 1-2-3-4N-5N-6
@FLOW 4Y-7N-8-9-20N-21-22N-10
@FLOW 7Y-9
@FLOW 5Y-15
@FLOW 11-12-3
@FLOW 13-14-3
@FLOW 20Y-10
@FLOW 22Y-23
@BOX 1.0
DIGIT
@BOX 2.0
NOTE UNSIGNED
GET PREVIOUS CH
@BOX 3.0
READ INT INTO
CNT
@BOX 4.0
NEXT CH
A P ?
@BOX 5.0
SIGNED OR ZERO
@BOX 6.0
SWITCH ON
CHAR
(
IAL
FEDG
HX
AND OTHER
CHARS FAULTY
@BOX 7.0
ACCEPT CH
NOT NEG SIGNED
@BOX 8.0
NEGATE CNT
@BOX 9.0
MAKE SCALE
FACTOR ENTRY
CLEAR CNT
@BOX 20.0
NEXT CH
NOT A DIGIT?
@BOX 21.0
READ INT INTO
CNT
@BOX 22.0
NEXT CH NOT
ALPHABETIC
@BOX 23.0
FALSE
@BOX 10.0
SWITCH ON
CHAR
/ :
) ,
FEDG
AND OTHER
CHARS FAULTY
@BOX 11.0
+
@BOX 12.0
NOTE SIGN
@BOX 13.0
-
@BOX 14.0
NOTE SIGN
@BOX 15.0
FALSE
@BOX 1.1
;DIGITS:
@BOX 2.1
;1 -> SS
;0 => SIGN
@BOX 3.1
; FIO.READ.INT(0) => CNT
@BOX 4.1
;IF LINE^[SS] = 'P
@BOX 5.1
;IF SIGN /= 0 OR CNT = 0
@BOX 6.1
;CH.CNTRL2[LINE^[1+>SS-1]] & %F => FD.I
;-> RESELECT
@BOX 7.1
;1 +> SS
; IF SIGN >= 0
@BOX 8.1
;0 -:> CNT
@BOX 9.1
;-6 => FMT.TBL^[F.P]
;CNT => FMT.TBL^[F.P+1]
; 2 +> F.P
; 0 => CNT
@BOX 20.1
; IF LINE^[SS] < '0 OR LINE^[SS] > '9
@BOX 21.1
; FIO.READ.INT(1) => CNT
@BOX 22.1
; IF LINE^[SS] < 'A OR LINE^[SS] > 'Z
@BOX 23.1
; -> FALSE
@BOX 10.1
;CH.CNTRL2[LINE^[1+>SS-1]] ->> 4 => FD.I
;-> RESELECT
@BOX 11.1
;PLUS:
@BOX 12.1
;1 => SIGN
@BOX 13.1
;MINUS:
@BOX 14.1
;-1 => SIGN
@BOX 15.1
;-> FALSE
@END


@TITLE FTN22.1.2(1,6)
@COL 16R-20C
@COL 1S-2T-3R-4T-5R-6R-7R-8R-9R-10T-11R-19T-12T-13R-14R-15R
@COL 17R-18R
@ROW 20-12
@ROW 1-17
@ROW 3-16
@ROW 11-18
@FLOW 1-2N-3-4N-5-6-7
@FLOW 8-9-10N-11-19N-12N-13-14-15
@FLOW 2Y-16-4
@FLOW 4Y-6
@FLOW 10Y-18-12
@FLOW 12Y-14
@FLOW 19Y-20
@FLOW 17-3
@BOX 1.0
A
@BOX 2.0
NEXT CH NOT
A DIGIT
@BOX 3.0
READ A NON ZERO
INT TO W
@BOX 4.0
RC NOT
PRESENT
@BOX 5.0
ADD RC ENTRY
@BOX 6.0
MAKE FD ENTRY
@BOX 7.0
SEPARATOR
@BOX 8.0
I
@BOX 9.0
READ A NON ZERO
INT INTO W
@BOX 10.0
NEXT CH /= .
@BOX 11.0
ACCEPT CH
READ UNSIGNED
INT CONST INTO M
@BOX 12.0
RC NOT PRESENT
@BOX 13.0
ADD RC ENTRY
@BOX 14.0
MAKE 3WD ENTRY
@BOX 15.0
SEPARATOR
@BOX 16.0
SET
W  = 0
@BOX 17.0
L
@BOX 18.0
SET M = 1
@BOX 19.0
M>W ?
@BOX 20.0
FALSE
@BOX 1.1
;A.SW:
@BOX 2.1
;IF LINE^[SS] => CH < '0 OR CH > '9
@BOX 3.1
; FIO.READ.INT(1) => W
@BOX 4.1
;IF CNT < 2
@BOX 5.1
;-5 => FMT.TBL^[F.P]
;CNT-1 => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 6.1
;FD.NO[FD.I] => FMT.TBL^[F.P]
;W => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 7.1
;-> SEPARATOR
@BOX 8.1
;I.SW:
@BOX 9.1
; FIO.READ.INT(1) => W
@BOX 10.1
;IF LINE^[SS] /= '.
@BOX 11.1
;1 +> SS
; FIO.READ.INT(0) => M
@BOX 12.1
;IF CNT< 2
@BOX 13.1
;-5 => FMT.TBL^[F.P]
;CNT-1 => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 14.1
;1 => FMT.TBL^[F.P]
;W => FMT.TBL^[F.P+1]
;M => FMT.TBL^[F.P+2]
; 3 +> F.P
@BOX 15.1
;-> SEPARATOR
@BOX 16.1
;0 => W
@BOX 17.1
;L.SW:
@BOX 18.1
;1 => M
@BOX 19.1
;IF M > W
@BOX 20.1
;-> FALSE
@END


@TITLE FTN22.1.3(1,6)
@COL 1S-2R-3T-4R-5T-6T-7T-8R-9T-10R-11R-12R
@COL 13C-14R
@ROW 13-5
@ROW 14-8
@FLOW 1-2-3N-4-5N-6N-7N-8-9N-10-11-12
@FLOW 3Y-13
@FLOW 5Y-13
@FLOW 6Y-14-9
@FLOW 7Y-14
@FLOW 9Y-11
@BOX 1.0
D,E,F,G
@BOX 2.0
READ NON ZERO INT
INTO W
@BOX 3.0
NEXT CHAR
NOT POINT
@BOX 4.0
ACCEPT CH UNSIGNED
READ INT INTO D
@BOX 5.0
W < D
@BOX 6.0
'F' OR 'D'
@BOX 7.0
NEXT CH /= E
@BOX 8.0
ACCEPT CH
READ NON ZERO INT
INTO E
@BOX 9.0
R.C NOT PRESENT
@BOX 10.0
ADD R.C
ENTRY
@BOX 11.0
MAKE 4WD
ENTRY
@BOX 12.0
SEPARATOR
@BOX 13.0
FALSE
@BOX 14.0
SET E = 0
@BOX 1.1
;F.SW:
E.SW:
D.SW:
G.SW:
@BOX 2.1
; FIO.READ.INT(1) => W
@BOX 3.1
;IF LINE^[SS] /= '.
@BOX 4.1
;1 +> SS
; FIO.READ.INT(0) => D
@BOX 5.1
;IF W < D
@BOX 6.1
;IF FD.NO[FD.I] => FD & %100 = 0
@BOX 7.1
;IF LINE^[SS] /= 'E
@BOX 8.1
;1 +> SS
; FIO.READ.INT(1) => E
@BOX 9.1
;IF CNT < 2
@BOX 10.1
;-5 => FMT.TBL^[F.P]
;CNT-1 => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 11.1
;FD & %F => FMT.TBL^[F.P]
;W => FMT.TBL^[F.P+1]
;D => FMT.TBL^[F.P+2]
;E => FMT.TBL^[F.P+3]
; 4 +> F.P
@BOX 12.1
;-> SEPARATOR
@BOX 13.1
;-> FALSE
@BOX 14.1
;0 => E
@END


@TITLE FTN22.1.4(1,6)
@COL 1S-12T-2R-3T-4R-5T-11R-6R-7R-8R
@COL 13C-9R-10R
@ROW 2-13
@FLOW 1-12N-2-3N-4-3
@FLOW 12Y-13
@FLOW 3Y-5Y-6-7-8
@FLOW 5N-11-4
@FLOW 9-10-7
@BOX 1.0
'
@BOX 12.0
IN HOLL?
@BOX 2.0
INITIALISE CHAR
CONSTANT
@BOX 3.0
NEXT CHAR = '
@BOX 4.0
ADD CHAR TO
CONSTANT
@BOX 5.0
FOLLOWING CHAR /= '
@BOX 6.0
MAKE
CHAR CONSTANT
ENTRY
@BOX 7.0
MAKE FD ENTRY
@BOX 8.0
SEPARATOR
@BOX 13.0
FALSE
@BOX 9.0
ITEMISED HOLL
@BOX 10.0
OBTAIN CHAR
CONSTANT PTR
AND CONSTANT LENGTH
@BOX 11.0
GET NEXT CHAR
@BOX 1.1
;PRIME:
@BOX 12.1
; IF HOLL /= 0
@BOX 13.1
; -> FALSE
@BOX 2.1
;0 => CNT
;CHAR.CONST.PTR => C.P
@BOX 3.1
;IF LINE^[1+>SS-1] => CH = ''
@BOX 4.1
;CH => CHAR.CONST.TBL^[CNT+C.P]
; 1+> CNT
@BOX 5.1
;IF LINE^[SS] /= ''
@BOX 6.1
;CNT +> CHAR.CONST.PTR
@BOX 7.1
;0 => FMT.TBL^[F.P]
;CNT => FMT.TBL^[F.P+1]
;C.P => FMT.TBL^[F.P+2]
; 3 +> F.P
@BOX 8.1
;-> SEPARATOR
@BOX 9.1
;I.HOLL:
@BOX 10.1
; 0=> CNT
; WHILE LINE^[1+>SS-1] => C.P /= 0 DO
   C.P => CHAR.CONST.TBL^[CNT+CHAR.CONST.PTR]
   ; 1+> CNT
  OD
;CHAR.CONST.PTR => C.P +CNT => CHAR.CONST.PTR
@BOX 11.1
;1 +> SS
@END


@TITLE FTN22.1.5(1,6)
@COL 1S-2T-3T-4R-5R-6R-7R
@COL 8R-9R-24N
@COL 22R-23T-10T-11R-12R-13R
@COL 14R-15R-26N
@COL 16R-17T-18T-19C-20R-21R
@ROW 8-2-23-14
@ROW 11-15
@ROW 1-22-16
@FLOW 1-2N-3N-4-5-6-7
@FLOW 2Y-8-24-5
@FLOW 3Y-9-24
@FLOW 22-23N-10N-11-12-13
@FLOW 23Y-14-26
@FLOW 16-17N-18N-19
@FLOW 10Y-15-26-12
@FLOW 17Y-21-12
@FLOW 18Y-20-12
@BOX 1.0
T
@BOX 2.0
NEXT CHAR = L
@BOX 3.0
NEXT CHAR = R
@BOX 4.0
NOTE T
@BOX 5.0
READ NON ZERO INT
TO C
@BOX 6.0
MAKE 2WD ENTRY
@BOX 7.0
SEPARATOR
@BOX 8.0
NOTE TL
@BOX 9.0
NOTE TR
@BOX 10.0
NXT CHAR = P
@BOX 11.0
NOTE S
@BOX 12.0
MAKE 2WD ENTRY
@BOX 13.0
SEPARATOR
@BOX 14.0
NOTE SS
@BOX 15.0
NOTE SP
@BOX 16.0
B
@BOX 17.0
NEXT CHAR =N
@BOX 18.0
NEXT CHAR = Z
@BOX 19.0
FALSE
@BOX 20.0
NOTE BZ
@BOX 21.0
NOTE BN
@BOX 22.0
S
@BOX 23.0
NEXT CHAR = S
@BOX 1.1
;T.SW:
@BOX 2.1
;IF LINE^[SS] => CH = 'L
@BOX 3.1
;IF CH = 'R
@BOX 4.1
;-14 => FD
@BOX 5.1
; FIO.READ.INT(1) => C
@BOX 6.1
;FD => FMT.TBL^[F.P]
;C => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 7.1
;-> SEPARATOR
@BOX 8.1
;-13 => FD
;1+>SS
@BOX 9.1
;-12 => FD
;1+>SS
@BOX 22.1
;S.SW:
@BOX 23.1
;IF LINE^[SS] => CH = 'S
@BOX 10.1
;IF CH = 'P
@BOX 11.1
;0 => C
@BOX 12.1
;FD.NO[FD.I] => FMT.TBL^[F.P]
;C => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 13.1
;-> SEPARATOR
@BOX 14.1
;1 +> SS
;0 => C
@BOX 15.1
;1 +> SS
;1 => C
@BOX 16.1
;B.SW:
@BOX 17.1
;IF LINE^[1+>SS-1] => CH = 'N
@BOX 18.1
;IF CH = 'Z
@BOX 19.1
;-> FALSE
@BOX 20.1
;0 => C
@BOX 21.1
;1 => C
@END


@TITLE FTN22.1.6(1,6)
@COL 1S-2R-3T-4R
@COL 5R-6R
@ROW 3-5
@FLOW 1-2-3N-4
@FLOW 3Y-5-4
@FLOW 6-4
@BOX 1.0
/ OR :
@BOX 2.0
ADD 1WD
ENTRY
@BOX 3.0
NEXT CHAR = ,
@BOX 4.0
NEXT ITEM
@BOX 5.0
ACCEPT CH
@BOX 6.0
,
@BOX 1.1
;SLASH:
IF LINE^[SS-1] = 1 THEN
     ; FD.NO[0] => FMT.TBL^[F.P]
     ; 1 +> F.P
FI
;COLON:
@BOX 2.1
;FD.NO[FD.I] => FMT.TBL^[F.P]
; 1 +> F.P
@BOX 3.1
;IF LINE^[SS] = ',
@BOX 4.1
;-> NEXT.ITEM
@BOX 5.1
;1 +> SS
@BOX 6.1
;COMMA:
@END


@TITLE FTN22.1.7(1,6)
@COL 1S-2R-3R
@COL 4R-5T-6R-7R
@COL 8R-10T-9F-11C
@ROW 8-6
@FLOW 1-2-3
@FLOW 4-5N-6-7
@FLOW 5Y-8-10N-9
@FLOW 10Y-11
@BOX 1.0
(
@BOX 2.0
ADD GROUP
ENTRY PTR
UPDATE FMT REPEAT
ADDR IF AN OUTERMOST
GROUP
@BOX 3.0
NEXT
ITEM
@BOX 4.0
)
@BOX 5.0
END OF FORMAT
@BOX 6.0
MAKE END
GROUP ENTRY
@BOX 7.0
SEPARATOR
@BOX 8.0
MAKE END
FORMAT ENTRY
@BOX 9.0
FINISH
@BOX 10.0
IF COMPILE TIME
 CHECK FOR EOL
@BOX 11.0
FALSE
@BOX 1.1
;LEFT:
@BOX 2.1
;-3 => FMT.TBL^[F.P]
;CNT-1 => FMT.TBL^[F.P+1]
;IF GRP.F.P = 0 THEN F.P => FMT.ST FI
; GRP.F.P => FMT.STACK[FMT.NEST]
; 1 +> FMT.NEST
;F.P => GRP.F.P + 2 => F.P
@BOX 3.1
;-> NEXT.ITEM
@BOX 4.1
;RIGHT:
@BOX 5.1
;IF GRP.F.P = 0
@BOX 6.1
;-4 => FMT.TBL^[F.P]
;GRP.F.P => FMT.TBL^[F.P+1]
; 2 +> F.P
; FMT.STACK[1->FMT.NEST] => GRP.F.P
@BOX 7.1
;-> SEPARATOR
@BOX 8.1
;-2 => FMT.TBL^[F.P]
;FMT.ST => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 9.1
; 0 => CHAR.CONST.TBL^[CHAR.CONST.PTR]
;F.P => FIO.FORMAT
EXIT
@BOX 10.1
IF COMP = 1 AND LINE^[SS] /= NL
@BOX 11.1
-> FALSE
@END


@TITLE FTN22.1.8(1,6)
@COL 1S-2R-3R
@COL 4R-8T-5R-6R-7R
@COL 9C
@ROW 5-9
@ROW 1-4
@FLOW 1-2-3
@FLOW 4-8N-5-6-7
@FLOW 8Y-9
@BOX 1.0
nX
@BOX 2.0
MAKE 2WD
ENTRY
@BOX 3.0
SEPARATOR
@BOX 4.0
nH
@BOX 8.0
IN HOLL?
@BOX 9.0
FALSE
@BOX 5.0
COPY n CHARS
TO CHAR CONSTANT
ENTRY
@BOX 6.0
MAKE 3WD FMT
TABLE ENTRY
@BOX 7.0
SEPARATOR
@BOX 1.1
;X.SW:
@BOX 2.1
;-7 => FMT.TBL^[F.P]
;CNT => FMT.TBL^[F.P+1]
; 2 +> F.P
@BOX 3.1
;-> SEPARATOR
@BOX 4.1
;H.SW:
@BOX 8.1
; IF HOLL /= 0
@BOX 9.1
; -> FALSE
@BOX 5.1
;FOR I < CNT
     DO LINE^[1+>SS-1] => CHAR.CONST.TBL^[CHAR.CONST.PTR+I] OD
@BOX 6.1
;0 => FMT.TBL^[F.P]
;CNT => FMT.TBL^[F.P+1]
;CHAR.CONST.PTR => FMT.TBL^[F.P+2] + CNT => CHAR.CONST.PTR
; 3 +> F.P
@BOX 7.1
;-> SEPARATOR
@END


@TITLE FTN22.1.9(1,11)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
SEPARATOR
@BOX 2.0
SWITCH ON CHAR
/ :
) ,
OTHER CHARS
FAULTY
@BOX 1.1
;SEPARATOR:
@BOX 2.1
;WHILE LINE^[SS] = SPACE.L DO 1+> SS OD
;CH.CNTRL1[LINE^[1+>SS-1]] ->> 5 => FD.I
;-> RESELECT
@END


@TITLE FTN22.1.10(1,11)
@COL 1S-2T-3R-4T-5F
@COL 6C
@ROW 6-5
@FLOW 1-2N-3-4N-5
@FLOW 2Y-6
@FLOW 4Y-6
@BOX 1.0
READ.INT
@BOX 2.0
CH NOT A DIGIT OR SPACE?
@BOX 3.0
READ IN ADD
ACC INTEGER
@BOX 4.0
INT NOT IN RANGE ?
@BOX 5.0
END
@BOX 6.0
FALSE
@BOX 1.1
;PROC FIO.READ.INT(MIN.INT)
@BOX 2.1
;IF [LINE^[SS] => CH < '0 OR CH > '9] AND CH /= SPACE.L
@BOX 3.1
;CH - '0 => NO
;WHILE LINE^[1+>SS] => CH >= '0 AND CH =< '9 OR CH = SPACE.L
DO IF CH /= SPACE.L THEN NO * 10 + CH - '0 => NO FI OD
@BOX 4.1
;IF NO < MIN.INT
@BOX 5.1
;NO => FIO.READ.INT
END
@BOX 6.1
; -> G.FALSE
@END



@TITLE FTN22.2(1,11)
@COL 1S-2R-5F
@FLOW 1-2-5
@BOX 1.0
C.FORMAT(SOURCE)
@BOX 2.0
PROCESS FORMAT:2.1:
@BOX 5.0
END
@BOX 1.1
;PROC FIO.C.FORMAT(A,B,C)
@BOX 2.1
; FIO.FORMAT(A,B,C,0,1) => FIO.C.FORMAT
@BOX 5.1
END
@END

