Subversion Repositories Kolibri OS

Rev

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