1 | /*␊ |
2 | Copyright (c) 2008-2012, Troy D. Hanson http://uthash.sourceforge.net␊ |
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 | * see http://uthash.sourceforge.net/utstring␊ |
26 | */␊ |
27 | #ifndef UTSTRING_H␊ |
28 | #define UTSTRING_H␊ |
29 | ␊ |
30 | #define UTSTRING_VERSION 1.9.6␊ |
31 | ␊ |
32 | #ifdef __GNUC__␊ |
33 | #define _UNUSED_ __attribute__ ((__unused__)) ␊ |
34 | #else␊ |
35 | #define _UNUSED_ ␊ |
36 | #endif␊ |
37 | ␊ |
38 | #include "libsaio.h"␊ |
39 | #ifndef utstring_oom␊ |
40 | #define utstring_oom() longjmp(THIS_BUF_ERROR,-1)␊ |
41 | #endif␊ |
42 | #ifndef __utstring_malloc␊ |
43 | #define __utstring_malloc(sz) pool_alloc(THIS_POOL,sz) /* malloc fcn */␊ |
44 | #endif␊ |
45 | #ifndef __utstring_free␊ |
46 | #define __utstring_free(ptr) pool_free(THIS_POOL,ptr) /* free fcn */␊ |
47 | #endif␊ |
48 | #ifndef __utarray_realloc␊ |
49 | #define __utarray_realloc(ptr,sz) pool_realloc(THIS_POOL,nmemb,sz) /* realloc fcn */␊ |
50 | #endif␊ |
51 | #ifndef __utarray_calloc␊ |
52 | #define __utarray_calloc(n,sz) pool_calloc(THIS_POOL,n,sz) /* calloc fcn */␊ |
53 | #endif␊ |
54 | typedef struct {␊ |
55 | char *d;␊ |
56 | size_t n; /* allocd size */␊ |
57 | size_t i; /* index of first unused byte */␊ |
58 | } UT_string;␊ |
59 | ␊ |
60 | #define utstring_reserve(s,amt) \␊ |
61 | do { \␊ |
62 | if (((s)->n - (s)->i) < (size_t)(amt)) { \␊ |
63 | (s)->d = (char*)__utarray_realloc((s)->d, (s)->n + amt); \␊ |
64 | if ((s)->d == NULL) utstring_oom(); \␊ |
65 | (s)->n += amt; \␊ |
66 | } \␊ |
67 | } while(0)␊ |
68 | ␊ |
69 | #define utstring_init(s) \␊ |
70 | do { \␊ |
71 | (s)->n = 0; (s)->i = 0; (s)->d = NULL; \␊ |
72 | utstring_reserve(s,100); \␊ |
73 | (s)->d[0] = '\0'; \␊ |
74 | } while(0)␊ |
75 | ␊ |
76 | #define utstring_done(s) \␊ |
77 | do { \␊ |
78 | if ((s)->d != NULL) __utstring_free((s)->d); \␊ |
79 | (s)->n = 0; \␊ |
80 | } while(0)␊ |
81 | ␊ |
82 | #define utstring_free(s) \␊ |
83 | do { \␊ |
84 | utstring_done(s); \␊ |
85 | __utstring_free(s); \␊ |
86 | } while(0)␊ |
87 | ␊ |
88 | #define utstring_new(s) \␊ |
89 | do { \␊ |
90 | s = (UT_string*)__utarray_calloc(sizeof(UT_string),1); \␊ |
91 | if (!s) utstring_oom(); \␊ |
92 | utstring_init(s); \␊ |
93 | } while(0)␊ |
94 | ␊ |
95 | #define utstring_renew(s) \␊ |
96 | do { \␊ |
97 | if (s) { \␊ |
98 | utstring_clear(s); \␊ |
99 | } else { \␊ |
100 | utstring_new(s); \␊ |
101 | } \␊ |
102 | } while(0)␊ |
103 | ␊ |
104 | #define utstring_clear(s) \␊ |
105 | do { \␊ |
106 | (s)->i = 0; \␊ |
107 | (s)->d[0] = '\0'; \␊ |
108 | } while(0)␊ |
109 | ␊ |
110 | #define utstring_bincpy(s,b,l) \␊ |
111 | do { \␊ |
112 | utstring_reserve((s),(l)+1); \␊ |
113 | if (l) memcpy(&(s)->d[(s)->i], b, l); \␊ |
114 | (s)->i += l; \␊ |
115 | (s)->d[(s)->i]='\0'; \␊ |
116 | } while(0)␊ |
117 | ␊ |
118 | #define utstring_concat(dst,src) \␊ |
119 | do { \␊ |
120 | utstring_reserve((dst),((src)->i)+1); \␊ |
121 | if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \␊ |
122 | (dst)->i += (src)->i; \␊ |
123 | (dst)->d[(dst)->i]='\0'; \␊ |
124 | } while(0)␊ |
125 | ␊ |
126 | #define utstring_len(s) ((unsigned)((s)->i))␊ |
127 | ␊ |
128 | #define utstring_body(s) ((s)->d)␊ |
129 | ␊ |
130 | _UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {␊ |
131 | int n;␊ |
132 | va_list cp;␊ |
133 | while (1) {␊ |
134 | #ifdef _WIN32␊ |
135 | cp = ap;␊ |
136 | #else␊ |
137 | va_copy(cp, ap);␊ |
138 | #endif␊ |
139 | n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp); // vsnprintf not implemented yet in chameleon␊ |
140 | va_end(cp);␊ |
141 | ␊ |
142 | if ((n > -1) && (n < (int)(s->n-s->i))) {␊ |
143 | s->i += n;␊ |
144 | return;␊ |
145 | }␊ |
146 | ␊ |
147 | /* Else try again with more space. */␊ |
148 | if (n > -1) utstring_reserve(s,n+1); /* exact */␊ |
149 | else utstring_reserve(s,(s->n)*2); /* 2x */␊ |
150 | }␊ |
151 | }␊ |
152 | _UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) {␊ |
153 | va_list ap;␊ |
154 | va_start(ap,fmt);␊ |
155 | utstring_printf_va(s,fmt,ap);␊ |
156 | va_end(ap);␊ |
157 | }␊ |
158 | ␊ |
159 | #endif /* UTSTRING_H */␊ |
160 | |