snprintf.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110
  1. /*
  2. * Copyright (c) 1995 Patrick Powell.
  3. *
  4. * This code is based on code written by Patrick Powell <papowell@astart.com>.
  5. * It may be used for any purpose as long as this notice remains intact on all
  6. * source code distributions.
  7. */
  8. /*
  9. * Copyright (c) 2008 Holger Weiss.
  10. *
  11. * This version of the code is maintained by Holger Weiss <holger@jhweiss.de>.
  12. * My changes to the code may freely be used, modified and/or redistributed for
  13. * any purpose. It would be nice if additions and fixes to this file (including
  14. * trivial code cleanups) would be sent back in order to let me include them in
  15. * the version available at <http://www.jhweiss.de/software/snprintf.html>.
  16. * However, this is not a requirement for using or redistributing (possibly
  17. * modified) versions of this file, nor is leaving this notice intact mandatory.
  18. */
  19. /*
  20. * History
  21. *
  22. * 2008-01-20 Holger Weiss <holger@jhweiss.de> for C99-snprintf 1.1:
  23. *
  24. * Fixed the detection of infinite floating point values on IRIX (and
  25. * possibly other systems) and applied another few minor cleanups.
  26. *
  27. * 2008-01-06 Holger Weiss <holger@jhweiss.de> for C99-snprintf 1.0:
  28. *
  29. * Added a lot of new features, fixed many bugs, and incorporated various
  30. * improvements done by Andrew Tridgell <tridge@samba.org>, Russ Allbery
  31. * <rra@stanford.edu>, Hrvoje Niksic <hniksic@xemacs.org>, Damien Miller
  32. * <djm@mindrot.org>, and others for the Samba, INN, Wget, and OpenSSH
  33. * projects. The additions include: support the "e", "E", "g", "G", and
  34. * "F" conversion specifiers (and use conversion style "f" or "F" for the
  35. * still unsupported "a" and "A" specifiers); support the "hh", "ll", "j",
  36. * "t", and "z" length modifiers; support the "#" flag and the (non-C99)
  37. * "'" flag; use localeconv(3) (if available) to get both the current
  38. * locale's decimal point character and the separator between groups of
  39. * digits; fix the handling of various corner cases of field width and
  40. * precision specifications; fix various floating point conversion bugs;
  41. * handle infinite and NaN floating point values; don't attempt to write to
  42. * the output buffer (which may be NULL) if a size of zero was specified;
  43. * check for integer overflow of the field width, precision, and return
  44. * values and during the floating point conversion; use the OUTCHAR() macro
  45. * instead of a function for better performance; provide asprintf(3) and
  46. * vasprintf(3) functions; add new test cases. The replacement functions
  47. * have been renamed to use an "rpl_" prefix, the function calls in the
  48. * main project (and in this file) must be redefined accordingly for each
  49. * replacement function which is needed (by using Autoconf or other means).
  50. * Various other minor improvements have been applied and the coding style
  51. * was cleaned up for consistency.
  52. *
  53. * 2007-07-23 Holger Weiss <holger@jhweiss.de> for Mutt 1.5.13:
  54. *
  55. * C99 compliant snprintf(3) and vsnprintf(3) functions return the number
  56. * of characters that would have been written to a sufficiently sized
  57. * buffer (excluding the '\0'). The original code simply returned the
  58. * length of the resulting output string, so that's been fixed.
  59. *
  60. * 1998-03-05 Michael Elkins <me@mutt.org> for Mutt 0.90.8:
  61. *
  62. * The original code assumed that both snprintf(3) and vsnprintf(3) were
  63. * missing. Some systems only have snprintf(3) but not vsnprintf(3), so
  64. * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
  65. *
  66. * 1998-01-27 Thomas Roessler <roessler@does-not-exist.org> for Mutt 0.89i:
  67. *
  68. * The PGP code was using unsigned hexadecimal formats. Unfortunately,
  69. * unsigned formats simply didn't work.
  70. *
  71. * 1997-10-22 Brandon Long <blong@fiction.net> for Mutt 0.87.1:
  72. *
  73. * Ok, added some minimal floating point support, which means this probably
  74. * requires libm on most operating systems. Don't yet support the exponent
  75. * (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just
  76. * wasn't being exercised in ways which showed it, so that's been fixed.
  77. * Also, formatted the code to Mutt conventions, and removed dead code left
  78. * over from the original. Also, there is now a builtin-test, run with:
  79. * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf
  80. *
  81. * 2996-09-15 Brandon Long <blong@fiction.net> for Mutt 0.43:
  82. *
  83. * This was ugly. It is still ugly. I opted out of floating point
  84. * numbers, but the formatter understands just about everything from the
  85. * normal C string format, at least as far as I can tell from the Solaris
  86. * 2.5 printf(3S) man page.
  87. */
  88. /*
  89. * ToDo
  90. *
  91. * - Add wide character support.
  92. * - Add support for "%a" and "%A" conversions.
  93. * - Create test routines which predefine the expected results. Our test cases
  94. * usually expose bugs in system implementations rather than in ours :-)
  95. */
  96. /*
  97. * Usage
  98. *
  99. * 1) The following preprocessor macros should be defined to 1 if the feature or
  100. * file in question is available on the target system (by using Autoconf or
  101. * other means), though basic functionality should be available as long as
  102. * HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly:
  103. *
  104. * HAVE_VSNPRINTF
  105. * HAVE_SNPRINTF
  106. * HAVE_VASPRINTF
  107. * HAVE_ASPRINTF
  108. * HAVE_STDARG_H
  109. * HAVE_STDDEF_H
  110. * HAVE_STDINT_H
  111. * HAVE_STDLIB_H
  112. * HAVE_FLOAT_H
  113. * HAVE_INTTYPES_H
  114. * HAVE_LOCALE_H
  115. * HAVE_LOCALECONV
  116. * HAVE_LCONV_DECIMAL_POINT
  117. * HAVE_LCONV_THOUSANDS_SEP
  118. * HAVE_LONG_DOUBLE
  119. * HAVE_LONG_LONG_INT
  120. * HAVE_UNSIGNED_LONG_LONG_INT
  121. * HAVE_INTMAX_T
  122. * HAVE_UINTMAX_T
  123. * HAVE_UINTPTR_T
  124. * HAVE_PTRDIFF_T
  125. * HAVE_VA_COPY
  126. * HAVE___VA_COPY
  127. *
  128. * 2) The calls to the functions which should be replaced must be redefined
  129. * throughout the project files (by using Autoconf or other means):
  130. *
  131. * #define vsnprintf rpl_vsnprintf
  132. * #define snprintf rpl_snprintf
  133. * #define vasprintf rpl_vasprintf
  134. * #define asprintf rpl_asprintf
  135. *
  136. * 3) The required replacement functions should be declared in some header file
  137. * included throughout the project files:
  138. *
  139. * #if HAVE_CONFIG_H
  140. * #include <config.h>
  141. * #endif
  142. * #if HAVE_STDARG_H
  143. * #include <stdarg.h>
  144. * #if !HAVE_VSNPRINTF
  145. * int rpl_vsnprintf(char *, size_t, const char *, va_list);
  146. * #endif
  147. * #if !HAVE_SNPRINTF
  148. * int rpl_snprintf(char *, size_t, const char *, ...);
  149. * #endif
  150. * #if !HAVE_VASPRINTF
  151. * int rpl_vasprintf(char **, const char *, va_list);
  152. * #endif
  153. * #if !HAVE_ASPRINTF
  154. * int rpl_asprintf(char **, const char *, ...);
  155. * #endif
  156. * #endif
  157. *
  158. * Autoconf macros for handling step 1 and step 2 are available at
  159. * <http://www.jhweiss.de/software/snprintf.html>.
  160. */
  161. #if HAVE_CONFIG_H
  162. #include "snp_config.h"
  163. #endif /* HAVE_CONFIG_H */
  164. #if TEST_SNPRINTF
  165. #include <math.h> /* For pow(3), NAN, and INFINITY. */
  166. #include <string.h> /* For strcmp(3). */
  167. #if defined(__NetBSD__) || \
  168. defined(__FreeBSD__) || \
  169. defined(__OpenBSD__) || \
  170. defined(__NeXT__) || \
  171. defined(__bsd__)
  172. #define OS_BSD 1
  173. #elif defined(sgi) || defined(__sgi)
  174. #ifndef __c99
  175. #define __c99 /* Force C99 mode to get <stdint.h> included on IRIX 6.5.30. */
  176. #endif /* !defined(__c99) */
  177. #define OS_IRIX 1
  178. #define OS_SYSV 1
  179. #elif defined(__svr4__)
  180. #define OS_SYSV 1
  181. #elif defined(__linux__)
  182. #define OS_LINUX 1
  183. #endif /* defined(__NetBSD__) || defined(__FreeBSD__) || [...] */
  184. #if HAVE_CONFIG_H /* Undefine definitions possibly done in config.h. */
  185. #ifdef HAVE_SNPRINTF
  186. #undef HAVE_SNPRINTF
  187. #endif /* defined(HAVE_SNPRINTF) */
  188. #ifdef HAVE_VSNPRINTF
  189. #undef HAVE_VSNPRINTF
  190. #endif /* defined(HAVE_VSNPRINTF) */
  191. #ifdef HAVE_ASPRINTF
  192. #undef HAVE_ASPRINTF
  193. #endif /* defined(HAVE_ASPRINTF) */
  194. #ifdef HAVE_VASPRINTF
  195. #undef HAVE_VASPRINTF
  196. #endif /* defined(HAVE_VASPRINTF) */
  197. #ifdef snprintf
  198. #undef snprintf
  199. #endif /* defined(snprintf) */
  200. #ifdef vsnprintf
  201. #undef vsnprintf
  202. #endif /* defined(vsnprintf) */
  203. #ifdef asprintf
  204. #undef asprintf
  205. #endif /* defined(asprintf) */
  206. #ifdef vasprintf
  207. #undef vasprintf
  208. #endif /* defined(vasprintf) */
  209. #else /* By default, we assume a modern system for testing. */
  210. #ifndef HAVE_STDARG_H
  211. #define HAVE_STDARG_H 1
  212. #endif /* HAVE_STDARG_H */
  213. #ifndef HAVE_STDDEF_H
  214. #define HAVE_STDDEF_H 1
  215. #endif /* HAVE_STDDEF_H */
  216. #ifndef HAVE_STDINT_H
  217. #define HAVE_STDINT_H 1
  218. #endif /* HAVE_STDINT_H */
  219. #ifndef HAVE_STDLIB_H
  220. #define HAVE_STDLIB_H 1
  221. #endif /* HAVE_STDLIB_H */
  222. #ifndef HAVE_FLOAT_H
  223. #define HAVE_FLOAT_H 1
  224. #endif /* HAVE_FLOAT_H */
  225. #ifndef HAVE_INTTYPES_H
  226. #define HAVE_INTTYPES_H 1
  227. #endif /* HAVE_INTTYPES_H */
  228. #ifndef HAVE_LOCALE_H
  229. #define HAVE_LOCALE_H 1
  230. #endif /* HAVE_LOCALE_H */
  231. #ifndef HAVE_LOCALECONV
  232. #define HAVE_LOCALECONV 1
  233. #endif /* !defined(HAVE_LOCALECONV) */
  234. #ifndef HAVE_LCONV_DECIMAL_POINT
  235. #define HAVE_LCONV_DECIMAL_POINT 1
  236. #endif /* HAVE_LCONV_DECIMAL_POINT */
  237. #ifndef HAVE_LCONV_THOUSANDS_SEP
  238. #define HAVE_LCONV_THOUSANDS_SEP 1
  239. #endif /* HAVE_LCONV_THOUSANDS_SEP */
  240. #ifndef HAVE_LONG_DOUBLE
  241. #define HAVE_LONG_DOUBLE 1
  242. #endif /* !defined(HAVE_LONG_DOUBLE) */
  243. #ifndef HAVE_LONG_LONG_INT
  244. #define HAVE_LONG_LONG_INT 1
  245. #endif /* !defined(HAVE_LONG_LONG_INT) */
  246. #ifndef HAVE_UNSIGNED_LONG_LONG_INT
  247. #define HAVE_UNSIGNED_LONG_LONG_INT 1
  248. #endif /* !defined(HAVE_UNSIGNED_LONG_LONG_INT) */
  249. #ifndef HAVE_INTMAX_T
  250. #define HAVE_INTMAX_T 1
  251. #endif /* !defined(HAVE_INTMAX_T) */
  252. #ifndef HAVE_UINTMAX_T
  253. #define HAVE_UINTMAX_T 1
  254. #endif /* !defined(HAVE_UINTMAX_T) */
  255. #ifndef HAVE_UINTPTR_T
  256. #define HAVE_UINTPTR_T 1
  257. #endif /* !defined(HAVE_UINTPTR_T) */
  258. #ifndef HAVE_PTRDIFF_T
  259. #define HAVE_PTRDIFF_T 1
  260. #endif /* !defined(HAVE_PTRDIFF_T) */
  261. #ifndef HAVE_VA_COPY
  262. #define HAVE_VA_COPY 1
  263. #endif /* !defined(HAVE_VA_COPY) */
  264. #ifndef HAVE___VA_COPY
  265. #define HAVE___VA_COPY 1
  266. #endif /* !defined(HAVE___VA_COPY) */
  267. #endif /* HAVE_CONFIG_H */
  268. #define snprintf rpl_snprintf
  269. #define vsnprintf rpl_vsnprintf
  270. #define asprintf rpl_asprintf
  271. #define vasprintf rpl_vasprintf
  272. #endif /* TEST_SNPRINTF */
  273. #if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF
  274. #include <stdio.h> /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */
  275. #ifdef VA_START
  276. #undef VA_START
  277. #endif /* defined(VA_START) */
  278. #ifdef VA_SHIFT
  279. #undef VA_SHIFT
  280. #endif /* defined(VA_SHIFT) */
  281. #if HAVE_STDARG_H
  282. #include <stdarg.h>
  283. #define VA_START(ap, last) va_start(ap, last)
  284. #define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */
  285. #else /* Assume <varargs.h> is available. */
  286. #include <varargs.h>
  287. #define VA_START(ap, last) va_start(ap) /* "last" is ignored. */
  288. #define VA_SHIFT(ap, value, type) value = va_arg(ap, type)
  289. #endif /* HAVE_STDARG_H */
  290. #if !HAVE_VASPRINTF
  291. #if HAVE_STDLIB_H
  292. #include <stdlib.h> /* For malloc(3). */
  293. #endif /* HAVE_STDLIB_H */
  294. #ifdef VA_COPY
  295. #undef VA_COPY
  296. #endif /* defined(VA_COPY) */
  297. #ifdef VA_END_COPY
  298. #undef VA_END_COPY
  299. #endif /* defined(VA_END_COPY) */
  300. #if HAVE_VA_COPY
  301. #define VA_COPY(dest, src) va_copy(dest, src)
  302. #define VA_END_COPY(ap) va_end(ap)
  303. #elif HAVE___VA_COPY
  304. #define VA_COPY(dest, src) __va_copy(dest, src)
  305. #define VA_END_COPY(ap) va_end(ap)
  306. #else
  307. #define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list))
  308. #define VA_END_COPY(ap) /* No-op. */
  309. #define NEED_MYMEMCPY 1
  310. static void *mymemcpy(void *, void *, size_t);
  311. #endif /* HAVE_VA_COPY */
  312. #endif /* !HAVE_VASPRINTF */
  313. #if !HAVE_VSNPRINTF
  314. #include <errno.h> /* For ERANGE and errno. */
  315. #include <limits.h> /* For *_MAX. */
  316. #if HAVE_FLOAT_H
  317. #include <float.h> /* For *DBL_{MIN,MAX}_10_EXP. */
  318. #endif /* HAVE_FLOAT_H */
  319. #if HAVE_INTTYPES_H
  320. #include <inttypes.h> /* For intmax_t (if not defined in <stdint.h>). */
  321. #endif /* HAVE_INTTYPES_H */
  322. #if HAVE_LOCALE_H
  323. #include <locale.h> /* For localeconv(3). */
  324. #endif /* HAVE_LOCALE_H */
  325. #if HAVE_STDDEF_H
  326. #include <stddef.h> /* For ptrdiff_t. */
  327. #endif /* HAVE_STDDEF_H */
  328. #if HAVE_STDINT_H
  329. #include <stdint.h> /* For intmax_t. */
  330. #endif /* HAVE_STDINT_H */
  331. /* Support for unsigned long long int. We may also need ULLONG_MAX. */
  332. #ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */
  333. #ifdef UINT_MAX
  334. #define ULONG_MAX UINT_MAX
  335. #else
  336. #define ULONG_MAX INT_MAX
  337. #endif /* defined(UINT_MAX) */
  338. #endif /* !defined(ULONG_MAX) */
  339. #ifdef ULLONG
  340. #undef ULLONG
  341. #endif /* defined(ULLONG) */
  342. #if HAVE_UNSIGNED_LONG_LONG_INT
  343. #define ULLONG unsigned long long int
  344. #ifndef ULLONG_MAX
  345. #define ULLONG_MAX ULONG_MAX
  346. #endif /* !defined(ULLONG_MAX) */
  347. #else
  348. #define ULLONG unsigned long int
  349. #ifdef ULLONG_MAX
  350. #undef ULLONG_MAX
  351. #endif /* defined(ULLONG_MAX) */
  352. #define ULLONG_MAX ULONG_MAX
  353. #endif /* HAVE_LONG_LONG_INT */
  354. /* Support for uintmax_t. We also need UINTMAX_MAX. */
  355. #ifdef UINTMAX_T
  356. #undef UINTMAX_T
  357. #endif /* defined(UINTMAX_T) */
  358. #if HAVE_UINTMAX_T || defined(uintmax_t)
  359. #define UINTMAX_T uintmax_t
  360. #ifndef UINTMAX_MAX
  361. #define UINTMAX_MAX ULLONG_MAX
  362. #endif /* !defined(UINTMAX_MAX) */
  363. #else
  364. #define UINTMAX_T ULLONG
  365. #ifdef UINTMAX_MAX
  366. #undef UINTMAX_MAX
  367. #endif /* defined(UINTMAX_MAX) */
  368. #define UINTMAX_MAX ULLONG_MAX
  369. #endif /* HAVE_UINTMAX_T || defined(uintmax_t) */
  370. /* Support for long double. */
  371. #ifndef LDOUBLE
  372. #if HAVE_LONG_DOUBLE
  373. #define LDOUBLE long double
  374. #define LDOUBLE_MIN_10_EXP LDBL_MIN_10_EXP
  375. #define LDOUBLE_MAX_10_EXP LDBL_MAX_10_EXP
  376. #else
  377. #define LDOUBLE double
  378. #define LDOUBLE_MIN_10_EXP DBL_MIN_10_EXP
  379. #define LDOUBLE_MAX_10_EXP DBL_MAX_10_EXP
  380. #endif /* HAVE_LONG_DOUBLE */
  381. #endif /* !defined(LDOUBLE) */
  382. /* Support for long long int. */
  383. #ifndef LLONG
  384. #if HAVE_LONG_LONG_INT
  385. #define LLONG long long int
  386. #else
  387. #define LLONG long int
  388. #endif /* HAVE_LONG_LONG_INT */
  389. #endif /* !defined(LLONG) */
  390. /* Support for intmax_t. */
  391. #ifndef INTMAX_T
  392. #if HAVE_INTMAX_T || defined(intmax_t)
  393. #define INTMAX_T intmax_t
  394. #else
  395. #define INTMAX_T LLONG
  396. #endif /* HAVE_INTMAX_T || defined(intmax_t) */
  397. #endif /* !defined(INTMAX_T) */
  398. /* Support for uintptr_t. */
  399. #ifndef UINTPTR_T
  400. #if HAVE_UINTPTR_T || defined(uintptr_t)
  401. #define UINTPTR_T uintptr_t
  402. #else
  403. #define UINTPTR_T unsigned long int
  404. #endif /* HAVE_UINTPTR_T || defined(uintptr_t) */
  405. #endif /* !defined(UINTPTR_T) */
  406. /* Support for ptrdiff_t. */
  407. #ifndef PTRDIFF_T
  408. #if HAVE_PTRDIFF_T || defined(ptrdiff_t)
  409. #define PTRDIFF_T ptrdiff_t
  410. #else
  411. #define PTRDIFF_T long int
  412. #endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */
  413. #endif /* !defined(PTRDIFF_T) */
  414. /*
  415. * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99:
  416. * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an
  417. * unsigned type if necessary. This should work just fine in practice.
  418. */
  419. #ifndef UPTRDIFF_T
  420. #define UPTRDIFF_T PTRDIFF_T
  421. #endif /* !defined(UPTRDIFF_T) */
  422. /*
  423. * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7).
  424. * However, we'll simply use size_t and convert it to a signed type if
  425. * necessary. This should work just fine in practice.
  426. */
  427. #ifndef SSIZE_T
  428. #define SSIZE_T size_t
  429. #endif /* !defined(SSIZE_T) */
  430. /* Either ERANGE or E2BIG should be available everywhere. */
  431. #ifndef ERANGE
  432. #define ERANGE E2BIG
  433. #endif /* !defined(ERANGE) */
  434. #ifndef EOVERFLOW
  435. #define EOVERFLOW ERANGE
  436. #endif /* !defined(EOVERFLOW) */
  437. /*
  438. * Buffer size to hold the octal string representation of UINT128_MAX without
  439. * nul-termination ("3777777777777777777777777777777777777777777").
  440. */
  441. #ifdef MAX_CONVERT_LENGTH
  442. #undef MAX_CONVERT_LENGTH
  443. #endif /* defined(MAX_CONVERT_LENGTH) */
  444. #define MAX_CONVERT_LENGTH 43
  445. /* Format read states. */
  446. #define PRINT_S_DEFAULT 0
  447. #define PRINT_S_FLAGS 1
  448. #define PRINT_S_WIDTH 2
  449. #define PRINT_S_DOT 3
  450. #define PRINT_S_PRECISION 4
  451. #define PRINT_S_MOD 5
  452. #define PRINT_S_CONV 6
  453. /* Format flags. */
  454. #define PRINT_F_MINUS (1 << 0)
  455. #define PRINT_F_PLUS (1 << 1)
  456. #define PRINT_F_SPACE (1 << 2)
  457. #define PRINT_F_NUM (1 << 3)
  458. #define PRINT_F_ZERO (1 << 4)
  459. #define PRINT_F_QUOTE (1 << 5)
  460. #define PRINT_F_UP (1 << 6)
  461. #define PRINT_F_UNSIGNED (1 << 7)
  462. #define PRINT_F_TYPE_G (1 << 8)
  463. #define PRINT_F_TYPE_E (1 << 9)
  464. /* Conversion flags. */
  465. #define PRINT_C_CHAR 1
  466. #define PRINT_C_SHORT 2
  467. #define PRINT_C_LONG 3
  468. #define PRINT_C_LLONG 4
  469. #define PRINT_C_LDOUBLE 5
  470. #define PRINT_C_SIZE 6
  471. #define PRINT_C_PTRDIFF 7
  472. #define PRINT_C_INTMAX 8
  473. #ifndef MAX
  474. #define MAX(x, y) ((x >= y) ? x : y)
  475. #endif /* !defined(MAX) */
  476. #ifndef CHARTOINT
  477. #define CHARTOINT(ch) (ch - '0')
  478. #endif /* !defined(CHARTOINT) */
  479. #ifndef ISDIGIT
  480. #define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9')
  481. #endif /* !defined(ISDIGIT) */
  482. #ifndef ISNAN
  483. #define ISNAN(x) (x != x)
  484. #endif /* !defined(ISNAN) */
  485. #ifndef ISINF
  486. #define ISINF(x) ((x < -1 || x > 1) && x + x == x)
  487. #endif /* !defined(ISINF) */
  488. #ifdef OUTCHAR
  489. #undef OUTCHAR
  490. #endif /* defined(OUTCHAR) */
  491. #define OUTCHAR(str, len, size, ch) \
  492. do { \
  493. if (len + 1 < size) \
  494. str[len] = ch; \
  495. (len)++; \
  496. } while (/* CONSTCOND */ 0)
  497. static void fmtstr(char *, size_t *, size_t, const char *, int, int, int);
  498. static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int);
  499. static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *);
  500. static void printsep(char *, size_t *, size_t);
  501. static int getnumsep(int);
  502. static int getexponent(LDOUBLE);
  503. static int convert(UINTMAX_T, char *, size_t, int, int);
  504. static UINTMAX_T cast(LDOUBLE);
  505. static UINTMAX_T myround(LDOUBLE);
  506. static LDOUBLE mypow10(int);
  507. extern int errno;
  508. int
  509. rpl_vsnprintf(char *str, size_t size, const char *format, va_list args)
  510. {
  511. LDOUBLE fvalue;
  512. INTMAX_T value;
  513. unsigned char cvalue;
  514. const char *strvalue;
  515. INTMAX_T *intmaxptr;
  516. PTRDIFF_T *ptrdiffptr;
  517. SSIZE_T *sizeptr;
  518. LLONG *llongptr;
  519. long int *longptr;
  520. int *intptr;
  521. short int *shortptr;
  522. signed char *charptr;
  523. size_t len = 0;
  524. int overflow = 0;
  525. int base = 0;
  526. int cflags = 0;
  527. int flags = 0;
  528. int width = 0;
  529. int precision = -1;
  530. int state = PRINT_S_DEFAULT;
  531. char ch = *format++;
  532. /*
  533. * C99 says: "If `n' is zero, nothing is written, and `s' may be a null
  534. * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer
  535. * even if a size larger than zero was specified. At least NetBSD's
  536. * snprintf(3) does the same, as well as other versions of this file.
  537. * (Though some of these versions will write to a non-NULL buffer even
  538. * if a size of zero was specified, which violates the standard.)
  539. */
  540. if (str == NULL && size != 0)
  541. size = 0;
  542. while (ch != '\0')
  543. switch (state) {
  544. case PRINT_S_DEFAULT:
  545. if (ch == '%')
  546. state = PRINT_S_FLAGS;
  547. else
  548. OUTCHAR(str, len, size, ch);
  549. ch = *format++;
  550. break;
  551. case PRINT_S_FLAGS:
  552. switch (ch) {
  553. case '-':
  554. flags |= PRINT_F_MINUS;
  555. ch = *format++;
  556. break;
  557. case '+':
  558. flags |= PRINT_F_PLUS;
  559. ch = *format++;
  560. break;
  561. case ' ':
  562. flags |= PRINT_F_SPACE;
  563. ch = *format++;
  564. break;
  565. case '#':
  566. flags |= PRINT_F_NUM;
  567. ch = *format++;
  568. break;
  569. case '0':
  570. flags |= PRINT_F_ZERO;
  571. ch = *format++;
  572. break;
  573. case '\'': /* SUSv2 flag (not in C99). */
  574. flags |= PRINT_F_QUOTE;
  575. ch = *format++;
  576. break;
  577. default:
  578. state = PRINT_S_WIDTH;
  579. break;
  580. }
  581. break;
  582. case PRINT_S_WIDTH:
  583. if (ISDIGIT(ch)) {
  584. ch = CHARTOINT(ch);
  585. if (width > (INT_MAX - ch) / 10) {
  586. overflow = 1;
  587. goto out;
  588. }
  589. width = 10 * width + ch;
  590. ch = *format++;
  591. } else if (ch == '*') {
  592. /*
  593. * C99 says: "A negative field width argument is
  594. * taken as a `-' flag followed by a positive
  595. * field width." (7.19.6.1, 5)
  596. */
  597. if ((width = va_arg(args, int)) < 0) {
  598. flags |= PRINT_F_MINUS;
  599. width = -width;
  600. }
  601. ch = *format++;
  602. state = PRINT_S_DOT;
  603. } else
  604. state = PRINT_S_DOT;
  605. break;
  606. case PRINT_S_DOT:
  607. if (ch == '.') {
  608. state = PRINT_S_PRECISION;
  609. ch = *format++;
  610. } else
  611. state = PRINT_S_MOD;
  612. break;
  613. case PRINT_S_PRECISION:
  614. if (precision == -1)
  615. precision = 0;
  616. if (ISDIGIT(ch)) {
  617. ch = CHARTOINT(ch);
  618. if (precision > (INT_MAX - ch) / 10) {
  619. overflow = 1;
  620. goto out;
  621. }
  622. precision = 10 * precision + ch;
  623. ch = *format++;
  624. } else if (ch == '*') {
  625. /*
  626. * C99 says: "A negative precision argument is
  627. * taken as if the precision were omitted."
  628. * (7.19.6.1, 5)
  629. */
  630. if ((precision = va_arg(args, int)) < 0)
  631. precision = -1;
  632. ch = *format++;
  633. state = PRINT_S_MOD;
  634. } else
  635. state = PRINT_S_MOD;
  636. break;
  637. case PRINT_S_MOD:
  638. switch (ch) {
  639. case 'h':
  640. ch = *format++;
  641. if (ch == 'h') { /* It's a char. */
  642. ch = *format++;
  643. cflags = PRINT_C_CHAR;
  644. } else
  645. cflags = PRINT_C_SHORT;
  646. break;
  647. case 'l':
  648. ch = *format++;
  649. if (ch == 'l') { /* It's a long long. */
  650. ch = *format++;
  651. cflags = PRINT_C_LLONG;
  652. } else
  653. cflags = PRINT_C_LONG;
  654. break;
  655. case 'L':
  656. cflags = PRINT_C_LDOUBLE;
  657. ch = *format++;
  658. break;
  659. case 'j':
  660. cflags = PRINT_C_INTMAX;
  661. ch = *format++;
  662. break;
  663. case 't':
  664. cflags = PRINT_C_PTRDIFF;
  665. ch = *format++;
  666. break;
  667. case 'z':
  668. cflags = PRINT_C_SIZE;
  669. ch = *format++;
  670. break;
  671. }
  672. state = PRINT_S_CONV;
  673. break;
  674. case PRINT_S_CONV:
  675. switch (ch) {
  676. case 'd':
  677. /* FALLTHROUGH */
  678. case 'i':
  679. switch (cflags) {
  680. case PRINT_C_CHAR:
  681. value = (signed char)va_arg(args, int);
  682. break;
  683. case PRINT_C_SHORT:
  684. value = (short int)va_arg(args, int);
  685. break;
  686. case PRINT_C_LONG:
  687. value = va_arg(args, long int);
  688. break;
  689. case PRINT_C_LLONG:
  690. value = va_arg(args, LLONG);
  691. break;
  692. case PRINT_C_SIZE:
  693. value = va_arg(args, SSIZE_T);
  694. break;
  695. case PRINT_C_INTMAX:
  696. value = va_arg(args, INTMAX_T);
  697. break;
  698. case PRINT_C_PTRDIFF:
  699. value = va_arg(args, PTRDIFF_T);
  700. break;
  701. default:
  702. value = va_arg(args, int);
  703. break;
  704. }
  705. fmtint(str, &len, size, value, 10, width,
  706. precision, flags);
  707. break;
  708. case 'X':
  709. flags |= PRINT_F_UP;
  710. /* FALLTHROUGH */
  711. case 'x':
  712. base = 16;
  713. /* FALLTHROUGH */
  714. case 'o':
  715. if (base == 0)
  716. base = 8;
  717. /* FALLTHROUGH */
  718. case 'u':
  719. if (base == 0)
  720. base = 10;
  721. flags |= PRINT_F_UNSIGNED;
  722. switch (cflags) {
  723. case PRINT_C_CHAR:
  724. value = (unsigned char)va_arg(args,
  725. unsigned int);
  726. break;
  727. case PRINT_C_SHORT:
  728. value = (unsigned short int)va_arg(args,
  729. unsigned int);
  730. break;
  731. case PRINT_C_LONG:
  732. value = va_arg(args, unsigned long int);
  733. break;
  734. case PRINT_C_LLONG:
  735. value = va_arg(args, ULLONG);
  736. break;
  737. case PRINT_C_SIZE:
  738. value = va_arg(args, size_t);
  739. break;
  740. case PRINT_C_INTMAX:
  741. value = va_arg(args, UINTMAX_T);
  742. break;
  743. case PRINT_C_PTRDIFF:
  744. value = va_arg(args, UPTRDIFF_T);
  745. break;
  746. default:
  747. value = va_arg(args, unsigned int);
  748. break;
  749. }
  750. fmtint(str, &len, size, value, base, width,
  751. precision, flags);
  752. break;
  753. case 'A':
  754. /* Not yet supported, we'll use "%F". */
  755. /* FALLTHROUGH */
  756. case 'E':
  757. if (ch == 'E')
  758. flags |= PRINT_F_TYPE_E;
  759. /* FALLTHROUGH */
  760. case 'G':
  761. if (ch == 'G')
  762. flags |= PRINT_F_TYPE_G;
  763. /* FALLTHROUGH */
  764. case 'F':
  765. flags |= PRINT_F_UP;
  766. /* FALLTHROUGH */
  767. case 'a':
  768. /* Not yet supported, we'll use "%f". */
  769. /* FALLTHROUGH */
  770. case 'e':
  771. if (ch == 'e')
  772. flags |= PRINT_F_TYPE_E;
  773. /* FALLTHROUGH */
  774. case 'g':
  775. if (ch == 'g')
  776. flags |= PRINT_F_TYPE_G;
  777. /* FALLTHROUGH */
  778. case 'f':
  779. if (cflags == PRINT_C_LDOUBLE)
  780. fvalue = va_arg(args, LDOUBLE);
  781. else
  782. fvalue = va_arg(args, double);
  783. fmtflt(str, &len, size, fvalue, width,
  784. precision, flags, &overflow);
  785. if (overflow)
  786. goto out;
  787. break;
  788. case 'c':
  789. cvalue = va_arg(args, int);
  790. OUTCHAR(str, len, size, cvalue);
  791. break;
  792. case 's':
  793. strvalue = va_arg(args, char *);
  794. fmtstr(str, &len, size, strvalue, width,
  795. precision, flags);
  796. break;
  797. case 'p':
  798. /*
  799. * C99 says: "The value of the pointer is
  800. * converted to a sequence of printing
  801. * characters, in an implementation-defined
  802. * manner." (C99: 7.19.6.1, 8)
  803. */
  804. if ((strvalue = va_arg(args, void *)) == NULL)
  805. /*
  806. * We use the glibc format. BSD prints
  807. * "0x0", SysV "0".
  808. */
  809. fmtstr(str, &len, size, "(nil)", width,
  810. -1, flags);
  811. else {
  812. /*
  813. * We use the BSD/glibc format. SysV
  814. * omits the "0x" prefix (which we emit
  815. * using the PRINT_F_NUM flag).
  816. */
  817. flags |= PRINT_F_NUM;
  818. flags |= PRINT_F_UNSIGNED;
  819. fmtint(str, &len, size,
  820. (UINTPTR_T)strvalue, 16, width,
  821. precision, flags);
  822. }
  823. break;
  824. case 'n':
  825. switch (cflags) {
  826. case PRINT_C_CHAR:
  827. charptr = va_arg(args, signed char *);
  828. *charptr = len;
  829. break;
  830. case PRINT_C_SHORT:
  831. shortptr = va_arg(args, short int *);
  832. *shortptr = len;
  833. break;
  834. case PRINT_C_LONG:
  835. longptr = va_arg(args, long int *);
  836. *longptr = len;
  837. break;
  838. case PRINT_C_LLONG:
  839. llongptr = va_arg(args, LLONG *);
  840. *llongptr = len;
  841. break;
  842. case PRINT_C_SIZE:
  843. /*
  844. * C99 says that with the "z" length
  845. * modifier, "a following `n' conversion
  846. * specifier applies to a pointer to a
  847. * signed integer type corresponding to
  848. * size_t argument." (7.19.6.1, 7)
  849. */
  850. sizeptr = va_arg(args, SSIZE_T *);
  851. *sizeptr = len;
  852. break;
  853. case PRINT_C_INTMAX:
  854. intmaxptr = va_arg(args, INTMAX_T *);
  855. *intmaxptr = len;
  856. break;
  857. case PRINT_C_PTRDIFF:
  858. ptrdiffptr = va_arg(args, PTRDIFF_T *);
  859. *ptrdiffptr = len;
  860. break;
  861. default:
  862. intptr = va_arg(args, int *);
  863. *intptr = len;
  864. break;
  865. }
  866. break;
  867. case '%': /* Print a "%" character verbatim. */
  868. OUTCHAR(str, len, size, ch);
  869. break;
  870. default: /* Skip other characters. */
  871. break;
  872. }
  873. ch = *format++;
  874. state = PRINT_S_DEFAULT;
  875. base = cflags = flags = width = 0;
  876. precision = -1;
  877. break;
  878. }
  879. out:
  880. if (len < size)
  881. str[len] = '\0';
  882. else if (size > 0)
  883. str[size - 1] = '\0';
  884. if (overflow || len > INT_MAX) {
  885. errno = EOVERFLOW;
  886. return -1;
  887. }
  888. return (int)len;
  889. }
  890. static void
  891. fmtstr(char *str, size_t *len, size_t size, const char *value, int width,
  892. int precision, int flags)
  893. {
  894. int padlen, strln; /* Amount to pad. */
  895. int noprecision = (precision == -1);
  896. if (value == NULL) /* We're forgiving. */
  897. value = "(null)";
  898. /* If a precision was specified, don't read the string past it. */
  899. for (strln = 0; value[strln] != '\0' &&
  900. (noprecision || strln < precision); strln++)
  901. continue;
  902. if ((padlen = width - strln) < 0)
  903. padlen = 0;
  904. if (flags & PRINT_F_MINUS) /* Left justify. */
  905. padlen = -padlen;
  906. while (padlen > 0) { /* Leading spaces. */
  907. OUTCHAR(str, *len, size, ' ');
  908. padlen--;
  909. }
  910. while (*value != '\0' && (noprecision || precision-- > 0)) {
  911. OUTCHAR(str, *len, size, *value);
  912. value++;
  913. }
  914. while (padlen < 0) { /* Trailing spaces. */
  915. OUTCHAR(str, *len, size, ' ');
  916. padlen++;
  917. }
  918. }
  919. static void
  920. fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width,
  921. int precision, int flags)
  922. {
  923. UINTMAX_T uvalue;
  924. char iconvert[MAX_CONVERT_LENGTH];
  925. char sign = 0;
  926. char hexprefix = 0;
  927. int spadlen = 0; /* Amount to space pad. */
  928. int zpadlen = 0; /* Amount to zero pad. */
  929. int pos;
  930. int separators = (flags & PRINT_F_QUOTE);
  931. int noprecision = (precision == -1);
  932. if (flags & PRINT_F_UNSIGNED)
  933. uvalue = value;
  934. else {
  935. uvalue = (value >= 0) ? value : -value;
  936. if (value < 0)
  937. sign = '-';
  938. else if (flags & PRINT_F_PLUS) /* Do a sign. */
  939. sign = '+';
  940. else if (flags & PRINT_F_SPACE)
  941. sign = ' ';
  942. }
  943. pos = convert(uvalue, iconvert, sizeof(iconvert), base,
  944. flags & PRINT_F_UP);
  945. if (flags & PRINT_F_NUM && uvalue != 0) {
  946. /*
  947. * C99 says: "The result is converted to an `alternative form'.
  948. * For `o' conversion, it increases the precision, if and only
  949. * if necessary, to force the first digit of the result to be a
  950. * zero (if the value and precision are both 0, a single 0 is
  951. * printed). For `x' (or `X') conversion, a nonzero result has
  952. * `0x' (or `0X') prefixed to it." (7.19.6.1, 6)
  953. */
  954. switch (base) {
  955. case 8:
  956. if (precision <= pos)
  957. precision = pos + 1;
  958. break;
  959. case 16:
  960. hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x';
  961. break;
  962. }
  963. }
  964. if (separators) /* Get the number of group separators we'll print. */
  965. separators = getnumsep(pos);
  966. zpadlen = precision - pos - separators;
  967. spadlen = width /* Minimum field width. */
  968. - separators /* Number of separators. */
  969. - MAX(precision, pos) /* Number of integer digits. */
  970. - ((sign != 0) ? 1 : 0) /* Will we print a sign? */
  971. - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */
  972. if (zpadlen < 0)
  973. zpadlen = 0;
  974. if (spadlen < 0)
  975. spadlen = 0;
  976. /*
  977. * C99 says: "If the `0' and `-' flags both appear, the `0' flag is
  978. * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a
  979. * precision is specified, the `0' flag is ignored." (7.19.6.1, 6)
  980. */
  981. if (flags & PRINT_F_MINUS) /* Left justify. */
  982. spadlen = -spadlen;
  983. else if (flags & PRINT_F_ZERO && noprecision) {
  984. zpadlen += spadlen;
  985. spadlen = 0;
  986. }
  987. while (spadlen > 0) { /* Leading spaces. */
  988. OUTCHAR(str, *len, size, ' ');
  989. spadlen--;
  990. }
  991. if (sign != 0) /* Sign. */
  992. OUTCHAR(str, *len, size, sign);
  993. if (hexprefix != 0) { /* A "0x" or "0X" prefix. */
  994. OUTCHAR(str, *len, size, '0');
  995. OUTCHAR(str, *len, size, hexprefix);
  996. }
  997. while (zpadlen > 0) { /* Leading zeros. */
  998. OUTCHAR(str, *len, size, '0');
  999. zpadlen--;
  1000. }
  1001. while (pos > 0) { /* The actual digits. */
  1002. pos--;
  1003. OUTCHAR(str, *len, size, iconvert[pos]);
  1004. if (separators > 0 && pos > 0 && pos % 3 == 0)
  1005. printsep(str, len, size);
  1006. }
  1007. while (spadlen < 0) { /* Trailing spaces. */
  1008. OUTCHAR(str, *len, size, ' ');
  1009. spadlen++;
  1010. }
  1011. }
  1012. static void
  1013. fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width,
  1014. int precision, int flags, int *overflow)
  1015. {
  1016. LDOUBLE ufvalue;
  1017. UINTMAX_T intpart;
  1018. UINTMAX_T fracpart;
  1019. UINTMAX_T mask;
  1020. const char *infnan = NULL;
  1021. char iconvert[MAX_CONVERT_LENGTH];
  1022. char fconvert[MAX_CONVERT_LENGTH];
  1023. char econvert[5]; /* "e-300" (without nul-termination). */
  1024. char esign = 0;
  1025. char sign = 0;
  1026. int leadfraczeros = 0;
  1027. int exponent = 0;
  1028. int emitpoint = 0;
  1029. int omitzeros = 0;
  1030. int omitcount = 0;
  1031. int padlen = 0;
  1032. int epos = 0;
  1033. int fpos = 0;
  1034. int ipos = 0;
  1035. int separators = (flags & PRINT_F_QUOTE);
  1036. int estyle = (flags & PRINT_F_TYPE_E);
  1037. #if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT
  1038. struct lconv *lc = localeconv();
  1039. #endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */
  1040. /*
  1041. * AIX' man page says the default is 0, but C99 and at least Solaris'
  1042. * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX
  1043. * defaults to 6.
  1044. */
  1045. if (precision == -1)
  1046. precision = 6;
  1047. if (fvalue < 0.0)
  1048. sign = '-';
  1049. else if (flags & PRINT_F_PLUS) /* Do a sign. */
  1050. sign = '+';
  1051. else if (flags & PRINT_F_SPACE)
  1052. sign = ' ';
  1053. if (ISNAN(fvalue))
  1054. infnan = (flags & PRINT_F_UP) ? "NAN" : "nan";
  1055. else if (ISINF(fvalue))
  1056. infnan = (flags & PRINT_F_UP) ? "INF" : "inf";
  1057. if (infnan != NULL) {
  1058. if (sign != 0)
  1059. iconvert[ipos++] = sign;
  1060. while (*infnan != '\0')
  1061. iconvert[ipos++] = *infnan++;
  1062. fmtstr(str, len, size, iconvert, width, ipos, flags);
  1063. return;
  1064. }
  1065. /* "%e" (or "%E") or "%g" (or "%G") conversion. */
  1066. if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) {
  1067. if (flags & PRINT_F_TYPE_G) {
  1068. /*
  1069. * If the precision is zero, it is treated as one (cf.
  1070. * C99: 7.19.6.1, 8).
  1071. */
  1072. if (precision == 0)
  1073. precision = 1;
  1074. /*
  1075. * For "%g" (and "%G") conversions, the precision
  1076. * specifies the number of significant digits, which
  1077. * includes the digits in the integer part. The
  1078. * conversion will or will not be using "e-style" (like
  1079. * "%e" or "%E" conversions) depending on the precision
  1080. * and on the exponent. However, the exponent can be
  1081. * affected by rounding the converted value, so we'll
  1082. * leave this decision for later. Until then, we'll
  1083. * assume that we're going to do an "e-style" conversion
  1084. * (in order to get the exponent calculated). For
  1085. * "e-style", the precision must be decremented by one.
  1086. */
  1087. precision--;
  1088. /*
  1089. * For "%g" (and "%G") conversions, trailing zeros are
  1090. * removed from the fractional portion of the result
  1091. * unless the "#" flag was specified.
  1092. */
  1093. if (!(flags & PRINT_F_NUM))
  1094. omitzeros = 1;
  1095. }
  1096. exponent = getexponent(fvalue);
  1097. estyle = 1;
  1098. }
  1099. again:
  1100. /*
  1101. * Sorry, we only support 9, 19, or 38 digits (that is, the number of
  1102. * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value
  1103. * minus one) past the decimal point due to our conversion method.
  1104. */
  1105. switch (sizeof(UINTMAX_T)) {
  1106. case 16:
  1107. if (precision > 38)
  1108. precision = 38;
  1109. break;
  1110. case 8:
  1111. if (precision > 19)
  1112. precision = 19;
  1113. break;
  1114. default:
  1115. if (precision > 9)
  1116. precision = 9;
  1117. break;
  1118. }
  1119. ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue;
  1120. if (estyle) /* We want exactly one integer digit. */
  1121. ufvalue /= mypow10(exponent);
  1122. if ((intpart = cast(ufvalue)) == UINTMAX_MAX) {
  1123. *overflow = 1;
  1124. return;
  1125. }
  1126. /*
  1127. * Factor of ten with the number of digits needed for the fractional
  1128. * part. For example, if the precision is 3, the mask will be 1000.
  1129. */
  1130. mask = mypow10(precision);
  1131. /*
  1132. * We "cheat" by converting the fractional part to integer by
  1133. * multiplying by a factor of ten.
  1134. */
  1135. if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) {
  1136. /*
  1137. * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000
  1138. * (because precision = 3). Now, myround(1000 * 0.99962) will
  1139. * return 1000. So, the integer part must be incremented by one
  1140. * and the fractional part must be set to zero.
  1141. */
  1142. intpart++;
  1143. fracpart = 0;
  1144. if (estyle && intpart == 10) {
  1145. /*
  1146. * The value was rounded up to ten, but we only want one
  1147. * integer digit if using "e-style". So, the integer
  1148. * part must be set to one and the exponent must be
  1149. * incremented by one.
  1150. */
  1151. intpart = 1;
  1152. exponent++;
  1153. }
  1154. }
  1155. /*
  1156. * Now that we know the real exponent, we can check whether or not to
  1157. * use "e-style" for "%g" (and "%G") conversions. If we don't need
  1158. * "e-style", the precision must be adjusted and the integer and
  1159. * fractional parts must be recalculated from the original value.
  1160. *
  1161. * C99 says: "Let P equal the precision if nonzero, 6 if the precision
  1162. * is omitted, or 1 if the precision is zero. Then, if a conversion
  1163. * with style `E' would have an exponent of X:
  1164. *
  1165. * - if P > X >= -4, the conversion is with style `f' (or `F') and
  1166. * precision P - (X + 1).
  1167. *
  1168. * - otherwise, the conversion is with style `e' (or `E') and precision
  1169. * P - 1." (7.19.6.1, 8)
  1170. *
  1171. * Note that we had decremented the precision by one.
  1172. */
  1173. if (flags & PRINT_F_TYPE_G && estyle &&
  1174. precision + 1 > exponent && exponent >= -4) {
  1175. precision -= exponent;
  1176. estyle = 0;
  1177. goto again;
  1178. }
  1179. if (estyle) {
  1180. if (exponent < 0) {
  1181. exponent = -exponent;
  1182. esign = '-';
  1183. } else
  1184. esign = '+';
  1185. /*
  1186. * Convert the exponent. The sizeof(econvert) is 5. So, the
  1187. * econvert buffer can hold e.g. "e+999" and "e-999". We don't
  1188. * support an exponent which contains more than three digits.
  1189. * Therefore, the following stores are safe.
  1190. */
  1191. epos = convert(exponent, econvert, 3, 10, 0);
  1192. /*
  1193. * C99 says: "The exponent always contains at least two digits,
  1194. * and only as many more digits as necessary to represent the
  1195. * exponent." (7.19.6.1, 8)
  1196. */
  1197. if (epos == 1)
  1198. econvert[epos++] = '0';
  1199. econvert[epos++] = esign;
  1200. econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e';
  1201. }
  1202. /* Convert the integer part and the fractional part. */
  1203. ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0);
  1204. if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */
  1205. fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0);
  1206. leadfraczeros = precision - fpos;
  1207. if (omitzeros) {
  1208. if (fpos > 0) /* Omit trailing fractional part zeros. */
  1209. while (omitcount < fpos && fconvert[omitcount] == '0')
  1210. omitcount++;
  1211. else { /* The fractional part is zero, omit it completely. */
  1212. omitcount = precision;
  1213. leadfraczeros = 0;
  1214. }
  1215. precision -= omitcount;
  1216. }
  1217. /*
  1218. * Print a decimal point if either the fractional part is non-zero
  1219. * and/or the "#" flag was specified.
  1220. */
  1221. if (precision > 0 || flags & PRINT_F_NUM)
  1222. emitpoint = 1;
  1223. if (separators) /* Get the number of group separators we'll print. */
  1224. separators = getnumsep(ipos);
  1225. padlen = width /* Minimum field width. */
  1226. - ipos /* Number of integer digits. */
  1227. - epos /* Number of exponent characters. */
  1228. - precision /* Number of fractional digits. */
  1229. - separators /* Number of group separators. */
  1230. - (emitpoint ? 1 : 0) /* Will we print a decimal point? */
  1231. - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */
  1232. if (padlen < 0)
  1233. padlen = 0;
  1234. /*
  1235. * C99 says: "If the `0' and `-' flags both appear, the `0' flag is
  1236. * ignored." (7.19.6.1, 6)
  1237. */
  1238. if (flags & PRINT_F_MINUS) /* Left justifty. */
  1239. padlen = -padlen;
  1240. else if (flags & PRINT_F_ZERO && padlen > 0) {
  1241. if (sign != 0) { /* Sign. */
  1242. OUTCHAR(str, *len, size, sign);
  1243. sign = 0;
  1244. }
  1245. while (padlen > 0) { /* Leading zeros. */
  1246. OUTCHAR(str, *len, size, '0');
  1247. padlen--;
  1248. }
  1249. }
  1250. while (padlen > 0) { /* Leading spaces. */
  1251. OUTCHAR(str, *len, size, ' ');
  1252. padlen--;
  1253. }
  1254. if (sign != 0) /* Sign. */
  1255. OUTCHAR(str, *len, size, sign);
  1256. while (ipos > 0) { /* Integer part. */
  1257. ipos--;
  1258. OUTCHAR(str, *len, size, iconvert[ipos]);
  1259. if (separators > 0 && ipos > 0 && ipos % 3 == 0)
  1260. printsep(str, len, size);
  1261. }
  1262. if (emitpoint) { /* Decimal point. */
  1263. #if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT
  1264. if (lc->decimal_point != NULL && *lc->decimal_point != '\0')
  1265. OUTCHAR(str, *len, size, *lc->decimal_point);
  1266. else /* We'll always print some decimal point character. */
  1267. #endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */
  1268. OUTCHAR(str, *len, size, '.');
  1269. }
  1270. while (leadfraczeros > 0) { /* Leading fractional part zeros. */
  1271. OUTCHAR(str, *len, size, '0');
  1272. leadfraczeros--;
  1273. }
  1274. while (fpos > omitcount) { /* The remaining fractional part. */
  1275. fpos--;
  1276. OUTCHAR(str, *len, size, fconvert[fpos]);
  1277. }
  1278. while (epos > 0) { /* Exponent. */
  1279. epos--;
  1280. OUTCHAR(str, *len, size, econvert[epos]);
  1281. }
  1282. while (padlen < 0) { /* Trailing spaces. */
  1283. OUTCHAR(str, *len, size, ' ');
  1284. padlen++;
  1285. }
  1286. }
  1287. static void
  1288. printsep(char *str, size_t *len, size_t size)
  1289. {
  1290. #if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP
  1291. struct lconv *lc = localeconv();
  1292. int i;
  1293. if (lc->thousands_sep != NULL)
  1294. for (i = 0; lc->thousands_sep[i] != '\0'; i++)
  1295. OUTCHAR(str, *len, size, lc->thousands_sep[i]);
  1296. else
  1297. #endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */
  1298. OUTCHAR(str, *len, size, ',');
  1299. }
  1300. static int
  1301. getnumsep(int digits)
  1302. {
  1303. int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3;
  1304. #if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP
  1305. int strln;
  1306. struct lconv *lc = localeconv();
  1307. /* We support an arbitrary separator length (including zero). */
  1308. if (lc->thousands_sep != NULL) {
  1309. for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++)
  1310. continue;
  1311. separators *= strln;
  1312. }
  1313. #endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */
  1314. return separators;
  1315. }
  1316. static int
  1317. getexponent(LDOUBLE value)
  1318. {
  1319. LDOUBLE tmp = (value >= 0.0) ? value : -value;
  1320. int exponent = 0;
  1321. /*
  1322. * We check for LDOUBLE_MAX_10_EXP >= exponent >= LDOUBLE_MIN_10_EXP in
  1323. * order to work around possible endless loops which could happen (at
  1324. * least) in the second loop (at least) if we're called with an infinite
  1325. * value. However, we checked for infinity before calling this function
  1326. * using our ISINF() macro, so this might be somewhat paranoid.
  1327. */
  1328. while (tmp < 1.0 && tmp > 0.0 && --exponent >= LDOUBLE_MIN_10_EXP)
  1329. tmp *= 10;
  1330. while (tmp >= 10.0 && ++exponent <= LDOUBLE_MAX_10_EXP)
  1331. tmp /= 10;
  1332. return exponent;
  1333. }
  1334. static int
  1335. convert(UINTMAX_T value, char *buf, size_t size, int base, int caps)
  1336. {
  1337. const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef";
  1338. size_t pos = 0;
  1339. /* We return an unterminated buffer with the digits in reverse order. */
  1340. do {
  1341. buf[pos++] = digits[value % base];
  1342. value /= base;
  1343. } while (value != 0 && pos < size);
  1344. return (int)pos;
  1345. }
  1346. static UINTMAX_T
  1347. cast(LDOUBLE value)
  1348. {
  1349. UINTMAX_T result;
  1350. /*
  1351. * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be
  1352. * represented exactly as an LDOUBLE value (but is less than LDBL_MAX),
  1353. * it may be increased to the nearest higher representable value for the
  1354. * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE
  1355. * value although converting the latter to UINTMAX_T would overflow.
  1356. */
  1357. if (value >= UINTMAX_MAX)
  1358. return UINTMAX_MAX;
  1359. result = value;
  1360. /*
  1361. * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to
  1362. * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates
  1363. * the standard). Sigh.
  1364. */
  1365. return (result <= value) ? result : result - 1;
  1366. }
  1367. static UINTMAX_T
  1368. myround(LDOUBLE value)
  1369. {
  1370. UINTMAX_T intpart = cast(value);
  1371. return ((value -= intpart) < 0.5) ? intpart : intpart + 1;
  1372. }
  1373. static LDOUBLE
  1374. mypow10(int exponent)
  1375. {
  1376. LDOUBLE result = 1;
  1377. while (exponent > 0) {
  1378. result *= 10;
  1379. exponent--;
  1380. }
  1381. while (exponent < 0) {
  1382. result /= 10;
  1383. exponent++;
  1384. }
  1385. return result;
  1386. }
  1387. #endif /* !HAVE_VSNPRINTF */
  1388. #if !HAVE_VASPRINTF
  1389. #if NEED_MYMEMCPY
  1390. void *
  1391. mymemcpy(void *dst, void *src, size_t len)
  1392. {
  1393. const char *from = src;
  1394. char *to = dst;
  1395. /* No need for optimization, we use this only to replace va_copy(3). */
  1396. while (len-- > 0)
  1397. *to++ = *from++;
  1398. return dst;
  1399. }
  1400. #endif /* NEED_MYMEMCPY */
  1401. int
  1402. rpl_vasprintf(char **ret, const char *format, va_list ap)
  1403. {
  1404. size_t size;
  1405. int len;
  1406. va_list aq;
  1407. VA_COPY(aq, ap);
  1408. len = vsnprintf(NULL, 0, format, aq);
  1409. VA_END_COPY(aq);
  1410. if (len < 0 || (*ret = malloc(size = len + 1)) == NULL)
  1411. return -1;
  1412. return vsnprintf(*ret, size, format, ap);
  1413. }
  1414. #endif /* !HAVE_VASPRINTF */
  1415. #if !HAVE_SNPRINTF
  1416. #if HAVE_STDARG_H
  1417. int
  1418. rpl_snprintf(char *str, size_t size, const char *format, ...)
  1419. #else
  1420. int
  1421. rpl_snprintf(va_alist) va_dcl
  1422. #endif /* HAVE_STDARG_H */
  1423. {
  1424. #if !HAVE_STDARG_H
  1425. char *str;
  1426. size_t size;
  1427. char *format;
  1428. #endif /* HAVE_STDARG_H */
  1429. va_list ap;
  1430. int len;
  1431. VA_START(ap, format);
  1432. VA_SHIFT(ap, str, char *);
  1433. VA_SHIFT(ap, size, size_t);
  1434. VA_SHIFT(ap, format, const char *);
  1435. len = vsnprintf(str, size, format, ap);
  1436. va_end(ap);
  1437. return len;
  1438. }
  1439. #endif /* !HAVE_SNPRINTF */
  1440. #if !HAVE_ASPRINTF
  1441. #if HAVE_STDARG_H
  1442. int
  1443. rpl_asprintf(char **ret, const char *format, ...)
  1444. #else
  1445. int
  1446. rpl_asprintf(va_alist) va_dcl
  1447. #endif /* HAVE_STDARG_H */
  1448. {
  1449. #if !HAVE_STDARG_H
  1450. char **ret;
  1451. char *format;
  1452. #endif /* HAVE_STDARG_H */
  1453. va_list ap;
  1454. int len;
  1455. VA_START(ap, format);
  1456. VA_SHIFT(ap, ret, char **);
  1457. VA_SHIFT(ap, format, const char *);
  1458. len = vasprintf(ret, format, ap);
  1459. va_end(ap);
  1460. return len;
  1461. }
  1462. #endif /* !HAVE_ASPRINTF */
  1463. #else /* Dummy declaration to avoid empty translation unit warnings. */
  1464. int main(int argc, char **argv);
  1465. #endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */
  1466. int sprintf(char *s, const char *fmt, ...)
  1467. {
  1468. int n;
  1469. va_list arg;
  1470. va_start(arg, fmt);
  1471. n = vsnprintf(s, 1024, fmt, arg);
  1472. va_end(arg);
  1473. return n;
  1474. }
  1475. int vsprintf (char *d, const char *s, va_list ap)
  1476. {
  1477. return vsnprintf(d, 1024, s, ap);
  1478. }
  1479. #if TEST_SNPRINTF
  1480. int
  1481. main(void)
  1482. {
  1483. const char *float_fmt[] = {
  1484. /* "%E" and "%e" formats. */
  1485. #if HAVE_LONG_LONG_INT && !OS_BSD && !OS_IRIX
  1486. "%.16e",
  1487. "%22.16e",
  1488. "%022.16e",
  1489. "%-22.16e",
  1490. "%#+'022.16e",
  1491. #endif /* HAVE_LONG_LONG_INT && !OS_BSD && !OS_IRIX */
  1492. "foo|%#+0123.9E|bar",
  1493. "%-123.9e",
  1494. "%123.9e",
  1495. "%+23.9e",
  1496. "%+05.8e",
  1497. "%-05.8e",
  1498. "%05.8e",
  1499. "%+5.8e",
  1500. "%-5.8e",
  1501. "% 5.8e",
  1502. "%5.8e",
  1503. "%+4.9e",
  1504. #if !OS_LINUX /* glibc sometimes gets these wrong. */
  1505. "%+#010.0e",
  1506. "%#10.1e",
  1507. "%10.5e",
  1508. "% 10.5e",
  1509. "%5.0e",
  1510. "%5.e",
  1511. "%#5.0e",
  1512. "%#5.e",
  1513. "%3.2e",
  1514. "%3.1e",
  1515. "%-1.5e",
  1516. "%1.5e",
  1517. "%01.3e",
  1518. "%1.e",
  1519. "%.1e",
  1520. "%#.0e",
  1521. "%+.0e",
  1522. "% .0e",
  1523. "%.0e",
  1524. "%#.e",
  1525. "%+.e",
  1526. "% .e",
  1527. "%.e",
  1528. "%4e",
  1529. "%e",
  1530. "%E",
  1531. #endif /* !OS_LINUX */
  1532. /* "%F" and "%f" formats. */
  1533. #if !OS_BSD && !OS_IRIX
  1534. "% '022f",
  1535. "%+'022f",
  1536. "%-'22f",
  1537. "%'22f",
  1538. #if HAVE_LONG_LONG_INT
  1539. "%.16f",
  1540. "%22.16f",
  1541. "%022.16f",
  1542. "%-22.16f",
  1543. "%#+'022.16f",
  1544. #endif /* HAVE_LONG_LONG_INT */
  1545. #endif /* !OS_BSD && !OS_IRIX */
  1546. "foo|%#+0123.9F|bar",
  1547. "%-123.9f",
  1548. "%123.9f",
  1549. "%+23.9f",
  1550. "%+#010.0f",
  1551. "%#10.1f",
  1552. "%10.5f",
  1553. "% 10.5f",
  1554. "%+05.8f",
  1555. "%-05.8f",
  1556. "%05.8f",
  1557. "%+5.8f",
  1558. "%-5.8f",
  1559. "% 5.8f",
  1560. "%5.8f",
  1561. "%5.0f",
  1562. "%5.f",
  1563. "%#5.0f",
  1564. "%#5.f",
  1565. "%+4.9f",
  1566. "%3.2f",
  1567. "%3.1f",
  1568. "%-1.5f",
  1569. "%1.5f",
  1570. "%01.3f",
  1571. "%1.f",
  1572. "%.1f",
  1573. "%#.0f",
  1574. "%+.0f",
  1575. "% .0f",
  1576. "%.0f",
  1577. "%#.f",
  1578. "%+.f",
  1579. "% .f",
  1580. "%.f",
  1581. "%4f",
  1582. "%f",
  1583. "%F",
  1584. /* "%G" and "%g" formats. */
  1585. #if !OS_BSD && !OS_IRIX && !OS_LINUX
  1586. "% '022g",
  1587. "%+'022g",
  1588. "%-'22g",
  1589. "%'22g",
  1590. #if HAVE_LONG_LONG_INT
  1591. "%.16g",
  1592. "%22.16g",
  1593. "%022.16g",
  1594. "%-22.16g",
  1595. "%#+'022.16g",
  1596. #endif /* HAVE_LONG_LONG_INT */
  1597. #endif /* !OS_BSD && !OS_IRIX && !OS_LINUX */
  1598. "foo|%#+0123.9G|bar",
  1599. "%-123.9g",
  1600. "%123.9g",
  1601. "%+23.9g",
  1602. "%+05.8g",
  1603. "%-05.8g",
  1604. "%05.8g",
  1605. "%+5.8g",
  1606. "%-5.8g",
  1607. "% 5.8g",
  1608. "%5.8g",
  1609. "%+4.9g",
  1610. #if !OS_LINUX /* glibc sometimes gets these wrong. */
  1611. "%+#010.0g",
  1612. "%#10.1g",
  1613. "%10.5g",
  1614. "% 10.5g",
  1615. "%5.0g",
  1616. "%5.g",
  1617. "%#5.0g",
  1618. "%#5.g",
  1619. "%3.2g",
  1620. "%3.1g",
  1621. "%-1.5g",
  1622. "%1.5g",
  1623. "%01.3g",
  1624. "%1.g",
  1625. "%.1g",
  1626. "%#.0g",
  1627. "%+.0g",
  1628. "% .0g",
  1629. "%.0g",
  1630. "%#.g",
  1631. "%+.g",
  1632. "% .g",
  1633. "%.g",
  1634. "%4g",
  1635. "%g",
  1636. "%G",
  1637. #endif /* !OS_LINUX */
  1638. NULL
  1639. };
  1640. double float_val[] = {
  1641. -4.136,
  1642. -134.52,
  1643. -5.04030201,
  1644. -3410.01234,
  1645. -999999.999999,
  1646. -913450.29876,
  1647. -913450.2,
  1648. -91345.2,
  1649. -9134.2,
  1650. -913.2,
  1651. -91.2,
  1652. -9.2,
  1653. -9.9,
  1654. 4.136,
  1655. 134.52,
  1656. 5.04030201,
  1657. 3410.01234,
  1658. 999999.999999,
  1659. 913450.29876,
  1660. 913450.2,
  1661. 91345.2,
  1662. 9134.2,
  1663. 913.2,
  1664. 91.2,
  1665. 9.2,
  1666. 9.9,
  1667. 9.96,
  1668. 9.996,
  1669. 9.9996,
  1670. 9.99996,
  1671. 9.999996,
  1672. 9.9999996,
  1673. 9.99999996,
  1674. 0.99999996,
  1675. 0.99999999,
  1676. 0.09999999,
  1677. 0.00999999,
  1678. 0.00099999,
  1679. 0.00009999,
  1680. 0.00000999,
  1681. 0.00000099,
  1682. 0.00000009,
  1683. 0.00000001,
  1684. 0.0000001,
  1685. 0.000001,
  1686. 0.00001,
  1687. 0.0001,
  1688. 0.001,
  1689. 0.01,
  1690. 0.1,
  1691. 1.0,
  1692. 1.5,
  1693. -1.5,
  1694. -1.0,
  1695. -0.1,
  1696. #if !OS_BSD /* BSD sometimes gets these wrong. */
  1697. #ifdef INFINITY
  1698. INFINITY,
  1699. -INFINITY,
  1700. #endif /* defined(INFINITY) */
  1701. #ifdef NAN
  1702. NAN,
  1703. #endif /* defined(NAN) */
  1704. #endif /* !OS_BSD */
  1705. 0
  1706. };
  1707. const char *long_fmt[] = {
  1708. "foo|%0123ld|bar",
  1709. #if !OS_IRIX
  1710. "% '0123ld",
  1711. "%+'0123ld",
  1712. "%-'123ld",
  1713. "%'123ld",
  1714. #endif /* !OS_IRiX */
  1715. "%123.9ld",
  1716. "% 123.9ld",
  1717. "%+123.9ld",
  1718. "%-123.9ld",
  1719. "%0123ld",
  1720. "% 0123ld",
  1721. "%+0123ld",
  1722. "%-0123ld",
  1723. "%10.5ld",
  1724. "% 10.5ld",
  1725. "%+10.5ld",
  1726. "%-10.5ld",
  1727. "%010ld",
  1728. "% 010ld",
  1729. "%+010ld",
  1730. "%-010ld",
  1731. "%4.2ld",
  1732. "% 4.2ld",
  1733. "%+4.2ld",
  1734. "%-4.2ld",
  1735. "%04ld",
  1736. "% 04ld",
  1737. "%+04ld",
  1738. "%-04ld",
  1739. "%5.5ld",
  1740. "%+22.33ld",
  1741. "%01.3ld",
  1742. "%1.5ld",
  1743. "%-1.5ld",
  1744. "%44ld",
  1745. "%4ld",
  1746. "%4.0ld",
  1747. "%4.ld",
  1748. "%.44ld",
  1749. "%.4ld",
  1750. "%.0ld",
  1751. "%.ld",
  1752. "%ld",
  1753. NULL
  1754. };
  1755. long int long_val[] = {
  1756. #ifdef LONG_MAX
  1757. LONG_MAX,
  1758. #endif /* LONG_MAX */
  1759. #ifdef LONG_MIN
  1760. LONG_MIN,
  1761. #endif /* LONG_MIN */
  1762. -91340,
  1763. 91340,
  1764. 341,
  1765. 134,
  1766. 0203,
  1767. -1,
  1768. 1,
  1769. 0
  1770. };
  1771. const char *ulong_fmt[] = {
  1772. /* "%u" formats. */
  1773. "foo|%0123lu|bar",
  1774. #if !OS_IRIX
  1775. "% '0123lu",
  1776. "%+'0123lu",
  1777. "%-'123lu",
  1778. "%'123lu",
  1779. #endif /* !OS_IRiX */
  1780. "%123.9lu",
  1781. "% 123.9lu",
  1782. "%+123.9lu",
  1783. "%-123.9lu",
  1784. "%0123lu",
  1785. "% 0123lu",
  1786. "%+0123lu",
  1787. "%-0123lu",
  1788. "%5.5lu",
  1789. "%+22.33lu",
  1790. "%01.3lu",
  1791. "%1.5lu",
  1792. "%-1.5lu",
  1793. "%44lu",
  1794. "%lu",
  1795. /* "%o" formats. */
  1796. "foo|%#0123lo|bar",
  1797. "%#123.9lo",
  1798. "%# 123.9lo",
  1799. "%#+123.9lo",
  1800. "%#-123.9lo",
  1801. "%#0123lo",
  1802. "%# 0123lo",
  1803. "%#+0123lo",
  1804. "%#-0123lo",
  1805. "%#5.5lo",
  1806. "%#+22.33lo",
  1807. "%#01.3lo",
  1808. "%#1.5lo",
  1809. "%#-1.5lo",
  1810. "%#44lo",
  1811. "%#lo",
  1812. "%123.9lo",
  1813. "% 123.9lo",
  1814. "%+123.9lo",
  1815. "%-123.9lo",
  1816. "%0123lo",
  1817. "% 0123lo",
  1818. "%+0123lo",
  1819. "%-0123lo",
  1820. "%5.5lo",
  1821. "%+22.33lo",
  1822. "%01.3lo",
  1823. "%1.5lo",
  1824. "%-1.5lo",
  1825. "%44lo",
  1826. "%lo",
  1827. /* "%X" and "%x" formats. */
  1828. "foo|%#0123lX|bar",
  1829. "%#123.9lx",
  1830. "%# 123.9lx",
  1831. "%#+123.9lx",
  1832. "%#-123.9lx",
  1833. "%#0123lx",
  1834. "%# 0123lx",
  1835. "%#+0123lx",
  1836. "%#-0123lx",
  1837. "%#5.5lx",
  1838. "%#+22.33lx",
  1839. "%#01.3lx",
  1840. "%#1.5lx",
  1841. "%#-1.5lx",
  1842. "%#44lx",
  1843. "%#lx",
  1844. "%#lX",
  1845. "%123.9lx",
  1846. "% 123.9lx",
  1847. "%+123.9lx",
  1848. "%-123.9lx",
  1849. "%0123lx",
  1850. "% 0123lx",
  1851. "%+0123lx",
  1852. "%-0123lx",
  1853. "%5.5lx",
  1854. "%+22.33lx",
  1855. "%01.3lx",
  1856. "%1.5lx",
  1857. "%-1.5lx",
  1858. "%44lx",
  1859. "%lx",
  1860. "%lX",
  1861. NULL
  1862. };
  1863. unsigned long int ulong_val[] = {
  1864. #ifdef ULONG_MAX
  1865. ULONG_MAX,
  1866. #endif /* ULONG_MAX */
  1867. 91340,
  1868. 341,
  1869. 134,
  1870. 0203,
  1871. 1,
  1872. 0
  1873. };
  1874. const char *llong_fmt[] = {
  1875. "foo|%0123lld|bar",
  1876. "%123.9lld",
  1877. "% 123.9lld",
  1878. "%+123.9lld",
  1879. "%-123.9lld",
  1880. "%0123lld",
  1881. "% 0123lld",
  1882. "%+0123lld",
  1883. "%-0123lld",
  1884. "%5.5lld",
  1885. "%+22.33lld",
  1886. "%01.3lld",
  1887. "%1.5lld",
  1888. "%-1.5lld",
  1889. "%44lld",
  1890. "%lld",
  1891. NULL
  1892. };
  1893. LLONG llong_val[] = {
  1894. #ifdef LLONG_MAX
  1895. LLONG_MAX,
  1896. #endif /* LLONG_MAX */
  1897. #ifdef LLONG_MIN
  1898. LLONG_MIN,
  1899. #endif /* LLONG_MIN */
  1900. -91340,
  1901. 91340,
  1902. 341,
  1903. 134,
  1904. 0203,
  1905. -1,
  1906. 1,
  1907. 0
  1908. };
  1909. const char *string_fmt[] = {
  1910. "foo|%10.10s|bar",
  1911. "%-10.10s",
  1912. "%10.10s",
  1913. "%10.5s",
  1914. "%5.10s",
  1915. "%10.1s",
  1916. "%1.10s",
  1917. "%10.0s",
  1918. "%0.10s",
  1919. "%-42.5s",
  1920. "%2.s",
  1921. "%.10s",
  1922. "%.1s",
  1923. "%.0s",
  1924. "%.s",
  1925. "%4s",
  1926. "%s",
  1927. NULL
  1928. };
  1929. const char *string_val[] = {
  1930. "Hello",
  1931. "Hello, world!",
  1932. "Sound check: One, two, three.",
  1933. "This string is a little longer than the other strings.",
  1934. "1",
  1935. "",
  1936. NULL
  1937. };
  1938. #if !OS_SYSV /* SysV uses a different format than we do. */
  1939. const char *pointer_fmt[] = {
  1940. "foo|%p|bar",
  1941. "%42p",
  1942. "%p",
  1943. NULL
  1944. };
  1945. const char *pointer_val[] = {
  1946. *pointer_fmt,
  1947. *string_fmt,
  1948. *string_val,
  1949. NULL
  1950. };
  1951. #endif /* !OS_SYSV */
  1952. char buf1[1024], buf2[1024];
  1953. double value, digits = 9.123456789012345678901234567890123456789;
  1954. int i, j, r1, r2, failed = 0, num = 0;
  1955. /*
  1956. * Use -DTEST_NILS in order to also test the conversion of nil values. Might
  1957. * segfault on systems which don't support converting a NULL pointer with "%s"
  1958. * and lets some test cases fail against BSD and glibc due to bugs in their
  1959. * implementations.
  1960. */
  1961. #ifndef TEST_NILS
  1962. #define TEST_NILS 0
  1963. #elif TEST_NILS
  1964. #undef TEST_NILS
  1965. #define TEST_NILS 1
  1966. #endif /* !defined(TEST_NILS) */
  1967. #ifdef TEST
  1968. #undef TEST
  1969. #endif /* defined(TEST) */
  1970. #define TEST(fmt, val) \
  1971. do { \
  1972. for (i = 0; fmt[i] != NULL; i++) \
  1973. for (j = 0; j == 0 || val[j - TEST_NILS] != 0; j++) { \
  1974. r1 = sprintf(buf1, fmt[i], val[j]); \
  1975. r2 = snprintf(buf2, sizeof(buf2), fmt[i], val[j]); \
  1976. if (strcmp(buf1, buf2) != 0 || r1 != r2) { \
  1977. (void)printf("Results don't match, " \
  1978. "format string: %s\n" \
  1979. "\t sprintf(3): [%s] (%d)\n" \
  1980. "\tsnprintf(3): [%s] (%d)\n", \
  1981. fmt[i], buf1, r1, buf2, r2); \
  1982. failed++; \
  1983. } \
  1984. num++; \
  1985. } \
  1986. } while (/* CONSTCOND */ 0)
  1987. #if HAVE_LOCALE_H
  1988. (void)setlocale(LC_ALL, "");
  1989. #endif /* HAVE_LOCALE_H */
  1990. (void)puts("Testing our snprintf(3) against your system's sprintf(3).");
  1991. TEST(float_fmt, float_val);
  1992. TEST(long_fmt, long_val);
  1993. TEST(ulong_fmt, ulong_val);
  1994. TEST(llong_fmt, llong_val);
  1995. TEST(string_fmt, string_val);
  1996. #if !OS_SYSV /* SysV uses a different format than we do. */
  1997. TEST(pointer_fmt, pointer_val);
  1998. #endif /* !OS_SYSV */
  1999. (void)printf("Result: %d out of %d tests failed.\n", failed, num);
  2000. (void)fputs("Checking how many digits we support: ", stdout);
  2001. for (i = 0; i < 100; i++) {
  2002. value = pow(10, i) * digits;
  2003. (void)sprintf(buf1, "%.1f", value);
  2004. (void)snprintf(buf2, sizeof(buf2), "%.1f", value);
  2005. if (strcmp(buf1, buf2) != 0) {
  2006. (void)printf("apparently %d.\n", i);
  2007. break;
  2008. }
  2009. }
  2010. return (failed == 0) ? 0 : 1;
  2011. }
  2012. #endif /* TEST_SNPRINTF */
  2013. /* vim: set joinspaces noexpandtab textwidth=80 cinoptions=(4,u0: */