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