xref: /freebsd/contrib/libucl/uthash/utstring.h (revision 98e0ffaefb0f241cda3a72395d3be04192ae0d47)
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