diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-09-21 17:59:41 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-09-21 17:59:41 +0000 |
commit | 3aa04aa72c6ec522395919d528dfce6a92b0de98 (patch) | |
tree | a1746cfbdb1cc7c83f9252ee5a0edd11e7329ad1 | |
parent | a95547030959517c5817b815b4b6bfdc9b955326 (diff) | |
download | netpbm-mirror-3aa04aa72c6ec522395919d528dfce6a92b0de98.tar.gz netpbm-mirror-3aa04aa72c6ec522395919d528dfce6a92b0de98.tar.xz netpbm-mirror-3aa04aa72c6ec522395919d528dfce6a92b0de98.zip |
part of Release 10.36.0
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@64 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r-- | lib/util/vasprintf.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/util/vasprintf.c b/lib/util/vasprintf.c new file mode 100644 index 00000000..a4229c70 --- /dev/null +++ b/lib/util/vasprintf.c @@ -0,0 +1,59 @@ +#define _GNU_SOURCE + /* Due to conditional compilation, this is GNU source only if the C library + is GNU. + */ +#include <stdlib.h> +#include <string.h> + +#include "nstring.h" + +#ifdef __GNUC__ + #define HAVE_VASPRINTF 1 +#else + #define HAVE_VASPRINTF 0 +#endif + +void +vasprintfN(const char ** const resultP, + const char * const format, + va_list varargs) { + + char * result; + +#if HAVE_VASPRINTF + vasprintf(&result, format, varargs); + + if (result == NULL) + *resultP = strsol; + else + *resultP = result; +#else + /* We have a big compromise here. To do this right, without a + huge amount of work, we need to go through the variable + arguments twice: once to determine how much memory to allocate, + and once to format the string. On some machines, you can + simply make two copies of the va_list variable in normal C + fashion, but on others you need va_copy, which is a relatively + recent invention. In particular, the simple va_list copy + failed on an AMD64 Gcc Linux system in March 2006. + + So instead, we just allocate 4K and truncate or waste as + necessary. + */ + size_t const allocSize = 4096; + result = malloc(allocSize); + + if (result == NULL) + *resultP = strsol; + else { + size_t realLen; + + vsnprintfN(result, allocSize, format, varargs, &realLen); + + if (realLen >= allocSize) + strcpy(result + allocSize - 15, "<<<TRUNCATED"); + + *resultP = result; + } +#endif +} |