Subversion Repositories Kolibri OS

Rev

Rev 9903 | Go to most recent revision | 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
 
9907 akron1 118
PROCEDURE find* (text: tBuffer; s: ARRAY OF WCHAR; whole: BOOLEAN; list: List.tList; offset: INTEGER);
8728 leency 119
VAR
9907 akron1 120
	k, pos, n, i, x, prev_item_pos: INTEGER;
9903 akron1 121
	item: tPos;
122
	c1, c2: WCHAR;
123
	flag: BOOLEAN;
8728 leency 124
BEGIN
9902 akron1 125
	ASSERT(table # NIL);
9903 akron1 126
	n := LENGTH(s);
9907 akron1 127
	i := 0;
128
	WHILE (i < n) & whole DO
129
		whole := Utils.isWordChar(s[i]);
130
		INC(i)
131
	END;
9903 akron1 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);
9907 akron1 146
				flag := Utils.isWordChar(c1) OR Utils.isWordChar(c2)
9903 akron1 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;
9907 akron1 156
				item.pos[item.cnt] := x + offset;
9903 akron1 157
				INC(item.cnt)
158
			END
159
		END;
160
		INC(pos, SYSTEM.SIZE(INTEGER));
161
		DEC(k)
162
	END
8728 leency 163
END find;
164
 
165
 
9902 akron1 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
8728 leency 176
END Search.