Subversion Repositories Kolibri OS

Rev

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

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