/* Checked size_t computations. */
#include "xsize.h"
+#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
+# include "isnan.h"
+# include "isnanl.h"
+# if HAVE_LONG_DOUBLE
+# include "printf-frexp.h"
+# include "printf-frexpl.h"
+# endif
+#endif
+
#if HAVE_WCHAR_T
# if HAVE_WCSLEN
# define local_wcslen wcslen
abort ();
}
}
+#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
+ else if (dp->conversion == 'a' || dp->conversion == 'A')
+ {
+ arg_type type = a.arg[dp->arg_index].type;
+ int flags = dp->flags;
+ int has_width;
+ size_t width;
+ int has_precision;
+ size_t precision;
+ size_t tmp_length;
+ CHAR_T tmpbuf[700];
+ CHAR_T *tmp;
+ CHAR_T *pad_ptr;
+ CHAR_T *p;
+
+ has_width = 0;
+ width = 0;
+ if (dp->width_start != dp->width_end)
+ {
+ if (dp->width_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->width_arg_index].a.a_int;
+ if (arg < 0)
+ {
+ /* "A negative field width is taken as a '-' flag
+ followed by a positive field width." */
+ flags |= FLAG_LEFT;
+ width = (unsigned int) (-arg);
+ }
+ else
+ width = arg;
+ }
+ else
+ {
+ const CHAR_T *digitp = dp->width_start;
+
+ do
+ width = xsum (xtimes (width, 10), *digitp++ - '0');
+ while (digitp != dp->width_end);
+ }
+ has_width = 1;
+ }
+
+ has_precision = 0;
+ precision = 0;
+ if (dp->precision_start != dp->precision_end)
+ {
+ if (dp->precision_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->precision_arg_index].a.a_int;
+ /* "A negative precision is taken as if the precision
+ were omitted." */
+ if (arg >= 0)
+ {
+ precision = arg;
+ has_precision = 1;
+ }
+ }
+ else
+ {
+ const CHAR_T *digitp = dp->precision_start + 1;
+
+ precision = 0;
+ while (digitp != dp->precision_end)
+ precision = xsum (xtimes (precision, 10), *digitp++ - '0');
+ has_precision = 1;
+ }
+ }
+
+ /* Allocate a temporary buffer of sufficient size. */
+# if HAVE_LONG_DOUBLE
+ if (type == TYPE_LONGDOUBLE)
+ tmp_length =
+ (unsigned int) ((LDBL_DIG + 1)
+ * 0.831 /* decimal -> hexadecimal */
+ )
+ + 1; /* turn floor into ceil */
+ else
+# endif
+ tmp_length =
+ (unsigned int) ((DBL_DIG + 1)
+ * 0.831 /* decimal -> hexadecimal */
+ )
+ + 1; /* turn floor into ceil */
+ if (tmp_length < precision)
+ tmp_length = precision;
+ /* Account for sign, decimal point etc. */
+ tmp_length = xsum (tmp_length, 12);
+
+ if (tmp_length < width)
+ tmp_length = width;
+
+ tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
+
+ if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
+ tmp = tmpbuf;
+ else
+ {
+ size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
+
+ if (size_overflow_p (tmp_memsize))
+ /* Overflow, would lead to out of memory. */
+ goto out_of_memory;
+ tmp = (CHAR_T *) malloc (tmp_memsize);
+ if (tmp == NULL)
+ /* Out of memory. */
+ goto out_of_memory;
+ }
+
+ pad_ptr = NULL;
+ p = tmp;
+# if HAVE_LONG_DOUBLE
+ if (type == TYPE_LONGDOUBLE)
+ {
+ long double arg = a.arg[dp->arg_index].a.a_longdouble;
+
+ if (isnanl (arg))
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+ }
+ else
+ {
+ *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+ }
+ }
+ else
+ {
+ int sign = 0;
+
+ if (arg < 0.0L)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ else if (arg == 0.0L)
+ {
+ /* Distinguish 0.0L and -0.0L. */
+ static long double plus_zero = 0.0L;
+ long double arg_mem = arg;
+ if (memcmp (&plus_zero, &arg_mem, sizeof (long double)) != 0)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ }
+
+ if (sign < 0)
+ *p++ = '-';
+ else if (flags & FLAG_SHOWSIGN)
+ *p++ = '+';
+ else if (flags & FLAG_SPACE)
+ *p++ = ' ';
+
+ if (x > 0.0L && x + x == x)
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+ }
+ else
+ {
+ *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+ }
+ }
+ else
+ {
+ int exponent;
+ long double mantissa;
+
+ if (x > 0.0L)
+ mantissa = printf_frexpl (arg, &exponent);
+ else
+ {
+ exponent = 0;
+ mantissa = 0.0L;
+ }
+
+ if (has_precision
+ && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
+ {
+ /* Round the mantissa. */
+ long double tail = arg;
+ size_t q;
+
+ for (q = precision; ; q--)
+ {
+ int digit = (int) tail;
+ tail -= digit;
+ if (q == 0)
+ {
+ if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
+ tail = 1 - tail;
+ else
+ tail = 0;
+ break;
+ }
+ tail *= 16.0L;
+ }
+ if (tail > 0.0L)
+ for (q = precision; q > 0; q--)
+ tail *= 0.0625L;
+ arg += tail;
+ }
+
+ *p++ = '0';
+ *p++ = dp->conversion - 'A' + 'X';
+ pad_ptr = p;
+ {
+ int digit;
+
+ digit = (int) arg;
+ arg -= digit;
+ *p++ = '0' + digit;
+ if ((flags & FLAG_ALT) || arg > 0.0L)
+ {
+ *p++ = '.';
+ /* This loop terminates because we assume
+ that FLT_RADIX is a power of 2. */
+ while (arg > 0.0L)
+ {
+ arg *= 16.0L;
+ digit = (int) arg;
+ arg -= digit;
+ *p++ = digit
+ + (digit < 10
+ ? '0'
+ : dp->conversion - 10);
+ if (precision > 0)
+ precision--;
+ }
+ while (precision > 0)
+ {
+ *p++ = '0';
+ precision--;
+ }
+ }
+ }
+ *p++ = dp->conversion - 'A' + 'P';
+# if WIDE_CHAR_VERSION
+ {
+ static const wchar_t decimal_format[] =
+ { '%', 'd', '\0' };
+ SNPRINTF (p, 6 + 1, decimal_format, exponent);
+ }
+# else
+ sprintf (p, "%d", exponent);
+# endif
+ while (*p != '\0')
+ p++;
+ }
+ }
+ }
+ else
+# endif
+ {
+ double arg = a.arg[dp->arg_index].a.a_double;
+
+ if (isnan (arg))
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+ }
+ else
+ {
+ *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+ }
+ }
+ else
+ {
+ int sign = 0;
+
+ if (arg < 0.0)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ else if (arg == 0.0)
+ {
+ /* Distinguish 0.0 and -0.0. */
+ static double plus_zero = 0.0;
+ double arg_mem = arg;
+ if (memcmp (&plus_zero, &arg_mem, sizeof (double)) != 0)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ }
+
+ if (sign < 0)
+ *p++ = '-';
+ else if (flags & FLAG_SHOWSIGN)
+ *p++ = '+';
+ else if (flags & FLAG_SPACE)
+ *p++ = ' ';
+
+ if (x > 0.0 && x + x == x)
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+ }
+ else
+ {
+ *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+ }
+ }
+ else
+ {
+ int exponent;
+ double mantissa;
+
+ if (x > 0.0)
+ mantissa = printf_frexp (arg, &exponent);
+ else
+ {
+ exponent = 0;
+ mantissa = 0.0;
+ }
+
+ if (has_precision
+ && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
+ {
+ /* Round the mantissa. */
+ double tail = arg;
+ size_t q;
+
+ for (q = precision; ; q--)
+ {
+ int digit = (int) tail;
+ tail -= digit;
+ if (q == 0)
+ {
+ if (digit & 1 ? tail >= 0.5 : tail > 0.5)
+ tail = 1 - tail;
+ else
+ tail = 0;
+ break;
+ }
+ tail *= 16.0;
+ }
+ if (tail > 0.0)
+ for (q = precision; q > 0; q--)
+ tail *= 0.0625;
+ arg += tail;
+ }
+
+ *p++ = '0';
+ *p++ = dp->conversion - 'A' + 'X';
+ pad_ptr = p;
+ {
+ int digit;
+
+ digit = (int) arg;
+ arg -= digit;
+ *p++ = '0' + digit;
+ if ((flags & FLAG_ALT) || arg > 0.0)
+ {
+ *p++ = '.';
+ /* This loop terminates because we assume
+ that FLT_RADIX is a power of 2. */
+ while (arg > 0.0)
+ {
+ arg *= 16.0;
+ digit = (int) arg;
+ arg -= digit;
+ *p++ = digit
+ + (digit < 10
+ ? '0'
+ : dp->conversion - 10);
+ if (precision > 0)
+ precision--;
+ }
+ while (precision > 0)
+ {
+ *p++ = '0';
+ precision--;
+ }
+ }
+ }
+ *p++ = dp->conversion - 'A' + 'P';
+# if WIDE_CHAR_VERSION
+ {
+ static const wchar_t decimal_format[] =
+ { '%', 'd', '\0' };
+ SNPRINTF (p, 6 + 1, decimal_format, exponent);
+ }
+# else
+ sprintf (p, "%d", exponent);
+# endif
+ while (*p != '\0')
+ p++;
+ }
+ }
+ }
+ /* The generated string now extends from tmp to p, with the
+ zero padding insertion point being at pad_ptr. */
+ if (has_width && p - tmp < width)
+ {
+ size_t pad = width - (p - tmp);
+ CHAR_T *end = p + pad;
+
+ if (flags & FLAG_LEFT)
+ {
+ /* Pad with spaces on the right. */
+ for (; pad > 0; pad--)
+ *p++ = ' ';
+ }
+ else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+ {
+ /* Pad with zeroes. */
+ CHAR_T *q = end;
+
+ while (p > pad_ptr)
+ *--q = *--p;
+ for (; pad > 0; pad--)
+ *p++ = '0';
+ }
+ else
+ {
+ /* Pad with spaces on the left. */
+ CHAR_T *q = end;
+
+ while (p > tmp)
+ *--q = *--p;
+ for (; pad > 0; pad--)
+ *p++ = ' ';
+ }
+
+ p = end;
+ }
+
+ {
+ size_t count = p - tmp;
+
+ if (count >= tmp_length)
+ /* tmp_length was incorrectly calculated - fix the
+ code above! */
+ abort ();
+
+ /* Make room for the result. */
+ if (count >= allocated - length)
+ {
+ size_t n = xsum (length, count);
+
+ ENSURE_ALLOCATION (n);
+ }
+
+ /* Append the result. */
+ memcpy (result + length, tmp, count * sizeof (CHAR_T));
+ if (tmp != tmpbuf)
+ free (tmp);
+ length += count;
+ }
+ }
+#endif
else
{
arg_type type = a.arg[dp->arg_index].type;
--- /dev/null
+# printf.m4 serial 1
+dnl Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Test whether the *printf family of functions supports the 'j', 'z', 't',
+dnl 'L' size specifiers. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_sizes_c99.
+
+AC_DEFUN([gl_PRINTF_SIZES_C99],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+ AC_REQUIRE([gt_TYPE_LONGDOUBLE])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether printf supports size specifiers as in C99],
+ [gl_cv_func_printf_sizes_c99],
+ [
+ AC_TRY_RUN([
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+# include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+# include <inttypes.h>
+#endif
+static char buf[100];
+int main ()
+{
+#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
+ buf[0] = '\0';
+ if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0
+ || strcmp (buf, "12345671 33") != 0)
+ return 1;
+#endif
+ buf[0] = '\0';
+ if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0
+ || strcmp (buf, "12345672 33") != 0)
+ return 1;
+ buf[0] = '\0';
+ if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
+ || strcmp (buf, "12345673 33") != 0)
+ return 1;
+#if HAVE_LONG_DOUBLE
+ buf[0] = '\0';
+ if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
+ || strcmp (buf, "1.5 33") != 0)
+ return 1;
+#endif
+ return 0;
+}], [gl_cv_func_printf_sizes_c99=yes], [gl_cv_func_printf_sizes_c99=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ dnl Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_printf_sizes_c99="guessing yes";;
+ dnl Guess yes on FreeBSD >= 5.
+ freebsd[1-4]*) gl_cv_func_printf_sizes_c99="guessing no";;
+ freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
+ dnl Gusss yes on MacOS X >= 10.3.
+ darwin[1-6].*) gl_cv_func_printf_sizes_c99="guessing no";;
+ darwin*) gl_cv_func_printf_sizes_c99="guessing yes";;
+ dnl Guess yes on Solaris >= 2.10.
+ solaris2.[0-9]*) gl_cv_func_printf_sizes_c99="guessing no";;
+ solaris*) gl_cv_func_printf_sizes_c99="guessing yes";;
+ dnl Guess yes on NetBSD >= 3.
+ netbsd[1-2]*) gl_cv_func_printf_sizes_c99="guessing no";;
+ netbsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
+ dnl If we don't know, assume the worst.
+ *) gl_cv_func_printf_sizes_c99="guessing no";;
+ esac
+changequote([,])dnl
+ ])
+ ])
+])
+
+dnl Test whether the *printf family of functions supports the 'a' and 'A'
+dnl conversion specifier for hexadecimal output of floating-point numbers.
+dnl (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_directive_a.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
+ [gl_cv_func_printf_directive_a],
+ [
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+ if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
+ || strcmp (buf, "0x1.922p+1 33") != 0)
+ return 1;
+ if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
+ || strcmp (buf, "-0X1.922P+1 33") != 0)
+ return 1;
+ return 0;
+}], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ dnl Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_printf_directive_a="guessing yes";;
+ dnl Guess yes on FreeBSD >= 5.
+ freebsd[1-4]*) gl_cv_func_printf_directive_a="guessing no";;
+ freebsd* | kfreebsd*) gl_cv_func_printf_directive_a="guessing yes";;
+ dnl Gusss yes on MacOS X >= 10.3.
+ darwin[1-6].*) gl_cv_func_printf_directive_a="guessing no";;
+ darwin*) gl_cv_func_printf_directive_a="guessing yes";;
+ dnl If we don't know, assume the worst.
+ *) gl_cv_func_printf_directive_a="guessing no";;
+ esac
+changequote([,])dnl
+ ])
+ ])
+])
+
+dnl Test whether the *printf family of functions supports the %n format
+dnl directive. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_directive_n.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether printf supports the 'n' directive],
+ [gl_cv_func_printf_directive_n],
+ [
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+ int count = -1;
+ if (sprintf (buf, "%d %n", 123, &count, 33, 44, 55) < 0
+ || strcmp (buf, "123 ") != 0
+ || count != 4)
+ return 1;
+ return 0;
+}], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ hpux*) gl_cv_func_printf_directive_n="guessing no";;
+ *) gl_cv_func_printf_directive_n="guessing yes";;
+ esac
+changequote([,])dnl
+ ])
+ ])
+])
+
+dnl Test whether the *printf family of functions supports POSIX/XSI format
+dnl strings with positions. (POSIX:2001)
+dnl Result is gl_cv_func_printf_positions.
+
+AC_DEFUN([gl_PRINTF_POSITIONS],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
+ [gl_cv_func_printf_positions],
+ [
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+/* The string "%2$d %1$d", with dollar characters protected from the shell's
+ dollar expansion (possibly an autoconf bug). */
+static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
+static char buf[100];
+int main ()
+{
+ sprintf (buf, format, 33, 55);
+ return (strcmp (buf, "55 33") != 0);
+}], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ netbsd*) gl_cv_func_printf_positions="guessing no";;
+ beos*) gl_cv_func_printf_positions="guessing no";;
+ mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
+ *) gl_cv_func_printf_positions="guessing yes";;
+ esac
+changequote([,])dnl
+ ])
+ ])
+])
+
+dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
+dnl Result is ac_cv_func_snprintf.
+
+AC_DEFUN([gl_SNPRINTF_PRESENCE],
+[
+ AC_CHECK_FUNCS_ONCE([snprintf])
+])
+
+dnl Test whether the string produced by the snprintf function is always NUL
+dnl terminated. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_snprintf_truncation_c99.
+
+AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
+ [gl_cv_func_snprintf_truncation_c99],
+ [
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+ strcpy (buf, "ABCDEF");
+ snprintf (buf, 3, "%d %d", 4567, 89);
+ if (memcmp (buf, "45\0DEF", 6) != 0)
+ return 1;
+ return 0;
+}], [gl_cv_func_snprintf_truncation_c99=yes], [gl_cv_func_snprintf_truncation_c99=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ dnl Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on FreeBSD >= 5.
+ freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Gusss yes on MacOS X >= 10.3.
+ darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on Solaris >= 2.6.
+ solaris2.[0-5]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ solaris*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on AIX >= 4.
+ aix[1-3]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ aix*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on HP-UX >= 11.
+ hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ hpux*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on IRIX >= 6.5.
+ irix6.5) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on OSF/1 >= 5.
+ osf[3-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ osf*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on NetBSD >= 3.
+ netbsd[1-2]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ netbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl Guess yes on BeOS.
+ beos*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
+ dnl If we don't know, assume the worst.
+ *) gl_cv_func_snprintf_truncation_c99="guessing no";;
+ esac
+changequote([,])dnl
+ ])
+ ])
+])
+
+dnl Test whether the return value of the snprintf function is the number
+dnl of bytes (excluding the terminating NUL) that would have been produced
+dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_printf_retval_c99.
+
+AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
+ [gl_cv_func_printf_retval_c99],
+ [
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+ strcpy (buf, "ABCDEF");
+ if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
+ return 1;
+ return 0;
+}], [gl_cv_func_printf_retval_c99=yes], [gl_cv_func_printf_retval_c99=no],
+ [
+changequote(,)dnl
+ case "$host_os" in
+ dnl Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl Guess yes on FreeBSD >= 5.
+ freebsd[1-4]*) gl_cv_func_printf_retval_c99="guessing no";;
+ freebsd* | kfreebsd*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl Gusss yes on MacOS X >= 10.3.
+ darwin[1-6].*) gl_cv_func_printf_retval_c99="guessing no";;
+ darwin*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl Guess yes on Solaris >= 2.6.
+ solaris2.[0-5]*) gl_cv_func_printf_retval_c99="guessing no";;
+ solaris*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl Guess yes on AIX >= 4.
+ aix[1-3]*) gl_cv_func_printf_retval_c99="guessing no";;
+ aix*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl Guess yes on NetBSD >= 3.
+ netbsd[1-2]*) gl_cv_func_printf_retval_c99="guessing no";;
+ netbsd*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl Guess yes on BeOS.
+ beos*) gl_cv_func_printf_retval_c99="guessing yes";;
+ dnl If we don't know, assume the worst.
+ *) gl_cv_func_printf_retval_c99="guessing no";;
+ esac
+changequote([,])dnl
+ ])
+ ])
+])
+
+dnl The results of these tests on various platforms are:
+dnl
+dnl 1 = gl_PRINTF_SIZES_C99
+dnl 2 = gl_PRINTF_DIRECTIVE_A
+dnl 3 = gl_PRINTF_DIRECTIVE_N
+dnl 4 = gl_PRINTF_POSITIONS
+dnl 5 = gl_SNPRINTF_PRESENCE
+dnl 6 = gl_SNPRINTF_TRUNCATION_C99
+dnl 7 = gl_SNPRINTF_RETVAL_C99
+dnl
+dnl 1 = checking whether printf supports size specifiers as in C99...
+dnl 2 = checking whether printf supports the 'a' and 'A' directives...
+dnl 3 = checking whether printf supports the 'n' directive...
+dnl 4 = checking whether printf supports POSIX/XSI format strings with positions...
+dnl 5 = checking for snprintf...
+dnl 6 = checking whether snprintf truncates the result as in C99...
+dnl 7 = checking whether snprintf returns a byte count as in C99...
+dnl
+dnl . = yes, # = no.
+dnl
+dnl 1 2 3 4 5 6 7
+dnl glibc 2.3.6 . . . . . . .
+dnl FreeBSD 5.4, 6.1 . . . . . . .
+dnl MacOS X 10.3.9 . . . . . . .
+dnl Cygwin 2007 . # . . . . .
+dnl Solaris 10 . # . . . . .
+dnl Solaris 2.6 ... 9 # # . . . . .
+dnl Solaris 2.5.1 # # . . # # #
+dnl AIX 4.3.2, 5.1 # # . . . . .
+dnl HP-UX 11.31 . # . . . . #
+dnl HP-UX 11.00, 11.11, 11.23 # # . . . . #
+dnl HP-UX 10.20 # # # ? . ? #
+dnl IRIX 6.5 # # . . . . #
+dnl OSF/1 5.1 # # . . . . #
+dnl OSF/1 4.0d # # . . # # #
+dnl NetBSD 3.0 . # . # . . .
+dnl BeOS # # . # . . .
+dnl mingw # # . # . # #