Subversion Repositories Kolibri OS

Rev

Rev 9599 | Rev 9668 | 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
9659 akron1 187
    res: WCHAR;
8728 leency 188
BEGIN
9659 akron1 189
    IF i >= line.length THEN
190
        res := 0X
191
    ELSE
192
    	SYSTEM.GET(line.ptr + i*WCHAR_SIZE, res)
193
    END
194
    RETURN res
9174 akron1 195
END getChar;
8728 leency 196
 
197
 
9174 akron1 198
PROCEDURE tabWidth (line: tLine; pos: INTEGER): INTEGER;
199
VAR
200
    n: INTEGER;
201
BEGIN
202
    n := pos;
203
    IF getChar(line, pos) = TAB THEN
204
        INC(pos);
205
        WHILE getChar(line, pos) = TAB1 DO
206
            INC(pos)
207
        END
208
    END
209
    RETURN pos - n
210
END tabWidth;
211
 
212
 
8728 leency 213
PROCEDURE save* (line: tLine);
214
BEGIN
215
    IF ~line.temp THEN
9452 akron1 216
        movBool2(line, line.saved, TRUE);
217
        movBool2(line, line.modified, FALSE)
8728 leency 218
    END;
219
    line.modified := FALSE;
220
    line.saved := TRUE
221
END save;
222
 
223
 
9174 akron1 224
PROCEDURE isSpace* (c: WCHAR): BOOLEAN;
225
    RETURN (c = SPACE) OR (c = TAB) OR (c = TAB1)
226
END isSpace;
8728 leency 227
 
228
 
229
PROCEDURE trimLength* (line: tLine): INTEGER;
230
VAR
231
    i: INTEGER;
232
BEGIN
233
    i := line.length - 1;
9174 akron1 234
    WHILE (i >= 0) & isSpace(getChar(line, i)) DO
8728 leency 235
        DEC(i)
236
    END
237
    RETURN i + 1
238
END trimLength;
239
 
240
 
241
PROCEDURE getPChar* (line: tLine; i: INTEGER): INTEGER;
242
    RETURN line.ptr + i*WCHAR_SIZE
243
END getPChar;
244
 
245
 
246
PROCEDURE setChar* (line: tLine; i: INTEGER; c: WCHAR);
247
BEGIN
248
    SYSTEM.PUT(line.ptr + i*WCHAR_SIZE, c)
249
END setChar;
250
 
251
 
9010 leency 252
PROCEDURE move* (src, dst: tLine);
253
BEGIN
254
    SYSTEM.MOVE(src.ptr, dst.ptr, (MIN(src.length, dst.length) + 1)*WCHAR_SIZE)
255
END move;
256
 
257
 
8728 leency 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
 
9522 akron1 295
PROCEDURE _insert2* (line1: tLine; pos: INTEGER; line2: tLine);
8728 leency 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);
9522 akron1 313
        free(line1, ptr)
8728 leency 314
    END
9522 akron1 315
END _insert2;
316
 
317
 
318
PROCEDURE insert2* (line1: tLine; pos: INTEGER; line2: tLine);
319
BEGIN
320
	_insert2(line1, pos, line2);
321
	IF line2.length > 0 THEN
322
		line2.length := 0;
323
		free(line2, 0)
324
	END
8728 leency 325
END insert2;
326
 
327
 
328
PROCEDURE insert3* (line: tLine; pos, n: INTEGER);
329
VAR
330
    ptr: INTEGER;
331
BEGIN
332
    IF n > 0 THEN
333
        ptr := malloc(line.length + n + 1);
334
        ASSERT(ptr # 0);
335
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
336
        SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + (pos + n)*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
337
        SYSTEM.PUT16(ptr + (line.length + n)*WCHAR_SIZE, 0);
338
        IF ~line.temp THEN
339
            movInt(line.length, line.length + n)
340
        END;
341
        INC(line.length, n);
342
        free(line, ptr)
343
    END
344
END insert3;
345
 
346
 
347
PROCEDURE delCharN* (line: tLine; pos, n: INTEGER);
348
VAR
349
    ptr: INTEGER;
350
BEGIN
351
    IF n > 0 THEN
352
        ptr := malloc(line.length - n + 1);
353
        ASSERT(ptr # 0);
354
        SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
355
        SYSTEM.MOVE(line.ptr + (pos + n)*WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos - n)*WCHAR_SIZE);
356
        SYSTEM.PUT16(ptr + (line.length - n)*WCHAR_SIZE, 0);
357
        IF ~line.temp THEN
358
            movInt(line.length, line.length - n)
359
        END;
360
        DEC(line.length, n);
361
        free(line, ptr)
362
    END
363
END delCharN;
364
 
365
 
9174 akron1 366
PROCEDURE fixTabs (line: tLine);
367
VAR
368
    i, n, k: INTEGER;
369
BEGIN
370
    i := 0;
371
    WHILE i < line.length DO
372
        n := tabWidth(line, i);
373
        IF n # 0 THEN
374
            k := tab - i MOD tab;
375
            IF n > k THEN
376
                delCharN(line, i + 1, n - k)
377
            ELSIF n < k THEN
378
                DEC(k, n);
379
                insert3(line, i + 1, k);
380
                WHILE k > 0 DO
381
                    setChar(line, i + 1, TAB1);
382
                    INC(i);
383
                    DEC(k)
384
                END
385
            END
386
        END;
387
        INC(i)
388
    END
389
END fixTabs;
390
 
391
 
392
PROCEDURE modify* (line: tLine);
393
BEGIN
394
    IF ~line.temp THEN
9452 akron1 395
        movBool(line, line.modified, TRUE);
396
        movBool(line, line.saved, FALSE)
9174 akron1 397
    END;
398
    line.modified := TRUE;
399
    line.saved := FALSE;
400
    fixTabs(line)
401
END modify;
402
 
403
 
8728 leency 404
PROCEDURE wrap* (line, nextLine: tLine; pos: INTEGER);
405
VAR
406
    ptr1, ptr2: INTEGER;
407
    n: INTEGER;
408
BEGIN
409
    ptr1 := malloc(pos + 1);
410
    ASSERT(ptr1 # 0);
411
    n := line.length - pos;
412
    ptr2 := malloc(n + 1);
413
    ASSERT(ptr2 # 0);
414
    SYSTEM.MOVE(line.ptr, ptr1, pos*WCHAR_SIZE);
415
    SYSTEM.PUT16(ptr1 + pos*WCHAR_SIZE, 0);
416
    SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr2, n*WCHAR_SIZE);
417
    SYSTEM.PUT16(ptr2 + n*WCHAR_SIZE, 0);
418
    IF ~line.temp THEN
419
        movInt(line.length, pos)
420
    END;
421
    IF ~nextLine.temp THEN
422
        movInt(nextLine.length, n)
423
    END;
424
    line.length := pos;
425
    nextLine.length := n;
426
    free(line, ptr1);
427
    free(nextLine, ptr2)
428
END wrap;
429
 
430
 
431
PROCEDURE copy* (line: tLine);
432
VAR
433
    ptr: INTEGER;
434
BEGIN
435
    ptr := malloc(line.length + 1);
436
    ASSERT(ptr # 0);
437
    SYSTEM.MOVE(line.ptr, ptr, line.length*WCHAR_SIZE);
438
    SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
439
    free(line, ptr)
440
END copy;
441
 
442
 
443
PROCEDURE chCase* (line: tLine; pos1, pos2: INTEGER; upper: BOOLEAN): BOOLEAN;
444
VAR
445
    i: INTEGER;
446
    modified: BOOLEAN;
447
    c: WCHAR;
448
    func: PROCEDURE (VAR c: WCHAR): BOOLEAN;
449
BEGIN
450
    modified := FALSE;
451
    IF upper THEN
452
        func := Utils.cap
453
    ELSE
454
        func := Utils.low
455
    END;
456
    i := pos2;
457
    WHILE i >= pos1 DO
458
        c := getChar(line, i);
459
        IF func(c) THEN
460
            modified := TRUE
461
        END;
462
        DEC(i)
463
    END;
464
 
465
    IF modified THEN
466
        copy(line);
467
        i := pos2;
468
        WHILE i >= pos1 DO
469
            c := getChar(line, i);
470
            IF func(c) THEN
471
                setChar(line, i, c)
472
            END;
473
            DEC(i)
474
        END;
475
        modify(line)
476
    END
477
    RETURN modified
478
END chCase;
479
 
480
 
9448 akron1 481
PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr; movBool, movBool2: PmovBool; typedPtr: PTypedPtr; untypedPtr: PUntypedPtr);
8728 leency 482
BEGIN
483
    _movInt := movInt;
484
    _movPtr := movPtr;
485
    _movBool := movBool;
9073 leency 486
    _movBool2 := movBool2;
9448 akron1 487
    _typedPtr := typedPtr;
488
    _untypedPtr := untypedPtr;
8728 leency 489
END init;
490
 
491
 
9050 leency 492
PROCEDURE setMaxLength* (VAR maxLength: INTEGER);
8728 leency 493
BEGIN
9050 leency 494
    pMaxLength := SYSTEM.ADR(maxLength)
495
END setMaxLength;
496
 
497
 
9174 akron1 498
PROCEDURE setTabs* (_tab: INTEGER);
9050 leency 499
BEGIN
9174 akron1 500
    IF _tab = 0 THEN
501
        _tab := 4
502
    END;
503
    tabs := _tab > 0;
9599 akron1 504
    tab := ABS(_tab);
505
    IF tab > 32 THEN
506
    	tab := 32
507
    END
9174 akron1 508
END setTabs;
509
 
510
 
511
BEGIN
9050 leency 512
    pMaxLength := 0
8728 leency 513
END Lines.