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