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