Add an entertaining `procedure->pointer' test.
[bpt/guile.git] / m4 / printf.m4
CommitLineData
c4b681fd 1# printf.m4 serial 33
61cd9dc9 2dnl Copyright (C) 2003, 2007-2010 Free Software Foundation, Inc.
c4b681fd
LC
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7dnl Test whether the *printf family of functions supports the 'j', 'z', 't',
8dnl 'L' size specifiers. (ISO C99, POSIX:2001)
9dnl Result is gl_cv_func_printf_sizes_c99.
10
11AC_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
31static char buf[100];
32int 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 [
55changequote(,)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
79changequote([,])dnl
80 ])
81 ])
82])
83
84dnl Test whether the *printf family of functions supports 'long double'
85dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
86dnl Result is gl_cv_func_printf_long_double.
87
88AC_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>
98static char buf[10000];
99int 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 [
116changequote(,)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
122changequote([,])dnl
123 ])
124 ])
125])
126
127dnl Test whether the *printf family of functions supports infinite and NaN
128dnl 'double' arguments and negative zero arguments in the %f, %e, %g
129dnl directives. (ISO C99, POSIX:2001)
130dnl Result is gl_cv_func_printf_infinite.
131
132AC_DEFUN([gl_PRINTF_INFINITE],
133[
134 AC_REQUIRE([AC_PROG_CC])
135 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
136 AC_CACHE_CHECK([whether printf supports infinite 'double' arguments],
137 [gl_cv_func_printf_infinite],
138 [
139 AC_TRY_RUN([
140#include <stdio.h>
141#include <string.h>
142static int
143strisnan (const char *string, size_t start_index, size_t end_index)
144{
145 if (start_index < end_index)
146 {
147 if (string[start_index] == '-')
148 start_index++;
149 if (start_index + 3 <= end_index
150 && memcmp (string + start_index, "nan", 3) == 0)
151 {
152 start_index += 3;
153 if (start_index == end_index
154 || (string[start_index] == '(' && string[end_index - 1] == ')'))
155 return 1;
156 }
157 }
158 return 0;
159}
160static int
161have_minus_zero ()
162{
163 static double plus_zero = 0.0;
164 double minus_zero = - plus_zero;
165 return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
166}
167static char buf[10000];
168static double zero = 0.0;
169int main ()
170{
171 if (sprintf (buf, "%f", 1.0 / 0.0) < 0
172 || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
173 return 1;
174 if (sprintf (buf, "%f", -1.0 / 0.0) < 0
175 || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
176 return 1;
177 if (sprintf (buf, "%f", zero / zero) < 0
178 || !strisnan (buf, 0, strlen (buf)))
179 return 1;
180 if (sprintf (buf, "%e", 1.0 / 0.0) < 0
181 || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
182 return 1;
183 if (sprintf (buf, "%e", -1.0 / 0.0) < 0
184 || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
185 return 1;
186 if (sprintf (buf, "%e", zero / zero) < 0
187 || !strisnan (buf, 0, strlen (buf)))
188 return 1;
189 if (sprintf (buf, "%g", 1.0 / 0.0) < 0
190 || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
191 return 1;
192 if (sprintf (buf, "%g", -1.0 / 0.0) < 0
193 || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
194 return 1;
195 if (sprintf (buf, "%g", zero / zero) < 0
196 || !strisnan (buf, 0, strlen (buf)))
197 return 1;
198 /* This test fails on HP-UX 10.20. */
199 if (have_minus_zero ())
200 if (sprintf (buf, "%g", - zero) < 0
201 || strcmp (buf, "-0") != 0)
202 return 1;
203 return 0;
204}], [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no],
205 [
206changequote(,)dnl
207 case "$host_os" in
208 # Guess yes on glibc systems.
209 *-gnu*) gl_cv_func_printf_infinite="guessing yes";;
210 # Guess yes on FreeBSD >= 6.
211 freebsd[1-5]*) gl_cv_func_printf_infinite="guessing no";;
212 freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";;
213 # Guess yes on MacOS X >= 10.3.
214 darwin[1-6].*) gl_cv_func_printf_infinite="guessing no";;
215 darwin*) gl_cv_func_printf_infinite="guessing yes";;
216 # Guess yes on HP-UX >= 11.
217 hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
218 hpux*) gl_cv_func_printf_infinite="guessing yes";;
219 # Guess yes on NetBSD >= 3.
220 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
221 gl_cv_func_printf_infinite="guessing no";;
222 netbsd*) gl_cv_func_printf_infinite="guessing yes";;
223 # Guess yes on BeOS.
224 beos*) gl_cv_func_printf_infinite="guessing yes";;
225 # If we don't know, assume the worst.
226 *) gl_cv_func_printf_infinite="guessing no";;
227 esac
228changequote([,])dnl
229 ])
230 ])
231])
232
233dnl Test whether the *printf family of functions supports infinite and NaN
234dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
235dnl Result is gl_cv_func_printf_infinite_long_double.
236
237AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
238[
239 AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
240 AC_REQUIRE([AC_PROG_CC])
241 AC_REQUIRE([gl_BIGENDIAN])
242 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
243 dnl The user can set or unset the variable gl_printf_safe to indicate
244 dnl that he wishes a safe handling of non-IEEE-754 'long double' values.
245 if test -n "$gl_printf_safe"; then
246 AC_DEFINE([CHECK_PRINTF_SAFE], [1],
247 [Define if you wish *printf() functions that have a safe handling of
248 non-IEEE-754 'long double' values.])
249 fi
250 case "$gl_cv_func_printf_long_double" in
251 *yes)
252 AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments],
253 [gl_cv_func_printf_infinite_long_double],
254 [
255 AC_TRY_RUN([
256]GL_NOCRASH[
257#include <float.h>
258#include <stdio.h>
259#include <string.h>
260static int
261strisnan (const char *string, size_t start_index, size_t end_index)
262{
263 if (start_index < end_index)
264 {
265 if (string[start_index] == '-')
266 start_index++;
267 if (start_index + 3 <= end_index
268 && memcmp (string + start_index, "nan", 3) == 0)
269 {
270 start_index += 3;
271 if (start_index == end_index
272 || (string[start_index] == '(' && string[end_index - 1] == ')'))
273 return 1;
274 }
275 }
276 return 0;
277}
278static char buf[10000];
279static long double zeroL = 0.0L;
280int main ()
281{
282 nocrash_init();
283 if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0
284 || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
285 return 1;
286 if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0
287 || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
288 return 1;
289 if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
290 || !strisnan (buf, 0, strlen (buf)))
291 return 1;
292 if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0
293 || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
294 return 1;
295 if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0
296 || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
297 return 1;
298 if (sprintf (buf, "%Le", zeroL / zeroL) < 0
299 || !strisnan (buf, 0, strlen (buf)))
300 return 1;
301 if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0
302 || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
303 return 1;
304 if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0
305 || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
306 return 1;
307 if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
308 || !strisnan (buf, 0, strlen (buf)))
309 return 1;
310#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
311/* Representation of an 80-bit 'long double' as an initializer for a sequence
312 of 'unsigned int' words. */
313# ifdef WORDS_BIGENDIAN
314# define LDBL80_WORDS(exponent,manthi,mantlo) \
315 { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
316 ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
317 (unsigned int) (mantlo) << 16 \
318 }
319# else
320# define LDBL80_WORDS(exponent,manthi,mantlo) \
321 { mantlo, manthi, exponent }
322# endif
323 { /* Quiet NaN. */
324 static union { unsigned int word[4]; long double value; } x =
325 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
326 if (sprintf (buf, "%Lf", x.value) < 0
327 || !strisnan (buf, 0, strlen (buf)))
328 return 1;
329 if (sprintf (buf, "%Le", x.value) < 0
330 || !strisnan (buf, 0, strlen (buf)))
331 return 1;
332 if (sprintf (buf, "%Lg", x.value) < 0
333 || !strisnan (buf, 0, strlen (buf)))
334 return 1;
335 }
336 {
337 /* Signalling NaN. */
338 static union { unsigned int word[4]; long double value; } x =
339 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
340 if (sprintf (buf, "%Lf", x.value) < 0
341 || !strisnan (buf, 0, strlen (buf)))
342 return 1;
343 if (sprintf (buf, "%Le", x.value) < 0
344 || !strisnan (buf, 0, strlen (buf)))
345 return 1;
346 if (sprintf (buf, "%Lg", x.value) < 0
347 || !strisnan (buf, 0, strlen (buf)))
348 return 1;
349 }
350 { /* Pseudo-NaN. */
351 static union { unsigned int word[4]; long double value; } x =
352 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
353 if (sprintf (buf, "%Lf", x.value) < 0
354 || !strisnan (buf, 0, strlen (buf)))
355 return 1;
356 if (sprintf (buf, "%Le", x.value) < 0
357 || !strisnan (buf, 0, strlen (buf)))
358 return 1;
359 if (sprintf (buf, "%Lg", x.value) < 0
360 || !strisnan (buf, 0, strlen (buf)))
361 return 1;
362 }
363 { /* Pseudo-Infinity. */
364 static union { unsigned int word[4]; long double value; } x =
365 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
366 if (sprintf (buf, "%Lf", x.value) < 0
367 || !strisnan (buf, 0, strlen (buf)))
368 return 1;
369 if (sprintf (buf, "%Le", x.value) < 0
370 || !strisnan (buf, 0, strlen (buf)))
371 return 1;
372 if (sprintf (buf, "%Lg", x.value) < 0
373 || !strisnan (buf, 0, strlen (buf)))
374 return 1;
375 }
376 { /* Pseudo-Zero. */
377 static union { unsigned int word[4]; long double value; } x =
378 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
379 if (sprintf (buf, "%Lf", x.value) < 0
380 || !strisnan (buf, 0, strlen (buf)))
381 return 1;
382 if (sprintf (buf, "%Le", x.value) < 0
383 || !strisnan (buf, 0, strlen (buf)))
384 return 1;
385 if (sprintf (buf, "%Lg", x.value) < 0
386 || !strisnan (buf, 0, strlen (buf)))
387 return 1;
388 }
389 { /* Unnormalized number. */
390 static union { unsigned int word[4]; long double value; } x =
391 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
392 if (sprintf (buf, "%Lf", x.value) < 0
393 || !strisnan (buf, 0, strlen (buf)))
394 return 1;
395 if (sprintf (buf, "%Le", x.value) < 0
396 || !strisnan (buf, 0, strlen (buf)))
397 return 1;
398 if (sprintf (buf, "%Lg", x.value) < 0
399 || !strisnan (buf, 0, strlen (buf)))
400 return 1;
401 }
402 { /* Pseudo-Denormal. */
403 static union { unsigned int word[4]; long double value; } x =
404 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
405 if (sprintf (buf, "%Lf", x.value) < 0
406 || !strisnan (buf, 0, strlen (buf)))
407 return 1;
408 if (sprintf (buf, "%Le", x.value) < 0
409 || !strisnan (buf, 0, strlen (buf)))
410 return 1;
411 if (sprintf (buf, "%Lg", x.value) < 0
412 || !strisnan (buf, 0, strlen (buf)))
413 return 1;
414 }
415#endif
416 return 0;
417}],
418 [gl_cv_func_printf_infinite_long_double=yes],
419 [gl_cv_func_printf_infinite_long_double=no],
420 [
421changequote(,)dnl
422 case "$host_cpu" in
423 # Guess no on ia64, x86_64, i386.
424 ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";;
425 *)
426 case "$host_os" in
427 # Guess yes on glibc systems.
428 *-gnu*) gl_cv_func_printf_infinite_long_double="guessing yes";;
429 # Guess yes on FreeBSD >= 6.
430 freebsd[1-5]*) gl_cv_func_printf_infinite_long_double="guessing no";;
431 freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";;
432 # Guess yes on MacOS X >= 10.3.
433 darwin[1-6].*) gl_cv_func_printf_infinite_long_double="guessing no";;
434 darwin*) gl_cv_func_printf_infinite_long_double="guessing yes";;
435 # Guess yes on HP-UX >= 11.
436 hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";;
437 hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";;
438 # Guess yes on NetBSD >= 3.
439 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
440 gl_cv_func_printf_infinite_long_double="guessing no";;
441 netbsd*) gl_cv_func_printf_infinite_long_double="guessing yes";;
442 # If we don't know, assume the worst.
443 *) gl_cv_func_printf_infinite_long_double="guessing no";;
444 esac
445 ;;
446 esac
447changequote([,])dnl
448 ])
449 ])
450 ;;
451 *)
452 gl_cv_func_printf_infinite_long_double="irrelevant"
453 ;;
454 esac
455])
456
457dnl Test whether the *printf family of functions supports the 'a' and 'A'
458dnl conversion specifier for hexadecimal output of floating-point numbers.
459dnl (ISO C99, POSIX:2001)
460dnl Result is gl_cv_func_printf_directive_a.
461
462AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
463[
464 AC_REQUIRE([AC_PROG_CC])
465 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
466 AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
467 [gl_cv_func_printf_directive_a],
468 [
469 AC_TRY_RUN([
470#include <stdio.h>
471#include <string.h>
472static char buf[100];
473int main ()
474{
475 if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
476 || (strcmp (buf, "0x1.922p+1 33") != 0
477 && strcmp (buf, "0x3.244p+0 33") != 0
478 && strcmp (buf, "0x6.488p-1 33") != 0
479 && strcmp (buf, "0xc.91p-2 33") != 0))
480 return 1;
481 if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
482 || (strcmp (buf, "-0X1.922P+1 33") != 0
483 && strcmp (buf, "-0X3.244P+0 33") != 0
484 && strcmp (buf, "-0X6.488P-1 33") != 0
485 && strcmp (buf, "-0XC.91P-2 33") != 0))
486 return 1;
487 /* This catches a FreeBSD 6.1 bug: it doesn't round. */
488 if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
489 || (strcmp (buf, "0x1.83p+0 33") != 0
490 && strcmp (buf, "0x3.05p-1 33") != 0
491 && strcmp (buf, "0x6.0ap-2 33") != 0
492 && strcmp (buf, "0xc.14p-3 33") != 0))
493 return 1;
494 /* This catches a FreeBSD 6.1 bug. See
495 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
496 if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0
497 || buf[0] == '0')
498 return 1;
499 /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug. */
500 if (sprintf (buf, "%.1a", 1.999) < 0
501 || (strcmp (buf, "0x1.0p+1") != 0
502 && strcmp (buf, "0x2.0p+0") != 0
503 && strcmp (buf, "0x4.0p-1") != 0
504 && strcmp (buf, "0x8.0p-2") != 0))
505 return 1;
506 /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
507 glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
508 if (sprintf (buf, "%.1La", 1.999L) < 0
509 || (strcmp (buf, "0x1.0p+1") != 0
510 && strcmp (buf, "0x2.0p+0") != 0
511 && strcmp (buf, "0x4.0p-1") != 0
512 && strcmp (buf, "0x8.0p-2") != 0))
513 return 1;
514 return 0;
515}], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
516 [
517 case "$host_os" in
518 # Guess yes on glibc >= 2.5 systems.
519 *-gnu*)
520 AC_EGREP_CPP([BZ2908], [
521 #include <features.h>
522 #ifdef __GNU_LIBRARY__
523 #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)
524 BZ2908
525 #endif
526 #endif
527 ],
528 [gl_cv_func_printf_directive_a="guessing yes"],
529 [gl_cv_func_printf_directive_a="guessing no"])
530 ;;
531 # If we don't know, assume the worst.
532 *) gl_cv_func_printf_directive_a="guessing no";;
533 esac
534 ])
535 ])
536])
537
538dnl Test whether the *printf family of functions supports the %F format
539dnl directive. (ISO C99, POSIX:2001)
540dnl Result is gl_cv_func_printf_directive_f.
541
542AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
543[
544 AC_REQUIRE([AC_PROG_CC])
545 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
546 AC_CACHE_CHECK([whether printf supports the 'F' directive],
547 [gl_cv_func_printf_directive_f],
548 [
549 AC_TRY_RUN([
550#include <stdio.h>
551#include <string.h>
552static char buf[100];
553int main ()
554{
555 if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
556 || strcmp (buf, "1234567.000000 33") != 0)
557 return 1;
558 if (sprintf (buf, "%F", 1.0 / 0.0) < 0
559 || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
560 return 1;
561 /* This catches a Cygwin 1.5.x bug. */
562 if (sprintf (buf, "%.F", 1234.0) < 0
563 || strcmp (buf, "1234") != 0)
564 return 1;
565 return 0;
566}], [gl_cv_func_printf_directive_f=yes], [gl_cv_func_printf_directive_f=no],
567 [
568changequote(,)dnl
569 case "$host_os" in
570 # Guess yes on glibc systems.
571 *-gnu*) gl_cv_func_printf_directive_f="guessing yes";;
572 # Guess yes on FreeBSD >= 6.
573 freebsd[1-5]*) gl_cv_func_printf_directive_f="guessing no";;
574 freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
575 # Guess yes on MacOS X >= 10.3.
576 darwin[1-6].*) gl_cv_func_printf_directive_f="guessing no";;
577 darwin*) gl_cv_func_printf_directive_f="guessing yes";;
578 # Guess yes on Solaris >= 2.10.
579 solaris2.[0-9]*) gl_cv_func_printf_directive_f="guessing no";;
580 solaris*) gl_cv_func_printf_directive_f="guessing yes";;
581 # If we don't know, assume the worst.
582 *) gl_cv_func_printf_directive_f="guessing no";;
583 esac
584changequote([,])dnl
585 ])
586 ])
587])
588
589dnl Test whether the *printf family of functions supports the %n format
590dnl directive. (ISO C99, POSIX:2001)
591dnl Result is gl_cv_func_printf_directive_n.
592
593AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
594[
595 AC_REQUIRE([AC_PROG_CC])
596 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
597 AC_CACHE_CHECK([whether printf supports the 'n' directive],
598 [gl_cv_func_printf_directive_n],
599 [
600 AC_TRY_RUN([
601#include <stdio.h>
602#include <string.h>
603static char fmtstring[10];
604static char buf[100];
605int main ()
606{
607 int count = -1;
608 /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2)
609 support %n in format strings in read-only memory but not in writable
610 memory. */
611 strcpy (fmtstring, "%d %n");
612 if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0
613 || strcmp (buf, "123 ") != 0
614 || count != 4)
615 return 1;
616 return 0;
617}], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no],
618 [
619changequote(,)dnl
620 case "$host_os" in
621 *) gl_cv_func_printf_directive_n="guessing yes";;
622 esac
623changequote([,])dnl
624 ])
625 ])
626])
627
628dnl Test whether the *printf family of functions supports the %ls format
629dnl directive and in particular, when a precision is specified, whether
630dnl the functions stop converting the wide string argument when the number
631dnl of bytes that have been produced by this conversion equals or exceeds
632dnl the precision.
633dnl Result is gl_cv_func_printf_directive_ls.
634
635AC_DEFUN([gl_PRINTF_DIRECTIVE_LS],
636[
637 AC_REQUIRE([AC_PROG_CC])
638 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
639 AC_CACHE_CHECK([whether printf supports the 'ls' directive],
640 [gl_cv_func_printf_directive_ls],
641 [
642 AC_TRY_RUN([
643/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
644 <wchar.h>.
645 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
646 included before <wchar.h>. */
647#include <stddef.h>
648#include <stdio.h>
649#include <time.h>
650#include <wchar.h>
651#include <string.h>
652int main ()
653{
654 char buf[100];
655 /* Test whether %ls works at all.
656 This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
657 Cygwin 1.5. */
658 {
659 static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
660 buf[0] = '\0';
661 if (sprintf (buf, "%ls", wstring) < 0
662 || strcmp (buf, "abc") != 0)
663 return 1;
664 }
665 /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
666 assertion failure inside libc), but not on OpenBSD 4.0. */
667 {
668 static const wchar_t wstring[] = { 'a', 0 };
669 buf[0] = '\0';
670 if (sprintf (buf, "%ls", wstring) < 0
671 || strcmp (buf, "a") != 0)
672 return 1;
673 }
674 /* Test whether precisions in %ls are supported as specified in ISO C 99
675 section 7.19.6.1:
676 "If a precision is specified, no more than that many bytes are written
677 (including shift sequences, if any), and the array shall contain a
678 null wide character if, to equal the multibyte character sequence
679 length given by the precision, the function would need to access a
680 wide character one past the end of the array."
681 This test fails on Solaris 10. */
682 {
683 static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 };
684 buf[0] = '\0';
685 if (sprintf (buf, "%.2ls", wstring) < 0
686 || strcmp (buf, "ab") != 0)
687 return 1;
688 }
689 return 0;
690}], [gl_cv_func_printf_directive_ls=yes], [gl_cv_func_printf_directive_ls=no],
691 [
692changequote(,)dnl
693 case "$host_os" in
694 openbsd*) gl_cv_func_printf_directive_ls="guessing no";;
695 irix*) gl_cv_func_printf_directive_ls="guessing no";;
696 solaris*) gl_cv_func_printf_directive_ls="guessing no";;
697 cygwin*) gl_cv_func_printf_directive_ls="guessing no";;
698 beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";;
699 *) gl_cv_func_printf_directive_ls="guessing yes";;
700 esac
701changequote([,])dnl
702 ])
703 ])
704])
705
706dnl Test whether the *printf family of functions supports POSIX/XSI format
707dnl strings with positions. (POSIX:2001)
708dnl Result is gl_cv_func_printf_positions.
709
710AC_DEFUN([gl_PRINTF_POSITIONS],
711[
712 AC_REQUIRE([AC_PROG_CC])
713 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
714 AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
715 [gl_cv_func_printf_positions],
716 [
717 AC_TRY_RUN([
718#include <stdio.h>
719#include <string.h>
720/* The string "%2$d %1$d", with dollar characters protected from the shell's
721 dollar expansion (possibly an autoconf bug). */
722static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
723static char buf[100];
724int main ()
725{
726 sprintf (buf, format, 33, 55);
727 return (strcmp (buf, "55 33") != 0);
728}], [gl_cv_func_printf_positions=yes], [gl_cv_func_printf_positions=no],
729 [
730changequote(,)dnl
731 case "$host_os" in
732 netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
733 gl_cv_func_printf_positions="guessing no";;
734 beos*) gl_cv_func_printf_positions="guessing no";;
735 mingw* | pw*) gl_cv_func_printf_positions="guessing no";;
736 *) gl_cv_func_printf_positions="guessing yes";;
737 esac
738changequote([,])dnl
739 ])
740 ])
741])
742
743dnl Test whether the *printf family of functions supports POSIX/XSI format
744dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
745dnl Result is gl_cv_func_printf_flag_grouping.
746
747AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
748[
749 AC_REQUIRE([AC_PROG_CC])
750 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
751 AC_CACHE_CHECK([whether printf supports the grouping flag],
752 [gl_cv_func_printf_flag_grouping],
753 [
754 AC_TRY_RUN([
755#include <stdio.h>
756#include <string.h>
757static char buf[100];
758int main ()
759{
760 if (sprintf (buf, "%'d %d", 1234567, 99) < 0
761 || buf[strlen (buf) - 1] != '9')
762 return 1;
763 return 0;
764}], [gl_cv_func_printf_flag_grouping=yes], [gl_cv_func_printf_flag_grouping=no],
765 [
766changequote(,)dnl
767 case "$host_os" in
768 cygwin*) gl_cv_func_printf_flag_grouping="guessing no";;
769 netbsd*) gl_cv_func_printf_flag_grouping="guessing no";;
770 mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";;
771 *) gl_cv_func_printf_flag_grouping="guessing yes";;
772 esac
773changequote([,])dnl
774 ])
775 ])
776])
777
778dnl Test whether the *printf family of functions supports the - flag correctly.
779dnl (ISO C99.) See
780dnl <http://lists.gnu.org/archive/html/bug-coreutils/2008-02/msg00035.html>
781dnl Result is gl_cv_func_printf_flag_leftadjust.
782
783AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST],
784[
785 AC_REQUIRE([AC_PROG_CC])
786 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
787 AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly],
788 [gl_cv_func_printf_flag_leftadjust],
789 [
790 AC_TRY_RUN([
791#include <stdio.h>
792#include <string.h>
793static char buf[100];
794int main ()
795{
796 /* Check that a '-' flag is not annihilated by a negative width. */
797 if (sprintf (buf, "a%-*sc", -3, "b") < 0
798 || strcmp (buf, "ab c") != 0)
799 return 1;
800 return 0;
801}],
802 [gl_cv_func_printf_flag_leftadjust=yes],
803 [gl_cv_func_printf_flag_leftadjust=no],
804 [
805changequote(,)dnl
806 case "$host_os" in
807 # Guess yes on HP-UX 11.
808 hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";;
809 # Guess no on HP-UX 10 and older.
810 hpux*) gl_cv_func_printf_flag_leftadjust="guessing no";;
811 # Guess yes otherwise.
812 *) gl_cv_func_printf_flag_leftadjust="guessing yes";;
813 esac
814changequote([,])dnl
815 ])
816 ])
817])
818
819dnl Test whether the *printf family of functions supports padding of non-finite
820dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
821dnl <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html>
822dnl Result is gl_cv_func_printf_flag_zero.
823
824AC_DEFUN([gl_PRINTF_FLAG_ZERO],
825[
826 AC_REQUIRE([AC_PROG_CC])
827 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
828 AC_CACHE_CHECK([whether printf supports the zero flag correctly],
829 [gl_cv_func_printf_flag_zero],
830 [
831 AC_TRY_RUN([
832#include <stdio.h>
833#include <string.h>
834static char buf[100];
835int main ()
836{
837 if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0
838 || (strcmp (buf, " inf") != 0
839 && strcmp (buf, " infinity") != 0))
840 return 1;
841 return 0;
842}], [gl_cv_func_printf_flag_zero=yes], [gl_cv_func_printf_flag_zero=no],
843 [
844changequote(,)dnl
845 case "$host_os" in
846 # Guess yes on glibc systems.
847 *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";;
848 # Guess yes on BeOS.
849 beos*) gl_cv_func_printf_flag_zero="guessing yes";;
850 # If we don't know, assume the worst.
851 *) gl_cv_func_printf_flag_zero="guessing no";;
852 esac
853changequote([,])dnl
854 ])
855 ])
856])
857
858dnl Test whether the *printf family of functions supports large precisions.
859dnl On mingw, precisions larger than 512 are treated like 512, in integer,
860dnl floating-point or pointer output. On BeOS, precisions larger than 1044
861dnl crash the program.
862dnl Result is gl_cv_func_printf_precision.
863
864AC_DEFUN([gl_PRINTF_PRECISION],
865[
866 AC_REQUIRE([AC_PROG_CC])
867 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
868 AC_CACHE_CHECK([whether printf supports large precisions],
869 [gl_cv_func_printf_precision],
870 [
871 AC_TRY_RUN([
872#include <stdio.h>
873#include <string.h>
874static char buf[5000];
875int main ()
876{
877#ifdef __BEOS__
878 /* On BeOS, this would crash and show a dialog box. Avoid the crash. */
879 return 1;
880#endif
881 if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3)
882 return 1;
883 return 0;
884}], [gl_cv_func_printf_precision=yes], [gl_cv_func_printf_precision=no],
885 [
886changequote(,)dnl
887 case "$host_os" in
888 # Guess no only on native Win32 and BeOS systems.
889 mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;;
890 beos*) gl_cv_func_printf_precision="guessing no" ;;
891 *) gl_cv_func_printf_precision="guessing yes" ;;
892 esac
893changequote([,])dnl
894 ])
895 ])
896])
897
898dnl Test whether the *printf family of functions recovers gracefully in case
899dnl of an out-of-memory condition, or whether it crashes the entire program.
900dnl Result is gl_cv_func_printf_enomem.
901
902AC_DEFUN([gl_PRINTF_ENOMEM],
903[
904 AC_REQUIRE([AC_PROG_CC])
905 AC_REQUIRE([gl_MULTIARCH])
906 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
907 AC_CACHE_CHECK([whether printf survives out-of-memory conditions],
908 [gl_cv_func_printf_enomem],
909 [
910 gl_cv_func_printf_enomem="guessing no"
911 if test "$cross_compiling" = no; then
912 if test $APPLE_UNIVERSAL_BUILD = 0; then
913 AC_LANG_CONFTEST([AC_LANG_SOURCE([
914]GL_NOCRASH[
915changequote(,)dnl
916#include <stdio.h>
917#include <sys/types.h>
918#include <sys/time.h>
919#include <sys/resource.h>
920#include <errno.h>
921int main()
922{
923 struct rlimit limit;
924 int ret;
925 nocrash_init ();
926 /* Some printf implementations allocate temporary space with malloc. */
927 /* On BSD systems, malloc() is limited by RLIMIT_DATA. */
928#ifdef RLIMIT_DATA
929 if (getrlimit (RLIMIT_DATA, &limit) < 0)
930 return 77;
931 if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
932 limit.rlim_max = 5000000;
933 limit.rlim_cur = limit.rlim_max;
934 if (setrlimit (RLIMIT_DATA, &limit) < 0)
935 return 77;
936#endif
937 /* On Linux systems, malloc() is limited by RLIMIT_AS. */
938#ifdef RLIMIT_AS
939 if (getrlimit (RLIMIT_AS, &limit) < 0)
940 return 77;
941 if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
942 limit.rlim_max = 5000000;
943 limit.rlim_cur = limit.rlim_max;
944 if (setrlimit (RLIMIT_AS, &limit) < 0)
945 return 77;
946#endif
947 /* Some printf implementations allocate temporary space on the stack. */
948#ifdef RLIMIT_STACK
949 if (getrlimit (RLIMIT_STACK, &limit) < 0)
950 return 77;
951 if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
952 limit.rlim_max = 5000000;
953 limit.rlim_cur = limit.rlim_max;
954 if (setrlimit (RLIMIT_STACK, &limit) < 0)
955 return 77;
956#endif
957 ret = printf ("%.5000000f", 1.0);
958 return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
959}
960changequote([,])dnl
961 ])])
962 if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
963 (./conftest
964 result=$?
965 if test $result != 0 && test $result != 77; then result=1; fi
966 exit $result
967 ) >/dev/null 2>/dev/null
968 case $? in
969 0) gl_cv_func_printf_enomem="yes" ;;
970 77) gl_cv_func_printf_enomem="guessing no" ;;
971 *) gl_cv_func_printf_enomem="no" ;;
972 esac
973 else
974 gl_cv_func_printf_enomem="guessing no"
975 fi
976 rm -fr conftest*
977 else
978 dnl A universal build on Apple MacOS X platforms.
979 dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode.
980 dnl But we need a configuration result that is valid in both modes.
981 gl_cv_func_printf_enomem="guessing no"
982 fi
983 fi
984 if test "$gl_cv_func_printf_enomem" = "guessing no"; then
985changequote(,)dnl
986 case "$host_os" in
987 # Guess yes on glibc systems.
988 *-gnu*) gl_cv_func_printf_enomem="guessing yes";;
989 # Guess yes on Solaris.
990 solaris*) gl_cv_func_printf_enomem="guessing yes";;
991 # Guess yes on AIX.
992 aix*) gl_cv_func_printf_enomem="guessing yes";;
993 # Guess yes on HP-UX/hppa.
994 hpux*) case "$host_cpu" in
995 hppa*) gl_cv_func_printf_enomem="guessing yes";;
996 *) gl_cv_func_printf_enomem="guessing no";;
997 esac
998 ;;
999 # Guess yes on IRIX.
1000 irix*) gl_cv_func_printf_enomem="guessing yes";;
1001 # Guess yes on OSF/1.
1002 osf*) gl_cv_func_printf_enomem="guessing yes";;
1003 # Guess yes on BeOS.
1004 beos*) gl_cv_func_printf_enomem="guessing yes";;
1005 # Guess yes on Haiku.
1006 haiku*) gl_cv_func_printf_enomem="guessing yes";;
1007 # If we don't know, assume the worst.
1008 *) gl_cv_func_printf_enomem="guessing no";;
1009 esac
1010changequote([,])dnl
1011 fi
1012 ])
1013])
1014
1015dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
1016dnl Result is ac_cv_func_snprintf.
1017
1018AC_DEFUN([gl_SNPRINTF_PRESENCE],
1019[
1020 AC_CHECK_FUNCS_ONCE([snprintf])
1021])
1022
1023dnl Test whether the string produced by the snprintf function is always NUL
1024dnl terminated. (ISO C99, POSIX:2001)
1025dnl Result is gl_cv_func_snprintf_truncation_c99.
1026
1027AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99],
1028[
1029 AC_REQUIRE([AC_PROG_CC])
1030 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1031 AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
1032 [gl_cv_func_snprintf_truncation_c99],
1033 [
1034 AC_TRY_RUN([
1035#include <stdio.h>
1036#include <string.h>
1037static char buf[100];
1038int main ()
1039{
1040 strcpy (buf, "ABCDEF");
1041 snprintf (buf, 3, "%d %d", 4567, 89);
1042 if (memcmp (buf, "45\0DEF", 6) != 0)
1043 return 1;
1044 return 0;
1045}], [gl_cv_func_snprintf_truncation_c99=yes], [gl_cv_func_snprintf_truncation_c99=no],
1046 [
1047changequote(,)dnl
1048 case "$host_os" in
1049 # Guess yes on glibc systems.
1050 *-gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1051 # Guess yes on FreeBSD >= 5.
1052 freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1053 freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1054 # Guess yes on MacOS X >= 10.3.
1055 darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1056 darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1057 # Guess yes on OpenBSD >= 3.9.
1058 openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1059 gl_cv_func_snprintf_truncation_c99="guessing no";;
1060 openbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1061 # Guess yes on Solaris >= 2.6.
1062 solaris2.[0-5]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1063 solaris*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1064 # Guess yes on AIX >= 4.
1065 aix[1-3]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1066 aix*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1067 # Guess yes on HP-UX >= 11.
1068 hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1069 hpux*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1070 # Guess yes on IRIX >= 6.5.
1071 irix6.5) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1072 # Guess yes on OSF/1 >= 5.
1073 osf[3-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1074 osf*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1075 # Guess yes on NetBSD >= 3.
1076 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1077 gl_cv_func_snprintf_truncation_c99="guessing no";;
1078 netbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1079 # Guess yes on BeOS.
1080 beos*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1081 # If we don't know, assume the worst.
1082 *) gl_cv_func_snprintf_truncation_c99="guessing no";;
1083 esac
1084changequote([,])dnl
1085 ])
1086 ])
1087])
1088
1089dnl Test whether the return value of the snprintf function is the number
1090dnl of bytes (excluding the terminating NUL) that would have been produced
1091dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
1092dnl For example, this test program fails on IRIX 6.5:
1093dnl ---------------------------------------------------------------------
1094dnl #include <stdio.h>
1095dnl int main()
1096dnl {
1097dnl static char buf[8];
1098dnl int retval = snprintf (buf, 3, "%d", 12345);
1099dnl return retval >= 0 && retval < 3;
1100dnl }
1101dnl ---------------------------------------------------------------------
1102dnl Result is gl_cv_func_snprintf_retval_c99.
1103
1104AC_DEFUN([gl_SNPRINTF_RETVAL_C99],
1105[
1106 AC_REQUIRE([AC_PROG_CC])
1107 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1108 AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
1109 [gl_cv_func_snprintf_retval_c99],
1110 [
1111 AC_TRY_RUN([
1112#include <stdio.h>
1113#include <string.h>
1114static char buf[100];
1115int main ()
1116{
1117 strcpy (buf, "ABCDEF");
1118 if (snprintf (buf, 3, "%d %d", 4567, 89) != 7)
1119 return 1;
1120 return 0;
1121}], [gl_cv_func_snprintf_retval_c99=yes], [gl_cv_func_snprintf_retval_c99=no],
1122 [
1123changequote(,)dnl
1124 case "$host_os" in
1125 # Guess yes on glibc systems.
1126 *-gnu*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1127 # Guess yes on FreeBSD >= 5.
1128 freebsd[1-4]*) gl_cv_func_snprintf_retval_c99="guessing no";;
1129 freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1130 # Guess yes on MacOS X >= 10.3.
1131 darwin[1-6].*) gl_cv_func_snprintf_retval_c99="guessing no";;
1132 darwin*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1133 # Guess yes on OpenBSD >= 3.9.
1134 openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1135 gl_cv_func_snprintf_retval_c99="guessing no";;
1136 openbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1137 # Guess yes on Solaris >= 2.6.
1138 solaris2.[0-5]*) gl_cv_func_snprintf_retval_c99="guessing no";;
1139 solaris*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1140 # Guess yes on AIX >= 4.
1141 aix[1-3]*) gl_cv_func_snprintf_retval_c99="guessing no";;
1142 aix*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1143 # Guess yes on NetBSD >= 3.
1144 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1145 gl_cv_func_snprintf_retval_c99="guessing no";;
1146 netbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1147 # Guess yes on BeOS.
1148 beos*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1149 # If we don't know, assume the worst.
1150 *) gl_cv_func_snprintf_retval_c99="guessing no";;
1151 esac
1152changequote([,])dnl
1153 ])
1154 ])
1155])
1156
1157dnl Test whether the snprintf function supports the %n format directive
1158dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
1159dnl Result is gl_cv_func_snprintf_directive_n.
1160
1161AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
1162[
1163 AC_REQUIRE([AC_PROG_CC])
1164 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1165 AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
1166 [gl_cv_func_snprintf_directive_n],
1167 [
1168 AC_TRY_RUN([
1169#include <stdio.h>
1170#include <string.h>
1171static char fmtstring[10];
1172static char buf[100];
1173int main ()
1174{
1175 int count = -1;
1176 /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2)
1177 support %n in format strings in read-only memory but not in writable
1178 memory. */
1179 strcpy (fmtstring, "%d %n");
1180 snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55);
1181 if (count != 6)
1182 return 1;
1183 return 0;
1184}], [gl_cv_func_snprintf_directive_n=yes], [gl_cv_func_snprintf_directive_n=no],
1185 [
1186changequote(,)dnl
1187 case "$host_os" in
1188 # Guess yes on glibc systems.
1189 *-gnu*) gl_cv_func_snprintf_directive_n="guessing yes";;
1190 # Guess yes on FreeBSD >= 5.
1191 freebsd[1-4]*) gl_cv_func_snprintf_directive_n="guessing no";;
1192 freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
1193 # Guess yes on MacOS X >= 10.3.
1194 darwin[1-6].*) gl_cv_func_snprintf_directive_n="guessing no";;
1195 darwin*) gl_cv_func_snprintf_directive_n="guessing yes";;
1196 # Guess yes on Solaris >= 2.6.
1197 solaris2.[0-5]*) gl_cv_func_snprintf_directive_n="guessing no";;
1198 solaris*) gl_cv_func_snprintf_directive_n="guessing yes";;
1199 # Guess yes on AIX >= 4.
1200 aix[1-3]*) gl_cv_func_snprintf_directive_n="guessing no";;
1201 aix*) gl_cv_func_snprintf_directive_n="guessing yes";;
1202 # Guess yes on IRIX >= 6.5.
1203 irix6.5) gl_cv_func_snprintf_directive_n="guessing yes";;
1204 # Guess yes on OSF/1 >= 5.
1205 osf[3-4]*) gl_cv_func_snprintf_directive_n="guessing no";;
1206 osf*) gl_cv_func_snprintf_directive_n="guessing yes";;
1207 # Guess yes on NetBSD >= 3.
1208 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1209 gl_cv_func_snprintf_directive_n="guessing no";;
1210 netbsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
1211 # Guess yes on BeOS.
1212 beos*) gl_cv_func_snprintf_directive_n="guessing yes";;
1213 # If we don't know, assume the worst.
1214 *) gl_cv_func_snprintf_directive_n="guessing no";;
1215 esac
1216changequote([,])dnl
1217 ])
1218 ])
1219])
1220
1221dnl Test whether the snprintf function, when passed a size = 1, writes any
1222dnl output without bounds in this case, behaving like sprintf. This is the
1223dnl case on Linux libc5.
1224dnl Result is gl_cv_func_snprintf_size1.
1225
1226AC_DEFUN([gl_SNPRINTF_SIZE1],
1227[
1228 AC_REQUIRE([AC_PROG_CC])
1229 AC_CACHE_CHECK([whether snprintf respects a size of 1],
1230 [gl_cv_func_snprintf_size1],
1231 [
1232 AC_TRY_RUN([
1233#include <stdio.h>
1234int main()
1235{
1236 static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1237 snprintf (buf, 1, "%d", 12345);
1238 return buf[1] != 'E';
1239}],
1240 [gl_cv_func_snprintf_size1=yes],
1241 [gl_cv_func_snprintf_size1=no],
1242 [gl_cv_func_snprintf_size1="guessing yes"])
1243 ])
1244])
1245
1246dnl Test whether the vsnprintf function, when passed a zero size, produces no
1247dnl output. (ISO C99, POSIX:2001)
1248dnl For example, snprintf nevertheless writes a NUL byte in this case
1249dnl on OSF/1 5.1:
1250dnl ---------------------------------------------------------------------
1251dnl #include <stdio.h>
1252dnl int main()
1253dnl {
1254dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1255dnl snprintf (buf, 0, "%d", 12345);
1256dnl return buf[0] != 'D';
1257dnl }
1258dnl ---------------------------------------------------------------------
1259dnl And vsnprintf writes any output without bounds in this case, behaving like
1260dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
1261dnl ---------------------------------------------------------------------
1262dnl #include <stdarg.h>
1263dnl #include <stdio.h>
1264dnl static int my_snprintf (char *buf, int size, const char *format, ...)
1265dnl {
1266dnl va_list args;
1267dnl int ret;
1268dnl va_start (args, format);
1269dnl ret = vsnprintf (buf, size, format, args);
1270dnl va_end (args);
1271dnl return ret;
1272dnl }
1273dnl int main()
1274dnl {
1275dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1276dnl my_snprintf (buf, 0, "%d", 12345);
1277dnl return buf[0] != 'D';
1278dnl }
1279dnl ---------------------------------------------------------------------
1280dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
1281
1282AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
1283[
1284 AC_REQUIRE([AC_PROG_CC])
1285 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1286 AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
1287 [gl_cv_func_vsnprintf_zerosize_c99],
1288 [
1289 AC_TRY_RUN([
1290#include <stdarg.h>
1291#include <stdio.h>
1292static int my_snprintf (char *buf, int size, const char *format, ...)
1293{
1294 va_list args;
1295 int ret;
1296 va_start (args, format);
1297 ret = vsnprintf (buf, size, format, args);
1298 va_end (args);
1299 return ret;
1300}
1301int main()
1302{
1303 static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1304 my_snprintf (buf, 0, "%d", 12345);
1305 return buf[0] != 'D';
1306}],
1307 [gl_cv_func_vsnprintf_zerosize_c99=yes],
1308 [gl_cv_func_vsnprintf_zerosize_c99=no],
1309 [
1310changequote(,)dnl
1311 case "$host_os" in
1312 # Guess yes on glibc systems.
1313 *-gnu*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1314 # Guess yes on FreeBSD >= 5.
1315 freebsd[1-4]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1316 freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1317 # Guess yes on MacOS X >= 10.3.
1318 darwin[1-6].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1319 darwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1320 # Guess yes on Cygwin.
1321 cygwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1322 # Guess yes on Solaris >= 2.6.
1323 solaris2.[0-5]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1324 solaris*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1325 # Guess yes on AIX >= 4.
1326 aix[1-3]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1327 aix*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1328 # Guess yes on IRIX >= 6.5.
1329 irix6.5) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1330 # Guess yes on NetBSD >= 3.
1331 netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1332 gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1333 netbsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1334 # Guess yes on BeOS.
1335 beos*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1336 # Guess yes on mingw.
1337 mingw* | pw*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1338 # If we don't know, assume the worst.
1339 *) gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1340 esac
1341changequote([,])dnl
1342 ])
1343 ])
1344])
1345
1346dnl The results of these tests on various platforms are:
1347dnl
1348dnl 1 = gl_PRINTF_SIZES_C99
1349dnl 2 = gl_PRINTF_LONG_DOUBLE
1350dnl 3 = gl_PRINTF_INFINITE
1351dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
1352dnl 5 = gl_PRINTF_DIRECTIVE_A
1353dnl 6 = gl_PRINTF_DIRECTIVE_F
1354dnl 7 = gl_PRINTF_DIRECTIVE_N
1355dnl 8 = gl_PRINTF_DIRECTIVE_LS
1356dnl 9 = gl_PRINTF_POSITIONS
1357dnl 10 = gl_PRINTF_FLAG_GROUPING
1358dnl 11 = gl_PRINTF_FLAG_LEFTADJUST
1359dnl 12 = gl_PRINTF_FLAG_ZERO
1360dnl 13 = gl_PRINTF_PRECISION
1361dnl 14 = gl_PRINTF_ENOMEM
1362dnl 15 = gl_SNPRINTF_PRESENCE
1363dnl 16 = gl_SNPRINTF_TRUNCATION_C99
1364dnl 17 = gl_SNPRINTF_RETVAL_C99
1365dnl 18 = gl_SNPRINTF_DIRECTIVE_N
1366dnl 19 = gl_SNPRINTF_SIZE1
1367dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99
1368dnl
1369dnl 1 = checking whether printf supports size specifiers as in C99...
1370dnl 2 = checking whether printf supports 'long double' arguments...
1371dnl 3 = checking whether printf supports infinite 'double' arguments...
1372dnl 4 = checking whether printf supports infinite 'long double' arguments...
1373dnl 5 = checking whether printf supports the 'a' and 'A' directives...
1374dnl 6 = checking whether printf supports the 'F' directive...
1375dnl 7 = checking whether printf supports the 'n' directive...
1376dnl 8 = checking whether printf supports the 'ls' directive...
1377dnl 9 = checking whether printf supports POSIX/XSI format strings with positions...
1378dnl 10 = checking whether printf supports the grouping flag...
1379dnl 11 = checking whether printf supports the left-adjust flag correctly...
1380dnl 12 = checking whether printf supports the zero flag correctly...
1381dnl 13 = checking whether printf supports large precisions...
1382dnl 14 = checking whether printf survives out-of-memory conditions...
1383dnl 15 = checking for snprintf...
1384dnl 16 = checking whether snprintf truncates the result as in C99...
1385dnl 17 = checking whether snprintf returns a byte count as in C99...
1386dnl 18 = checking whether snprintf fully supports the 'n' directive...
1387dnl 19 = checking whether snprintf respects a size of 1...
1388dnl 20 = checking whether vsnprintf respects a zero size as in C99...
1389dnl
1390dnl . = yes, # = no.
1391dnl
1392dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1393dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . .
1394dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . .
1395dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . .
1396dnl MacOS X 10.3.9 . . . . # . . . . . . # . # . . . . . .
1397dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . .
1398dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . .
1399dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . .
1400dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . .
1401dnl Solaris 10 . . # # # . . # . . . # . . . . . . . .
1402dnl Solaris 2.6 ... 9 # . # # # # . # . . . # . . . . . . . .
1403dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # #
1404dnl AIX 5.2 . . # # # . . . . . . # . . . . . . . .
1405dnl AIX 4.3.2, 5.1 # . # # # # . . . . . # . . . . . . . .
1406dnl HP-UX 11.31 . . . . # . . . . . . # . . . . # # . .
1407dnl HP-UX 11.{00,11,23} # . . . # # . . . . . # . . . . # # . #
1408dnl HP-UX 10.20 # . # . # # . ? . . # # . . . . # # ? #
1409dnl IRIX 6.5 # . # # # # . # . . . # . . . . # . . .
1410dnl OSF/1 5.1 # . # # # # . . . . . # . . . . # . . #
1411dnl OSF/1 4.0d # . # # # # . . . . . # . . # # # # # #
1412dnl NetBSD 4.0 . ? ? ? ? ? . ? . ? ? ? ? ? . . . ? ? ?
1413dnl NetBSD 3.0 . . . . # # . ? # # ? # . # . . . . . .
1414dnl Haiku . . . # # # . # . . . . . ? . . . . . .
1415dnl BeOS # # . # # # . ? # . ? . # ? . . . . . .
1416dnl mingw # # # # # # . . # # . # # ? . # # # . .