Subversion Repositories Kolibri OS

Rev

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.