Subversion Repositories Kolibri OS

Rev

Rev 9448 | Rev 9522 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
2
    Copyright 2021 Anton Krotov
3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE Lines;
21
 
22
IMPORT
23
    List, SYSTEM, API, Utils;
24
 
25
CONST
26
    WCHAR_SIZE = 2;
9174 akron1 27
    SPACE* = 20X;
28
    TAB* = 9X;
29
    TAB1* = 0FFFEX;
8728 leency 30
 
31
TYPE
32
 
33
    tLine* = POINTER TO RECORD (List.tItem)
34
        ptr: INTEGER;
35
        length*: INTEGER;
9060 leency 36
        modified*, saved*, temp, label*: BOOLEAN;
8728 leency 37
        cin*, cout*, pos*: INTEGER
38
    END;
39
 
40
    PmovInt = PROCEDURE (VAR v: INTEGER; x: INTEGER);
9452 akron1 41
    PmovBool = PROCEDURE (line: tLine; VAR v: BOOLEAN; x: BOOLEAN);
8728 leency 42
    PmovPtr = PROCEDURE (VAR v: List.tItem; x: List.tItem);
9448 akron1 43
 
8728 leency 44
    PTypedPtr = PROCEDURE (p: List.tItem);
45
    PUntypedPtr = PROCEDURE (p: INTEGER);
46
 
9448 akron1 47
 
8728 leency 48
VAR
49
 
50
    _movInt: PmovInt;
9073 leency 51
    _movBool, _movBool2: PmovBool;
8728 leency 52
    _movPtr: PmovPtr;
9448 akron1 53
    _typedPtr: PTypedPtr;
54
    _untypedPtr: PUntypedPtr;
8728 leency 55
 
9174 akron1 56
    pMaxLength, tab*: INTEGER;
57
    tabs*: BOOLEAN;
8728 leency 58
 
59
 
60
PROCEDURE movInt (VAR v: INTEGER; x: INTEGER);
61
BEGIN
62
    _movInt(v, x)
63
END movInt;
64
 
65
 
9452 akron1 66
PROCEDURE movBool (line: tLine; VAR v: BOOLEAN; x: BOOLEAN);
8728 leency 67
BEGIN
9452 akron1 68
    _movBool(line, v, x)
8728 leency 69
END movBool;
70
 
71
 
9452 akron1 72
PROCEDURE movBool2 (line: tLine; VAR v: BOOLEAN; x: BOOLEAN);
9073 leency 73
BEGIN
9452 akron1 74
    _movBool2(line, v, x)
9073 leency 75
END movBool2;
76
 
77
 
8728 leency 78
PROCEDURE movPtr (VAR v: List.tItem; x: List.tItem);
79
BEGIN
80
    _movPtr(v, x)
81
END movPtr;
82
 
83
 
84
PROCEDURE malloc (size: INTEGER): INTEGER;
85
VAR
9050 leency 86
    maxLength: INTEGER;
8728 leency 87
BEGIN
9050 leency 88
    ASSERT(pMaxLength # 0);
89
    SYSTEM.GET(pMaxLength, maxLength);
8728 leency 90
    IF size > maxLength THEN
9050 leency 91
        SYSTEM.PUT(pMaxLength, size)
8728 leency 92
    END;
93
    size := size*WCHAR_SIZE + 4;
9448 akron1 94
    INC(size, (-size) MOD 32)
95
    RETURN API._NEW(size)
8728 leency 96
END malloc;
97
 
98
 
99
PROCEDURE free (line: tLine; newPtr: INTEGER);
100
BEGIN
101
    IF line.ptr # 0 THEN
102
        IF line.temp THEN
103
            line.ptr := API._DISPOSE(line.ptr)
104
        ELSE
105
            line.ptr := 0
106
        END
107
    END;
108
    IF ~line.temp THEN
109
        movInt(line.ptr, newPtr);
9448 akron1 110
        IF newPtr # 0 THEN
8728 leency 111
            _untypedPtr(newPtr)
9448 akron1 112
        END
8728 leency 113
    END;
114
    line.ptr := newPtr
115
END free;
116
 
117
 
118
PROCEDURE create* (temp: BOOLEAN): tLine;
119
VAR
120
    line: tLine;
121
BEGIN
122
    NEW(line);
9060 leency 123
    line.label := FALSE;
8728 leency 124
    ASSERT(line # NIL);
9448 akron1 125
    IF ~temp THEN
8728 leency 126
        _typedPtr(line)
9448 akron1 127
    END;
8728 leency 128
    line.next := NIL;
129
    line.prev := NIL;
130
    IF ~temp THEN
131
        movPtr(line.next, NIL);
132
        movPtr(line.prev, NIL)
133
    END;
134
    line.ptr := malloc(1);
135
    ASSERT(line.ptr # 0);
136
    IF ~temp THEN
9448 akron1 137
        _untypedPtr(line.ptr);
8728 leency 138
        movInt(line.ptr, line.ptr)
139
    END;
140
    SYSTEM.PUT16(line.ptr, 0);
141
    line.length := 0;
142
    IF ~temp THEN
143
        movInt(line.length, 0)
144
    END;
145
    line.temp := temp;
146
    line.modified := FALSE;
147
    line.saved := FALSE;
148
    IF ~temp THEN
9452 akron1 149
        movBool(line, line.modified, FALSE);
150
        movBool(line, line.saved, FALSE)
8728 leency 151
    END;
152
    line.cin := 0;
153
    line.cout := 0;
154
    line.pos := 0
155
    RETURN line
156
END create;
157
 
158
 
159
PROCEDURE destroy* (VAR line: tLine);
160
BEGIN
161
    IF line.temp THEN
162
        free(line, 0);
163
        DISPOSE(line)
164
    ELSE
165
        line := NIL
166
    END
167
END destroy;
168
 
169
 
9174 akron1 170
PROCEDURE getChar* (line: tLine; i: INTEGER): WCHAR;
171
VAR
172
    c: WCHAR;
8728 leency 173
BEGIN
9174 akron1 174
    SYSTEM.GET(line.ptr + i*WCHAR_SIZE, c)
175
    RETURN c
176
END getChar;
8728 leency 177
 
178
 
9174 akron1 179
PROCEDURE tabWidth (line: tLine; pos: INTEGER): INTEGER;
180
VAR
181
    n: INTEGER;
182
BEGIN
183
    n := pos;
184
    IF getChar(line, pos) = TAB THEN
185
        INC(pos);
186
        WHILE getChar(line, pos) = TAB1 DO
187
            INC(pos)
188
        END
189
    END
190
    RETURN pos - n
191
END tabWidth;
192
 
193
 
8728 leency 194
PROCEDURE save* (line: tLine);
195
BEGIN
196
    IF ~line.temp THEN
9452 akron1 197
        movBool2(line, line.saved, TRUE);
198
        movBool2(line, line.modified, FALSE)
8728 leency 199
    END;
200
    line.modified := FALSE;
201
    line.saved := TRUE
202
END save;
203
 
204
 
9174 akron1 205
PROCEDURE isSpace* (c: WCHAR): BOOLEAN;
206
    RETURN (c = SPACE) OR (c = TAB) OR (c = TAB1)
207
END isSpace;
8728 leency 208
 
209
 
210
PROCEDURE trimLength* (line: tLine): INTEGER;
211
VAR
212
    i: INTEGER;
213
BEGIN
214
    i := line.length - 1;
9174 akron1 215
    WHILE (i >= 0) & isSpace(getChar(line, i)) DO
8728 leency 216
        DEC(i)
217
    END
218
    RETURN i + 1
219
END trimLength;
220
 
221
 
222
PROCEDURE getPChar* (line: tLine; i: INTEGER): INTEGER;
223
    RETURN line.ptr + i*WCHAR_SIZE
224
END getPChar;
225
 
226
 
227
PROCEDURE setChar* (line: tLine; i: INTEGER; c: WCHAR);
228
BEGIN
229
    SYSTEM.PUT(line.ptr + i*WCHAR_SIZE, c)
230
END setChar;
231
 
232
 
9010 leency 233
PROCEDURE move* (src, dst: tLine);
234
BEGIN
235
    SYSTEM.MOVE(src.ptr, dst.ptr, (MIN(src.length, dst.length) + 1)*WCHAR_SIZE)
236
END move;
237
 
238
 
8728 leency 239
PROCEDURE concat* (line: tLine; s: ARRAY OF WCHAR);
240
VAR
241
    Len: INTEGER;
242
    ptr: INTEGER;
243
BEGIN
244
    Len := LENGTH(s);
245
    ptr := malloc(line.length + Len + 1);
246
    ASSERT(ptr # 0);
247
    SYSTEM.MOVE(line.ptr, ptr, line.length*WCHAR_SIZE);
248
    SYSTEM.MOVE(SYSTEM.ADR(s[0]), ptr + line.length*WCHAR_SIZE, Len*WCHAR_SIZE);
249
    SYSTEM.PUT16(ptr + (line.length + Len)*WCHAR_SIZE, 0);
250
    IF ~line.temp THEN
251
        movInt(line.length, line.length + Len)
252
    END;
253
    INC(line.length, Len);
254
    free(line, ptr)
255
END concat;
256
 
257
 
258
PROCEDURE delChar* (line: tLine; pos: INTEGER);
259
VAR
260
    ptr: INTEGER;
261
BEGIN
262
    IF pos < line.length THEN
263
        ptr := malloc(line.length);
264
        ASSERT(ptr # 0);
265
        IF ~line.temp THEN
266
            movInt(line.length, line.length - 1)
267
        END;
268
        DEC(line.length);
269
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
270
        SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE + WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
271
        SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
272
        free(line, ptr)
273
    END
274
END delChar;
275
 
276
 
277
PROCEDURE insert* (line: tLine; pos: INTEGER; c: WCHAR);
278
VAR
279
    ptr: INTEGER;
280
BEGIN
281
    ptr := malloc(line.length + 2);
282
    ASSERT(ptr # 0);
283
    SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
284
    SYSTEM.PUT(ptr + pos*WCHAR_SIZE, c);
285
    SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + pos*WCHAR_SIZE + WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
286
    IF ~line.temp THEN
287
        movInt(line.length, line.length + 1)
288
    END;
289
    INC(line.length);
290
    SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
291
    free(line, ptr)
292
END insert;
293
 
294
 
295
PROCEDURE insert2* (line1: tLine; pos: INTEGER; line2: tLine);
296
VAR
297
    ptr: INTEGER;
298
BEGIN
299
    IF line2.length > 0 THEN
300
        ptr := malloc(line1.length + line2.length + 1);
301
        ASSERT(ptr # 0);
302
        SYSTEM.MOVE(line1.ptr, ptr, pos*WCHAR_SIZE);
303
        SYSTEM.MOVE(line2.ptr, ptr + pos*WCHAR_SIZE, line2.length*WCHAR_SIZE);
304
        SYSTEM.MOVE(line1.ptr + pos*WCHAR_SIZE, ptr + (pos + line2.length)*WCHAR_SIZE, (line1.length - pos)*WCHAR_SIZE);
305
        SYSTEM.PUT16(ptr + (line1.length + line2.length)*WCHAR_SIZE, 0);
306
        IF ~line1.temp THEN
307
            movInt(line1.length, line1.length + line2.length)
308
        END;
309
        IF ~line2.temp THEN
310
            movInt(line2.length, 0)
311
        END;
312
        INC(line1.length, line2.length);
313
        line2.length := 0;
314
        free(line1, ptr);
315
        free(line2, 0)
316
    END
317
END insert2;
318
 
319
 
320
PROCEDURE insert3* (line: tLine; pos, n: INTEGER);
321
VAR
322
    ptr: INTEGER;
323
BEGIN
324
    IF n > 0 THEN
325
        ptr := malloc(line.length + n + 1);
326
        ASSERT(ptr # 0);
327
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
328
        SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + (pos + n)*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
329
        SYSTEM.PUT16(ptr + (line.length + n)*WCHAR_SIZE, 0);
330
        IF ~line.temp THEN
331
            movInt(line.length, line.length + n)
332
        END;
333
        INC(line.length, n);
334
        free(line, ptr)
335
    END
336
END insert3;
337
 
338
 
339
PROCEDURE delCharN* (line: tLine; pos, n: INTEGER);
340
VAR
341
    ptr: INTEGER;
342
BEGIN
343
    IF n > 0 THEN
344
        ptr := malloc(line.length - n + 1);
345
        ASSERT(ptr # 0);
346
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
347
        SYSTEM.MOVE(line.ptr + (pos + n)*WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos - n)*WCHAR_SIZE);
348
        SYSTEM.PUT16(ptr + (line.length - n)*WCHAR_SIZE, 0);
349
        IF ~line.temp THEN
350
            movInt(line.length, line.length - n)
351
        END;
352
        DEC(line.length, n);
353
        free(line, ptr)
354
    END
355
END delCharN;
356
 
357
 
9174 akron1 358
PROCEDURE fixTabs (line: tLine);
359
VAR
360
    i, n, k: INTEGER;
361
BEGIN
362
    i := 0;
363
    WHILE i < line.length DO
364
        n := tabWidth(line, i);
365
        IF n # 0 THEN
366
            k := tab - i MOD tab;
367
            IF n > k THEN
368
                delCharN(line, i + 1, n - k)
369
            ELSIF n < k THEN
370
                DEC(k, n);
371
                insert3(line, i + 1, k);
372
                WHILE k > 0 DO
373
                    setChar(line, i + 1, TAB1);
374
                    INC(i);
375
                    DEC(k)
376
                END
377
            END
378
        END;
379
        INC(i)
380
    END
381
END fixTabs;
382
 
383
 
384
PROCEDURE modify* (line: tLine);
385
BEGIN
386
    IF ~line.temp THEN
9452 akron1 387
        movBool(line, line.modified, TRUE);
388
        movBool(line, line.saved, FALSE)
9174 akron1 389
    END;
390
    line.modified := TRUE;
391
    line.saved := FALSE;
392
    fixTabs(line)
393
END modify;
394
 
395
 
8728 leency 396
PROCEDURE wrap* (line, nextLine: tLine; pos: INTEGER);
397
VAR
398
    ptr1, ptr2: INTEGER;
399
    n: INTEGER;
400
BEGIN
401
    ptr1 := malloc(pos + 1);
402
    ASSERT(ptr1 # 0);
403
    n := line.length - pos;
404
    ptr2 := malloc(n + 1);
405
    ASSERT(ptr2 # 0);
406
    SYSTEM.MOVE(line.ptr, ptr1, pos*WCHAR_SIZE);
407
    SYSTEM.PUT16(ptr1 + pos*WCHAR_SIZE, 0);
408
    SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr2, n*WCHAR_SIZE);
409
    SYSTEM.PUT16(ptr2 + n*WCHAR_SIZE, 0);
410
    IF ~line.temp THEN
411
        movInt(line.length, pos)
412
    END;
413
    IF ~nextLine.temp THEN
414
        movInt(nextLine.length, n)
415
    END;
416
    line.length := pos;
417
    nextLine.length := n;
418
    free(line, ptr1);
419
    free(nextLine, ptr2)
420
END wrap;
421
 
422
 
423
PROCEDURE copy* (line: tLine);
424
VAR
425
    ptr: INTEGER;
426
BEGIN
427
    ptr := malloc(line.length + 1);
428
    ASSERT(ptr # 0);
429
    SYSTEM.MOVE(line.ptr, ptr, line.length*WCHAR_SIZE);
430
    SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
431
    free(line, ptr)
432
END copy;
433
 
434
 
435
PROCEDURE chCase* (line: tLine; pos1, pos2: INTEGER; upper: BOOLEAN): BOOLEAN;
436
VAR
437
    i: INTEGER;
438
    modified: BOOLEAN;
439
    c: WCHAR;
440
    func: PROCEDURE (VAR c: WCHAR): BOOLEAN;
441
BEGIN
442
    modified := FALSE;
443
    IF upper THEN
444
        func := Utils.cap
445
    ELSE
446
        func := Utils.low
447
    END;
448
    i := pos2;
449
    WHILE i >= pos1 DO
450
        c := getChar(line, i);
451
        IF func(c) THEN
452
            modified := TRUE
453
        END;
454
        DEC(i)
455
    END;
456
 
457
    IF modified THEN
458
        copy(line);
459
        i := pos2;
460
        WHILE i >= pos1 DO
461
            c := getChar(line, i);
462
            IF func(c) THEN
463
                setChar(line, i, c)
464
            END;
465
            DEC(i)
466
        END;
467
        modify(line)
468
    END
469
    RETURN modified
470
END chCase;
471
 
472
 
9448 akron1 473
PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr; movBool, movBool2: PmovBool; typedPtr: PTypedPtr; untypedPtr: PUntypedPtr);
8728 leency 474
BEGIN
475
    _movInt := movInt;
476
    _movPtr := movPtr;
477
    _movBool := movBool;
9073 leency 478
    _movBool2 := movBool2;
9448 akron1 479
    _typedPtr := typedPtr;
480
    _untypedPtr := untypedPtr;
8728 leency 481
END init;
482
 
483
 
9050 leency 484
PROCEDURE setMaxLength* (VAR maxLength: INTEGER);
8728 leency 485
BEGIN
9050 leency 486
    pMaxLength := SYSTEM.ADR(maxLength)
487
END setMaxLength;
488
 
489
 
9174 akron1 490
PROCEDURE setTabs* (_tab: INTEGER);
9050 leency 491
BEGIN
9174 akron1 492
    IF _tab = 0 THEN
493
        _tab := 4
494
    END;
495
    tabs := _tab > 0;
496
    tab := ABS(_tab)
497
END setTabs;
498
 
499
 
500
BEGIN
9050 leency 501
    pMaxLength := 0
8728 leency 502
END Lines.