Subversion Repositories Kolibri OS

Rev

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