Skip to content

Commit aa7f8ac

Browse files
committed
[c89stringutils/c89stringutils_string_extras.h] Re-add asprintf
1 parent 8beb386 commit aa7f8ac

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

c89stringutils/c89stringutils_string_extras.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,91 @@ size_t strerrorlen_s(errno_t errnum)
259259

260260
#endif /* !HAVE_STRERRORLEN_S */
261261

262+
#ifndef HAVE_ASPRINTF
263+
264+
extern int vasprintf(char **str, const char *fmt, va_list ap);
265+
266+
extern int asprintf(char **str, const char *fmt, ...);
267+
268+
#ifdef C89STRINGUTILS_IMPLEMENTATION
269+
270+
#define HAVE_ASPRINTF
271+
272+
#include <errno.h>
273+
#include <limits.h> /* for INT_MAX */
274+
#include <stdlib.h>
275+
276+
#ifndef VA_COPY
277+
# if defined(HAVE_VA_COPY) || defined(va_copy)
278+
# define VA_COPY(dest, src) va_copy(dest, src)
279+
# else
280+
# ifdef HAVE___VA_COPY
281+
# define VA_COPY(dest, src) __va_copy(dest, src)
282+
# else
283+
# define VA_COPY(dest, src) (dest) = (src)
284+
# endif
285+
# endif
286+
#endif /* ! VA_COPY */
287+
288+
#define INIT_SZ 128
289+
290+
extern int
291+
vasprintf(char **str, const char *fmt, va_list ap)
292+
{
293+
int ret;
294+
va_list ap2;
295+
char *string, *newstr;
296+
size_t len;
297+
298+
if ((string = (char*) malloc(INIT_SZ)) == NULL)
299+
goto fail;
300+
301+
VA_COPY(ap2, ap);
302+
ret = vsnprintf(string, INIT_SZ, fmt, ap2);
303+
va_end(ap2);
304+
if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
305+
*str = string;
306+
} else if (ret == INT_MAX || ret < 0) { /* Bad length */
307+
free(string);
308+
goto fail;
309+
} else { /* bigger than initial, realloc allowing for nul */
310+
len = (size_t)ret + 1;
311+
if ((newstr = (char*)realloc(string, len)) == NULL) {
312+
free(string);
313+
goto fail;
314+
}
315+
VA_COPY(ap2, ap);
316+
ret = vsnprintf(newstr, len, fmt, ap2);
317+
va_end(ap2);
318+
if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */
319+
free(newstr);
320+
goto fail;
321+
}
322+
*str = newstr;
323+
}
324+
return ret;
325+
326+
fail:
327+
*str = NULL;
328+
errno = ENOMEM;
329+
return -1;
330+
}
331+
332+
extern int asprintf(char **str, const char *fmt, ...)
333+
{
334+
va_list ap;
335+
int ret;
336+
337+
*str = NULL;
338+
va_start(ap, fmt);
339+
ret = vasprintf(str, fmt, ap);
340+
va_end(ap);
341+
342+
return ret;
343+
}
344+
345+
#endif /* C89STRINGUTILS_IMPLEMENTATION */
346+
347+
#endif /* !HAVE_ASPRINTF */
348+
262349
#endif /* ! C89STRINGUTILS_STRING_EXTRAS_H */

0 commit comments

Comments
 (0)