abstractaccelerator/opene906/smart_run/tests/lib/newlib_wrap/vasprintf.c

66 lines
1.2 KiB
C

#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHUNKSIZE (256)
int vasprintf(char **ret, const char *fmt, va_list ap)
{
size_t chunks;
size_t buflen;
char * buf;
int len;
chunks = ((strlen(fmt) + 1) / CHUNKSIZE) + 1;
buflen = chunks * CHUNKSIZE;
*ret = NULL;
for (;;) {
buf = malloc(buflen);
if (buf == NULL) {
return -ENOMEM;
}
len = vsnprintf(buf, buflen, fmt, ap);
if (len >= 0 && (size_t)len < buflen - 1) {
break;
}
free(buf);
buflen = (++chunks) * CHUNKSIZE;
/*
* len >= 0 is required for vsnprintf implementations that
* return -1 for insufficient buffer
*/
if (len >= 0 && buflen <= (size_t)len) {
buflen = len + 1;
}
}
if (len > 0 && buf != NULL) {
// strip the string
*ret = strdup(buf);
if (*ret != NULL)
free(buf);
else
*ret = buf;
}
return len;
}
int asprintf(char **buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i = vasprintf(buf, fmt, args);
va_end(args);
return i;
}