X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Futils.c;h=c83e4499f5e8c6f432a4a36462208c67e369e74e;hp=36542c9e3e6a3e201f2b0825f2d34373629f3dc2;hb=0ff9eb47276f0485e7c2e1ed1c014c7c82758ef7;hpb=83b0e389400b03110402d1408fd9610988ba3419 diff --git a/src/utils.c b/src/utils.c index 36542c9e..c83e4499 100644 --- a/src/utils.c +++ b/src/utils.c @@ -61,6 +61,11 @@ so, delete this exception statement from your version. */ #endif #include #include +#ifdef WGET_USE_STDARG +# include +#else +# include +#endif /* For TIOCGWINSZ and friends: */ #ifdef HAVE_SYS_IOCTL_H @@ -176,6 +181,52 @@ sepstring (const char *s) return res; } +#ifdef WGET_USE_STDARG +# define VA_START(args, arg1) va_start (args, arg1) +#else +# define VA_START(args, ignored) va_start (args) +#endif + +/* Like sprintf, but allocates a string of sufficient size with malloc + and returns it. GNU libc has a similar function named asprintf, + which requires the pointer to the string to be passed. */ + +char * +aprintf (const char *fmt, ...) +{ + /* This function is implemented using vsnprintf, which we provide + for the systems that don't have it. Therefore, it should be 100% + portable. */ + + int size = 32; + char *str = xmalloc (size); + + while (1) + { + int n; + va_list args; + + /* See log_vprintf_internal for explanation why it's OK to rely + on the return value of vsnprintf. */ + + VA_START (args, fmt); + n = vsnprintf (str, size, fmt, args); + va_end (args); + + /* If the printing worked, return the string. */ + if (n > -1 && n < size) + return str; + + /* Else try again with a larger buffer. */ + if (n > -1) /* C99 */ + size = n + 1; /* precisely what is needed */ + else + size <<= 1; /* twice the old size */ + str = xrealloc (str, size); + } + return NULL; /* unreached */ +} + /* Return pointer to a static char[] buffer in which zero-terminated string-representation of TM (in form hh:mm:ss) is printed.