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