forked from KolibriOS/kolibrios
fbb49920de
- highlight @@:/@f/@b/@r - numpad support git-svn-id: svn://kolibrios.org@9909 a494cfbc-eb01-0410-851d-a64ba20cac60
183 lines
3.8 KiB
Plaintext
183 lines
3.8 KiB
Plaintext
(*
|
|
Copyright 2021-2023 Anton Krotov
|
|
|
|
This file is part of CEdit.
|
|
|
|
CEdit is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
CEdit is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with CEdit. If not, see <http://www.gnu.org/licenses/>.
|
|
*)
|
|
|
|
MODULE Search;
|
|
|
|
IMPORT
|
|
CB := Clipboard, List, Utils, SYSTEM;
|
|
|
|
CONST
|
|
itemSize = 64;
|
|
|
|
TYPE
|
|
tBuffer = CB.tBuffer;
|
|
|
|
tIdxTable = ARRAY 65536, 2 OF INTEGER;
|
|
|
|
tPos* = POINTER TO RECORD (List.tItem)
|
|
cnt*: INTEGER;
|
|
pos*: ARRAY itemSize OF INTEGER
|
|
END;
|
|
|
|
VAR
|
|
table: POINTER TO RECORD data: tIdxTable END;
|
|
|
|
|
|
PROCEDURE _index (text: tBuffer; cs: BOOLEAN; VAR table: tIdxTable): tBuffer;
|
|
VAR
|
|
pChar, cnt, i: INTEGER;
|
|
c: WCHAR;
|
|
res: tBuffer;
|
|
BEGIN
|
|
pChar := text.dataPtr;
|
|
cnt := CB.bufSize(text) DIV SYSTEM.SIZE(WCHAR);
|
|
|
|
FOR i := 0 TO 65535 DO
|
|
table[i, 1] := 0
|
|
END;
|
|
|
|
i := cnt;
|
|
WHILE i > 0 DO
|
|
SYSTEM.GET(pChar, c);
|
|
IF ~cs & Utils.lower(c) THEN
|
|
SYSTEM.PUT(pChar, c)
|
|
END;
|
|
INC(table[ORD(c), 1]);
|
|
INC(pChar, SYSTEM.SIZE(WCHAR));
|
|
DEC(i)
|
|
END;
|
|
|
|
res := CB.create(cnt*SYSTEM.SIZE(INTEGER));
|
|
|
|
table[0, 0] := res.dataPtr;
|
|
FOR i := 1 TO 65535 DO
|
|
table[i, 0] := table[i - 1, 0] + table[i - 1, 1]*SYSTEM.SIZE(INTEGER)
|
|
END;
|
|
|
|
pChar := text.dataPtr;
|
|
i := 0;
|
|
WHILE i < cnt DO
|
|
SYSTEM.GET(pChar, c);
|
|
SYSTEM.PUT(table[ORD(c), 0], i);
|
|
INC(table[ORD(c), 0], SYSTEM.SIZE(INTEGER));
|
|
INC(pChar, SYSTEM.SIZE(WCHAR));
|
|
INC(i)
|
|
END;
|
|
|
|
FOR i := 0 TO 65535 DO
|
|
DEC(table[i, 0], table[i, 1]*SYSTEM.SIZE(INTEGER))
|
|
END
|
|
|
|
RETURN res
|
|
END _index;
|
|
|
|
|
|
PROCEDURE index* (text: tBuffer; cs: BOOLEAN): tBuffer;
|
|
BEGIN
|
|
IF table = NIL THEN
|
|
NEW(table)
|
|
END
|
|
RETURN _index(text, cs, table.data)
|
|
END index;
|
|
|
|
|
|
PROCEDURE next* (VAR item: tPos; VAR i: INTEGER): INTEGER;
|
|
VAR
|
|
res: INTEGER;
|
|
BEGIN
|
|
IF (item # NIL) & (i >= item.cnt) THEN
|
|
item := item.next(tPos);
|
|
i := 0;
|
|
END;
|
|
IF (item # NIL ) & (i < item.cnt) THEN
|
|
res := item.pos[i];
|
|
INC(i)
|
|
ELSE
|
|
res := -1
|
|
END
|
|
RETURN res
|
|
END next;
|
|
|
|
|
|
PROCEDURE add* (list: List.tList; pos: INTEGER);
|
|
VAR
|
|
item: tPos;
|
|
BEGIN
|
|
item := list.last(tPos);
|
|
IF (item = NIL) OR (item.cnt = itemSize) THEN
|
|
NEW(item);
|
|
item.cnt := 0;
|
|
List.append(list, item)
|
|
END;
|
|
item.pos[item.cnt] := pos;
|
|
INC(item.cnt)
|
|
END add;
|
|
|
|
|
|
PROCEDURE find* (text: tBuffer; s: ARRAY OF WCHAR; whole: BOOLEAN; list: List.tList; offset: INTEGER);
|
|
VAR
|
|
k, pos, n, i, x, prev_item_pos: INTEGER;
|
|
c1, c2: WCHAR;
|
|
flag: BOOLEAN;
|
|
BEGIN
|
|
ASSERT(table # NIL);
|
|
n := LENGTH(s);
|
|
i := 0;
|
|
WHILE (i < n) & whole DO
|
|
whole := Utils.isWordChar(s[i]);
|
|
INC(i)
|
|
END;
|
|
k := table.data[ORD(s[0]), 1];
|
|
pos := table.data[ORD(s[0]), 0];
|
|
prev_item_pos := 0;
|
|
WHILE k > 0 DO
|
|
SYSTEM.GET(pos, x);
|
|
IF Utils.streq(text.dataPtr + x*SYSTEM.SIZE(WCHAR), SYSTEM.ADR(s[0]), n) THEN
|
|
flag := whole;
|
|
IF flag THEN
|
|
IF x > 0 THEN
|
|
SYSTEM.GET(text.dataPtr + (x - 1)*SYSTEM.SIZE(WCHAR), c1);
|
|
ELSE
|
|
c1 := 0X
|
|
END;
|
|
SYSTEM.GET(text.dataPtr + (x + n)*SYSTEM.SIZE(WCHAR), c2);
|
|
flag := Utils.isWordChar(c1) OR Utils.isWordChar(c2)
|
|
END;
|
|
IF ~flag & (x >= prev_item_pos) THEN
|
|
prev_item_pos := x + n;
|
|
add(list, x + offset)
|
|
END
|
|
END;
|
|
INC(pos, SYSTEM.SIZE(INTEGER));
|
|
DEC(k)
|
|
END
|
|
END find;
|
|
|
|
|
|
PROCEDURE close*;
|
|
BEGIN
|
|
IF table # NIL THEN
|
|
DISPOSE(table)
|
|
END
|
|
END close;
|
|
|
|
|
|
BEGIN
|
|
table := NIL
|
|
END Search. |