Coverage Report

Created: 2026-02-04 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libucl/uthash/utstring.h
Line
Count
Source
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
65.0k
#define utstring_reserve(s,amt)                            \
53
65.0k
do {                                                       \
54
65.0k
  if (((s)->n - (s)->i) < (size_t)(amt)) {                 \
55
65.0k
     (s)->d = (char*)realloc((s)->d, (s)->n + amt);        \
56
65.0k
     if ((s)->d == NULL) oom();                            \
57
65.0k
     else {(s)->n += amt;                                  \
58
65.0k
     if ((s)->pd) *((s)->pd) = (s)->d;}                    \
59
65.0k
  }                                                        \
60
65.0k
} while(0)
61
62
50.3k
#define utstring_init(s)                                   \
63
50.3k
do {                                                       \
64
50.3k
  (s)->n = 0; (s)->i = 0; (s)->d = NULL;                   \
65
50.3k
  utstring_reserve(s,128);                                 \
66
50.3k
  (s)->d[0] = '\0'; \
67
50.3k
} while(0)
68
69
49.4k
#define utstring_done(s)                                   \
70
49.4k
do {                                                       \
71
49.4k
  if ((s)->d != NULL) free((s)->d);                        \
72
49.4k
  (s)->n = 0;                                              \
73
49.4k
} while(0)
74
75
49.4k
#define utstring_free(s)                                   \
76
49.4k
do {                                                       \
77
49.4k
  utstring_done(s);                                        \
78
49.4k
  free(s);                                                 \
79
49.4k
} while(0)
80
81
50.3k
#define utstring_new(s)                                    \
82
50.3k
do {                                                       \
83
50.3k
   s = (UT_string*)calloc(1, sizeof(UT_string));          \
84
50.3k
   if (!s) oom();                                          \
85
50.3k
   else utstring_init(s);                                  \
86
50.3k
} while(0)
87
88
#define utstring_renew(s)                                  \
89
do {                                                       \
90
   if (s) {                                                \
91
     utstring_clear(s);                                    \
92
   } else {                                                \
93
     utstring_new(s);                                      \
94
   }                                                       \
95
} while(0)
96
97
#define utstring_clear(s)                                  \
98
do {                                                       \
99
  (s)->i = 0;                                              \
100
  (s)->d[0] = '\0';                                        \
101
} while(0)
102
103
#define utstring_bincpy(s,b,l)                             \
104
do {                                                       \
105
  utstring_reserve((s),(l)+1);                               \
106
  if (l) memcpy(&(s)->d[(s)->i], b, l);                    \
107
  (s)->i += l;                                               \
108
  (s)->d[(s)->i]='\0';                                         \
109
} while(0)
110
111
#define utstring_concat(dst,src)                                 \
112
do {                                                             \
113
  utstring_reserve((dst),((src)->i)+1);                          \
114
  if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
115
  (dst)->i += (src)->i;                                          \
116
  (dst)->d[(dst)->i]='\0';                                       \
117
} while(0)
118
119
#define utstring_len(s) ((unsigned)((s)->i))
120
121
843
#define utstring_body(s) ((s)->d)
122
123
65.6k
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124
65.6k
   int n;
125
65.6k
   va_list cp;
126
80.3k
   while (1) {
127
#ifdef _WIN32
128
      cp = ap;
129
#else
130
80.3k
      va_copy(cp, ap);
131
80.3k
#endif
132
80.3k
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133
80.3k
      va_end(cp);
134
135
80.3k
      if ((n > -1) && (n < (int)(s->n-s->i))) {
136
65.6k
        s->i += n;
137
65.6k
        return;
138
65.6k
      }
139
140
      /* Else try again with more space. */
141
14.7k
      if (n > -1) utstring_reserve(s,n+1); /* exact */
142
0
      else utstring_reserve(s,(s->n)*2);   /* 2x */
143
14.7k
   }
144
65.6k
}
ucl_parser.c:utstring_printf_va
Line
Count
Source
123
46.0k
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124
46.0k
   int n;
125
46.0k
   va_list cp;
126
60.1k
   while (1) {
127
#ifdef _WIN32
128
      cp = ap;
129
#else
130
60.1k
      va_copy(cp, ap);
131
60.1k
#endif
132
60.1k
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133
60.1k
      va_end(cp);
134
135
60.1k
      if ((n > -1) && (n < (int)(s->n-s->i))) {
136
46.0k
        s->i += n;
137
46.0k
        return;
138
46.0k
      }
139
140
      /* Else try again with more space. */
141
14.0k
      if (n > -1) utstring_reserve(s,n+1); /* exact */
142
      else utstring_reserve(s,(s->n)*2);   /* 2x */
143
14.0k
   }
144
46.0k
}
ucl_util.c:utstring_printf_va
Line
Count
Source
123
19.5k
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124
19.5k
   int n;
125
19.5k
   va_list cp;
126
20.1k
   while (1) {
127
#ifdef _WIN32
128
      cp = ap;
129
#else
130
20.1k
      va_copy(cp, ap);
131
20.1k
#endif
132
20.1k
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133
20.1k
      va_end(cp);
134
135
20.1k
      if ((n > -1) && (n < (int)(s->n-s->i))) {
136
19.5k
        s->i += n;
137
19.5k
        return;
138
19.5k
      }
139
140
      /* Else try again with more space. */
141
649
      if (n > -1) utstring_reserve(s,n+1); /* exact */
142
      else utstring_reserve(s,(s->n)*2);   /* 2x */
143
649
   }
144
19.5k
}
Unexecuted instantiation: ucl_msgpack.c:utstring_printf_va
Unexecuted instantiation: ucl_sexp.c:utstring_printf_va
Unexecuted instantiation: ucl_emitter_utils.c:utstring_printf_va
Unexecuted instantiation: ucl_hash.c:utstring_printf_va
Unexecuted instantiation: ucl_emitter.c:utstring_printf_va
145
#ifdef __GNUC__
146
/* support printf format checking (2=the format string, 3=start of varargs) */
147
static void utstring_printf(UT_string *s, const char *fmt, ...)
148
  __attribute__ (( format( printf, 2, 3) ));
149
#endif
150
20.2k
_UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {
151
20.2k
   va_list ap;
152
20.2k
   va_start(ap,fmt);
153
20.2k
   utstring_printf_va(s,fmt,ap);
154
20.2k
   va_end(ap);
155
20.2k
}
ucl_parser.c:utstring_printf
Line
Count
Source
150
20.2k
_UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {
151
20.2k
   va_list ap;
152
20.2k
   va_start(ap,fmt);
153
20.2k
   utstring_printf_va(s,fmt,ap);
154
   va_end(ap);
155
20.2k
}
Unexecuted instantiation: ucl_util.c:utstring_printf
Unexecuted instantiation: ucl_msgpack.c:utstring_printf
Unexecuted instantiation: ucl_sexp.c:utstring_printf
Unexecuted instantiation: ucl_emitter_utils.c:utstring_printf
Unexecuted instantiation: ucl_hash.c:utstring_printf
Unexecuted instantiation: ucl_emitter.c:utstring_printf
156
157
0
#define utstring_append_len(dst, src, len)                                    \
158
0
do {                                                                           \
159
0
    while ((dst)->n-(dst)->i <= (len)) utstring_reserve((dst),((dst)->n)*2);   \
160
0
    memcpy(&(dst)->d[(dst)->i], (src), (len));                                 \
161
0
    (dst)->i+=(len);                                                           \
162
0
    (dst)->d[(dst)->i]='\0';                                                   \
163
0
} while(0)
164
165
0
#define utstring_append_c(dst, c)                                             \
166
0
do {                                                                           \
167
0
    if ((dst)->n-(dst)->i < 2) utstring_reserve((dst),((dst)->n)*2);            \
168
0
    (dst)->d[(dst)->i++] = (c);                                                \
169
0
    (dst)->d[(dst)->i]='\0';                                                   \
170
0
} while(0)
171
172
/*******************************************************************************
173
 * begin substring search functions                                            *
174
 ******************************************************************************/
175
/* Build KMP table from left to right. */
176
_UNUSED_ static void _utstring_BuildTable(
177
    const char *P_Needle, 
178
    ssize_t P_NeedleLen, 
179
    long *P_KMP_Table)
180
0
{
181
0
    long i, j;
182
0
183
0
    i = 0;
184
0
    j = i - 1;
185
0
    P_KMP_Table[i] = j;
186
0
    while (i < P_NeedleLen)
187
0
    {
188
0
        while ( (j > -1) && (P_Needle[i] != P_Needle[j]) )
189
0
        {
190
0
           j = P_KMP_Table[j];
191
0
        }
192
0
        i++;
193
0
        j++;
194
0
        if (i < P_NeedleLen)
195
0
        {
196
0
            if (P_Needle[i] == P_Needle[j])
197
0
            {
198
0
                P_KMP_Table[i] = P_KMP_Table[j];
199
0
            }
200
0
            else
201
0
            {
202
0
                P_KMP_Table[i] = j;
203
0
            }
204
0
        }
205
0
        else
206
0
        {
207
0
            P_KMP_Table[i] = j;
208
0
        }
209
0
    }
210
0
211
0
    return;
212
0
}
Unexecuted instantiation: ucl_parser.c:_utstring_BuildTable
Unexecuted instantiation: ucl_util.c:_utstring_BuildTable
Unexecuted instantiation: ucl_msgpack.c:_utstring_BuildTable
Unexecuted instantiation: ucl_sexp.c:_utstring_BuildTable
Unexecuted instantiation: ucl_emitter_utils.c:_utstring_BuildTable
Unexecuted instantiation: ucl_hash.c:_utstring_BuildTable
Unexecuted instantiation: ucl_emitter.c:_utstring_BuildTable
213
214
215
/* Build KMP table from right to left. */
216
_UNUSED_ static void _utstring_BuildTableR(
217
    const char *P_Needle, 
218
    ssize_t P_NeedleLen, 
219
    long *P_KMP_Table)
220
0
{
221
0
    long i, j;
222
0
223
0
    i = P_NeedleLen - 1;
224
0
    j = i + 1;
225
0
    P_KMP_Table[i + 1] = j;
226
0
    while (i >= 0)
227
0
    {
228
0
        while ( (j < P_NeedleLen) && (P_Needle[i] != P_Needle[j]) )
229
0
        {
230
0
           j = P_KMP_Table[j + 1];
231
0
        }
232
0
        i--;
233
0
        j--;
234
0
        if (i >= 0)
235
0
        {
236
0
            if (P_Needle[i] == P_Needle[j])
237
0
            {
238
0
                P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
239
0
            }
240
0
            else
241
0
            {
242
0
                P_KMP_Table[i + 1] = j;
243
0
            }
244
0
        }
245
0
        else
246
0
        {
247
0
            P_KMP_Table[i + 1] = j;
248
0
        }
249
0
    }
250
0
251
0
    return;
252
0
}
Unexecuted instantiation: ucl_parser.c:_utstring_BuildTableR
Unexecuted instantiation: ucl_util.c:_utstring_BuildTableR
Unexecuted instantiation: ucl_msgpack.c:_utstring_BuildTableR
Unexecuted instantiation: ucl_sexp.c:_utstring_BuildTableR
Unexecuted instantiation: ucl_emitter_utils.c:_utstring_BuildTableR
Unexecuted instantiation: ucl_hash.c:_utstring_BuildTableR
Unexecuted instantiation: ucl_emitter.c:_utstring_BuildTableR
253
254
255
/* Search data from left to right. ( Multiple search mode. ) */
256
_UNUSED_ static long _utstring_find(
257
    const char *P_Haystack, 
258
    size_t P_HaystackLen, 
259
    const char *P_Needle, 
260
    size_t P_NeedleLen, 
261
    long *P_KMP_Table)
262
0
{
263
0
    long i, j;
264
0
    long V_FindPosition = -1;
265
0
266
0
    /* Search from left to right. */
267
0
    i = j = 0;
268
0
    while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) )
269
0
    {
270
0
        while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) )
271
0
        {
272
0
            i = P_KMP_Table[i];
273
0
        }
274
0
        i++;
275
0
        j++;
276
0
        if (i >= (int)P_NeedleLen)
277
0
        {
278
0
            /* Found. */
279
0
            V_FindPosition = j - i;
280
0
            break;
281
0
        }
282
0
    }
283
0
284
0
    return V_FindPosition;
285
0
}
Unexecuted instantiation: ucl_parser.c:_utstring_find
Unexecuted instantiation: ucl_util.c:_utstring_find
Unexecuted instantiation: ucl_msgpack.c:_utstring_find
Unexecuted instantiation: ucl_sexp.c:_utstring_find
Unexecuted instantiation: ucl_emitter_utils.c:_utstring_find
Unexecuted instantiation: ucl_hash.c:_utstring_find
Unexecuted instantiation: ucl_emitter.c:_utstring_find
286
287
288
/* Search data from right to left. ( Multiple search mode. ) */
289
_UNUSED_ static long _utstring_findR(
290
    const char *P_Haystack, 
291
    size_t P_HaystackLen, 
292
    const char *P_Needle, 
293
    size_t P_NeedleLen, 
294
    long *P_KMP_Table)
295
0
{
296
0
    long i, j;
297
0
    long V_FindPosition = -1;
298
0
299
0
    /* Search from right to left. */
300
0
    j = (P_HaystackLen - 1);
301
0
    i = (P_NeedleLen - 1);
302
0
    while ( (j >= 0) && (j >= i) )
303
0
    {
304
0
        while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) )
305
0
        {
306
0
            i = P_KMP_Table[i + 1];
307
0
        }
308
0
        i--;
309
0
        j--;
310
0
        if (i < 0)
311
0
        {
312
0
            /* Found. */
313
0
            V_FindPosition = j + 1;
314
0
            break;
315
0
        }
316
0
    }
317
0
318
0
    return V_FindPosition;
319
0
}
Unexecuted instantiation: ucl_parser.c:_utstring_findR
Unexecuted instantiation: ucl_util.c:_utstring_findR
Unexecuted instantiation: ucl_msgpack.c:_utstring_findR
Unexecuted instantiation: ucl_sexp.c:_utstring_findR
Unexecuted instantiation: ucl_emitter_utils.c:_utstring_findR
Unexecuted instantiation: ucl_hash.c:_utstring_findR
Unexecuted instantiation: ucl_emitter.c:_utstring_findR
320
321
322
/* Search data from left to right. ( One time search mode. ) */
323
_UNUSED_ static long utstring_find(
324
    UT_string *s, 
325
    long P_StartPosition,   /* Start from 0. -1 means last position. */
326
    const char *P_Needle, 
327
    ssize_t P_NeedleLen)
328
0
{
329
0
    long V_StartPosition;
330
0
    long V_HaystackLen;
331
0
    long *V_KMP_Table;
332
0
    long V_FindPosition = -1;
333
0
334
0
    if (P_StartPosition < 0)
335
0
    {
336
0
        V_StartPosition = s->i + P_StartPosition;
337
0
    }
338
0
    else
339
0
    {
340
0
        V_StartPosition = P_StartPosition;
341
0
    }
342
0
    V_HaystackLen = s->i - V_StartPosition;
343
0
    if ( (V_HaystackLen >= P_NeedleLen) && (P_NeedleLen > 0) )
344
0
    {
345
0
        V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
346
0
        if (V_KMP_Table != NULL)
347
0
        {
348
0
            _utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
349
0
350
0
            V_FindPosition = _utstring_find(s->d + V_StartPosition, 
351
0
                                            V_HaystackLen, 
352
0
                                            P_Needle, 
353
0
                                            P_NeedleLen, 
354
0
                                            V_KMP_Table);
355
0
            if (V_FindPosition >= 0)
356
0
            {
357
0
                V_FindPosition += V_StartPosition;
358
0
            }
359
0
360
0
            free(V_KMP_Table);
361
0
        }
362
0
    }
363
0
364
0
    return V_FindPosition;
365
0
}
Unexecuted instantiation: ucl_parser.c:utstring_find
Unexecuted instantiation: ucl_util.c:utstring_find
Unexecuted instantiation: ucl_msgpack.c:utstring_find
Unexecuted instantiation: ucl_sexp.c:utstring_find
Unexecuted instantiation: ucl_emitter_utils.c:utstring_find
Unexecuted instantiation: ucl_hash.c:utstring_find
Unexecuted instantiation: ucl_emitter.c:utstring_find
366
367
368
/* Search data from right to left. ( One time search mode. ) */
369
_UNUSED_ static long utstring_findR(
370
    UT_string *s, 
371
    long P_StartPosition,   /* Start from 0. -1 means last position. */
372
    const char *P_Needle, 
373
    ssize_t P_NeedleLen)
374
0
{
375
0
    long V_StartPosition;
376
0
    long V_HaystackLen;
377
0
    long *V_KMP_Table;
378
0
    long V_FindPosition = -1;
379
0
380
0
    if (P_StartPosition < 0)
381
0
    {
382
0
        V_StartPosition = s->i + P_StartPosition;
383
0
    }
384
0
    else
385
0
    {
386
0
        V_StartPosition = P_StartPosition;
387
0
    }
388
0
    V_HaystackLen = V_StartPosition + 1;
389
0
    if ( (V_HaystackLen >= P_NeedleLen) && (P_NeedleLen > 0) )
390
0
    {
391
0
        V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
392
0
        if (V_KMP_Table != NULL)
393
0
        {
394
0
            _utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
395
0
396
0
            V_FindPosition = _utstring_findR(s->d, 
397
0
                                             V_HaystackLen, 
398
0
                                             P_Needle, 
399
0
                                             P_NeedleLen, 
400
0
                                             V_KMP_Table);
401
0
402
0
            free(V_KMP_Table);
403
0
        }
404
0
    }
405
0
406
0
    return V_FindPosition;
407
0
}
Unexecuted instantiation: ucl_parser.c:utstring_findR
Unexecuted instantiation: ucl_util.c:utstring_findR
Unexecuted instantiation: ucl_msgpack.c:utstring_findR
Unexecuted instantiation: ucl_sexp.c:utstring_findR
Unexecuted instantiation: ucl_emitter_utils.c:utstring_findR
Unexecuted instantiation: ucl_hash.c:utstring_findR
Unexecuted instantiation: ucl_emitter.c:utstring_findR
408
/*******************************************************************************
409
 * end substring search functions                                              *
410
 ******************************************************************************/
411
412
#endif /* UTSTRING_H */