Rev 7696 | 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 | |||
7696 | akron1 | 4 | Copyright (c) 2018-2019, 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; |
||
31 | eof*: BOOLEAN; |
||
32 | eol*: BOOLEAN; |
||
7693 | akron1 | 33 | peak*: CHAR |
7597 | akron1 | 34 | |
35 | END; |
||
36 | |||
37 | |||
38 | VAR |
||
39 | |||
40 | texts: C.COLLECTION; |
||
41 | |||
42 | |||
43 | PROCEDURE load (text: TEXT); |
||
44 | BEGIN |
||
45 | IF ~text.eof THEN |
||
46 | text.size := FILES.read(text.file, text.chunk, LEN(text.chunk)); |
||
47 | text.pos := 0; |
||
48 | IF text.size = 0 THEN |
||
49 | text.eof := TRUE; |
||
7696 | akron1 | 50 | text.chunk[0] := 0X |
7693 | akron1 | 51 | END; |
7696 | akron1 | 52 | text.peak := text.chunk[0] |
7597 | akron1 | 53 | END |
54 | END load; |
||
55 | |||
56 | |||
7693 | akron1 | 57 | PROCEDURE next* (text: TEXT); |
7597 | akron1 | 58 | VAR |
59 | c: CHAR; |
||
7693 | akron1 | 60 | |
7597 | akron1 | 61 | BEGIN |
62 | IF text.pos < text.size - 1 THEN |
||
7693 | akron1 | 63 | INC(text.pos); |
7696 | akron1 | 64 | text.peak := text.chunk[text.pos] |
7597 | akron1 | 65 | ELSE |
66 | load(text) |
||
67 | END; |
||
68 | |||
69 | IF ~text.eof THEN |
||
70 | |||
7693 | akron1 | 71 | c := text.peak; |
7597 | akron1 | 72 | |
73 | IF c = CR THEN |
||
74 | INC(text.line); |
||
7693 | akron1 | 75 | text.col := 0; |
76 | text.eol := TRUE; |
||
77 | text.CR := TRUE |
||
7597 | akron1 | 78 | ELSIF c = LF THEN |
79 | IF ~text.CR THEN |
||
80 | INC(text.line); |
||
7693 | akron1 | 81 | text.col := 0; |
82 | text.eol := TRUE |
||
7597 | akron1 | 83 | ELSE |
7693 | akron1 | 84 | text.eol := FALSE |
7597 | akron1 | 85 | END; |
86 | text.CR := FALSE |
||
87 | ELSE |
||
88 | text.eol := FALSE; |
||
89 | IF text.utf8 THEN |
||
7696 | akron1 | 90 | IF ORD(c) DIV 64 # 2 THEN |
7597 | akron1 | 91 | INC(text.col) |
92 | END |
||
93 | ELSE |
||
94 | INC(text.col) |
||
95 | END; |
||
96 | text.CR := FALSE |
||
97 | END |
||
98 | |||
99 | END |
||
100 | |||
101 | END next; |
||
102 | |||
103 | |||
104 | PROCEDURE init (text: TEXT); |
||
105 | BEGIN |
||
106 | IF (text.pos = 0) & (text.size >= 3) THEN |
||
7696 | akron1 | 107 | IF (text.chunk[0] = 0EFX) & |
108 | (text.chunk[1] = 0BBX) & |
||
109 | (text.chunk[2] = 0BFX) THEN |
||
7597 | akron1 | 110 | text.pos := 3; |
111 | text.utf8 := TRUE |
||
112 | END |
||
113 | END; |
||
114 | |||
115 | IF text.size = 0 THEN |
||
7696 | akron1 | 116 | text.chunk[0] := 0X; |
7597 | akron1 | 117 | text.size := 1; |
118 | text.eof := FALSE |
||
119 | END; |
||
120 | |||
121 | text.line := 1; |
||
7693 | akron1 | 122 | text.col := 1; |
7597 | akron1 | 123 | |
7696 | akron1 | 124 | text.peak := text.chunk[text.pos] |
7597 | akron1 | 125 | END init; |
126 | |||
127 | |||
7693 | akron1 | 128 | PROCEDURE close* (VAR text: TEXT); |
7597 | akron1 | 129 | BEGIN |
7693 | akron1 | 130 | IF text # NIL THEN |
131 | IF text.file # NIL THEN |
||
132 | FILES.close(text.file) |
||
133 | END; |
||
7597 | akron1 | 134 | |
7693 | akron1 | 135 | C.push(texts, text); |
136 | text := NIL |
||
7597 | akron1 | 137 | END |
7693 | akron1 | 138 | END close; |
7597 | akron1 | 139 | |
140 | |||
7693 | akron1 | 141 | PROCEDURE open* (name: ARRAY OF CHAR): TEXT; |
7597 | akron1 | 142 | VAR |
7693 | akron1 | 143 | text: TEXT; |
7597 | akron1 | 144 | citem: C.ITEM; |
145 | |||
146 | BEGIN |
||
147 | citem := C.pop(texts); |
||
148 | IF citem = NIL THEN |
||
149 | NEW(text) |
||
150 | ELSE |
||
151 | text := citem(TEXT) |
||
7693 | akron1 | 152 | END; |
7597 | akron1 | 153 | |
154 | IF text # NIL THEN |
||
7696 | akron1 | 155 | text.chunk[0] := 0X; |
7693 | akron1 | 156 | text.pos := 0; |
157 | text.size := 0; |
||
158 | text.utf8 := FALSE; |
||
159 | text.CR := FALSE; |
||
160 | text.line := 1; |
||
161 | text.col := 1; |
||
162 | text.eof := FALSE; |
||
163 | text.eol := FALSE; |
||
164 | text.peak := 0X; |
||
165 | text.file := FILES.open(name); |
||
7597 | akron1 | 166 | IF text.file # NIL THEN |
7693 | akron1 | 167 | load(text); |
168 | init(text) |
||
169 | ELSE |
||
170 | close(text) |
||
171 | END |
||
7597 | akron1 | 172 | END |
173 | |||
7693 | akron1 | 174 | RETURN text |
175 | END open; |
||
7597 | akron1 | 176 | |
7693 | akron1 | 177 | |
7597 | akron1 | 178 | BEGIN |
179 | texts := C.create() |
||
7983 | leency | 180 | END TEXTDRV.> |