Subversion Repositories Kolibri OS

Rev

Rev 9073 | Rev 9448 | 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 Lines;
  21.  
  22. IMPORT
  23.     List, SYSTEM, API, Utils;
  24.  
  25. CONST
  26.     WCHAR_SIZE = 2;
  27.     SPACE* = 20X;
  28.     TAB* = 9X;
  29.     TAB1* = 0FFFEX;
  30.  
  31. TYPE
  32.  
  33.     tLine* = POINTER TO RECORD (List.tItem)
  34.         ptr: INTEGER;
  35.         length*: INTEGER;
  36.         modified*, saved*, temp, label*: BOOLEAN;
  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;
  51.     _movBool, _movBool2: PmovBool;
  52.     _movPtr: PmovPtr;
  53. (*    _typedPtr: PTypedPtr;
  54.     _untypedPtr: PUntypedPtr;*)
  55.  
  56.     pMaxLength, tab*: INTEGER;
  57.     tabs*: BOOLEAN;
  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.  
  72. PROCEDURE movBool2 (VAR v: BOOLEAN; x: BOOLEAN);
  73. BEGIN
  74.     _movBool2(v, x)
  75. END movBool2;
  76.  
  77.  
  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;
  87.     maxLength: INTEGER;
  88. BEGIN
  89.     ASSERT(pMaxLength # 0);
  90.     SYSTEM.GET(pMaxLength, maxLength);
  91.     IF size > maxLength THEN
  92.         SYSTEM.PUT(pMaxLength, size)
  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);
  125.     line.label := FALSE;
  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.  
  172. PROCEDURE getChar* (line: tLine; i: INTEGER): WCHAR;
  173. VAR
  174.     c: WCHAR;
  175. BEGIN
  176.     SYSTEM.GET(line.ptr + i*WCHAR_SIZE, c)
  177.     RETURN c
  178. END getChar;
  179.  
  180.  
  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.  
  196. PROCEDURE save* (line: tLine);
  197. BEGIN
  198.     IF ~line.temp THEN
  199.         movBool2(line.saved, TRUE);
  200.         movBool2(line.modified, FALSE)
  201.     END;
  202.     line.modified := FALSE;
  203.     line.saved := TRUE
  204. END save;
  205.  
  206.  
  207. PROCEDURE isSpace* (c: WCHAR): BOOLEAN;
  208.     RETURN (c = SPACE) OR (c = TAB) OR (c = TAB1)
  209. END isSpace;
  210.  
  211.  
  212. PROCEDURE trimLength* (line: tLine): INTEGER;
  213. VAR
  214.     i: INTEGER;
  215. BEGIN
  216.     i := line.length - 1;
  217.     WHILE (i >= 0) & isSpace(getChar(line, i)) DO
  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.  
  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.  
  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.  
  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.  
  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.  
  475. PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr; movBool, movBool2: PmovBool(*; typedPtr: PTypedPtr; untypedPtr: PUntypedPtr*));
  476. BEGIN
  477.     _movInt := movInt;
  478.     _movPtr := movPtr;
  479.     _movBool := movBool;
  480.     _movBool2 := movBool2;
  481. (*    _typedPtr := typedPtr;
  482.     _untypedPtr := untypedPtr;*)
  483. END init;
  484.  
  485.  
  486. PROCEDURE setMaxLength* (VAR maxLength: INTEGER);
  487. BEGIN
  488.     pMaxLength := SYSTEM.ADR(maxLength)
  489. END setMaxLength;
  490.  
  491.  
  492. PROCEDURE setTabs* (_tab: INTEGER);
  493. BEGIN
  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
  503.     pMaxLength := 0
  504. END Lines.