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