Subversion Repositories Kolibri OS

Rev

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