Subversion Repositories Kolibri OS

Rev

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

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