Subversion Repositories Kolibri OS

Rev

Rev 9599 | Rev 9668 | 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 Lines;
  21.  
  22. IMPORT
  23.     List, SYSTEM, API, Utils;
  24.  
  25. CONST
  26.     WCHAR_SIZE = 2;
  27.     SPACE* = 20X;
  28.     TAB* = 9X;
  29.     NUL* = 0FDD0X;
  30.     TAB1* = 0FDD1X;
  31.  
  32. TYPE
  33.  
  34.     tLine* = POINTER TO RECORD (List.tItem)
  35.         ptr: INTEGER;
  36.         length*: INTEGER;
  37.         modified*, saved*, temp, label*: BOOLEAN;
  38.         cin*, cout*, pos*: INTEGER
  39.     END;
  40.  
  41.     PmovInt = PROCEDURE (VAR v: INTEGER; x: INTEGER);
  42.     PmovBool = PROCEDURE (line: tLine; VAR v: BOOLEAN; x: BOOLEAN);
  43.     PmovPtr = PROCEDURE (VAR v: List.tItem; x: List.tItem);
  44.  
  45.     PTypedPtr = PROCEDURE (p: List.tItem);
  46.     PUntypedPtr = PROCEDURE (p: INTEGER);
  47.  
  48.  
  49. VAR
  50.  
  51.     _movInt: PmovInt;
  52.     _movBool, _movBool2: PmovBool;
  53.     _movPtr: PmovPtr;
  54.     _typedPtr: PTypedPtr;
  55.     _untypedPtr: PUntypedPtr;
  56.  
  57.     pMaxLength, tab*: INTEGER;
  58.     tabs*: BOOLEAN;
  59.  
  60.  
  61. PROCEDURE movInt (VAR v: INTEGER; x: INTEGER);
  62. BEGIN
  63.     _movInt(v, x)
  64. END movInt;
  65.  
  66.  
  67. PROCEDURE movBool (line: tLine; VAR v: BOOLEAN; x: BOOLEAN);
  68. BEGIN
  69.     _movBool(line, v, x)
  70. END movBool;
  71.  
  72.  
  73. PROCEDURE movBool2 (line: tLine; VAR v: BOOLEAN; x: BOOLEAN);
  74. BEGIN
  75.     _movBool2(line, v, x)
  76. END movBool2;
  77.  
  78.  
  79. PROCEDURE movPtr (VAR v: List.tItem; x: List.tItem);
  80. BEGIN
  81.     _movPtr(v, x)
  82. END movPtr;
  83.  
  84.  
  85. PROCEDURE malloc (size: INTEGER): INTEGER;
  86. VAR
  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.     RETURN API._NEW(size)
  97. END malloc;
  98.  
  99.  
  100. PROCEDURE free (line: tLine; newPtr: INTEGER);
  101. BEGIN
  102.     IF line.ptr # 0 THEN
  103.         IF line.temp THEN
  104.             line.ptr := API._DISPOSE(line.ptr)
  105.         ELSE
  106.             line.ptr := 0
  107.         END
  108.     END;
  109.     IF ~line.temp THEN
  110.         movInt(line.ptr, newPtr);
  111.         IF newPtr # 0 THEN
  112.             _untypedPtr(newPtr)
  113.         END
  114.     END;
  115.     line.ptr := newPtr
  116. END free;
  117.  
  118.  
  119. PROCEDURE create* (temp: BOOLEAN): tLine;
  120. VAR
  121.     line: tLine;
  122. BEGIN
  123.     NEW(line);
  124.     line.label := FALSE;
  125.     ASSERT(line # NIL);
  126.     IF ~temp THEN
  127.         _typedPtr(line)
  128.     END;
  129.     line.next := NIL;
  130.     line.prev := NIL;
  131.     IF ~temp THEN
  132.         movPtr(line.next, NIL);
  133.         movPtr(line.prev, NIL)
  134.     END;
  135.     line.ptr := malloc(1);
  136.     ASSERT(line.ptr # 0);
  137.     IF ~temp THEN
  138.         _untypedPtr(line.ptr);
  139.         movInt(line.ptr, line.ptr)
  140.     END;
  141.     SYSTEM.PUT16(line.ptr, 0);
  142.     line.length := 0;
  143.     IF ~temp THEN
  144.         movInt(line.length, 0)
  145.     END;
  146.     line.temp := temp;
  147.     line.modified := FALSE;
  148.     line.saved := FALSE;
  149.     IF ~temp THEN
  150.         movBool(line, line.modified, FALSE);
  151.         movBool(line, line.saved, FALSE)
  152.     END;
  153.     line.cin := 0;
  154.     line.cout := 0;
  155.     line.pos := 0
  156.     RETURN line
  157. END create;
  158.  
  159.  
  160. PROCEDURE destroy* (VAR line: tLine);
  161. BEGIN
  162.     IF line.temp THEN
  163.         free(line, 0);
  164.         DISPOSE(line)
  165.     ELSE
  166.         line := NIL
  167.     END
  168. END destroy;
  169.  
  170.  
  171. PROCEDURE resize* (line: tLine; size: INTEGER);
  172. BEGIN
  173.         ASSERT(line.temp);
  174.         IF size > 0 THEN
  175.                 line.ptr := API._DISPOSE(line.ptr);
  176.             size := size*WCHAR_SIZE + 4;
  177.         INC(size, (-size) MOD 32);
  178.                 line.ptr := API._NEW(size)
  179.         ELSE
  180.                 destroy(line)
  181.         END
  182. END resize;
  183.  
  184.  
  185. PROCEDURE getChar* (line: tLine; i: INTEGER): WCHAR;
  186. VAR
  187.     res: WCHAR;
  188. BEGIN
  189.     IF i >= line.length THEN
  190.         res := 0X
  191.     ELSE
  192.         SYSTEM.GET(line.ptr + i*WCHAR_SIZE, res)
  193.     END
  194.     RETURN res
  195. END getChar;
  196.  
  197.  
  198. PROCEDURE tabWidth (line: tLine; pos: INTEGER): INTEGER;
  199. VAR
  200.     n: INTEGER;
  201. BEGIN
  202.     n := pos;
  203.     IF getChar(line, pos) = TAB THEN
  204.         INC(pos);
  205.         WHILE getChar(line, pos) = TAB1 DO
  206.             INC(pos)
  207.         END
  208.     END
  209.     RETURN pos - n
  210. END tabWidth;
  211.  
  212.  
  213. PROCEDURE save* (line: tLine);
  214. BEGIN
  215.     IF ~line.temp THEN
  216.         movBool2(line, line.saved, TRUE);
  217.         movBool2(line, line.modified, FALSE)
  218.     END;
  219.     line.modified := FALSE;
  220.     line.saved := TRUE
  221. END save;
  222.  
  223.  
  224. PROCEDURE isSpace* (c: WCHAR): BOOLEAN;
  225.     RETURN (c = SPACE) OR (c = TAB) OR (c = TAB1)
  226. END isSpace;
  227.  
  228.  
  229. PROCEDURE trimLength* (line: tLine): INTEGER;
  230. VAR
  231.     i: INTEGER;
  232. BEGIN
  233.     i := line.length - 1;
  234.     WHILE (i >= 0) & isSpace(getChar(line, i)) DO
  235.         DEC(i)
  236.     END
  237.     RETURN i + 1
  238. END trimLength;
  239.  
  240.  
  241. PROCEDURE getPChar* (line: tLine; i: INTEGER): INTEGER;
  242.     RETURN line.ptr + i*WCHAR_SIZE
  243. END getPChar;
  244.  
  245.  
  246. PROCEDURE setChar* (line: tLine; i: INTEGER; c: WCHAR);
  247. BEGIN
  248.     SYSTEM.PUT(line.ptr + i*WCHAR_SIZE, c)
  249. END setChar;
  250.  
  251.  
  252. PROCEDURE move* (src, dst: tLine);
  253. BEGIN
  254.     SYSTEM.MOVE(src.ptr, dst.ptr, (MIN(src.length, dst.length) + 1)*WCHAR_SIZE)
  255. END move;
  256.  
  257.  
  258. PROCEDURE delChar* (line: tLine; pos: INTEGER);
  259. VAR
  260.     ptr: INTEGER;
  261. BEGIN
  262.     IF pos < line.length THEN
  263.         ptr := malloc(line.length);
  264.         ASSERT(ptr # 0);
  265.         IF ~line.temp THEN
  266.             movInt(line.length, line.length - 1)
  267.         END;
  268.         DEC(line.length);
  269.         SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
  270.         SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE + WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
  271.         SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
  272.         free(line, ptr)
  273.     END
  274. END delChar;
  275.  
  276.  
  277. PROCEDURE insert* (line: tLine; pos: INTEGER; c: WCHAR);
  278. VAR
  279.     ptr: INTEGER;
  280. BEGIN
  281.     ptr := malloc(line.length + 2);
  282.     ASSERT(ptr # 0);
  283.     SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
  284.     SYSTEM.PUT(ptr + pos*WCHAR_SIZE, c);
  285.     SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + pos*WCHAR_SIZE + WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
  286.     IF ~line.temp THEN
  287.         movInt(line.length, line.length + 1)
  288.     END;
  289.     INC(line.length);
  290.     SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
  291.     free(line, ptr)
  292. END insert;
  293.  
  294.  
  295. PROCEDURE _insert2* (line1: tLine; pos: INTEGER; line2: tLine);
  296. VAR
  297.     ptr: INTEGER;
  298. BEGIN
  299.     IF line2.length > 0 THEN
  300.         ptr := malloc(line1.length + line2.length + 1);
  301.         ASSERT(ptr # 0);
  302.         SYSTEM.MOVE(line1.ptr, ptr, pos*WCHAR_SIZE);
  303.         SYSTEM.MOVE(line2.ptr, ptr + pos*WCHAR_SIZE, line2.length*WCHAR_SIZE);
  304.         SYSTEM.MOVE(line1.ptr + pos*WCHAR_SIZE, ptr + (pos + line2.length)*WCHAR_SIZE, (line1.length - pos)*WCHAR_SIZE);
  305.         SYSTEM.PUT16(ptr + (line1.length + line2.length)*WCHAR_SIZE, 0);
  306.         IF ~line1.temp THEN
  307.             movInt(line1.length, line1.length + line2.length)
  308.         END;
  309.         IF ~line2.temp THEN
  310.             movInt(line2.length, 0)
  311.         END;
  312.         INC(line1.length, line2.length);
  313.         free(line1, ptr)
  314.     END
  315. END _insert2;
  316.  
  317.  
  318. PROCEDURE insert2* (line1: tLine; pos: INTEGER; line2: tLine);
  319. BEGIN
  320.         _insert2(line1, pos, line2);
  321.         IF line2.length > 0 THEN
  322.                 line2.length := 0;
  323.                 free(line2, 0)
  324.         END
  325. END insert2;
  326.  
  327.  
  328. PROCEDURE insert3* (line: tLine; pos, n: INTEGER);
  329. VAR
  330.     ptr: INTEGER;
  331. BEGIN
  332.     IF n > 0 THEN
  333.         ptr := malloc(line.length + n + 1);
  334.         ASSERT(ptr # 0);
  335.         SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
  336.         SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr + (pos + n)*WCHAR_SIZE, (line.length - pos)*WCHAR_SIZE);
  337.         SYSTEM.PUT16(ptr + (line.length + n)*WCHAR_SIZE, 0);
  338.         IF ~line.temp THEN
  339.             movInt(line.length, line.length + n)
  340.         END;
  341.         INC(line.length, n);
  342.         free(line, ptr)
  343.     END
  344. END insert3;
  345.  
  346.  
  347. PROCEDURE delCharN* (line: tLine; pos, n: INTEGER);
  348. VAR
  349.     ptr: INTEGER;
  350. BEGIN
  351.     IF n > 0 THEN
  352.         ptr := malloc(line.length - n + 1);
  353.         ASSERT(ptr # 0);
  354.         SYSTEM.MOVE(line.ptr, ptr, pos*WCHAR_SIZE);
  355.         SYSTEM.MOVE(line.ptr + (pos + n)*WCHAR_SIZE, ptr + pos*WCHAR_SIZE, (line.length - pos - n)*WCHAR_SIZE);
  356.         SYSTEM.PUT16(ptr + (line.length - n)*WCHAR_SIZE, 0);
  357.         IF ~line.temp THEN
  358.             movInt(line.length, line.length - n)
  359.         END;
  360.         DEC(line.length, n);
  361.         free(line, ptr)
  362.     END
  363. END delCharN;
  364.  
  365.  
  366. PROCEDURE fixTabs (line: tLine);
  367. VAR
  368.     i, n, k: INTEGER;
  369. BEGIN
  370.     i := 0;
  371.     WHILE i < line.length DO
  372.         n := tabWidth(line, i);
  373.         IF n # 0 THEN
  374.             k := tab - i MOD tab;
  375.             IF n > k THEN
  376.                 delCharN(line, i + 1, n - k)
  377.             ELSIF n < k THEN
  378.                 DEC(k, n);
  379.                 insert3(line, i + 1, k);
  380.                 WHILE k > 0 DO
  381.                     setChar(line, i + 1, TAB1);
  382.                     INC(i);
  383.                     DEC(k)
  384.                 END
  385.             END
  386.         END;
  387.         INC(i)
  388.     END
  389. END fixTabs;
  390.  
  391.  
  392. PROCEDURE modify* (line: tLine);
  393. BEGIN
  394.     IF ~line.temp THEN
  395.         movBool(line, line.modified, TRUE);
  396.         movBool(line, line.saved, FALSE)
  397.     END;
  398.     line.modified := TRUE;
  399.     line.saved := FALSE;
  400.     fixTabs(line)
  401. END modify;
  402.  
  403.  
  404. PROCEDURE wrap* (line, nextLine: tLine; pos: INTEGER);
  405. VAR
  406.     ptr1, ptr2: INTEGER;
  407.     n: INTEGER;
  408. BEGIN
  409.     ptr1 := malloc(pos + 1);
  410.     ASSERT(ptr1 # 0);
  411.     n := line.length - pos;
  412.     ptr2 := malloc(n + 1);
  413.     ASSERT(ptr2 # 0);
  414.     SYSTEM.MOVE(line.ptr, ptr1, pos*WCHAR_SIZE);
  415.     SYSTEM.PUT16(ptr1 + pos*WCHAR_SIZE, 0);
  416.     SYSTEM.MOVE(line.ptr + pos*WCHAR_SIZE, ptr2, n*WCHAR_SIZE);
  417.     SYSTEM.PUT16(ptr2 + n*WCHAR_SIZE, 0);
  418.     IF ~line.temp THEN
  419.         movInt(line.length, pos)
  420.     END;
  421.     IF ~nextLine.temp THEN
  422.         movInt(nextLine.length, n)
  423.     END;
  424.     line.length := pos;
  425.     nextLine.length := n;
  426.     free(line, ptr1);
  427.     free(nextLine, ptr2)
  428. END wrap;
  429.  
  430.  
  431. PROCEDURE copy* (line: tLine);
  432. VAR
  433.     ptr: INTEGER;
  434. BEGIN
  435.     ptr := malloc(line.length + 1);
  436.     ASSERT(ptr # 0);
  437.     SYSTEM.MOVE(line.ptr, ptr, line.length*WCHAR_SIZE);
  438.     SYSTEM.PUT16(ptr + line.length*WCHAR_SIZE, 0);
  439.     free(line, ptr)
  440. END copy;
  441.  
  442.  
  443. PROCEDURE chCase* (line: tLine; pos1, pos2: INTEGER; upper: BOOLEAN): BOOLEAN;
  444. VAR
  445.     i: INTEGER;
  446.     modified: BOOLEAN;
  447.     c: WCHAR;
  448.     func: PROCEDURE (VAR c: WCHAR): BOOLEAN;
  449. BEGIN
  450.     modified := FALSE;
  451.     IF upper THEN
  452.         func := Utils.cap
  453.     ELSE
  454.         func := Utils.low
  455.     END;
  456.     i := pos2;
  457.     WHILE i >= pos1 DO
  458.         c := getChar(line, i);
  459.         IF func(c) THEN
  460.             modified := TRUE
  461.         END;
  462.         DEC(i)
  463.     END;
  464.  
  465.     IF modified THEN
  466.         copy(line);
  467.         i := pos2;
  468.         WHILE i >= pos1 DO
  469.             c := getChar(line, i);
  470.             IF func(c) THEN
  471.                 setChar(line, i, c)
  472.             END;
  473.             DEC(i)
  474.         END;
  475.         modify(line)
  476.     END
  477.     RETURN modified
  478. END chCase;
  479.  
  480.  
  481. PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr; movBool, movBool2: PmovBool; typedPtr: PTypedPtr; untypedPtr: PUntypedPtr);
  482. BEGIN
  483.     _movInt := movInt;
  484.     _movPtr := movPtr;
  485.     _movBool := movBool;
  486.     _movBool2 := movBool2;
  487.     _typedPtr := typedPtr;
  488.     _untypedPtr := untypedPtr;
  489. END init;
  490.  
  491.  
  492. PROCEDURE setMaxLength* (VAR maxLength: INTEGER);
  493. BEGIN
  494.     pMaxLength := SYSTEM.ADR(maxLength)
  495. END setMaxLength;
  496.  
  497.  
  498. PROCEDURE setTabs* (_tab: INTEGER);
  499. BEGIN
  500.     IF _tab = 0 THEN
  501.         _tab := 4
  502.     END;
  503.     tabs := _tab > 0;
  504.     tab := ABS(_tab);
  505.     IF tab > 32 THEN
  506.         tab := 32
  507.     END
  508. END setTabs;
  509.  
  510.  
  511. BEGIN
  512.     pMaxLength := 0
  513. END Lines.