Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     Copyright 2021-2023 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 Search;
  21.  
  22. IMPORT
  23.         CB := Clipboard, List, Utils, SYSTEM;
  24.  
  25. CONST
  26.         itemSize = 64;
  27.  
  28. TYPE
  29.         tBuffer = CB.tBuffer;
  30.  
  31.         tIdxTable = ARRAY 65536, 2 OF INTEGER;
  32.  
  33.         tPos* = POINTER TO RECORD (List.tItem)
  34.                 cnt*: INTEGER;
  35.                 pos*: ARRAY itemSize OF INTEGER
  36.         END;
  37.  
  38. VAR
  39.         table: POINTER TO RECORD data: tIdxTable END;
  40.  
  41.  
  42. PROCEDURE _index (text: tBuffer; cs: BOOLEAN; VAR table: tIdxTable): tBuffer;
  43. VAR
  44.         pChar, cnt, i: INTEGER;
  45.         c: WCHAR;
  46.         res: tBuffer;
  47. BEGIN
  48.         pChar := text.dataPtr;
  49.         cnt := CB.bufSize(text) DIV SYSTEM.SIZE(WCHAR);
  50.  
  51.         FOR i := 0 TO 65535 DO
  52.                 table[i, 1] := 0
  53.         END;
  54.  
  55.         i := cnt;
  56.         WHILE i > 0 DO
  57.                 SYSTEM.GET(pChar, c);
  58.                 IF ~cs & Utils.lower(c) THEN
  59.                         SYSTEM.PUT(pChar, c)
  60.                 END;
  61.                 INC(table[ORD(c), 1]);
  62.                 INC(pChar, SYSTEM.SIZE(WCHAR));
  63.                 DEC(i)
  64.         END;
  65.  
  66.         res := CB.create(cnt*SYSTEM.SIZE(INTEGER));
  67.  
  68.         table[0, 0] := res.dataPtr;
  69.         FOR i := 1 TO 65535 DO
  70.                 table[i, 0] := table[i - 1, 0] + table[i - 1, 1]*SYSTEM.SIZE(INTEGER)
  71.         END;
  72.  
  73.         pChar := text.dataPtr;
  74.         i := 0;
  75.         WHILE i < cnt DO
  76.                 SYSTEM.GET(pChar, c);
  77.                 SYSTEM.PUT(table[ORD(c), 0], i);
  78.                 INC(table[ORD(c), 0], SYSTEM.SIZE(INTEGER));
  79.                 INC(pChar, SYSTEM.SIZE(WCHAR));
  80.                 INC(i)
  81.         END;
  82.  
  83.         FOR i := 0 TO 65535 DO
  84.                 DEC(table[i, 0], table[i, 1]*SYSTEM.SIZE(INTEGER))
  85.         END
  86.  
  87.         RETURN res
  88. END _index;
  89.  
  90.  
  91. PROCEDURE index* (text: tBuffer; cs: BOOLEAN): tBuffer;
  92. BEGIN
  93.         IF table = NIL THEN
  94.                 NEW(table)
  95.         END
  96.         RETURN _index(text, cs, table.data)
  97. END index;
  98.  
  99.  
  100. PROCEDURE next* (VAR item: tPos; VAR i: INTEGER): INTEGER;
  101. VAR
  102.         res: INTEGER;
  103. BEGIN
  104.         IF (item # NIL) & (i >= item.cnt) THEN
  105.                 item := item.next(tPos);
  106.                 i := 0;
  107.         END;
  108.         IF (item # NIL ) & (i < item.cnt) THEN
  109.                 res := item.pos[i];
  110.                 INC(i)
  111.         ELSE
  112.                 res := -1
  113.         END
  114.         RETURN res
  115. END next;
  116.  
  117.  
  118. PROCEDURE find* (text: tBuffer; s: ARRAY OF WCHAR; whole: BOOLEAN; list: List.tList; offset: INTEGER);
  119. VAR
  120.         k, pos, n, i, x, prev_item_pos: INTEGER;
  121.         item: tPos;
  122.         c1, c2: WCHAR;
  123.         flag: BOOLEAN;
  124. BEGIN
  125.         ASSERT(table # NIL);
  126.         n := LENGTH(s);
  127.         i := 0;
  128.         WHILE (i < n) & whole DO
  129.                 whole := Utils.isWordChar(s[i]);
  130.                 INC(i)
  131.         END;
  132.         k := table.data[ORD(s[0]), 1];
  133.         pos := table.data[ORD(s[0]), 0];
  134.         prev_item_pos := 0;
  135.         WHILE k > 0 DO
  136.                 SYSTEM.GET(pos, x);
  137.                 IF Utils.streq(text.dataPtr + x*SYSTEM.SIZE(WCHAR), SYSTEM.ADR(s[0]), n) THEN
  138.                         flag := whole;
  139.                         IF flag THEN
  140.                                 IF x > 0 THEN
  141.                                         SYSTEM.GET(text.dataPtr + (x - 1)*SYSTEM.SIZE(WCHAR), c1);
  142.                                 ELSE
  143.                                         c1 := 0X
  144.                                 END;
  145.                                 SYSTEM.GET(text.dataPtr + (x + n)*SYSTEM.SIZE(WCHAR), c2);
  146.                                 flag := Utils.isWordChar(c1) OR Utils.isWordChar(c2)
  147.                         END;
  148.                         IF ~flag & (x >= prev_item_pos) THEN
  149.                                 prev_item_pos := x + n;
  150.                                 item := list.last(tPos);
  151.                                 IF (item = NIL) OR (item.cnt = itemSize) THEN
  152.                                         NEW(item);
  153.                                         item.cnt := 0;
  154.                                         List.append(list, item)
  155.                                 END;
  156.                                 item.pos[item.cnt] := x + offset;
  157.                                 INC(item.cnt)
  158.                         END
  159.                 END;
  160.                 INC(pos, SYSTEM.SIZE(INTEGER));
  161.                 DEC(k)
  162.         END
  163. END find;
  164.  
  165.  
  166. PROCEDURE close*;
  167. BEGIN
  168.         IF table # NIL THEN
  169.                 DISPOSE(table)
  170.         END
  171. END close;
  172.  
  173.  
  174. BEGIN
  175.         table := NIL
  176. END Search.