Subversion Repositories Kolibri OS

Rev

Rev 9907 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
9902 akron1 2
    Copyright 2021-2023 Anton Krotov
8728 leency 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 .
18
*)
19
 
20
MODULE Search;
21
 
22
IMPORT
9903 akron1 23
	CB := Clipboard, List, Utils, SYSTEM;
8728 leency 24
 
9903 akron1 25
CONST
26
	itemSize = 64;
8728 leency 27
 
28
TYPE
9907 akron1 29
	tBuffer = CB.tBuffer;
8728 leency 30
 
9903 akron1 31
	tIdxTable = ARRAY 65536, 2 OF INTEGER;
8728 leency 32
 
9903 akron1 33
	tPos* = POINTER TO RECORD (List.tItem)
34
		cnt*: INTEGER;
35
		pos*: ARRAY itemSize OF INTEGER
36
	END;
8728 leency 37
 
9902 akron1 38
VAR
39
	table: POINTER TO RECORD data: tIdxTable END;
8728 leency 40
 
9902 akron1 41
 
42
PROCEDURE _index (text: tBuffer; cs: BOOLEAN; VAR table: tIdxTable): tBuffer;
8728 leency 43
VAR
9903 akron1 44
	pChar, cnt, i: INTEGER;
45
	c: WCHAR;
46
	res: tBuffer;
8728 leency 47
BEGIN
9903 akron1 48
	pChar := text.dataPtr;
49
	cnt := CB.bufSize(text) DIV SYSTEM.SIZE(WCHAR);
8728 leency 50
 
9903 akron1 51
	FOR i := 0 TO 65535 DO
52
		table[i, 1] := 0
53
	END;
8728 leency 54
 
9903 akron1 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;
8728 leency 65
 
9903 akron1 66
	res := CB.create(cnt*SYSTEM.SIZE(INTEGER));
8728 leency 67
 
9903 akron1 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;
8728 leency 72
 
9903 akron1 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;
8728 leency 82
 
9903 akron1 83
	FOR i := 0 TO 65535 DO
84
		DEC(table[i, 0], table[i, 1]*SYSTEM.SIZE(INTEGER))
85
	END
8728 leency 86
 
9903 akron1 87
	RETURN res
9902 akron1 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)
8728 leency 97
END index;
98
 
99
 
9903 akron1 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
 
9909 akron1 118
PROCEDURE add* (list: List.tList; pos: INTEGER);
119
VAR
120
	item: tPos;
121
BEGIN
122
	item := list.last(tPos);
123
	IF (item = NIL) OR (item.cnt = itemSize) THEN
124
		NEW(item);
125
		item.cnt := 0;
126
		List.append(list, item)
127
	END;
128
	item.pos[item.cnt] := pos;
129
	INC(item.cnt)
130
END add;
131
 
132
 
9907 akron1 133
PROCEDURE find* (text: tBuffer; s: ARRAY OF WCHAR; whole: BOOLEAN; list: List.tList; offset: INTEGER);
8728 leency 134
VAR
9907 akron1 135
	k, pos, n, i, x, prev_item_pos: INTEGER;
9903 akron1 136
	c1, c2: WCHAR;
137
	flag: BOOLEAN;
8728 leency 138
BEGIN
9902 akron1 139
	ASSERT(table # NIL);
9903 akron1 140
	n := LENGTH(s);
9907 akron1 141
	i := 0;
142
	WHILE (i < n) & whole DO
143
		whole := Utils.isWordChar(s[i]);
144
		INC(i)
145
	END;
9903 akron1 146
	k := table.data[ORD(s[0]), 1];
147
	pos := table.data[ORD(s[0]), 0];
148
	prev_item_pos := 0;
149
	WHILE k > 0 DO
150
		SYSTEM.GET(pos, x);
151
		IF Utils.streq(text.dataPtr + x*SYSTEM.SIZE(WCHAR), SYSTEM.ADR(s[0]), n) THEN
152
			flag := whole;
153
			IF flag THEN
154
				IF x > 0 THEN
155
					SYSTEM.GET(text.dataPtr + (x - 1)*SYSTEM.SIZE(WCHAR), c1);
156
				ELSE
157
					c1 := 0X
158
				END;
159
				SYSTEM.GET(text.dataPtr + (x + n)*SYSTEM.SIZE(WCHAR), c2);
9907 akron1 160
				flag := Utils.isWordChar(c1) OR Utils.isWordChar(c2)
9903 akron1 161
			END;
162
			IF ~flag & (x >= prev_item_pos) THEN
163
				prev_item_pos := x + n;
9909 akron1 164
				add(list, x + offset)
9903 akron1 165
			END
166
		END;
167
		INC(pos, SYSTEM.SIZE(INTEGER));
168
		DEC(k)
169
	END
8728 leency 170
END find;
171
 
172
 
9902 akron1 173
PROCEDURE close*;
174
BEGIN
175
	IF table # NIL THEN
176
		DISPOSE(table)
177
	END
178
END close;
179
 
180
 
181
BEGIN
182
	table := NIL
8728 leency 183
END Search.