Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
8728 leency 1
(*
9902 akron1 2
    Copyright 2021-2023 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 ChangeLog;
21
 
9448 akron1 22
IMPORT List, Lines, API, SYSTEM;
8728 leency 23
 
24
TYPE
25
    tIntItem = POINTER TO RECORD (List.tItem)
9902 akron1 26
    	cnt: INTEGER;
27
    	adr, val: ARRAY 8 OF INTEGER
8728 leency 28
    END;
29
 
30
    tBoolItem = POINTER TO RECORD (List.tItem)
9452 akron1 31
        line: Lines.tLine;
32
        adr: INTEGER;
33
        val, save: BOOLEAN
8728 leency 34
    END;
9448 akron1 35
 
8728 leency 36
    tUntypedPtr = POINTER TO RECORD (List.tItem)
9902 akron1 37
    	cnt: INTEGER;
38
    	p: ARRAY 64 OF INTEGER
8728 leency 39
    END;
40
 
41
    tTypedPtr = POINTER TO RECORD (List.tItem)
9902 akron1 42
    	cnt: INTEGER;
43
    	p: ARRAY 64 OF List.tItem
8728 leency 44
    END;
9448 akron1 45
 
8728 leency 46
    tGuard* = POINTER TO RECORD (List.tItem)
9073 leency 47
        saved*: BOOLEAN
8728 leency 48
    END;
49
 
9050 leency 50
    tLog* = POINTER TO RECORD
9902 akron1 51
        Log*, TPointers, UPointers: List.tList;
9668 akron1 52
        guard, first: tGuard;
9050 leency 53
        isLast: BOOLEAN
54
    END;
8728 leency 55
 
9050 leency 56
 
8728 leency 57
VAR
9050 leency 58
    CL*: tLog;
8728 leency 59
 
60
 
61
PROCEDURE isLastGuard* (guard: tGuard): BOOLEAN;
62
VAR
63
    item: List.tItem;
64
    res: BOOLEAN;
65
BEGIN
66
    IF guard # NIL THEN
9050 leency 67
        item := CL.Log.last;
8728 leency 68
        WHILE ~(item IS tGuard) DO
69
            item := item.prev
70
        END;
71
        res := guard = item
72
    ELSE
73
        res := TRUE
74
    END
75
    RETURN res
76
END isLastGuard;
77
 
78
 
9668 akron1 79
PROCEDURE getFirstGuard (): tGuard;
8728 leency 80
VAR
9668 akron1 81
	item: List.tItem;
8728 leency 82
BEGIN
9668 akron1 83
	item := CL.Log.first;
84
	WHILE ~(item IS tGuard) DO
85
		item := item.next
86
	END
87
	RETURN item(tGuard)
88
END getFirstGuard;
89
 
90
 
91
PROCEDURE isFirstGuard* (guard: tGuard): BOOLEAN;
92
BEGIN
93
	ASSERT(guard # NIL);
94
	IF CL.first = NIL THEN
95
		CL.first := getFirstGuard()
96
	END
97
	RETURN guard = CL.first
8728 leency 98
END isFirstGuard;
99
 
100
 
101
PROCEDURE setGuard* (_guard: tGuard);
102
BEGIN
9050 leency 103
    CL.guard := _guard;
104
    CL.isLast := isLastGuard(_guard)
8728 leency 105
END setGuard;
106
 
107
 
108
PROCEDURE redo* (item: List.tItem);
9902 akron1 109
VAR
110
	i: INTEGER;
8728 leency 111
BEGIN
9902 akron1 112
	IF item IS tIntItem THEN
113
		FOR i := 0 TO item(tIntItem).cnt - 1 DO
114
			SYSTEM.PUT(item(tIntItem).adr[i], item(tIntItem).val[i])
115
		END
116
	ELSIF item IS tBoolItem THEN
117
		SYSTEM.PUT(item(tBoolItem).adr, item(tBoolItem).val)
118
	END
8728 leency 119
END redo;
120
 
121
 
122
PROCEDURE clear (guard: tGuard);
123
VAR
124
    item: List.tItem;
125
BEGIN
9050 leency 126
    CL.isLast := TRUE;
8728 leency 127
    REPEAT
9050 leency 128
        item := List.pop(CL.Log);
8728 leency 129
        IF item # guard THEN
130
            DISPOSE(item)
131
        END
132
    UNTIL item = guard;
9050 leency 133
    List.append(CL.Log, item)
8728 leency 134
END clear;
135
 
136
 
9073 leency 137
PROCEDURE save* (guard: tGuard);
138
VAR
9452 akron1 139
	item: List.tItem;
140
	boolItem: tBoolItem;
141
	cur: List.tItem;
142
	del: BOOLEAN;
9073 leency 143
BEGIN
144
    item := CL.Log.first;
145
    WHILE item # NIL DO
146
        IF item IS tGuard THEN
147
            item(tGuard).saved := FALSE
148
        END;
149
        item := item.next
150
    END;
9452 akron1 151
    guard.saved := TRUE;
152
 
153
    cur := CL.guard.prev;
154
    WHILE cur # NIL DO
155
        IF cur IS tBoolItem THEN
156
            boolItem := cur(tBoolItem);
157
            del := boolItem.save & boolItem.line.modified
158
        ELSE
159
            del := FALSE
160
        END;
161
        cur := cur.prev;
162
        IF del THEN
163
            List.delete(CL.Log, boolItem);
164
            DISPOSE(boolItem)
165
        END
166
    END
9073 leency 167
END save;
168
 
169
 
8728 leency 170
PROCEDURE changeWord (adrV, adrX: INTEGER);
171
VAR
9902 akron1 172
	item: tIntItem;
173
	cur: List.tItem;
8728 leency 174
BEGIN
9902 akron1 175
	IF ~CL.isLast THEN
176
		clear(CL.guard)
177
	END;
178
	cur := CL.Log.last;
179
	WHILE (cur # NIL) & ~(cur IS tGuard) & ~(cur IS tIntItem) DO
180
		cur := cur.prev
181
	END;
182
	IF (cur IS tIntItem) & (cur(tIntItem).cnt < LEN(cur(tIntItem).adr)) THEN
183
		item := cur(tIntItem)
184
	ELSE
185
		NEW(item);
186
		item.cnt := 0;
187
		List.append(CL.Log, item)
188
	END;
189
	item.adr[item.cnt] := adrV;
190
	SYSTEM.GET(adrX, item.val[item.cnt]);
191
	INC(item.cnt)
8728 leency 192
END changeWord;
193
 
194
 
9452 akron1 195
PROCEDURE changeBool (line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN);
8728 leency 196
VAR
197
    item: tBoolItem;
198
BEGIN
199
    NEW(item);
9452 akron1 200
    item.line := line;
8728 leency 201
    item.adr := SYSTEM.ADR(v);
202
    item.val := x;
9073 leency 203
    item.save := FALSE;
9050 leency 204
    IF ~CL.isLast THEN
205
        clear(CL.guard)
8728 leency 206
    END;
9050 leency 207
    List.append(CL.Log, item)
8728 leency 208
END changeBool;
209
 
210
 
9073 leency 211
PROCEDURE delSaved*;
212
VAR
213
    boolItem: tBoolItem;
214
    cur: List.tItem;
215
    del: BOOLEAN;
216
BEGIN
217
    cur := CL.guard.next;
218
    WHILE cur # NIL DO
219
        IF cur IS tBoolItem THEN
220
            boolItem := cur(tBoolItem);
221
            del := boolItem.save
222
        ELSE
223
            del := FALSE
224
        END;
225
        cur := cur.next;
226
        IF del THEN
227
            List.delete(CL.Log, boolItem);
228
            DISPOSE(boolItem)
229
        END
230
    END
231
END delSaved;
232
 
233
 
234
PROCEDURE delCurSaved*;
235
VAR
236
    boolItem: tBoolItem;
237
    cur: List.tItem;
238
    del: BOOLEAN;
239
BEGIN
240
    cur := CL.guard.prev;
241
    WHILE (cur # NIL) & ~(cur IS tGuard) DO
242
        IF cur IS tBoolItem THEN
243
            boolItem := cur(tBoolItem);
244
            del := boolItem.save
245
        ELSE
246
            del := FALSE
247
        END;
248
        cur := cur.prev;
249
        IF del THEN
250
            SYSTEM.PUT(boolItem.adr, ~boolItem.val);
251
            List.delete(CL.Log, boolItem);
252
            DISPOSE(boolItem)
253
        END
254
    END
255
END delCurSaved;
256
 
257
 
9452 akron1 258
PROCEDURE changeBool2 (line: Lines.tLine; VAR v: BOOLEAN; x: BOOLEAN);
9073 leency 259
VAR
9452 akron1 260
    item: tBoolItem;
9073 leency 261
BEGIN
262
    NEW(item);
9452 akron1 263
    item.line := line;
9073 leency 264
    item.adr := SYSTEM.ADR(v);
265
    item.val := x;
266
    item.save := TRUE;
267
    List.insert(CL.Log, CL.guard.prev, item)
268
END changeBool2;
269
 
270
 
9336 akron1 271
PROCEDURE changeInt* (VAR v: INTEGER; x: INTEGER);
8728 leency 272
BEGIN
273
    changeWord(SYSTEM.ADR(v), SYSTEM.ADR(x))
274
END changeInt;
275
 
276
 
277
PROCEDURE changePtr (VAR v: List.tItem; x: List.tItem);
278
BEGIN
279
    changeWord(SYSTEM.ADR(v), SYSTEM.ADR(x))
280
END changePtr;
281
 
9448 akron1 282
 
8728 leency 283
PROCEDURE typedPtr (p: List.tItem);
284
VAR
9902 akron1 285
	item: tTypedPtr;
8728 leency 286
BEGIN
9902 akron1 287
	item := CL.TPointers.last(tTypedPtr);
288
	IF (item = NIL) OR (item.cnt = LEN(item.p)) THEN
289
		NEW(item);
290
		item.cnt := 0;
291
		List.append(CL.TPointers, item)
292
	END;
293
	item.p[item.cnt] := p;
294
	INC(item.cnt)
8728 leency 295
END typedPtr;
296
 
297
 
298
PROCEDURE untypedPtr (p: INTEGER);
299
VAR
9902 akron1 300
	item: tUntypedPtr;
8728 leency 301
BEGIN
9902 akron1 302
	item := CL.UPointers.last(tUntypedPtr);
303
	IF (item = NIL) OR (item.cnt = LEN(item.p)) THEN
304
		NEW(item);
305
		item.cnt := 0;
306
		List.append(CL.UPointers, item)
307
	END;
308
	item.p[item.cnt] := p;
309
	INC(item.cnt)
8728 leency 310
END untypedPtr;
311
 
9448 akron1 312
 
9902 akron1 313
PROCEDURE setLog* (_CL: tLog);
8728 leency 314
BEGIN
9050 leency 315
    CL := _CL
9902 akron1 316
END setLog;
9050 leency 317
 
318
 
319
PROCEDURE create* (VAR maxLength: INTEGER): tLog;
320
VAR
321
    newLog: tLog;
322
BEGIN
323
    NEW(newLog);
324
    newLog.guard := NIL;
9668 akron1 325
    newLog.first := NIL;
9050 leency 326
    newLog.isLast := TRUE;
327
    newLog.Log := List.create(NIL);
9902 akron1 328
    newLog.TPointers := List.create(NIL);
329
    newLog.UPointers := List.create(NIL);
9050 leency 330
    CL := newLog;
331
    Lines.setMaxLength(maxLength)
332
    RETURN newLog
333
END create;
334
 
335
 
9448 akron1 336
PROCEDURE destroy* (VAR log: tLog);
337
VAR
338
	item: List.tItem;
9902 akron1 339
	res, i: INTEGER;
9050 leency 340
BEGIN
9448 akron1 341
	IF log # NIL THEN
342
		item := List.pop(log.Log);
343
		WHILE item # NIL DO
344
			DISPOSE(item);
345
			item := List.pop(log.Log)
346
		END;
347
		DISPOSE(log.Log);
348
 
9902 akron1 349
		item := List.pop(log.TPointers);
9448 akron1 350
		WHILE item # NIL DO
9902 akron1 351
			FOR i := 0 TO item(tTypedPtr).cnt - 1 DO
352
				DISPOSE(item(tTypedPtr).p[i])
353
			END;
9448 akron1 354
			DISPOSE(item);
9902 akron1 355
			item := List.pop(log.TPointers)
9448 akron1 356
		END;
9902 akron1 357
		DISPOSE(log.TPointers);
9448 akron1 358
 
9902 akron1 359
		item := List.pop(log.UPointers);
360
		WHILE item # NIL DO
361
			FOR i := 0 TO item(tUntypedPtr).cnt - 1 DO
362
				res := API._DISPOSE(item(tUntypedPtr).p[i])
363
			END;
364
			DISPOSE(item);
365
			item := List.pop(log.UPointers)
366
		END;
367
		DISPOSE(log.UPointers);
368
 
9448 akron1 369
		DISPOSE(log)
370
	END
371
END destroy;
372
 
373
 
374
BEGIN
8728 leency 375
    List.init(changeInt, changePtr);
9448 akron1 376
    Lines.init(changeInt, changePtr, changeBool, changeBool2, typedPtr, untypedPtr)
8728 leency 377
END ChangeLog.