Rev 7983 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7983 | leency | 1 | (* |
7597 | akron1 | 2 | BSD 2-Clause License |
3 | |||
8097 | maxcodehac | 4 | Copyright (c) 2018-2020, Anton Krotov |
7597 | akron1 | 5 | All rights reserved. |
6 | *) |
||
7 | |||
8 | MODULE TEXTDRV; |
||
9 | |||
10 | IMPORT FILES, C := COLLECTIONS; |
||
11 | |||
12 | |||
13 | CONST |
||
14 | |||
15 | CR = 0DX; LF = 0AX; |
||
16 | |||
17 | CHUNK = 1024 * 256; |
||
18 | |||
19 | |||
20 | TYPE |
||
21 | |||
22 | TEXT* = POINTER TO RECORD (C.ITEM) |
||
23 | |||
7696 | akron1 | 24 | chunk: ARRAY CHUNK OF CHAR; |
7597 | akron1 | 25 | pos, size: INTEGER; |
26 | file: FILES.FILE; |
||
27 | utf8: BOOLEAN; |
||
28 | CR: BOOLEAN; |
||
29 | |||
30 | line*, col*: INTEGER; |
||
8097 | maxcodehac | 31 | ifc*: INTEGER; |
32 | elsec*: INTEGER; |
||
7597 | akron1 | 33 | eof*: BOOLEAN; |
34 | eol*: BOOLEAN; |
||
8097 | maxcodehac | 35 | skip*: BOOLEAN; |
36 | peak*: CHAR; |
||
37 | _skip*, |
||
38 | _elsif*, |
||
39 | _else*: ARRAY 100 OF BOOLEAN; |
||
40 | fname*: ARRAY 2048 OF CHAR |
||
7597 | akron1 | 41 | |
42 | END; |
||
43 | |||
44 | |||
45 | VAR |
||
46 | |||
47 | texts: C.COLLECTION; |
||
48 | |||
49 | |||
50 | PROCEDURE load (text: TEXT); |
||
51 | BEGIN |
||
52 | IF ~text.eof THEN |
||
53 | text.size := FILES.read(text.file, text.chunk, LEN(text.chunk)); |
||
54 | text.pos := 0; |
||
55 | IF text.size = 0 THEN |
||
56 | text.eof := TRUE; |
||
7696 | akron1 | 57 | text.chunk[0] := 0X |
7693 | akron1 | 58 | END; |
7696 | akron1 | 59 | text.peak := text.chunk[0] |
7597 | akron1 | 60 | END |
61 | END load; |
||
62 | |||
63 | |||
7693 | akron1 | 64 | PROCEDURE next* (text: TEXT); |
7597 | akron1 | 65 | VAR |
66 | c: CHAR; |
||
7693 | akron1 | 67 | |
7597 | akron1 | 68 | BEGIN |
69 | IF text.pos < text.size - 1 THEN |
||
7693 | akron1 | 70 | INC(text.pos); |
7696 | akron1 | 71 | text.peak := text.chunk[text.pos] |
7597 | akron1 | 72 | ELSE |
73 | load(text) |
||
74 | END; |
||
75 | |||
76 | IF ~text.eof THEN |
||
77 | |||
7693 | akron1 | 78 | c := text.peak; |
7597 | akron1 | 79 | |
80 | IF c = CR THEN |
||
81 | INC(text.line); |
||
7693 | akron1 | 82 | text.col := 0; |
83 | text.eol := TRUE; |
||
84 | text.CR := TRUE |
||
7597 | akron1 | 85 | ELSIF c = LF THEN |
86 | IF ~text.CR THEN |
||
87 | INC(text.line); |
||
7693 | akron1 | 88 | text.col := 0; |
89 | text.eol := TRUE |
||
7597 | akron1 | 90 | ELSE |
7693 | akron1 | 91 | text.eol := FALSE |
7597 | akron1 | 92 | END; |
93 | text.CR := FALSE |
||
94 | ELSE |
||
95 | text.eol := FALSE; |
||
96 | IF text.utf8 THEN |
||
7696 | akron1 | 97 | IF ORD(c) DIV 64 # 2 THEN |
7597 | akron1 | 98 | INC(text.col) |
99 | END |
||
100 | ELSE |
||
101 | INC(text.col) |
||
102 | END; |
||
103 | text.CR := FALSE |
||
104 | END |
||
105 | |||
106 | END |
||
107 | |||
108 | END next; |
||
109 | |||
110 | |||
111 | PROCEDURE init (text: TEXT); |
||
112 | BEGIN |
||
113 | IF (text.pos = 0) & (text.size >= 3) THEN |
||
7696 | akron1 | 114 | IF (text.chunk[0] = 0EFX) & |
115 | (text.chunk[1] = 0BBX) & |
||
116 | (text.chunk[2] = 0BFX) THEN |
||
7597 | akron1 | 117 | text.pos := 3; |
118 | text.utf8 := TRUE |
||
119 | END |
||
120 | END; |
||
121 | |||
122 | IF text.size = 0 THEN |
||
7696 | akron1 | 123 | text.chunk[0] := 0X; |
7597 | akron1 | 124 | text.size := 1; |
125 | text.eof := FALSE |
||
126 | END; |
||
127 | |||
128 | text.line := 1; |
||
7693 | akron1 | 129 | text.col := 1; |
7597 | akron1 | 130 | |
7696 | akron1 | 131 | text.peak := text.chunk[text.pos] |
7597 | akron1 | 132 | END init; |
133 | |||
134 | |||
7693 | akron1 | 135 | PROCEDURE close* (VAR text: TEXT); |
7597 | akron1 | 136 | BEGIN |
7693 | akron1 | 137 | IF text # NIL THEN |
138 | IF text.file # NIL THEN |
||
139 | FILES.close(text.file) |
||
140 | END; |
||
7597 | akron1 | 141 | |
7693 | akron1 | 142 | C.push(texts, text); |
143 | text := NIL |
||
7597 | akron1 | 144 | END |
7693 | akron1 | 145 | END close; |
7597 | akron1 | 146 | |
147 | |||
7693 | akron1 | 148 | PROCEDURE open* (name: ARRAY OF CHAR): TEXT; |
7597 | akron1 | 149 | VAR |
7693 | akron1 | 150 | text: TEXT; |
7597 | akron1 | 151 | citem: C.ITEM; |
152 | |||
153 | BEGIN |
||
154 | citem := C.pop(texts); |
||
155 | IF citem = NIL THEN |
||
156 | NEW(text) |
||
157 | ELSE |
||
158 | text := citem(TEXT) |
||
7693 | akron1 | 159 | END; |
7597 | akron1 | 160 | |
161 | IF text # NIL THEN |
||
7696 | akron1 | 162 | text.chunk[0] := 0X; |
7693 | akron1 | 163 | text.pos := 0; |
164 | text.size := 0; |
||
165 | text.utf8 := FALSE; |
||
166 | text.CR := FALSE; |
||
167 | text.line := 1; |
||
168 | text.col := 1; |
||
169 | text.eof := FALSE; |
||
170 | text.eol := FALSE; |
||
8097 | maxcodehac | 171 | text.skip := FALSE; |
172 | text.ifc := 0; |
||
173 | text.elsec := 0; |
||
174 | text._skip[0] := FALSE; |
||
7693 | akron1 | 175 | text.peak := 0X; |
176 | text.file := FILES.open(name); |
||
8097 | maxcodehac | 177 | COPY(name, text.fname); |
7597 | akron1 | 178 | IF text.file # NIL THEN |
7693 | akron1 | 179 | load(text); |
180 | init(text) |
||
181 | ELSE |
||
182 | close(text) |
||
183 | END |
||
7597 | akron1 | 184 | END |
185 | |||
7693 | akron1 | 186 | RETURN text |
187 | END open; |
||
7597 | akron1 | 188 | |
7693 | akron1 | 189 | |
7597 | akron1 | 190 | BEGIN |
191 | texts := C.create() |
||
7983 | leency | 192 | END TEXTDRV.> |