Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
8728 leency 1
(*
9904 akron1 2
    Copyright 2021-2023 Anton Krotov
8728 leency 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;
9560 akron1 29
    NUL* = 0FDD0X;
30
    TAB1* = 0FDD1X;
8728 leency 31
 
32
TYPE
33
 
34
    tLine* = POINTER TO RECORD (List.tItem)
35
        ptr: INTEGER;
36
        length*: INTEGER;
9060 leency 37
        modified*, saved*, temp, label*: BOOLEAN;
8728 leency 38
        cin*, cout*, pos*: INTEGER
39
    END;
40
 
41
    PmovInt = PROCEDURE (VAR v: INTEGER; x: INTEGER);
9904 akron1 42
    PmovBool = PROCEDURE (save: BOOLEAN; VAR v1: BOOLEAN; x1: BOOLEAN; VAR v2: BOOLEAN; x2: BOOLEAN);
8728 leency 43
    PmovPtr = PROCEDURE (VAR v: List.tItem; x: List.tItem);
9448 akron1 44
 
8728 leency 45
    PTypedPtr = PROCEDURE (p: List.tItem);
46
    PUntypedPtr = PROCEDURE (p: INTEGER);
47
 
9668 akron1 48
    tVector* = POINTER TO RECORD
49
    	size, data: INTEGER
50
    END;
9448 akron1 51
 
9668 akron1 52
    tVectorItem = tLine;
53
 
9674 akron1 54
    fConvert* = PROCEDURE (VAR c: WCHAR): BOOLEAN;
9668 akron1 55
 
9674 akron1 56
 
8728 leency 57
VAR
58
 
59
    _movInt: PmovInt;
9904 akron1 60
    _movBool: PmovBool;
8728 leency 61
    _movPtr: PmovPtr;
9448 akron1 62
    _typedPtr: PTypedPtr;
63
    _untypedPtr: PUntypedPtr;
8728 leency 64
 
9174 akron1 65
    pMaxLength, tab*: INTEGER;
66
    tabs*: BOOLEAN;
8728 leency 67
 
68
 
9668 akron1 69
PROCEDURE createVector* (size: INTEGER): tVector;
70
VAR
71
	res: tVector;
72
BEGIN
73
	IF size > 0 THEN
74
		NEW(res);
75
		res.size := size;
76
		IF size < 4096 THEN
77
			size := 4096
78
		END;
79
		res.data := API._NEW(size*SYSTEM.SIZE(tVectorItem));
80
		IF res.data = 0 THEN
81
			DISPOSE(res)
82
		END
83
	ELSE
84
		res := NIL
85
	END
86
	RETURN res
87
END createVector;
88
 
89
 
90
PROCEDURE destroyVector* (VAR vector: tVector);
91
BEGIN
92
	IF vector # NIL THEN
93
		IF vector.data # 0 THEN
94
			vector.data := API._DISPOSE(vector.data)
95
		END;
96
		DISPOSE(vector)
97
	END
98
END destroyVector;
99
 
100
 
101
PROCEDURE setVectorItem* (vector: tVector; idx: INTEGER; item: tVectorItem);
102
BEGIN
103
	ASSERT(vector # NIL);
104
	ASSERT((0 <= idx) & (idx < vector.size));
105
	SYSTEM.PUT(vector.data + idx*SYSTEM.SIZE(tVectorItem), item)
106
END setVectorItem;
107
 
108
 
109
PROCEDURE getVectorItem* (vector: tVector; idx: INTEGER): tVectorItem;
110
VAR
111
	res: tVectorItem;
112
BEGIN
113
	ASSERT(vector # NIL);
114
	ASSERT((0 <= idx) & (idx < vector.size));
115
	SYSTEM.GET(vector.data + idx*SYSTEM.SIZE(tVectorItem), res)
116
	RETURN res
117
END getVectorItem;
118
 
119
 
8728 leency 120
PROCEDURE movInt (VAR v: INTEGER; x: INTEGER);
121
BEGIN
122
    _movInt(v, x)
123
END movInt;
124
 
125
 
126
PROCEDURE movPtr (VAR v: List.tItem; x: List.tItem);
127
BEGIN
128
    _movPtr(v, x)
129
END movPtr;
130
 
131
 
132
PROCEDURE malloc (size: INTEGER): INTEGER;
133
VAR
9050 leency 134
    maxLength: INTEGER;
8728 leency 135
BEGIN
9050 leency 136
    ASSERT(pMaxLength # 0);
137
    SYSTEM.GET(pMaxLength, maxLength);
8728 leency 138
    IF size > maxLength THEN
9050 leency 139
        SYSTEM.PUT(pMaxLength, size)
8728 leency 140
    END;
141
    size := size*WCHAR_SIZE + 4;
9448 akron1 142
    INC(size, (-size) MOD 32)
143
    RETURN API._NEW(size)
8728 leency 144
END malloc;
145
 
146
 
147
PROCEDURE free (line: tLine; newPtr: INTEGER);
148
BEGIN
149
    IF line.ptr # 0 THEN
150
        IF line.temp THEN
151
            line.ptr := API._DISPOSE(line.ptr)
152
        ELSE
153
            line.ptr := 0
154
        END
155
    END;
156
    IF ~line.temp THEN
157
        movInt(line.ptr, newPtr);
9448 akron1 158
        IF newPtr # 0 THEN
8728 leency 159
            _untypedPtr(newPtr)
9448 akron1 160
        END
8728 leency 161
    END;
162
    line.ptr := newPtr
163
END free;
164
 
165
 
166
PROCEDURE create* (temp: BOOLEAN): tLine;
167
VAR
168
    line: tLine;
169
BEGIN
170
    NEW(line);
9060 leency 171
    line.label := FALSE;
8728 leency 172
    ASSERT(line # NIL);
9448 akron1 173
    IF ~temp THEN
8728 leency 174
        _typedPtr(line)
9448 akron1 175
    END;
8728 leency 176
    line.next := NIL;
177
    line.prev := NIL;
178
    IF ~temp THEN
179
        movPtr(line.next, NIL);
180
        movPtr(line.prev, NIL)
181
    END;
182
    line.ptr := malloc(1);
183
    ASSERT(line.ptr # 0);
184
    IF ~temp THEN
9448 akron1 185
        _untypedPtr(line.ptr);
8728 leency 186
        movInt(line.ptr, line.ptr)
187
    END;
188
    SYSTEM.PUT16(line.ptr, 0);
189
    line.length := 0;
190
    IF ~temp THEN
191
        movInt(line.length, 0)
192
    END;
193
    line.temp := temp;
194
    line.modified := FALSE;
195
    line.saved := FALSE;
196
    IF ~temp THEN
9904 akron1 197
        _movBool(FALSE, line.modified, FALSE, line.saved, FALSE)
8728 leency 198
    END;
199
    line.cin := 0;
200
    line.cout := 0;
201
    line.pos := 0
202
    RETURN line
203
END create;
204
 
205
 
206
PROCEDURE destroy* (VAR line: tLine);
207
BEGIN
208
    IF line.temp THEN
209
        free(line, 0);
210
        DISPOSE(line)
211
    ELSE
212
        line := NIL
213
    END
214
END destroy;
215
 
216
 
9522 akron1 217
PROCEDURE resize* (line: tLine; size: INTEGER);
218
BEGIN
219
	ASSERT(line.temp);
220
	IF size > 0 THEN
221
		line.ptr := API._DISPOSE(line.ptr);
9668 akron1 222
		size := size*WCHAR_SIZE + 4;
223
		INC(size, (-size) MOD 32);
9522 akron1 224
		line.ptr := API._NEW(size)
225
	ELSE
226
		destroy(line)
227
	END
228
END resize;
229
 
230
 
9174 akron1 231
PROCEDURE getChar* (line: tLine; i: INTEGER): WCHAR;
232
VAR
9659 akron1 233
    res: WCHAR;
8728 leency 234
BEGIN
9659 akron1 235
    IF i >= line.length THEN
236
        res := 0X
237
    ELSE
238
    	SYSTEM.GET(line.ptr + i*WCHAR_SIZE, res)
239
    END
240
    RETURN res
9174 akron1 241
END getChar;
8728 leency 242
 
243
 
9174 akron1 244
PROCEDURE tabWidth (line: tLine; pos: INTEGER): INTEGER;
245
VAR
246
    n: INTEGER;
247
BEGIN
248
    n := pos;
249
    IF getChar(line, pos) = TAB THEN
250
        INC(pos);
251
        WHILE getChar(line, pos) = TAB1 DO
252
            INC(pos)
253
        END
254
    END
255
    RETURN pos - n
256
END tabWidth;
257
 
258
 
8728 leency 259
PROCEDURE save* (line: tLine);
260
BEGIN
261
    IF ~line.temp THEN
9904 akron1 262
    	_movBool(TRUE, line.modified, FALSE, line.saved, TRUE)
8728 leency 263
    END;
264
    line.modified := FALSE;
265
    line.saved := TRUE
266
END save;
267
 
268
 
9174 akron1 269
PROCEDURE isSpace* (c: WCHAR): BOOLEAN;
270
    RETURN (c = SPACE) OR (c = TAB) OR (c = TAB1)
271
END isSpace;
8728 leency 272
 
273
 
274
PROCEDURE trimLength* (line: tLine): INTEGER;
275
VAR
276
    i: INTEGER;
277
BEGIN
278
    i := line.length - 1;
9174 akron1 279
    WHILE (i >= 0) & isSpace(getChar(line, i)) DO
8728 leency 280
        DEC(i)
281
    END
282
    RETURN i + 1
283
END trimLength;
284
 
285
 
286
PROCEDURE getPChar* (line: tLine; i: INTEGER): INTEGER;
287
    RETURN line.ptr + i*WCHAR_SIZE
288
END getPChar;
289
 
290
 
291
PROCEDURE setChar* (line: tLine; i: INTEGER; c: WCHAR);
292
BEGIN
293
    SYSTEM.PUT(line.ptr + i*WCHAR_SIZE, c)
294
END setChar;
295
 
296
 
9010 leency 297
PROCEDURE move* (src, dst: tLine);
298
BEGIN
299
    SYSTEM.MOVE(src.ptr, dst.ptr, (MIN(src.length, dst.length) + 1)*WCHAR_SIZE)
300
END move;
301
 
302
 
8728 leency 303
PROCEDURE delChar* (line: tLine; pos: INTEGER);
304
VAR
305
    ptr: INTEGER;
306
BEGIN
307
    IF pos < line.length THEN
308
        ptr := malloc(line.length);
309
        ASSERT(ptr # 0);
310
        IF ~line.temp THEN
311
            movInt(line.length, line.length - 1)
312
        END;
313
        DEC(line.length);
314
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
315
        SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE + WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
316
        SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
317
        free(line, ptr)
318
    END
319
END delChar;
320
 
321
 
322
PROCEDURE insert* (line: tLine; pos: INTEGER; c: WCHAR);
323
VAR
324
    ptr: INTEGER;
325
BEGIN
326
    ptr := malloc(line.length + 2);
327
    ASSERT(ptr # 0);
328
    SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
329
    SYSTEM.PUT(ptr + pos*WCHAR_SIZE, c);
330
    SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + pos*WCHAR_SIZE + WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
331
    IF ~line.temp THEN
332
        movInt(line.length, line.length + 1)
333
    END;
334
    INC(line.length);
335
    SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
336
    free(line, ptr)
337
END insert;
338
 
339
 
9522 akron1 340
PROCEDURE _insert2* (line1: tLine; pos: INTEGER; line2: tLine);
8728 leency 341
VAR
342
    ptr: INTEGER;
343
BEGIN
344
    IF line2.length > 0 THEN
345
        ptr := malloc(line1.length + line2.length + 1);
346
        ASSERT(ptr # 0);
347
        SYSTEM.MOVE(line1.ptr, ptr, pos*WCHAR_SIZE);
348
        SYSTEM.MOVE(line2.ptr, ptr + pos*WCHAR_SIZE, line2.length*WCHAR_SIZE);
349
        SYSTEM.MOVE(line1.ptr + pos*WCHAR_SIZE, ptr + (pos + line2.length)*WCHAR_SIZE, (line1.length - pos)*WCHAR_SIZE);
350
        SYSTEM.PUT16(ptr + (line1.length + line2.length)*WCHAR_SIZE, 0);
351
        IF ~line1.temp THEN
352
            movInt(line1.length, line1.length + line2.length)
353
        END;
354
        IF ~line2.temp THEN
355
            movInt(line2.length, 0)
356
        END;
357
        INC(line1.length, line2.length);
9522 akron1 358
        free(line1, ptr)
8728 leency 359
    END
9522 akron1 360
END _insert2;
361
 
362
 
363
PROCEDURE insert2* (line1: tLine; pos: INTEGER; line2: tLine);
364
BEGIN
365
	_insert2(line1, pos, line2);
366
	IF line2.length > 0 THEN
367
		line2.length := 0;
368
		free(line2, 0)
369
	END
8728 leency 370
END insert2;
371
 
372
 
373
PROCEDURE insert3* (line: tLine; pos, n: INTEGER);
374
VAR
375
    ptr: INTEGER;
376
BEGIN
377
    IF n > 0 THEN
378
        ptr := malloc(line.length + n + 1);
379
        ASSERT(ptr # 0);
380
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
381
        SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + (pos + n)*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
382
        SYSTEM.PUT16(ptr + (line.length + n)*WCHAR_SIZE, 0);
383
        IF ~line.temp THEN
384
            movInt(line.length, line.length + n)
385
        END;
386
        INC(line.length, n);
387
        free(line, ptr)
388
    END
389
END insert3;
390
 
391
 
392
PROCEDURE delCharN* (line: tLine; pos, n: INTEGER);
393
VAR
394
    ptr: INTEGER;
395
BEGIN
396
    IF n > 0 THEN
397
        ptr := malloc(line.length - n + 1);
398
        ASSERT(ptr # 0);
399
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
400
        SYSTEM.MOVE(line.ptr + (pos + n)*WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos - n)*WCHAR_SIZE);
401
        SYSTEM.PUT16(ptr + (line.length - n)*WCHAR_SIZE, 0);
402
        IF ~line.temp THEN
403
            movInt(line.length, line.length - n)
404
        END;
405
        DEC(line.length, n);
406
        free(line, ptr)
407
    END
408
END delCharN;
409
 
410
 
9174 akron1 411
PROCEDURE fixTabs (line: tLine);
412
VAR
413
    i, n, k: INTEGER;
414
BEGIN
415
    i := 0;
416
    WHILE i < line.length DO
417
        n := tabWidth(line, i);
418
        IF n # 0 THEN
419
            k := tab - i MOD tab;
420
            IF n > k THEN
421
                delCharN(line, i + 1, n - k)
422
            ELSIF n < k THEN
423
                DEC(k, n);
424
                insert3(line, i + 1, k);
425
                WHILE k > 0 DO
426
                    setChar(line, i + 1, TAB1);
427
                    INC(i);
428
                    DEC(k)
429
                END
430
            END
431
        END;
432
        INC(i)
433
    END
434
END fixTabs;
435
 
436
 
437
PROCEDURE modify* (line: tLine);
438
BEGIN
439
    IF ~line.temp THEN
9904 akron1 440
        _movBool(FALSE, line.modified, TRUE, line.saved, FALSE)
9174 akron1 441
    END;
442
    line.modified := TRUE;
443
    line.saved := FALSE;
444
    fixTabs(line)
445
END modify;
446
 
447
 
8728 leency 448
PROCEDURE wrap* (line, nextLine: tLine; pos: INTEGER);
449
VAR
450
    ptr1, ptr2: INTEGER;
451
    n: INTEGER;
452
BEGIN
453
    ptr1 := malloc(pos + 1);
454
    ASSERT(ptr1 # 0);
455
    n := line.length - pos;
456
    ptr2 := malloc(n + 1);
457
    ASSERT(ptr2 # 0);
458
    SYSTEM.MOVE(line.ptr, ptr1, pos*WCHAR_SIZE);
459
    SYSTEM.PUT16(ptr1 + pos*WCHAR_SIZE, 0);
460
    SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr2, n*WCHAR_SIZE);
461
    SYSTEM.PUT16(ptr2 + n*WCHAR_SIZE, 0);
462
    IF ~line.temp THEN
463
        movInt(line.length, pos)
464
    END;
465
    IF ~nextLine.temp THEN
466
        movInt(nextLine.length, n)
467
    END;
468
    line.length := pos;
469
    nextLine.length := n;
470
    free(line, ptr1);
471
    free(nextLine, ptr2)
472
END wrap;
473
 
474
 
475
PROCEDURE copy* (line: tLine);
476
VAR
477
    ptr: INTEGER;
478
BEGIN
479
    ptr := malloc(line.length + 1);
480
    ASSERT(ptr # 0);
481
    SYSTEM.MOVE(line.ptr, ptr, line.length*WCHAR_SIZE);
482
    SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
483
    free(line, ptr)
484
END copy;
485
 
486
 
9674 akron1 487
PROCEDURE convert* (line: tLine; pos1, pos2: INTEGER; func: fConvert): BOOLEAN;
8728 leency 488
VAR
489
    i: INTEGER;
490
    modified: BOOLEAN;
491
    c: WCHAR;
492
BEGIN
9674 akron1 493
	ASSERT(func # NIL);
8728 leency 494
    modified := FALSE;
495
    i := pos2;
496
    WHILE i >= pos1 DO
497
        c := getChar(line, i);
498
        IF func(c) THEN
499
            modified := TRUE
500
        END;
501
        DEC(i)
502
    END;
503
 
504
    IF modified THEN
505
        copy(line);
506
        i := pos2;
507
        WHILE i >= pos1 DO
508
            c := getChar(line, i);
509
            IF func(c) THEN
510
                setChar(line, i, c)
511
            END;
512
            DEC(i)
513
        END;
514
        modify(line)
515
    END
516
    RETURN modified
9674 akron1 517
END convert;
8728 leency 518
 
519
 
9904 akron1 520
PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr; movBool: PmovBool; typedPtr: PTypedPtr; untypedPtr: PUntypedPtr);
8728 leency 521
BEGIN
522
    _movInt := movInt;
523
    _movPtr := movPtr;
524
    _movBool := movBool;
9448 akron1 525
    _typedPtr := typedPtr;
526
    _untypedPtr := untypedPtr;
8728 leency 527
END init;
528
 
529
 
9050 leency 530
PROCEDURE setMaxLength* (VAR maxLength: INTEGER);
8728 leency 531
BEGIN
9050 leency 532
    pMaxLength := SYSTEM.ADR(maxLength)
533
END setMaxLength;
534
 
535
 
9174 akron1 536
PROCEDURE setTabs* (_tab: INTEGER);
9050 leency 537
BEGIN
9174 akron1 538
    IF _tab = 0 THEN
539
        _tab := 4
540
    END;
541
    tabs := _tab > 0;
9599 akron1 542
    tab := ABS(_tab);
543
    IF tab > 32 THEN
544
    	tab := 32
545
    END
9174 akron1 546
END setTabs;
547
 
548
 
549
BEGIN
9050 leency 550
    pMaxLength := 0
8728 leency 551
END Lines.