autoconf_vsnprintf.c
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#define USE_FMT_1_3 0
static int my_autoconf(const char *fmt, ...)
{
va_list ap;
char buf[1] = "";
int ret = -1;
va_start(ap, fmt);
ret = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return (ret);
}
#if 0
static char *my_fmt0(const char *fmt, ...)
{
char *tmp = NULL;
va_list ap;
int ret = -1;
size_t lim = 32;
char buf[1024] = "";
va_start(ap, fmt);
ret = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
printf("fmt0\n");
printf("%d\n", ret);
if (ret == -1)
return (NULL);
if ((size_t)ret > lim)
return (NULL);
if (!(tmp = malloc(ret + 1))) exit(1);
va_start(ap, fmt);
ret = vsnprintf(tmp, ret + 1, fmt, ap);
va_end(ap);
printf("%d\n", ret);
printf("\n");
return (tmp);
}
static char *my_fmt1(const char *fmt, ...)
{
char *tmp = NULL;
va_list ap;
int ret = -1;
size_t sz = 1;
printf("fmt1\n");
if (!(tmp = malloc(sz))) exit(1);
tmp[0] = 0;
va_start(ap, fmt);
while ((ret = vsnprintf(tmp, sz, fmt, ap)) == -1)
{
printf("%d - %lu\n", ret, (unsigned long)strlen(tmp));
sz <<= 1;
if (!(tmp = realloc(tmp, sz))) exit(1);
if (sz > 1024) exit(2);
va_end(ap);
va_start(ap, fmt);
}
va_end(ap);
if (sz <= (unsigned)ret)
{
sz = ret + 1;
if (!(tmp = realloc(tmp, sz))) exit(1);
va_start(ap, fmt);
ret = vsnprintf(tmp, sz, fmt, ap);
va_end(ap);
}
printf("%d\n", ret);
printf("\n");
return (tmp);
}
#endif
#if USE_FMT_1_3
static char *myx_vfmt(size_t lim, const char *fmt, va_list ap)
{
char *tmp = NULL;
va_list nap;
int ret = -1;
va_copy(nap, ap);
ret = vsnprintf(NULL, 0, fmt, nap);
va_end(nap);
printf("%d\n", ret);
if (ret == -1)
return (NULL);
if ((size_t)ret > lim)
return (NULL);
if (!(tmp = malloc(ret + 1)))
{
errno = ENOMEM;
return (NULL);
}
ret = vsnprintf(tmp, ret + 1, fmt, ap);
printf("%d\n", ret);
printf("\n");
return (tmp);
}
static char *my_fmt2(const char *fmt, ...)
{
va_list ap;
char *ret = NULL;
va_start(ap, fmt);
ret = myx_vfmt(32, fmt, ap);
va_end(ap);
return (ret);
}
static char *my_vfmt(const char *fmt, va_list ap)
{ return (myx_vfmt(32, fmt, ap)); }
static char *my_fmt3(const char *fmt, ...)
{
va_list ap;
char *ret = NULL;
va_start(ap, fmt);
ret = my_vfmt(fmt, ap);
va_end(ap);
return (ret);
}
#endif
int main(void)
{
#if 0
char *tmp0 = my_fmt0("a b %d c d", 42);
char *tmp1 = my_fmt1("a b %d c d", 42);
#if USE_FMT_1_3
char *tmp2 = my_fmt2("a b %d c d", 42);
char *tmp3 = my_fmt3("a b %d c d", 42);
#endif
if (tmp0) puts(tmp0); free(tmp0);
if (tmp1) puts(tmp1); free(tmp1);
#if USE_FMT_1_3
if (tmp2) puts(tmp2); free(tmp2);
if (tmp3) puts(tmp3); free(tmp3);
#endif
#endif
if (my_autoconf("12") == -1)
puts("1");
else
puts("0");
return 0;
}