rt_vsnprintf.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373
  1. /*
  2. * Copyright (c) 2021, Meco Jianting Man <jiantingman@foxmail.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-11-27 Meco Man porting for rt_vsnprintf as the fully functional version
  9. */
  10. /**
  11. * @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
  12. * 2021-2022, Haifa, Palestine/Israel
  13. * @author (c) Marco Paland (info@paland.com)
  14. * 2014-2019, PALANDesign Hannover, Germany
  15. *
  16. * @note Others have made smaller contributions to this file: see the
  17. * contributors page at https://github.com/eyalroz/printf/graphs/contributors
  18. * or ask one of the authors. The original code for exponential specifiers was
  19. * contributed by Martijn Jasperse <m.jasperse@gmail.com>.
  20. *
  21. * @brief Small stand-alone implementation of the printf family of functions
  22. * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with
  23. * a very limited resources.
  24. *
  25. * @note the implementations are thread-safe; re-entrant; use no functions from
  26. * the standard library; and do not dynamically allocate any memory.
  27. *
  28. * @license The MIT License (MIT)
  29. *
  30. * Permission is hereby granted, free of charge, to any person obtaining a copy
  31. * of this software and associated documentation files (the "Software"), to deal
  32. * in the Software without restriction, including without limitation the rights
  33. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  34. * copies of the Software, and to permit persons to whom the Software is
  35. * furnished to do so, subject to the following conditions:
  36. *
  37. * The above copyright notice and this permission notice shall be included in
  38. * all copies or substantial portions of the Software.
  39. *
  40. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  41. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  42. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  43. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  44. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  45. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  46. * THE SOFTWARE.
  47. */
  48. #include <stdio.h>
  49. #include <stdint.h>
  50. #include <limits.h>
  51. #include <stdbool.h>
  52. #include <rtconfig.h>
  53. #include <rtdef.h>
  54. #include <rtthread.h>
  55. #ifndef RT_VER_NUM /* Doesn't use menuconfig */
  56. // 'ntoa' conversion buffer size, this must be big enough to hold one converted
  57. // numeric number including padded zeros (dynamically created on stack)
  58. #ifndef PKG_VSNPRINTF_INTEGER_BUFFER_SIZE
  59. #define PKG_VSNPRINTF_INTEGER_BUFFER_SIZE 32
  60. #endif
  61. // size of the fixed (on-stack) buffer for printing individual decimal numbers.
  62. // this must be big enough to hold one converted floating-point value including
  63. // padded zeros.
  64. #ifndef PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE
  65. #define PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE 32
  66. #endif
  67. // Support for the decimal notation floating point conversion specifiers (%f, %F)
  68. #ifndef PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS
  69. #define PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS
  70. #endif
  71. // Support for the exponential notation floating point conversion specifiers (%e, %g, %E, %G)
  72. #ifndef PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  73. #define PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  74. #endif
  75. // Support for the length write-back specifier (%n)
  76. #ifndef PKG_VSNPRINTF_SUPPORT_WRITEBACK_SPECIFIER
  77. #define PKG_VSNPRINTF_SUPPORT_WRITEBACK_SPECIFIER
  78. #endif
  79. // Default precision for the floating point conversion specifiers (the C standard sets this at 6)
  80. #ifndef PKG_VSNPRINTF_DEFAULT_FLOAT_PRECISION
  81. #define PKG_VSNPRINTF_DEFAULT_FLOAT_PRECISION 6
  82. #endif
  83. // According to the C languages standard, printf() and related functions must be able to print any
  84. // integral number in floating-point notation, regardless of length, when using the %f specifier -
  85. // possibly hundreds of characters, potentially overflowing your buffers. In this implementation,
  86. // all values beyond this threshold are switched to exponential notation.
  87. #ifndef PKG_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL
  88. #define PKG_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9
  89. #endif
  90. // Support for the long long integral types (with the ll, z and t length modifiers for specifiers
  91. // %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: 'L' (long double) is not supported.
  92. #ifndef PKG_VSNPRINTF_SUPPORT_LONG_LONG
  93. #define PKG_VSNPRINTF_SUPPORT_LONG_LONG
  94. #endif
  95. // The number of terms in a Taylor series expansion of log_10(x) to
  96. // use for approximation - including the power-zero term (i.e. the
  97. // value at the point of expansion).
  98. #ifndef PKG_VSNPRINTF_LOG10_TAYLOR_TERMS
  99. #define PKG_VSNPRINTF_LOG10_TAYLOR_TERMS 4
  100. #endif
  101. // Be extra-safe, and don't assume format specifiers are completed correctly
  102. // before the format string end.
  103. #ifndef PKG_VSNPRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
  104. #define PKG_VSNPRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
  105. #endif
  106. #endif /* RT_VER_NUM */
  107. #if PKG_VSNPRINTF_LOG10_TAYLOR_TERMS <= 1
  108. #error "At least one non-constant Taylor expansion is necessary for the log10() calculation"
  109. #endif
  110. ///////////////////////////////////////////////////////////////////////////////
  111. #define PRINTF_PREFER_DECIMAL false
  112. #define PRINTF_PREFER_EXPONENTIAL true
  113. // The following will convert the number-of-digits into an exponential-notation literal
  114. #define PRINTF_CONCATENATE(s1, s2) s1##s2
  115. #define PRINTF_EXPAND_THEN_CONCATENATE(s1, s2) PRINTF_CONCATENATE(s1, s2)
  116. #define PRINTF_FLOAT_NOTATION_THRESHOLD PRINTF_EXPAND_THEN_CONCATENATE(1e,PKG_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL)
  117. // internal flag definitions
  118. #define FLAGS_ZEROPAD (1U << 0U)
  119. #define FLAGS_LEFT (1U << 1U)
  120. #define FLAGS_PLUS (1U << 2U)
  121. #define FLAGS_SPACE (1U << 3U)
  122. #define FLAGS_HASH (1U << 4U)
  123. #define FLAGS_UPPERCASE (1U << 5U)
  124. #define FLAGS_CHAR (1U << 6U)
  125. #define FLAGS_SHORT (1U << 7U)
  126. #define FLAGS_INT (1U << 8U)
  127. // Only used with PKG_VSNPRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
  128. #define FLAGS_LONG (1U << 9U)
  129. #define FLAGS_LONG_LONG (1U << 10U)
  130. #define FLAGS_PRECISION (1U << 11U)
  131. #define FLAGS_ADAPT_EXP (1U << 12U)
  132. #define FLAGS_POINTER (1U << 13U)
  133. // Note: Similar, but not identical, effect as FLAGS_HASH
  134. #define FLAGS_SIGNED (1U << 14U)
  135. // Only used with PKG_VSNPRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
  136. #ifdef PKG_VSNPRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
  137. #define FLAGS_INT8 FLAGS_CHAR
  138. #if (SHRT_MAX == 32767LL)
  139. #define FLAGS_INT16 FLAGS_SHORT
  140. #elif (INT_MAX == 32767LL)
  141. #define FLAGS_INT16 FLAGS_INT
  142. #elif (LONG_MAX == 32767LL)
  143. #define FLAGS_INT16 FLAGS_LONG
  144. #elif (LLONG_MAX == 32767LL)
  145. #define FLAGS_INT16 FLAGS_LONG_LONG
  146. #else
  147. #error "No basic integer type has a size of 16 bits exactly"
  148. #endif
  149. #if (SHRT_MAX == 2147483647LL)
  150. #define FLAGS_INT32 FLAGS_SHORT
  151. #elif (INT_MAX == 2147483647LL)
  152. #define FLAGS_INT32 FLAGS_INT
  153. #elif (LONG_MAX == 2147483647LL)
  154. #define FLAGS_INT32 FLAGS_LONG
  155. #elif (LLONG_MAX == 2147483647LL)
  156. #define FLAGS_INT32 FLAGS_LONG_LONG
  157. #else
  158. #error "No basic integer type has a size of 32 bits exactly"
  159. #endif
  160. #if (SHRT_MAX == 9223372036854775807LL)
  161. #define FLAGS_INT64 FLAGS_SHORT
  162. #elif (INT_MAX == 9223372036854775807LL)
  163. #define FLAGS_INT64 FLAGS_INT
  164. #elif (LONG_MAX == 9223372036854775807LL)
  165. #define FLAGS_INT64 FLAGS_LONG
  166. #elif (LLONG_MAX == 9223372036854775807LL)
  167. #define FLAGS_INT64 FLAGS_LONG_LONG
  168. #else
  169. #error "No basic integer type has a size of 64 bits exactly"
  170. #endif
  171. #endif // PKG_VSNPRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
  172. typedef unsigned int printf_flags_t;
  173. #define BASE_BINARY 2
  174. #define BASE_OCTAL 8
  175. #define BASE_DECIMAL 10
  176. #define BASE_HEX 16
  177. typedef uint8_t numeric_base_t;
  178. #ifdef PKG_VSNPRINTF_SUPPORT_LONG_LONG
  179. typedef unsigned long long printf_unsigned_value_t;
  180. typedef long long printf_signed_value_t;
  181. #else
  182. typedef unsigned long printf_unsigned_value_t;
  183. typedef long printf_signed_value_t;
  184. #endif
  185. // The printf()-family functions return an `int`; it is therefore
  186. // unnecessary/inappropriate to use size_t - often larger than int
  187. // in practice - for non-negative related values, such as widths,
  188. // precisions, offsets into buffers used for printing and the sizes
  189. // of these buffers. instead, we use:
  190. typedef unsigned int printf_size_t;
  191. #define PRINTF_MAX_POSSIBLE_BUFFER_SIZE INT_MAX
  192. // If we were to nitpick, this would actually be INT_MAX + 1,
  193. // since INT_MAX is the maximum return value, which excludes the
  194. // trailing '\0'.
  195. #if defined(PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS) || defined(PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
  196. #include <float.h>
  197. #if FLT_RADIX != 2
  198. #error "Non-binary-radix floating-point types are unsupported."
  199. #endif
  200. #if DBL_MANT_DIG == 24
  201. #define DOUBLE_SIZE_IN_BITS 32
  202. typedef uint32_t double_uint_t;
  203. #define DOUBLE_EXPONENT_MASK 0xFFU
  204. #define DOUBLE_BASE_EXPONENT 127
  205. #define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -38
  206. #define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-38
  207. #elif DBL_MANT_DIG == 53
  208. #define DOUBLE_SIZE_IN_BITS 64
  209. typedef uint64_t double_uint_t;
  210. #define DOUBLE_EXPONENT_MASK 0x7FFU
  211. #define DOUBLE_BASE_EXPONENT 1023
  212. #define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -308
  213. #define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 ((double)1e-308L)
  214. #else
  215. #error "Unsupported double type configuration"
  216. #endif
  217. #define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1)
  218. typedef union {
  219. double_uint_t U;
  220. double F;
  221. } double_with_bit_access;
  222. // This is unnecessary in C99, since compound initializers can be used,
  223. // but:
  224. // 1. Some compilers are finicky about this;
  225. // 2. Some people may want to convert this to C89;
  226. // 3. If you try to use it as C++, only C++20 supports compound literals
  227. static inline double_with_bit_access get_bit_access(double x)
  228. {
  229. double_with_bit_access dwba;
  230. dwba.F = x;
  231. return dwba;
  232. }
  233. static inline int get_sign_bit(double x)
  234. {
  235. // The sign is stored in the highest bit
  236. return (int) (get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
  237. }
  238. static inline int get_exp2(double_with_bit_access x)
  239. {
  240. // The exponent in an IEEE-754 floating-point number occupies a contiguous
  241. // sequence of bits (e.g. 52..62 for 64-bit doubles), but with a non-trivial representation: An
  242. // unsigned offset from some negative value (with the extremal offset values reserved for
  243. // special use).
  244. return (int)((x.U >> DOUBLE_STORED_MANTISSA_BITS ) & DOUBLE_EXPONENT_MASK) - DOUBLE_BASE_EXPONENT;
  245. }
  246. #define PRINTF_ABS(_x) ( (_x) > 0 ? (_x) : -(_x) )
  247. #endif // (PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS || PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
  248. // Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid
  249. // and well-defined, but if you're not careful you can easily trigger undefined
  250. // behavior with -LONG_MIN or -LLONG_MIN
  251. #define ABS_FOR_PRINTING(_x) ((printf_unsigned_value_t) ( (_x) > 0 ? (_x) : -((printf_signed_value_t)_x) ))
  252. // wrapper (used as buffer) for output function type
  253. //
  254. // One of the following must hold:
  255. // 1. max_chars is 0
  256. // 2. buffer is non-null
  257. // 3. function is non-null
  258. //
  259. // ... otherwise bad things will happen.
  260. typedef struct {
  261. void (*function)(char c, void* extra_arg);
  262. void* extra_function_arg;
  263. char* buffer;
  264. printf_size_t pos;
  265. printf_size_t max_chars;
  266. } output_gadget_t;
  267. // Note: This function currently assumes it is not passed a '\0' c,
  268. // or alternatively, that '\0' can be passed to the function in the output
  269. // gadget. The former assumption holds within the printf library. It also
  270. // assumes that the output gadget has been properly initialized.
  271. static inline void putchar_via_gadget(output_gadget_t* gadget, char c)
  272. {
  273. printf_size_t write_pos = gadget->pos++;
  274. // We're _always_ increasing pos, so as to count how may characters
  275. // _would_ have been written if not for the max_chars limitation
  276. if (write_pos >= gadget->max_chars) {
  277. return;
  278. }
  279. if (gadget->function != NULL) {
  280. // No check for c == '\0' .
  281. gadget->function(c, gadget->extra_function_arg);
  282. }
  283. else {
  284. // it must be the case that gadget->buffer != NULL , due to the constraint
  285. // on output_gadget_t ; and note we're relying on write_pos being non-negative.
  286. gadget->buffer[write_pos] = c;
  287. }
  288. }
  289. // Possibly-write the string-terminating '\0' character
  290. static inline void append_termination_with_gadget(output_gadget_t* gadget)
  291. {
  292. if (gadget->function != NULL || gadget->max_chars == 0) {
  293. return;
  294. }
  295. if (gadget->buffer == NULL) {
  296. return;
  297. }
  298. printf_size_t null_char_pos = gadget->pos < gadget->max_chars ? gadget->pos : gadget->max_chars - 1;
  299. gadget->buffer[null_char_pos] = '\0';
  300. }
  301. static inline output_gadget_t discarding_gadget(void)
  302. {
  303. output_gadget_t gadget;
  304. gadget.function = NULL;
  305. gadget.extra_function_arg = NULL;
  306. gadget.buffer = NULL;
  307. gadget.pos = 0;
  308. gadget.max_chars = 0;
  309. return gadget;
  310. }
  311. static inline output_gadget_t buffer_gadget(char* buffer, size_t buffer_size)
  312. {
  313. printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ?
  314. PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t) buffer_size;
  315. output_gadget_t result = discarding_gadget();
  316. if (buffer != NULL) {
  317. result.buffer = buffer;
  318. result.max_chars = usable_buffer_size;
  319. }
  320. return result;
  321. }
  322. // internal secure strlen
  323. // @return The length of the string (excluding the terminating 0) limited by 'maxsize'
  324. // @note strlen uses size_t, but wes only use this function with printf_size_t
  325. // variables - hence the signature.
  326. static inline printf_size_t strnlen_s_(const char* str, printf_size_t maxsize)
  327. {
  328. const char* s;
  329. for (s = str; *s && maxsize--; ++s);
  330. return (printf_size_t)(s - str);
  331. }
  332. // internal test if char is a digit (0-9)
  333. // @return true if char is a digit
  334. static inline bool is_digit_(char ch)
  335. {
  336. return (ch >= '0') && (ch <= '9');
  337. }
  338. // internal ASCII string to printf_size_t conversion
  339. static printf_size_t atou_(const char** str)
  340. {
  341. printf_size_t i = 0U;
  342. while (is_digit_(**str)) {
  343. i = i * 10U + (printf_size_t)(*((*str)++) - '0');
  344. }
  345. return i;
  346. }
  347. // output the specified string in reverse, taking care of any zero-padding
  348. static void out_rev_(output_gadget_t* output, const char* buf, printf_size_t len, printf_size_t width, printf_flags_t flags)
  349. {
  350. const printf_size_t start_pos = output->pos;
  351. // pad spaces up to given width
  352. if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
  353. for (printf_size_t i = len; i < width; i++) {
  354. putchar_via_gadget(output, ' ');
  355. }
  356. }
  357. // reverse string
  358. while (len) {
  359. putchar_via_gadget(output, buf[--len]);
  360. }
  361. // append pad spaces up to given width
  362. if (flags & FLAGS_LEFT) {
  363. while (output->pos - start_pos < width) {
  364. putchar_via_gadget(output, ' ');
  365. }
  366. }
  367. }
  368. // Invoked by print_integer after the actual number has been printed, performing necessary
  369. // work on the number's prefix (as the number is initially printed in reverse order)
  370. static void print_integer_finalization(output_gadget_t* output, char* buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
  371. {
  372. printf_size_t unpadded_len = len;
  373. // pad with leading zeros
  374. {
  375. if (!(flags & FLAGS_LEFT)) {
  376. if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
  377. width--;
  378. }
  379. while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE)) {
  380. buf[len++] = '0';
  381. }
  382. }
  383. while ((len < precision) && (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE)) {
  384. buf[len++] = '0';
  385. }
  386. if (base == BASE_OCTAL && (len > unpadded_len)) {
  387. // Since we've written some zeros, we've satisfied the alternative format leading space requirement
  388. flags &= ~FLAGS_HASH;
  389. }
  390. }
  391. // handle hash
  392. if (flags & (FLAGS_HASH | FLAGS_POINTER)) {
  393. if (!(flags & FLAGS_PRECISION) && len && ((len == precision) || (len == width))) {
  394. // Let's take back some padding digits to fit in what will eventually
  395. // be the format-specific prefix
  396. if (unpadded_len < len) {
  397. len--; // This should suffice for BASE_OCTAL
  398. }
  399. if (len && (base == BASE_HEX || base == BASE_BINARY) && (unpadded_len < len)) {
  400. len--; // ... and an extra one for 0x or 0b
  401. }
  402. }
  403. if ((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) && (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE)) {
  404. buf[len++] = 'x';
  405. }
  406. else if ((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) && (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE)) {
  407. buf[len++] = 'X';
  408. }
  409. else if ((base == BASE_BINARY) && (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE)) {
  410. buf[len++] = 'b';
  411. }
  412. if (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE) {
  413. buf[len++] = '0';
  414. }
  415. }
  416. if (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE) {
  417. if (negative) {
  418. buf[len++] = '-';
  419. }
  420. else if (flags & FLAGS_PLUS) {
  421. buf[len++] = '+'; // ignore the space if the '+' exists
  422. }
  423. else if (flags & FLAGS_SPACE) {
  424. buf[len++] = ' ';
  425. }
  426. }
  427. out_rev_(output, buf, len, width, flags);
  428. }
  429. // An internal itoa-like function
  430. static void print_integer(output_gadget_t* output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
  431. {
  432. char buf[PKG_VSNPRINTF_INTEGER_BUFFER_SIZE];
  433. printf_size_t len = 0U;
  434. if (!value) {
  435. if ( !(flags & FLAGS_PRECISION) ) {
  436. buf[len++] = '0';
  437. flags &= ~FLAGS_HASH;
  438. // We drop this flag this since either the alternative and regular modes of the specifier
  439. // don't differ on 0 values, or (in the case of octal) we've already provided the special
  440. // handling for this mode.
  441. }
  442. else if (base == BASE_HEX) {
  443. flags &= ~FLAGS_HASH;
  444. // We drop this flag this since either the alternative and regular modes of the specifier
  445. // don't differ on 0 values
  446. }
  447. }
  448. else {
  449. do {
  450. const char digit = (char)(value % base);
  451. buf[len++] = (char)(digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10);
  452. value /= base;
  453. } while (value && (len < PKG_VSNPRINTF_INTEGER_BUFFER_SIZE));
  454. }
  455. print_integer_finalization(output, buf, len, negative, base, precision, width, flags);
  456. }
  457. #if defined(PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS) || defined(PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
  458. // Stores a fixed-precision representation of a double relative
  459. // to a fixed precision (which cannot be determined by examining this structure)
  460. struct double_components {
  461. int_fast64_t integral;
  462. int_fast64_t fractional;
  463. // ... truncation of the actual fractional part of the double value, scaled
  464. // by the precision value
  465. bool is_negative;
  466. };
  467. #define NUM_DECIMAL_DIGITS_IN_INT64_T 18
  468. #define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T
  469. static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = {
  470. 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08,
  471. 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17
  472. };
  473. #define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1
  474. // Break up a double number - which is known to be a finite non-negative number -
  475. // into its base-10 parts: integral - before the decimal point, and fractional - after it.
  476. // Taken the precision into account, but does not change it even internally.
  477. static struct double_components get_components(double number, printf_size_t precision)
  478. {
  479. struct double_components number_;
  480. number_.is_negative = get_sign_bit(number);
  481. double abs_number = (number_.is_negative) ? -number : number;
  482. number_.integral = (int_fast64_t)abs_number;
  483. double remainder = (abs_number - (double) number_.integral) * powers_of_10[precision];
  484. number_.fractional = (int_fast64_t)remainder;
  485. remainder -= (double) number_.fractional;
  486. if (remainder > 0.5) {
  487. ++number_.fractional;
  488. // handle rollover, e.g. case 0.99 with precision 1 is 1.0
  489. if ((double) number_.fractional >= powers_of_10[precision]) {
  490. number_.fractional = 0;
  491. ++number_.integral;
  492. }
  493. }
  494. else if ((remainder == 0.5) && ((number_.fractional == 0U) || (number_.fractional & 1U))) {
  495. // if halfway, round up if odd OR if last digit is 0
  496. ++number_.fractional;
  497. }
  498. if (precision == 0U) {
  499. remainder = abs_number - (double) number_.integral;
  500. if ((!(remainder < 0.5) || (remainder > 0.5)) && (number_.integral & 1)) {
  501. // exactly 0.5 and ODD, then round up
  502. // 1.5 -> 2, but 2.5 -> 2
  503. ++number_.integral;
  504. }
  505. }
  506. return number_;
  507. }
  508. #ifdef PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  509. struct scaling_factor {
  510. double raw_factor;
  511. bool multiply; // if true, need to multiply by raw_factor; otherwise need to divide by it
  512. };
  513. static double apply_scaling(double num, struct scaling_factor normalization)
  514. {
  515. return normalization.multiply ? num * normalization.raw_factor : num / normalization.raw_factor;
  516. }
  517. static double unapply_scaling(double normalized, struct scaling_factor normalization)
  518. {
  519. #if defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */
  520. // accounting for a static analysis bug in GCC 6.x and earlier
  521. #pragma GCC diagnostic push
  522. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  523. #endif
  524. return normalization.multiply ? normalized / normalization.raw_factor : normalized * normalization.raw_factor;
  525. #if defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */
  526. #pragma GCC diagnostic pop
  527. #endif
  528. }
  529. static struct scaling_factor update_normalization(struct scaling_factor sf, double extra_multiplicative_factor)
  530. {
  531. struct scaling_factor result;
  532. if (sf.multiply) {
  533. result.multiply = true;
  534. result.raw_factor = sf.raw_factor * extra_multiplicative_factor;
  535. }
  536. else {
  537. int factor_exp2 = get_exp2(get_bit_access(sf.raw_factor));
  538. int extra_factor_exp2 = get_exp2(get_bit_access(extra_multiplicative_factor));
  539. // Divide the larger-exponent raw raw_factor by the smaller
  540. if (PRINTF_ABS(factor_exp2) > PRINTF_ABS(extra_factor_exp2)) {
  541. result.multiply = false;
  542. result.raw_factor = sf.raw_factor / extra_multiplicative_factor;
  543. }
  544. else {
  545. result.multiply = true;
  546. result.raw_factor = extra_multiplicative_factor / sf.raw_factor;
  547. }
  548. }
  549. return result;
  550. }
  551. static struct double_components get_normalized_components(bool negative, printf_size_t precision, double non_normalized, struct scaling_factor normalization, int floored_exp10)
  552. {
  553. struct double_components components;
  554. components.is_negative = negative;
  555. double scaled = apply_scaling(non_normalized, normalization);
  556. bool close_to_representation_extremum = ( (-floored_exp10 + (int) precision) >= DBL_MAX_10_EXP - 1 );
  557. if (close_to_representation_extremum) {
  558. // We can't have a normalization factor which also accounts for the precision, i.e. moves
  559. // some decimal digits into the mantissa, since it's unrepresentable, or nearly unrepresentable.
  560. // So, we'll give up early on getting extra precision...
  561. return get_components(negative ? -scaled : scaled, precision);
  562. }
  563. components.integral = (int_fast64_t) scaled;
  564. double remainder = non_normalized - unapply_scaling((double) components.integral, normalization);
  565. double prec_power_of_10 = powers_of_10[precision];
  566. struct scaling_factor account_for_precision = update_normalization(normalization, prec_power_of_10);
  567. double scaled_remainder = apply_scaling(remainder, account_for_precision);
  568. double rounding_threshold = 0.5;
  569. components.fractional = (int_fast64_t) scaled_remainder; // when precision == 0, the assigned value should be 0
  570. scaled_remainder -= (double) components.fractional; //when precision == 0, this will not change scaled_remainder
  571. components.fractional += (scaled_remainder >= rounding_threshold);
  572. if (scaled_remainder == rounding_threshold) {
  573. // banker's rounding: Round towards the even number (making the mean error 0)
  574. components.fractional &= ~((int_fast64_t) 0x1);
  575. }
  576. // handle rollover, e.g. the case of 0.99 with precision 1 becoming (0,100),
  577. // and must then be corrected into (1, 0).
  578. // Note: for precision = 0, this will "translate" the rounding effect from
  579. // the fractional part to the integral part where it should actually be
  580. // felt (as prec_power_of_10 is 1)
  581. if ((double) components.fractional >= prec_power_of_10) {
  582. components.fractional = 0;
  583. ++components.integral;
  584. }
  585. return components;
  586. }
  587. #endif // PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  588. static void print_broken_up_decimal(
  589. struct double_components number_, output_gadget_t* output, printf_size_t precision,
  590. printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
  591. {
  592. if (precision != 0U) {
  593. // do fractional part, as an unsigned number
  594. printf_size_t count = precision;
  595. // %g/%G mandates we skip the trailing 0 digits...
  596. if ((flags & FLAGS_ADAPT_EXP) && !(flags & FLAGS_HASH) && (number_.fractional > 0)) {
  597. while(true) {
  598. int_fast64_t digit = number_.fractional % 10U;
  599. if (digit != 0) {
  600. break;
  601. }
  602. --count;
  603. number_.fractional /= 10U;
  604. }
  605. // ... and even the decimal point if there are no
  606. // non-zero fractional part digits (see below)
  607. }
  608. if (number_.fractional > 0 || !(flags & FLAGS_ADAPT_EXP) || (flags & FLAGS_HASH) ) {
  609. while (len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE) {
  610. --count;
  611. buf[len++] = (char)('0' + number_.fractional % 10U);
  612. if (!(number_.fractional /= 10U)) {
  613. break;
  614. }
  615. }
  616. // add extra 0s
  617. while ((len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE) && (count > 0U)) {
  618. buf[len++] = '0';
  619. --count;
  620. }
  621. if (len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE) {
  622. buf[len++] = '.';
  623. }
  624. }
  625. }
  626. else {
  627. if ((flags & FLAGS_HASH) && (len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE)) {
  628. buf[len++] = '.';
  629. }
  630. }
  631. // Write the integer part of the number (it comes after the fractional
  632. // since the character order is reversed)
  633. while (len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE) {
  634. buf[len++] = (char)('0' + (number_.integral % 10));
  635. if (!(number_.integral /= 10)) {
  636. break;
  637. }
  638. }
  639. // pad leading zeros
  640. if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
  641. if (width && (number_.is_negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
  642. width--;
  643. }
  644. while ((len < width) && (len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE)) {
  645. buf[len++] = '0';
  646. }
  647. }
  648. if (len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE) {
  649. if (number_.is_negative) {
  650. buf[len++] = '-';
  651. }
  652. else if (flags & FLAGS_PLUS) {
  653. buf[len++] = '+'; // ignore the space if the '+' exists
  654. }
  655. else if (flags & FLAGS_SPACE) {
  656. buf[len++] = ' ';
  657. }
  658. }
  659. out_rev_(output, buf, len, width, flags);
  660. }
  661. // internal ftoa for fixed decimal floating point
  662. static void print_decimal_number(output_gadget_t* output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, printf_size_t len)
  663. {
  664. struct double_components value_ = get_components(number, precision);
  665. print_broken_up_decimal(value_, output, precision, width, flags, buf, len);
  666. }
  667. #ifdef PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  668. // A floor function - but one which only works for numbers whose
  669. // floor value is representable by an int.
  670. static int bastardized_floor(double x)
  671. {
  672. if (x >= 0) { return (int) x; }
  673. int n = (int) x;
  674. return ( ((double) n) == x ) ? n : n-1;
  675. }
  676. // Computes the base-10 logarithm of the input number - which must be an actual
  677. // positive number (not infinity or NaN, nor a sub-normal)
  678. static double log10_of_positive(double positive_number)
  679. {
  680. // The implementation follows David Gay (https://www.ampl.com/netlib/fp/dtoa.c).
  681. //
  682. // Since log_10 ( M * 2^x ) = log_10(M) + x , we can separate the components of
  683. // our input number, and need only solve log_10(M) for M between 1 and 2 (as
  684. // the base-2 mantissa is always 1-point-something). In that limited range, a
  685. // Taylor series expansion of log10(x) should serve us well enough; and we'll
  686. // take the mid-point, 1.5, as the point of expansion.
  687. double_with_bit_access dwba = get_bit_access(positive_number);
  688. // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
  689. int exp2 = get_exp2(dwba);
  690. // drop the exponent, so dwba.F comes into the range [1,2)
  691. dwba.U = (dwba.U & (((double_uint_t) (1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) |
  692. ((double_uint_t) DOUBLE_BASE_EXPONENT << DOUBLE_STORED_MANTISSA_BITS);
  693. double z = (dwba.F - 1.5);
  694. return (
  695. // Taylor expansion around 1.5:
  696. 0.1760912590556812420 // Expansion term 0: ln(1.5) / ln(10)
  697. + z * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 2/3 / ln(10)
  698. #if PKG_VSNPRINTF_LOG10_TAYLOR_TERMS > 2
  699. - z*z * 0.0965098848673892950 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10)
  700. #if PKG_VSNPRINTF_LOG10_TAYLOR_TERMS > 3
  701. + z*z*z * 0.0428932821632841311 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10)
  702. #endif
  703. #endif
  704. // exact log_2 of the exponent x, with logarithm base change
  705. + exp2 * 0.30102999566398119521 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10)
  706. );
  707. }
  708. static double pow10_of_int(int floored_exp10)
  709. {
  710. // A crude hack for avoiding undesired behavior with barely-normal or slightly-subnormal values.
  711. if (floored_exp10 == DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10) {
  712. return DOUBLE_MAX_SUBNORMAL_POWER_OF_10;
  713. }
  714. // Compute 10^(floored_exp10) but (try to) make sure that doesn't overflow
  715. double_with_bit_access dwba;
  716. int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5);
  717. const double z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453;
  718. const double z2 = z * z;
  719. dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS;
  720. // compute exp(z) using continued fractions,
  721. // see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
  722. dwba.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
  723. return dwba.F;
  724. }
  725. static void print_exponential_number(output_gadget_t* output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, printf_size_t len)
  726. {
  727. const bool negative = get_sign_bit(number);
  728. // This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it
  729. double abs_number = negative ? -number : number;
  730. int floored_exp10;
  731. bool abs_exp10_covered_by_powers_table;
  732. struct scaling_factor normalization;
  733. // Determine the decimal exponent
  734. if (abs_number == 0.0) {
  735. // TODO: This is a special-case for 0.0 (and -0.0); but proper handling is required for denormals more generally.
  736. floored_exp10 = 0; // ... and no need to set a normalization factor or check the powers table
  737. }
  738. else {
  739. double exp10 = log10_of_positive(abs_number);
  740. floored_exp10 = bastardized_floor(exp10);
  741. double p10 = pow10_of_int(floored_exp10);
  742. // correct for rounding errors
  743. if (abs_number < p10) {
  744. floored_exp10--;
  745. p10 /= 10;
  746. }
  747. abs_exp10_covered_by_powers_table = PRINTF_ABS(floored_exp10) < PRINTF_MAX_PRECOMPUTED_POWER_OF_10;
  748. normalization.raw_factor = abs_exp10_covered_by_powers_table ? powers_of_10[PRINTF_ABS(floored_exp10)] : p10;
  749. }
  750. // We now begin accounting for the widths of the two parts of our printed field:
  751. // the decimal part after decimal exponent extraction, and the base-10 exponent part.
  752. // For both of these, the value of 0 has a special meaning, but not the same one:
  753. // a 0 exponent-part width means "don't print the exponent"; a 0 decimal-part width
  754. // means "use as many characters as necessary".
  755. bool fall_back_to_decimal_only_mode = false;
  756. if (flags & FLAGS_ADAPT_EXP) {
  757. int required_significant_digits = (precision == 0) ? 1 : (int) precision;
  758. // Should we want to fall-back to "%f" mode, and only print the decimal part?
  759. fall_back_to_decimal_only_mode = (floored_exp10 >= -4 && floored_exp10 < required_significant_digits);
  760. // Now, let's adjust the precision
  761. // This also decided how we adjust the precision value - as in "%g" mode,
  762. // "precision" is the number of _significant digits_, and this is when we "translate"
  763. // the precision value to an actual number of decimal digits.
  764. int precision_ = fall_back_to_decimal_only_mode ?
  765. (int) precision - 1 - floored_exp10 :
  766. (int) precision - 1; // the presence of the exponent ensures only one significant digit comes before the decimal point
  767. precision = (precision_ > 0 ? (unsigned) precision_ : 0U);
  768. flags |= FLAGS_PRECISION; // make sure print_broken_up_decimal respects our choice above
  769. }
  770. normalization.multiply = (floored_exp10 < 0 && abs_exp10_covered_by_powers_table);
  771. bool should_skip_normalization = (fall_back_to_decimal_only_mode || floored_exp10 == 0);
  772. struct double_components decimal_part_components =
  773. should_skip_normalization ?
  774. get_components(negative ? -abs_number : abs_number, precision) :
  775. get_normalized_components(negative, precision, abs_number, normalization, floored_exp10);
  776. // Account for roll-over, e.g. rounding from 9.99 to 100.0 - which effects
  777. // the exponent and may require additional tweaking of the parts
  778. if (fall_back_to_decimal_only_mode) {
  779. if ((flags & FLAGS_ADAPT_EXP) && floored_exp10 >= -1 && decimal_part_components.integral == powers_of_10[floored_exp10 + 1]) {
  780. floored_exp10++; // Not strictly necessary, since floored_exp10 is no longer really used
  781. precision--;
  782. // ... and it should already be the case that decimal_part_components.fractional == 0
  783. }
  784. // TODO: What about rollover strictly within the fractional part?
  785. }
  786. else {
  787. if (decimal_part_components.integral >= 10) {
  788. floored_exp10++;
  789. decimal_part_components.integral = 1;
  790. decimal_part_components.fractional = 0;
  791. }
  792. }
  793. // the floored_exp10 format is "E%+03d" and largest possible floored_exp10 value for a 64-bit double
  794. // is "307" (for 2^1023), so we set aside 4-5 characters overall
  795. printf_size_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(floored_exp10) < 100) ? 4U : 5U;
  796. printf_size_t decimal_part_width =
  797. ((flags & FLAGS_LEFT) && exp10_part_width) ?
  798. // We're padding on the right, so the width constraint is the exponent part's
  799. // problem, not the decimal part's, so we'll use as many characters as we need:
  800. 0U :
  801. // We're padding on the left; so the width constraint is the decimal part's
  802. // problem. Well, can both the decimal part and the exponent part fit within our overall width?
  803. ((width > exp10_part_width) ?
  804. // Yes, so we limit our decimal part's width.
  805. // (Note this is trivially valid even if we've fallen back to "%f" mode)
  806. width - exp10_part_width :
  807. // No; we just give up on any restriction on the decimal part and use as many
  808. // characters as we need
  809. 0U);
  810. const printf_size_t printed_exponential_start_pos = output->pos;
  811. print_broken_up_decimal(decimal_part_components, output, precision, decimal_part_width, flags, buf, len);
  812. if (! fall_back_to_decimal_only_mode) {
  813. putchar_via_gadget(output, (flags & FLAGS_UPPERCASE) ? 'E' : 'e');
  814. print_integer(output,
  815. ABS_FOR_PRINTING(floored_exp10),
  816. floored_exp10 < 0, 10, 0, exp10_part_width - 1,
  817. FLAGS_ZEROPAD | FLAGS_PLUS);
  818. if (flags & FLAGS_LEFT) {
  819. // We need to right-pad with spaces to meet the width requirement
  820. while (output->pos - printed_exponential_start_pos < width) {
  821. putchar_via_gadget(output, ' ');
  822. }
  823. }
  824. }
  825. }
  826. #endif // PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  827. static void print_floating_point(output_gadget_t* output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential)
  828. {
  829. char buf[PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE];
  830. printf_size_t len = 0U;
  831. // test for special values
  832. if (value != value) {
  833. out_rev_(output, "nan", 3, width, flags);
  834. return;
  835. }
  836. if (value < -DBL_MAX) {
  837. out_rev_(output, "fni-", 4, width, flags);
  838. return;
  839. }
  840. if (value > DBL_MAX) {
  841. out_rev_(output, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
  842. return;
  843. }
  844. if (!prefer_exponential &&
  845. ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) {
  846. // The required behavior of standard printf is to print _every_ integral-part digit -- which could mean
  847. // printing hundreds of characters, overflowing any fixed internal buffer and necessitating a more complicated
  848. // implementation.
  849. #ifdef PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  850. print_exponential_number(output, value, precision, width, flags, buf, len);
  851. #endif
  852. return;
  853. }
  854. // set default precision, if not set explicitly
  855. if (!(flags & FLAGS_PRECISION)) {
  856. precision = PKG_VSNPRINTF_DEFAULT_FLOAT_PRECISION;
  857. }
  858. // limit precision so that our integer holding the fractional part does not overflow
  859. while ((len < PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE) && (precision > PRINTF_MAX_SUPPORTED_PRECISION)) {
  860. buf[len++] = '0'; // This respects the precision in terms of result length only
  861. precision--;
  862. }
  863. #ifdef PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  864. if (prefer_exponential)
  865. print_exponential_number(output, value, precision, width, flags, buf, len);
  866. else
  867. #endif
  868. print_decimal_number(output, value, precision, width, flags, buf, len);
  869. }
  870. #endif // (PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS || PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
  871. // Advances the format pointer past the flags, and returns the parsed flags
  872. // due to the characters passed
  873. static printf_flags_t parse_flags(const char** format)
  874. {
  875. printf_flags_t flags = 0U;
  876. do {
  877. switch (**format) {
  878. case '0': flags |= FLAGS_ZEROPAD; (*format)++; break;
  879. case '-': flags |= FLAGS_LEFT; (*format)++; break;
  880. case '+': flags |= FLAGS_PLUS; (*format)++; break;
  881. case ' ': flags |= FLAGS_SPACE; (*format)++; break;
  882. case '#': flags |= FLAGS_HASH; (*format)++; break;
  883. default : return flags;
  884. }
  885. } while (true);
  886. }
  887. static inline void format_string_loop(output_gadget_t* output, const char* format, va_list args)
  888. {
  889. #ifdef PKG_VSNPRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
  890. #define ADVANCE_IN_FORMAT_STRING(cptr_) do { (cptr_)++; if (!*(cptr_)) return; } while(0)
  891. #else
  892. #define ADVANCE_IN_FORMAT_STRING(cptr_) (cptr_)++
  893. #endif
  894. while (*format)
  895. {
  896. if (*format != '%') {
  897. // A regular content character
  898. putchar_via_gadget(output, *format);
  899. format++;
  900. continue;
  901. }
  902. // We're parsing a format specifier: %[flags][width][.precision][length]
  903. ADVANCE_IN_FORMAT_STRING(format);
  904. printf_flags_t flags = parse_flags(&format);
  905. // evaluate width field
  906. printf_size_t width = 0U;
  907. if (is_digit_(*format)) {
  908. width = (printf_size_t) atou_(&format);
  909. }
  910. else if (*format == '*') {
  911. const int w = va_arg(args, int);
  912. if (w < 0) {
  913. flags |= FLAGS_LEFT; // reverse padding
  914. width = (printf_size_t)-w;
  915. }
  916. else {
  917. width = (printf_size_t)w;
  918. }
  919. ADVANCE_IN_FORMAT_STRING(format);
  920. }
  921. // evaluate precision field
  922. printf_size_t precision = 0U;
  923. if (*format == '.') {
  924. flags |= FLAGS_PRECISION;
  925. ADVANCE_IN_FORMAT_STRING(format);
  926. if (is_digit_(*format)) {
  927. precision = (printf_size_t) atou_(&format);
  928. }
  929. else if (*format == '*') {
  930. const int precision_ = va_arg(args, int);
  931. precision = precision_ > 0 ? (printf_size_t) precision_ : 0U;
  932. ADVANCE_IN_FORMAT_STRING(format);
  933. }
  934. }
  935. // evaluate length field
  936. switch (*format) {
  937. #ifdef PKG_VSNPRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
  938. case 'I' : {
  939. ADVANCE_IN_FORMAT_STRING(format);
  940. // Greedily parse for size in bits: 8, 16, 32 or 64
  941. switch(*format) {
  942. case '8': flags |= FLAGS_INT8;
  943. ADVANCE_IN_FORMAT_STRING(format);
  944. break;
  945. case '1':
  946. ADVANCE_IN_FORMAT_STRING(format);
  947. if (*format == '6') { format++; flags |= FLAGS_INT16; }
  948. break;
  949. case '3':
  950. ADVANCE_IN_FORMAT_STRING(format);
  951. if (*format == '2') { ADVANCE_IN_FORMAT_STRING(format); flags |= FLAGS_INT32; }
  952. break;
  953. case '6':
  954. ADVANCE_IN_FORMAT_STRING(format);
  955. if (*format == '4') { ADVANCE_IN_FORMAT_STRING(format); flags |= FLAGS_INT64; }
  956. break;
  957. default: break;
  958. }
  959. break;
  960. }
  961. #endif
  962. case 'l' :
  963. flags |= FLAGS_LONG;
  964. ADVANCE_IN_FORMAT_STRING(format);
  965. if (*format == 'l') {
  966. flags |= FLAGS_LONG_LONG;
  967. ADVANCE_IN_FORMAT_STRING(format);
  968. }
  969. break;
  970. case 'h' :
  971. flags |= FLAGS_SHORT;
  972. ADVANCE_IN_FORMAT_STRING(format);
  973. if (*format == 'h') {
  974. flags |= FLAGS_CHAR;
  975. ADVANCE_IN_FORMAT_STRING(format);
  976. }
  977. break;
  978. case 't' :
  979. flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
  980. ADVANCE_IN_FORMAT_STRING(format);
  981. break;
  982. case 'j' :
  983. flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
  984. ADVANCE_IN_FORMAT_STRING(format);
  985. break;
  986. case 'z' :
  987. flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
  988. ADVANCE_IN_FORMAT_STRING(format);
  989. break;
  990. default:
  991. break;
  992. }
  993. // evaluate specifier
  994. switch (*format) {
  995. case 'd' :
  996. case 'i' :
  997. case 'u' :
  998. case 'x' :
  999. case 'X' :
  1000. case 'o' :
  1001. case 'b' : {
  1002. if (*format == 'd' || *format == 'i') {
  1003. flags |= FLAGS_SIGNED;
  1004. }
  1005. numeric_base_t base;
  1006. if (*format == 'x' || *format == 'X') {
  1007. base = BASE_HEX;
  1008. }
  1009. else if (*format == 'o') {
  1010. base = BASE_OCTAL;
  1011. }
  1012. else if (*format == 'b') {
  1013. base = BASE_BINARY;
  1014. }
  1015. else {
  1016. base = BASE_DECIMAL;
  1017. flags &= ~FLAGS_HASH; // decimal integers have no alternative presentation
  1018. }
  1019. if (*format == 'X') {
  1020. flags |= FLAGS_UPPERCASE;
  1021. }
  1022. format++;
  1023. // ignore '0' flag when precision is given
  1024. if (flags & FLAGS_PRECISION) {
  1025. flags &= ~FLAGS_ZEROPAD;
  1026. }
  1027. if (flags & FLAGS_SIGNED) {
  1028. // A signed specifier: d, i or possibly I + bit size if enabled
  1029. if (flags & FLAGS_LONG_LONG) {
  1030. #ifdef PKG_VSNPRINTF_SUPPORT_LONG_LONG
  1031. const long long value = va_arg(args, long long);
  1032. print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags);
  1033. #endif
  1034. }
  1035. else if (flags & FLAGS_LONG) {
  1036. const long value = va_arg(args, long);
  1037. print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags);
  1038. }
  1039. else {
  1040. // We never try to interpret the argument as something potentially-smaller than int,
  1041. // due to integer promotion rules: Even if the user passed a short int, short unsigned
  1042. // etc. - these will come in after promotion, as int's (or unsigned for the case of
  1043. // short unsigned when it has the same size as int)
  1044. const int value =
  1045. (flags & FLAGS_CHAR) ? (signed char) va_arg(args, int) :
  1046. (flags & FLAGS_SHORT) ? (short int) va_arg(args, int) :
  1047. va_arg(args, int);
  1048. print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags);
  1049. }
  1050. }
  1051. else {
  1052. // An unsigned specifier: u, x, X, o, b
  1053. flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
  1054. if (flags & FLAGS_LONG_LONG) {
  1055. #ifdef PKG_VSNPRINTF_SUPPORT_LONG_LONG
  1056. print_integer(output, (printf_unsigned_value_t) va_arg(args, unsigned long long), false, base, precision, width, flags);
  1057. #endif
  1058. }
  1059. else if (flags & FLAGS_LONG) {
  1060. print_integer(output, (printf_unsigned_value_t) va_arg(args, unsigned long), false, base, precision, width, flags);
  1061. }
  1062. else {
  1063. const unsigned int value =
  1064. (flags & FLAGS_CHAR) ? (unsigned char)va_arg(args, unsigned int) :
  1065. (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(args, unsigned int) :
  1066. va_arg(args, unsigned int);
  1067. print_integer(output, (printf_unsigned_value_t) value, false, base, precision, width, flags);
  1068. }
  1069. }
  1070. break;
  1071. }
  1072. #ifdef PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS
  1073. case 'f' :
  1074. case 'F' :
  1075. if (*format == 'F') flags |= FLAGS_UPPERCASE;
  1076. print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_DECIMAL);
  1077. format++;
  1078. break;
  1079. #endif
  1080. #ifdef PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  1081. case 'e':
  1082. case 'E':
  1083. case 'g':
  1084. case 'G':
  1085. if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
  1086. if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
  1087. print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_EXPONENTIAL);
  1088. format++;
  1089. break;
  1090. #endif // PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
  1091. case 'c' : {
  1092. printf_size_t l = 1U;
  1093. // pre padding
  1094. if (!(flags & FLAGS_LEFT)) {
  1095. while (l++ < width) {
  1096. putchar_via_gadget(output, ' ');
  1097. }
  1098. }
  1099. // char output
  1100. putchar_via_gadget(output, (char) va_arg(args, int) );
  1101. // post padding
  1102. if (flags & FLAGS_LEFT) {
  1103. while (l++ < width) {
  1104. putchar_via_gadget(output, ' ');
  1105. }
  1106. }
  1107. format++;
  1108. break;
  1109. }
  1110. case 's' : {
  1111. const char* p = va_arg(args, char*);
  1112. if (p == NULL) {
  1113. out_rev_(output, ")llun(", 6, width, flags);
  1114. }
  1115. else {
  1116. printf_size_t l = strnlen_s_(p, precision ? precision : PRINTF_MAX_POSSIBLE_BUFFER_SIZE);
  1117. // pre padding
  1118. if (flags & FLAGS_PRECISION) {
  1119. l = (l < precision ? l : precision);
  1120. }
  1121. if (!(flags & FLAGS_LEFT)) {
  1122. while (l++ < width) {
  1123. putchar_via_gadget(output, ' ');
  1124. }
  1125. }
  1126. // string output
  1127. while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision)) {
  1128. putchar_via_gadget(output, *(p++));
  1129. --precision;
  1130. }
  1131. // post padding
  1132. if (flags & FLAGS_LEFT) {
  1133. while (l++ < width) {
  1134. putchar_via_gadget(output, ' ');
  1135. }
  1136. }
  1137. }
  1138. format++;
  1139. break;
  1140. }
  1141. case 'p' : {
  1142. width = sizeof(void*) * 2U + 2; // 2 hex chars per byte + the "0x" prefix
  1143. flags |= FLAGS_ZEROPAD | FLAGS_POINTER;
  1144. uintptr_t value = (uintptr_t)va_arg(args, void*);
  1145. (value == (uintptr_t) NULL) ?
  1146. out_rev_(output, ")lin(", 5, width, flags) :
  1147. print_integer(output, (printf_unsigned_value_t) value, false, BASE_HEX, precision, width, flags);
  1148. format++;
  1149. break;
  1150. }
  1151. case '%' :
  1152. putchar_via_gadget(output, '%');
  1153. format++;
  1154. break;
  1155. // Many people prefer to disable support for %n, as it lets the caller
  1156. // engineer a write to an arbitrary location, of a value the caller
  1157. // effectively controls - which could be a security concern in some cases.
  1158. #ifdef PKG_VSNPRINTF_SUPPORT_WRITEBACK_SPECIFIER
  1159. case 'n' : {
  1160. if (flags & FLAGS_CHAR) *(va_arg(args, char*)) = (char) output->pos;
  1161. else if (flags & FLAGS_SHORT) *(va_arg(args, short*)) = (short) output->pos;
  1162. else if (flags & FLAGS_LONG) *(va_arg(args, long*)) = (long) output->pos;
  1163. #ifdef PKG_VSNPRINTF_SUPPORT_LONG_LONG
  1164. else if (flags & FLAGS_LONG_LONG) *(va_arg(args, long long*)) = (long long int) output->pos;
  1165. #endif // PKG_VSNPRINTF_SUPPORT_LONG_LONG
  1166. else *(va_arg(args, int*)) = (int) output->pos;
  1167. format++;
  1168. break;
  1169. }
  1170. #endif // PKG_VSNPRINTF_SUPPORT_WRITEBACK_SPECIFIER
  1171. default :
  1172. putchar_via_gadget(output, *format);
  1173. format++;
  1174. break;
  1175. }
  1176. }
  1177. }
  1178. // internal vsnprintf - used for implementing _all library functions
  1179. static int vsnprintf_impl(output_gadget_t* output, const char* format, va_list args)
  1180. {
  1181. // Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is
  1182. // possible to call this function with a non-zero pos value for some "remedial printing".
  1183. format_string_loop(output, format, args);
  1184. // termination
  1185. append_termination_with_gadget(output);
  1186. // return written chars without terminating \0
  1187. return (int)output->pos;
  1188. }
  1189. ///////////////////////////////////////////////////////////////////////////////
  1190. /**
  1191. * This function will fill a formatted string to buffer.
  1192. *
  1193. * @param buf is the buffer to save formatted string.
  1194. *
  1195. * @param size is the size of buffer.
  1196. *
  1197. * @param fmt is the format parameters.
  1198. *
  1199. * @param args is a list of variable parameters.
  1200. *
  1201. * @return The number of characters actually written to buffer.
  1202. */
  1203. #if (RTTHREAD_VERSION >= 40100) || (RTTHREAD_VERSION < 40000 && RTTHREAD_VERSION >= 30106)
  1204. int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args)
  1205. #else
  1206. rt_int32_t rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args)
  1207. #endif
  1208. {
  1209. output_gadget_t gadget = buffer_gadget(buf, size);
  1210. return vsnprintf_impl(&gadget, fmt, args);
  1211. }
  1212. #ifdef RT_VSNPRINTF_FULL_REPLACING_VSNPRINTF
  1213. int vsnprintf(char * s, size_t n, const char * format, va_list arg)
  1214. {
  1215. return rt_vsnprintf(s, n, format, arg);
  1216. }
  1217. #endif
  1218. #ifdef RT_VSNPRINTF_FULL_REPLACING_VSPRINTF
  1219. int vsprintf(char * s, const char * format, va_list arg)
  1220. {
  1221. return rt_vsprintf(s, format, arg);
  1222. }
  1223. #endif