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