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 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 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. */ 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. */ 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. ) */ 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. ) */ 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. ) */ 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. ) */ 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