printf.m4 70 KB

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