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