Correct last change.
[gnulib.git] / m4 / printf.m4
1 # printf.m4 serial 13
2 dnl Copyright (C) 2003, 2007 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[100];
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 in the %f, %e, %g directives. (ISO C99, POSIX:2001)
129 dnl Result is gl_cv_func_printf_infinite.
130
131 AC_DEFUN([gl_PRINTF_INFINITE],
132 [
133   AC_REQUIRE([AC_PROG_CC])
134   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
135   AC_CACHE_CHECK([whether printf supports infinite 'double' arguments],
136     [gl_cv_func_printf_infinite],
137     [
138       AC_TRY_RUN([
139 #include <stdio.h>
140 #include <string.h>
141 static int
142 strisnan (const char *string, size_t start_index, size_t end_index)
143 {
144   if (start_index < end_index)
145     {
146       if (string[start_index] == '-')
147         start_index++;
148       if (start_index + 3 <= end_index
149           && memcmp (string + start_index, "nan", 3) == 0)
150         {
151           start_index += 3;
152           if (start_index == end_index
153               || (string[start_index] == '(' && string[end_index - 1] == ')'))
154             return 1;
155         }
156     }
157   return 0;
158 }
159 static char buf[100];
160 static double zero = 0.0;
161 int main ()
162 {
163   if (sprintf (buf, "%f", 1.0 / 0.0) < 0
164       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
165     return 1;
166   if (sprintf (buf, "%f", -1.0 / 0.0) < 0
167       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
168     return 1;
169   if (sprintf (buf, "%f", zero / zero) < 0
170       || !strisnan (buf, 0, strlen (buf)))
171     return 1;
172   if (sprintf (buf, "%e", 1.0 / 0.0) < 0
173       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
174     return 1;
175   if (sprintf (buf, "%e", -1.0 / 0.0) < 0
176       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
177     return 1;
178   if (sprintf (buf, "%e", zero / zero) < 0
179       || !strisnan (buf, 0, strlen (buf)))
180     return 1;
181   if (sprintf (buf, "%g", 1.0 / 0.0) < 0
182       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
183     return 1;
184   if (sprintf (buf, "%g", -1.0 / 0.0) < 0
185       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
186     return 1;
187   if (sprintf (buf, "%g", zero / zero) < 0
188       || !strisnan (buf, 0, strlen (buf)))
189     return 1;
190   return 0;
191 }], [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no],
192       [
193 changequote(,)dnl
194        case "$host_os" in
195                                # Guess yes on glibc systems.
196          *-gnu*)               gl_cv_func_printf_infinite="guessing yes";;
197                                # Guess yes on FreeBSD >= 6.
198          freebsd[1-5]*)        gl_cv_func_printf_infinite="guessing no";;
199          freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";;
200                                # Guess yes on MacOS X >= 10.3.
201          darwin[1-6].*)        gl_cv_func_printf_infinite="guessing no";;
202          darwin*)              gl_cv_func_printf_infinite="guessing yes";;
203                                # Guess yes on HP-UX >= 11.
204          hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
205          hpux*)                gl_cv_func_printf_infinite="guessing yes";;
206                                # Guess yes on NetBSD >= 3.
207          netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
208                                gl_cv_func_printf_infinite="guessing no";;
209          netbsd*)              gl_cv_func_printf_infinite="guessing yes";;
210                                # Guess yes on BeOS.
211          beos*)                gl_cv_func_printf_infinite="guessing yes";;
212                                # If we don't know, assume the worst.
213          *)                    gl_cv_func_printf_infinite="guessing no";;
214        esac
215 changequote([,])dnl
216       ])
217     ])
218 ])
219
220 dnl Test whether the *printf family of functions supports infinite and NaN
221 dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
222 dnl Result is gl_cv_func_printf_infinite_long_double.
223
224 AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
225 [
226   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
227   AC_REQUIRE([AC_PROG_CC])
228   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
229   case "$gl_cv_func_printf_long_double" in
230     *yes)
231       AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments],
232         [gl_cv_func_printf_infinite_long_double],
233         [
234           AC_TRY_RUN([
235 #include <stdio.h>
236 #include <string.h>
237 static int
238 strisnan (const char *string, size_t start_index, size_t end_index)
239 {
240   if (start_index < end_index)
241     {
242       if (string[start_index] == '-')
243         start_index++;
244       if (start_index + 3 <= end_index
245           && memcmp (string + start_index, "nan", 3) == 0)
246         {
247           start_index += 3;
248           if (start_index == end_index
249               || (string[start_index] == '(' && string[end_index - 1] == ')'))
250             return 1;
251         }
252     }
253   return 0;
254 }
255 static char buf[100];
256 static long double zeroL = 0.0L;
257 int main ()
258 {
259   if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0
260       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
261     return 1;
262   if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0
263       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
264     return 1;
265   if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
266       || !strisnan (buf, 0, strlen (buf)))
267     return 1;
268   if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0
269       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
270     return 1;
271   if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0
272       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
273     return 1;
274   if (sprintf (buf, "%Le", zeroL / zeroL) < 0
275       || !strisnan (buf, 0, strlen (buf)))
276     return 1;
277   if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0
278       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
279     return 1;
280   if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0
281       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
282     return 1;
283   if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
284       || !strisnan (buf, 0, strlen (buf)))
285     return 1;
286   return 0;
287 }],
288           [gl_cv_func_printf_infinite_long_double=yes],
289           [gl_cv_func_printf_infinite_long_double=no],
290           [
291 changequote(,)dnl
292            case "$host_os" in
293                                    # Guess yes on glibc systems.
294              *-gnu*)               gl_cv_func_printf_infinite_long_double="guessing yes";;
295                                    # Guess yes on FreeBSD >= 6.
296              freebsd[1-5]*)        gl_cv_func_printf_infinite_long_double="guessing no";;
297              freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";;
298                                    # Guess yes on MacOS X >= 10.3.
299              darwin[1-6].*)        gl_cv_func_printf_infinite_long_double="guessing no";;
300              darwin*)              gl_cv_func_printf_infinite_long_double="guessing yes";;
301                                    # Guess yes on HP-UX >= 11.
302              hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";;
303              hpux*)                gl_cv_func_printf_infinite_long_double="guessing yes";;
304                                    # Guess yes on NetBSD >= 3.
305              netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
306                                    gl_cv_func_printf_infinite_long_double="guessing no";;
307              netbsd*)              gl_cv_func_printf_infinite_long_double="guessing yes";;
308                                    # If we don't know, assume the worst.
309              *)                    gl_cv_func_printf_infinite_long_double="guessing no";;
310            esac
311 changequote([,])dnl
312           ])
313         ])
314       ;;
315     *)
316       gl_cv_func_printf_infinite_long_double="irrelevant"
317       ;;
318   esac
319 ])
320
321 dnl Test whether the *printf family of functions supports the 'a' and 'A'
322 dnl conversion specifier for hexadecimal output of floating-point numbers.
323 dnl (ISO C99, POSIX:2001)
324 dnl Result is gl_cv_func_printf_directive_a.
325
326 AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
327 [
328   AC_REQUIRE([AC_PROG_CC])
329   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
330   AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
331     [gl_cv_func_printf_directive_a],
332     [
333       AC_TRY_RUN([
334 #include <stdio.h>
335 #include <string.h>
336 static char buf[100];
337 int main ()
338 {
339   if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
340       || (strcmp (buf, "0x1.922p+1 33") != 0
341           && strcmp (buf, "0x3.244p+0 33") != 0
342           && strcmp (buf, "0x6.488p-1 33") != 0
343           && strcmp (buf, "0xc.91p-2 33") != 0))
344     return 1;
345   if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
346       || (strcmp (buf, "-0X1.922P+1 33") != 0
347           && strcmp (buf, "-0X3.244P+0 33") != 0
348           && strcmp (buf, "-0X6.488P-1 33") != 0
349           && strcmp (buf, "-0XC.91P-2 33") != 0))
350     return 1;
351   /* This catches a FreeBSD 6.1 bug: it doesn't round.  */
352   if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
353       || (strcmp (buf, "0x1.83p+0 33") != 0
354           && strcmp (buf, "0x3.05p-1 33") != 0
355           && strcmp (buf, "0x6.0ap-2 33") != 0
356           && strcmp (buf, "0xc.14p-3 33") != 0))
357     return 1;
358   /* This catches a FreeBSD 6.1 bug.  See
359      <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
360   if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0
361       || buf[0] == '0')
362     return 1;
363   /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug.  */
364   if (sprintf (buf, "%.1a", 1.999) < 0
365       || (strcmp (buf, "0x1.0p+1") != 0
366           && strcmp (buf, "0x2.0p+0") != 0
367           && strcmp (buf, "0x4.0p-1") != 0
368           && strcmp (buf, "0x8.0p-2") != 0))
369     return 1;
370   /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
371      glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
372   if (sprintf (buf, "%.1La", 1.999L) < 0
373       || (strcmp (buf, "0x1.0p+1") != 0
374           && strcmp (buf, "0x2.0p+0") != 0
375           && strcmp (buf, "0x4.0p-1") != 0
376           && strcmp (buf, "0x8.0p-2") != 0))
377     return 1;
378   return 0;
379 }], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
380       [
381        case "$host_os" in
382                                # Guess yes on glibc >= 2.5 systems.
383          *-gnu*)
384            AC_EGREP_CPP([BZ2908], [
385              #include <features.h>
386              #ifdef __GNU_LIBRARY__
387               #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)
388                BZ2908
389               #endif
390              #endif
391              ],
392              [gl_cv_func_printf_directive_a="guessing yes"],
393              [gl_cv_func_printf_directive_a="guessing no"])
394            ;;
395                                # If we don't know, assume the worst.
396          *)                    gl_cv_func_printf_directive_a="guessing no";;
397        esac
398       ])
399     ])
400 ])
401
402 dnl Test whether the *printf family of functions supports the %F format
403 dnl directive. (ISO C99, POSIX:2001)
404 dnl Result is gl_cv_func_printf_directive_f.
405
406 AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
407 [
408   AC_REQUIRE([AC_PROG_CC])
409   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
410   AC_CACHE_CHECK([whether printf supports the 'F' directive],
411     [gl_cv_func_printf_directive_f],
412     [
413       AC_TRY_RUN([
414 #include <stdio.h>
415 #include <string.h>
416 static char buf[100];
417 int main ()
418 {
419   if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
420       || strcmp (buf, "1234567.000000 33") != 0)
421     return 1;
422   if (sprintf (buf, "%F", 1.0 / 0.0) < 0
423       || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
424     return 1;
425   /* This catches a Cygwin 2007 bug.  */
426   if (sprintf (buf, "%.F", 1234.0) < 0
427       || strcmp (buf, "1234") != 0)
428     return 1;
429   return 0;
430 }], [gl_cv_func_printf_directive_f=yes], [gl_cv_func_printf_directive_f=no],
431       [
432 changequote(,)dnl
433        case "$host_os" in
434                                # Guess yes on glibc systems.
435          *-gnu*)               gl_cv_func_printf_directive_f="guessing yes";;
436                                # Guess yes on FreeBSD >= 6.
437          freebsd[1-5]*)        gl_cv_func_printf_directive_f="guessing no";;
438          freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
439                                # Guess yes on MacOS X >= 10.3.
440          darwin[1-6].*)        gl_cv_func_printf_directive_f="guessing no";;
441          darwin*)              gl_cv_func_printf_directive_f="guessing yes";;
442                                # Guess yes on Solaris >= 2.10.
443          solaris2.[0-9]*)      gl_cv_func_printf_directive_f="guessing no";;
444          solaris*)             gl_cv_func_printf_directive_f="guessing yes";;
445                                # If we don't know, assume the worst.
446          *)                    gl_cv_func_printf_directive_f="guessing no";;
447        esac
448 changequote([,])dnl
449       ])
450     ])
451 ])
452
453 dnl Test whether the *printf family of functions supports the %n format
454 dnl directive. (ISO C99, POSIX:2001)
455 dnl Result is gl_cv_func_printf_directive_n.
456
457 AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
458 [
459   AC_REQUIRE([AC_PROG_CC])
460   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
461   AC_CACHE_CHECK([whether printf supports the 'n' directive],
462     [gl_cv_func_printf_directive_n],
463     [
464       AC_TRY_RUN([
465 #include <stdio.h>
466 #include <string.h>
467 static char buf[100];
468 int main ()
469 {
470   int count = -1;
471   if (sprintf (buf, "%d %n", 123, &count, 33, 44, 55) < 0
472       || strcmp (buf, "123 ") != 0
473       || count != 4)
474     return 1;
475   return 0;
476 }], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no],
477       [
478 changequote(,)dnl
479        case "$host_os" in
480          *)     gl_cv_func_printf_directive_n="guessing yes";;
481        esac
482 changequote([,])dnl
483       ])
484     ])
485 ])
486
487 dnl Test whether the *printf family of functions supports POSIX/XSI format
488 dnl strings with positions. (POSIX:2001)
489 dnl Result is gl_cv_func_printf_positions.
490
491 AC_DEFUN([gl_PRINTF_POSITIONS],
492 [
493   AC_REQUIRE([AC_PROG_CC])
494   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
495   AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
496     [gl_cv_func_printf_positions],
497     [
498       AC_TRY_RUN([
499 #include <stdio.h>
500 #include <string.h>
501 /* The string "%2$d %1$d", with dollar characters protected from the shell's
502    dollar expansion (possibly an autoconf bug).  */
503 static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
504 static char buf[100];
505 int main ()
506 {
507   sprintf (buf, format, 33, 55);
508   return (strcmp (buf, "55 33") != 0);
509 }], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no],
510       [
511 changequote(,)dnl
512        case "$host_os" in
513          netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
514                        gl_cv_func_printf_positions="guessing no";;
515          beos*)        gl_cv_func_printf_positions="guessing no";;
516          mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
517          *)            gl_cv_func_printf_positions="guessing yes";;
518        esac
519 changequote([,])dnl
520       ])
521     ])
522 ])
523
524 dnl Test whether the *printf family of functions supports POSIX/XSI format
525 dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
526 dnl Result is gl_cv_func_printf_flag_grouping.
527
528 AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
529 [
530   AC_REQUIRE([AC_PROG_CC])
531   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
532   AC_CACHE_CHECK([whether printf supports the grouping flag],
533     [gl_cv_func_printf_flag_grouping],
534     [
535       AC_TRY_RUN([
536 #include <stdio.h>
537 #include <string.h>
538 static char buf[100];
539 int main ()
540 {
541   if (sprintf (buf, "%'d %d", 1234567, 99) < 0
542       || buf[strlen (buf) - 1] != '9')
543     return 1;
544   return 0;
545 }], [gl_cv_func_printf_flag_grouping=yes], [gl_cv_func_printf_flag_grouping=no],
546       [
547 changequote(,)dnl
548        case "$host_os" in
549          cygwin*)      gl_cv_func_printf_flag_grouping="guessing no";;
550          netbsd*)      gl_cv_func_printf_flag_grouping="guessing no";;
551          mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";;
552          *)            gl_cv_func_printf_flag_grouping="guessing yes";;
553        esac
554 changequote([,])dnl
555       ])
556     ])
557 ])
558
559 dnl Test whether the *printf family of functions supports padding of non-finite
560 dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
561 dnl <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html>
562 dnl Result is gl_cv_func_printf_flag_zero.
563
564 AC_DEFUN([gl_PRINTF_FLAG_ZERO],
565 [
566   AC_REQUIRE([AC_PROG_CC])
567   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
568   AC_CACHE_CHECK([whether printf supports the zero flag correctly],
569     [gl_cv_func_printf_flag_zero],
570     [
571       AC_TRY_RUN([
572 #include <stdio.h>
573 #include <string.h>
574 static char buf[100];
575 int main ()
576 {
577   if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0
578       || (strcmp (buf, "       inf") != 0
579           && strcmp (buf, "  infinity") != 0))
580     return 1;
581   return 0;
582 }], [gl_cv_func_printf_flag_zero=yes], [gl_cv_func_printf_flag_zero=no],
583       [
584 changequote(,)dnl
585        case "$host_os" in
586                  # Guess yes on glibc systems.
587          *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";;
588                  # Guess yes on BeOS.
589          beos*)  gl_cv_func_printf_flag_zero="guessing yes";;
590                  # If we don't know, assume the worst.
591          *)      gl_cv_func_printf_flag_zero="guessing no";;
592        esac
593 changequote([,])dnl
594       ])
595     ])
596 ])
597
598 dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
599 dnl Result is ac_cv_func_snprintf.
600
601 AC_DEFUN([gl_SNPRINTF_PRESENCE],
602 [
603   AC_CHECK_FUNCS_ONCE([snprintf])
604 ])
605
606 dnl Test whether the string produced by the snprintf function is always NUL
607 dnl terminated. (ISO C99, POSIX:2001)
608 dnl Result is gl_cv_func_snprintf_truncation_c99.
609
610 AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
611 [
612   AC_REQUIRE([AC_PROG_CC])
613   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
614   AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
615     [gl_cv_func_snprintf_truncation_c99],
616     [
617       AC_TRY_RUN([
618 #include <stdio.h>
619 #include <string.h>
620 static char buf[100];
621 int main ()
622 {
623   strcpy (buf, "ABCDEF");
624   snprintf (buf, 3, "%d %d", 4567, 89);
625   if (memcmp (buf, "45\0DEF", 6) != 0)
626     return 1;
627   return 0;
628 }], [gl_cv_func_snprintf_truncation_c99=yes], [gl_cv_func_snprintf_truncation_c99=no],
629       [
630 changequote(,)dnl
631        case "$host_os" in
632                                # Guess yes on glibc systems.
633          *-gnu*)               gl_cv_func_snprintf_truncation_c99="guessing yes";;
634                                # Guess yes on FreeBSD >= 5.
635          freebsd[1-4]*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
636          freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
637                                # Guess yes on MacOS X >= 10.3.
638          darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
639          darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
640                                # Guess yes on OpenBSD >= 3.9.
641          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
642                                gl_cv_func_snprintf_truncation_c99="guessing no";;
643          openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
644                                # Guess yes on Solaris >= 2.6.
645          solaris2.[0-5]*)      gl_cv_func_snprintf_truncation_c99="guessing no";;
646          solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
647                                # Guess yes on AIX >= 4.
648          aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
649          aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
650                                # Guess yes on HP-UX >= 11.
651          hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
652          hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
653                                # Guess yes on IRIX >= 6.5.
654          irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
655                                # Guess yes on OSF/1 >= 5.
656          osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
657          osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
658                                # Guess yes on NetBSD >= 3.
659          netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
660                                gl_cv_func_snprintf_truncation_c99="guessing no";;
661          netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
662                                # Guess yes on BeOS.
663          beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
664                                # If we don't know, assume the worst.
665          *)                    gl_cv_func_snprintf_truncation_c99="guessing no";;
666        esac
667 changequote([,])dnl
668       ])
669     ])
670 ])
671
672 dnl Test whether the return value of the snprintf function is the number
673 dnl of bytes (excluding the terminating NUL) that would have been produced
674 dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
675 dnl For example, this test program fails on IRIX 6.5:
676 dnl     ---------------------------------------------------------------------
677 dnl     #include <stdio.h>
678 dnl     int main()
679 dnl     {
680 dnl       static char buf[8];
681 dnl       int retval = snprintf (buf, 3, "%d", 12345);
682 dnl       return retval >= 0 && retval < 3;
683 dnl     }
684 dnl     ---------------------------------------------------------------------
685 dnl Result is gl_cv_func_snprintf_retval_c99.
686
687 AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
688 [
689   AC_REQUIRE([AC_PROG_CC])
690   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
691   AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
692     [gl_cv_func_snprintf_retval_c99],
693     [
694       AC_TRY_RUN([
695 #include <stdio.h>
696 #include <string.h>
697 static char buf[100];
698 int main ()
699 {
700   strcpy (buf, "ABCDEF");
701   if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
702     return 1;
703   return 0;
704 }], [gl_cv_func_snprintf_retval_c99=yes], [gl_cv_func_snprintf_retval_c99=no],
705       [
706 changequote(,)dnl
707        case "$host_os" in
708                                # Guess yes on glibc systems.
709          *-gnu*)               gl_cv_func_snprintf_retval_c99="guessing yes";;
710                                # Guess yes on FreeBSD >= 5.
711          freebsd[1-4]*)        gl_cv_func_snprintf_retval_c99="guessing no";;
712          freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
713                                # Guess yes on MacOS X >= 10.3.
714          darwin[1-6].*)        gl_cv_func_snprintf_retval_c99="guessing no";;
715          darwin*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
716                                # Guess yes on OpenBSD >= 3.9.
717          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
718                                gl_cv_func_snprintf_retval_c99="guessing no";;
719          openbsd*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
720                                # Guess yes on Solaris >= 2.6.
721          solaris2.[0-5]*)      gl_cv_func_snprintf_retval_c99="guessing no";;
722          solaris*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
723                                # Guess yes on AIX >= 4.
724          aix[1-3]*)            gl_cv_func_snprintf_retval_c99="guessing no";;
725          aix*)                 gl_cv_func_snprintf_retval_c99="guessing yes";;
726                                # Guess yes on NetBSD >= 3.
727          netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
728                                gl_cv_func_snprintf_retval_c99="guessing no";;
729          netbsd*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
730                                # Guess yes on BeOS.
731          beos*)                gl_cv_func_snprintf_retval_c99="guessing yes";;
732                                # If we don't know, assume the worst.
733          *)                    gl_cv_func_snprintf_retval_c99="guessing no";;
734        esac
735 changequote([,])dnl
736       ])
737     ])
738 ])
739
740 dnl Test whether the snprintf function supports the %n format directive
741 dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
742 dnl Result is gl_cv_func_snprintf_directive_n.
743
744 AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
745 [
746   AC_REQUIRE([AC_PROG_CC])
747   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
748   AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
749     [gl_cv_func_snprintf_directive_n],
750     [
751       AC_TRY_RUN([
752 #include <stdio.h>
753 #include <string.h>
754 static char buf[100];
755 int main ()
756 {
757   int count = -1;
758   snprintf (buf, 4, "%d %n", 12345, &count, 33, 44, 55);
759   if (count != 6)
760     return 1;
761   return 0;
762 }], [gl_cv_func_snprintf_directive_n=yes], [gl_cv_func_snprintf_directive_n=no],
763       [
764 changequote(,)dnl
765        case "$host_os" in
766                                # Guess yes on glibc systems.
767          *-gnu*)               gl_cv_func_snprintf_directive_n="guessing yes";;
768                                # Guess yes on FreeBSD >= 5.
769          freebsd[1-4]*)        gl_cv_func_snprintf_directive_n="guessing no";;
770          freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
771                                # Guess yes on MacOS X >= 10.3.
772          darwin[1-6].*)        gl_cv_func_snprintf_directive_n="guessing no";;
773          darwin*)              gl_cv_func_snprintf_directive_n="guessing yes";;
774                                # Guess yes on Solaris >= 2.6.
775          solaris2.[0-5]*)      gl_cv_func_snprintf_directive_n="guessing no";;
776          solaris*)             gl_cv_func_snprintf_directive_n="guessing yes";;
777                                # Guess yes on AIX >= 4.
778          aix[1-3]*)            gl_cv_func_snprintf_directive_n="guessing no";;
779          aix*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
780                                # Guess yes on IRIX >= 6.5.
781          irix6.5)              gl_cv_func_snprintf_directive_n="guessing yes";;
782                                # Guess yes on OSF/1 >= 5.
783          osf[3-4]*)            gl_cv_func_snprintf_directive_n="guessing no";;
784          osf*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
785                                # Guess yes on NetBSD >= 3.
786          netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
787                                gl_cv_func_snprintf_directive_n="guessing no";;
788          netbsd*)              gl_cv_func_snprintf_directive_n="guessing yes";;
789                                # Guess yes on BeOS.
790          beos*)                gl_cv_func_snprintf_directive_n="guessing yes";;
791                                # If we don't know, assume the worst.
792          *)                    gl_cv_func_snprintf_directive_n="guessing no";;
793        esac
794 changequote([,])dnl
795       ])
796     ])
797 ])
798
799 dnl Test whether the vsnprintf function, when passed a zero size, produces no
800 dnl output. (ISO C99, POSIX:2001)
801 dnl For example, snprintf nevertheless writes a NUL byte in this case
802 dnl on OSF/1 5.1:
803 dnl     ---------------------------------------------------------------------
804 dnl     #include <stdio.h>
805 dnl     int main()
806 dnl     {
807 dnl       static char buf[8] = "DEADBEEF";
808 dnl       snprintf (buf, 0, "%d", 12345);
809 dnl       return buf[0] != 'D';
810 dnl     }
811 dnl     ---------------------------------------------------------------------
812 dnl And vsnprintf writes any output without bounds in this case, behaving like
813 dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
814 dnl     ---------------------------------------------------------------------
815 dnl     #include <stdarg.h>
816 dnl     #include <stdio.h>
817 dnl     static int my_snprintf (char *buf, int size, const char *format, ...)
818 dnl     {
819 dnl       va_list args;
820 dnl       int ret;
821 dnl       va_start (args, format);
822 dnl       ret = vsnprintf (buf, size, format, args);
823 dnl       va_end (args);
824 dnl       return ret;
825 dnl     }
826 dnl     int main()
827 dnl     {
828 dnl       static char buf[8] = "DEADBEEF";
829 dnl       my_snprintf (buf, 0, "%d", 12345);
830 dnl       return buf[0] != 'D';
831 dnl     }
832 dnl     ---------------------------------------------------------------------
833 dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
834
835 AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
836 [
837   AC_REQUIRE([AC_PROG_CC])
838   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
839   AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
840     [gl_cv_func_vsnprintf_zerosize_c99],
841     [
842       AC_TRY_RUN([
843 #include <stdarg.h>
844 #include <stdio.h>
845 static int my_snprintf (char *buf, int size, const char *format, ...)
846 {
847   va_list args;
848   int ret;
849   va_start (args, format);
850   ret = vsnprintf (buf, size, format, args);
851   va_end (args);
852   return ret;
853 }
854 int main()
855 {
856   static char buf[8] = "DEADBEEF";
857   my_snprintf (buf, 0, "%d", 12345);
858   return buf[0] != 'D';
859 }],
860       [gl_cv_func_vsnprintf_zerosize_c99=yes],
861       [gl_cv_func_vsnprintf_zerosize_c99=no],
862       [
863 changequote(,)dnl
864        case "$host_os" in
865                                # Guess yes on glibc systems.
866          *-gnu*)               gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
867                                # Guess yes on FreeBSD >= 5.
868          freebsd[1-4]*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
869          freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
870                                # Guess yes on MacOS X >= 10.3.
871          darwin[1-6].*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
872          darwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
873                                # Guess yes on Cygwin.
874          cygwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
875                                # Guess yes on Solaris >= 2.6.
876          solaris2.[0-5]*)      gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
877          solaris*)             gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
878                                # Guess yes on AIX >= 4.
879          aix[1-3]*)            gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
880          aix*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
881                                # Guess yes on IRIX >= 6.5.
882          irix6.5)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
883                                # Guess yes on NetBSD >= 3.
884          netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
885                                gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
886          netbsd*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
887                                # Guess yes on BeOS.
888          beos*)                gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
889                                # Guess yes on mingw.
890          mingw* | pw*)         gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
891                                # If we don't know, assume the worst.
892          *)                    gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
893        esac
894 changequote([,])dnl
895       ])
896     ])
897 ])
898
899 dnl The results of these tests on various platforms are:
900 dnl
901 dnl 1 = gl_PRINTF_SIZES_C99
902 dnl 2 = gl_PRINTF_LONG_DOUBLE
903 dnl 3 = gl_PRINTF_INFINITE
904 dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
905 dnl 5 = gl_PRINTF_DIRECTIVE_A
906 dnl 6 = gl_PRINTF_DIRECTIVE_F
907 dnl 7 = gl_PRINTF_DIRECTIVE_N
908 dnl 8 = gl_PRINTF_POSITIONS
909 dnl 9 = gl_PRINTF_FLAG_GROUPING
910 dnl 10 = gl_PRINTF_FLAG_ZERO
911 dnl 11 = gl_SNPRINTF_PRESENCE
912 dnl 12 = gl_SNPRINTF_TRUNCATION_C99
913 dnl 13 = gl_SNPRINTF_RETVAL_C99
914 dnl 14 = gl_SNPRINTF_DIRECTIVE_N
915 dnl 15 = gl_VSNPRINTF_ZEROSIZE_C99
916 dnl
917 dnl 1 = checking whether printf supports size specifiers as in C99...
918 dnl 2 = checking whether printf supports 'long double' arguments...
919 dnl 3 = checking whether printf supports infinite 'double' arguments...
920 dnl 4 = checking whether printf supports infinite 'long double' arguments...
921 dnl 5 = checking whether printf supports the 'a' and 'A' directives...
922 dnl 6 = checking whether printf supports the 'F' directive...
923 dnl 7 = checking whether printf supports the 'n' directive...
924 dnl 8 = checking whether printf supports POSIX/XSI format strings with positions...
925 dnl 9 = checking whether printf supports the grouping flag...
926 dnl 10 = checking whether printf supports the zero flag correctly...
927 dnl 11 = checking for snprintf...
928 dnl 12 = checking whether snprintf truncates the result as in C99...
929 dnl 13 = checking whether snprintf returns a byte count as in C99...
930 dnl 14 = checking whether snprintf fully supports the 'n' directive...
931 dnl 15 = checking whether vsnprintf respects a zero size as in C99...
932 dnl
933 dnl . = yes, # = no.
934 dnl
935 dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
936 dnl   glibc 2.5                      .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
937 dnl   glibc 2.3.6                    .  .  .  .  #  .  .  .  .  .  .  .  .  .  .
938 dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  .  .  .  .  #  .  .  .  .  .
939 dnl   MacOS X 10.3.9                 .  .  .  .  #  .  .  .  .  #  .  .  .  .  .
940 dnl   OpenBSD 3.9, 4.0               .  ?  ?  ?  #  ?  .  .  ?  ?  .  .  .  ?  ?
941 dnl   Cygwin 2007 (= Cygwin 1.5.24)  .  .  .  .  #  #  .  .  .  #  .  .  .  .  .
942 dnl   Cygwin 2006 (= Cygwin 1.5.19)  #  .  .  .  #  #  .  .  #  #  .  .  .  .  .
943 dnl   Solaris 10                     .  .  #  #  #  .  .  .  .  #  .  .  .  .  .
944 dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  .  .  .  #  .  .  .  .  .
945 dnl   Solaris 2.5.1                  #  .  #  #  #  #  .  .  .  #  #  #  #  #  #
946 dnl   AIX 5.2                        .  .  #  #  #  .  .  .  .  #  .  .  .  .  .
947 dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  .  .  .  #  .  .  .  .  .
948 dnl   HP-UX 11.31                    .  .  .  .  #  .  .  .  .  #  .  .  #  #  .
949 dnl   HP-UX 10.20, 11.{00,11,23}     #  .  .  .  #  #  .  .  .  #  .  .  #  #  #
950 dnl   IRIX 6.5                       #  .  #  #  #  #  .  .  .  #  .  .  #  .  .
951 dnl   OSF/1 5.1                      #  .  #  #  #  #  .  .  .  #  .  .  #  .  #
952 dnl   OSF/1 4.0d                     #  .  #  #  #  #  .  .  .  #  #  #  #  #  #
953 dnl   NetBSD 4.0                     .  ?  ?  ?  ?  ?  .  .  ?  ?  .  .  .  ?  ?
954 dnl   NetBSD 3.0                     .  .  .  .  #  #  .  #  #  #  .  .  .  .  .
955 dnl   BeOS                           #  #  .  #  #  #  .  #  .  .  .  .  .  .  .
956 dnl   mingw                          #  #  #  #  #  #  .  #  #  #  .  #  #  #  .