1# printf.m4 serial 73
2dnl Copyright (C) 2003, 2007-2021 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_RUN_IFELSE(
21        [AC_LANG_SOURCE([[
22#include <stddef.h>
23#include <stdio.h>
24#include <string.h>
25#include <sys/types.h>
26#if HAVE_STDINT_H_WITH_UINTMAX
27# include <stdint.h>
28#endif
29#if HAVE_INTTYPES_H_WITH_UINTMAX
30# include <inttypes.h>
31#endif
32static char buf[100];
33int main ()
34{
35  int result = 0;
36#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
37  buf[0] = '\0';
38  if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0
39      || strcmp (buf, "12345671 33") != 0)
40    result |= 1;
41#else
42  result |= 1;
43#endif
44  buf[0] = '\0';
45  if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0
46      || strcmp (buf, "12345672 33") != 0)
47    result |= 2;
48  buf[0] = '\0';
49  if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
50      || strcmp (buf, "12345673 33") != 0)
51    result |= 4;
52  buf[0] = '\0';
53  if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
54      || strcmp (buf, "1.5 33") != 0)
55    result |= 8;
56  return result;
57}]])],
58        [gl_cv_func_printf_sizes_c99=yes],
59        [gl_cv_func_printf_sizes_c99=no],
60        [
61         case "$host_os" in
62changequote(,)dnl
63                                 # Guess yes on glibc systems.
64           *-gnu* | gnu*)        gl_cv_func_printf_sizes_c99="guessing yes";;
65                                 # Guess yes on musl systems.
66           *-musl*)              gl_cv_func_printf_sizes_c99="guessing yes";;
67                                 # Guess yes on FreeBSD >= 5.
68           freebsd[1-4].*)       gl_cv_func_printf_sizes_c99="guessing no";;
69           freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
70           midnightbsd*)         gl_cv_func_printf_sizes_c99="guessing yes";;
71                                 # Guess yes on Mac OS X >= 10.3.
72           darwin[1-6].*)        gl_cv_func_printf_sizes_c99="guessing no";;
73           darwin*)              gl_cv_func_printf_sizes_c99="guessing yes";;
74                                 # Guess yes on OpenBSD >= 3.9.
75           openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
76                                 gl_cv_func_printf_sizes_c99="guessing no";;
77           openbsd*)             gl_cv_func_printf_sizes_c99="guessing yes";;
78                                 # Guess yes on Solaris >= 2.10.
79           solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";;
80           solaris*)             gl_cv_func_printf_sizes_c99="guessing no";;
81                                 # Guess yes on NetBSD >= 3.
82           netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
83                                 gl_cv_func_printf_sizes_c99="guessing no";;
84           netbsd*)              gl_cv_func_printf_sizes_c99="guessing yes";;
85                                 # Guess yes on Android.
86           linux*-android*)      gl_cv_func_printf_sizes_c99="guessing yes";;
87changequote([,])dnl
88                                 # Guess yes on MSVC, no on mingw.
89           mingw*)               AC_EGREP_CPP([Known], [
90#ifdef _MSC_VER
91 Known
92#endif
93                                   ],
94                                   [gl_cv_func_printf_sizes_c99="guessing yes"],
95                                   [gl_cv_func_printf_sizes_c99="guessing no"])
96                                 ;;
97                                 # If we don't know, obey --enable-cross-guesses.
98           *)                    gl_cv_func_printf_sizes_c99="$gl_cross_guess_normal";;
99         esac
100        ])
101    ])
102])
103
104dnl Test whether the *printf family of functions supports 'long double'
105dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
106dnl Result is gl_cv_func_printf_long_double.
107
108AC_DEFUN([gl_PRINTF_LONG_DOUBLE],
109[
110  AC_REQUIRE([AC_PROG_CC])
111  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
112  AC_CACHE_CHECK([whether printf supports 'long double' arguments],
113    [gl_cv_func_printf_long_double],
114    [
115      AC_RUN_IFELSE(
116        [AC_LANG_SOURCE([[
117#include <stdio.h>
118#include <string.h>
119static char buf[10000];
120int main ()
121{
122  int result = 0;
123  buf[0] = '\0';
124  if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0
125      || strcmp (buf, "1.750000 33") != 0)
126    result |= 1;
127  buf[0] = '\0';
128  if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0
129      || strcmp (buf, "1.750000e+00 33") != 0)
130    result |= 2;
131  buf[0] = '\0';
132  if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0
133      || strcmp (buf, "1.75 33") != 0)
134    result |= 4;
135  return result;
136}]])],
137        [gl_cv_func_printf_long_double=yes],
138        [gl_cv_func_printf_long_double=no],
139        [case "$host_os" in
140                            # Guess no on BeOS.
141           beos*)           gl_cv_func_printf_long_double="guessing no";;
142                            # Guess yes on Android.
143           linux*-android*) gl_cv_func_printf_long_double="guessing yes";;
144                            # Guess yes on MSVC, no on mingw.
145           mingw*)          AC_EGREP_CPP([Known], [
146#ifdef _MSC_VER
147 Known
148#endif
149                              ],
150                              [gl_cv_func_printf_long_double="guessing yes"],
151                              [gl_cv_func_printf_long_double="guessing no"])
152                            ;;
153           *)               gl_cv_func_printf_long_double="guessing yes";;
154         esac
155        ])
156    ])
157])
158
159dnl Test whether the *printf family of functions supports infinite and NaN
160dnl 'double' arguments and negative zero arguments in the %f, %e, %g
161dnl directives. (ISO C99, POSIX:2001)
162dnl Result is gl_cv_func_printf_infinite.
163
164AC_DEFUN([gl_PRINTF_INFINITE],
165[
166  AC_REQUIRE([AC_PROG_CC])
167  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
168  AC_CACHE_CHECK([whether printf supports infinite 'double' arguments],
169    [gl_cv_func_printf_infinite],
170    [
171      AC_RUN_IFELSE(
172        [AC_LANG_SOURCE([[
173#include <stdio.h>
174#include <string.h>
175static int
176strisnan (const char *string, size_t start_index, size_t end_index)
177{
178  if (start_index < end_index)
179    {
180      if (string[start_index] == '-')
181        start_index++;
182      if (start_index + 3 <= end_index
183          && memcmp (string + start_index, "nan", 3) == 0)
184        {
185          start_index += 3;
186          if (start_index == end_index
187              || (string[start_index] == '(' && string[end_index - 1] == ')'))
188            return 1;
189        }
190    }
191  return 0;
192}
193static int
194have_minus_zero ()
195{
196  static double plus_zero = 0.0;
197  double minus_zero = - plus_zero;
198  return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
199}
200static char buf[10000];
201static double zero = 0.0;
202int main ()
203{
204  int result = 0;
205  if (sprintf (buf, "%f", 1.0 / zero) < 0
206      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
207    result |= 1;
208  if (sprintf (buf, "%f", -1.0 / zero) < 0
209      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
210    result |= 1;
211  if (sprintf (buf, "%f", zero / zero) < 0
212      || !strisnan (buf, 0, strlen (buf)))
213    result |= 2;
214  if (sprintf (buf, "%e", 1.0 / zero) < 0
215      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
216    result |= 4;
217  if (sprintf (buf, "%e", -1.0 / zero) < 0
218      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
219    result |= 4;
220  if (sprintf (buf, "%e", zero / zero) < 0
221      || !strisnan (buf, 0, strlen (buf)))
222    result |= 8;
223  if (sprintf (buf, "%g", 1.0 / zero) < 0
224      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
225    result |= 16;
226  if (sprintf (buf, "%g", -1.0 / zero) < 0
227      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
228    result |= 16;
229  if (sprintf (buf, "%g", zero / zero) < 0
230      || !strisnan (buf, 0, strlen (buf)))
231    result |= 32;
232  /* This test fails on HP-UX 10.20.  */
233  if (have_minus_zero ())
234    if (sprintf (buf, "%g", - zero) < 0
235        || strcmp (buf, "-0") != 0)
236    result |= 64;
237  return result;
238}]])],
239        [gl_cv_func_printf_infinite=yes],
240        [gl_cv_func_printf_infinite=no],
241        [
242         case "$host_os" in
243changequote(,)dnl
244                                 # Guess yes on glibc systems.
245           *-gnu* | gnu*)        gl_cv_func_printf_infinite="guessing yes";;
246                                 # Guess yes on musl systems.
247           *-musl*)              gl_cv_func_printf_infinite="guessing yes";;
248                                 # Guess yes on FreeBSD >= 6.
249           freebsd[1-5].*)       gl_cv_func_printf_infinite="guessing no";;
250           freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";;
251           midnightbsd*)         gl_cv_func_printf_infinite="guessing yes";;
252                                 # Guess yes on Mac OS X >= 10.3.
253           darwin[1-6].*)        gl_cv_func_printf_infinite="guessing no";;
254           darwin*)              gl_cv_func_printf_infinite="guessing yes";;
255                                 # Guess yes on HP-UX >= 11.
256           hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
257           hpux*)                gl_cv_func_printf_infinite="guessing yes";;
258                                 # Guess yes on NetBSD >= 3.
259           netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
260                                 gl_cv_func_printf_infinite="guessing no";;
261           netbsd*)              gl_cv_func_printf_infinite="guessing yes";;
262                                 # Guess yes on OpenBSD >= 6.0.
263           openbsd[1-5].*)       gl_cv_func_printf_infinite="guessing no";;
264           openbsd*)             gl_cv_func_printf_infinite="guessing yes";;
265                                 # Guess yes on BeOS.
266           beos*)                gl_cv_func_printf_infinite="guessing yes";;
267                                 # Guess no on Android.
268           linux*-android*)      gl_cv_func_printf_infinite="guessing no";;
269changequote([,])dnl
270                                 # Guess yes on MSVC, no on mingw.
271           mingw*)               AC_EGREP_CPP([Known], [
272#ifdef _MSC_VER
273 Known
274#endif
275                                   ],
276                                   [gl_cv_func_printf_infinite="guessing yes"],
277                                   [gl_cv_func_printf_infinite="guessing no"])
278                                 ;;
279                                 # If we don't know, obey --enable-cross-guesses.
280           *)                    gl_cv_func_printf_infinite="$gl_cross_guess_normal";;
281         esac
282        ])
283    ])
284])
285
286dnl Test whether the *printf family of functions supports infinite and NaN
287dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
288dnl Result is gl_cv_func_printf_infinite_long_double.
289
290AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
291[
292  AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
293  AC_REQUIRE([AC_PROG_CC])
294  AC_REQUIRE([gl_BIGENDIAN])
295  AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
296  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
297  dnl The user can set or unset the variable gl_printf_safe to indicate
298  dnl that he wishes a safe handling of non-IEEE-754 'long double' values.
299  if test -n "$gl_printf_safe"; then
300    AC_DEFINE([CHECK_PRINTF_SAFE], [1],
301      [Define if you wish *printf() functions that have a safe handling of
302       non-IEEE-754 'long double' values.])
303  fi
304  case "$gl_cv_func_printf_long_double" in
305    *yes)
306      AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments],
307        [gl_cv_func_printf_infinite_long_double],
308        [
309          AC_RUN_IFELSE(
310            [AC_LANG_SOURCE([[
311]GL_NOCRASH[
312#include <float.h>
313#include <stdio.h>
314#include <string.h>
315static int
316strisnan (const char *string, size_t start_index, size_t end_index)
317{
318  if (start_index < end_index)
319    {
320      if (string[start_index] == '-')
321        start_index++;
322      if (start_index + 3 <= end_index
323          && memcmp (string + start_index, "nan", 3) == 0)
324        {
325          start_index += 3;
326          if (start_index == end_index
327              || (string[start_index] == '(' && string[end_index - 1] == ')'))
328            return 1;
329        }
330    }
331  return 0;
332}
333static char buf[10000];
334static long double zeroL = 0.0L;
335int main ()
336{
337  int result = 0;
338  nocrash_init();
339  if (sprintf (buf, "%Lf", 1.0L / zeroL) < 0
340      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
341    result |= 1;
342  if (sprintf (buf, "%Lf", -1.0L / zeroL) < 0
343      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
344    result |= 1;
345  if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
346      || !strisnan (buf, 0, strlen (buf)))
347    result |= 1;
348  if (sprintf (buf, "%Le", 1.0L / zeroL) < 0
349      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
350    result |= 1;
351  if (sprintf (buf, "%Le", -1.0L / zeroL) < 0
352      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
353    result |= 1;
354  if (sprintf (buf, "%Le", zeroL / zeroL) < 0
355      || !strisnan (buf, 0, strlen (buf)))
356    result |= 1;
357  if (sprintf (buf, "%Lg", 1.0L / zeroL) < 0
358      || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
359    result |= 1;
360  if (sprintf (buf, "%Lg", -1.0L / zeroL) < 0
361      || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
362    result |= 1;
363  if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
364      || !strisnan (buf, 0, strlen (buf)))
365    result |= 1;
366#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_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
367/* Representation of an 80-bit 'long double' as an initializer for a sequence
368   of 'unsigned int' words.  */
369# ifdef WORDS_BIGENDIAN
370#  define LDBL80_WORDS(exponent,manthi,mantlo) \
371     { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
372       ((unsigned int) (manthi) << 16) | ((unsigned int) (mantlo) >> 16),   \
373       (unsigned int) (mantlo) << 16                                        \
374     }
375# else
376#  define LDBL80_WORDS(exponent,manthi,mantlo) \
377     { mantlo, manthi, exponent }
378# endif
379  { /* Quiet NaN.  */
380    static union { unsigned int word[4]; long double value; } x =
381      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
382    if (sprintf (buf, "%Lf", x.value) < 0
383        || !strisnan (buf, 0, strlen (buf)))
384      result |= 2;
385    if (sprintf (buf, "%Le", x.value) < 0
386        || !strisnan (buf, 0, strlen (buf)))
387      result |= 2;
388    if (sprintf (buf, "%Lg", x.value) < 0
389        || !strisnan (buf, 0, strlen (buf)))
390      result |= 2;
391  }
392  {
393    /* Signalling NaN.  */
394    static union { unsigned int word[4]; long double value; } x =
395      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
396    if (sprintf (buf, "%Lf", x.value) < 0
397        || !strisnan (buf, 0, strlen (buf)))
398      result |= 2;
399    if (sprintf (buf, "%Le", x.value) < 0
400        || !strisnan (buf, 0, strlen (buf)))
401      result |= 2;
402    if (sprintf (buf, "%Lg", x.value) < 0
403        || !strisnan (buf, 0, strlen (buf)))
404      result |= 2;
405  }
406  { /* Pseudo-NaN.  */
407    static union { unsigned int word[4]; long double value; } x =
408      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
409    if (sprintf (buf, "%Lf", x.value) <= 0)
410      result |= 4;
411    if (sprintf (buf, "%Le", x.value) <= 0)
412      result |= 4;
413    if (sprintf (buf, "%Lg", x.value) <= 0)
414      result |= 4;
415  }
416  { /* Pseudo-Infinity.  */
417    static union { unsigned int word[4]; long double value; } x =
418      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
419    if (sprintf (buf, "%Lf", x.value) <= 0)
420      result |= 8;
421    if (sprintf (buf, "%Le", x.value) <= 0)
422      result |= 8;
423    if (sprintf (buf, "%Lg", x.value) <= 0)
424      result |= 8;
425  }
426  { /* Pseudo-Zero.  */
427    static union { unsigned int word[4]; long double value; } x =
428      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
429    if (sprintf (buf, "%Lf", x.value) <= 0)
430      result |= 16;
431    if (sprintf (buf, "%Le", x.value) <= 0)
432      result |= 16;
433    if (sprintf (buf, "%Lg", x.value) <= 0)
434      result |= 16;
435  }
436  { /* Unnormalized number.  */
437    static union { unsigned int word[4]; long double value; } x =
438      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
439    if (sprintf (buf, "%Lf", x.value) <= 0)
440      result |= 32;
441    if (sprintf (buf, "%Le", x.value) <= 0)
442      result |= 32;
443    if (sprintf (buf, "%Lg", x.value) <= 0)
444      result |= 32;
445  }
446  { /* Pseudo-Denormal.  */
447    static union { unsigned int word[4]; long double value; } x =
448      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
449    if (sprintf (buf, "%Lf", x.value) <= 0)
450      result |= 64;
451    if (sprintf (buf, "%Le", x.value) <= 0)
452      result |= 64;
453    if (sprintf (buf, "%Lg", x.value) <= 0)
454      result |= 64;
455  }
456#endif
457  return result;
458}]])],
459            [gl_cv_func_printf_infinite_long_double=yes],
460            [gl_cv_func_printf_infinite_long_double=no],
461            [case "$host_cpu" in
462                                     # Guess no on ia64, x86_64, i386.
463               ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";;
464               *)
465                 case "$host_os" in
466changequote(,)dnl
467                                         # Guess yes on glibc systems.
468                   *-gnu* | gnu*)        gl_cv_func_printf_infinite_long_double="guessing yes";;
469                                         # Guess yes on musl systems.
470                   *-musl*)              gl_cv_func_printf_infinite_long_double="guessing yes";;
471                                         # Guess yes on FreeBSD >= 6.
472                   freebsd[1-5].*)       gl_cv_func_printf_infinite_long_double="guessing no";;
473                   freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";;
474                   midnightbsd*)         gl_cv_func_printf_infinite_long_double="guessing yes";;
475                                         # Guess yes on HP-UX >= 11.
476                   hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";;
477                   hpux*)                gl_cv_func_printf_infinite_long_double="guessing yes";;
478                                         # Guess yes on OpenBSD >= 6.0.
479                   openbsd[1-5].*)       gl_cv_func_printf_infinite_long_double="guessing no";;
480                   openbsd*)             gl_cv_func_printf_infinite_long_double="guessing yes";;
481                                         # Guess no on Android.
482                   linux*-android*)      gl_cv_func_printf_infinite_long_double="guessing no";;
483changequote([,])dnl
484                                         # Guess yes on MSVC, no on mingw.
485                   mingw*)               AC_EGREP_CPP([Known], [
486#ifdef _MSC_VER
487 Known
488#endif
489                                           ],
490                                           [gl_cv_func_printf_infinite_long_double="guessing yes"],
491                                           [gl_cv_func_printf_infinite_long_double="guessing no"])
492                                         ;;
493                                         # If we don't know, obey --enable-cross-guesses.
494                   *)                    gl_cv_func_printf_infinite_long_double="$gl_cross_guess_normal";;
495                 esac
496                 ;;
497             esac
498            ])
499        ])
500      ;;
501    *)
502      gl_cv_func_printf_infinite_long_double="irrelevant"
503      ;;
504  esac
505])
506
507dnl Test whether the *printf family of functions supports the 'a' and 'A'
508dnl conversion specifier for hexadecimal output of floating-point numbers.
509dnl (ISO C99, POSIX:2001)
510dnl Result is gl_cv_func_printf_directive_a.
511
512AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
513[
514  AC_REQUIRE([AC_PROG_CC])
515  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
516  AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
517    [gl_cv_func_printf_directive_a],
518    [
519      AC_RUN_IFELSE(
520        [AC_LANG_SOURCE([[
521#include <stdio.h>
522#include <string.h>
523static char buf[100];
524static double zero = 0.0;
525int main ()
526{
527  int result = 0;
528  if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
529      || (strcmp (buf, "0x1.922p+1 33") != 0
530          && strcmp (buf, "0x3.244p+0 33") != 0
531          && strcmp (buf, "0x6.488p-1 33") != 0
532          && strcmp (buf, "0xc.91p-2 33") != 0))
533    result |= 1;
534  if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
535      || (strcmp (buf, "-0X1.922P+1 33") != 0
536          && strcmp (buf, "-0X3.244P+0 33") != 0
537          && strcmp (buf, "-0X6.488P-1 33") != 0
538          && strcmp (buf, "-0XC.91P-2 33") != 0))
539    result |= 2;
540  /* This catches a FreeBSD 13.0 bug: it doesn't round.  */
541  if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
542      || (strcmp (buf, "0x1.83p+0 33") != 0
543          && strcmp (buf, "0x3.05p-1 33") != 0
544          && strcmp (buf, "0x6.0ap-2 33") != 0
545          && strcmp (buf, "0xc.14p-3 33") != 0))
546    result |= 4;
547  /* This catches a Mac OS X 10.12.4 (Darwin 16.5) bug: it doesn't round.  */
548  if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0
549      || (strcmp (buf, "0x2p+0 33") != 0
550          && strcmp (buf, "0x3p-1 33") != 0
551          && strcmp (buf, "0x6p-2 33") != 0
552          && strcmp (buf, "0xcp-3 33") != 0))
553    result |= 4;
554  /* This catches a FreeBSD 6.1 bug.  See
555     <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
556  if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0
557      || buf[0] == '0')
558    result |= 8;
559  /* This catches a Mac OS X 10.3.9 (Darwin 7.9) bug.  */
560  if (sprintf (buf, "%.1a", 1.999) < 0
561      || (strcmp (buf, "0x1.0p+1") != 0
562          && strcmp (buf, "0x2.0p+0") != 0
563          && strcmp (buf, "0x4.0p-1") != 0
564          && strcmp (buf, "0x8.0p-2") != 0))
565    result |= 16;
566  /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a
567     glibc 2.4 bug <https://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
568  if (sprintf (buf, "%.1La", 1.999L) < 0
569      || (strcmp (buf, "0x1.0p+1") != 0
570          && strcmp (buf, "0x2.0p+0") != 0
571          && strcmp (buf, "0x4.0p-1") != 0
572          && strcmp (buf, "0x8.0p-2") != 0))
573    result |= 32;
574  return result;
575}]])],
576        [gl_cv_func_printf_directive_a=yes],
577        [gl_cv_func_printf_directive_a=no],
578        [
579         case "$host_os" in
580                                 # Guess yes on glibc >= 2.5 systems.
581           *-gnu* | gnu*)
582             AC_EGREP_CPP([BZ2908], [
583               #include <features.h>
584               #ifdef __GNU_LIBRARY__
585                #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)) && !defined __UCLIBC__
586                 BZ2908
587                #endif
588               #endif
589               ],
590               [gl_cv_func_printf_directive_a="guessing yes"],
591               [gl_cv_func_printf_directive_a="guessing no"])
592             ;;
593                                 # Guess yes on musl systems.
594           *-musl*)              gl_cv_func_printf_directive_a="guessing yes";;
595                                 # Guess no on Android.
596           linux*-android*)      gl_cv_func_printf_directive_a="guessing no";;
597                                 # Guess no on native Windows.
598           mingw*)               gl_cv_func_printf_directive_a="guessing no";;
599                                 # If we don't know, obey --enable-cross-guesses.
600           *)                    gl_cv_func_printf_directive_a="$gl_cross_guess_normal";;
601         esac
602        ])
603    ])
604])
605
606dnl Test whether the *printf family of functions supports the %F format
607dnl directive. (ISO C99, POSIX:2001)
608dnl Result is gl_cv_func_printf_directive_f.
609
610AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
611[
612  AC_REQUIRE([AC_PROG_CC])
613  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
614  AC_CACHE_CHECK([whether printf supports the 'F' directive],
615    [gl_cv_func_printf_directive_f],
616    [
617      AC_RUN_IFELSE(
618        [AC_LANG_SOURCE([[
619#include <stdio.h>
620#include <string.h>
621static char buf[100];
622static double zero = 0.0;
623int main ()
624{
625  int result = 0;
626  if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
627      || strcmp (buf, "1234567.000000 33") != 0)
628    result |= 1;
629  if (sprintf (buf, "%F", 1.0 / zero) < 0
630      || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
631    result |= 2;
632  /* This catches a Cygwin 1.5.x bug.  */
633  if (sprintf (buf, "%.F", 1234.0) < 0
634      || strcmp (buf, "1234") != 0)
635    result |= 4;
636  return result;
637}]])],
638        [gl_cv_func_printf_directive_f=yes],
639        [gl_cv_func_printf_directive_f=no],
640        [
641         case "$host_os" in
642changequote(,)dnl
643                                 # Guess yes on glibc systems.
644           *-gnu* | gnu*)        gl_cv_func_printf_directive_f="guessing yes";;
645                                 # Guess yes on musl systems.
646           *-musl*)              gl_cv_func_printf_directive_f="guessing yes";;
647                                 # Guess yes on FreeBSD >= 6.
648           freebsd[1-5].*)       gl_cv_func_printf_directive_f="guessing no";;
649           freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
650           midnightbsd*)         gl_cv_func_printf_directive_f="guessing yes";;
651                                 # Guess yes on Mac OS X >= 10.3.
652           darwin[1-6].*)        gl_cv_func_printf_directive_f="guessing no";;
653           darwin*)              gl_cv_func_printf_directive_f="guessing yes";;
654                                 # Guess yes on OpenBSD >= 6.0.
655           openbsd[1-5].*)       gl_cv_func_printf_directive_f="guessing no";;
656           openbsd*)             gl_cv_func_printf_directive_f="guessing yes";;
657                                 # Guess yes on Solaris >= 2.10.
658           solaris2.[1-9][0-9]*) gl_cv_func_printf_directive_f="guessing yes";;
659           solaris*)             gl_cv_func_printf_directive_f="guessing no";;
660                                 # Guess no on Android.
661           linux*-android*)      gl_cv_func_printf_directive_f="guessing no";;
662changequote([,])dnl
663                                 # Guess yes on MSVC, no on mingw.
664           mingw*)               AC_EGREP_CPP([Known], [
665#ifdef _MSC_VER
666 Known
667#endif
668                                   ],
669                                   [gl_cv_func_printf_directive_f="guessing yes"],
670                                   [gl_cv_func_printf_directive_f="guessing no"])
671                                 ;;
672                                 # If we don't know, obey --enable-cross-guesses.
673           *)                    gl_cv_func_printf_directive_f="$gl_cross_guess_normal";;
674         esac
675        ])
676    ])
677])
678
679dnl Test whether the *printf family of functions supports the %n format
680dnl directive. (ISO C99, POSIX:2001)
681dnl Result is gl_cv_func_printf_directive_n.
682
683AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
684[
685  AC_REQUIRE([AC_PROG_CC])
686  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
687  AC_CACHE_CHECK([whether printf supports the 'n' directive],
688    [gl_cv_func_printf_directive_n],
689    [
690      AC_RUN_IFELSE(
691        [AC_LANG_SOURCE([[
692#include <stdio.h>
693#include <stdlib.h>
694#include <string.h>
695#ifdef _MSC_VER
696#include <inttypes.h>
697/* See page about "Parameter Validation" on msdn.microsoft.com.
698   <https://docs.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation>
699   <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-invalid-parameter-handler-set-thread-local-invalid-parameter-handler>  */
700static void cdecl
701invalid_parameter_handler (const wchar_t *expression,
702                           const wchar_t *function,
703                           const wchar_t *file, unsigned int line,
704                           uintptr_t dummy)
705{
706  exit (1);
707}
708#endif
709static char fmtstring[10];
710static char buf[100];
711int main ()
712{
713  int count = -1;
714#ifdef _MSC_VER
715  _set_invalid_parameter_handler (invalid_parameter_handler);
716#endif
717  /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
718     support %n in format strings in read-only memory but not in writable
719     memory.  */
720  strcpy (fmtstring, "%d %n");
721  if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0
722      || strcmp (buf, "123 ") != 0
723      || count != 4)
724    return 1;
725  return 0;
726}]])],
727        [gl_cv_func_printf_directive_n=yes],
728        [gl_cv_func_printf_directive_n=no],
729        [case "$host_os" in
730                            # Guess no on glibc when _FORTIFY_SOURCE >= 2.
731           *-gnu* | gnu*)   AC_COMPILE_IFELSE(
732                              [AC_LANG_SOURCE(
733                                 [[#if _FORTIFY_SOURCE >= 2
734                                    error fail
735                                   #endif
736                                 ]])],
737                              [gl_cv_func_printf_directive_n="guessing yes"],
738                              [gl_cv_func_printf_directive_n="guessing no"])
739                            ;;
740                            # Guess no on Android.
741           linux*-android*) gl_cv_func_printf_directive_n="guessing no";;
742                            # Guess no on native Windows.
743           mingw*)          gl_cv_func_printf_directive_n="guessing no";;
744           *)               gl_cv_func_printf_directive_n="guessing yes";;
745         esac
746        ])
747    ])
748])
749
750dnl Test whether the *printf family of functions supports the %ls format
751dnl directive and in particular, when a precision is specified, whether
752dnl the functions stop converting the wide string argument when the number
753dnl of bytes that have been produced by this conversion equals or exceeds
754dnl the precision.
755dnl Result is gl_cv_func_printf_directive_ls.
756
757AC_DEFUN([gl_PRINTF_DIRECTIVE_LS],
758[
759  AC_REQUIRE([AC_PROG_CC])
760  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
761  AC_CACHE_CHECK([whether printf supports the 'ls' directive],
762    [gl_cv_func_printf_directive_ls],
763    [
764      AC_RUN_IFELSE(
765        [AC_LANG_SOURCE([[
766#include <stdio.h>
767#include <wchar.h>
768#include <string.h>
769int main ()
770{
771  int result = 0;
772  char buf[100];
773  /* Test whether %ls works at all.
774     This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
775     Cygwin 1.5.  */
776  {
777    static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
778    buf[0] = '\0';
779    if (sprintf (buf, "%ls", wstring) < 0
780        || strcmp (buf, "abc") != 0)
781      result |= 1;
782  }
783  /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
784     assertion failure inside libc), but not on OpenBSD 4.0.  */
785  {
786    static const wchar_t wstring[] = { 'a', 0 };
787    buf[0] = '\0';
788    if (sprintf (buf, "%ls", wstring) < 0
789        || strcmp (buf, "a") != 0)
790      result |= 2;
791  }
792  /* Test whether precisions in %ls are supported as specified in ISO C 99
793     section 7.19.6.1:
794       "If a precision is specified, no more than that many bytes are written
795        (including shift sequences, if any), and the array shall contain a
796        null wide character if, to equal the multibyte character sequence
797        length given by the precision, the function would need to access a
798        wide character one past the end of the array."
799     This test fails on Solaris 10.  */
800  {
801    static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 };
802    buf[0] = '\0';
803    if (sprintf (buf, "%.2ls", wstring) < 0
804        || strcmp (buf, "ab") != 0)
805      result |= 8;
806  }
807  return result;
808}]])],
809        [gl_cv_func_printf_directive_ls=yes],
810        [gl_cv_func_printf_directive_ls=no],
811        [
812changequote(,)dnl
813         case "$host_os" in
814                            # Guess yes on OpenBSD >= 6.0.
815           openbsd[1-5].*)  gl_cv_func_printf_directive_ls="guessing no";;
816           openbsd*)        gl_cv_func_printf_directive_ls="guessing yes";;
817           irix*)           gl_cv_func_printf_directive_ls="guessing no";;
818           solaris*)        gl_cv_func_printf_directive_ls="guessing no";;
819           cygwin*)         gl_cv_func_printf_directive_ls="guessing no";;
820           beos* | haiku*)  gl_cv_func_printf_directive_ls="guessing no";;
821                            # Guess no on Android.
822           linux*-android*) gl_cv_func_printf_directive_ls="guessing no";;
823                            # Guess yes on native Windows.
824           mingw*)          gl_cv_func_printf_directive_ls="guessing yes";;
825           *)               gl_cv_func_printf_directive_ls="guessing yes";;
826         esac
827changequote([,])dnl
828        ])
829    ])
830])
831
832dnl Test whether the *printf family of functions supports POSIX/XSI format
833dnl strings with positions. (POSIX:2001)
834dnl Result is gl_cv_func_printf_positions.
835
836AC_DEFUN([gl_PRINTF_POSITIONS],
837[
838  AC_REQUIRE([AC_PROG_CC])
839  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
840  AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
841    [gl_cv_func_printf_positions],
842    [
843      AC_RUN_IFELSE(
844        [AC_LANG_SOURCE([[
845#include <stdio.h>
846#include <string.h>
847/* The string "%2$d %1$d", with dollar characters protected from the shell's
848   dollar expansion (possibly an autoconf bug).  */
849static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
850static char buf[100];
851int main ()
852{
853  sprintf (buf, format, 33, 55);
854  return (strcmp (buf, "55 33") != 0);
855}]])],
856        [gl_cv_func_printf_positions=yes],
857        [gl_cv_func_printf_positions=no],
858        [
859changequote(,)dnl
860         case "$host_os" in
861           netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
862                            gl_cv_func_printf_positions="guessing no";;
863           beos*)           gl_cv_func_printf_positions="guessing no";;
864                            # Guess yes on Android.
865           linux*-android*) gl_cv_func_printf_positions="guessing yes";;
866                            # Guess no on native Windows.
867           mingw* | pw*)    gl_cv_func_printf_positions="guessing no";;
868           *)               gl_cv_func_printf_positions="guessing yes";;
869         esac
870changequote([,])dnl
871        ])
872    ])
873])
874
875dnl Test whether the *printf family of functions supports POSIX/XSI format
876dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
877dnl Result is gl_cv_func_printf_flag_grouping.
878
879AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
880[
881  AC_REQUIRE([AC_PROG_CC])
882  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
883  AC_CACHE_CHECK([whether printf supports the grouping flag],
884    [gl_cv_func_printf_flag_grouping],
885    [
886      AC_RUN_IFELSE(
887        [AC_LANG_SOURCE([[
888#include <stdio.h>
889#include <string.h>
890static char buf[100];
891int main ()
892{
893  if (sprintf (buf, "%'d %d", 1234567, 99) < 0
894      || buf[strlen (buf) - 1] != '9')
895    return 1;
896  return 0;
897}]])],
898        [gl_cv_func_printf_flag_grouping=yes],
899        [gl_cv_func_printf_flag_grouping=no],
900        [
901changequote(,)dnl
902         case "$host_os" in
903           cygwin*)         gl_cv_func_printf_flag_grouping="guessing no";;
904           netbsd*)         gl_cv_func_printf_flag_grouping="guessing no";;
905                            # Guess no on Android.
906           linux*-android*) gl_cv_func_printf_flag_grouping="guessing no";;
907                            # Guess no on native Windows.
908           mingw* | pw*)    gl_cv_func_printf_flag_grouping="guessing no";;
909           *)               gl_cv_func_printf_flag_grouping="guessing yes";;
910         esac
911changequote([,])dnl
912        ])
913    ])
914])
915
916dnl Test whether the *printf family of functions supports the - flag correctly.
917dnl (ISO C99.) See
918dnl <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html>
919dnl Result is gl_cv_func_printf_flag_leftadjust.
920
921AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST],
922[
923  AC_REQUIRE([AC_PROG_CC])
924  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
925  AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly],
926    [gl_cv_func_printf_flag_leftadjust],
927    [
928      AC_RUN_IFELSE(
929        [AC_LANG_SOURCE([[
930#include <stdio.h>
931#include <string.h>
932static char buf[100];
933int main ()
934{
935  /* Check that a '-' flag is not annihilated by a negative width.  */
936  if (sprintf (buf, "a%-*sc", -3, "b") < 0
937      || strcmp (buf, "ab  c") != 0)
938    return 1;
939  return 0;
940}]])],
941        [gl_cv_func_printf_flag_leftadjust=yes],
942        [gl_cv_func_printf_flag_leftadjust=no],
943        [
944changequote(,)dnl
945         case "$host_os" in
946                            # Guess yes on HP-UX 11.
947           hpux11*)         gl_cv_func_printf_flag_leftadjust="guessing yes";;
948                            # Guess no on HP-UX 10 and older.
949           hpux*)           gl_cv_func_printf_flag_leftadjust="guessing no";;
950                            # Guess yes on Android.
951           linux*-android*) gl_cv_func_printf_flag_leftadjust="guessing yes";;
952                            # Guess yes on native Windows.
953           mingw*)          gl_cv_func_printf_flag_leftadjust="guessing yes";;
954                            # Guess yes otherwise.
955           *)               gl_cv_func_printf_flag_leftadjust="guessing yes";;
956         esac
957changequote([,])dnl
958        ])
959    ])
960])
961
962dnl Test whether the *printf family of functions supports padding of non-finite
963dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
964dnl <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html>
965dnl Result is gl_cv_func_printf_flag_zero.
966
967AC_DEFUN([gl_PRINTF_FLAG_ZERO],
968[
969  AC_REQUIRE([AC_PROG_CC])
970  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
971  AC_CACHE_CHECK([whether printf supports the zero flag correctly],
972    [gl_cv_func_printf_flag_zero],
973    [
974      AC_RUN_IFELSE(
975        [AC_LANG_SOURCE([[
976#include <stdio.h>
977#include <string.h>
978static char buf[100];
979static double zero = 0.0;
980int main ()
981{
982  if (sprintf (buf, "%010f", 1.0 / zero, 33, 44, 55) < 0
983      || (strcmp (buf, "       inf") != 0
984          && strcmp (buf, "  infinity") != 0))
985    return 1;
986  return 0;
987}]])],
988        [gl_cv_func_printf_flag_zero=yes],
989        [gl_cv_func_printf_flag_zero=no],
990        [
991changequote(,)dnl
992         case "$host_os" in
993                            # Guess yes on glibc systems.
994           *-gnu* | gnu*)   gl_cv_func_printf_flag_zero="guessing yes";;
995                            # Guess yes on musl systems.
996           *-musl*)         gl_cv_func_printf_flag_zero="guessing yes";;
997                            # Guess yes on BeOS.
998           beos*)           gl_cv_func_printf_flag_zero="guessing yes";;
999                            # Guess no on Android.
1000           linux*-android*) gl_cv_func_printf_flag_zero="guessing no";;
1001                            # Guess no on native Windows.
1002           mingw*)          gl_cv_func_printf_flag_zero="guessing no";;
1003                            # If we don't know, obey --enable-cross-guesses.
1004           *)               gl_cv_func_printf_flag_zero="$gl_cross_guess_normal";;
1005         esac
1006changequote([,])dnl
1007        ])
1008    ])
1009])
1010
1011dnl Test whether the *printf family of functions supports large precisions.
1012dnl On mingw, precisions larger than 512 are treated like 512, in integer,
1013dnl floating-point or pointer output. On Solaris 10/x86, precisions larger
1014dnl than 510 in floating-point output crash the program. On Solaris 10/SPARC,
1015dnl precisions larger than 510 in floating-point output yield wrong results.
1016dnl On AIX 7.1, precisions larger than 998 in floating-point output yield
1017dnl wrong results. On BeOS, precisions larger than 1044 crash the program.
1018dnl Result is gl_cv_func_printf_precision.
1019
1020AC_DEFUN([gl_PRINTF_PRECISION],
1021[
1022  AC_REQUIRE([AC_PROG_CC])
1023  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1024  AC_CACHE_CHECK([whether printf supports large precisions],
1025    [gl_cv_func_printf_precision],
1026    [
1027      AC_RUN_IFELSE(
1028        [AC_LANG_SOURCE([[
1029#include <stdio.h>
1030#include <string.h>
1031static char buf[5000];
1032int main ()
1033{
1034  int result = 0;
1035#ifdef __BEOS__
1036  /* On BeOS, this would crash and show a dialog box.  Avoid the crash.  */
1037  return 1;
1038#endif
1039  if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3)
1040    result |= 1;
1041  if (sprintf (buf, "%.4000f %d", 1.0, 33, 44) < 4000 + 5)
1042    result |= 2;
1043  if (sprintf (buf, "%.511f %d", 1.0, 33, 44) < 511 + 5
1044      || buf[0] != '1')
1045    result |= 4;
1046  if (sprintf (buf, "%.999f %d", 1.0, 33, 44) < 999 + 5
1047      || buf[0] != '1')
1048    result |= 4;
1049  return result;
1050}]])],
1051        [gl_cv_func_printf_precision=yes],
1052        [gl_cv_func_printf_precision=no],
1053        [
1054changequote(,)dnl
1055         case "$host_os" in
1056           # Guess no only on Solaris, native Windows, and BeOS systems.
1057           solaris*)        gl_cv_func_printf_precision="guessing no" ;;
1058           mingw* | pw*)    gl_cv_func_printf_precision="guessing no" ;;
1059           beos*)           gl_cv_func_printf_precision="guessing no" ;;
1060                            # Guess yes on Android.
1061           linux*-android*) gl_cv_func_printf_precision="guessing yes" ;;
1062           *)               gl_cv_func_printf_precision="guessing yes" ;;
1063         esac
1064changequote([,])dnl
1065        ])
1066    ])
1067])
1068
1069dnl Test whether the *printf family of functions recovers gracefully in case
1070dnl of an out-of-memory condition, or whether it crashes the entire program.
1071dnl Result is gl_cv_func_printf_enomem.
1072
1073AC_DEFUN([gl_PRINTF_ENOMEM],
1074[
1075  AC_REQUIRE([AC_PROG_CC])
1076  AC_REQUIRE([gl_MULTIARCH])
1077  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1078  AC_CACHE_CHECK([whether printf survives out-of-memory conditions],
1079    [gl_cv_func_printf_enomem],
1080    [
1081      gl_cv_func_printf_enomem="guessing no"
1082      if test "$cross_compiling" = no; then
1083        if test $APPLE_UNIVERSAL_BUILD = 0; then
1084          AC_LANG_CONFTEST([AC_LANG_SOURCE([[
1085]GL_NOCRASH[
1086#include <stdio.h>
1087#include <sys/types.h>
1088#include <sys/time.h>
1089#include <sys/resource.h>
1090#include <errno.h>
1091int main()
1092{
1093  struct rlimit limit;
1094  int ret;
1095  nocrash_init ();
1096  /* Some printf implementations allocate temporary space with malloc.  */
1097  /* On BSD systems, malloc() is limited by RLIMIT_DATA.  */
1098#ifdef RLIMIT_DATA
1099  if (getrlimit (RLIMIT_DATA, &limit) < 0)
1100    return 77;
1101  if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
1102    limit.rlim_max = 5000000;
1103  limit.rlim_cur = limit.rlim_max;
1104  if (setrlimit (RLIMIT_DATA, &limit) < 0)
1105    return 77;
1106#endif
1107  /* On Linux systems, malloc() is limited by RLIMIT_AS.  */
1108#ifdef RLIMIT_AS
1109  if (getrlimit (RLIMIT_AS, &limit) < 0)
1110    return 77;
1111  if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
1112    limit.rlim_max = 5000000;
1113  limit.rlim_cur = limit.rlim_max;
1114  if (setrlimit (RLIMIT_AS, &limit) < 0)
1115    return 77;
1116#endif
1117  /* Some printf implementations allocate temporary space on the stack.  */
1118#ifdef RLIMIT_STACK
1119  if (getrlimit (RLIMIT_STACK, &limit) < 0)
1120    return 77;
1121  if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
1122    limit.rlim_max = 5000000;
1123  limit.rlim_cur = limit.rlim_max;
1124  if (setrlimit (RLIMIT_STACK, &limit) < 0)
1125    return 77;
1126#endif
1127  ret = printf ("%.5000000f", 1.0);
1128  return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
1129}
1130          ]])])
1131          if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
1132            (./conftest 2>&AS_MESSAGE_LOG_FD
1133             result=$?
1134             _AS_ECHO_LOG([\$? = $result])
1135             if test $result != 0 && test $result != 77; then result=1; fi
1136             exit $result
1137            ) >/dev/null 2>/dev/null
1138            case $? in
1139              0) gl_cv_func_printf_enomem="yes" ;;
1140              77) gl_cv_func_printf_enomem="guessing no" ;;
1141              *) gl_cv_func_printf_enomem="no" ;;
1142            esac
1143          else
1144            gl_cv_func_printf_enomem="guessing no"
1145          fi
1146          rm -fr conftest*
1147        else
1148          dnl A universal build on Apple Mac OS X platforms.
1149          dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode.
1150          dnl But we need a configuration result that is valid in both modes.
1151          gl_cv_func_printf_enomem="guessing no"
1152        fi
1153      fi
1154      if test "$gl_cv_func_printf_enomem" = "guessing no"; then
1155changequote(,)dnl
1156        case "$host_os" in
1157                           # Guess yes on glibc systems.
1158          *-gnu* | gnu*)   gl_cv_func_printf_enomem="guessing yes";;
1159                           # Guess yes on Solaris.
1160          solaris*)        gl_cv_func_printf_enomem="guessing yes";;
1161                           # Guess yes on AIX.
1162          aix*)            gl_cv_func_printf_enomem="guessing yes";;
1163                           # Guess yes on HP-UX/hppa.
1164          hpux*)           case "$host_cpu" in
1165                             hppa*) gl_cv_func_printf_enomem="guessing yes";;
1166                             *)     gl_cv_func_printf_enomem="guessing no";;
1167                           esac
1168                           ;;
1169                           # Guess yes on IRIX.
1170          irix*)           gl_cv_func_printf_enomem="guessing yes";;
1171                           # Guess yes on OSF/1.
1172          osf*)            gl_cv_func_printf_enomem="guessing yes";;
1173                           # Guess yes on BeOS.
1174          beos*)           gl_cv_func_printf_enomem="guessing yes";;
1175                           # Guess yes on Haiku.
1176          haiku*)          gl_cv_func_printf_enomem="guessing yes";;
1177                           # Guess no on Android.
1178          linux*-android*) gl_cv_func_printf_enomem="guessing no";;
1179                           # If we don't know, obey --enable-cross-guesses.
1180          *)               gl_cv_func_printf_enomem="$gl_cross_guess_normal";;
1181        esac
1182changequote([,])dnl
1183      fi
1184    ])
1185])
1186
1187dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
1188dnl Result is ac_cv_func_snprintf.
1189
1190AC_DEFUN([gl_SNPRINTF_PRESENCE],
1191[
1192  AC_CHECK_FUNCS_ONCE([snprintf])
1193])
1194
1195dnl Test whether the string produced by the snprintf function is always NUL
1196dnl terminated. (ISO C99, POSIX:2001)
1197dnl Result is gl_cv_func_snprintf_truncation_c99.
1198
1199AC_DEFUN_ONCE([gl_SNPRINTF_TRUNCATION_C99],
1200[
1201  AC_REQUIRE([AC_PROG_CC])
1202  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1203  AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1204  AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
1205    [gl_cv_func_snprintf_truncation_c99],
1206    [
1207      AC_RUN_IFELSE(
1208        [AC_LANG_SOURCE([[
1209#include <stdio.h>
1210#include <string.h>
1211#if HAVE_SNPRINTF
1212# define my_snprintf snprintf
1213#else
1214# include <stdarg.h>
1215static int my_snprintf (char *buf, int size, const char *format, ...)
1216{
1217  va_list args;
1218  int ret;
1219  va_start (args, format);
1220  ret = vsnprintf (buf, size, format, args);
1221  va_end (args);
1222  return ret;
1223}
1224#endif
1225static char buf[100];
1226int main ()
1227{
1228  strcpy (buf, "ABCDEF");
1229  my_snprintf (buf, 3, "%d %d", 4567, 89);
1230  if (memcmp (buf, "45\0DEF", 6) != 0)
1231    return 1;
1232  return 0;
1233}]])],
1234        [gl_cv_func_snprintf_truncation_c99=yes],
1235        [gl_cv_func_snprintf_truncation_c99=no],
1236        [
1237changequote(,)dnl
1238         case "$host_os" in
1239                                 # Guess yes on glibc systems.
1240           *-gnu* | gnu*)        gl_cv_func_snprintf_truncation_c99="guessing yes";;
1241                                 # Guess yes on musl systems.
1242           *-musl*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1243                                 # Guess yes on FreeBSD >= 5.
1244           freebsd[1-4].*)       gl_cv_func_snprintf_truncation_c99="guessing no";;
1245           freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1246           midnightbsd*)         gl_cv_func_snprintf_truncation_c99="guessing yes";;
1247                                 # Guess yes on Mac OS X >= 10.3.
1248           darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
1249           darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1250                                 # Guess yes on OpenBSD >= 3.9.
1251           openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1252                                 gl_cv_func_snprintf_truncation_c99="guessing no";;
1253           openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
1254                                 # Guess yes on Solaris >= 2.6.
1255           solaris2.[0-5] | solaris2.[0-5].*)
1256                                 gl_cv_func_snprintf_truncation_c99="guessing no";;
1257           solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
1258                                 # Guess yes on AIX >= 4.
1259           aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
1260           aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
1261                                 # Guess yes on HP-UX >= 11.
1262           hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1263           hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
1264                                 # Guess yes on IRIX >= 6.5.
1265           irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1266                                 # Guess yes on OSF/1 >= 5.
1267           osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
1268           osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
1269                                 # Guess yes on NetBSD >= 3.
1270           netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1271                                 gl_cv_func_snprintf_truncation_c99="guessing no";;
1272           netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1273                                 # Guess yes on BeOS.
1274           beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
1275                                 # Guess yes on Android.
1276           linux*-android*)      gl_cv_func_snprintf_truncation_c99="guessing yes";;
1277                                 # Guess no on native Windows.
1278           mingw*)               gl_cv_func_snprintf_truncation_c99="guessing no";;
1279                                 # If we don't know, obey --enable-cross-guesses.
1280           *)                    gl_cv_func_snprintf_truncation_c99="$gl_cross_guess_normal";;
1281         esac
1282changequote([,])dnl
1283        ])
1284    ])
1285])
1286
1287dnl Test whether the return value of the snprintf function is the number
1288dnl of bytes (excluding the terminating NUL) that would have been produced
1289dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
1290dnl For example, this test program fails on IRIX 6.5:
1291dnl     ---------------------------------------------------------------------
1292dnl     #include <stdio.h>
1293dnl     int main()
1294dnl     {
1295dnl       static char buf[8];
1296dnl       int retval = snprintf (buf, 3, "%d", 12345);
1297dnl       return retval >= 0 && retval < 3;
1298dnl     }
1299dnl     ---------------------------------------------------------------------
1300dnl Result is gl_cv_func_snprintf_retval_c99.
1301
1302AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99],
1303[
1304  AC_REQUIRE([AC_PROG_CC])
1305  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1306  AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1307  AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
1308    [gl_cv_func_snprintf_retval_c99],
1309    [
1310      AC_RUN_IFELSE(
1311        [AC_LANG_SOURCE([[
1312#include <stdio.h>
1313#include <string.h>
1314#if HAVE_SNPRINTF
1315# define my_snprintf snprintf
1316#else
1317# include <stdarg.h>
1318static int my_snprintf (char *buf, int size, const char *format, ...)
1319{
1320  va_list args;
1321  int ret;
1322  va_start (args, format);
1323  ret = vsnprintf (buf, size, format, args);
1324  va_end (args);
1325  return ret;
1326}
1327#endif
1328static char buf[100];
1329int main ()
1330{
1331  strcpy (buf, "ABCDEF");
1332  if (my_snprintf (buf, 3, "%d %d", 4567, 89) != 7)
1333    return 1;
1334  if (my_snprintf (buf, 0, "%d %d", 4567, 89) != 7)
1335    return 2;
1336  if (my_snprintf (NULL, 0, "%d %d", 4567, 89) != 7)
1337    return 3;
1338  return 0;
1339}]])],
1340        [gl_cv_func_snprintf_retval_c99=yes],
1341        [gl_cv_func_snprintf_retval_c99=no],
1342        [case "$host_os" in
1343changequote(,)dnl
1344                                 # Guess yes on glibc systems.
1345           *-gnu* | gnu*)        gl_cv_func_snprintf_retval_c99="guessing yes";;
1346                                 # Guess yes on musl systems.
1347           *-musl*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1348                                 # Guess yes on FreeBSD >= 5.
1349           freebsd[1-4].*)       gl_cv_func_snprintf_retval_c99="guessing no";;
1350           freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1351           midnightbsd*)         gl_cv_func_snprintf_retval_c99="guessing yes";;
1352                                 # Guess yes on Mac OS X >= 10.3.
1353           darwin[1-6].*)        gl_cv_func_snprintf_retval_c99="guessing no";;
1354           darwin*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1355                                 # Guess yes on OpenBSD >= 3.9.
1356           openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1357                                 gl_cv_func_snprintf_retval_c99="guessing no";;
1358           openbsd*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
1359                                 # Guess yes on Solaris >= 2.10.
1360           solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";;
1361           solaris*)             gl_cv_func_printf_sizes_c99="guessing no";;
1362                                 # Guess yes on AIX >= 4.
1363           aix[1-3]*)            gl_cv_func_snprintf_retval_c99="guessing no";;
1364           aix*)                 gl_cv_func_snprintf_retval_c99="guessing yes";;
1365                                 # Guess yes on NetBSD >= 3.
1366           netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1367                                 gl_cv_func_snprintf_retval_c99="guessing no";;
1368           netbsd*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1369                                 # Guess yes on BeOS.
1370           beos*)                gl_cv_func_snprintf_retval_c99="guessing yes";;
1371                                 # Guess yes on Android.
1372           linux*-android*)      gl_cv_func_snprintf_retval_c99="guessing yes";;
1373changequote([,])dnl
1374                                 # Guess yes on MSVC, no on mingw.
1375           mingw*)               AC_EGREP_CPP([Known], [
1376#ifdef _MSC_VER
1377 Known
1378#endif
1379                                   ],
1380                                   [gl_cv_func_snprintf_retval_c99="guessing yes"],
1381                                   [gl_cv_func_snprintf_retval_c99="guessing no"])
1382                                 ;;
1383                                 # If we don't know, obey --enable-cross-guesses.
1384           *)                    gl_cv_func_snprintf_retval_c99="$gl_cross_guess_normal";;
1385         esac
1386        ])
1387    ])
1388])
1389
1390dnl Test whether the snprintf function supports the %n format directive
1391dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
1392dnl Result is gl_cv_func_snprintf_directive_n.
1393
1394AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
1395[
1396  AC_REQUIRE([AC_PROG_CC])
1397  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1398  AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1399  AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
1400    [gl_cv_func_snprintf_directive_n],
1401    [
1402      AC_RUN_IFELSE(
1403        [AC_LANG_SOURCE([[
1404#include <stdio.h>
1405#include <string.h>
1406#if HAVE_SNPRINTF
1407# define my_snprintf snprintf
1408#else
1409# include <stdarg.h>
1410static int my_snprintf (char *buf, int size, const char *format, ...)
1411{
1412  va_list args;
1413  int ret;
1414  va_start (args, format);
1415  ret = vsnprintf (buf, size, format, args);
1416  va_end (args);
1417  return ret;
1418}
1419#endif
1420static char fmtstring[10];
1421static char buf[100];
1422int main ()
1423{
1424  int count = -1;
1425  /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
1426     support %n in format strings in read-only memory but not in writable
1427     memory.  */
1428  strcpy (fmtstring, "%d %n");
1429  my_snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55);
1430  if (count != 6)
1431    return 1;
1432  return 0;
1433}]])],
1434        [gl_cv_func_snprintf_directive_n=yes],
1435        [gl_cv_func_snprintf_directive_n=no],
1436        [
1437         case "$host_os" in
1438                                 # Guess no on glibc when _FORTIFY_SOURCE >= 2.
1439           *-gnu* | gnu*)        AC_COMPILE_IFELSE(
1440                                   [AC_LANG_SOURCE(
1441                                      [[#if _FORTIFY_SOURCE >= 2
1442                                         error fail
1443                                        #endif
1444                                      ]])],
1445                                   [gl_cv_func_snprintf_directive_n="guessing yes"],
1446                                   [gl_cv_func_snprintf_directive_n="guessing no"])
1447                                 ;;
1448changequote(,)dnl
1449                                 # Guess yes on musl systems.
1450           *-musl*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1451                                 # Guess yes on FreeBSD >= 5.
1452           freebsd[1-4].*)       gl_cv_func_snprintf_directive_n="guessing no";;
1453           freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
1454           midnightbsd*)         gl_cv_func_snprintf_directive_n="guessing yes";;
1455                                 # Guess yes on Mac OS X >= 10.3.
1456           darwin[1-6].*)        gl_cv_func_snprintf_directive_n="guessing no";;
1457           darwin*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1458                                 # Guess yes on Solaris >= 2.6.
1459           solaris2.[0-5] | solaris2.[0-5].*)
1460                                 gl_cv_func_snprintf_directive_n="guessing no";;
1461           solaris*)             gl_cv_func_snprintf_directive_n="guessing yes";;
1462                                 # Guess yes on AIX >= 4.
1463           aix[1-3]*)            gl_cv_func_snprintf_directive_n="guessing no";;
1464           aix*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
1465                                 # Guess yes on IRIX >= 6.5.
1466           irix6.5)              gl_cv_func_snprintf_directive_n="guessing yes";;
1467                                 # Guess yes on OSF/1 >= 5.
1468           osf[3-4]*)            gl_cv_func_snprintf_directive_n="guessing no";;
1469           osf*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
1470                                 # Guess yes on NetBSD >= 3.
1471           netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1472                                 gl_cv_func_snprintf_directive_n="guessing no";;
1473           netbsd*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1474                                 # Guess yes on BeOS.
1475           beos*)                gl_cv_func_snprintf_directive_n="guessing yes";;
1476                                 # Guess no on Android.
1477           linux*-android*)      gl_cv_func_snprintf_directive_n="guessing no";;
1478                                 # Guess no on native Windows.
1479           mingw*)               gl_cv_func_snprintf_directive_n="guessing no";;
1480                                 # If we don't know, obey --enable-cross-guesses.
1481           *)                    gl_cv_func_snprintf_directive_n="$gl_cross_guess_normal";;
1482changequote([,])dnl
1483         esac
1484        ])
1485    ])
1486])
1487
1488dnl Test whether the snprintf function, when passed a size = 1, writes any
1489dnl output without bounds in this case, behaving like sprintf. This is the
1490dnl case on Linux libc5.
1491dnl Result is gl_cv_func_snprintf_size1.
1492
1493AC_DEFUN([gl_SNPRINTF_SIZE1],
1494[
1495  AC_REQUIRE([AC_PROG_CC])
1496  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1497  AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1498  AC_CACHE_CHECK([whether snprintf respects a size of 1],
1499    [gl_cv_func_snprintf_size1],
1500    [
1501      AC_RUN_IFELSE(
1502        [AC_LANG_SOURCE([[
1503#include <stdio.h>
1504#if HAVE_SNPRINTF
1505# define my_snprintf snprintf
1506#else
1507# include <stdarg.h>
1508static int my_snprintf (char *buf, int size, const char *format, ...)
1509{
1510  va_list args;
1511  int ret;
1512  va_start (args, format);
1513  ret = vsnprintf (buf, size, format, args);
1514  va_end (args);
1515  return ret;
1516}
1517#endif
1518int main()
1519{
1520  static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1521  my_snprintf (buf, 1, "%d", 12345);
1522  return buf[1] != 'E';
1523}]])],
1524        [gl_cv_func_snprintf_size1=yes],
1525        [gl_cv_func_snprintf_size1=no],
1526        [case "$host_os" in
1527                            # Guess yes on Android.
1528           linux*-android*) gl_cv_func_snprintf_size1="guessing yes" ;;
1529                            # Guess yes on native Windows.
1530           mingw*)          gl_cv_func_snprintf_size1="guessing yes" ;;
1531           *)               gl_cv_func_snprintf_size1="guessing yes" ;;
1532         esac
1533        ])
1534    ])
1535])
1536
1537dnl Test whether the vsnprintf function, when passed a zero size, produces no
1538dnl output. (ISO C99, POSIX:2001)
1539dnl For example, snprintf nevertheless writes a NUL byte in this case
1540dnl on OSF/1 5.1:
1541dnl     ---------------------------------------------------------------------
1542dnl     #include <stdio.h>
1543dnl     int main()
1544dnl     {
1545dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1546dnl       snprintf (buf, 0, "%d", 12345);
1547dnl       return buf[0] != 'D';
1548dnl     }
1549dnl     ---------------------------------------------------------------------
1550dnl And vsnprintf writes any output without bounds in this case, behaving like
1551dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
1552dnl     ---------------------------------------------------------------------
1553dnl     #include <stdarg.h>
1554dnl     #include <stdio.h>
1555dnl     static int my_snprintf (char *buf, int size, const char *format, ...)
1556dnl     {
1557dnl       va_list args;
1558dnl       int ret;
1559dnl       va_start (args, format);
1560dnl       ret = vsnprintf (buf, size, format, args);
1561dnl       va_end (args);
1562dnl       return ret;
1563dnl     }
1564dnl     int main()
1565dnl     {
1566dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1567dnl       my_snprintf (buf, 0, "%d", 12345);
1568dnl       return buf[0] != 'D';
1569dnl     }
1570dnl     ---------------------------------------------------------------------
1571dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
1572
1573AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
1574[
1575  AC_REQUIRE([AC_PROG_CC])
1576  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1577  AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
1578    [gl_cv_func_vsnprintf_zerosize_c99],
1579    [
1580      AC_RUN_IFELSE(
1581        [AC_LANG_SOURCE([[
1582#include <stdarg.h>
1583#include <stdio.h>
1584static int my_snprintf (char *buf, int size, const char *format, ...)
1585{
1586  va_list args;
1587  int ret;
1588  va_start (args, format);
1589  ret = vsnprintf (buf, size, format, args);
1590  va_end (args);
1591  return ret;
1592}
1593int main()
1594{
1595  static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1596  my_snprintf (buf, 0, "%d", 12345);
1597  return buf[0] != 'D';
1598}]])],
1599        [gl_cv_func_vsnprintf_zerosize_c99=yes],
1600        [gl_cv_func_vsnprintf_zerosize_c99=no],
1601        [
1602changequote(,)dnl
1603         case "$host_os" in
1604                                 # Guess yes on glibc systems.
1605           *-gnu* | gnu*)        gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1606                                 # Guess yes on musl systems.
1607           *-musl*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1608                                 # Guess yes on FreeBSD >= 5.
1609           freebsd[1-4].*)       gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1610           freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1611           midnightbsd*)         gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1612                                 # Guess yes on Mac OS X >= 10.3.
1613           darwin[1-6].*)        gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1614           darwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1615                                 # Guess yes on Cygwin.
1616           cygwin*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1617                                 # Guess yes on Solaris >= 2.6.
1618           solaris2.[0-5] | solaris2.[0-5].*)
1619                                 gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1620           solaris*)             gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1621                                 # Guess yes on AIX >= 4.
1622           aix[1-3]*)            gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1623           aix*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1624                                 # Guess yes on IRIX >= 6.5.
1625           irix6.5)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1626                                 # Guess yes on NetBSD >= 3.
1627           netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1628                                 gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1629           netbsd*)              gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1630                                 # Guess yes on BeOS.
1631           beos*)                gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1632                                 # Guess yes on Android.
1633           linux*-android*)      gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1634                                 # Guess yes on native Windows.
1635           mingw* | pw*)         gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1636                                 # If we don't know, obey --enable-cross-guesses.
1637           *)                    gl_cv_func_vsnprintf_zerosize_c99="$gl_cross_guess_normal";;
1638         esac
1639changequote([,])dnl
1640        ])
1641    ])
1642])
1643
1644dnl The results of these tests on various platforms are:
1645dnl
1646dnl 1 = gl_PRINTF_SIZES_C99
1647dnl 2 = gl_PRINTF_LONG_DOUBLE
1648dnl 3 = gl_PRINTF_INFINITE
1649dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
1650dnl 5 = gl_PRINTF_DIRECTIVE_A
1651dnl 6 = gl_PRINTF_DIRECTIVE_F
1652dnl 7 = gl_PRINTF_DIRECTIVE_N
1653dnl 8 = gl_PRINTF_DIRECTIVE_LS
1654dnl 9 = gl_PRINTF_POSITIONS
1655dnl 10 = gl_PRINTF_FLAG_GROUPING
1656dnl 11 = gl_PRINTF_FLAG_LEFTADJUST
1657dnl 12 = gl_PRINTF_FLAG_ZERO
1658dnl 13 = gl_PRINTF_PRECISION
1659dnl 14 = gl_PRINTF_ENOMEM
1660dnl 15 = gl_SNPRINTF_PRESENCE
1661dnl 16 = gl_SNPRINTF_TRUNCATION_C99
1662dnl 17 = gl_SNPRINTF_RETVAL_C99
1663dnl 18 = gl_SNPRINTF_DIRECTIVE_N
1664dnl 19 = gl_SNPRINTF_SIZE1
1665dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99
1666dnl
1667dnl 1 = checking whether printf supports size specifiers as in C99...
1668dnl 2 = checking whether printf supports 'long double' arguments...
1669dnl 3 = checking whether printf supports infinite 'double' arguments...
1670dnl 4 = checking whether printf supports infinite 'long double' arguments...
1671dnl 5 = checking whether printf supports the 'a' and 'A' directives...
1672dnl 6 = checking whether printf supports the 'F' directive...
1673dnl 7 = checking whether printf supports the 'n' directive...
1674dnl 8 = checking whether printf supports the 'ls' directive...
1675dnl 9 = checking whether printf supports POSIX/XSI format strings with positions...
1676dnl 10 = checking whether printf supports the grouping flag...
1677dnl 11 = checking whether printf supports the left-adjust flag correctly...
1678dnl 12 = checking whether printf supports the zero flag correctly...
1679dnl 13 = checking whether printf supports large precisions...
1680dnl 14 = checking whether printf survives out-of-memory conditions...
1681dnl 15 = checking for snprintf...
1682dnl 16 = checking whether snprintf truncates the result as in C99...
1683dnl 17 = checking whether snprintf returns a byte count as in C99...
1684dnl 18 = checking whether snprintf fully supports the 'n' directive...
1685dnl 19 = checking whether snprintf respects a size of 1...
1686dnl 20 = checking whether vsnprintf respects a zero size as in C99...
1687dnl
1688dnl . = yes, # = no.
1689dnl
1690dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
1691dnl   glibc 2.5                      .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
1692dnl   glibc 2.3.6                    .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
1693dnl   FreeBSD 13.0                   .  .  .  .  #  .  .  .  .  .  .  .  .  #  .  .  .  .  .  .
1694dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .
1695dnl   Mac OS X 10.13.5               .  .  .  #  #  .  #  .  .  .  .  .  .  .  .  .  .  #  .  .
1696dnl   Mac OS X 10.5.8                .  .  .  #  #  .  .  .  .  .  .  #  .  .  .  .  .  .  .  .
1697dnl   Mac OS X 10.3.9                .  .  .  .  #  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .
1698dnl   OpenBSD 6.0, 6.7               .  .  .  .  #  .  .  .  .  .  .  .  .  #  .  .  .  .  .  .
1699dnl   OpenBSD 3.9, 4.0               .  .  #  #  #  #  .  #  .  #  .  #  .  #  .  .  .  .  .  .
1700dnl   Cygwin 1.7.0 (2009)            .  .  .  #  .  .  .  ?  .  .  .  .  .  ?  .  .  .  .  .  .
1701dnl   Cygwin 1.5.25 (2008)           .  .  .  #  #  .  .  #  .  .  .  .  .  #  .  .  .  .  .  .
1702dnl   Cygwin 1.5.19 (2006)           #  .  .  #  #  #  .  #  .  #  .  #  #  #  .  .  .  .  .  .
1703dnl   Solaris 11.4                   .  .  #  #  #  .  .  #  .  .  .  #  .  .  .  .  .  .  .  .
1704dnl   Solaris 11.3                   .  .  .  .  #  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .
1705dnl   Solaris 11.0                   .  .  #  #  #  .  .  #  .  .  .  #  .  .  .  .  .  .  .  .
1706dnl   Solaris 10                     .  .  #  #  #  .  .  #  .  .  .  #  #  .  .  .  .  .  .  .
1707dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  .  #  .  .  .  #  #  .  .  .  #  .  .  .
1708dnl   Solaris 2.5.1                  #  .  #  #  #  #  .  #  .  .  .  #  .  .  #  #  #  #  #  #
1709dnl   AIX 7.1                        .  .  #  #  #  .  .  .  .  .  .  #  #  .  .  .  .  .  .  .
1710dnl   AIX 5.2                        .  .  #  #  #  .  .  .  .  .  .  #  .  .  .  .  .  .  .  .
1711dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  .  .  .  .  .  #  .  .  .  .  #  .  .  .
1712dnl   HP-UX 11.31                    .  .  .  .  #  .  .  .  .  .  .  #  .  .  .  .  #  #  .  .
1713dnl   HP-UX 11.{00,11,23}            #  .  .  .  #  #  .  .  .  .  .  #  .  .  .  .  #  #  .  #
1714dnl   HP-UX 10.20                    #  .  #  .  #  #  .  ?  .  .  #  #  .  .  .  .  #  #  ?  #
1715dnl   IRIX 6.5                       #  .  #  #  #  #  .  #  .  .  .  #  .  .  .  .  #  .  .  .
1716dnl   OSF/1 5.1                      #  .  #  #  #  #  .  .  .  .  .  #  .  .  .  .  #  .  .  #
1717dnl   OSF/1 4.0d                     #  .  #  #  #  #  .  .  .  .  .  #  .  .  #  #  #  #  #  #
1718dnl   NetBSD 9.0                     .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
1719dnl   NetBSD 5.0                     .  .  .  #  #  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .
1720dnl   NetBSD 4.0                     .  ?  ?  ?  ?  ?  .  ?  .  ?  ?  ?  ?  ?  .  .  .  ?  ?  ?
1721dnl   NetBSD 3.0                     .  .  .  .  #  #  .  ?  #  #  ?  #  .  #  .  .  .  .  .  .
1722dnl   Haiku                          .  .  .  #  #  #  .  #  .  .  .  .  .  ?  .  .  ?  .  .  .
1723dnl   BeOS                           #  #  .  #  #  #  .  ?  #  .  ?  .  #  ?  .  .  ?  .  .  .
1724dnl   Android 4.3                    .  .  #  #  #  #  #  #  .  #  .  #  .  #  .  .  .  #  .  .
1725dnl   old mingw / msvcrt             #  #  #  #  #  #  .  .  #  #  .  #  #  ?  .  #  #  #  .  .
1726dnl   MSVC 9                         #  #  #  #  #  #  #  .  #  #  .  #  #  ?  #  #  #  #  .  .
1727dnl   mingw 2009-2011                .  #  .  #  .  .  .  .  #  #  .  .  .  ?  .  .  .  .  .  .
1728dnl   mingw-w64 2011                 #  #  #  #  #  #  .  .  #  #  .  #  #  ?  .  #  #  #  .  .
1729