1c99fb5f9SBaptiste Daroussin /*
2c99fb5f9SBaptiste Daroussin Copyright (c) 2008-2013, Troy D. Hanson http://troydhanson.github.com/uthash/
3c99fb5f9SBaptiste Daroussin All rights reserved.
4c99fb5f9SBaptiste Daroussin
5c99fb5f9SBaptiste Daroussin Redistribution and use in source and binary forms, with or without
6c99fb5f9SBaptiste Daroussin modification, are permitted provided that the following conditions are met:
7c99fb5f9SBaptiste Daroussin
8c99fb5f9SBaptiste Daroussin * Redistributions of source code must retain the above copyright
9c99fb5f9SBaptiste Daroussin notice, this list of conditions and the following disclaimer.
10c99fb5f9SBaptiste Daroussin
11c99fb5f9SBaptiste Daroussin THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
12c99fb5f9SBaptiste Daroussin IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
13c99fb5f9SBaptiste Daroussin TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14c99fb5f9SBaptiste Daroussin PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
15c99fb5f9SBaptiste Daroussin OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16c99fb5f9SBaptiste Daroussin EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17c99fb5f9SBaptiste Daroussin PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18c99fb5f9SBaptiste Daroussin PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19c99fb5f9SBaptiste Daroussin LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20c99fb5f9SBaptiste Daroussin NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21c99fb5f9SBaptiste Daroussin SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22c99fb5f9SBaptiste Daroussin */
23c99fb5f9SBaptiste Daroussin
24c99fb5f9SBaptiste Daroussin /* a dynamic string implementation using macros
25c99fb5f9SBaptiste Daroussin */
26c99fb5f9SBaptiste Daroussin #ifndef UTSTRING_H
27c99fb5f9SBaptiste Daroussin #define UTSTRING_H
28c99fb5f9SBaptiste Daroussin
29c99fb5f9SBaptiste Daroussin #define UTSTRING_VERSION 1.9.8
30c99fb5f9SBaptiste Daroussin
31c99fb5f9SBaptiste Daroussin #ifdef __GNUC__
32c99fb5f9SBaptiste Daroussin #define _UNUSED_ __attribute__ ((__unused__))
33c99fb5f9SBaptiste Daroussin #else
34c99fb5f9SBaptiste Daroussin #define _UNUSED_
35c99fb5f9SBaptiste Daroussin #endif
36c99fb5f9SBaptiste Daroussin
37c99fb5f9SBaptiste Daroussin #include <stdlib.h>
38c99fb5f9SBaptiste Daroussin #include <string.h>
39c99fb5f9SBaptiste Daroussin #include <stdarg.h>
40c99fb5f9SBaptiste Daroussin
41c99fb5f9SBaptiste Daroussin #ifndef oom
42*8e3b1ab2SBaptiste Daroussin #define oom abort
43c99fb5f9SBaptiste Daroussin #endif
44c99fb5f9SBaptiste Daroussin
45c99fb5f9SBaptiste Daroussin typedef struct {
46c99fb5f9SBaptiste Daroussin char *d;
473dcf5eb7SBaptiste Daroussin void **pd;
48c99fb5f9SBaptiste Daroussin size_t n; /* allocd size */
49c99fb5f9SBaptiste Daroussin size_t i; /* index of first unused byte */
50c99fb5f9SBaptiste Daroussin } UT_string;
51c99fb5f9SBaptiste Daroussin
52c99fb5f9SBaptiste Daroussin #define utstring_reserve(s,amt) \
53c99fb5f9SBaptiste Daroussin do { \
54c99fb5f9SBaptiste Daroussin if (((s)->n - (s)->i) < (size_t)(amt)) { \
55c99fb5f9SBaptiste Daroussin (s)->d = (char*)realloc((s)->d, (s)->n + amt); \
56c99fb5f9SBaptiste Daroussin if ((s)->d == NULL) oom(); \
57*8e3b1ab2SBaptiste Daroussin else {(s)->n += amt; \
58*8e3b1ab2SBaptiste Daroussin if ((s)->pd) *((s)->pd) = (s)->d;} \
59c99fb5f9SBaptiste Daroussin } \
60c99fb5f9SBaptiste Daroussin } while(0)
61c99fb5f9SBaptiste Daroussin
62c99fb5f9SBaptiste Daroussin #define utstring_init(s) \
63c99fb5f9SBaptiste Daroussin do { \
64c99fb5f9SBaptiste Daroussin (s)->n = 0; (s)->i = 0; (s)->d = NULL; \
65c99fb5f9SBaptiste Daroussin utstring_reserve(s,128); \
66c99fb5f9SBaptiste Daroussin (s)->d[0] = '\0'; \
67c99fb5f9SBaptiste Daroussin } while(0)
68c99fb5f9SBaptiste Daroussin
69c99fb5f9SBaptiste Daroussin #define utstring_done(s) \
70c99fb5f9SBaptiste Daroussin do { \
71c99fb5f9SBaptiste Daroussin if ((s)->d != NULL) free((s)->d); \
72c99fb5f9SBaptiste Daroussin (s)->n = 0; \
73c99fb5f9SBaptiste Daroussin } while(0)
74c99fb5f9SBaptiste Daroussin
75c99fb5f9SBaptiste Daroussin #define utstring_free(s) \
76c99fb5f9SBaptiste Daroussin do { \
77c99fb5f9SBaptiste Daroussin utstring_done(s); \
78c99fb5f9SBaptiste Daroussin free(s); \
79c99fb5f9SBaptiste Daroussin } while(0)
80c99fb5f9SBaptiste Daroussin
81c99fb5f9SBaptiste Daroussin #define utstring_new(s) \
82c99fb5f9SBaptiste Daroussin do { \
833dcf5eb7SBaptiste Daroussin s = (UT_string*)calloc(1, sizeof(UT_string)); \
84c99fb5f9SBaptiste Daroussin if (!s) oom(); \
85*8e3b1ab2SBaptiste Daroussin else utstring_init(s); \
86c99fb5f9SBaptiste Daroussin } while(0)
87c99fb5f9SBaptiste Daroussin
88c99fb5f9SBaptiste Daroussin #define utstring_renew(s) \
89c99fb5f9SBaptiste Daroussin do { \
90c99fb5f9SBaptiste Daroussin if (s) { \
91c99fb5f9SBaptiste Daroussin utstring_clear(s); \
92c99fb5f9SBaptiste Daroussin } else { \
93c99fb5f9SBaptiste Daroussin utstring_new(s); \
94c99fb5f9SBaptiste Daroussin } \
95c99fb5f9SBaptiste Daroussin } while(0)
96c99fb5f9SBaptiste Daroussin
97c99fb5f9SBaptiste Daroussin #define utstring_clear(s) \
98c99fb5f9SBaptiste Daroussin do { \
99c99fb5f9SBaptiste Daroussin (s)->i = 0; \
100c99fb5f9SBaptiste Daroussin (s)->d[0] = '\0'; \
101c99fb5f9SBaptiste Daroussin } while(0)
102c99fb5f9SBaptiste Daroussin
103c99fb5f9SBaptiste Daroussin #define utstring_bincpy(s,b,l) \
104c99fb5f9SBaptiste Daroussin do { \
105c99fb5f9SBaptiste Daroussin utstring_reserve((s),(l)+1); \
106c99fb5f9SBaptiste Daroussin if (l) memcpy(&(s)->d[(s)->i], b, l); \
107c99fb5f9SBaptiste Daroussin (s)->i += l; \
108c99fb5f9SBaptiste Daroussin (s)->d[(s)->i]='\0'; \
109c99fb5f9SBaptiste Daroussin } while(0)
110c99fb5f9SBaptiste Daroussin
111c99fb5f9SBaptiste Daroussin #define utstring_concat(dst,src) \
112c99fb5f9SBaptiste Daroussin do { \
113c99fb5f9SBaptiste Daroussin utstring_reserve((dst),((src)->i)+1); \
114c99fb5f9SBaptiste Daroussin if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
115c99fb5f9SBaptiste Daroussin (dst)->i += (src)->i; \
116c99fb5f9SBaptiste Daroussin (dst)->d[(dst)->i]='\0'; \
117c99fb5f9SBaptiste Daroussin } while(0)
118c99fb5f9SBaptiste Daroussin
119c99fb5f9SBaptiste Daroussin #define utstring_len(s) ((unsigned)((s)->i))
120c99fb5f9SBaptiste Daroussin
121c99fb5f9SBaptiste Daroussin #define utstring_body(s) ((s)->d)
122c99fb5f9SBaptiste Daroussin
utstring_printf_va(UT_string * s,const char * fmt,va_list ap)123c99fb5f9SBaptiste Daroussin _UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124c99fb5f9SBaptiste Daroussin int n;
125c99fb5f9SBaptiste Daroussin va_list cp;
126c99fb5f9SBaptiste Daroussin while (1) {
127c99fb5f9SBaptiste Daroussin #ifdef _WIN32
128c99fb5f9SBaptiste Daroussin cp = ap;
129c99fb5f9SBaptiste Daroussin #else
130c99fb5f9SBaptiste Daroussin va_copy(cp, ap);
131c99fb5f9SBaptiste Daroussin #endif
132c99fb5f9SBaptiste Daroussin n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133c99fb5f9SBaptiste Daroussin va_end(cp);
134c99fb5f9SBaptiste Daroussin
135c99fb5f9SBaptiste Daroussin if ((n > -1) && (n < (int)(s->n-s->i))) {
136c99fb5f9SBaptiste Daroussin s->i += n;
137c99fb5f9SBaptiste Daroussin return;
138c99fb5f9SBaptiste Daroussin }
139c99fb5f9SBaptiste Daroussin
140c99fb5f9SBaptiste Daroussin /* Else try again with more space. */
141c99fb5f9SBaptiste Daroussin if (n > -1) utstring_reserve(s,n+1); /* exact */
142c99fb5f9SBaptiste Daroussin else utstring_reserve(s,(s->n)*2); /* 2x */
143c99fb5f9SBaptiste Daroussin }
144c99fb5f9SBaptiste Daroussin }
145c99fb5f9SBaptiste Daroussin #ifdef __GNUC__
146c99fb5f9SBaptiste Daroussin /* support printf format checking (2=the format string, 3=start of varargs) */
147c99fb5f9SBaptiste Daroussin static void utstring_printf(UT_string *s, const char *fmt, ...)
148c99fb5f9SBaptiste Daroussin __attribute__ (( format( printf, 2, 3) ));
149c99fb5f9SBaptiste Daroussin #endif
utstring_printf(UT_string * s,const char * fmt,...)150c99fb5f9SBaptiste Daroussin _UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {
151c99fb5f9SBaptiste Daroussin va_list ap;
152c99fb5f9SBaptiste Daroussin va_start(ap,fmt);
153c99fb5f9SBaptiste Daroussin utstring_printf_va(s,fmt,ap);
154c99fb5f9SBaptiste Daroussin va_end(ap);
155c99fb5f9SBaptiste Daroussin }
156c99fb5f9SBaptiste Daroussin
157c99fb5f9SBaptiste Daroussin #define utstring_append_len(dst, src, len) \
158c99fb5f9SBaptiste Daroussin do { \
159c99fb5f9SBaptiste Daroussin while ((dst)->n-(dst)->i <= (len)) utstring_reserve((dst),((dst)->n)*2); \
160c99fb5f9SBaptiste Daroussin memcpy(&(dst)->d[(dst)->i], (src), (len)); \
161c99fb5f9SBaptiste Daroussin (dst)->i+=(len); \
162c99fb5f9SBaptiste Daroussin (dst)->d[(dst)->i]='\0'; \
163c99fb5f9SBaptiste Daroussin } while(0)
164c99fb5f9SBaptiste Daroussin
165c99fb5f9SBaptiste Daroussin #define utstring_append_c(dst, c) \
166c99fb5f9SBaptiste Daroussin do { \
167c99fb5f9SBaptiste Daroussin if ((dst)->n-(dst)->i < 2) utstring_reserve((dst),((dst)->n)*2); \
168c99fb5f9SBaptiste Daroussin (dst)->d[(dst)->i++] = (c); \
169c99fb5f9SBaptiste Daroussin (dst)->d[(dst)->i]='\0'; \
170c99fb5f9SBaptiste Daroussin } while(0)
171c99fb5f9SBaptiste Daroussin
172c99fb5f9SBaptiste Daroussin /*******************************************************************************
173c99fb5f9SBaptiste Daroussin * begin substring search functions *
174c99fb5f9SBaptiste Daroussin ******************************************************************************/
175c99fb5f9SBaptiste Daroussin /* Build KMP table from left to right. */
_utstring_BuildTable(const char * P_Needle,ssize_t P_NeedleLen,long * P_KMP_Table)176c99fb5f9SBaptiste Daroussin _UNUSED_ static void _utstring_BuildTable(
177c99fb5f9SBaptiste Daroussin const char *P_Needle,
178c99fb5f9SBaptiste Daroussin ssize_t P_NeedleLen,
179c99fb5f9SBaptiste Daroussin long *P_KMP_Table)
180c99fb5f9SBaptiste Daroussin {
181c99fb5f9SBaptiste Daroussin long i, j;
182c99fb5f9SBaptiste Daroussin
183c99fb5f9SBaptiste Daroussin i = 0;
184c99fb5f9SBaptiste Daroussin j = i - 1;
185c99fb5f9SBaptiste Daroussin P_KMP_Table[i] = j;
186c99fb5f9SBaptiste Daroussin while (i < P_NeedleLen)
187c99fb5f9SBaptiste Daroussin {
188c99fb5f9SBaptiste Daroussin while ( (j > -1) && (P_Needle[i] != P_Needle[j]) )
189c99fb5f9SBaptiste Daroussin {
190c99fb5f9SBaptiste Daroussin j = P_KMP_Table[j];
191c99fb5f9SBaptiste Daroussin }
192c99fb5f9SBaptiste Daroussin i++;
193c99fb5f9SBaptiste Daroussin j++;
194c99fb5f9SBaptiste Daroussin if (i < P_NeedleLen)
195c99fb5f9SBaptiste Daroussin {
196c99fb5f9SBaptiste Daroussin if (P_Needle[i] == P_Needle[j])
197c99fb5f9SBaptiste Daroussin {
198c99fb5f9SBaptiste Daroussin P_KMP_Table[i] = P_KMP_Table[j];
199c99fb5f9SBaptiste Daroussin }
200c99fb5f9SBaptiste Daroussin else
201c99fb5f9SBaptiste Daroussin {
202c99fb5f9SBaptiste Daroussin P_KMP_Table[i] = j;
203c99fb5f9SBaptiste Daroussin }
204c99fb5f9SBaptiste Daroussin }
205c99fb5f9SBaptiste Daroussin else
206c99fb5f9SBaptiste Daroussin {
207c99fb5f9SBaptiste Daroussin P_KMP_Table[i] = j;
208c99fb5f9SBaptiste Daroussin }
209c99fb5f9SBaptiste Daroussin }
210c99fb5f9SBaptiste Daroussin
211c99fb5f9SBaptiste Daroussin return;
212c99fb5f9SBaptiste Daroussin }
213c99fb5f9SBaptiste Daroussin
214c99fb5f9SBaptiste Daroussin
215c99fb5f9SBaptiste Daroussin /* Build KMP table from right to left. */
_utstring_BuildTableR(const char * P_Needle,ssize_t P_NeedleLen,long * P_KMP_Table)216c99fb5f9SBaptiste Daroussin _UNUSED_ static void _utstring_BuildTableR(
217c99fb5f9SBaptiste Daroussin const char *P_Needle,
218c99fb5f9SBaptiste Daroussin ssize_t P_NeedleLen,
219c99fb5f9SBaptiste Daroussin long *P_KMP_Table)
220c99fb5f9SBaptiste Daroussin {
221c99fb5f9SBaptiste Daroussin long i, j;
222c99fb5f9SBaptiste Daroussin
223c99fb5f9SBaptiste Daroussin i = P_NeedleLen - 1;
224c99fb5f9SBaptiste Daroussin j = i + 1;
225c99fb5f9SBaptiste Daroussin P_KMP_Table[i + 1] = j;
226c99fb5f9SBaptiste Daroussin while (i >= 0)
227c99fb5f9SBaptiste Daroussin {
228c99fb5f9SBaptiste Daroussin while ( (j < P_NeedleLen) && (P_Needle[i] != P_Needle[j]) )
229c99fb5f9SBaptiste Daroussin {
230c99fb5f9SBaptiste Daroussin j = P_KMP_Table[j + 1];
231c99fb5f9SBaptiste Daroussin }
232c99fb5f9SBaptiste Daroussin i--;
233c99fb5f9SBaptiste Daroussin j--;
234c99fb5f9SBaptiste Daroussin if (i >= 0)
235c99fb5f9SBaptiste Daroussin {
236c99fb5f9SBaptiste Daroussin if (P_Needle[i] == P_Needle[j])
237c99fb5f9SBaptiste Daroussin {
238c99fb5f9SBaptiste Daroussin P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
239c99fb5f9SBaptiste Daroussin }
240c99fb5f9SBaptiste Daroussin else
241c99fb5f9SBaptiste Daroussin {
242c99fb5f9SBaptiste Daroussin P_KMP_Table[i + 1] = j;
243c99fb5f9SBaptiste Daroussin }
244c99fb5f9SBaptiste Daroussin }
245c99fb5f9SBaptiste Daroussin else
246c99fb5f9SBaptiste Daroussin {
247c99fb5f9SBaptiste Daroussin P_KMP_Table[i + 1] = j;
248c99fb5f9SBaptiste Daroussin }
249c99fb5f9SBaptiste Daroussin }
250c99fb5f9SBaptiste Daroussin
251c99fb5f9SBaptiste Daroussin return;
252c99fb5f9SBaptiste Daroussin }
253c99fb5f9SBaptiste Daroussin
254c99fb5f9SBaptiste Daroussin
255c99fb5f9SBaptiste Daroussin /* Search data from left to right. ( Multiple search mode. ) */
_utstring_find(const char * P_Haystack,size_t P_HaystackLen,const char * P_Needle,size_t P_NeedleLen,long * P_KMP_Table)256c99fb5f9SBaptiste Daroussin _UNUSED_ static long _utstring_find(
257c99fb5f9SBaptiste Daroussin const char *P_Haystack,
258c99fb5f9SBaptiste Daroussin size_t P_HaystackLen,
259c99fb5f9SBaptiste Daroussin const char *P_Needle,
260c99fb5f9SBaptiste Daroussin size_t P_NeedleLen,
261c99fb5f9SBaptiste Daroussin long *P_KMP_Table)
262c99fb5f9SBaptiste Daroussin {
263c99fb5f9SBaptiste Daroussin long i, j;
264c99fb5f9SBaptiste Daroussin long V_FindPosition = -1;
265c99fb5f9SBaptiste Daroussin
266c99fb5f9SBaptiste Daroussin /* Search from left to right. */
267c99fb5f9SBaptiste Daroussin i = j = 0;
268c99fb5f9SBaptiste Daroussin while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) )
269c99fb5f9SBaptiste Daroussin {
270c99fb5f9SBaptiste Daroussin while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) )
271c99fb5f9SBaptiste Daroussin {
272c99fb5f9SBaptiste Daroussin i = P_KMP_Table[i];
273c99fb5f9SBaptiste Daroussin }
274c99fb5f9SBaptiste Daroussin i++;
275c99fb5f9SBaptiste Daroussin j++;
276c99fb5f9SBaptiste Daroussin if (i >= (int)P_NeedleLen)
277c99fb5f9SBaptiste Daroussin {
278c99fb5f9SBaptiste Daroussin /* Found. */
279c99fb5f9SBaptiste Daroussin V_FindPosition = j - i;
280c99fb5f9SBaptiste Daroussin break;
281c99fb5f9SBaptiste Daroussin }
282c99fb5f9SBaptiste Daroussin }
283c99fb5f9SBaptiste Daroussin
284c99fb5f9SBaptiste Daroussin return V_FindPosition;
285c99fb5f9SBaptiste Daroussin }
286c99fb5f9SBaptiste Daroussin
287c99fb5f9SBaptiste Daroussin
288c99fb5f9SBaptiste Daroussin /* Search data from right to left. ( Multiple search mode. ) */
_utstring_findR(const char * P_Haystack,size_t P_HaystackLen,const char * P_Needle,size_t P_NeedleLen,long * P_KMP_Table)289c99fb5f9SBaptiste Daroussin _UNUSED_ static long _utstring_findR(
290c99fb5f9SBaptiste Daroussin const char *P_Haystack,
291c99fb5f9SBaptiste Daroussin size_t P_HaystackLen,
292c99fb5f9SBaptiste Daroussin const char *P_Needle,
293c99fb5f9SBaptiste Daroussin size_t P_NeedleLen,
294c99fb5f9SBaptiste Daroussin long *P_KMP_Table)
295c99fb5f9SBaptiste Daroussin {
296c99fb5f9SBaptiste Daroussin long i, j;
297c99fb5f9SBaptiste Daroussin long V_FindPosition = -1;
298c99fb5f9SBaptiste Daroussin
299c99fb5f9SBaptiste Daroussin /* Search from right to left. */
300c99fb5f9SBaptiste Daroussin j = (P_HaystackLen - 1);
301c99fb5f9SBaptiste Daroussin i = (P_NeedleLen - 1);
302c99fb5f9SBaptiste Daroussin while ( (j >= 0) && (j >= i) )
303c99fb5f9SBaptiste Daroussin {
304c99fb5f9SBaptiste Daroussin while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) )
305c99fb5f9SBaptiste Daroussin {
306c99fb5f9SBaptiste Daroussin i = P_KMP_Table[i + 1];
307c99fb5f9SBaptiste Daroussin }
308c99fb5f9SBaptiste Daroussin i--;
309c99fb5f9SBaptiste Daroussin j--;
310c99fb5f9SBaptiste Daroussin if (i < 0)
311c99fb5f9SBaptiste Daroussin {
312c99fb5f9SBaptiste Daroussin /* Found. */
313c99fb5f9SBaptiste Daroussin V_FindPosition = j + 1;
314c99fb5f9SBaptiste Daroussin break;
315c99fb5f9SBaptiste Daroussin }
316c99fb5f9SBaptiste Daroussin }
317c99fb5f9SBaptiste Daroussin
318c99fb5f9SBaptiste Daroussin return V_FindPosition;
319c99fb5f9SBaptiste Daroussin }
320c99fb5f9SBaptiste Daroussin
321c99fb5f9SBaptiste Daroussin
322c99fb5f9SBaptiste Daroussin /* Search data from left to right. ( One time search mode. ) */
utstring_find(UT_string * s,long P_StartPosition,const char * P_Needle,ssize_t P_NeedleLen)323c99fb5f9SBaptiste Daroussin _UNUSED_ static long utstring_find(
324c99fb5f9SBaptiste Daroussin UT_string *s,
325c99fb5f9SBaptiste Daroussin long P_StartPosition, /* Start from 0. -1 means last position. */
326c99fb5f9SBaptiste Daroussin const char *P_Needle,
327c99fb5f9SBaptiste Daroussin ssize_t P_NeedleLen)
328c99fb5f9SBaptiste Daroussin {
329c99fb5f9SBaptiste Daroussin long V_StartPosition;
330c99fb5f9SBaptiste Daroussin long V_HaystackLen;
331c99fb5f9SBaptiste Daroussin long *V_KMP_Table;
332c99fb5f9SBaptiste Daroussin long V_FindPosition = -1;
333c99fb5f9SBaptiste Daroussin
334c99fb5f9SBaptiste Daroussin if (P_StartPosition < 0)
335c99fb5f9SBaptiste Daroussin {
336c99fb5f9SBaptiste Daroussin V_StartPosition = s->i + P_StartPosition;
337c99fb5f9SBaptiste Daroussin }
338c99fb5f9SBaptiste Daroussin else
339c99fb5f9SBaptiste Daroussin {
340c99fb5f9SBaptiste Daroussin V_StartPosition = P_StartPosition;
341c99fb5f9SBaptiste Daroussin }
342c99fb5f9SBaptiste Daroussin V_HaystackLen = s->i - V_StartPosition;
343c99fb5f9SBaptiste Daroussin if ( (V_HaystackLen >= P_NeedleLen) && (P_NeedleLen > 0) )
344c99fb5f9SBaptiste Daroussin {
345c99fb5f9SBaptiste Daroussin V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
346c99fb5f9SBaptiste Daroussin if (V_KMP_Table != NULL)
347c99fb5f9SBaptiste Daroussin {
348c99fb5f9SBaptiste Daroussin _utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
349c99fb5f9SBaptiste Daroussin
350c99fb5f9SBaptiste Daroussin V_FindPosition = _utstring_find(s->d + V_StartPosition,
351c99fb5f9SBaptiste Daroussin V_HaystackLen,
352c99fb5f9SBaptiste Daroussin P_Needle,
353c99fb5f9SBaptiste Daroussin P_NeedleLen,
354c99fb5f9SBaptiste Daroussin V_KMP_Table);
355c99fb5f9SBaptiste Daroussin if (V_FindPosition >= 0)
356c99fb5f9SBaptiste Daroussin {
357c99fb5f9SBaptiste Daroussin V_FindPosition += V_StartPosition;
358c99fb5f9SBaptiste Daroussin }
359c99fb5f9SBaptiste Daroussin
360c99fb5f9SBaptiste Daroussin free(V_KMP_Table);
361c99fb5f9SBaptiste Daroussin }
362c99fb5f9SBaptiste Daroussin }
363c99fb5f9SBaptiste Daroussin
364c99fb5f9SBaptiste Daroussin return V_FindPosition;
365c99fb5f9SBaptiste Daroussin }
366c99fb5f9SBaptiste Daroussin
367c99fb5f9SBaptiste Daroussin
368c99fb5f9SBaptiste Daroussin /* Search data from right to left. ( One time search mode. ) */
utstring_findR(UT_string * s,long P_StartPosition,const char * P_Needle,ssize_t P_NeedleLen)369c99fb5f9SBaptiste Daroussin _UNUSED_ static long utstring_findR(
370c99fb5f9SBaptiste Daroussin UT_string *s,
371c99fb5f9SBaptiste Daroussin long P_StartPosition, /* Start from 0. -1 means last position. */
372c99fb5f9SBaptiste Daroussin const char *P_Needle,
373c99fb5f9SBaptiste Daroussin ssize_t P_NeedleLen)
374c99fb5f9SBaptiste Daroussin {
375c99fb5f9SBaptiste Daroussin long V_StartPosition;
376c99fb5f9SBaptiste Daroussin long V_HaystackLen;
377c99fb5f9SBaptiste Daroussin long *V_KMP_Table;
378c99fb5f9SBaptiste Daroussin long V_FindPosition = -1;
379c99fb5f9SBaptiste Daroussin
380c99fb5f9SBaptiste Daroussin if (P_StartPosition < 0)
381c99fb5f9SBaptiste Daroussin {
382c99fb5f9SBaptiste Daroussin V_StartPosition = s->i + P_StartPosition;
383c99fb5f9SBaptiste Daroussin }
384c99fb5f9SBaptiste Daroussin else
385c99fb5f9SBaptiste Daroussin {
386c99fb5f9SBaptiste Daroussin V_StartPosition = P_StartPosition;
387c99fb5f9SBaptiste Daroussin }
388c99fb5f9SBaptiste Daroussin V_HaystackLen = V_StartPosition + 1;
389c99fb5f9SBaptiste Daroussin if ( (V_HaystackLen >= P_NeedleLen) && (P_NeedleLen > 0) )
390c99fb5f9SBaptiste Daroussin {
391c99fb5f9SBaptiste Daroussin V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
392c99fb5f9SBaptiste Daroussin if (V_KMP_Table != NULL)
393c99fb5f9SBaptiste Daroussin {
394c99fb5f9SBaptiste Daroussin _utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
395c99fb5f9SBaptiste Daroussin
396c99fb5f9SBaptiste Daroussin V_FindPosition = _utstring_findR(s->d,
397c99fb5f9SBaptiste Daroussin V_HaystackLen,
398c99fb5f9SBaptiste Daroussin P_Needle,
399c99fb5f9SBaptiste Daroussin P_NeedleLen,
400c99fb5f9SBaptiste Daroussin V_KMP_Table);
401c99fb5f9SBaptiste Daroussin
402c99fb5f9SBaptiste Daroussin free(V_KMP_Table);
403c99fb5f9SBaptiste Daroussin }
404c99fb5f9SBaptiste Daroussin }
405c99fb5f9SBaptiste Daroussin
406c99fb5f9SBaptiste Daroussin return V_FindPosition;
407c99fb5f9SBaptiste Daroussin }
408c99fb5f9SBaptiste Daroussin /*******************************************************************************
409c99fb5f9SBaptiste Daroussin * end substring search functions *
410c99fb5f9SBaptiste Daroussin ******************************************************************************/
411c99fb5f9SBaptiste Daroussin
412c99fb5f9SBaptiste Daroussin #endif /* UTSTRING_H */
413