Add info about OpenBSD.
[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 If we don't know, assume the worst.
156          *)                    gl_cv_func_printf_directive_a="guessing no";;
157        esac
158 changequote([,])dnl
159       ])
160     ])
161 ])
162
163 dnl Test whether the *printf family of functions supports the %n format
164 dnl directive. (ISO C99, POSIX:2001)
165 dnl Result is gl_cv_func_printf_directive_n.
166
167 AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
168 [
169   AC_REQUIRE([AC_PROG_CC])
170   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
171   AC_CACHE_CHECK([whether printf supports the 'n' directive],
172     [gl_cv_func_printf_directive_n], 
173     [
174       AC_TRY_RUN([
175 #include <stdio.h>
176 #include <string.h>
177 static char buf[100];
178 int main ()
179 {
180   int count = -1;
181   if (sprintf (buf, "%d %n", 123, &count, 33, 44, 55) < 0
182       || strcmp (buf, "123 ") != 0
183       || count != 4)
184     return 1;
185   return 0;
186 }], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no],
187       [
188 changequote(,)dnl
189        case "$host_os" in
190          hpux*) gl_cv_func_printf_directive_n="guessing no";;
191          *)     gl_cv_func_printf_directive_n="guessing yes";;
192        esac
193 changequote([,])dnl
194       ])
195     ])
196 ])
197
198 dnl Test whether the *printf family of functions supports POSIX/XSI format
199 dnl strings with positions. (POSIX:2001)
200 dnl Result is gl_cv_func_printf_positions.
201
202 AC_DEFUN([gl_PRINTF_POSITIONS],
203 [
204   AC_REQUIRE([AC_PROG_CC])
205   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
206   AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
207     [gl_cv_func_printf_positions], 
208     [
209       AC_TRY_RUN([
210 #include <stdio.h>
211 #include <string.h>
212 /* The string "%2$d %1$d", with dollar characters protected from the shell's
213    dollar expansion (possibly an autoconf bug).  */
214 static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
215 static char buf[100];
216 int main ()
217 {
218   sprintf (buf, format, 33, 55);
219   return (strcmp (buf, "55 33") != 0);
220 }], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no],
221       [
222 changequote(,)dnl
223        case "$host_os" in
224          netbsd*)      gl_cv_func_printf_positions="guessing no";;
225          beos*)        gl_cv_func_printf_positions="guessing no";;
226          mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
227          *)            gl_cv_func_printf_positions="guessing yes";;
228        esac
229 changequote([,])dnl
230       ])
231     ])
232 ])
233
234 dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
235 dnl Result is ac_cv_func_snprintf.
236
237 AC_DEFUN([gl_SNPRINTF_PRESENCE],
238 [
239   AC_CHECK_FUNCS_ONCE([snprintf])
240 ])
241
242 dnl Test whether the string produced by the snprintf function is always NUL
243 dnl terminated. (ISO C99, POSIX:2001)
244 dnl Result is gl_cv_func_snprintf_truncation_c99.
245
246 AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
247 [
248   AC_REQUIRE([AC_PROG_CC])
249   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
250   AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
251     [gl_cv_func_snprintf_truncation_c99], 
252     [
253       AC_TRY_RUN([
254 #include <stdio.h>
255 #include <string.h>
256 static char buf[100];
257 int main ()
258 {
259   strcpy (buf, "ABCDEF");
260   snprintf (buf, 3, "%d %d", 4567, 89);
261   if (memcmp (buf, "45\0DEF", 6) != 0)
262     return 1;
263   return 0;
264 }], [gl_cv_func_snprintf_truncation_c99=yes], [gl_cv_func_snprintf_truncation_c99=no],
265       [
266 changequote(,)dnl
267        case "$host_os" in
268                                dnl Guess yes on glibc systems.
269          *-gnu*)               gl_cv_func_snprintf_truncation_c99="guessing yes";;
270                                dnl Guess yes on FreeBSD >= 5.
271          freebsd[1-4]*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
272          freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
273                                dnl Guess yes on MacOS X >= 10.3.
274          darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
275          darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
276                                dnl Guess yes on OpenBSD >= 3.9.
277          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
278                                gl_cv_func_snprintf_truncation_c99="guessing no";;
279          openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
280                                dnl Guess yes on Solaris >= 2.6.
281          solaris2.[0-5]*)      gl_cv_func_snprintf_truncation_c99="guessing no";;
282          solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
283                                dnl Guess yes on AIX >= 4.
284          aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
285          aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
286                                dnl Guess yes on HP-UX >= 11.
287          hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
288          hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
289                                dnl Guess yes on IRIX >= 6.5.
290          irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
291                                dnl Guess yes on OSF/1 >= 5.
292          osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
293          osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
294                                dnl Guess yes on NetBSD >= 3.
295          netbsd[1-2]*)         gl_cv_func_snprintf_truncation_c99="guessing no";;
296          netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
297                                dnl Guess yes on BeOS.
298          beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
299                                dnl If we don't know, assume the worst.
300          *)                    gl_cv_func_snprintf_truncation_c99="guessing no";;
301        esac
302 changequote([,])dnl
303       ])
304     ])
305 ])
306
307 dnl Test whether the return value of the snprintf function is the number
308 dnl of bytes (excluding the terminating NUL) that would have been produced
309 dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
310 dnl Result is gl_cv_func_printf_retval_c99.
311
312 AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
313 [
314   AC_REQUIRE([AC_PROG_CC])
315   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
316   AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
317     [gl_cv_func_printf_retval_c99], 
318     [
319       AC_TRY_RUN([
320 #include <stdio.h>
321 #include <string.h>
322 static char buf[100];
323 int main ()
324 {
325   strcpy (buf, "ABCDEF");
326   if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
327     return 1;
328   return 0;
329 }], [gl_cv_func_printf_retval_c99=yes], [gl_cv_func_printf_retval_c99=no],
330       [
331 changequote(,)dnl
332        case "$host_os" in
333                                dnl Guess yes on glibc systems.
334          *-gnu*)               gl_cv_func_printf_retval_c99="guessing yes";;
335                                dnl Guess yes on FreeBSD >= 5.
336          freebsd[1-4]*)        gl_cv_func_printf_retval_c99="guessing no";;
337          freebsd* | kfreebsd*) gl_cv_func_printf_retval_c99="guessing yes";;
338                                dnl Guess yes on MacOS X >= 10.3.
339          darwin[1-6].*)        gl_cv_func_printf_retval_c99="guessing no";;
340          darwin*)              gl_cv_func_printf_retval_c99="guessing yes";;
341                                dnl Guess yes on OpenBSD >= 3.9.
342          openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
343                                gl_cv_func_printf_retval_c99="guessing no";;
344          openbsd*)             gl_cv_func_printf_retval_c99="guessing yes";;
345                                dnl Guess yes on Solaris >= 2.6.
346          solaris2.[0-5]*)      gl_cv_func_printf_retval_c99="guessing no";;
347          solaris*)             gl_cv_func_printf_retval_c99="guessing yes";;
348                                dnl Guess yes on AIX >= 4.
349          aix[1-3]*)            gl_cv_func_printf_retval_c99="guessing no";;
350          aix*)                 gl_cv_func_printf_retval_c99="guessing yes";;
351                                dnl Guess yes on NetBSD >= 3.
352          netbsd[1-2]*)         gl_cv_func_printf_retval_c99="guessing no";;
353          netbsd*)              gl_cv_func_printf_retval_c99="guessing yes";;
354                                dnl Guess yes on BeOS.
355          beos*)                gl_cv_func_printf_retval_c99="guessing yes";;
356                                dnl If we don't know, assume the worst.
357          *)                    gl_cv_func_printf_retval_c99="guessing no";;
358        esac
359 changequote([,])dnl
360       ])
361     ])
362 ])
363
364 dnl The results of these tests on various platforms are:
365 dnl
366 dnl 1 = gl_PRINTF_SIZES_C99
367 dnl 2 = gl_PRINTF_DIRECTIVE_A
368 dnl 3 = gl_PRINTF_DIRECTIVE_N
369 dnl 4 = gl_PRINTF_POSITIONS
370 dnl 5 = gl_SNPRINTF_PRESENCE
371 dnl 6 = gl_SNPRINTF_TRUNCATION_C99
372 dnl 7 = gl_SNPRINTF_RETVAL_C99
373 dnl
374 dnl 1 = checking whether printf supports size specifiers as in C99...
375 dnl 2 = checking whether printf supports the 'a' and 'A' directives...
376 dnl 3 = checking whether printf supports the 'n' directive...
377 dnl 4 = checking whether printf supports POSIX/XSI format strings with positions...
378 dnl 5 = checking for snprintf...
379 dnl 6 = checking whether snprintf truncates the result as in C99...
380 dnl 7 = checking whether snprintf returns a byte count as in C99...
381 dnl
382 dnl . = yes, # = no.
383 dnl
384 dnl                                   1  2  3  4  5  6  7
385 dnl   glibc 2.3.6                     .  #  .  .  .  .  .
386 dnl   FreeBSD 5.4, 6.1                .  .  .  .  .  .  .
387 dnl   MacOS X 10.3.9                  .  #  .  .  .  .  .
388 dnl   OpenBSD 3.9                     .  #  .  .  .  .  .
389 dnl   Cygwin 2007                     .  #  .  .  .  .  .
390 dnl   Cygwin 2006                     #  #  .  .  .  .  .
391 dnl   Solaris 10                      .  #  .  .  .  .  .
392 dnl   Solaris 2.6 ... 9               #  #  .  .  .  .  .
393 dnl   Solaris 2.5.1                   #  #  .  .  #  #  #
394 dnl   AIX 4.3.2, 5.1                  #  #  .  .  .  .  .
395 dnl   HP-UX 11.31                     .  #  .  .  .  .  #
396 dnl   HP-UX 11.00, 11.11, 11.23       #  #  .  .  .  .  #
397 dnl   HP-UX 10.20                     #  #  #  ?  .  ?  #
398 dnl   IRIX 6.5                        #  #  .  .  .  .  #
399 dnl   OSF/1 5.1                       #  #  .  .  .  .  #
400 dnl   OSF/1 4.0d                      #  #  .  .  #  #  #
401 dnl   NetBSD 3.0                      .  #  .  #  .  .  .
402 dnl   BeOS                            #  #  .  #  .  .  .
403 dnl   mingw                           #  #  .  #  .  #  #