*printf-posix: Detect a bug on Solaris 10/x86.
[gnulib.git] / m4 / printf.m4
1 # printf.m4 serial 39
2 dnl Copyright (C) 2003, 2007-2010 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 dnl Test whether the *printf family of functions supports the 'j', 'z', 't',
8 dnl 'L' size specifiers. (ISO C99, POSIX:2001)
9 dnl Result is gl_cv_func_printf_sizes_c99.
10
11 AC_DEFUN([gl_PRINTF_SIZES_C99],
12 [
13   AC_REQUIRE([AC_PROG_CC])
14   AC_REQUIRE([gl_AC_HEADER_STDINT_H])
15   AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
16   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
17   AC_CACHE_CHECK([whether printf supports size specifiers as in C99],
18     [gl_cv_func_printf_sizes_c99],
19     [
20       AC_RUN_IFELSE(
21         [AC_LANG_SOURCE([[
22 #include <stddef.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #if HAVE_STDINT_H_WITH_UINTMAX
27 # include <stdint.h>
28 #endif
29 #if HAVE_INTTYPES_H_WITH_UINTMAX
30 # include <inttypes.h>
31 #endif
32 static char buf[100];
33 int main ()
34 {
35 #if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
36   buf[0] = '\0';
37   if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0
38       || strcmp (buf, "12345671 33") != 0)
39     return 1;
40 #endif
41   buf[0] = '\0';
42   if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0
43       || strcmp (buf, "12345672 33") != 0)
44     return 1;
45   buf[0] = '\0';
46   if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
47       || strcmp (buf, "12345673 33") != 0)
48     return 1;
49   buf[0] = '\0';
50   if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
51       || strcmp (buf, "1.5 33") != 0)
52     return 1;
53   return 0;
54 }]])],
55         [gl_cv_func_printf_sizes_c99=yes],
56         [gl_cv_func_printf_sizes_c99=no],
57         [
58 changequote(,)dnl
59          case "$host_os" in
60                                  # Guess yes on glibc systems.
61            *-gnu*)               gl_cv_func_printf_sizes_c99="guessing yes";;
62                                  # Guess yes on FreeBSD >= 5.
63            freebsd[1-4]*)        gl_cv_func_printf_sizes_c99="guessing no";;
64            freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
65                                  # Guess yes on MacOS X >= 10.3.
66            darwin[1-6].*)        gl_cv_func_printf_sizes_c99="guessing no";;
67            darwin*)              gl_cv_func_printf_sizes_c99="guessing yes";;
68                                  # Guess yes on OpenBSD >= 3.9.
69            openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
70                                  gl_cv_func_printf_sizes_c99="guessing no";;
71            openbsd*)             gl_cv_func_printf_sizes_c99="guessing yes";;
72                                  # Guess yes on Solaris >= 2.10.
73            solaris2.[0-9]*)      gl_cv_func_printf_sizes_c99="guessing no";;
74            solaris*)             gl_cv_func_printf_sizes_c99="guessing yes";;
75                                  # Guess yes on NetBSD >= 3.
76            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
77                                  gl_cv_func_printf_sizes_c99="guessing no";;
78            netbsd*)              gl_cv_func_printf_sizes_c99="guessing yes";;
79                                  # If we don't know, assume the worst.
80            *)                    gl_cv_func_printf_sizes_c99="guessing no";;
81          esac
82 changequote([,])dnl
83         ])
84     ])
85 ])
86
87 dnl Test whether the *printf family of functions supports 'long double'
88 dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
89 dnl Result is gl_cv_func_printf_long_double.
90
91 AC_DEFUN([gl_PRINTF_LONG_DOUBLE],
92 [
93   AC_REQUIRE([AC_PROG_CC])
94   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
95   AC_CACHE_CHECK([whether printf supports 'long double' arguments],
96     [gl_cv_func_printf_long_double],
97     [
98       AC_RUN_IFELSE(
99         [AC_LANG_SOURCE([[
100 #include <stdio.h>
101 #include <string.h>
102 static char buf[10000];
103 int main ()
104 {
105   buf[0] = '\0';
106   if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0
107       || strcmp (buf, "1.750000 33") != 0)
108     return 1;
109   buf[0] = '\0';
110   if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0
111       || strcmp (buf, "1.750000e+00 33") != 0)
112     return 1;
113   buf[0] = '\0';
114   if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0
115       || strcmp (buf, "1.75 33") != 0)
116     return 1;
117   return 0;
118 }]])],
119         [gl_cv_func_printf_long_double=yes],
120         [gl_cv_func_printf_long_double=no],
121         [
122 changequote(,)dnl
123          case "$host_os" in
124            beos*)        gl_cv_func_printf_long_double="guessing no";;
125            mingw* | pw*) gl_cv_func_printf_long_double="guessing no";;
126            *)            gl_cv_func_printf_long_double="guessing yes";;
127          esac
128 changequote([,])dnl
129         ])
130     ])
131 ])
132
133 dnl Test whether the *printf family of functions supports infinite and NaN
134 dnl 'double' arguments and negative zero arguments in the %f, %e, %g
135 dnl directives. (ISO C99, POSIX:2001)
136 dnl Result is gl_cv_func_printf_infinite.
137
138 AC_DEFUN([gl_PRINTF_INFINITE],
139 [
140   AC_REQUIRE([AC_PROG_CC])
141   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
142   AC_CACHE_CHECK([whether printf supports infinite 'double' arguments],
143     [gl_cv_func_printf_infinite],
144     [
145       AC_RUN_IFELSE(
146         [AC_LANG_SOURCE([[
147 #include <stdio.h>
148 #include <string.h>
149 static int
150 strisnan (const char *string, size_t start_index, size_t end_index)
151 {
152   if (start_index < end_index)
153     {
154       if (string[start_index] == '-')
155         start_index++;
156       if (start_index + 3 <= end_index
157           && memcmp (string + start_index, "nan", 3) == 0)
158         {
159           start_index += 3;
160           if (start_index == end_index
161               || (string[start_index] == '(' && string[end_index - 1] == ')'))
162             return 1;
163         }
164     }
165   return 0;
166 }
167 static int
168 have_minus_zero ()
169 {
170   static double plus_zero = 0.0;
171   double minus_zero = - plus_zero;
172   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
173 }
174 static char buf[10000];
175 static double zero = 0.0;
176 int main ()
177 {
178   if (sprintf (buf, "%f", 1.0 / 0.0) < 0
179       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
180     return 1;
181   if (sprintf (buf, "%f", -1.0 / 0.0) < 0
182       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
183     return 1;
184   if (sprintf (buf, "%f", zero / zero) < 0
185       || !strisnan (buf, 0, strlen (buf)))
186     return 1;
187   if (sprintf (buf, "%e", 1.0 / 0.0) < 0
188       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
189     return 1;
190   if (sprintf (buf, "%e", -1.0 / 0.0) < 0
191       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
192     return 1;
193   if (sprintf (buf, "%e", zero / zero) < 0
194       || !strisnan (buf, 0, strlen (buf)))
195     return 1;
196   if (sprintf (buf, "%g", 1.0 / 0.0) < 0
197       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
198     return 1;
199   if (sprintf (buf, "%g", -1.0 / 0.0) < 0
200       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
201     return 1;
202   if (sprintf (buf, "%g", zero / zero) < 0
203       || !strisnan (buf, 0, strlen (buf)))
204     return 1;
205   /* This test fails on HP-UX 10.20.  */
206   if (have_minus_zero ())
207     if (sprintf (buf, "%g", - zero) < 0
208         || strcmp (buf, "-0") != 0)
209     return 1;
210   return 0;
211 }]])],
212         [gl_cv_func_printf_infinite=yes],
213         [gl_cv_func_printf_infinite=no],
214         [
215 changequote(,)dnl
216          case "$host_os" in
217                                  # Guess yes on glibc systems.
218            *-gnu*)               gl_cv_func_printf_infinite="guessing yes";;
219                                  # Guess yes on FreeBSD >= 6.
220            freebsd[1-5]*)        gl_cv_func_printf_infinite="guessing no";;
221            freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";;
222                                  # Guess yes on MacOS X >= 10.3.
223            darwin[1-6].*)        gl_cv_func_printf_infinite="guessing no";;
224            darwin*)              gl_cv_func_printf_infinite="guessing yes";;
225                                  # Guess yes on HP-UX >= 11.
226            hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
227            hpux*)                gl_cv_func_printf_infinite="guessing yes";;
228                                  # Guess yes on NetBSD >= 3.
229            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
230                                  gl_cv_func_printf_infinite="guessing no";;
231            netbsd*)              gl_cv_func_printf_infinite="guessing yes";;
232                                  # Guess yes on BeOS.
233            beos*)                gl_cv_func_printf_infinite="guessing yes";;
234                                  # If we don't know, assume the worst.
235            *)                    gl_cv_func_printf_infinite="guessing no";;
236          esac
237 changequote([,])dnl
238         ])
239     ])
240 ])
241
242 dnl Test whether the *printf family of functions supports infinite and NaN
243 dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
244 dnl Result is gl_cv_func_printf_infinite_long_double.
245
246 AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
247 [
248   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
249   AC_REQUIRE([AC_PROG_CC])
250   AC_REQUIRE([gl_BIGENDIAN])
251   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
252   dnl The user can set or unset the variable gl_printf_safe to indicate
253   dnl that he wishes a safe handling of non-IEEE-754 'long double' values.
254   if test -n "$gl_printf_safe"; then
255     AC_DEFINE([CHECK_PRINTF_SAFE], [1],
256       [Define if you wish *printf() functions that have a safe handling of
257        non-IEEE-754 'long double' values.])
258   fi
259   case "$gl_cv_func_printf_long_double" in
260     *yes)
261       AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments],
262         [gl_cv_func_printf_infinite_long_double],
263         [
264           AC_RUN_IFELSE(
265             [AC_LANG_SOURCE([[
266 ]GL_NOCRASH[
267 #include <float.h>
268 #include <stdio.h>
269 #include <string.h>
270 static int
271 strisnan (const char *string, size_t start_index, size_t end_index)
272 {
273   if (start_index < end_index)
274     {
275       if (string[start_index] == '-')
276         start_index++;
277       if (start_index + 3 <= end_index
278           && memcmp (string + start_index, "nan", 3) == 0)
279         {
280           start_index += 3;
281           if (start_index == end_index
282               || (string[start_index] == '(' && string[end_index - 1] == ')'))
283             return 1;
284         }
285     }
286   return 0;
287 }
288 static char buf[10000];
289 static long double zeroL = 0.0L;
290 int main ()
291 {
292   nocrash_init();
293   if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0
294       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
295     return 1;
296   if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0
297       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
298     return 1;
299   if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
300       || !strisnan (buf, 0, strlen (buf)))
301     return 1;
302   if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0
303       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
304     return 1;
305   if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0
306       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
307     return 1;
308   if (sprintf (buf, "%Le", zeroL / zeroL) < 0
309       || !strisnan (buf, 0, strlen (buf)))
310     return 1;
311   if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0
312       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
313     return 1;
314   if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0
315       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
316     return 1;
317   if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
318       || !strisnan (buf, 0, strlen (buf)))
319     return 1;
320 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
321 /* Representation of an 80-bit 'long double' as an initializer for a sequence
322    of 'unsigned int' words.  */
323 # ifdef WORDS_BIGENDIAN
324 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
325      { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
326        ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
327        (unsigned int) (mantlo) << 16                                        \
328      }
329 # else
330 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
331      { mantlo, manthi, exponent }
332 # endif
333   { /* Quiet NaN.  */
334     static union { unsigned int word[4]; long double value; } x =
335       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
336     if (sprintf (buf, "%Lf", x.value) < 0
337         || !strisnan (buf, 0, strlen (buf)))
338       return 1;
339     if (sprintf (buf, "%Le", x.value) < 0
340         || !strisnan (buf, 0, strlen (buf)))
341       return 1;
342     if (sprintf (buf, "%Lg", x.value) < 0
343         || !strisnan (buf, 0, strlen (buf)))
344       return 1;
345   }
346   {
347     /* Signalling NaN.  */
348     static union { unsigned int word[4]; long double value; } x =
349       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
350     if (sprintf (buf, "%Lf", x.value) < 0
351         || !strisnan (buf, 0, strlen (buf)))
352       return 1;
353     if (sprintf (buf, "%Le", x.value) < 0
354         || !strisnan (buf, 0, strlen (buf)))
355       return 1;
356     if (sprintf (buf, "%Lg", x.value) < 0
357         || !strisnan (buf, 0, strlen (buf)))
358       return 1;
359   }
360   { /* Pseudo-NaN.  */
361     static union { unsigned int word[4]; long double value; } x =
362       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
363     if (sprintf (buf, "%Lf", x.value) < 0
364         || !strisnan (buf, 0, strlen (buf)))
365       return 1;
366     if (sprintf (buf, "%Le", x.value) < 0
367         || !strisnan (buf, 0, strlen (buf)))
368       return 1;
369     if (sprintf (buf, "%Lg", x.value) < 0
370         || !strisnan (buf, 0, strlen (buf)))
371       return 1;
372   }
373   { /* Pseudo-Infinity.  */
374     static union { unsigned int word[4]; long double value; } x =
375       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
376     if (sprintf (buf, "%Lf", x.value) < 0
377         || !strisnan (buf, 0, strlen (buf)))
378       return 1;
379     if (sprintf (buf, "%Le", x.value) < 0
380         || !strisnan (buf, 0, strlen (buf)))
381       return 1;
382     if (sprintf (buf, "%Lg", x.value) < 0
383         || !strisnan (buf, 0, strlen (buf)))
384       return 1;
385   }
386   { /* Pseudo-Zero.  */
387     static union { unsigned int word[4]; long double value; } x =
388       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
389     if (sprintf (buf, "%Lf", x.value) < 0
390         || !strisnan (buf, 0, strlen (buf)))
391       return 1;
392     if (sprintf (buf, "%Le", x.value) < 0
393         || !strisnan (buf, 0, strlen (buf)))
394       return 1;
395     if (sprintf (buf, "%Lg", x.value) < 0
396         || !strisnan (buf, 0, strlen (buf)))
397       return 1;
398   }
399   { /* Unnormalized number.  */
400     static union { unsigned int word[4]; long double value; } x =
401       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
402     if (sprintf (buf, "%Lf", x.value) < 0
403         || !strisnan (buf, 0, strlen (buf)))
404       return 1;
405     if (sprintf (buf, "%Le", x.value) < 0
406         || !strisnan (buf, 0, strlen (buf)))
407       return 1;
408     if (sprintf (buf, "%Lg", x.value) < 0
409         || !strisnan (buf, 0, strlen (buf)))
410       return 1;
411   }
412   { /* Pseudo-Denormal.  */
413     static union { unsigned int word[4]; long double value; } x =
414       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
415     if (sprintf (buf, "%Lf", x.value) < 0
416         || !strisnan (buf, 0, strlen (buf)))
417       return 1;
418     if (sprintf (buf, "%Le", x.value) < 0
419         || !strisnan (buf, 0, strlen (buf)))
420       return 1;
421     if (sprintf (buf, "%Lg", x.value) < 0
422         || !strisnan (buf, 0, strlen (buf)))
423       return 1;
424   }
425 #endif
426   return 0;
427 }]])],
428             [gl_cv_func_printf_infinite_long_double=yes],
429             [gl_cv_func_printf_infinite_long_double=no],
430             [
431 changequote(,)dnl
432              case "$host_cpu" in
433                                      # Guess no on ia64, x86_64, i386.
434                ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";;
435                *)
436                  case "$host_os" in
437                                          # Guess yes on glibc systems.
438                    *-gnu*)               gl_cv_func_printf_infinite_long_double="guessing yes";;
439                                          # Guess yes on FreeBSD >= 6.
440                    freebsd[1-5]*)        gl_cv_func_printf_infinite_long_double="guessing no";;
441                    freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";;
442                                          # Guess yes on HP-UX >= 11.
443                    hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";;
444                    hpux*)                gl_cv_func_printf_infinite_long_double="guessing yes";;
445                                          # If we don't know, assume the worst.
446                    *)                    gl_cv_func_printf_infinite_long_double="guessing no";;
447                  esac
448                  ;;
449              esac
450 changequote([,])dnl
451             ])
452         ])
453       ;;
454     *)
455       gl_cv_func_printf_infinite_long_double="irrelevant"
456       ;;
457   esac
458 ])
459
460 dnl Test whether the *printf family of functions supports the 'a' and 'A'
461 dnl conversion specifier for hexadecimal output of floating-point numbers.
462 dnl (ISO C99, POSIX:2001)
463 dnl Result is gl_cv_func_printf_directive_a.
464
465 AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
466 [
467   AC_REQUIRE([AC_PROG_CC])
468   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
469   AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
470     [gl_cv_func_printf_directive_a],
471     [
472       AC_RUN_IFELSE(
473         [AC_LANG_SOURCE([[
474 #include <stdio.h>
475 #include <string.h>
476 static char buf[100];
477 int main ()
478 {
479   if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
480       || (strcmp (buf, "0x1.922p+1 33") != 0
481           && strcmp (buf, "0x3.244p+0 33") != 0
482           && strcmp (buf, "0x6.488p-1 33") != 0
483           && strcmp (buf, "0xc.91p-2 33") != 0))
484     return 1;
485   if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
486       || (strcmp (buf, "-0X1.922P+1 33") != 0
487           && strcmp (buf, "-0X3.244P+0 33") != 0
488           && strcmp (buf, "-0X6.488P-1 33") != 0
489           && strcmp (buf, "-0XC.91P-2 33") != 0))
490     return 1;
491   /* This catches a FreeBSD 6.1 bug: it doesn't round.  */
492   if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
493       || (strcmp (buf, "0x1.83p+0 33") != 0
494           && strcmp (buf, "0x3.05p-1 33") != 0
495           && strcmp (buf, "0x6.0ap-2 33") != 0
496           && strcmp (buf, "0xc.14p-3 33") != 0))
497     return 1;
498   /* This catches a FreeBSD 6.1 bug.  See
499      <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
500   if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0
501       || buf[0] == '0')
502     return 1;
503   /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug.  */
504   if (sprintf (buf, "%.1a", 1.999) < 0
505       || (strcmp (buf, "0x1.0p+1") != 0
506           && strcmp (buf, "0x2.0p+0") != 0
507           && strcmp (buf, "0x4.0p-1") != 0
508           && strcmp (buf, "0x8.0p-2") != 0))
509     return 1;
510   /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
511      glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
512   if (sprintf (buf, "%.1La", 1.999L) < 0
513       || (strcmp (buf, "0x1.0p+1") != 0
514           && strcmp (buf, "0x2.0p+0") != 0
515           && strcmp (buf, "0x4.0p-1") != 0
516           && strcmp (buf, "0x8.0p-2") != 0))
517     return 1;
518   return 0;
519 }]])],
520         [gl_cv_func_printf_directive_a=yes],
521         [gl_cv_func_printf_directive_a=no],
522         [
523          case "$host_os" in
524                                  # Guess yes on glibc >= 2.5 systems.
525            *-gnu*)
526              AC_EGREP_CPP([BZ2908], [
527                #include <features.h>
528                #ifdef __GNU_LIBRARY__
529                 #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)) && !defined __UCLIBC__
530                  BZ2908
531                 #endif
532                #endif
533                ],
534                [gl_cv_func_printf_directive_a="guessing yes"],
535                [gl_cv_func_printf_directive_a="guessing no"])
536              ;;
537                                  # If we don't know, assume the worst.
538            *)                    gl_cv_func_printf_directive_a="guessing no";;
539          esac
540         ])
541     ])
542 ])
543
544 dnl Test whether the *printf family of functions supports the %F format
545 dnl directive. (ISO C99, POSIX:2001)
546 dnl Result is gl_cv_func_printf_directive_f.
547
548 AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
549 [
550   AC_REQUIRE([AC_PROG_CC])
551   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
552   AC_CACHE_CHECK([whether printf supports the 'F' directive],
553     [gl_cv_func_printf_directive_f],
554     [
555       AC_RUN_IFELSE(
556         [AC_LANG_SOURCE([[
557 #include <stdio.h>
558 #include <string.h>
559 static char buf[100];
560 int main ()
561 {
562   if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
563       || strcmp (buf, "1234567.000000 33") != 0)
564     return 1;
565   if (sprintf (buf, "%F", 1.0 / 0.0) < 0
566       || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
567     return 1;
568   /* This catches a Cygwin 1.5.x bug.  */
569   if (sprintf (buf, "%.F", 1234.0) < 0
570       || strcmp (buf, "1234") != 0)
571     return 1;
572   return 0;
573 }]])],
574         [gl_cv_func_printf_directive_f=yes],
575         [gl_cv_func_printf_directive_f=no],
576         [
577 changequote(,)dnl
578          case "$host_os" in
579                                  # Guess yes on glibc systems.
580            *-gnu*)               gl_cv_func_printf_directive_f="guessing yes";;
581                                  # Guess yes on FreeBSD >= 6.
582            freebsd[1-5]*)        gl_cv_func_printf_directive_f="guessing no";;
583            freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
584                                  # Guess yes on MacOS X >= 10.3.
585            darwin[1-6].*)        gl_cv_func_printf_directive_f="guessing no";;
586            darwin*)              gl_cv_func_printf_directive_f="guessing yes";;
587                                  # Guess yes on Solaris >= 2.10.
588            solaris2.[0-9]*)      gl_cv_func_printf_directive_f="guessing no";;
589            solaris*)             gl_cv_func_printf_directive_f="guessing yes";;
590                                  # If we don't know, assume the worst.
591            *)                    gl_cv_func_printf_directive_f="guessing no";;
592          esac
593 changequote([,])dnl
594         ])
595     ])
596 ])
597
598 dnl Test whether the *printf family of functions supports the %n format
599 dnl directive. (ISO C99, POSIX:2001)
600 dnl Result is gl_cv_func_printf_directive_n.
601
602 AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
603 [
604   AC_REQUIRE([AC_PROG_CC])
605   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
606   AC_CACHE_CHECK([whether printf supports the 'n' directive],
607     [gl_cv_func_printf_directive_n],
608     [
609       AC_RUN_IFELSE(
610         [AC_LANG_SOURCE([[
611 #include <stdio.h>
612 #include <string.h>
613 static char fmtstring[10];
614 static char buf[100];
615 int main ()
616 {
617   int count = -1;
618   /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
619      support %n in format strings in read-only memory but not in writable
620      memory.  */
621   strcpy (fmtstring, "%d %n");
622   if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0
623       || strcmp (buf, "123 ") != 0
624       || count != 4)
625     return 1;
626   return 0;
627 }]])],
628         [gl_cv_func_printf_directive_n=yes],
629         [gl_cv_func_printf_directive_n=no],
630         [
631 changequote(,)dnl
632          case "$host_os" in
633            *)     gl_cv_func_printf_directive_n="guessing yes";;
634          esac
635 changequote([,])dnl
636         ])
637     ])
638 ])
639
640 dnl Test whether the *printf family of functions supports the %ls format
641 dnl directive and in particular, when a precision is specified, whether
642 dnl the functions stop converting the wide string argument when the number
643 dnl of bytes that have been produced by this conversion equals or exceeds
644 dnl the precision.
645 dnl Result is gl_cv_func_printf_directive_ls.
646
647 AC_DEFUN([gl_PRINTF_DIRECTIVE_LS],
648 [
649   AC_REQUIRE([AC_PROG_CC])
650   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
651   AC_CACHE_CHECK([whether printf supports the 'ls' directive],
652     [gl_cv_func_printf_directive_ls],
653     [
654       AC_RUN_IFELSE(
655         [AC_LANG_SOURCE([[
656 /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
657    <wchar.h>.
658    BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
659    included before <wchar.h>.  */
660 #include <stddef.h>
661 #include <stdio.h>
662 #include <time.h>
663 #include <wchar.h>
664 #include <string.h>
665 int main ()
666 {
667   char buf[100];
668   /* Test whether %ls works at all.
669      This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
670      Cygwin 1.5.  */
671   {
672     static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
673     buf[0] = '\0';
674     if (sprintf (buf, "%ls", wstring) < 0
675         || strcmp (buf, "abc") != 0)
676       return 1;
677   }
678   /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
679      assertion failure inside libc), but not on OpenBSD 4.0.  */
680   {
681     static const wchar_t wstring[] = { 'a', 0 };
682     buf[0] = '\0';
683     if (sprintf (buf, "%ls", wstring) < 0
684         || strcmp (buf, "a") != 0)
685       return 1;
686   }
687   /* Test whether precisions in %ls are supported as specified in ISO C 99
688      section 7.19.6.1:
689        "If a precision is specified, no more than that many bytes are written
690         (including shift sequences, if any), and the array shall contain a
691         null wide character if, to equal the multibyte character sequence
692         length given by the precision, the function would need to access a
693         wide character one past the end of the array."
694      This test fails on Solaris 10.  */
695   {
696     static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 };
697     buf[0] = '\0';
698     if (sprintf (buf, "%.2ls", wstring) < 0
699         || strcmp (buf, "ab") != 0)
700       return 1;
701   }
702   return 0;
703 }]])],
704         [gl_cv_func_printf_directive_ls=yes],
705         [gl_cv_func_printf_directive_ls=no],
706         [
707 changequote(,)dnl
708          case "$host_os" in
709            openbsd*)        gl_cv_func_printf_directive_ls="guessing no";;
710            irix*)           gl_cv_func_printf_directive_ls="guessing no";;
711            solaris*)        gl_cv_func_printf_directive_ls="guessing no";;
712            cygwin*)         gl_cv_func_printf_directive_ls="guessing no";;
713            beos* | haiku*)  gl_cv_func_printf_directive_ls="guessing no";;
714            *)               gl_cv_func_printf_directive_ls="guessing yes";;
715          esac
716 changequote([,])dnl
717         ])
718     ])
719 ])
720
721 dnl Test whether the *printf family of functions supports POSIX/XSI format
722 dnl strings with positions. (POSIX:2001)
723 dnl Result is gl_cv_func_printf_positions.
724
725 AC_DEFUN([gl_PRINTF_POSITIONS],
726 [
727   AC_REQUIRE([AC_PROG_CC])
728   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
729   AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
730     [gl_cv_func_printf_positions],
731     [
732       AC_RUN_IFELSE(
733         [AC_LANG_SOURCE([[
734 #include <stdio.h>
735 #include <string.h>
736 /* The string "%2$d %1$d", with dollar characters protected from the shell's
737    dollar expansion (possibly an autoconf bug).  */
738 static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
739 static char buf[100];
740 int main ()
741 {
742   sprintf (buf, format, 33, 55);
743   return (strcmp (buf, "55 33") != 0);
744 }]])],
745         [gl_cv_func_printf_positions=yes],
746         [gl_cv_func_printf_positions=no],
747         [
748 changequote(,)dnl
749          case "$host_os" in
750            netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
751                          gl_cv_func_printf_positions="guessing no";;
752            beos*)        gl_cv_func_printf_positions="guessing no";;
753            mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
754            *)            gl_cv_func_printf_positions="guessing yes";;
755          esac
756 changequote([,])dnl
757         ])
758     ])
759 ])
760
761 dnl Test whether the *printf family of functions supports POSIX/XSI format
762 dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
763 dnl Result is gl_cv_func_printf_flag_grouping.
764
765 AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
766 [
767   AC_REQUIRE([AC_PROG_CC])
768   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
769   AC_CACHE_CHECK([whether printf supports the grouping flag],
770     [gl_cv_func_printf_flag_grouping],
771     [
772       AC_RUN_IFELSE(
773         [AC_LANG_SOURCE([[
774 #include <stdio.h>
775 #include <string.h>
776 static char buf[100];
777 int main ()
778 {
779   if (sprintf (buf, "%'d %d", 1234567, 99) < 0
780       || buf[strlen (buf) - 1] != '9')
781     return 1;
782   return 0;
783 }]])],
784         [gl_cv_func_printf_flag_grouping=yes],
785         [gl_cv_func_printf_flag_grouping=no],
786         [
787 changequote(,)dnl
788          case "$host_os" in
789            cygwin*)      gl_cv_func_printf_flag_grouping="guessing no";;
790            netbsd*)      gl_cv_func_printf_flag_grouping="guessing no";;
791            mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";;
792            *)            gl_cv_func_printf_flag_grouping="guessing yes";;
793          esac
794 changequote([,])dnl
795         ])
796     ])
797 ])
798
799 dnl Test whether the *printf family of functions supports the - flag correctly.
800 dnl (ISO C99.) See
801 dnl <http://lists.gnu.org/archive/html/bug-coreutils/2008-02/msg00035.html>
802 dnl Result is gl_cv_func_printf_flag_leftadjust.
803
804 AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST],
805 [
806   AC_REQUIRE([AC_PROG_CC])
807   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
808   AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly],
809     [gl_cv_func_printf_flag_leftadjust],
810     [
811       AC_RUN_IFELSE(
812         [AC_LANG_SOURCE([[
813 #include <stdio.h>
814 #include <string.h>
815 static char buf[100];
816 int main ()
817 {
818   /* Check that a '-' flag is not annihilated by a negative width.  */
819   if (sprintf (buf, "a%-*sc", -3, "b") < 0
820       || strcmp (buf, "ab  c") != 0)
821     return 1;
822   return 0;
823 }]])],
824         [gl_cv_func_printf_flag_leftadjust=yes],
825         [gl_cv_func_printf_flag_leftadjust=no],
826         [
827 changequote(,)dnl
828          case "$host_os" in
829                     # Guess yes on HP-UX 11.
830            hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";;
831                     # Guess no on HP-UX 10 and older.
832            hpux*)   gl_cv_func_printf_flag_leftadjust="guessing no";;
833                     # Guess yes otherwise.
834            *)       gl_cv_func_printf_flag_leftadjust="guessing yes";;
835          esac
836 changequote([,])dnl
837         ])
838     ])
839 ])
840
841 dnl Test whether the *printf family of functions supports padding of non-finite
842 dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
843 dnl <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html>
844 dnl Result is gl_cv_func_printf_flag_zero.
845
846 AC_DEFUN([gl_PRINTF_FLAG_ZERO],
847 [
848   AC_REQUIRE([AC_PROG_CC])
849   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
850   AC_CACHE_CHECK([whether printf supports the zero flag correctly],
851     [gl_cv_func_printf_flag_zero],
852     [
853       AC_RUN_IFELSE(
854         [AC_LANG_SOURCE([[
855 #include <stdio.h>
856 #include <string.h>
857 static char buf[100];
858 int main ()
859 {
860   if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0
861       || (strcmp (buf, "       inf") != 0
862           && strcmp (buf, "  infinity") != 0))
863     return 1;
864   return 0;
865 }]])],
866         [gl_cv_func_printf_flag_zero=yes],
867         [gl_cv_func_printf_flag_zero=no],
868         [
869 changequote(,)dnl
870          case "$host_os" in
871                    # Guess yes on glibc systems.
872            *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";;
873                    # Guess yes on BeOS.
874            beos*)  gl_cv_func_printf_flag_zero="guessing yes";;
875                    # If we don't know, assume the worst.
876            *)      gl_cv_func_printf_flag_zero="guessing no";;
877          esac
878 changequote([,])dnl
879         ])
880     ])
881 ])
882
883 dnl Test whether the *printf family of functions supports large precisions.
884 dnl On mingw, precisions larger than 512 are treated like 512, in integer,
885 dnl floating-point or pointer output. On Solaris 10/x86, precisions larger
886 dnl than 510 in floating-point output crash the program. On BeOS, precisions
887 dnl larger than 1044 crash the program.
888 dnl Result is gl_cv_func_printf_precision.
889
890 AC_DEFUN([gl_PRINTF_PRECISION],
891 [
892   AC_REQUIRE([AC_PROG_CC])
893   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
894   AC_CACHE_CHECK([whether printf supports large precisions],
895     [gl_cv_func_printf_precision],
896     [
897       AC_RUN_IFELSE(
898         [AC_LANG_SOURCE([[
899 #include <stdio.h>
900 #include <string.h>
901 static char buf[5000];
902 int main ()
903 {
904 #ifdef __BEOS__
905   /* On BeOS, this would crash and show a dialog box.  Avoid the crash.  */
906   return 1;
907 #endif
908   if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3)
909     return 1;
910   if (sprintf (buf, "%.4000f %d", 1.0, 33, 44) < 4000 + 5)
911     return 2;
912   return 0;
913 }]])],
914         [gl_cv_func_printf_precision=yes],
915         [gl_cv_func_printf_precision=no],
916         [
917 changequote(,)dnl
918          case "$host_os" in
919            # Guess no only on Solaris, native Win32, and BeOS systems.
920            solaris*)     gl_cv_func_printf_precision="guessing no" ;;
921            mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;;
922            beos*)        gl_cv_func_printf_precision="guessing no" ;;
923            *)            gl_cv_func_printf_precision="guessing yes" ;;
924          esac
925 changequote([,])dnl
926         ])
927     ])
928 ])
929
930 dnl Test whether the *printf family of functions recovers gracefully in case
931 dnl of an out-of-memory condition, or whether it crashes the entire program.
932 dnl Result is gl_cv_func_printf_enomem.
933
934 AC_DEFUN([gl_PRINTF_ENOMEM],
935 [
936   AC_REQUIRE([AC_PROG_CC])
937   AC_REQUIRE([gl_MULTIARCH])
938   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
939   AC_CACHE_CHECK([whether printf survives out-of-memory conditions],
940     [gl_cv_func_printf_enomem],
941     [
942       gl_cv_func_printf_enomem="guessing no"
943       if test "$cross_compiling" = no; then
944         if test $APPLE_UNIVERSAL_BUILD = 0; then
945           AC_LANG_CONFTEST([AC_LANG_SOURCE([
946 ]GL_NOCRASH[
947 changequote(,)dnl
948 #include <stdio.h>
949 #include <sys/types.h>
950 #include <sys/time.h>
951 #include <sys/resource.h>
952 #include <errno.h>
953 int main()
954 {
955   struct rlimit limit;
956   int ret;
957   nocrash_init ();
958   /* Some printf implementations allocate temporary space with malloc.  */
959   /* On BSD systems, malloc() is limited by RLIMIT_DATA.  */
960 #ifdef RLIMIT_DATA
961   if (getrlimit (RLIMIT_DATA, &limit) < 0)
962     return 77;
963   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
964     limit.rlim_max = 5000000;
965   limit.rlim_cur = limit.rlim_max;
966   if (setrlimit (RLIMIT_DATA, &limit) < 0)
967     return 77;
968 #endif
969   /* On Linux systems, malloc() is limited by RLIMIT_AS.  */
970 #ifdef RLIMIT_AS
971   if (getrlimit (RLIMIT_AS, &limit) < 0)
972     return 77;
973   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
974     limit.rlim_max = 5000000;
975   limit.rlim_cur = limit.rlim_max;
976   if (setrlimit (RLIMIT_AS, &limit) < 0)
977     return 77;
978 #endif
979   /* Some printf implementations allocate temporary space on the stack.  */
980 #ifdef RLIMIT_STACK
981   if (getrlimit (RLIMIT_STACK, &limit) < 0)
982     return 77;
983   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
984     limit.rlim_max = 5000000;
985   limit.rlim_cur = limit.rlim_max;
986   if (setrlimit (RLIMIT_STACK, &limit) < 0)
987     return 77;
988 #endif
989   ret = printf ("%.5000000f", 1.0);
990   return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
991 }
992 changequote([,])dnl
993           ])])
994           if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
995             (./conftest
996              result=$?
997              if test $result != 0 && test $result != 77; then result=1; fi
998              exit $result
999             ) >/dev/null 2>/dev/null
1000             case $? in
1001               0) gl_cv_func_printf_enomem="yes" ;;
1002               77) gl_cv_func_printf_enomem="guessing no" ;;
1003               *) gl_cv_func_printf_enomem="no" ;;
1004             esac
1005           else
1006             gl_cv_func_printf_enomem="guessing no"
1007           fi
1008           rm -fr conftest*
1009         else
1010           dnl A universal build on Apple MacOS X platforms.
1011           dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode.
1012           dnl But we need a configuration result that is valid in both modes.
1013           gl_cv_func_printf_enomem="guessing no"
1014         fi
1015       fi
1016       if test "$gl_cv_func_printf_enomem" = "guessing no"; then
1017 changequote(,)dnl
1018         case "$host_os" in
1019                     # Guess yes on glibc systems.
1020           *-gnu*)   gl_cv_func_printf_enomem="guessing yes";;
1021                     # Guess yes on Solaris.
1022           solaris*) gl_cv_func_printf_enomem="guessing yes";;
1023                     # Guess yes on AIX.
1024           aix*)     gl_cv_func_printf_enomem="guessing yes";;
1025                     # Guess yes on HP-UX/hppa.
1026           hpux*)    case "$host_cpu" in
1027                       hppa*) gl_cv_func_printf_enomem="guessing yes";;
1028                       *)     gl_cv_func_printf_enomem="guessing no";;
1029                     esac
1030                     ;;
1031                     # Guess yes on IRIX.
1032           irix*)    gl_cv_func_printf_enomem="guessing yes";;
1033                     # Guess yes on OSF/1.
1034           osf*)     gl_cv_func_printf_enomem="guessing yes";;
1035                     # Guess yes on BeOS.
1036           beos*)    gl_cv_func_printf_enomem="guessing yes";;
1037                     # Guess yes on Haiku.
1038           haiku*)   gl_cv_func_printf_enomem="guessing yes";;
1039                     # If we don't know, assume the worst.
1040           *)        gl_cv_func_printf_enomem="guessing no";;
1041         esac
1042 changequote([,])dnl
1043       fi
1044     ])
1045 ])
1046
1047 dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
1048 dnl Result is ac_cv_func_snprintf.
1049
1050 AC_DEFUN([gl_SNPRINTF_PRESENCE],
1051 [
1052   AC_CHECK_FUNCS_ONCE([snprintf])
1053 ])
1054
1055 dnl Test whether the string produced by the snprintf function is always NUL
1056 dnl terminated. (ISO C99, POSIX:2001)
1057 dnl Result is gl_cv_func_snprintf_truncation_c99.
1058
1059 AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
1060 [
1061   AC_REQUIRE([AC_PROG_CC])
1062   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1063   AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
1064     [gl_cv_func_snprintf_truncation_c99],
1065     [
1066       AC_RUN_IFELSE(
1067         [AC_LANG_SOURCE([[
1068 #include <stdio.h>
1069 #include <string.h>
1070 static char buf[100];
1071 int main ()
1072 {
1073   strcpy (buf, "ABCDEF");
1074   snprintf (buf, 3, "%d %d", 4567, 89);
1075   if (memcmp (buf, "45\0DEF", 6) != 0)
1076     return 1;
1077   return 0;
1078 }]])],
1079         [gl_cv_func_snprintf_truncation_c99=yes],
1080         [gl_cv_func_snprintf_truncation_c99=no],
1081         [
1082 changequote(,)dnl
1083          case "$host_os" in
1084                                  # Guess yes on glibc systems.
1085            *-gnu*)               gl_cv_func_snprintf_truncation_c99="guessing yes";;
1086                                  # Guess yes on FreeBSD >= 5.
1087            freebsd[1-4]*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
1088            freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1089                                  # Guess yes on MacOS X >= 10.3.
1090            darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
1091            darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1092                                  # Guess yes on OpenBSD >= 3.9.
1093            openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1094                                  gl_cv_func_snprintf_truncation_c99="guessing no";;
1095            openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
1096                                  # Guess yes on Solaris >= 2.6.
1097            solaris2.[0-5]*)      gl_cv_func_snprintf_truncation_c99="guessing no";;
1098            solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
1099                                  # Guess yes on AIX >= 4.
1100            aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
1101            aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
1102                                  # Guess yes on HP-UX >= 11.
1103            hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1104            hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
1105                                  # Guess yes on IRIX >= 6.5.
1106            irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1107                                  # Guess yes on OSF/1 >= 5.
1108            osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
1109            osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
1110                                  # Guess yes on NetBSD >= 3.
1111            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1112                                  gl_cv_func_snprintf_truncation_c99="guessing no";;
1113            netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1114                                  # Guess yes on BeOS.
1115            beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
1116                                  # If we don't know, assume the worst.
1117            *)                    gl_cv_func_snprintf_truncation_c99="guessing no";;
1118          esac
1119 changequote([,])dnl
1120         ])
1121     ])
1122 ])
1123
1124 dnl Test whether the return value of the snprintf function is the number
1125 dnl of bytes (excluding the terminating NUL) that would have been produced
1126 dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
1127 dnl For example, this test program fails on IRIX 6.5:
1128 dnl     ---------------------------------------------------------------------
1129 dnl     #include <stdio.h>
1130 dnl     int main()
1131 dnl     {
1132 dnl       static char buf[8];
1133 dnl       int retval = snprintf (buf, 3, "%d", 12345);
1134 dnl       return retval >= 0 && retval < 3;
1135 dnl     }
1136 dnl     ---------------------------------------------------------------------
1137 dnl Result is gl_cv_func_snprintf_retval_c99.
1138
1139 AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99],
1140 [
1141   AC_REQUIRE([AC_PROG_CC])
1142   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1143   AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
1144     [gl_cv_func_snprintf_retval_c99],
1145     [
1146       AC_RUN_IFELSE(
1147         [AC_LANG_SOURCE([[
1148 #include <stdio.h>
1149 #include <string.h>
1150 static char buf[100];
1151 int main ()
1152 {
1153   strcpy (buf, "ABCDEF");
1154   if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
1155     return 1;
1156   return 0;
1157 }]])],
1158         [gl_cv_func_snprintf_retval_c99=yes],
1159         [gl_cv_func_snprintf_retval_c99=no],
1160         [
1161 changequote(,)dnl
1162          case "$host_os" in
1163                                  # Guess yes on glibc systems.
1164            *-gnu*)               gl_cv_func_snprintf_retval_c99="guessing yes";;
1165                                  # Guess yes on FreeBSD >= 5.
1166            freebsd[1-4]*)        gl_cv_func_snprintf_retval_c99="guessing no";;
1167            freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1168                                  # Guess yes on MacOS X >= 10.3.
1169            darwin[1-6].*)        gl_cv_func_snprintf_retval_c99="guessing no";;
1170            darwin*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1171                                  # Guess yes on OpenBSD >= 3.9.
1172            openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1173                                  gl_cv_func_snprintf_retval_c99="guessing no";;
1174            openbsd*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
1175                                  # Guess yes on Solaris >= 2.6.
1176            solaris2.[0-5]*)      gl_cv_func_snprintf_retval_c99="guessing no";;
1177            solaris*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
1178                                  # Guess yes on AIX >= 4.
1179            aix[1-3]*)            gl_cv_func_snprintf_retval_c99="guessing no";;
1180            aix*)                 gl_cv_func_snprintf_retval_c99="guessing yes";;
1181                                  # Guess yes on NetBSD >= 3.
1182            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1183                                  gl_cv_func_snprintf_retval_c99="guessing no";;
1184            netbsd*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1185                                  # Guess yes on BeOS.
1186            beos*)                gl_cv_func_snprintf_retval_c99="guessing yes";;
1187                                  # If we don't know, assume the worst.
1188            *)                    gl_cv_func_snprintf_retval_c99="guessing no";;
1189          esac
1190 changequote([,])dnl
1191         ])
1192     ])
1193 ])
1194
1195 dnl Test whether the snprintf function supports the %n format directive
1196 dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
1197 dnl Result is gl_cv_func_snprintf_directive_n.
1198
1199 AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
1200 [
1201   AC_REQUIRE([AC_PROG_CC])
1202   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1203   AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
1204     [gl_cv_func_snprintf_directive_n],
1205     [
1206       AC_RUN_IFELSE(
1207         [AC_LANG_SOURCE([[
1208 #include <stdio.h>
1209 #include <string.h>
1210 static char fmtstring[10];
1211 static char buf[100];
1212 int main ()
1213 {
1214   int count = -1;
1215   /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
1216      support %n in format strings in read-only memory but not in writable
1217      memory.  */
1218   strcpy (fmtstring, "%d %n");
1219   snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55);
1220   if (count != 6)
1221     return 1;
1222   return 0;
1223 }]])],
1224         [gl_cv_func_snprintf_directive_n=yes],
1225         [gl_cv_func_snprintf_directive_n=no],
1226         [
1227 changequote(,)dnl
1228          case "$host_os" in
1229                                  # Guess yes on glibc systems.
1230            *-gnu*)               gl_cv_func_snprintf_directive_n="guessing yes";;
1231                                  # Guess yes on FreeBSD >= 5.
1232            freebsd[1-4]*)        gl_cv_func_snprintf_directive_n="guessing no";;
1233            freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
1234                                  # Guess yes on MacOS X >= 10.3.
1235            darwin[1-6].*)        gl_cv_func_snprintf_directive_n="guessing no";;
1236            darwin*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1237                                  # Guess yes on Solaris >= 2.6.
1238            solaris2.[0-5]*)      gl_cv_func_snprintf_directive_n="guessing no";;
1239            solaris*)             gl_cv_func_snprintf_directive_n="guessing yes";;
1240                                  # Guess yes on AIX >= 4.
1241            aix[1-3]*)            gl_cv_func_snprintf_directive_n="guessing no";;
1242            aix*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
1243                                  # Guess yes on IRIX >= 6.5.
1244            irix6.5)              gl_cv_func_snprintf_directive_n="guessing yes";;
1245                                  # Guess yes on OSF/1 >= 5.
1246            osf[3-4]*)            gl_cv_func_snprintf_directive_n="guessing no";;
1247            osf*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
1248                                  # Guess yes on NetBSD >= 3.
1249            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1250                                  gl_cv_func_snprintf_directive_n="guessing no";;
1251            netbsd*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1252                                  # Guess yes on BeOS.
1253            beos*)                gl_cv_func_snprintf_directive_n="guessing yes";;
1254                                  # If we don't know, assume the worst.
1255            *)                    gl_cv_func_snprintf_directive_n="guessing no";;
1256          esac
1257 changequote([,])dnl
1258         ])
1259     ])
1260 ])
1261
1262 dnl Test whether the snprintf function, when passed a size = 1, writes any
1263 dnl output without bounds in this case, behaving like sprintf. This is the
1264 dnl case on Linux libc5.
1265 dnl Result is gl_cv_func_snprintf_size1.
1266
1267 AC_DEFUN([gl_SNPRINTF_SIZE1],
1268 [
1269   AC_REQUIRE([AC_PROG_CC])
1270   AC_CACHE_CHECK([whether snprintf respects a size of 1],
1271     [gl_cv_func_snprintf_size1],
1272     [
1273       AC_RUN_IFELSE(
1274         [AC_LANG_SOURCE([[
1275 #include <stdio.h>
1276 int main()
1277 {
1278   static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1279   snprintf (buf, 1, "%d", 12345);
1280   return buf[1] != 'E';
1281 }]])],
1282         [gl_cv_func_snprintf_size1=yes],
1283         [gl_cv_func_snprintf_size1=no],
1284         [gl_cv_func_snprintf_size1="guessing yes"])
1285     ])
1286 ])
1287
1288 dnl Test whether the vsnprintf function, when passed a zero size, produces no
1289 dnl output. (ISO C99, POSIX:2001)
1290 dnl For example, snprintf nevertheless writes a NUL byte in this case
1291 dnl on OSF/1 5.1:
1292 dnl     ---------------------------------------------------------------------
1293 dnl     #include <stdio.h>
1294 dnl     int main()
1295 dnl     {
1296 dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1297 dnl       snprintf (buf, 0, "%d", 12345);
1298 dnl       return buf[0] != 'D';
1299 dnl     }
1300 dnl     ---------------------------------------------------------------------
1301 dnl And vsnprintf writes any output without bounds in this case, behaving like
1302 dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
1303 dnl     ---------------------------------------------------------------------
1304 dnl     #include <stdarg.h>
1305 dnl     #include <stdio.h>
1306 dnl     static int my_snprintf (char *buf, int size, const char *format, ...)
1307 dnl     {
1308 dnl       va_list args;
1309 dnl       int ret;
1310 dnl       va_start (args, format);
1311 dnl       ret = vsnprintf (buf, size, format, args);
1312 dnl       va_end (args);
1313 dnl       return ret;
1314 dnl     }
1315 dnl     int main()
1316 dnl     {
1317 dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1318 dnl       my_snprintf (buf, 0, "%d", 12345);
1319 dnl       return buf[0] != 'D';
1320 dnl     }
1321 dnl     ---------------------------------------------------------------------
1322 dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
1323
1324 AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
1325 [
1326   AC_REQUIRE([AC_PROG_CC])
1327   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1328   AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
1329     [gl_cv_func_vsnprintf_zerosize_c99],
1330     [
1331       AC_RUN_IFELSE(
1332         [AC_LANG_SOURCE([[
1333 #include <stdarg.h>
1334 #include <stdio.h>
1335 static int my_snprintf (char *buf, int size, const char *format, ...)
1336 {
1337   va_list args;
1338   int ret;
1339   va_start (args, format);
1340   ret = vsnprintf (buf, size, format, args);
1341   va_end (args);
1342   return ret;
1343 }
1344 int main()
1345 {
1346   static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1347   my_snprintf (buf, 0, "%d", 12345);
1348   return buf[0] != 'D';
1349 }]])],
1350         [gl_cv_func_vsnprintf_zerosize_c99=yes],
1351         [gl_cv_func_vsnprintf_zerosize_c99=no],
1352         [
1353 changequote(,)dnl
1354          case "$host_os" in
1355                                  # Guess yes on glibc systems.
1356            *-gnu*)               gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1357                                  # Guess yes on FreeBSD >= 5.
1358            freebsd[1-4]*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1359            freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1360                                  # Guess yes on MacOS X >= 10.3.
1361            darwin[1-6].*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1362            darwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1363                                  # Guess yes on Cygwin.
1364            cygwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1365                                  # Guess yes on Solaris >= 2.6.
1366            solaris2.[0-5]*)      gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1367            solaris*)             gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1368                                  # Guess yes on AIX >= 4.
1369            aix[1-3]*)            gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1370            aix*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1371                                  # Guess yes on IRIX >= 6.5.
1372            irix6.5)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1373                                  # Guess yes on NetBSD >= 3.
1374            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1375                                  gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1376            netbsd*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1377                                  # Guess yes on BeOS.
1378            beos*)                gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1379                                  # Guess yes on mingw.
1380            mingw* | pw*)         gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1381                                  # If we don't know, assume the worst.
1382            *)                    gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1383          esac
1384 changequote([,])dnl
1385         ])
1386     ])
1387 ])
1388
1389 dnl The results of these tests on various platforms are:
1390 dnl
1391 dnl 1 = gl_PRINTF_SIZES_C99
1392 dnl 2 = gl_PRINTF_LONG_DOUBLE
1393 dnl 3 = gl_PRINTF_INFINITE
1394 dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
1395 dnl 5 = gl_PRINTF_DIRECTIVE_A
1396 dnl 6 = gl_PRINTF_DIRECTIVE_F
1397 dnl 7 = gl_PRINTF_DIRECTIVE_N
1398 dnl 8 = gl_PRINTF_DIRECTIVE_LS
1399 dnl 9 = gl_PRINTF_POSITIONS
1400 dnl 10 = gl_PRINTF_FLAG_GROUPING
1401 dnl 11 = gl_PRINTF_FLAG_LEFTADJUST
1402 dnl 12 = gl_PRINTF_FLAG_ZERO
1403 dnl 13 = gl_PRINTF_PRECISION
1404 dnl 14 = gl_PRINTF_ENOMEM
1405 dnl 15 = gl_SNPRINTF_PRESENCE
1406 dnl 16 = gl_SNPRINTF_TRUNCATION_C99
1407 dnl 17 = gl_SNPRINTF_RETVAL_C99
1408 dnl 18 = gl_SNPRINTF_DIRECTIVE_N
1409 dnl 19 = gl_SNPRINTF_SIZE1
1410 dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99
1411 dnl
1412 dnl 1 = checking whether printf supports size specifiers as in C99...
1413 dnl 2 = checking whether printf supports 'long double' arguments...
1414 dnl 3 = checking whether printf supports infinite 'double' arguments...
1415 dnl 4 = checking whether printf supports infinite 'long double' arguments...
1416 dnl 5 = checking whether printf supports the 'a' and 'A' directives...
1417 dnl 6 = checking whether printf supports the 'F' directive...
1418 dnl 7 = checking whether printf supports the 'n' directive...
1419 dnl 8 = checking whether printf supports the 'ls' directive...
1420 dnl 9 = checking whether printf supports POSIX/XSI format strings with positions...
1421 dnl 10 = checking whether printf supports the grouping flag...
1422 dnl 11 = checking whether printf supports the left-adjust flag correctly...
1423 dnl 12 = checking whether printf supports the zero flag correctly...
1424 dnl 13 = checking whether printf supports large precisions...
1425 dnl 14 = checking whether printf survives out-of-memory conditions...
1426 dnl 15 = checking for snprintf...
1427 dnl 16 = checking whether snprintf truncates the result as in C99...
1428 dnl 17 = checking whether snprintf returns a byte count as in C99...
1429 dnl 18 = checking whether snprintf fully supports the 'n' directive...
1430 dnl 19 = checking whether snprintf respects a size of 1...
1431 dnl 20 = checking whether vsnprintf respects a zero size as in C99...
1432 dnl
1433 dnl . = yes, # = no.
1434 dnl
1435 dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
1436 dnl   glibc 2.5                      .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
1437 dnl   glibc 2.3.6                    .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
1438 dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .
1439 dnl   MacOS X 10.5.8                 .  .  .  #  #  .  .  .  .  .  .  #  .  .  .  .  .  .  .  .
1440 dnl   MacOS X 10.3.9                 .  .  .  .  #  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .
1441 dnl   OpenBSD 3.9, 4.0               .  .  #  #  #  #  .  #  .  #  .  #  .  #  .  .  .  .  .  .
1442 dnl   Cygwin 1.7.0 (2009)            .  .  .  #  .  .  .  ?  .  .  .  .  .  ?  .  .  .  .  .  .
1443 dnl   Cygwin 1.5.25 (2008)           .  .  .  #  #  .  .  #  .  .  .  .  .  #  .  .  .  .  .  .
1444 dnl   Cygwin 1.5.19 (2006)           #  .  .  #  #  #  .  #  .  #  .  #  #  #  .  .  .  .  .  .
1445 dnl   Solaris 10                     .  .  #  #  #  .  .  #  .  .  .  #  #  .  .  .  .  .  .  .
1446 dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  .  #  .  .  .  #  .  .  .  .  .  .  .  .
1447 dnl   Solaris 2.5.1                  #  .  #  #  #  #  .  #  .  .  .  #  .  .  #  #  #  #  #  #
1448 dnl   AIX 5.2, 7.1                   .  .  #  #  #  .  .  .  .  .  .  #  .  .  .  .  .  .  .  .
1449 dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  .  .  .  .  .  #  .  .  .  .  .  .  .  .
1450 dnl   HP-UX 11.31                    .  .  .  .  #  .  .  .  .  .  .  #  .  .  .  .  #  #  .  .
1451 dnl   HP-UX 11.{00,11,23}            #  .  .  .  #  #  .  .  .  .  .  #  .  .  .  .  #  #  .  #
1452 dnl   HP-UX 10.20                    #  .  #  .  #  #  .  ?  .  .  #  #  .  .  .  .  #  #  ?  #
1453 dnl   IRIX 6.5                       #  .  #  #  #  #  .  #  .  .  .  #  .  .  .  .  #  .  .  .
1454 dnl   OSF/1 5.1                      #  .  #  #  #  #  .  .  .  .  .  #  .  .  .  .  #  .  .  #
1455 dnl   OSF/1 4.0d                     #  .  #  #  #  #  .  .  .  .  .  #  .  .  #  #  #  #  #  #
1456 dnl   NetBSD 5.0                     .  .  .  #  #  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .
1457 dnl   NetBSD 4.0                     .  ?  ?  ?  ?  ?  .  ?  .  ?  ?  ?  ?  ?  .  .  .  ?  ?  ?
1458 dnl   NetBSD 3.0                     .  .  .  .  #  #  .  ?  #  #  ?  #  .  #  .  .  .  .  .  .
1459 dnl   Haiku                          .  .  .  #  #  #  .  #  .  .  .  .  .  ?  .  .  .  .  .  .
1460 dnl   BeOS                           #  #  .  #  #  #  .  ?  #  .  ?  .  #  ?  .  .  .  .  .  .
1461 dnl   mingw                          #  #  #  #  #  #  .  .  #  #  .  #  #  ?  .  #  #  #  .  .