Subversion Repositories Kolibri OS

Rev

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