Add info about NetBSD 4, which has now borrowed the printf implementation
[gnulib.git] / m4 / printf.m4
1 # printf.m4 serial 1
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([gt_TYPE_LONGDOUBLE])
17   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
18   AC_CACHE_CHECK([whether printf supports size specifiers as in C99],
19     [gl_cv_func_printf_sizes_c99], 
20     [
21       AC_TRY_RUN([
22 #include <stddef.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #if HAVE_STDINT_H_WITH_UINTMAX
27 # include <stdint.h>
28 #endif
29 #if HAVE_INTTYPES_H_WITH_UINTMAX
30 # include <inttypes.h>
31 #endif
32 static char buf[100];
33 int main ()
34 {
35 #if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
36   buf[0] = '\0';
37   if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0
38       || strcmp (buf, "12345671 33") != 0)
39     return 1;
40 #endif
41   buf[0] = '\0';
42   if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0
43       || strcmp (buf, "12345672 33") != 0)
44     return 1;
45   buf[0] = '\0';
46   if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
47       || strcmp (buf, "12345673 33") != 0)
48     return 1;
49 #if HAVE_LONG_DOUBLE
50   buf[0] = '\0';
51   if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
52       || strcmp (buf, "1.5 33") != 0)
53     return 1;
54 #endif
55   return 0;
56 }], [gl_cv_func_printf_sizes_c99=yes], [gl_cv_func_printf_sizes_c99=no],
57       [
58 changequote(,)dnl
59        case "$host_os" in
60                                dnl Guess yes on glibc systems.
61          *-gnu*)               gl_cv_func_printf_sizes_c99="guessing yes";;
62                                dnl Guess yes on FreeBSD >= 5.
63          freebsd[1-4]*)        gl_cv_func_printf_sizes_c99="guessing no";;
64          freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
65                                dnl Guess yes on MacOS X >= 10.3.
66          darwin[1-6].*)        gl_cv_func_printf_sizes_c99="guessing no";;
67          darwin*)              gl_cv_func_printf_sizes_c99="guessing yes";;
68                                dnl Guess yes on OpenBSD >= 3.9.
69          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
70                                gl_cv_func_printf_sizes_c99="guessing no";;
71          openbsd*)             gl_cv_func_printf_sizes_c99="guessing yes";;
72                                dnl Guess yes on Solaris >= 2.10.
73          solaris2.[0-9]*)      gl_cv_func_printf_sizes_c99="guessing no";;
74          solaris*)             gl_cv_func_printf_sizes_c99="guessing yes";;
75                                dnl Guess yes on NetBSD >= 3.
76          netbsd[1-2]*)         gl_cv_func_printf_sizes_c99="guessing no";;
77          netbsd*)              gl_cv_func_printf_sizes_c99="guessing yes";;
78                                dnl If we don't know, assume the worst.
79          *)                    gl_cv_func_printf_sizes_c99="guessing no";;
80        esac
81 changequote([,])dnl
82       ])
83     ])
84 ])
85
86 dnl Test whether the *printf family of functions supports the 'a' and 'A'
87 dnl conversion specifier for hexadecimal output of floating-point numbers.
88 dnl (ISO C99, POSIX:2001)
89 dnl Result is gl_cv_func_printf_directive_a.
90
91 AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
92 [
93   AC_REQUIRE([AC_PROG_CC])
94   AC_REQUIRE([gt_TYPE_LONGDOUBLE])
95   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
96   AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
97     [gl_cv_func_printf_directive_a], 
98     [
99       AC_TRY_RUN([
100 #include <stdio.h>
101 #include <string.h>
102 static char buf[100];
103 int main ()
104 {
105   if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
106       || (strcmp (buf, "0x1.922p+1 33") != 0
107           && strcmp (buf, "0x3.244p+0 33") != 0
108           && strcmp (buf, "0x6.488p-1 33") != 0
109           && strcmp (buf, "0xc.91p-2 33") != 0))
110     return 1;
111   if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
112       || (strcmp (buf, "-0X1.922P+1 33") != 0
113           && strcmp (buf, "-0X3.244P+0 33") != 0
114           && strcmp (buf, "-0X6.488P-1 33") != 0
115           && strcmp (buf, "-0XC.91P-2 33") != 0))
116     return 1;
117   /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug.  */
118   if (sprintf (buf, "%.1a", 1.999) < 0
119       || (strcmp (buf, "0x1.0p+1") != 0
120           && strcmp (buf, "0x2.0p+0") != 0
121           && strcmp (buf, "0x4.0p-1") != 0
122           && strcmp (buf, "0x8.0p-2") != 0))
123     return 1;
124 #if HAVE_LONG_DOUBLE
125   /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
126      glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
127   if (sprintf (buf, "%.1La", 1.999L) < 0
128       || (strcmp (buf, "0x1.0p+1") != 0
129           && strcmp (buf, "0x2.0p+0") != 0
130           && strcmp (buf, "0x4.0p-1") != 0
131           && strcmp (buf, "0x8.0p-2") != 0))
132     return 1;
133 #endif
134   return 0;
135 }], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
136       [
137        case "$host_os" in
138                                dnl Guess yes on glibc >= 2.5 systems.
139          *-gnu*)
140            AC_EGREP_CPP([BZ2908], [
141              #include <features.h>
142              #ifdef __GNU_LIBRARY__
143               #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)
144                BZ2908
145               #endif
146              #endif
147              ],
148              [gl_cv_func_printf_directive_a="guessing yes"],
149              [gl_cv_func_printf_directive_a="guessing no"])
150            ;;
151 changequote(,)dnl
152                                dnl Guess yes on FreeBSD >= 5.
153          freebsd[1-4]*)        gl_cv_func_printf_directive_a="guessing no";;
154          freebsd* | kfreebsd*) gl_cv_func_printf_directive_a="guessing yes";;
155                                dnl Guess yes on NetBSD >= 4.
156          netbsd[1-3]*)         gl_cv_func_printf_directive_a="guessing no";;
157          netbsd*)              gl_cv_func_printf_directive_a="guessing yes";;
158                                dnl If we don't know, assume the worst.
159          *)                    gl_cv_func_printf_directive_a="guessing no";;
160        esac
161 changequote([,])dnl
162       ])
163     ])
164 ])
165
166 dnl Test whether the *printf family of functions supports the %n format
167 dnl directive. (ISO C99, POSIX:2001)
168 dnl Result is gl_cv_func_printf_directive_n.
169
170 AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
171 [
172   AC_REQUIRE([AC_PROG_CC])
173   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
174   AC_CACHE_CHECK([whether printf supports the 'n' directive],
175     [gl_cv_func_printf_directive_n], 
176     [
177       AC_TRY_RUN([
178 #include <stdio.h>
179 #include <string.h>
180 static char buf[100];
181 int main ()
182 {
183   int count = -1;
184   if (sprintf (buf, "%d %n", 123, &count, 33, 44, 55) < 0
185       || strcmp (buf, "123 ") != 0
186       || count != 4)
187     return 1;
188   return 0;
189 }], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no],
190       [
191 changequote(,)dnl
192        case "$host_os" in
193          *)     gl_cv_func_printf_directive_n="guessing yes";;
194        esac
195 changequote([,])dnl
196       ])
197     ])
198 ])
199
200 dnl Test whether the *printf family of functions supports POSIX/XSI format
201 dnl strings with positions. (POSIX:2001)
202 dnl Result is gl_cv_func_printf_positions.
203
204 AC_DEFUN([gl_PRINTF_POSITIONS],
205 [
206   AC_REQUIRE([AC_PROG_CC])
207   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
208   AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
209     [gl_cv_func_printf_positions], 
210     [
211       AC_TRY_RUN([
212 #include <stdio.h>
213 #include <string.h>
214 /* The string "%2$d %1$d", with dollar characters protected from the shell's
215    dollar expansion (possibly an autoconf bug).  */
216 static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
217 static char buf[100];
218 int main ()
219 {
220   sprintf (buf, format, 33, 55);
221   return (strcmp (buf, "55 33") != 0);
222 }], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no],
223       [
224 changequote(,)dnl
225        case "$host_os" in
226          netbsd[1-3]*) gl_cv_func_printf_positions="guessing no";;
227          beos*)        gl_cv_func_printf_positions="guessing no";;
228          mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
229          *)            gl_cv_func_printf_positions="guessing yes";;
230        esac
231 changequote([,])dnl
232       ])
233     ])
234 ])
235
236 dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
237 dnl Result is ac_cv_func_snprintf.
238
239 AC_DEFUN([gl_SNPRINTF_PRESENCE],
240 [
241   AC_CHECK_FUNCS_ONCE([snprintf])
242 ])
243
244 dnl Test whether the string produced by the snprintf function is always NUL
245 dnl terminated. (ISO C99, POSIX:2001)
246 dnl Result is gl_cv_func_snprintf_truncation_c99.
247
248 AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
249 [
250   AC_REQUIRE([AC_PROG_CC])
251   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
252   AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
253     [gl_cv_func_snprintf_truncation_c99], 
254     [
255       AC_TRY_RUN([
256 #include <stdio.h>
257 #include <string.h>
258 static char buf[100];
259 int main ()
260 {
261   strcpy (buf, "ABCDEF");
262   snprintf (buf, 3, "%d %d", 4567, 89);
263   if (memcmp (buf, "45\0DEF", 6) != 0)
264     return 1;
265   return 0;
266 }], [gl_cv_func_snprintf_truncation_c99=yes], [gl_cv_func_snprintf_truncation_c99=no],
267       [
268 changequote(,)dnl
269        case "$host_os" in
270                                dnl Guess yes on glibc systems.
271          *-gnu*)               gl_cv_func_snprintf_truncation_c99="guessing yes";;
272                                dnl Guess yes on FreeBSD >= 5.
273          freebsd[1-4]*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
274          freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
275                                dnl Guess yes on MacOS X >= 10.3.
276          darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
277          darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
278                                dnl Guess yes on OpenBSD >= 3.9.
279          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
280                                gl_cv_func_snprintf_truncation_c99="guessing no";;
281          openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
282                                dnl Guess yes on Solaris >= 2.6.
283          solaris2.[0-5]*)      gl_cv_func_snprintf_truncation_c99="guessing no";;
284          solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
285                                dnl Guess yes on AIX >= 4.
286          aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
287          aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
288                                dnl Guess yes on HP-UX >= 11.
289          hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
290          hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
291                                dnl Guess yes on IRIX >= 6.5.
292          irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
293                                dnl Guess yes on OSF/1 >= 5.
294          osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
295          osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
296                                dnl Guess yes on NetBSD >= 3.
297          netbsd[1-2]*)         gl_cv_func_snprintf_truncation_c99="guessing no";;
298          netbsd*           )   gl_cv_func_snprintf_truncation_c99="guessing yes";;
299                                dnl Guess yes on BeOS.
300          beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
301                                dnl If we don't know, assume the worst.
302          *)                    gl_cv_func_snprintf_truncation_c99="guessing no";;
303        esac
304 changequote([,])dnl
305       ])
306     ])
307 ])
308
309 dnl Test whether the return value of the snprintf function is the number
310 dnl of bytes (excluding the terminating NUL) that would have been produced
311 dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
312 dnl Result is gl_cv_func_printf_retval_c99.
313
314 AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
315 [
316   AC_REQUIRE([AC_PROG_CC])
317   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
318   AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
319     [gl_cv_func_printf_retval_c99], 
320     [
321       AC_TRY_RUN([
322 #include <stdio.h>
323 #include <string.h>
324 static char buf[100];
325 int main ()
326 {
327   strcpy (buf, "ABCDEF");
328   if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
329     return 1;
330   return 0;
331 }], [gl_cv_func_printf_retval_c99=yes], [gl_cv_func_printf_retval_c99=no],
332       [
333 changequote(,)dnl
334        case "$host_os" in
335                                dnl Guess yes on glibc systems.
336          *-gnu*)               gl_cv_func_printf_retval_c99="guessing yes";;
337                                dnl Guess yes on FreeBSD >= 5.
338          freebsd[1-4]*)        gl_cv_func_printf_retval_c99="guessing no";;
339          freebsd* | kfreebsd*) gl_cv_func_printf_retval_c99="guessing yes";;
340                                dnl Guess yes on MacOS X >= 10.3.
341          darwin[1-6].*)        gl_cv_func_printf_retval_c99="guessing no";;
342          darwin*)              gl_cv_func_printf_retval_c99="guessing yes";;
343                                dnl Guess yes on OpenBSD >= 3.9.
344          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
345                                gl_cv_func_printf_retval_c99="guessing no";;
346          openbsd*)             gl_cv_func_printf_retval_c99="guessing yes";;
347                                dnl Guess yes on Solaris >= 2.6.
348          solaris2.[0-5]*)      gl_cv_func_printf_retval_c99="guessing no";;
349          solaris*)             gl_cv_func_printf_retval_c99="guessing yes";;
350                                dnl Guess yes on AIX >= 4.
351          aix[1-3]*)            gl_cv_func_printf_retval_c99="guessing no";;
352          aix*)                 gl_cv_func_printf_retval_c99="guessing yes";;
353                                dnl Guess yes on NetBSD >= 3.
354          netbsd[1-2]*)         gl_cv_func_printf_retval_c99="guessing no";;
355          netbsd*)              gl_cv_func_printf_retval_c99="guessing yes";;
356                                dnl Guess yes on BeOS.
357          beos*)                gl_cv_func_printf_retval_c99="guessing yes";;
358                                dnl If we don't know, assume the worst.
359          *)                    gl_cv_func_printf_retval_c99="guessing no";;
360        esac
361 changequote([,])dnl
362       ])
363     ])
364 ])
365
366 dnl The results of these tests on various platforms are:
367 dnl
368 dnl 1 = gl_PRINTF_SIZES_C99
369 dnl 2 = gl_PRINTF_DIRECTIVE_A
370 dnl 3 = gl_PRINTF_DIRECTIVE_N
371 dnl 4 = gl_PRINTF_POSITIONS
372 dnl 5 = gl_SNPRINTF_PRESENCE
373 dnl 6 = gl_SNPRINTF_TRUNCATION_C99
374 dnl 7 = gl_SNPRINTF_RETVAL_C99
375 dnl
376 dnl 1 = checking whether printf supports size specifiers as in C99...
377 dnl 2 = checking whether printf supports the 'a' and 'A' directives...
378 dnl 3 = checking whether printf supports the 'n' directive...
379 dnl 4 = checking whether printf supports POSIX/XSI format strings with positions...
380 dnl 5 = checking for snprintf...
381 dnl 6 = checking whether snprintf truncates the result as in C99...
382 dnl 7 = checking whether snprintf returns a byte count as in C99...
383 dnl
384 dnl . = yes, # = no.
385 dnl
386 dnl                                        1  2  3  4  5  6  7
387 dnl   glibc 2.3.6                          .  #  .  .  .  .  .
388 dnl   FreeBSD 5.4, 6.1                     .  .  .  .  .  .  .
389 dnl   MacOS X 10.3.9                       .  #  .  .  .  .  .
390 dnl   OpenBSD 3.9                          .  #  .  .  .  .  .
391 dnl   Cygwin 2007                          .  #  .  .  .  .  .
392 dnl   Cygwin 2006                          #  #  .  .  .  .  .
393 dnl   Solaris 10                           .  #  .  .  .  .  .
394 dnl   Solaris 2.6 ... 9                    #  #  .  .  .  .  .
395 dnl   Solaris 2.5.1                        #  #  .  .  #  #  #
396 dnl   AIX 4.3.2, 5.1                       #  #  .  .  .  .  .
397 dnl   HP-UX 11.31                          .  #  .  .  .  .  #
398 dnl   HP-UX 10.20, 11.00, 11.11, 11.23     #  #  .  .  .  .  #
399 dnl   IRIX 6.5                             #  #  .  .  .  .  #
400 dnl   OSF/1 5.1                            #  #  .  .  .  .  #
401 dnl   OSF/1 4.0d                           #  #  .  .  #  #  #
402 dnl   NetBSD 4.0                           .  .  .  .  .  .  .
403 dnl   NetBSD 3.0                           .  #  .  #  .  .  .
404 dnl   BeOS                                 #  #  .  #  .  .  .
405 dnl   mingw                                #  #  .  #  .  #  #