string-buffer tests: Avoid test failure on native Windows.
[gnulib.git] / m4 / printf.m4
bloba6daa1a62cc0b95f09deec79a732d257eb8df926
1 # printf.m4
2 # serial 95
3 dnl Copyright (C) 2003, 2007-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
8 dnl Test whether the *printf family of functions supports the 'j', 'z', 't',
9 dnl 'L' size specifiers. (ISO C99, POSIX:2001)
10 dnl Result is gl_cv_func_printf_sizes_c99.
12 AC_DEFUN([gl_PRINTF_SIZES_C99],
14   AC_REQUIRE([AC_PROG_CC])
15   AC_REQUIRE([gl_AC_HEADER_STDINT_H])
16   AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
17   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
18   AC_CACHE_CHECK([whether printf supports size specifiers as in C99],
19     [gl_cv_func_printf_sizes_c99],
20     [
21       AC_RUN_IFELSE(
22         [AC_LANG_SOURCE([[
23 #include <stddef.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #if HAVE_STDINT_H_WITH_UINTMAX
28 # include <stdint.h>
29 #endif
30 #if HAVE_INTTYPES_H_WITH_UINTMAX
31 # include <inttypes.h>
32 #endif
33 static char buf[100];
34 int main ()
36   int result = 0;
37 #if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
38   buf[0] = '\0';
39   if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0
40       || strcmp (buf, "12345671 33") != 0)
41     result |= 1;
42 #else
43   result |= 1;
44 #endif
45   buf[0] = '\0';
46   if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0
47       || strcmp (buf, "12345672 33") != 0)
48     result |= 2;
49   buf[0] = '\0';
50   if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0
51       || strcmp (buf, "12345673 33") != 0)
52     result |= 4;
53   buf[0] = '\0';
54   if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0
55       || strcmp (buf, "1.5 33") != 0)
56     result |= 8;
57   return result;
58 }]])],
59         [gl_cv_func_printf_sizes_c99=yes],
60         [gl_cv_func_printf_sizes_c99=no],
61         [
62          case "$host_os" in
63 changequote(,)dnl
64                                  # Guess yes on glibc systems.
65            *-gnu* | gnu*)        gl_cv_func_printf_sizes_c99="guessing yes";;
66                                  # Guess yes on musl systems.
67            *-musl* | midipix*)   gl_cv_func_printf_sizes_c99="guessing yes";;
68                                  # Guess yes on FreeBSD >= 5.
69            freebsd[1-4].*)       gl_cv_func_printf_sizes_c99="guessing no";;
70            freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";;
71            midnightbsd*)         gl_cv_func_printf_sizes_c99="guessing yes";;
72                                  # Guess yes on Mac OS X >= 10.3.
73            darwin[1-6].*)        gl_cv_func_printf_sizes_c99="guessing no";;
74            darwin*)              gl_cv_func_printf_sizes_c99="guessing yes";;
75                                  # Guess yes on OpenBSD >= 3.9.
76            openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
77                                  gl_cv_func_printf_sizes_c99="guessing no";;
78            openbsd*)             gl_cv_func_printf_sizes_c99="guessing yes";;
79                                  # Guess yes on Solaris >= 2.10.
80            solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";;
81            solaris*)             gl_cv_func_printf_sizes_c99="guessing no";;
82                                  # Guess yes on NetBSD >= 3.
83            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
84                                  gl_cv_func_printf_sizes_c99="guessing no";;
85            netbsd*)              gl_cv_func_printf_sizes_c99="guessing yes";;
86                                  # Guess yes on Android.
87            linux*-android*)      gl_cv_func_printf_sizes_c99="guessing yes";;
88 changequote([,])dnl
89                                  # Guess yes on MSVC, no on mingw.
90            windows*-msvc*)       gl_cv_func_printf_sizes_c99="guessing yes" ;;
91            mingw* | windows*)    AC_EGREP_CPP([Known], [
92 #ifdef _MSC_VER
93  Known
94 #endif
95                                    ],
96                                    [gl_cv_func_printf_sizes_c99="guessing yes"],
97                                    [gl_cv_func_printf_sizes_c99="guessing no"])
98                                  ;;
99                                  # If we don't know, obey --enable-cross-guesses.
100            *)                    gl_cv_func_printf_sizes_c99="$gl_cross_guess_normal";;
101          esac
102         ])
103     ])
106 dnl Test whether the *printf family of functions supports the 'w8', 'w16',
107 dnl 'w32', 'w64', 'wf8', 'wf16', 'wf32', 'wf64' size specifiers. (ISO C23)
108 dnl Result is gl_cv_func_printf_sizes_c23.
110 AC_DEFUN([gl_PRINTF_SIZES_C23],
112   AC_REQUIRE([AC_PROG_CC])
113   AC_REQUIRE([gl_AC_HEADER_STDINT_H])
114   AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
115   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
116   AC_CACHE_CHECK([whether printf supports size specifiers as in C23],
117     [gl_cv_func_printf_sizes_c23],
118     [
119       AC_RUN_IFELSE(
120         [AC_LANG_SOURCE([[
121 #include <stddef.h>
122 #include <stdio.h>
123 #include <string.h>
124 #include <sys/types.h>
125 #if HAVE_STDINT_H_WITH_UINTMAX
126 # include <stdint.h>
127 #endif
128 #if HAVE_INTTYPES_H_WITH_UINTMAX
129 # include <inttypes.h>
130 #endif
131 static char buf[100];
132 int main ()
134   int result = 0;
135   buf[0] = '\0';
136   if (sprintf (buf, "%w8u %d", (uint8_t) 123, 33, 44, 55) < 0
137       || strcmp (buf, "123 33") != 0)
138     result |= 1;
139   buf[0] = '\0';
140   if (sprintf (buf, "%wf8u %d", (uint_fast8_t) 123, 33, 44, 55) < 0
141       || strcmp (buf, "123 33") != 0)
142     result |= 1;
143   buf[0] = '\0';
144   if (sprintf (buf, "%w16u %d", (uint16_t) 12345, 33, 44, 55) < 0
145       || strcmp (buf, "12345 33") != 0)
146     result |= 2;
147   buf[0] = '\0';
148   if (sprintf (buf, "%wf16u %d", (uint_fast16_t) 12345, 33, 44, 55) < 0
149       || strcmp (buf, "12345 33") != 0)
150     result |= 2;
151   buf[0] = '\0';
152   if (sprintf (buf, "%w32u %d", (uint32_t) 12345671, 33, 44, 55) < 0
153       || strcmp (buf, "12345671 33") != 0)
154     result |= 4;
155   buf[0] = '\0';
156   if (sprintf (buf, "%wf32u %d", (uint_fast32_t) 12345671, 33, 44, 55) < 0
157       || strcmp (buf, "12345671 33") != 0)
158     result |= 4;
159 #if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX
160   buf[0] = '\0';
161   if (sprintf (buf, "%w64u %d", (uint64_t) 12345671, 33, 44, 55) < 0
162       || strcmp (buf, "12345671 33") != 0)
163     result |= 8;
164   buf[0] = '\0';
165   if (sprintf (buf, "%wf64u %d", (uint_fast64_t) 12345671, 33, 44, 55) < 0
166       || strcmp (buf, "12345671 33") != 0)
167     result |= 8;
168 #else
169   result |= 8;
170 #endif
171   return result;
172 }]])],
173         [gl_cv_func_printf_sizes_c23=yes],
174         [gl_cv_func_printf_sizes_c23=no],
175         [
176          case "$host_os" in
177                                # Guess no on glibc systems.
178            *-gnu* | gnu*)      gl_cv_func_printf_sizes_c23="guessing no";;
179                                # Guess no on musl systems.
180            *-musl* | midipix*) gl_cv_func_printf_sizes_c23="guessing no";;
181                                # Guess no on Android.
182            linux*-android*)    gl_cv_func_printf_sizes_c23="guessing no";;
183                                # Guess no on native Windows.
184            mingw* | windows*)  gl_cv_func_printf_sizes_c23="guessing no";;
185                                # If we don't know, obey --enable-cross-guesses.
186            *)                  gl_cv_func_printf_sizes_c23="$gl_cross_guess_normal";;
187          esac
188         ])
189     ])
192 dnl Test whether the *printf family of functions supports 'long double'
193 dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
194 dnl Result is gl_cv_func_printf_long_double.
196 AC_DEFUN([gl_PRINTF_LONG_DOUBLE],
198   AC_REQUIRE([AC_PROG_CC])
199   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
200   AC_CACHE_CHECK([whether printf supports 'long double' arguments],
201     [gl_cv_func_printf_long_double],
202     [
203       AC_RUN_IFELSE(
204         [AC_LANG_SOURCE([[
205 #include <stdio.h>
206 #include <string.h>
207 static char buf[10000];
208 int main ()
210   int result = 0;
211   buf[0] = '\0';
212   if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0
213       || strcmp (buf, "1.750000 33") != 0)
214     result |= 1;
215   buf[0] = '\0';
216   if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0
217       || strcmp (buf, "1.750000e+00 33") != 0)
218     result |= 2;
219   buf[0] = '\0';
220   if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0
221       || strcmp (buf, "1.75 33") != 0)
222     result |= 4;
223   return result;
224 }]])],
225         [gl_cv_func_printf_long_double=yes],
226         [gl_cv_func_printf_long_double=no],
227         [case "$host_os" in
228                               # Guess no on BeOS.
229            beos*)             gl_cv_func_printf_long_double="guessing no";;
230                               # Guess yes on Android.
231            linux*-android*)   gl_cv_func_printf_long_double="guessing yes";;
232                               # Guess yes on MSVC, no on mingw.
233            windows*-msvc*)    gl_cv_func_printf_long_double="guessing yes" ;;
234            mingw* | windows*) AC_EGREP_CPP([Known], [
235 #ifdef _MSC_VER
236  Known
237 #endif
238                                 ],
239                                 [gl_cv_func_printf_long_double="guessing yes"],
240                                 [gl_cv_func_printf_long_double="guessing no"])
241                               ;;
242            *)                 gl_cv_func_printf_long_double="guessing yes";;
243          esac
244         ])
245     ])
248 dnl Test whether the *printf family of functions supports infinite and NaN
249 dnl 'double' arguments and negative zero arguments in the %f, %e, %g
250 dnl directives. (ISO C99, POSIX:2001)
251 dnl Result is gl_cv_func_printf_infinite.
253 AC_DEFUN([gl_PRINTF_INFINITE],
255   AC_REQUIRE([AC_PROG_CC])
256   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
257   AC_CACHE_CHECK([whether printf supports infinite 'double' arguments],
258     [gl_cv_func_printf_infinite],
259     [
260       AC_RUN_IFELSE(
261         [AC_LANG_SOURCE([[
262 #include <stdio.h>
263 #include <string.h>
264 static int
265 strisnan (const char *string, size_t start_index, size_t end_index)
267   if (start_index < end_index)
268     {
269       if (string[start_index] == '-')
270         start_index++;
271       if (start_index + 3 <= end_index
272           && memcmp (string + start_index, "nan", 3) == 0)
273         {
274           start_index += 3;
275           if (start_index == end_index
276               || (string[start_index] == '(' && string[end_index - 1] == ')'))
277             return 1;
278         }
279     }
280   return 0;
282 static int
283 have_minus_zero ()
285   static double plus_zero = 0.0;
286   double minus_zero = - plus_zero;
287   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
289 static char buf[10000];
290 static double zero = 0.0;
291 int main ()
293   int result = 0;
294   if (sprintf (buf, "%f", 1.0 / zero) < 0
295       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
296     result |= 1;
297   if (sprintf (buf, "%f", -1.0 / zero) < 0
298       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
299     result |= 1;
300   if (sprintf (buf, "%f", zero / zero) < 0
301       || !strisnan (buf, 0, strlen (buf)))
302     result |= 2;
303   if (sprintf (buf, "%e", 1.0 / zero) < 0
304       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
305     result |= 4;
306   if (sprintf (buf, "%e", -1.0 / zero) < 0
307       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
308     result |= 4;
309   if (sprintf (buf, "%e", zero / zero) < 0
310       || !strisnan (buf, 0, strlen (buf)))
311     result |= 8;
312   if (sprintf (buf, "%g", 1.0 / zero) < 0
313       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
314     result |= 16;
315   if (sprintf (buf, "%g", -1.0 / zero) < 0
316       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
317     result |= 16;
318   if (sprintf (buf, "%g", zero / zero) < 0
319       || !strisnan (buf, 0, strlen (buf)))
320     result |= 32;
321   /* This test fails on HP-UX 10.20.  */
322   if (have_minus_zero ())
323     if (sprintf (buf, "%g", - zero) < 0
324         || strcmp (buf, "-0") != 0)
325     result |= 64;
326   return result;
327 }]])],
328         [gl_cv_func_printf_infinite=yes],
329         [gl_cv_func_printf_infinite=no],
330         [
331          case "$host_os" in
332 changequote(,)dnl
333                                  # Guess yes on glibc systems.
334            *-gnu* | gnu*)        gl_cv_func_printf_infinite="guessing yes";;
335                                  # Guess yes on musl systems.
336            *-musl* | midipix*)   gl_cv_func_printf_infinite="guessing yes";;
337                                  # Guess yes on FreeBSD >= 6.
338            freebsd[1-5].*)       gl_cv_func_printf_infinite="guessing no";;
339            freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";;
340            midnightbsd*)         gl_cv_func_printf_infinite="guessing yes";;
341                                  # Guess yes on Mac OS X >= 10.3.
342            darwin[1-6].*)        gl_cv_func_printf_infinite="guessing no";;
343            darwin*)              gl_cv_func_printf_infinite="guessing yes";;
344                                  # Guess yes on HP-UX >= 11.
345            hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
346            hpux*)                gl_cv_func_printf_infinite="guessing yes";;
347                                  # Guess yes on NetBSD >= 3.
348            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
349                                  gl_cv_func_printf_infinite="guessing no";;
350            netbsd*)              gl_cv_func_printf_infinite="guessing yes";;
351                                  # Guess yes on OpenBSD >= 6.0.
352            openbsd[1-5].*)       gl_cv_func_printf_infinite="guessing no";;
353            openbsd*)             gl_cv_func_printf_infinite="guessing yes";;
354                                  # Guess yes on BeOS.
355            beos*)                gl_cv_func_printf_infinite="guessing yes";;
356                                  # Guess no on Android.
357            linux*-android*)      gl_cv_func_printf_infinite="guessing no";;
358 changequote([,])dnl
359                                  # Guess yes on MSVC, no on mingw.
360            windows*-msvc*)       gl_cv_func_printf_infinite="guessing yes" ;;
361            mingw* | windows*)    AC_EGREP_CPP([Known], [
362 #ifdef _MSC_VER
363  Known
364 #endif
365                                    ],
366                                    [gl_cv_func_printf_infinite="guessing yes"],
367                                    [gl_cv_func_printf_infinite="guessing no"])
368                                  ;;
369                                  # If we don't know, obey --enable-cross-guesses.
370            *)                    gl_cv_func_printf_infinite="$gl_cross_guess_normal";;
371          esac
372         ])
373     ])
376 dnl Test whether the *printf family of functions supports infinite and NaN
377 dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
378 dnl Result is gl_cv_func_printf_infinite_long_double.
380 AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
382   AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
383   AC_REQUIRE([AC_PROG_CC])
384   AC_REQUIRE([gl_BIGENDIAN])
385   AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
386   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
387   dnl The user can set or unset the variable gl_printf_safe to indicate
388   dnl that he wishes a safe handling of non-IEEE-754 'long double' values.
389   if test -n "$gl_printf_safe"; then
390     AC_DEFINE([CHECK_PRINTF_SAFE], [1],
391       [Define if you wish *printf() functions that have a safe handling of
392        non-IEEE-754 'long double' values.])
393   fi
394   case "$gl_cv_func_printf_long_double" in
395     *yes)
396       AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments],
397         [gl_cv_func_printf_infinite_long_double],
398         [
399           AC_RUN_IFELSE(
400             [AC_LANG_SOURCE([[
401 ]GL_NOCRASH[
402 #include <float.h>
403 #include <stdio.h>
404 #include <string.h>
405 static int
406 strisnan (const char *string, size_t start_index, size_t end_index)
408   if (start_index < end_index)
409     {
410       if (string[start_index] == '-')
411         start_index++;
412       if (start_index + 3 <= end_index
413           && memcmp (string + start_index, "nan", 3) == 0)
414         {
415           start_index += 3;
416           if (start_index == end_index
417               || (string[start_index] == '(' && string[end_index - 1] == ')'))
418             return 1;
419         }
420     }
421   return 0;
423 static char buf[10000];
424 static long double zeroL = 0.0L;
425 int main ()
427   int result = 0;
428   nocrash_init();
429   if (sprintf (buf, "%Lf", 1.0L / zeroL) < 0
430       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
431     result |= 1;
432   if (sprintf (buf, "%Lf", -1.0L / zeroL) < 0
433       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
434     result |= 1;
435   if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
436       || !strisnan (buf, 0, strlen (buf)))
437     result |= 1;
438   if (sprintf (buf, "%Le", 1.0L / zeroL) < 0
439       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
440     result |= 1;
441   if (sprintf (buf, "%Le", -1.0L / zeroL) < 0
442       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
443     result |= 1;
444   if (sprintf (buf, "%Le", zeroL / zeroL) < 0
445       || !strisnan (buf, 0, strlen (buf)))
446     result |= 1;
447   if (sprintf (buf, "%Lg", 1.0L / zeroL) < 0
448       || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
449     result |= 1;
450   if (sprintf (buf, "%Lg", -1.0L / zeroL) < 0
451       || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
452     result |= 1;
453   if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
454       || !strisnan (buf, 0, strlen (buf)))
455     result |= 1;
456 #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
457 /* Representation of an 80-bit 'long double' as an initializer for a sequence
458    of 'unsigned int' words.  */
459 # ifdef WORDS_BIGENDIAN
460 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
461      { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
462        ((unsigned int) (manthi) << 16) | ((unsigned int) (mantlo) >> 16),   \
463        (unsigned int) (mantlo) << 16                                        \
464      }
465 # else
466 #  define LDBL80_WORDS(exponent,manthi,mantlo) \
467      { mantlo, manthi, exponent }
468 # endif
469   { /* Quiet NaN.  */
470     static union { unsigned int word[4]; long double value; } x =
471       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
472     if (sprintf (buf, "%Lf", x.value) < 0
473         || !strisnan (buf, 0, strlen (buf)))
474       result |= 2;
475     if (sprintf (buf, "%Le", x.value) < 0
476         || !strisnan (buf, 0, strlen (buf)))
477       result |= 2;
478     if (sprintf (buf, "%Lg", x.value) < 0
479         || !strisnan (buf, 0, strlen (buf)))
480       result |= 2;
481   }
482   {
483     /* Signalling NaN.  */
484     static union { unsigned int word[4]; long double value; } x =
485       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
486     if (sprintf (buf, "%Lf", x.value) < 0
487         || !strisnan (buf, 0, strlen (buf)))
488       result |= 2;
489     if (sprintf (buf, "%Le", x.value) < 0
490         || !strisnan (buf, 0, strlen (buf)))
491       result |= 2;
492     if (sprintf (buf, "%Lg", x.value) < 0
493         || !strisnan (buf, 0, strlen (buf)))
494       result |= 2;
495   }
496   { /* Pseudo-NaN.  */
497     static union { unsigned int word[4]; long double value; } x =
498       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
499     if (sprintf (buf, "%Lf", x.value) <= 0)
500       result |= 4;
501     if (sprintf (buf, "%Le", x.value) <= 0)
502       result |= 4;
503     if (sprintf (buf, "%Lg", x.value) <= 0)
504       result |= 4;
505   }
506   { /* Pseudo-Infinity.  */
507     static union { unsigned int word[4]; long double value; } x =
508       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
509     if (sprintf (buf, "%Lf", x.value) <= 0)
510       result |= 8;
511     if (sprintf (buf, "%Le", x.value) <= 0)
512       result |= 8;
513     if (sprintf (buf, "%Lg", x.value) <= 0)
514       result |= 8;
515   }
516   { /* Pseudo-Zero.  */
517     static union { unsigned int word[4]; long double value; } x =
518       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
519     if (sprintf (buf, "%Lf", x.value) <= 0)
520       result |= 16;
521     if (sprintf (buf, "%Le", x.value) <= 0)
522       result |= 16;
523     if (sprintf (buf, "%Lg", x.value) <= 0)
524       result |= 16;
525   }
526   { /* Unnormalized number.  */
527     static union { unsigned int word[4]; long double value; } x =
528       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
529     if (sprintf (buf, "%Lf", x.value) <= 0)
530       result |= 32;
531     if (sprintf (buf, "%Le", x.value) <= 0)
532       result |= 32;
533     if (sprintf (buf, "%Lg", x.value) <= 0)
534       result |= 32;
535   }
536   { /* Pseudo-Denormal.  */
537     static union { unsigned int word[4]; long double value; } x =
538       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
539     if (sprintf (buf, "%Lf", x.value) <= 0)
540       result |= 64;
541     if (sprintf (buf, "%Le", x.value) <= 0)
542       result |= 64;
543     if (sprintf (buf, "%Lg", x.value) <= 0)
544       result |= 64;
545   }
546 #endif
547   return result;
548 }]])],
549             [gl_cv_func_printf_infinite_long_double=yes],
550             [gl_cv_func_printf_infinite_long_double=no],
551             [case "$host_cpu" in
552                                      # Guess no on ia64, x86_64, i386.
553                ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";;
554                *)
555                  case "$host_os" in
556 changequote(,)dnl
557                                          # Guess yes on glibc systems.
558                    *-gnu* | gnu*)        gl_cv_func_printf_infinite_long_double="guessing yes";;
559                                          # Guess yes on musl systems.
560                    *-musl* | midipix*)   gl_cv_func_printf_infinite_long_double="guessing yes";;
561                                          # Guess yes on FreeBSD >= 6.
562                    freebsd[1-5].*)       gl_cv_func_printf_infinite_long_double="guessing no";;
563                    freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";;
564                    midnightbsd*)         gl_cv_func_printf_infinite_long_double="guessing yes";;
565                                          # Guess yes on HP-UX >= 11.
566                    hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";;
567                    hpux*)                gl_cv_func_printf_infinite_long_double="guessing yes";;
568                                          # Guess yes on OpenBSD >= 6.0.
569                    openbsd[1-5].*)       gl_cv_func_printf_infinite_long_double="guessing no";;
570                    openbsd*)             gl_cv_func_printf_infinite_long_double="guessing yes";;
571                                          # Guess no on Android.
572                    linux*-android*)      gl_cv_func_printf_infinite_long_double="guessing no";;
573 changequote([,])dnl
574                                          # Guess yes on MSVC, no on mingw.
575                    windows*-msvc*)       gl_cv_func_printf_infinite_long_double="guessing yes" ;;
576                    mingw* | windows*)    AC_EGREP_CPP([Known], [
577 #ifdef _MSC_VER
578  Known
579 #endif
580                                            ],
581                                            [gl_cv_func_printf_infinite_long_double="guessing yes"],
582                                            [gl_cv_func_printf_infinite_long_double="guessing no"])
583                                          ;;
584                                          # If we don't know, obey --enable-cross-guesses.
585                    *)                    gl_cv_func_printf_infinite_long_double="$gl_cross_guess_normal";;
586                  esac
587                  ;;
588              esac
589             ])
590         ])
591       ;;
592     *)
593       gl_cv_func_printf_infinite_long_double="irrelevant"
594       ;;
595   esac
598 dnl Test whether the *printf family of functions supports the 'a' and 'A'
599 dnl conversion specifier for hexadecimal output of floating-point numbers.
600 dnl (ISO C99, POSIX:2001)
601 dnl Result is gl_cv_func_printf_directive_a.
603 AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
605   AC_REQUIRE([AC_PROG_CC])
606   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
607   AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
608     [gl_cv_func_printf_directive_a],
609     [
610       AC_RUN_IFELSE(
611         [AC_LANG_SOURCE([[
612 #include <stdio.h>
613 #include <string.h>
614 static char buf[100];
615 static double zero = 0.0;
616 int main ()
618   int result = 0;
619   /* This fails on FreeBSD 5.2.1, Solaris 11.4.  */
620   if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
621       || (strcmp (buf, "0x1.922p+1 33") != 0
622           && strcmp (buf, "0x3.244p+0 33") != 0
623           && strcmp (buf, "0x6.488p-1 33") != 0
624           && strcmp (buf, "0xc.91p-2 33") != 0))
625     result |= 1;
626   if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
627       || (strcmp (buf, "-0X1.922P+1 33") != 0
628           && strcmp (buf, "-0X3.244P+0 33") != 0
629           && strcmp (buf, "-0X6.488P-1 33") != 0
630           && strcmp (buf, "-0XC.91P-2 33") != 0))
631     result |= 1;
632   /* This catches a Mac OS X 10.5, FreeBSD 6.4, NetBSD 10.0 bug:
633      it doesn't round.  */
634   if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
635       || (strcmp (buf, "0x1.83p+0 33") != 0
636           && strcmp (buf, "0x3.05p-1 33") != 0
637           && strcmp (buf, "0x6.0ap-2 33") != 0
638           && strcmp (buf, "0xc.14p-3 33") != 0))
639     result |= 2;
640   /* This catches a macOS 14 (Darwin 23), FreeBSD 14.0, OpenBSD 7.5, AIX 7.3,
641      Solaris 11.4 bug: it doesn't round.  */
642   if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0
643       || (strcmp (buf, "0x2p+0 33") != 0
644           && strcmp (buf, "0x3p-1 33") != 0
645           && strcmp (buf, "0x6p-2 33") != 0
646           && strcmp (buf, "0xcp-3 33") != 0))
647     result |= 4;
648   /* This catches a Mac OS X 10.5, FreeBSD 6.4 bug.  See
649      <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
650   if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0
651       || buf[0] == '0')
652     result |= 8;
653   /* This catches a Mac OS X 10.3.9 (Darwin 7.9), FreeBSD 6.4 bug.  */
654   if (sprintf (buf, "%.1a", 1.999) < 0
655       || (strcmp (buf, "0x1.0p+1") != 0
656           && strcmp (buf, "0x2.0p+0") != 0
657           && strcmp (buf, "0x4.0p-1") != 0
658           && strcmp (buf, "0x8.0p-2") != 0))
659     result |= 16;
660   /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a
661      glibc 2.4 bug <https://sourceware.org/bugzilla/show_bug.cgi?id=2908>
662      and a FreeBSD 6.4, NetBSD 10.0 bug.  */
663   if (sprintf (buf, "%.1La", 1.999L) < 0
664       || (strcmp (buf, "0x1.0p+1") != 0
665           && strcmp (buf, "0x2.0p+0") != 0
666           && strcmp (buf, "0x4.0p-1") != 0
667           && strcmp (buf, "0x8.0p-2") != 0))
668     result |= 32;
669   return result;
670 }]])],
671         [gl_cv_func_printf_directive_a=yes],
672         [gl_cv_func_printf_directive_a=no],
673         [
674          case "$host_os" in
675                                  # Guess yes on glibc >= 2.5 systems.
676            *-gnu* | gnu*)
677              AC_EGREP_CPP([BZ2908], [
678                #include <features.h>
679                #ifdef __GNU_LIBRARY__
680                 #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)) && !defined __UCLIBC__
681                  BZ2908
682                 #endif
683                #endif
684                ],
685                [gl_cv_func_printf_directive_a="guessing yes"],
686                [gl_cv_func_printf_directive_a="guessing no"])
687              ;;
688                                  # Guess yes on musl systems.
689            *-musl* | midipix*)   gl_cv_func_printf_directive_a="guessing yes";;
690                                  # Guess no on Android.
691            linux*-android*)      gl_cv_func_printf_directive_a="guessing no";;
692                                  # Guess no on native Windows.
693            mingw* | windows*)    gl_cv_func_printf_directive_a="guessing no";;
694                                  # If we don't know, obey --enable-cross-guesses.
695            *)                    gl_cv_func_printf_directive_a="$gl_cross_guess_normal";;
696          esac
697         ])
698     ])
701 dnl Test whether the *printf family of functions supports the 'b' conversion
702 dnl specifier for binary output of integers.
703 dnl (ISO C23)
704 dnl Result is gl_cv_func_printf_directive_b.
706 AC_DEFUN([gl_PRINTF_DIRECTIVE_B],
708   AC_REQUIRE([AC_PROG_CC])
709   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
710   AC_CACHE_CHECK([whether printf supports the 'b' directive],
711     [gl_cv_func_printf_directive_b],
712     [
713       AC_RUN_IFELSE(
714         [AC_LANG_SOURCE([[
715 #include <stdio.h>
716 #include <string.h>
717 static char buf[100];
718 int main ()
720   int result = 0;
721   if (sprintf (buf, "%b %d", 12345, 33, 44, 55) < 0
722       || strcmp (buf, "11000000111001 33") != 0)
723     result |= 1;
724   return result;
725 }]])],
726         [gl_cv_func_printf_directive_b=yes],
727         [gl_cv_func_printf_directive_b=no],
728         [
729          case "$host_os" in
730                                # Guess yes on glibc >= 2.35 systems.
731            *-gnu* | gnu*)
732              AC_EGREP_CPP([Lucky], [
733                #include <features.h>
734                #ifdef __GNU_LIBRARY__
735                 #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 35) || (__GLIBC__ > 2)
736                  Lucky user
737                 #endif
738                #endif
739                ],
740                [gl_cv_func_printf_directive_uppercase_b="guessing yes"],
741                [gl_cv_func_printf_directive_uppercase_b="guessing no"])
742              ;;
743                                # Guess no on musl systems.
744            *-musl* | midipix*) gl_cv_func_printf_directive_b="guessing no";;
745                                # Guess no on Android.
746            linux*-android*)    gl_cv_func_printf_directive_b="guessing no";;
747                                # Guess no on native Windows.
748            mingw* | windows*)  gl_cv_func_printf_directive_b="guessing no";;
749                                # If we don't know, obey --enable-cross-guesses.
750            *)                  gl_cv_func_printf_directive_b="$gl_cross_guess_normal";;
751          esac
752         ])
753     ])
756 dnl Test whether the *printf family of functions supports the 'B' conversion
757 dnl specifier for binary output of integers.
758 dnl (GNU, encouraged by ISO C23 Â§ 7.23.6.1)
759 dnl Result is gl_cv_func_printf_directive_uppercase_b.
761 AC_DEFUN([gl_PRINTF_DIRECTIVE_UPPERCASE_B],
763   AC_REQUIRE([AC_PROG_CC])
764   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
765   AC_CACHE_CHECK([whether printf supports the 'B' directive],
766     [gl_cv_func_printf_directive_uppercase_b],
767     [
768       AC_RUN_IFELSE(
769         [AC_LANG_SOURCE([[
770 #include <stdio.h>
771 #include <string.h>
772 static char buf[100];
773 int main ()
775   int result = 0;
776   if (sprintf (buf, "%#B %d", 12345, 33, 44, 55) < 0
777       || strcmp (buf, "0B11000000111001 33") != 0)
778     result |= 1;
779   return result;
780 }]])],
781         [gl_cv_func_printf_directive_uppercase_b=yes],
782         [gl_cv_func_printf_directive_uppercase_b=no],
783         [
784          case "$host_os" in
785                                # Guess yes on glibc >= 2.35 systems.
786            *-gnu* | gnu*)
787              AC_EGREP_CPP([Lucky], [
788                #include <features.h>
789                #ifdef __GNU_LIBRARY__
790                 #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 35) || (__GLIBC__ > 2)
791                  Lucky user
792                 #endif
793                #endif
794                ],
795                [gl_cv_func_printf_directive_uppercase_b="guessing yes"],
796                [gl_cv_func_printf_directive_uppercase_b="guessing no"])
797              ;;
798                                # Guess no on musl systems.
799            *-musl* | midipix*) gl_cv_func_printf_directive_uppercase_b="guessing no";;
800                                # Guess no on Android.
801            linux*-android*)    gl_cv_func_printf_directive_uppercase_b="guessing no";;
802                                # Guess no on native Windows.
803            mingw* | windows*)  gl_cv_func_printf_directive_uppercase_b="guessing no";;
804                                # If we don't know, obey --enable-cross-guesses.
805            *)                  gl_cv_func_printf_directive_uppercase_b="$gl_cross_guess_normal";;
806          esac
807         ])
808     ])
811 dnl Test whether the *printf family of functions supports the %F format
812 dnl directive. (ISO C99, POSIX:2001)
813 dnl Result is gl_cv_func_printf_directive_f.
815 AC_DEFUN([gl_PRINTF_DIRECTIVE_F],
817   AC_REQUIRE([AC_PROG_CC])
818   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
819   AC_CACHE_CHECK([whether printf supports the 'F' directive],
820     [gl_cv_func_printf_directive_f],
821     [
822       AC_RUN_IFELSE(
823         [AC_LANG_SOURCE([[
824 #include <stdio.h>
825 #include <string.h>
826 static char buf[100];
827 static double zero = 0.0;
828 int main ()
830   int result = 0;
831   if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
832       || strcmp (buf, "1234567.000000 33") != 0)
833     result |= 1;
834   if (sprintf (buf, "%F", 1.0 / zero) < 0
835       || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
836     result |= 2;
837   /* This catches a Cygwin 1.5.x bug.  */
838   if (sprintf (buf, "%.F", 1234.0) < 0
839       || strcmp (buf, "1234") != 0)
840     result |= 4;
841   return result;
842 }]])],
843         [gl_cv_func_printf_directive_f=yes],
844         [gl_cv_func_printf_directive_f=no],
845         [
846          case "$host_os" in
847 changequote(,)dnl
848                                  # Guess yes on glibc systems.
849            *-gnu* | gnu*)        gl_cv_func_printf_directive_f="guessing yes";;
850                                  # Guess yes on musl systems.
851            *-musl* | midipix*)   gl_cv_func_printf_directive_f="guessing yes";;
852                                  # Guess yes on FreeBSD >= 6.
853            freebsd[1-5].*)       gl_cv_func_printf_directive_f="guessing no";;
854            freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";;
855            midnightbsd*)         gl_cv_func_printf_directive_f="guessing yes";;
856                                  # Guess yes on Mac OS X >= 10.3.
857            darwin[1-6].*)        gl_cv_func_printf_directive_f="guessing no";;
858            darwin*)              gl_cv_func_printf_directive_f="guessing yes";;
859                                  # Guess yes on OpenBSD >= 6.0.
860            openbsd[1-5].*)       gl_cv_func_printf_directive_f="guessing no";;
861            openbsd*)             gl_cv_func_printf_directive_f="guessing yes";;
862                                  # Guess yes on Solaris >= 2.10.
863            solaris2.[1-9][0-9]*) gl_cv_func_printf_directive_f="guessing yes";;
864            solaris*)             gl_cv_func_printf_directive_f="guessing no";;
865                                  # Guess no on Android.
866            linux*-android*)      gl_cv_func_printf_directive_f="guessing no";;
867 changequote([,])dnl
868                                  # Guess yes on MSVC, no on mingw.
869            windows*-msvc*)       gl_cv_func_printf_directive_f="guessing yes" ;;
870            mingw* | windows*)    AC_EGREP_CPP([Known], [
871 #ifdef _MSC_VER
872  Known
873 #endif
874                                    ],
875                                    [gl_cv_func_printf_directive_f="guessing yes"],
876                                    [gl_cv_func_printf_directive_f="guessing no"])
877                                  ;;
878                                  # If we don't know, obey --enable-cross-guesses.
879            *)                    gl_cv_func_printf_directive_f="$gl_cross_guess_normal";;
880          esac
881         ])
882     ])
885 dnl Test whether the *printf family of functions supports the %n format
886 dnl directive. (ISO C99, POSIX:2001)
887 dnl Result is gl_cv_func_printf_directive_n.
889 AC_DEFUN([gl_PRINTF_DIRECTIVE_N],
891   AC_REQUIRE([AC_PROG_CC])
892   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
893   AC_CACHE_CHECK([whether printf supports the 'n' directive],
894     [gl_cv_func_printf_directive_n],
895     [
896       AC_RUN_IFELSE(
897         [AC_LANG_SOURCE([[
898 #include <signal.h>
899 #include <stdio.h>
900 #include <string.h>
901 #if defined _WIN32 && !defined __CYGWIN__
902 # include <stdlib.h>
903 #else
904 # include <unistd.h>
905 #endif
906 #ifdef _MSC_VER
907 #include <crtdbg.h>
908 #include <inttypes.h>
909 /* See page about "Parameter Validation" on msdn.microsoft.com.
910    <https://docs.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation>
911    <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-invalid-parameter-handler-set-thread-local-invalid-parameter-handler>  */
912 static void cdecl
913 invalid_parameter_handler (const wchar_t *expression,
914                            const wchar_t *function,
915                            const wchar_t *file, unsigned int line,
916                            uintptr_t dummy)
918   exit (1);
920 #endif
921 static void
922 abort_handler (int sig)
924   (void) sig;
925   _exit (1);
927 static char fmtstring[10];
928 static char buf[100];
929 int main ()
931   int count = -1;
932 #ifdef _MSC_VER
933   _set_invalid_parameter_handler (invalid_parameter_handler);
934   /* Also avoid an Abort/Retry/Ignore dialog in debug builds.
935      <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/crtsetreportmode>  */
936   _CrtSetReportMode (_CRT_ASSERT, 0);
937 #endif
938   signal (SIGABRT, abort_handler);
939   /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
940      support %n in format strings in read-only memory but not in writable
941      memory.  */
942   strcpy (fmtstring, "%d %n");
943   if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0
944       || strcmp (buf, "123 ") != 0
945       || count != 4)
946     return 1;
947   return 0;
948 }]])],
949         [gl_cv_func_printf_directive_n=yes],
950         [gl_cv_func_printf_directive_n=no],
951         [case "$host_os" in
952                               # Guess no on glibc when _FORTIFY_SOURCE >= 2.
953            *-gnu* | gnu*)     AC_COMPILE_IFELSE(
954                                 [AC_LANG_SOURCE(
955                                    [[#if _FORTIFY_SOURCE >= 2
956                                       error fail
957                                      #endif
958                                    ]])],
959                                 [gl_cv_func_printf_directive_n="guessing yes"],
960                                 [gl_cv_func_printf_directive_n="guessing no"])
961                               ;;
962                               # Guess no on Android.
963            linux*-android*)   gl_cv_func_printf_directive_n="guessing no";;
964                               # Guess no on native Windows.
965            mingw* | windows*) gl_cv_func_printf_directive_n="guessing no";;
966            *)                 gl_cv_func_printf_directive_n="guessing yes";;
967          esac
968         ])
969     ])
972 dnl Test whether the *printf family of functions supports the %ls format
973 dnl directive and in particular, when a precision is specified, whether
974 dnl the functions stop converting the wide string argument when the number
975 dnl of bytes that have been produced by this conversion equals or exceeds
976 dnl the precision.
977 dnl Result is gl_cv_func_printf_directive_ls.
979 AC_DEFUN([gl_PRINTF_DIRECTIVE_LS],
981   AC_REQUIRE([AC_PROG_CC])
982   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
983   AC_CACHE_CHECK([whether printf supports the 'ls' directive],
984     [gl_cv_func_printf_directive_ls],
985     [
986       AC_RUN_IFELSE(
987         [AC_LANG_SOURCE([[
988 #include <stdio.h>
989 #include <wchar.h>
990 #include <string.h>
991 int main ()
993   int result = 0;
994   char buf[100];
995   /* Test whether %ls works at all.
996      This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
997      Cygwin 1.5.  */
998   {
999     static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
1000     buf[0] = '\0';
1001     if (sprintf (buf, "%ls", wstring) < 0
1002         || strcmp (buf, "abc") != 0)
1003       result |= 1;
1004   }
1005   /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
1006      assertion failure inside libc), but not on OpenBSD 4.0.  */
1007   {
1008     static const wchar_t wstring[] = { 'a', 0 };
1009     buf[0] = '\0';
1010     if (sprintf (buf, "%ls", wstring) < 0
1011         || strcmp (buf, "a") != 0)
1012       result |= 2;
1013   }
1014   /* Test whether precisions in %ls are supported as specified in ISO C 99
1015      section 7.19.6.1:
1016        "If a precision is specified, no more than that many bytes are written
1017         (including shift sequences, if any), and the array shall contain a
1018         null wide character if, to equal the multibyte character sequence
1019         length given by the precision, the function would need to access a
1020         wide character one past the end of the array."
1021      This test fails on Solaris 10.  */
1022   {
1023     static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 };
1024     buf[0] = '\0';
1025     if (sprintf (buf, "%.2ls", wstring) < 0
1026         || strcmp (buf, "ab") != 0)
1027       result |= 8;
1028   }
1029   return result;
1030 }]])],
1031         [gl_cv_func_printf_directive_ls=yes],
1032         [gl_cv_func_printf_directive_ls=no],
1033         [
1034 changequote(,)dnl
1035          case "$host_os" in
1036                               # Guess yes on OpenBSD >= 6.0.
1037            openbsd[1-5].*)    gl_cv_func_printf_directive_ls="guessing no";;
1038            openbsd*)          gl_cv_func_printf_directive_ls="guessing yes";;
1039            irix*)             gl_cv_func_printf_directive_ls="guessing no";;
1040            solaris*)          gl_cv_func_printf_directive_ls="guessing no";;
1041            cygwin*)           gl_cv_func_printf_directive_ls="guessing no";;
1042            beos* | haiku*)    gl_cv_func_printf_directive_ls="guessing no";;
1043                               # Guess no on Android.
1044            linux*-android*)   gl_cv_func_printf_directive_ls="guessing no";;
1045                               # Guess yes on native Windows.
1046            mingw* | windows*) gl_cv_func_printf_directive_ls="guessing yes";;
1047            *)                 gl_cv_func_printf_directive_ls="guessing yes";;
1048          esac
1049 changequote([,])dnl
1050         ])
1051     ])
1054 dnl Test whether the *printf family of functions supports the %lc format
1055 dnl directive and in particular, when the argument is a null wide character,
1056 dnl whether the functions produce a NUL byte, as specified in ISO C 23
1057 dnl after the issue GB-141 was fixed.
1058 dnl Result is gl_cv_func_printf_directive_lc.
1060 AC_DEFUN([gl_PRINTF_DIRECTIVE_LC],
1062   AC_REQUIRE([AC_PROG_CC])
1063   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1064   AC_CACHE_CHECK([whether printf supports the 'lc' directive correctly],
1065     [gl_cv_func_printf_directive_lc],
1066     [
1067       AC_RUN_IFELSE(
1068         [AC_LANG_SOURCE([[
1069 #include <stdio.h>
1070 #include <wchar.h>
1071 #include <string.h>
1072 int main ()
1074   int result = 0;
1075   char buf[100];
1076   /* This test fails on musl libc 1.2.4.  */
1077   {
1078     buf[0] = '\0';
1079     if (sprintf (buf, "%lc%lc%lc", (wint_t) 'a', (wint_t) 0, (wint_t) 'z') < 0
1080         || memcmp (buf, "a\0z", 4) != 0)
1081       result |= 1;
1082   }
1083   return result;
1084 }]])],
1085         [gl_cv_func_printf_directive_lc=yes],
1086         [gl_cv_func_printf_directive_lc=no],
1087         [
1088 changequote(,)dnl
1089          case "$host_os" in
1090                                # Guess no on musl libc.
1091            *-musl* | midipix*) gl_cv_func_printf_directive_lc="guessing no";;
1092                                # Guess yes otherwise.
1093            *)                  gl_cv_func_printf_directive_lc="guessing yes";;
1094          esac
1095 changequote([,])dnl
1096         ])
1097     ])
1100 dnl Test whether the *printf family of functions supports POSIX/XSI format
1101 dnl strings with positions. (POSIX:2001)
1102 dnl Result is gl_cv_func_printf_positions.
1104 AC_DEFUN_ONCE([gl_PRINTF_POSITIONS],
1106   AC_REQUIRE([AC_PROG_CC])
1107   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1108   AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions],
1109     [gl_cv_func_printf_positions],
1110     [
1111       AC_RUN_IFELSE(
1112         [AC_LANG_SOURCE([[
1113 #include <stdio.h>
1114 #include <string.h>
1115 /* The string "%2$d %1$d", with dollar characters protected from the shell's
1116    dollar expansion (possibly an autoconf bug).  */
1117 static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
1118 static char buf[100];
1119 int main ()
1121   sprintf (buf, format, 33, 55);
1122   return (strcmp (buf, "55 33") != 0);
1123 }]])],
1124         [gl_cv_func_printf_positions=yes],
1125         [gl_cv_func_printf_positions=no],
1126         [
1127 changequote(,)dnl
1128          case "$host_os" in
1129            netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*)
1130              gl_cv_func_printf_positions="guessing no";;
1131            beos*)
1132              gl_cv_func_printf_positions="guessing no";;
1133              # Guess yes on Android.
1134            linux*-android*)
1135              gl_cv_func_printf_positions="guessing yes";;
1136              # Guess no on native Windows.
1137            mingw* | windows* | pw*)
1138              gl_cv_func_printf_positions="guessing no";;
1139            *)
1140              gl_cv_func_printf_positions="guessing yes";;
1141          esac
1142 changequote([,])dnl
1143         ])
1144     ])
1147 dnl Test whether the *printf family of functions supports POSIX/XSI format
1148 dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001)
1149 dnl Result is gl_cv_func_printf_flag_grouping.
1151 AC_DEFUN([gl_PRINTF_FLAG_GROUPING],
1153   AC_REQUIRE([AC_PROG_CC])
1154   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1155   AC_CACHE_CHECK([whether printf supports the grouping flag],
1156     [gl_cv_func_printf_flag_grouping],
1157     [
1158       AC_RUN_IFELSE(
1159         [AC_LANG_SOURCE([[
1160 #include <stdio.h>
1161 #include <string.h>
1162 static char buf[100];
1163 int main ()
1165   if (sprintf (buf, "%'d %d", 1234567, 99) < 0
1166       || buf[strlen (buf) - 1] != '9')
1167     return 1;
1168   return 0;
1169 }]])],
1170         [gl_cv_func_printf_flag_grouping=yes],
1171         [gl_cv_func_printf_flag_grouping=no],
1172         [
1173 changequote(,)dnl
1174          case "$host_os" in
1175            cygwin*)                 gl_cv_func_printf_flag_grouping="guessing no";;
1176            netbsd*)                 gl_cv_func_printf_flag_grouping="guessing no";;
1177                                     # Guess no on Android.
1178            linux*-android*)         gl_cv_func_printf_flag_grouping="guessing no";;
1179                                     # Guess no on native Windows.
1180            mingw* | windows* | pw*) gl_cv_func_printf_flag_grouping="guessing no";;
1181            *)                       gl_cv_func_printf_flag_grouping="guessing yes";;
1182          esac
1183 changequote([,])dnl
1184         ])
1185     ])
1188 dnl Test whether the *printf family of functions supports the - flag correctly.
1189 dnl (ISO C99.) See
1190 dnl <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html>
1191 dnl Result is gl_cv_func_printf_flag_leftadjust.
1193 AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST],
1195   AC_REQUIRE([AC_PROG_CC])
1196   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1197   AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly],
1198     [gl_cv_func_printf_flag_leftadjust],
1199     [
1200       AC_RUN_IFELSE(
1201         [AC_LANG_SOURCE([[
1202 #include <stdio.h>
1203 #include <string.h>
1204 static char buf[100];
1205 int main ()
1207   /* Check that a '-' flag is not annihilated by a negative width.  */
1208   if (sprintf (buf, "a%-*sc", -3, "b") < 0
1209       || strcmp (buf, "ab  c") != 0)
1210     return 1;
1211   return 0;
1212 }]])],
1213         [gl_cv_func_printf_flag_leftadjust=yes],
1214         [gl_cv_func_printf_flag_leftadjust=no],
1215         [
1216 changequote(,)dnl
1217          case "$host_os" in
1218                               # Guess yes on HP-UX 11.
1219            hpux11*)           gl_cv_func_printf_flag_leftadjust="guessing yes";;
1220                               # Guess no on HP-UX 10 and older.
1221            hpux*)             gl_cv_func_printf_flag_leftadjust="guessing no";;
1222                               # Guess yes on Android.
1223            linux*-android*)   gl_cv_func_printf_flag_leftadjust="guessing yes";;
1224                               # Guess yes on native Windows.
1225            mingw* | windows*) gl_cv_func_printf_flag_leftadjust="guessing yes";;
1226                               # Guess yes otherwise.
1227            *)                 gl_cv_func_printf_flag_leftadjust="guessing yes";;
1228          esac
1229 changequote([,])dnl
1230         ])
1231     ])
1234 dnl Test whether the *printf family of functions supports padding of non-finite
1235 dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
1236 dnl <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html>
1237 dnl Result is gl_cv_func_printf_flag_zero.
1239 AC_DEFUN([gl_PRINTF_FLAG_ZERO],
1241   AC_REQUIRE([AC_PROG_CC])
1242   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1243   AC_CACHE_CHECK([whether printf supports the zero flag correctly],
1244     [gl_cv_func_printf_flag_zero],
1245     [
1246       AC_RUN_IFELSE(
1247         [AC_LANG_SOURCE([[
1248 #include <stdio.h>
1249 #include <string.h>
1250 static char buf[100];
1251 static double zero = 0.0;
1252 int main ()
1254   if (sprintf (buf, "%010f", 1.0 / zero, 33, 44, 55) < 0
1255       || (strcmp (buf, "       inf") != 0
1256           && strcmp (buf, "  infinity") != 0))
1257     return 1;
1258   return 0;
1259 }]])],
1260         [gl_cv_func_printf_flag_zero=yes],
1261         [gl_cv_func_printf_flag_zero=no],
1262         [
1263 changequote(,)dnl
1264          case "$host_os" in
1265                                # Guess yes on glibc systems.
1266            *-gnu* | gnu*)      gl_cv_func_printf_flag_zero="guessing yes";;
1267                                # Guess yes on musl systems.
1268            *-musl* | midipix*) gl_cv_func_printf_flag_zero="guessing yes";;
1269                                # Guess yes on BeOS.
1270            beos*)              gl_cv_func_printf_flag_zero="guessing yes";;
1271                                # Guess no on Android.
1272            linux*-android*)    gl_cv_func_printf_flag_zero="guessing no";;
1273                                # Guess no on native Windows.
1274            mingw* | windows*)  gl_cv_func_printf_flag_zero="guessing no";;
1275                                # If we don't know, obey --enable-cross-guesses.
1276            *)                  gl_cv_func_printf_flag_zero="$gl_cross_guess_normal";;
1277          esac
1278 changequote([,])dnl
1279         ])
1280     ])
1283 dnl Test whether the *printf family of functions supports the # flag with a
1284 dnl zero precision and a zero value in the 'x' and 'X' directives correctly.
1285 dnl ISO C and POSIX specify that for the 'd', 'i', 'b', 'o', 'u', 'x', 'X'
1286 dnl directives: "The result of converting a zero value with a precision of
1287 dnl zero is no characters."  But on Mac OS X 10.5, for the 'x', 'X' directives,
1288 dnl when a # flag is present, the output is "0" instead of "".
1289 dnl Result is gl_cv_func_printf_flag_alt_precision_zero.
1291 AC_DEFUN([gl_PRINTF_FLAG_ALT_PRECISION_ZERO],
1293   AC_REQUIRE([AC_PROG_CC])
1294   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1295   AC_CACHE_CHECK([whether printf supports the alternative flag with a zero precision],
1296     [gl_cv_func_printf_flag_alt_precision_zero],
1297     [
1298       AC_RUN_IFELSE(
1299         [AC_LANG_SOURCE([[
1300 #include <stdio.h>
1301 static char buf[10];
1302 int main ()
1304   int result = 0;
1305   if (sprintf (buf, "%#.0x %d", 0, 33, 44) > 0 + 3)
1306     result |= 1;
1307   return result;
1308 }]])],
1309         [gl_cv_func_printf_flag_alt_precision_zero=yes],
1310         [gl_cv_func_printf_flag_alt_precision_zero=no],
1311         [
1312 changequote(,)dnl
1313          case "$host_os" in
1314            # Guess no only on macOS 10..12 systems.
1315            darwin[0-9] | darwin[0-9].* | \
1316            darwin1[0-9] | darwin1[0-9].* | \
1317            darwin2[0-1] | darwin2[0-1].*)
1318                     gl_cv_func_printf_flag_alt_precision_zero="guessing no" ;;
1319            darwin*) gl_cv_func_printf_flag_alt_precision_zero="guessing yes" ;;
1320            *)       gl_cv_func_printf_flag_alt_precision_zero="guessing yes" ;;
1321          esac
1322 changequote([,])dnl
1323         ])
1324     ])
1327 dnl Test whether the *printf family of functions supports large precisions.
1328 dnl On mingw, precisions larger than 512 are treated like 512, in integer,
1329 dnl floating-point or pointer output. On Solaris 10/x86, precisions larger
1330 dnl than 510 in floating-point output crash the program. On Solaris 10/SPARC,
1331 dnl precisions larger than 510 in floating-point output yield wrong results.
1332 dnl On AIX 7.1, precisions larger than 998 in floating-point output yield
1333 dnl wrong results. On BeOS, precisions larger than 1044 crash the program.
1334 dnl Result is gl_cv_func_printf_precision.
1336 AC_DEFUN([gl_PRINTF_PRECISION],
1338   AC_REQUIRE([AC_PROG_CC])
1339   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1340   AC_CACHE_CHECK([whether printf supports large precisions],
1341     [gl_cv_func_printf_precision],
1342     [
1343       AC_RUN_IFELSE(
1344         [AC_LANG_SOURCE([[
1345 #include <stdio.h>
1346 #include <string.h>
1347 static char buf[5000];
1348 int main ()
1350   int result = 0;
1351 #ifdef __BEOS__
1352   /* On BeOS, this would crash and show a dialog box.  Avoid the crash.  */
1353   return 1;
1354 #endif
1355   if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3)
1356     result |= 1;
1357   if (sprintf (buf, "%.4000f %d", 1.0, 33, 44) < 4000 + 5)
1358     result |= 2;
1359   if (sprintf (buf, "%.511f %d", 1.0, 33, 44) < 511 + 5
1360       || buf[0] != '1')
1361     result |= 4;
1362   if (sprintf (buf, "%.999f %d", 1.0, 33, 44) < 999 + 5
1363       || buf[0] != '1')
1364     result |= 4;
1365   return result;
1366 }]])],
1367         [gl_cv_func_printf_precision=yes],
1368         [gl_cv_func_printf_precision=no],
1369         [
1370 changequote(,)dnl
1371          case "$host_os" in
1372            # Guess no only on Solaris, native Windows, and BeOS systems.
1373            solaris*)                gl_cv_func_printf_precision="guessing no" ;;
1374            mingw* | windows* | pw*) gl_cv_func_printf_precision="guessing no" ;;
1375            beos*)                   gl_cv_func_printf_precision="guessing no" ;;
1376                                     # Guess yes on Android.
1377            linux*-android*)         gl_cv_func_printf_precision="guessing yes" ;;
1378            *)                       gl_cv_func_printf_precision="guessing yes" ;;
1379          esac
1380 changequote([,])dnl
1381         ])
1382     ])
1385 dnl Test whether the *printf family of functions recovers gracefully in case
1386 dnl of an out-of-memory condition, or whether it crashes the entire program.
1387 dnl Result is gl_cv_func_printf_enomem.
1389 AC_DEFUN([gl_PRINTF_ENOMEM],
1391   AC_REQUIRE([AC_PROG_CC])
1392   AC_REQUIRE([gl_MULTIARCH])
1393   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1394   AC_CACHE_CHECK([whether printf survives out-of-memory conditions],
1395     [gl_cv_func_printf_enomem],
1396     [
1397       gl_cv_func_printf_enomem="guessing no"
1398       if test "$cross_compiling" = no; then
1399         if test $APPLE_UNIVERSAL_BUILD = 0; then
1400           AC_LANG_CONFTEST([AC_LANG_SOURCE([[
1401 ]GL_NOCRASH[
1402 #include <stdio.h>
1403 #include <sys/types.h>
1404 #include <sys/time.h>
1405 #include <sys/resource.h>
1406 #include <errno.h>
1407 int main()
1409   struct rlimit limit;
1410   int ret;
1411   nocrash_init ();
1412   /* Some printf implementations allocate temporary space with malloc.  */
1413   /* On BSD systems, malloc() is limited by RLIMIT_DATA.  */
1414 #ifdef RLIMIT_DATA
1415   if (getrlimit (RLIMIT_DATA, &limit) < 0)
1416     return 77;
1417   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
1418     limit.rlim_max = 5000000;
1419   limit.rlim_cur = limit.rlim_max;
1420   if (setrlimit (RLIMIT_DATA, &limit) < 0)
1421     return 77;
1422 #endif
1423   /* On Linux systems, malloc() is limited by RLIMIT_AS.  */
1424 #ifdef RLIMIT_AS
1425   if (getrlimit (RLIMIT_AS, &limit) < 0)
1426     return 77;
1427   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
1428     limit.rlim_max = 5000000;
1429   limit.rlim_cur = limit.rlim_max;
1430   if (setrlimit (RLIMIT_AS, &limit) < 0)
1431     return 77;
1432 #endif
1433   /* Some printf implementations allocate temporary space on the stack.  */
1434 #ifdef RLIMIT_STACK
1435   if (getrlimit (RLIMIT_STACK, &limit) < 0)
1436     return 77;
1437   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
1438     limit.rlim_max = 5000000;
1439   limit.rlim_cur = limit.rlim_max;
1440   if (setrlimit (RLIMIT_STACK, &limit) < 0)
1441     return 77;
1442 #endif
1443   ret = printf ("%.5000000f", 1.0);
1444   return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
1446           ]])])
1447           if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
1448             (./conftest 2>&AS_MESSAGE_LOG_FD
1449              result=$?
1450              _AS_ECHO_LOG([\$? = $result])
1451              if test $result != 0 && test $result != 77; then result=1; fi
1452              exit $result
1453             ) >/dev/null 2>/dev/null
1454             case $? in
1455               0) gl_cv_func_printf_enomem="yes" ;;
1456               77) gl_cv_func_printf_enomem="guessing no" ;;
1457               *) gl_cv_func_printf_enomem="no" ;;
1458             esac
1459           else
1460             gl_cv_func_printf_enomem="guessing no"
1461           fi
1462           rm -fr conftest*
1463         else
1464           dnl A universal build on Apple Mac OS X platforms.
1465           dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode.
1466           dnl But we need a configuration result that is valid in both modes.
1467           gl_cv_func_printf_enomem="guessing no"
1468         fi
1469       fi
1470       if test "$gl_cv_func_printf_enomem" = "guessing no"; then
1471 changequote(,)dnl
1472         case "$host_os" in
1473                            # Guess yes on glibc systems.
1474           *-gnu* | gnu*)   gl_cv_func_printf_enomem="guessing yes";;
1475                            # Guess yes on Solaris.
1476           solaris*)        gl_cv_func_printf_enomem="guessing yes";;
1477                            # Guess yes on AIX.
1478           aix*)            gl_cv_func_printf_enomem="guessing yes";;
1479                            # Guess yes on HP-UX/hppa.
1480           hpux*)           case "$host_cpu" in
1481                              hppa*) gl_cv_func_printf_enomem="guessing yes";;
1482                              *)     gl_cv_func_printf_enomem="guessing no";;
1483                            esac
1484                            ;;
1485                            # Guess yes on IRIX.
1486           irix*)           gl_cv_func_printf_enomem="guessing yes";;
1487                            # Guess yes on OSF/1.
1488           osf*)            gl_cv_func_printf_enomem="guessing yes";;
1489                            # Guess yes on BeOS.
1490           beos*)           gl_cv_func_printf_enomem="guessing yes";;
1491                            # Guess yes on Haiku.
1492           haiku*)          gl_cv_func_printf_enomem="guessing yes";;
1493                            # Guess no on Android.
1494           linux*-android*) gl_cv_func_printf_enomem="guessing no";;
1495                            # If we don't know, obey --enable-cross-guesses.
1496           *)               gl_cv_func_printf_enomem="$gl_cross_guess_normal";;
1497         esac
1498 changequote([,])dnl
1499       fi
1500     ])
1503 dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001)
1504 dnl Result is ac_cv_func_snprintf.
1506 AC_DEFUN([gl_SNPRINTF_PRESENCE],
1508   AC_CHECK_FUNCS_ONCE([snprintf])
1511 dnl Test whether the string produced by the snprintf function is always NUL
1512 dnl terminated. (ISO C99, POSIX:2001)
1513 dnl Result is gl_cv_func_snprintf_truncation_c99.
1515 AC_DEFUN_ONCE([gl_SNPRINTF_TRUNCATION_C99],
1517   AC_REQUIRE([AC_PROG_CC])
1518   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1519   AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1520   AC_CACHE_CHECK([whether snprintf truncates the result as in C99],
1521     [gl_cv_func_snprintf_truncation_c99],
1522     [
1523       AC_RUN_IFELSE(
1524         [AC_LANG_SOURCE([[
1525 #include <stdio.h>
1526 #include <string.h>
1527 #if HAVE_SNPRINTF
1528 # define my_snprintf snprintf
1529 #else
1530 # include <stdarg.h>
1531 static int my_snprintf (char *buf, int size, const char *format, ...)
1533   va_list args;
1534   int ret;
1535   va_start (args, format);
1536   ret = vsnprintf (buf, size, format, args);
1537   va_end (args);
1538   return ret;
1540 #endif
1541 static char buf[100];
1542 int main ()
1544   strcpy (buf, "ABCDEF");
1545   my_snprintf (buf, 3, "%d %d", 4567, 89);
1546   if (memcmp (buf, "45\0DEF", 6) != 0)
1547     return 1;
1548   return 0;
1549 }]])],
1550         [gl_cv_func_snprintf_truncation_c99=yes],
1551         [gl_cv_func_snprintf_truncation_c99=no],
1552         [
1553 changequote(,)dnl
1554          case "$host_os" in
1555                                  # Guess yes on glibc systems.
1556            *-gnu* | gnu*)        gl_cv_func_snprintf_truncation_c99="guessing yes";;
1557                                  # Guess yes on musl systems.
1558            *-musl* | midipix*)   gl_cv_func_snprintf_truncation_c99="guessing yes";;
1559                                  # Guess yes on FreeBSD >= 5.
1560            freebsd[1-4].*)       gl_cv_func_snprintf_truncation_c99="guessing no";;
1561            freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";;
1562            midnightbsd*)         gl_cv_func_snprintf_truncation_c99="guessing yes";;
1563                                  # Guess yes on Mac OS X >= 10.3.
1564            darwin[1-6].*)        gl_cv_func_snprintf_truncation_c99="guessing no";;
1565            darwin*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1566                                  # Guess yes on OpenBSD >= 3.9.
1567            openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1568                                  gl_cv_func_snprintf_truncation_c99="guessing no";;
1569            openbsd*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
1570                                  # Guess yes on Solaris >= 2.6.
1571            solaris2.[0-5] | solaris2.[0-5].*)
1572                                  gl_cv_func_snprintf_truncation_c99="guessing no";;
1573            solaris*)             gl_cv_func_snprintf_truncation_c99="guessing yes";;
1574                                  # Guess yes on AIX >= 4.
1575            aix[1-3]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
1576            aix*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
1577                                  # Guess yes on HP-UX >= 11.
1578            hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";;
1579            hpux*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
1580                                  # Guess yes on IRIX >= 6.5.
1581            irix6.5)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1582                                  # Guess yes on OSF/1 >= 5.
1583            osf[3-4]*)            gl_cv_func_snprintf_truncation_c99="guessing no";;
1584            osf*)                 gl_cv_func_snprintf_truncation_c99="guessing yes";;
1585                                  # Guess yes on NetBSD >= 3.
1586            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1587                                  gl_cv_func_snprintf_truncation_c99="guessing no";;
1588            netbsd*)              gl_cv_func_snprintf_truncation_c99="guessing yes";;
1589                                  # Guess yes on BeOS.
1590            beos*)                gl_cv_func_snprintf_truncation_c99="guessing yes";;
1591                                  # Guess yes on Android.
1592            linux*-android*)      gl_cv_func_snprintf_truncation_c99="guessing yes";;
1593                                  # Guess no on native Windows.
1594            mingw* | windows*)    gl_cv_func_snprintf_truncation_c99="guessing no";;
1595                                  # If we don't know, obey --enable-cross-guesses.
1596            *)                    gl_cv_func_snprintf_truncation_c99="$gl_cross_guess_normal";;
1597          esac
1598 changequote([,])dnl
1599         ])
1600     ])
1603 dnl Test whether the return value of the snprintf function is the number
1604 dnl of bytes (excluding the terminating NUL) that would have been produced
1605 dnl if the buffer had been large enough. (ISO C99, POSIX:2001)
1606 dnl For example, this test program fails on IRIX 6.5:
1607 dnl     ---------------------------------------------------------------------
1608 dnl     #include <stdio.h>
1609 dnl     int main()
1610 dnl     {
1611 dnl       static char buf[8];
1612 dnl       int retval = snprintf (buf, 3, "%d", 12345);
1613 dnl       return retval >= 0 && retval < 3;
1614 dnl     }
1615 dnl     ---------------------------------------------------------------------
1616 dnl Result is gl_cv_func_snprintf_retval_c99.
1618 AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99],
1620   AC_REQUIRE([AC_PROG_CC])
1621   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1622   AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1623   AC_CACHE_CHECK([whether snprintf returns a byte count as in C99],
1624     [gl_cv_func_snprintf_retval_c99],
1625     [
1626       AC_RUN_IFELSE(
1627         [AC_LANG_SOURCE([[
1628 #include <stdio.h>
1629 #include <string.h>
1630 #if HAVE_SNPRINTF
1631 # define my_snprintf snprintf
1632 #else
1633 # include <stdarg.h>
1634 static int my_snprintf (char *buf, int size, const char *format, ...)
1636   va_list args;
1637   int ret;
1638   va_start (args, format);
1639   ret = vsnprintf (buf, size, format, args);
1640   va_end (args);
1641   return ret;
1643 #endif
1644 static char buf[100];
1645 int main ()
1647   strcpy (buf, "ABCDEF");
1648   if (my_snprintf (buf, 3, "%d %d", 4567, 89) != 7)
1649     return 1;
1650   if (my_snprintf (buf, 0, "%d %d", 4567, 89) != 7)
1651     return 2;
1652   if (my_snprintf (NULL, 0, "%d %d", 4567, 89) != 7)
1653     return 3;
1654   return 0;
1655 }]])],
1656         [gl_cv_func_snprintf_retval_c99=yes],
1657         [gl_cv_func_snprintf_retval_c99=no],
1658         [case "$host_os" in
1659 changequote(,)dnl
1660                                  # Guess yes on glibc systems.
1661            *-gnu* | gnu*)        gl_cv_func_snprintf_retval_c99="guessing yes";;
1662                                  # Guess yes on musl systems.
1663            *-musl* | midipix*)   gl_cv_func_snprintf_retval_c99="guessing yes";;
1664                                  # Guess yes on FreeBSD >= 5.
1665            freebsd[1-4].*)       gl_cv_func_snprintf_retval_c99="guessing no";;
1666            freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";;
1667            midnightbsd*)         gl_cv_func_snprintf_retval_c99="guessing yes";;
1668                                  # Guess yes on Mac OS X >= 10.3.
1669            darwin[1-6].*)        gl_cv_func_snprintf_retval_c99="guessing no";;
1670            darwin*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1671                                  # Guess yes on OpenBSD >= 3.9.
1672            openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*)
1673                                  gl_cv_func_snprintf_retval_c99="guessing no";;
1674            openbsd*)             gl_cv_func_snprintf_retval_c99="guessing yes";;
1675                                  # Guess yes on Solaris >= 2.10.
1676            solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";;
1677            solaris*)             gl_cv_func_printf_sizes_c99="guessing no";;
1678                                  # Guess yes on AIX >= 4.
1679            aix[1-3]*)            gl_cv_func_snprintf_retval_c99="guessing no";;
1680            aix*)                 gl_cv_func_snprintf_retval_c99="guessing yes";;
1681                                  # Guess yes on NetBSD >= 3.
1682            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1683                                  gl_cv_func_snprintf_retval_c99="guessing no";;
1684            netbsd*)              gl_cv_func_snprintf_retval_c99="guessing yes";;
1685                                  # Guess yes on BeOS.
1686            beos*)                gl_cv_func_snprintf_retval_c99="guessing yes";;
1687                                  # Guess yes on Android.
1688            linux*-android*)      gl_cv_func_snprintf_retval_c99="guessing yes";;
1689 changequote([,])dnl
1690                                  # Guess yes on MSVC, no on mingw.
1691            windows*-msvc*)       gl_cv_func_snprintf_retval_c99="guessing yes" ;;
1692            mingw* | windows*)    AC_EGREP_CPP([Known], [
1693 #ifdef _MSC_VER
1694  Known
1695 #endif
1696                                    ],
1697                                    [gl_cv_func_snprintf_retval_c99="guessing yes"],
1698                                    [gl_cv_func_snprintf_retval_c99="guessing no"])
1699                                  ;;
1700                                  # If we don't know, obey --enable-cross-guesses.
1701            *)                    gl_cv_func_snprintf_retval_c99="$gl_cross_guess_normal";;
1702          esac
1703         ])
1704     ])
1707 dnl Test whether the snprintf function supports the %n format directive
1708 dnl also in truncated portions of the format string. (ISO C99, POSIX:2001)
1709 dnl Result is gl_cv_func_snprintf_directive_n.
1711 AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N],
1713   AC_REQUIRE([AC_PROG_CC])
1714   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1715   AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1716   AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive],
1717     [gl_cv_func_snprintf_directive_n],
1718     [
1719       AC_RUN_IFELSE(
1720         [AC_LANG_SOURCE([[
1721 #include <signal.h>
1722 #include <stdio.h>
1723 #include <string.h>
1724 #if defined _WIN32 && !defined __CYGWIN__
1725 # include <stdlib.h>
1726 #else
1727 # include <unistd.h>
1728 #endif
1729 #if HAVE_SNPRINTF
1730 # define my_snprintf snprintf
1731 #else
1732 # include <stdarg.h>
1733 static int my_snprintf (char *buf, int size, const char *format, ...)
1735   va_list args;
1736   int ret;
1737   va_start (args, format);
1738   ret = vsnprintf (buf, size, format, args);
1739   va_end (args);
1740   return ret;
1742 #endif
1743 static void
1744 abort_handler (int sig)
1746   (void) sig;
1747   _exit (1);
1749 static char fmtstring[10];
1750 static char buf[100];
1751 int main ()
1753   int count = -1;
1754   signal (SIGABRT, abort_handler);
1755   /* Copy the format string.  Some systems (glibc with _FORTIFY_SOURCE=2)
1756      support %n in format strings in read-only memory but not in writable
1757      memory.  */
1758   strcpy (fmtstring, "%d %n");
1759   my_snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55);
1760   if (count != 6)
1761     return 1;
1762   return 0;
1763 }]])],
1764         [gl_cv_func_snprintf_directive_n=yes],
1765         [gl_cv_func_snprintf_directive_n=no],
1766         [
1767          case "$host_os" in
1768                                  # Guess no on glibc when _FORTIFY_SOURCE >= 2.
1769            *-gnu* | gnu*)        AC_COMPILE_IFELSE(
1770                                    [AC_LANG_SOURCE(
1771                                       [[#if _FORTIFY_SOURCE >= 2
1772                                          error fail
1773                                         #endif
1774                                       ]])],
1775                                    [gl_cv_func_snprintf_directive_n="guessing yes"],
1776                                    [gl_cv_func_snprintf_directive_n="guessing no"])
1777                                  ;;
1778 changequote(,)dnl
1779                                  # Guess yes on musl systems.
1780            *-musl* | midipix*)   gl_cv_func_snprintf_directive_n="guessing yes";;
1781                                  # Guess yes on FreeBSD >= 5.
1782            freebsd[1-4].*)       gl_cv_func_snprintf_directive_n="guessing no";;
1783            freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";;
1784            midnightbsd*)         gl_cv_func_snprintf_directive_n="guessing yes";;
1785                                  # Guess yes on Mac OS X >= 10.3.
1786            darwin[1-6].*)        gl_cv_func_snprintf_directive_n="guessing no";;
1787            darwin*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1788                                  # Guess yes on Solaris >= 2.6.
1789            solaris2.[0-5] | solaris2.[0-5].*)
1790                                  gl_cv_func_snprintf_directive_n="guessing no";;
1791            solaris*)             gl_cv_func_snprintf_directive_n="guessing yes";;
1792                                  # Guess yes on AIX >= 4.
1793            aix[1-3]*)            gl_cv_func_snprintf_directive_n="guessing no";;
1794            aix*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
1795                                  # Guess yes on IRIX >= 6.5.
1796            irix6.5)              gl_cv_func_snprintf_directive_n="guessing yes";;
1797                                  # Guess yes on OSF/1 >= 5.
1798            osf[3-4]*)            gl_cv_func_snprintf_directive_n="guessing no";;
1799            osf*)                 gl_cv_func_snprintf_directive_n="guessing yes";;
1800                                  # Guess yes on NetBSD >= 3.
1801            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1802                                  gl_cv_func_snprintf_directive_n="guessing no";;
1803            netbsd*)              gl_cv_func_snprintf_directive_n="guessing yes";;
1804                                  # Guess yes on BeOS.
1805            beos*)                gl_cv_func_snprintf_directive_n="guessing yes";;
1806                                  # Guess no on Android.
1807            linux*-android*)      gl_cv_func_snprintf_directive_n="guessing no";;
1808                                  # Guess no on native Windows.
1809            mingw* | windows*)    gl_cv_func_snprintf_directive_n="guessing no";;
1810                                  # If we don't know, obey --enable-cross-guesses.
1811            *)                    gl_cv_func_snprintf_directive_n="$gl_cross_guess_normal";;
1812 changequote([,])dnl
1813          esac
1814         ])
1815     ])
1818 dnl Test whether the snprintf function, when passed a size = 1, writes any
1819 dnl output without bounds in this case, behaving like sprintf. This is the
1820 dnl case on Linux libc5.
1821 dnl Result is gl_cv_func_snprintf_size1.
1823 AC_DEFUN([gl_SNPRINTF_SIZE1],
1825   AC_REQUIRE([AC_PROG_CC])
1826   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1827   AC_REQUIRE([gl_SNPRINTF_PRESENCE])
1828   AC_CACHE_CHECK([whether snprintf respects a size of 1],
1829     [gl_cv_func_snprintf_size1],
1830     [
1831       AC_RUN_IFELSE(
1832         [AC_LANG_SOURCE([[
1833 #include <stdio.h>
1834 #if HAVE_SNPRINTF
1835 # define my_snprintf snprintf
1836 #else
1837 # include <stdarg.h>
1838 static int my_snprintf (char *buf, int size, const char *format, ...)
1840   va_list args;
1841   int ret;
1842   va_start (args, format);
1843   ret = vsnprintf (buf, size, format, args);
1844   va_end (args);
1845   return ret;
1847 #endif
1848 int main()
1850   static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1851   my_snprintf (buf, 1, "%d", 12345);
1852   return buf[1] != 'E';
1853 }]])],
1854         [gl_cv_func_snprintf_size1=yes],
1855         [gl_cv_func_snprintf_size1=no],
1856         [case "$host_os" in
1857                               # Guess yes on Android.
1858            linux*-android*)   gl_cv_func_snprintf_size1="guessing yes" ;;
1859                               # Guess yes on native Windows.
1860            mingw* | windows*) gl_cv_func_snprintf_size1="guessing yes" ;;
1861            *)                 gl_cv_func_snprintf_size1="guessing yes" ;;
1862          esac
1863         ])
1864     ])
1867 dnl Test whether the vsnprintf function, when passed a zero size, produces no
1868 dnl output. (ISO C99, POSIX:2001)
1869 dnl For example, snprintf nevertheless writes a NUL byte in this case
1870 dnl on OSF/1 5.1:
1871 dnl     ---------------------------------------------------------------------
1872 dnl     #include <stdio.h>
1873 dnl     int main()
1874 dnl     {
1875 dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1876 dnl       snprintf (buf, 0, "%d", 12345);
1877 dnl       return buf[0] != 'D';
1878 dnl     }
1879 dnl     ---------------------------------------------------------------------
1880 dnl And vsnprintf writes any output without bounds in this case, behaving like
1881 dnl vsprintf, on HP-UX 11 and OSF/1 5.1:
1882 dnl     ---------------------------------------------------------------------
1883 dnl     #include <stdarg.h>
1884 dnl     #include <stdio.h>
1885 dnl     static int my_snprintf (char *buf, int size, const char *format, ...)
1886 dnl     {
1887 dnl       va_list args;
1888 dnl       int ret;
1889 dnl       va_start (args, format);
1890 dnl       ret = vsnprintf (buf, size, format, args);
1891 dnl       va_end (args);
1892 dnl       return ret;
1893 dnl     }
1894 dnl     int main()
1895 dnl     {
1896 dnl       static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1897 dnl       my_snprintf (buf, 0, "%d", 12345);
1898 dnl       return buf[0] != 'D';
1899 dnl     }
1900 dnl     ---------------------------------------------------------------------
1901 dnl Result is gl_cv_func_vsnprintf_zerosize_c99.
1903 AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99],
1905   AC_REQUIRE([AC_PROG_CC])
1906   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1907   AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99],
1908     [gl_cv_func_vsnprintf_zerosize_c99],
1909     [
1910       AC_RUN_IFELSE(
1911         [AC_LANG_SOURCE([[
1912 #include <stdarg.h>
1913 #include <stdio.h>
1914 static int my_snprintf (char *buf, int size, const char *format, ...)
1916   va_list args;
1917   int ret;
1918   va_start (args, format);
1919   ret = vsnprintf (buf, size, format, args);
1920   va_end (args);
1921   return ret;
1923 int main()
1925   static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' };
1926   my_snprintf (buf, 0, "%d", 12345);
1927   return buf[0] != 'D';
1928 }]])],
1929         [gl_cv_func_vsnprintf_zerosize_c99=yes],
1930         [gl_cv_func_vsnprintf_zerosize_c99=no],
1931         [
1932 changequote(,)dnl
1933          case "$host_os" in
1934                                     # Guess yes on glibc systems.
1935            *-gnu* | gnu*)           gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1936                                     # Guess yes on musl systems.
1937            *-musl* | midipix*)      gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1938                                     # Guess yes on FreeBSD >= 5.
1939            freebsd[1-4].*)          gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1940            freebsd* | kfreebsd*)    gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1941            midnightbsd*)            gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1942                                     # Guess yes on Mac OS X >= 10.3.
1943            darwin[1-6].*)           gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1944            darwin*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1945                                     # Guess yes on Cygwin.
1946            cygwin*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1947                                     # Guess yes on Solaris >= 2.6.
1948            solaris2.[0-5] | solaris2.[0-5].*)
1949                                     gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1950            solaris*)                gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1951                                     # Guess yes on AIX >= 4.
1952            aix[1-3]*)               gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1953            aix*)                    gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1954                                     # Guess yes on IRIX >= 6.5.
1955            irix6.5)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1956                                     # Guess yes on NetBSD >= 3.
1957            netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
1958                                     gl_cv_func_vsnprintf_zerosize_c99="guessing no";;
1959            netbsd*)                 gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1960                                     # Guess yes on BeOS.
1961            beos*)                   gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1962                                     # Guess yes on Android.
1963            linux*-android*)         gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1964                                     # Guess yes on native Windows.
1965            mingw* | windows* | pw*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";;
1966                                     # If we don't know, obey --enable-cross-guesses.
1967            *)                       gl_cv_func_vsnprintf_zerosize_c99="$gl_cross_guess_normal";;
1968          esac
1969 changequote([,])dnl
1970         ])
1971     ])
1974 dnl Test whether the swprintf function works correctly when it produces output
1975 dnl that contains null wide characters.
1976 dnl Result is gl_cv_func_swprintf_works.
1978 AC_DEFUN([gl_SWPRINTF_WORKS],
1980   AC_REQUIRE([AC_PROG_CC])
1981   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
1982   AC_CHECK_FUNCS_ONCE([swprintf])
1983   AC_CACHE_CHECK([whether swprintf works],
1984     [gl_cv_func_swprintf_works],
1985     [
1986       AC_RUN_IFELSE(
1987         [AC_LANG_SOURCE([[
1988 #ifndef __USE_MINGW_ANSI_STDIO
1989 # define __USE_MINGW_ANSI_STDIO 1
1990 #endif
1991 #include <stdio.h>
1992 #include <wchar.h>
1993 int main()
1995   int result = 0;
1996   { /* This test fails on musl libc 1.2.3, FreeBSD, NetBSD, OpenBSD, macOS, AIX.  */
1997     wchar_t buf[5] = { 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF };
1998     int ret = swprintf (buf, 4, L"%cz", '\0');
1999     /* Expected result:
2000          ret = 2, buf[0] = 0x0, buf[1] = 0x7a, buf[2] = 0x0, buf[3] = 0xbeef
2001        musl libc 1.2.3:
2002          ret = 2, buf[0] = 0x0, buf[1] = 0x0, buf[2] = 0x0, buf[3] = 0x0
2003          Reported at <https://www.openwall.com/lists/musl/2023/03/22/9>.
2004        FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2:
2005          ret = 2, buf[0] = 0x0, buf[1] = 0xbeef, buf[2] = 0xbeef, buf[3] = 0xbeef
2006      */
2007     if (ret < 0 || buf[1] != 'z')
2008       result |= 1;
2009   }
2010   { /* This test fails on mingw.  */
2011     wchar_t buf[2];
2012     int ret = swprintf (buf, 2, L"%lc", (wint_t)0);
2013     /* Expected: ret = 1
2014        mingw:    ret = 0
2015      */
2016     if (ret != 1)
2017       result |= 2;
2018   }
2019   return result;
2020 }]])],
2021         [gl_cv_func_swprintf_works=yes],
2022         [gl_cv_func_swprintf_works=no],
2023         [case "$host_os" in
2024                                     # Guess yes on glibc systems.
2025            *-gnu* | gnu*)           gl_cv_func_swprintf_works="guessing yes";;
2026                                     # Guess no on musl systems.
2027            *-musl* | midipix*)      gl_cv_func_swprintf_works="guessing no";;
2028                                     # Guess no on FreeBSD, NetBSD, OpenBSD, macOS, AIX.
2029            freebsd* | midnightbsd* | netbsd* | openbsd* | darwin* | aix*)
2030                                     gl_cv_func_swprintf_works="guessing no";;
2031                                     # Guess no on native Windows.
2032            mingw* | windows* | pw*) gl_cv_func_swprintf_works="guessing no";;
2033                                     # If we don't know, obey --enable-cross-guesses.
2034            *)                       gl_cv_func_swprintf_works="$gl_cross_guess_normal";;
2035          esac
2036         ])
2037     ])
2040 dnl Test whether the *wprintf family of functions supports the 'a' and 'A'
2041 dnl conversion specifier for hexadecimal output of 'long double' numbers.
2042 dnl (ISO C99, POSIX:2001)
2043 dnl Result is gl_cv_func_swprintf_directive_la.
2045 AC_DEFUN([gl_SWPRINTF_DIRECTIVE_LA],
2047   AC_REQUIRE([AC_PROG_CC])
2048   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
2049   AC_CACHE_CHECK([whether swprintf supports the 'La' and 'LA' directives],
2050     [gl_cv_func_swprintf_directive_la],
2051     [
2052       AC_RUN_IFELSE(
2053         [AC_LANG_SOURCE([[
2054 #include <stdio.h>
2055 #include <wchar.h>
2056 static wchar_t buf[100];
2057 int main ()
2059   int result = 0;
2060   /* This catches a glibc 2.15, Haiku 2022, NetBSD 10.0 bug.  */
2061   if (swprintf (buf, sizeof (buf) / sizeof (wchar_t),
2062                 L"%La %d", 3.1416015625L, 33, 44, 55) < 0
2063       || (wcscmp (buf, L"0x1.922p+1 33") != 0
2064           && wcscmp (buf, L"0x3.244p+0 33") != 0
2065           && wcscmp (buf, L"0x6.488p-1 33") != 0
2066           && wcscmp (buf, L"0xc.91p-2 33") != 0))
2067     result |= 1;
2068   return result;
2069 }]])],
2070         [gl_cv_func_swprintf_directive_la=yes],
2071         [gl_cv_func_swprintf_directive_la=no],
2072         [case "$host_os" in
2073                                # Guess yes on glibc >= 2.17 systems.
2074            *-gnu* | gnu*)
2075              AC_EGREP_CPP([Unlucky], [
2076                #include <features.h>
2077                #ifdef __GNU_LIBRARY__
2078                 #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16) || (__GLIBC__ > 2)) && !defined __UCLIBC__
2079                  Unlucky
2080                 #endif
2081                #endif
2082                ],
2083                [gl_cv_func_swprintf_directive_la="guessing yes"],
2084                [gl_cv_func_swprintf_directive_la="guessing no"])
2085              ;;
2086                                # Guess yes on musl systems.
2087            *-musl* | midipix*) gl_cv_func_swprintf_directive_la="guessing yes";;
2088                                # Guess yes on Android.
2089            linux*-android*)    gl_cv_func_swprintf_directive_la="guessing yes";;
2090                                # Guess no on NetBSD.
2091            netbsd*)            gl_cv_func_swprintf_directive_la="guessing no";;
2092                                # Guess no on native Windows.
2093            mingw* | windows*)  gl_cv_func_swprintf_directive_la="guessing no";;
2094                                # If we don't know, obey --enable-cross-guesses.
2095            *)                  gl_cv_func_swprintf_directive_la="$gl_cross_guess_normal";;
2096          esac
2097         ])
2098     ])
2101 dnl Test whether the *wprintf family of functions supports the 'lc' conversion
2102 dnl specifier for all wide characters.
2103 dnl (ISO C11, POSIX:2001)
2104 dnl Result is gl_cv_func_swprintf_directive_lc.
2106 AC_DEFUN([gl_SWPRINTF_DIRECTIVE_LC],
2108   AC_REQUIRE([AC_PROG_CC])
2109   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
2110   AC_CACHE_CHECK([whether swprintf supports the 'lc' directive],
2111     [gl_cv_func_swprintf_directive_lc],
2112     [
2113       AC_RUN_IFELSE(
2114         [AC_LANG_SOURCE([[
2115 #include <stdio.h>
2116 #include <wchar.h>
2117 static wchar_t buf[100];
2118 static wint_t L_invalid = (wchar_t) 0x76543210;
2119 int main ()
2121   int result = 0;
2122   /* This catches a musl libc 1.2.4, Android bug.
2123      Reported at <https://www.openwall.com/lists/musl/2023/06/12/3>. */
2124   if (swprintf (buf, sizeof (buf) / sizeof (wchar_t),
2125                 L"%lc %d", L_invalid, 33, 44, 55) < 0)
2126     result |= 1;
2127   return result;
2128 }]])],
2129         [gl_cv_func_swprintf_directive_lc=yes],
2130         [gl_cv_func_swprintf_directive_lc=no],
2131         [case "$host_os" in
2132                                # Guess yes on glibc systems.
2133            *-gnu* | gnu*)      gl_cv_func_swprintf_directive_lc="guessing yes";;
2134                                # Guess no on musl systems.
2135            *-musl* | midipix*) gl_cv_func_swprintf_directive_lc="guessing no";;
2136                                # Guess no on Android.
2137            linux*-android*)    gl_cv_func_swprintf_directive_lc="guessing no";;
2138                                # Guess yes on native Windows.
2139            mingw* | windows*)  gl_cv_func_swprintf_directive_lc="guessing yes";;
2140                                # If we don't know, obey --enable-cross-guesses.
2141            *)                  gl_cv_func_swprintf_directive_lc="$gl_cross_guess_normal";;
2142          esac
2143         ])
2144     ])
2147 dnl The results of these tests on various platforms are:
2149 dnl 1 = gl_PRINTF_SIZES_C99
2150 dnl 2 = gl_PRINTF_SIZES_C23
2151 dnl 3 = gl_PRINTF_LONG_DOUBLE
2152 dnl 4 = gl_PRINTF_INFINITE
2153 dnl 5 = gl_PRINTF_INFINITE_LONG_DOUBLE
2154 dnl 6 = gl_PRINTF_DIRECTIVE_A
2155 dnl 7 = gl_PRINTF_DIRECTIVE_B
2156 dnl 8 = gl_PRINTF_DIRECTIVE_UPPERCASE_B
2157 dnl 9 = gl_PRINTF_DIRECTIVE_F
2158 dnl 10 = gl_PRINTF_DIRECTIVE_N
2159 dnl 11 = gl_PRINTF_DIRECTIVE_LS
2160 dnl 12 = gl_PRINTF_DIRECTIVE_LC
2161 dnl 13 = gl_PRINTF_POSITIONS
2162 dnl 14 = gl_PRINTF_FLAG_GROUPING
2163 dnl 15 = gl_PRINTF_FLAG_LEFTADJUST
2164 dnl 16 = gl_PRINTF_FLAG_ZERO
2165 dnl 17 = gl_PRINTF_FLAG_ALT_PRECISION_ZERO
2166 dnl 18 = gl_PRINTF_PRECISION
2167 dnl 19 = gl_PRINTF_ENOMEM
2168 dnl 20 = gl_SNPRINTF_PRESENCE
2169 dnl 21 = gl_SNPRINTF_TRUNCATION_C99
2170 dnl 22 = gl_SNPRINTF_RETVAL_C99
2171 dnl 23 = gl_SNPRINTF_DIRECTIVE_N
2172 dnl 24 = gl_SNPRINTF_SIZE1
2173 dnl 25 = gl_VSNPRINTF_ZEROSIZE_C99
2174 dnl 26 = gl_SWPRINTF_WORKS
2175 dnl 27 = gl_SWPRINTF_DIRECTIVE_LA
2176 dnl 28 = gl_SWPRINTF_DIRECTIVE_LC
2178 dnl 1 = checking whether printf supports size specifiers as in C99...
2179 dnl 2 = checking whether printf supports size specifiers as in C23...
2180 dnl 3 = checking whether printf supports 'long double' arguments...
2181 dnl 4 = checking whether printf supports infinite 'double' arguments...
2182 dnl 5 = checking whether printf supports infinite 'long double' arguments...
2183 dnl 6 = checking whether printf supports the 'a' and 'A' directives...
2184 dnl 7 = checking whether printf supports the 'b' directive...
2185 dnl 8 = checking whether printf supports the 'B' directive...
2186 dnl 9 = checking whether printf supports the 'F' directive...
2187 dnl 10 = checking whether printf supports the 'n' directive...
2188 dnl 11 = checking whether printf supports the 'ls' directive...
2189 dnl 12 = checking whether printf supports the 'lc' directive correctly...
2190 dnl 13 = checking whether printf supports POSIX/XSI format strings with positions...
2191 dnl 14 = checking whether printf supports the grouping flag...
2192 dnl 15 = checking whether printf supports the left-adjust flag correctly...
2193 dnl 16 = checking whether printf supports the zero flag correctly...
2194 dnl 17 = checking whether printf supports the alternative flag with a zero precision...
2195 dnl 18 = checking whether printf supports large precisions...
2196 dnl 19 = checking whether printf survives out-of-memory conditions...
2197 dnl 20 = checking for snprintf...
2198 dnl 21 = checking whether snprintf truncates the result as in C99...
2199 dnl 22 = checking whether snprintf returns a byte count as in C99...
2200 dnl 23 = checking whether snprintf fully supports the 'n' directive...
2201 dnl 24 = checking whether snprintf respects a size of 1...
2202 dnl 25 = checking whether vsnprintf respects a zero size as in C99...
2203 dnl 26 = checking whether swprintf works...
2204 dnl 27 = checking whether swprintf supports the 'La' and 'LA' directives...
2205 dnl 28 = checking whether swprintf supports the 'lc' directive...
2207 dnl . = yes, # = no.
2209 dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
2210 dnl   musl libc 1.2.3                .  #  .  .  .  .  #  #  .  .  .  #  .  .  .  .  ?  .  .  .  .  .  .  .  .  #  .  #
2211 dnl   glibc 2.35                     .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
2212 dnl   glibc 2.5                      .  #  .  .  .  .  #  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  #  .
2213 dnl   glibc 2.3.6                    .  #  .  .  .  #  #  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  #  .
2214 dnl   FreeBSD 14.0                   .  .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  #  .  .  .  .  .  .  #  .  #
2215 dnl   FreeBSD 13.0                   .  #  .  .  .  #  #  #  .  .  .  .  .  .  .  .  .  .  #  .  .  .  .  .  .  #  .  #
2216 dnl   FreeBSD 5.4, 6.1               .  #  .  .  .  #  #  #  .  .  .  .  .  .  .  #  ?  .  #  .  .  .  .  .  .  #  ?  ?
2217 dnl   Mac OS X 10.13.5               .  #  .  .  #  #  #  #  .  #  .  .  .  .  .  .  .  .  .  .  .  .  #  .  .  #  ?  ?
2218 dnl   Mac OS X 10.5.8                .  #  .  .  #  #  #  #  .  .  .  .  .  .  .  #  #  .  .  .  .  .  .  .  .  #  ?  ?
2219 dnl   Mac OS X 10.3.9                .  #  .  .  .  #  #  #  .  .  .  .  .  .  .  #  #  .  #  .  .  .  .  .  .  #  ?  ?
2220 dnl   OpenBSD 6.0, 6.7               .  #  .  .  .  #  #  #  .  .  .  .  .  .  .  .  .  .  #  .  .  .  .  .  .  #  .  #
2221 dnl   OpenBSD 3.9, 4.0               .  #  .  #  #  #  #  #  #  .  #  .  .  #  .  #  ?  .  #  .  .  .  .  .  .  #  ?  ?
2222 dnl   Cygwin 1.7.0 (2009)            .  #  .  .  #  .  #  #  .  .  ?  ?  .  .  .  .  ?  .  ?  .  .  .  .  .  .  ?  ?  ?
2223 dnl   Cygwin 1.5.25 (2008)           .  #  .  .  #  #  #  #  .  .  #  ?  .  .  .  .  ?  .  #  .  .  .  .  .  .  ?  ?  ?
2224 dnl   Cygwin 1.5.19 (2006)           #  #  .  .  #  #  #  #  #  .  #  ?  .  #  .  #  ?  #  #  .  .  .  .  .  .  ?  ?  ?
2225 dnl   Solaris 11.4                   .  #  .  #  #  #  #  #  .  .  #  .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  #  .
2226 dnl   Solaris 11.3                   .  #  .  .  .  #  #  #  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  #  .
2227 dnl   Solaris 11.0                   .  #  .  #  #  #  #  #  .  .  #  .  .  .  .  #  .  .  .  .  .  .  .  .  .  ?  ?  ?
2228 dnl   Solaris 10                     .  #  .  #  #  #  #  #  .  .  #  .  .  .  .  #  .  #  .  .  .  .  .  .  .  .  #  .
2229 dnl   Solaris 2.6 ... 9              #  #  .  #  #  #  #  #  #  .  #  .  .  .  .  #  ?  #  .  .  .  #  .  .  .  ?  ?  ?
2230 dnl   Solaris 2.5.1                  #  #  .  #  #  #  #  #  #  .  #  .  .  .  .  #  ?  .  .  #  #  #  #  #  #  ?  ?  ?
2231 dnl   AIX 7.1                        .  #  .  #  #  #  #  #  .  .  .  .  .  .  .  #  .  #  .  .  .  .  .  .  .  #  .  .
2232 dnl   AIX 5.2                        .  #  .  #  #  #  #  #  .  .  .  .  .  .  .  #  ?  .  .  .  .  .  .  .  .  #  ?  ?
2233 dnl   AIX 4.3.2, 5.1                 #  #  .  #  #  #  #  #  #  .  .  .  .  .  .  #  ?  .  .  .  .  #  .  .  .  #  ?  ?
2234 dnl   HP-UX 11.31                    .  #  .  .  .  #  #  #  .  .  .  ?  .  .  .  #  ?  .  .  .  .  #  #  .  .  ?  ?  ?
2235 dnl   HP-UX 11.{00,11,23}            #  #  .  .  .  #  #  #  #  .  .  ?  .  .  .  #  ?  .  .  .  .  #  #  .  #  ?  ?  ?
2236 dnl   HP-UX 10.20                    #  #  .  #  .  #  #  #  #  .  ?  ?  .  .  #  #  ?  .  .  .  .  #  #  ?  #  ?  ?  ?
2237 dnl   IRIX 6.5                       #  #  .  #  #  #  #  #  #  .  #  .  .  .  .  #  ?  .  .  .  .  #  .  .  .  #  ?  ?
2238 dnl   OSF/1 5.1                      #  #  .  #  #  #  #  #  #  .  .  ?  .  .  .  #  ?  .  .  .  .  #  .  .  #  ?  ?  ?
2239 dnl   OSF/1 4.0d                     #  #  .  #  #  #  #  #  #  .  .  ?  .  .  .  #  ?  .  .  #  #  #  #  #  #  ?  ?  ?
2240 dnl   NetBSD 9.0                     .  #  .  .  .  #  #  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  #  .  #
2241 dnl   NetBSD 5.0                     .  #  .  .  #  #  #  #  .  .  .  .  .  .  .  #  ?  .  #  .  .  .  .  .  .  #  ?  ?
2242 dnl   NetBSD 4.0                     .  #  ?  ?  ?  ?  #  #  ?  .  ?  .  .  ?  ?  ?  ?  ?  ?  .  .  .  ?  ?  ?  #  ?  ?
2243 dnl   NetBSD 3.0                     .  #  .  .  .  #  #  #  #  .  ?  .  #  #  ?  #  ?  .  #  .  .  .  .  .  .  #  ?  ?
2244 dnl   Haiku                          .  #  .  .  #  #  #  #  #  .  #  ?  .  .  .  .  ?  .  ?  .  .  ?  .  .  .  .  #  .
2245 dnl   BeOS                           #  #  #  .  #  #  #  #  #  .  ?  ?  #  .  ?  .  ?  #  ?  .  .  ?  .  .  .  ?  ?  ?
2246 dnl   Android 4.3                    .  #  .  #  #  #  #  #  #  #  #  ?  .  #  .  #  ?  .  #  .  .  .  #  .  .  ?  ?  ?
2247 dnl   old mingw / msvcrt             #  #  #  #  #  #  #  #  #  .  .  ?  #  #  .  #  ?  #  ?  .  #  #  #  .  .  #  ?  ?
2248 dnl   MSVC 9                         #  #  #  #  #  #  #  #  #  #  .  ?  #  #  .  #  ?  #  ?  #  #  #  #  .  .  #  ?  ?
2249 dnl   mingw 2009-2011                .  #  #  .  #  .  #  #  .  .  .  ?  #  #  .  .  ?  .  ?  .  .  .  .  .  .  #  ?  ?
2250 dnl   mingw-w64 2011                 #  #  #  #  #  #  #  #  #  .  .  ?  #  #  .  #  ?  #  ?  .  #  #  #  .  .  #  ?  ?