Coverage Report

Created: 2025-08-29 06:59

/src/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
4.66k
#define utstring_reserve(s,amt)                            \
53
4.66k
do {                                                       \
54
4.66k
  if (((s)->n - (s)->i) < (size_t)(amt)) {                 \
55
4.66k
     (s)->d = (char*)realloc((s)->d, (s)->n + amt);        \
56
4.66k
     if ((s)->d == NULL) oom();                            \
57
4.66k
     else {(s)->n += amt;                                  \
58
4.66k
     if ((s)->pd) *((s)->pd) = (s)->d;}                    \
59
4.66k
  }                                                        \
60
4.66k
} while(0)
61
62
3.56k
#define utstring_init(s)                                   \
63
3.56k
do {                                                       \
64
3.56k
  (s)->n = 0; (s)->i = 0; (s)->d = NULL;                   \
65
3.56k
  utstring_reserve(s,128);                                 \
66
3.56k
  (s)->d[0] = '\0'; \
67
3.56k
} while(0)
68
69
3.49k
#define utstring_done(s)                                   \
70
3.49k
do {                                                       \
71
3.49k
  if ((s)->d != NULL) free((s)->d);                        \
72
3.49k
  (s)->n = 0;                                              \
73
3.49k
} while(0)
74
75
3.49k
#define utstring_free(s)                                   \
76
3.49k
do {                                                       \
77
3.49k
  utstring_done(s);                                        \
78
3.49k
  free(s);                                                 \
79
3.49k
} while(0)
80
81
3.56k
#define utstring_new(s)                                    \
82
3.56k
do {                                                       \
83
3.56k
   s = (UT_string*)calloc(1, sizeof(UT_string));          \
84
3.56k
   if (!s) oom();                                          \
85
3.56k
   else utstring_init(s);                                  \
86
3.56k
} 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
67
#define utstring_body(s) ((s)->d)
122
123
4.69k
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124
4.69k
   int n;
125
4.69k
   va_list cp;
126
5.79k
   while (1) {
127
#ifdef _WIN32
128
      cp = ap;
129
#else
130
5.79k
      va_copy(cp, ap);
131
5.79k
#endif
132
5.79k
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133
5.79k
      va_end(cp);
134
135
5.79k
      if ((n > -1) && (n < (int)(s->n-s->i))) {
136
4.69k
        s->i += n;
137
4.69k
        return;
138
4.69k
      }
139
140
      /* Else try again with more space. */
141
1.09k
      if (n > -1) utstring_reserve(s,n+1); /* exact */
142
0
      else utstring_reserve(s,(s->n)*2);   /* 2x */
143
1.09k
   }
144
4.69k
}
ucl_parser.c:utstring_printf_va
Line
Count
Source
123
2.66k
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124
2.66k
   int n;
125
2.66k
   va_list cp;
126
3.72k
   while (1) {
127
#ifdef _WIN32
128
      cp = ap;
129
#else
130
3.72k
      va_copy(cp, ap);
131
3.72k
#endif
132
3.72k
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133
3.72k
      va_end(cp);
134
135
3.72k
      if ((n > -1) && (n < (int)(s->n-s->i))) {
136
2.66k
        s->i += n;
137
2.66k
        return;
138
2.66k
      }
139
140
      /* Else try again with more space. */
141
1.05k
      if (n > -1) utstring_reserve(s,n+1); /* exact */
142
0
      else utstring_reserve(s,(s->n)*2);   /* 2x */
143
1.05k
   }
144
2.66k
}
ucl_util.c:utstring_printf_va
Line
Count
Source
123
2.02k
_UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
124
2.02k
   int n;
125
2.02k
   va_list cp;
126
2.06k
   while (1) {
127
#ifdef _WIN32
128
      cp = ap;
129
#else
130
2.06k
      va_copy(cp, ap);
131
2.06k
#endif
132
2.06k
      n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp);
133
2.06k
      va_end(cp);
134
135
2.06k
      if ((n > -1) && (n < (int)(s->n-s->i))) {
136
2.02k
        s->i += n;
137
2.02k
        return;
138
2.02k
      }
139
140
      /* Else try again with more space. */
141
38
      if (n > -1) utstring_reserve(s,n+1); /* exact */
142
0
      else utstring_reserve(s,(s->n)*2);   /* 2x */
143
38
   }
144
2.02k
}
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
1.32k
_UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {
151
1.32k
   va_list ap;
152
1.32k
   va_start(ap,fmt);
153
1.32k
   utstring_printf_va(s,fmt,ap);
154
1.32k
   va_end(ap);
155
1.32k
}
ucl_parser.c:utstring_printf
Line
Count
Source
150
1.32k
_UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {
151
1.32k
   va_list ap;
152
1.32k
   va_start(ap,fmt);
153
1.32k
   utstring_printf_va(s,fmt,ap);
154
1.32k
   va_end(ap);
155
1.32k
}
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 */