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