Subversion Repositories Kolibri OS

Rev

Rev 9336 | Rev 9452 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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