58 char buf[CX_PRINTF_SBO_SIZE]; |
59 char buf[CX_PRINTF_SBO_SIZE]; |
59 va_list ap2; |
60 va_list ap2; |
60 va_copy(ap2, ap); |
61 va_copy(ap2, ap); |
61 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); |
62 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); |
62 if (ret < 0) { |
63 if (ret < 0) { |
|
64 va_end(ap2); |
63 return ret; |
65 return ret; |
64 } else if (ret < CX_PRINTF_SBO_SIZE) { |
66 } else if (ret < CX_PRINTF_SBO_SIZE) { |
|
67 va_end(ap2); |
65 return (int) wfc(buf, 1, ret, stream); |
68 return (int) wfc(buf, 1, ret, stream); |
66 } else { |
69 } else { |
67 int len = ret + 1; |
70 int len = ret + 1; |
68 char *newbuf = malloc(len); |
71 char *newbuf = malloc(len); |
69 if (!newbuf) { |
72 if (!newbuf) { |
|
73 va_end(ap2); |
70 return -1; |
74 return -1; |
71 } |
75 } |
72 |
76 |
73 ret = vsnprintf(newbuf, len, fmt, ap2); |
77 ret = vsnprintf(newbuf, len, fmt, ap2); |
|
78 va_end(ap2); |
74 if (ret > 0) { |
79 if (ret > 0) { |
75 ret = (int) wfc(newbuf, 1, ret, stream); |
80 ret = (int) wfc(newbuf, 1, ret, stream); |
76 } |
81 } |
77 free(newbuf); |
82 free(newbuf); |
78 } |
83 } |
102 s.length = 0; |
106 s.length = 0; |
103 char buf[CX_PRINTF_SBO_SIZE]; |
107 char buf[CX_PRINTF_SBO_SIZE]; |
104 va_list ap2; |
108 va_list ap2; |
105 va_copy(ap2, ap); |
109 va_copy(ap2, ap); |
106 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); |
110 int ret = vsnprintf(buf, CX_PRINTF_SBO_SIZE, fmt, ap); |
107 if (ret > 0 && ret < CX_PRINTF_SBO_SIZE) { |
111 if (ret >= 0 && ret < CX_PRINTF_SBO_SIZE) { |
108 s.ptr = cxMalloc(a, ret + 1); |
112 s.ptr = cxMalloc(a, ret + 1); |
109 if (s.ptr) { |
113 if (s.ptr) { |
110 s.length = (size_t) ret; |
114 s.length = (size_t) ret; |
111 memcpy(s.ptr, buf, ret); |
115 memcpy(s.ptr, buf, ret); |
112 s.ptr[s.length] = '\0'; |
116 s.ptr[s.length] = '\0'; |
122 } else { |
126 } else { |
123 s.length = (size_t) ret; |
127 s.length = (size_t) ret; |
124 } |
128 } |
125 } |
129 } |
126 } |
130 } |
|
131 va_end(ap2); |
127 return s; |
132 return s; |
128 } |
133 } |
129 |
134 |
|
135 int cx_sprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, ... ) { |
|
136 va_list ap; |
|
137 va_start(ap, fmt); |
|
138 int ret = cx_vsprintf_a(alloc, str, len, fmt, ap); |
|
139 va_end(ap); |
|
140 return ret; |
|
141 } |
|
142 |
|
143 int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t len, const char *fmt, va_list ap) { |
|
144 va_list ap2; |
|
145 va_copy(ap2, ap); |
|
146 int ret = vsnprintf(*str, len, fmt, ap); |
|
147 if ((unsigned) ret >= len) { |
|
148 unsigned newlen = ret + 1; |
|
149 char *ptr = cxRealloc(alloc, *str, newlen); |
|
150 if (ptr) { |
|
151 int newret = vsnprintf(ptr, newlen, fmt, ap2); |
|
152 if (newret < 0) { |
|
153 cxFree(alloc, ptr); |
|
154 } else { |
|
155 *str = ptr; |
|
156 ret = newret; |
|
157 } |
|
158 } |
|
159 } |
|
160 va_end(ap2); |
|
161 return ret; |
|
162 } |
|
163 |
|
164 int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, ... ) { |
|
165 va_list ap; |
|
166 va_start(ap, fmt); |
|
167 int ret = cx_vsprintf_sa(alloc, buf, len, str, fmt, ap); |
|
168 va_end(ap); |
|
169 return ret; |
|
170 } |
|
171 |
|
172 int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t len, char **str, const char *fmt, va_list ap) { |
|
173 va_list ap2; |
|
174 va_copy(ap2, ap); |
|
175 int ret = vsnprintf(buf, len, fmt, ap); |
|
176 *str = buf; |
|
177 if ((unsigned) ret >= len) { |
|
178 unsigned newlen = ret + 1; |
|
179 char *ptr = cxMalloc(alloc, newlen); |
|
180 if (ptr) { |
|
181 int newret = vsnprintf(ptr, newlen, fmt, ap2); |
|
182 if (newret < 0) { |
|
183 cxFree(alloc, ptr); |
|
184 } else { |
|
185 *str = ptr; |
|
186 ret = newret; |
|
187 } |
|
188 } |
|
189 } |
|
190 va_end(ap2); |
|
191 return ret; |
|
192 } |