1 : #define VSTR_SRCH_CASE_C
2 : /*
3 : * Copyright (C) 2002, 2003, 2004 James Antill
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it under the terms of the GNU Lesser General Public
7 : * License as published by the Free Software Foundation; either
8 : * version 2 of the License, or (at your option) any later version.
9 : *
10 : * This library is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * Lesser General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public
16 : * License along with this library; if not, write to the Free Software
17 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 : *
19 : * email: james@and.org
20 : */
21 : /* functions for searching within a vstr, in a case independant manner */
22 : #include "main.h"
23 :
24 : size_t vstr_srch_case_chr_fwd(const Vstr_base *base, size_t pos, size_t len,
25 : char srch)
26 128 : {
27 128 : Vstr_iter iter[1];
28 :
29 128 : if (!VSTR__IS_ASCII_ALPHA(srch)) /* not searching for a case dependant char */
30 40 : return (vstr_srch_chr_fwd(base, pos, len, srch));
31 :
32 88 : if (VSTR__IS_ASCII_LOWER(srch))
33 28 : srch = VSTR__TO_ASCII_UPPER(srch);
34 :
35 88 : if (!vstr_iter_fwd_beg(base, pos, len, iter))
36 8 : return (0);
37 :
38 232 : do
39 : {
40 232 : if (iter->node->type != VSTR_TYPE_NODE_NON)
41 : {
42 232 : size_t count = 0;
43 :
44 1912 : while (count < iter->len)
45 : {
46 1740 : char scan_tmp = iter->ptr[count];
47 1740 : if (VSTR__IS_ASCII_LOWER(scan_tmp))
48 360 : scan_tmp = VSTR__TO_ASCII_UPPER(scan_tmp);
49 :
50 1740 : if (scan_tmp == srch)
51 60 : return (vstr_iter_pos(iter, pos, len) + count);
52 :
53 1680 : ++count;
54 : }
55 : }
56 172 : } while (vstr_iter_fwd_nxt(iter));
57 :
58 20 : return (0);
59 : }
60 :
61 : size_t vstr_srch_case_chr_rev(const Vstr_base *base, size_t pos, size_t len,
62 : char passed_srch)
63 120 : {
64 120 : char srch[2];
65 :
66 120 : srch[0] = passed_srch; /* not searching for a case dependant char */
67 120 : if (!VSTR__IS_ASCII_ALPHA(srch[0]))
68 40 : return (vstr_srch_chr_rev(base, pos, len, srch[0]));
69 :
70 80 : if (VSTR__IS_ASCII_LOWER(srch[0]))
71 20 : srch[1] = VSTR__TO_ASCII_UPPER(srch[0]);
72 : else
73 60 : srch[1] = VSTR__TO_ASCII_LOWER(srch[0]);
74 :
75 80 : return (vstr_srch_chrs_rev(base, pos, len, srch, 2));
76 : }
77 :
78 : size_t vstr_srch_case_buf_fwd(const Vstr_base *base, size_t pos, size_t len,
79 : const void *const str, const size_t str_len)
80 15294 : {
81 15294 : Vstr_iter iter[1];
82 15294 : char tmp = 0;
83 :
84 15294 : if (!len || (str_len > len))
85 7621 : return (0);
86 :
87 7673 : if (!str_len)
88 960 : return (pos);
89 :
90 6713 : if (!str) /* search for _NON lengths are no different */
91 172 : return (vstr_srch_buf_fwd(base, pos, len, str, str_len));
92 :
93 6541 : if (str_len == 1)
94 20 : return (vstr_srch_case_chr_fwd(base, pos, len, *(const char *)str));
95 :
96 6521 : if (!vstr_iter_fwd_beg(base, pos, len, iter))
97 8 : return (0);
98 :
99 6513 : assert(len == vstr_iter_len(iter));
100 :
101 6513 : tmp = *(const char *)str;
102 6513 : if (VSTR__IS_ASCII_LOWER(tmp))
103 280 : tmp = VSTR__TO_ASCII_UPPER(tmp);
104 :
105 8582 : do
106 : {
107 8582 : assert(str);
108 8582 : if (iter->node->type == VSTR_TYPE_NODE_NON)
109 4 : goto next_loop;
110 :
111 : /* find buf */
112 69440 : while (iter->len && (vstr_iter_len(iter) >= str_len))
113 : {
114 61556 : size_t beg_pos = 0;
115 61556 : char scan_tmp = 0;
116 :
117 61556 : scan_tmp = *iter->ptr;
118 61556 : if (VSTR__IS_ASCII_LOWER(scan_tmp))
119 32725 : scan_tmp = VSTR__TO_ASCII_UPPER(scan_tmp);
120 61556 : if (scan_tmp != tmp)
121 60702 : goto next_inc_loop;
122 :
123 854 : beg_pos = vstr_iter_pos(iter, pos, len);
124 854 : if (!vstr_cmp_case_buf(base, beg_pos, str_len,
125 : (const char *)str, str_len))
126 694 : return (beg_pos);
127 :
128 : next_inc_loop:
129 60862 : ++iter->ptr;
130 60862 : --iter->len;
131 : }
132 :
133 : next_loop:
134 7888 : continue;
135 7888 : } while (vstr_iter_fwd_nxt(iter) && (vstr_iter_len(iter) >= str_len));
136 :
137 5819 : return (0);
138 : }
139 :
140 : static size_t vstr__srch_case_buf_rev_slow(const Vstr_base *base,
141 : size_t pos, size_t len,
142 : const void *const str,
143 : const size_t str_len)
144 92 : {
145 92 : size_t ret = 0;
146 92 : size_t scan_pos = pos;
147 92 : size_t scan_len = len;
148 :
149 296 : while ((scan_pos < (pos + len - 1)) &&
150 : (scan_len >= str_len))
151 : {
152 276 : size_t tmp = vstr_srch_case_buf_fwd(base, scan_pos, scan_len,
153 276 : str, str_len);
154 276 : if (!tmp)
155 72 : break;
156 :
157 204 : ret = tmp;
158 :
159 204 : scan_pos = ret + 1;
160 204 : scan_len = len - VSTR_SC_POSDIFF(pos, ret);
161 : }
162 :
163 92 : return (ret);
164 : }
165 :
166 : size_t vstr_srch_case_buf_rev(const Vstr_base *base, size_t pos, size_t len,
167 : const void *const str, const size_t str_len)
168 1116 : {
169 1116 : if (!len || (str_len > len))
170 40 : return (0);
171 :
172 1076 : if (!str_len)
173 964 : return (pos + len - 1);
174 :
175 112 : if (str && (str_len == 1))
176 20 : return (vstr_srch_case_chr_rev(base, pos, len, *(const char *)str));
177 :
178 92 : return (vstr__srch_case_buf_rev_slow(base, pos, len, str, str_len));
179 : }
180 :
181 : size_t vstr_srch_case_vstr_fwd(const Vstr_base *base, size_t pos, size_t len,
182 : const Vstr_base *ndl_base,
183 : size_t ndl_pos, size_t ndl_len)
184 808 : {
185 808 : Vstr_iter iter[1];
186 808 : size_t scan_pos = pos;
187 808 : size_t scan_len = len;
188 :
189 808 : if (ndl_len > len)
190 80 : return (0);
191 :
192 728 : if (!vstr_iter_fwd_beg(ndl_base, ndl_pos, ndl_len, iter))
193 8 : return (0);
194 :
195 4520 : while ((scan_pos < (pos + len - 1)) &&
196 : (scan_len >= ndl_len))
197 : {
198 4440 : if (!vstr_cmp_case(base, scan_pos, ndl_len, ndl_base, ndl_pos, ndl_len))
199 360 : return (scan_pos);
200 :
201 4080 : --scan_len;
202 4080 : ++scan_pos;
203 :
204 4080 : if (iter->node->type != VSTR_TYPE_NODE_NON)
205 : {
206 560 : size_t tmp = 0;
207 :
208 560 : if (!(tmp = vstr_srch_case_buf_fwd(base, scan_pos, scan_len,
209 : iter->ptr, iter->len)))
210 280 : return (0);
211 :
212 280 : ASSERT(tmp >= scan_pos);
213 280 : scan_len -= tmp - scan_pos;
214 280 : scan_pos = tmp;
215 : }
216 : }
217 :
218 80 : return (0);
219 : }
220 :
221 : static size_t vstr__srch_case_vstr_rev_slow(const Vstr_base *base,
222 : size_t pos, size_t len,
223 : const Vstr_base *ndl_base,
224 : size_t ndl_pos, size_t ndl_len)
225 360 : {
226 360 : size_t ret = 0;
227 360 : size_t scan_pos = pos;
228 360 : size_t scan_len = len;
229 :
230 560 : while ((scan_pos < (pos + len - 1)) &&
231 : (scan_len >= ndl_len))
232 : {
233 440 : size_t tmp = vstr_srch_case_vstr_fwd(base, scan_pos, scan_len,
234 440 : ndl_base, ndl_pos, ndl_len);
235 440 : if (!tmp)
236 240 : break;
237 :
238 200 : ret = tmp;
239 :
240 200 : scan_pos = ret + 1;
241 200 : scan_len = len - VSTR_SC_POSDIFF(pos, ret);
242 : }
243 :
244 360 : return (ret);
245 : }
246 :
247 : size_t vstr_srch_case_vstr_rev(const Vstr_base *base, size_t pos, size_t len,
248 : const Vstr_base *ndl_base,
249 : size_t ndl_pos, size_t ndl_len)
250 360 : {
251 360 : return (vstr__srch_case_vstr_rev_slow(base, pos, len,
252 : ndl_base, ndl_pos, ndl_len));
253 : }
|