45#define SYSCLIB_DISABLE_BUILTINS
54#if PRINTF_INCLUDE_CONFIG_H
55#include "printf_config.h"
63#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
64# define printf_ printf
65# define sprintf_ sprintf
66# define vsprintf_ vsprintf
67# define snprintf_ snprintf
68# define vsnprintf_ vsnprintf
69# define vprintf_ vprintf
75#ifndef PRINTF_INTEGER_BUFFER_SIZE
76#define PRINTF_INTEGER_BUFFER_SIZE 32
82#ifndef PRINTF_DECIMAL_BUFFER_SIZE
83#define PRINTF_DECIMAL_BUFFER_SIZE 32
87#ifndef PRINTF_SUPPORT_DECIMAL_SPECIFIERS
88#define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 1
92#ifndef PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
93#define PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS 1
97#ifndef PRINTF_SUPPORT_WRITEBACK_SPECIFIER
98#define PRINTF_SUPPORT_WRITEBACK_SPECIFIER 1
102#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
103#define PRINTF_DEFAULT_FLOAT_PRECISION 6
110#ifndef PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL
111#define PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9
116#ifndef PRINTF_SUPPORT_LONG_LONG
117#define PRINTF_SUPPORT_LONG_LONG 1
123#ifndef PRINTF_LOG10_TAYLOR_TERMS
124#define PRINTF_LOG10_TAYLOR_TERMS 4
127#if PRINTF_LOG10_TAYLOR_TERMS <= 1
128#error "At least one non-constant Taylor expansion is necessary for the log10() calculation"
132#define PRINTF_PREFER_DECIMAL false
133#define PRINTF_PREFER_EXPONENTIAL true
138#define PRINTF_CONCATENATE(s1, s2) s1##s2
139#define PRINTF_EXPAND_THEN_CONCATENATE(s1, s2) PRINTF_CONCATENATE(s1, s2)
140#define PRINTF_FLOAT_NOTATION_THRESHOLD PRINTF_EXPAND_THEN_CONCATENATE(1e,PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL)
143#define FLAGS_ZEROPAD (1U << 0U)
144#define FLAGS_LEFT (1U << 1U)
145#define FLAGS_PLUS (1U << 2U)
146#define FLAGS_SPACE (1U << 3U)
147#define FLAGS_HASH (1U << 4U)
148#define FLAGS_UPPERCASE (1U << 5U)
149#define FLAGS_CHAR (1U << 6U)
150#define FLAGS_SHORT (1U << 7U)
151#define FLAGS_INT (1U << 8U)
153#define FLAGS_LONG (1U << 9U)
154#define FLAGS_LONG_LONG (1U << 10U)
155#define FLAGS_PRECISION (1U << 11U)
156#define FLAGS_ADAPT_EXP (1U << 12U)
157#define FLAGS_POINTER (1U << 13U)
159#define FLAGS_SIGNED (1U << 14U)
162#ifdef PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
164#define FLAGS_INT8 FLAGS_CHAR
167#if (SHRT_MAX == 32767LL)
168#define FLAGS_INT16 FLAGS_SHORT
169#elif (INT_MAX == 32767LL)
170#define FLAGS_INT16 FLAGS_INT
171#elif (LONG_MAX == 32767LL)
172#define FLAGS_INT16 FLAGS_LONG
173#elif (LLONG_MAX == 32767LL)
174#define FLAGS_INT16 FLAGS_LONG_LONG
176#error "No basic integer type has a size of 16 bits exactly"
179#if (SHRT_MAX == 2147483647LL)
180#define FLAGS_INT32 FLAGS_SHORT
181#elif (INT_MAX == 2147483647LL)
182#define FLAGS_INT32 FLAGS_INT
183#elif (LONG_MAX == 2147483647LL)
184#define FLAGS_INT32 FLAGS_LONG
185#elif (LLONG_MAX == 2147483647LL)
186#define FLAGS_INT32 FLAGS_LONG_LONG
188#error "No basic integer type has a size of 32 bits exactly"
191#if (SHRT_MAX == 9223372036854775807LL)
192#define FLAGS_INT64 FLAGS_SHORT
193#elif (INT_MAX == 9223372036854775807LL)
194#define FLAGS_INT64 FLAGS_INT
195#elif (LONG_MAX == 9223372036854775807LL)
196#define FLAGS_INT64 FLAGS_LONG
197#elif (LLONG_MAX == 9223372036854775807LL)
198#define FLAGS_INT64 FLAGS_LONG_LONG
200#error "No basic integer type has a size of 64 bits exactly"
206typedef unsigned int printf_flags_t;
210#define BASE_DECIMAL 10
213typedef uint8_t numeric_base_t;
215#if PRINTF_SUPPORT_LONG_LONG
216typedef unsigned long long printf_unsigned_value_t;
217typedef long long printf_signed_value_t;
219typedef unsigned long printf_unsigned_value_t;
220typedef long printf_signed_value_t;
228typedef unsigned int printf_size_t;
229#define PRINTF_MAX_POSSIBLE_BUFFER_SIZE INT_MAX
234#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
237#error "Non-binary-radix floating-point types are unsupported."
240#if DBL_MANT_DIG == 24
242#define DOUBLE_SIZE_IN_BITS 32
243typedef uint32_t double_uint_t;
244#define DOUBLE_EXPONENT_MASK 0xFFU
245#define DOUBLE_BASE_EXPONENT 127
246#define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -38
247#define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-38
249#elif DBL_MANT_DIG == 53
251#define DOUBLE_SIZE_IN_BITS 64
252typedef uint64_t double_uint_t;
253#define DOUBLE_EXPONENT_MASK 0x7FFU
254#define DOUBLE_BASE_EXPONENT 1023
255#define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -308
256#define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-308
259#error "Unsupported double type configuration"
261#define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1)
280static inline int get_sign_bit(
double x)
283 return (
int) (get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
292 return (
int)((x.U >> DOUBLE_STORED_MANTISSA_BITS ) & DOUBLE_EXPONENT_MASK) - DOUBLE_BASE_EXPONENT;
294#define PRINTF_ABS(_x) ( (_x) > 0 ? (_x) : -(_x) )
301#define ABS_FOR_PRINTING(_x) ((printf_unsigned_value_t) ( (_x) > 0 ? (_x) : -((printf_signed_value_t)_x) ))
312 void (*function)(
char c,
void* extra_arg);
313 void* extra_function_arg;
316 printf_size_t max_chars;
325 printf_size_t write_pos = gadget->pos++;
328 if (write_pos >= gadget->max_chars) {
331 if (gadget->function != NULL) {
333 gadget->function(c, gadget->extra_function_arg);
338 gadget->buffer[write_pos] = c;
343static inline void append_termination_with_gadget(
output_gadget_t* gadget)
345 if (gadget->function != NULL || gadget->max_chars == 0) {
348 if (gadget->buffer == NULL) {
351 printf_size_t null_char_pos = gadget->pos < gadget->max_chars ? gadget->pos : gadget->max_chars - 1;
352 gadget->buffer[null_char_pos] =
'\0';
358static inline void putchar_wrapper(
char c,
void* unused)
368 gadget.function = NULL;
369 gadget.extra_function_arg = NULL;
370 gadget.buffer = NULL;
372 gadget.max_chars = 0;
376static inline output_gadget_t buffer_gadget(
char* buffer,
size_t buffer_size)
378 printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ?
379 PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t) buffer_size;
381 if (buffer != NULL) {
382 result.buffer = buffer;
383 result.max_chars = usable_buffer_size;
388static inline output_gadget_t function_gadget(
void (*function)(
char,
void*),
void* extra_arg)
391 result.function = function;
392 result.extra_function_arg = extra_arg;
393 result.max_chars = PRINTF_MAX_POSSIBLE_BUFFER_SIZE;
400 return function_gadget(putchar_wrapper, NULL);
408static inline printf_size_t strnlen_s_(
const char* str, printf_size_t maxsize)
411 for (s = str; *s && maxsize--; ++s);
412 return (printf_size_t)(s - str);
418static inline bool is_digit_(
char ch)
420 return (ch >=
'0') && (ch <=
'9');
425static printf_size_t atou_(
const char** str)
427 printf_size_t i = 0U;
428 while (is_digit_(**str)) {
429 i = i * 10U + (printf_size_t)(*((*str)++) -
'0');
436static void out_rev_(
output_gadget_t* output,
const char* buf, printf_size_t len, printf_size_t width, printf_flags_t flags)
438 const printf_size_t start_pos = output->pos;
441 if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
442 for (printf_size_t i = len; i < width; i++) {
443 putchar_via_gadget(output,
' ');
449 putchar_via_gadget(output, buf[--len]);
453 if (flags & FLAGS_LEFT) {
454 while (output->pos - start_pos < width) {
455 putchar_via_gadget(output,
' ');
463static 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)
465 printf_size_t unpadded_len = len;
469 if (!(flags & FLAGS_LEFT)) {
470 if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
473 while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
478 while ((len < precision) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
482 if (base == BASE_OCTAL && (len > unpadded_len)) {
484 flags &= ~FLAGS_HASH;
489 if (flags & (FLAGS_HASH | FLAGS_POINTER)) {
490 if (!(flags & FLAGS_PRECISION) && len && ((len == precision) || (len == width))) {
493 if (unpadded_len < len) {
496 if (len && (base == BASE_HEX || base == BASE_BINARY) && (unpadded_len < len)) {
500 if ((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
503 else if ((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
506 else if ((base == BASE_BINARY) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
509 if (len < PRINTF_INTEGER_BUFFER_SIZE) {
514 if (len < PRINTF_INTEGER_BUFFER_SIZE) {
518 else if (flags & FLAGS_PLUS) {
521 else if (flags & FLAGS_SPACE) {
526 out_rev_(output, buf, len, width, flags);
530static 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)
532 char buf[PRINTF_INTEGER_BUFFER_SIZE];
533 printf_size_t len = 0U;
536 if ( !(flags & FLAGS_PRECISION) ) {
538 flags &= ~FLAGS_HASH;
543 else if (base == BASE_HEX) {
544 flags &= ~FLAGS_HASH;
551 const char digit = (char)(value % base);
552 buf[len++] = (char)(digit < 10 ?
'0' + digit : (flags & FLAGS_UPPERCASE ?
'A' :
'a') + digit - 10);
554 }
while (value && (len < PRINTF_INTEGER_BUFFER_SIZE));
557 print_integer_finalization(output, buf, len, negative, base, precision, width, flags);
560#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
565 int_fast64_t integral;
566 int_fast64_t fractional;
572#define NUM_DECIMAL_DIGITS_IN_INT64_T 18
573#define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T
574static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = {
575 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08,
576 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17
579#define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1
585static struct double_components get_components(double number, printf_size_t precision)
588 number_.is_negative = get_sign_bit(number);
589 double abs_number = (number_.is_negative) ? -number : number;
590 number_.integral = (int_fast64_t)abs_number;
591 double remainder = (abs_number - (double) number_.integral) * powers_of_10[precision];
592 number_.fractional = (int_fast64_t)remainder;
594 remainder -= (double) number_.fractional;
596 if (remainder > 0.5) {
597 ++number_.fractional;
599 if ((
double) number_.fractional >= powers_of_10[precision]) {
600 number_.fractional = 0;
604 else if ((remainder == 0.5) && ((number_.fractional == 0U) || (number_.fractional & 1U))) {
606 ++number_.fractional;
609 if (precision == 0U) {
610 remainder = abs_number - (double) number_.integral;
611 if ((!(remainder < 0.5) || (remainder > 0.5)) && (number_.integral & 1)) {
620#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
626static double apply_scaling(
double num,
struct scaling_factor normalization)
628 return normalization.multiply ? num * normalization.raw_factor : num / normalization.raw_factor;
631static double unapply_scaling(
double normalized,
struct scaling_factor normalization)
633 return normalization.multiply ? normalized / normalization.raw_factor : normalized * normalization.raw_factor;
640 result.multiply =
true;
641 result.raw_factor = sf.raw_factor * extra_multiplicative_factor;
644 int factor_exp2 = get_exp2(get_bit_access(sf.raw_factor));
645 int extra_factor_exp2 = get_exp2(get_bit_access(extra_multiplicative_factor));
648 if (PRINTF_ABS(factor_exp2) > PRINTF_ABS(extra_factor_exp2)) {
649 result.multiply =
false;
650 result.raw_factor = sf.raw_factor / extra_multiplicative_factor;
653 result.multiply =
true;
654 result.raw_factor = extra_multiplicative_factor / sf.raw_factor;
660static struct double_components get_normalized_components(bool negative, printf_size_t precision, double non_normalized, struct
scaling_factor normalization, int floored_exp10)
663 components.is_negative = negative;
664 double scaled = apply_scaling(non_normalized, normalization);
666 bool close_to_representation_extremum = ( (-floored_exp10 + (int) precision) >= DBL_MAX_10_EXP - 1 );
667 if (close_to_representation_extremum) {
671 return get_components(negative ? -scaled : scaled, precision);
673 components.integral = (int_fast64_t) scaled;
674 double remainder = non_normalized - unapply_scaling((
double) components.integral, normalization);
675 double prec_power_of_10 = powers_of_10[precision];
676 struct scaling_factor account_for_precision = update_normalization(normalization, prec_power_of_10);
677 double scaled_remainder = apply_scaling(remainder, account_for_precision);
678 double rounding_threshold = 0.5;
680 components.fractional = (int_fast64_t) scaled_remainder;
681 scaled_remainder -= (double) components.fractional;
683 components.fractional += (scaled_remainder >= rounding_threshold);
684 if (scaled_remainder == rounding_threshold) {
686 components.fractional &= ~((int_fast64_t) 0x1);
693 if ((
double) components.fractional >= prec_power_of_10) {
694 components.fractional = 0;
695 ++components.integral;
701static void print_broken_up_decimal(
703 printf_size_t width, printf_flags_t flags,
char *buf, printf_size_t len)
705 if (precision != 0U) {
708 printf_size_t
count = precision;
711 if ((flags & FLAGS_ADAPT_EXP) && !(flags & FLAGS_HASH) && (number_.fractional > 0)) {
713 int_fast64_t digit = number_.fractional % 10U;
718 number_.fractional /= 10U;
725 if (number_.fractional > 0 || !(flags & FLAGS_ADAPT_EXP) || (flags & FLAGS_HASH) ) {
726 while (len < PRINTF_DECIMAL_BUFFER_SIZE) {
728 buf[len++] = (char)(
'0' + number_.fractional % 10U);
729 if (!(number_.fractional /= 10U)) {
734 while ((len < PRINTF_DECIMAL_BUFFER_SIZE) && (
count > 0U)) {
738 if (len < PRINTF_DECIMAL_BUFFER_SIZE) {
744 if ((flags & FLAGS_HASH) && (len < PRINTF_DECIMAL_BUFFER_SIZE)) {
751 while (len < PRINTF_DECIMAL_BUFFER_SIZE) {
752 buf[len++] = (char)(
'0' + (number_.integral % 10));
753 if (!(number_.integral /= 10)) {
759 if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
760 if (width && (number_.is_negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
763 while ((len < width) && (len < PRINTF_DECIMAL_BUFFER_SIZE)) {
768 if (len < PRINTF_DECIMAL_BUFFER_SIZE) {
769 if (number_.is_negative) {
772 else if (flags & FLAGS_PLUS) {
775 else if (flags & FLAGS_SPACE) {
780 out_rev_(output, buf, len, width, flags);
784static 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)
787 print_broken_up_decimal(value_, output, precision, width, flags, buf, len);
790#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
794static int bastardized_floor(
double x)
796 if (x >= 0) {
return (
int) x; }
798 return ( ((
double) n) == x ) ? n : n-1;
803static double log10_of_positive(
double positive_number)
815 int exp2 = get_exp2(dwba);
817 dwba.U = (dwba.U & (((double_uint_t) (1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) |
818 ((double_uint_t) DOUBLE_BASE_EXPONENT << DOUBLE_STORED_MANTISSA_BITS);
819 double z = (dwba.F - 1.5);
822 0.1760912590556812420
823 + z * 0.2895296546021678851
824#
if PRINTF_LOG10_TAYLOR_TERMS > 2
825 - z*z * 0.0965098848673892950
826#
if PRINTF_LOG10_TAYLOR_TERMS > 3
827 + z*z*z * 0.0428932821632841311
831 + exp2 * 0.30102999566398119521
836static double pow10_of_int(
int floored_exp10)
839 if (floored_exp10 == DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10) {
840 return DOUBLE_MAX_SUBNORMAL_POWER_OF_10;
844 int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5);
845 const double z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453;
846 const double z2 = z * z;
847 dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS;
850 dwba.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
854static 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)
856 const bool negative = get_sign_bit(number);
858 double abs_number = negative ? -number : number;
861 bool abs_exp10_covered_by_powers_table;
866 if (abs_number == 0.0) {
871 double exp10 = log10_of_positive(abs_number);
872 floored_exp10 = bastardized_floor(exp10);
873 double p10 = pow10_of_int(floored_exp10);
875 if (abs_number < p10) {
879 abs_exp10_covered_by_powers_table = PRINTF_ABS(floored_exp10) < PRINTF_MAX_PRECOMPUTED_POWER_OF_10;
880 normalization.raw_factor = abs_exp10_covered_by_powers_table ? powers_of_10[PRINTF_ABS(floored_exp10)] : p10;
889 bool fall_back_to_decimal_only_mode =
false;
890 if (flags & FLAGS_ADAPT_EXP) {
891 int required_significant_digits = (precision == 0) ? 1 : (int) precision;
893 fall_back_to_decimal_only_mode = (floored_exp10 >= -4 && floored_exp10 < required_significant_digits);
898 int precision_ = fall_back_to_decimal_only_mode ?
899 (int) precision - 1 - floored_exp10 :
901 precision = (precision_ > 0 ? (unsigned) precision_ : 0U);
902 flags |= FLAGS_PRECISION;
905 normalization.multiply = (floored_exp10 < 0 && abs_exp10_covered_by_powers_table);
906 bool should_skip_normalization = (fall_back_to_decimal_only_mode || floored_exp10 == 0);
908 should_skip_normalization ?
909 get_components(negative ? -abs_number : abs_number, precision) :
910 get_normalized_components(negative, precision, abs_number, normalization, floored_exp10);
914 if (fall_back_to_decimal_only_mode) {
915 if ((flags & FLAGS_ADAPT_EXP) && floored_exp10 >= -1 && decimal_part_components.integral == powers_of_10[floored_exp10 + 1]) {
923 if (decimal_part_components.integral >= 10) {
925 decimal_part_components.integral = 1;
926 decimal_part_components.fractional = 0;
932 printf_size_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(floored_exp10) < 100) ? 4U : 5U;
934 printf_size_t decimal_part_width =
935 ((flags & FLAGS_LEFT) && exp10_part_width) ?
941 ((width > exp10_part_width) ?
944 width - exp10_part_width :
949 const printf_size_t printed_exponential_start_pos = output->pos;
950 print_broken_up_decimal(decimal_part_components, output, precision, decimal_part_width, flags, buf, len);
952 if (! fall_back_to_decimal_only_mode) {
953 putchar_via_gadget(output, (flags & FLAGS_UPPERCASE) ?
'E' :
'e');
954 print_integer(output,
955 ABS_FOR_PRINTING(floored_exp10),
956 floored_exp10 < 0, 10, 0, exp10_part_width - 1,
957 FLAGS_ZEROPAD | FLAGS_PLUS);
958 if (flags & FLAGS_LEFT) {
960 while (output->pos - printed_exponential_start_pos < width) {
961 putchar_via_gadget(output,
' ');
968static 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)
970 char buf[PRINTF_DECIMAL_BUFFER_SIZE];
971 printf_size_t len = 0U;
974 if (value != value) {
975 out_rev_(output,
"nan", 3, width, flags);
978 if (value < -DBL_MAX) {
979 out_rev_(output,
"fni-", 4, width, flags);
982 if (value > DBL_MAX) {
983 out_rev_(output, (flags & FLAGS_PLUS) ?
"fni+" :
"fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
987 if (!prefer_exponential &&
988 ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) {
992#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
993 print_exponential_number(output, value, precision, width, flags, buf, len);
999 if (!(flags & FLAGS_PRECISION)) {
1000 precision = PRINTF_DEFAULT_FLOAT_PRECISION;
1004 while ((len < PRINTF_DECIMAL_BUFFER_SIZE) && (precision > PRINTF_MAX_SUPPORTED_PRECISION)) {
1009#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
1010 if (prefer_exponential)
1011 print_exponential_number(output, value, precision, width, flags, buf, len);
1014 print_decimal_number(output, value, precision, width, flags, buf, len);
1021static printf_flags_t parse_flags(
const char** format)
1023 printf_flags_t flags = 0U;
1026 case '0': flags |= FLAGS_ZEROPAD; (*format)++;
break;
1027 case '-': flags |= FLAGS_LEFT; (*format)++;
break;
1028 case '+': flags |= FLAGS_PLUS; (*format)++;
break;
1029 case ' ': flags |= FLAGS_SPACE; (*format)++;
break;
1030 case '#': flags |= FLAGS_HASH; (*format)++;
break;
1031 default :
return flags;
1039static int _vsnprintf(
output_gadget_t* output,
const char* format, va_list args)
1047 if (*format !=
'%') {
1049 putchar_via_gadget(output, *format);
1058 printf_flags_t flags = parse_flags(&format);
1061 printf_size_t width = 0U;
1062 if (is_digit_(*format)) {
1063 width = (printf_size_t) atou_(&format);
1065 else if (*format ==
'*') {
1066 const int w = va_arg(args,
int);
1068 flags |= FLAGS_LEFT;
1069 width = (printf_size_t)-w;
1072 width = (printf_size_t)w;
1078 printf_size_t precision = 0U;
1079 if (*format ==
'.') {
1080 flags |= FLAGS_PRECISION;
1082 if (is_digit_(*format)) {
1083 precision = (printf_size_t) atou_(&format);
1085 else if (*format ==
'*') {
1086 const int precision_ = va_arg(args,
int);
1087 precision = precision_ > 0 ? (printf_size_t) precision_ : 0U;
1094#ifdef PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
1099 case '8': flags |= FLAGS_INT8;
1104 if (*format ==
'6') { format++; flags |= FLAGS_INT16; }
1108 if (*format ==
'2') { format++; flags |= FLAGS_INT32; }
1112 if (*format ==
'4') { format++; flags |= FLAGS_INT64; }
1120 flags |= FLAGS_LONG;
1122 if (*format ==
'l') {
1123 flags |= FLAGS_LONG_LONG;
1128 flags |= FLAGS_SHORT;
1130 if (*format ==
'h') {
1131 flags |= FLAGS_CHAR;
1136 flags |= (
sizeof(ptrdiff_t) ==
sizeof(
long) ? FLAGS_LONG : FLAGS_LONG_LONG);
1140 flags |= (
sizeof(intmax_t) ==
sizeof(
long) ? FLAGS_LONG : FLAGS_LONG_LONG);
1144 flags |= (
sizeof(size_t) ==
sizeof(
long) ? FLAGS_LONG : FLAGS_LONG_LONG);
1161 if (*format ==
'd' || *format ==
'i') {
1162 flags |= FLAGS_SIGNED;
1165 numeric_base_t base;
1166 if (*format ==
'x' || *format ==
'X') {
1169 else if (*format ==
'o') {
1172 else if (*format ==
'b') {
1176 base = BASE_DECIMAL;
1177 flags &= ~FLAGS_HASH;
1180 if (*format ==
'X') {
1181 flags |= FLAGS_UPPERCASE;
1186 if (flags & FLAGS_PRECISION) {
1187 flags &= ~FLAGS_ZEROPAD;
1190 if (flags & FLAGS_SIGNED) {
1193 if (flags & FLAGS_LONG_LONG) {
1194#if PRINTF_SUPPORT_LONG_LONG
1195 const long long value = va_arg(args,
long long);
1196 print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags);
1199 else if (flags & FLAGS_LONG) {
1200 const long value = va_arg(args,
long);
1201 print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags);
1209 (flags & FLAGS_CHAR) ? (
signed char) va_arg(args,
int) :
1210 (flags & FLAGS_SHORT) ? (short int) va_arg(args, int) :
1212 print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags);
1218 flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
1220 if (flags & FLAGS_LONG_LONG) {
1221#if PRINTF_SUPPORT_LONG_LONG
1222 print_integer(output, (printf_unsigned_value_t) va_arg(args,
unsigned long long),
false, base, precision, width, flags);
1225 else if (flags & FLAGS_LONG) {
1226 print_integer(output, (printf_unsigned_value_t) va_arg(args,
unsigned long),
false, base, precision, width, flags);
1229 const unsigned int value =
1230 (flags & FLAGS_CHAR) ? (
unsigned char)va_arg(args,
unsigned int) :
1231 (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(args, unsigned int) :
1232 va_arg(args, unsigned int);
1233 print_integer(output, (printf_unsigned_value_t) value,
false, base, precision, width, flags);
1238#if PRINTF_SUPPORT_DECIMAL_SPECIFIERS
1241 if (*format ==
'F') flags |= FLAGS_UPPERCASE;
1242 print_floating_point(output, va_arg(args,
double), precision, width, flags, PRINTF_PREFER_DECIMAL);
1246#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
1251 if ((*format ==
'g')||(*format ==
'G')) flags |= FLAGS_ADAPT_EXP;
1252 if ((*format ==
'E')||(*format ==
'G')) flags |= FLAGS_UPPERCASE;
1253 print_floating_point(output, va_arg(args,
double), precision, width, flags, PRINTF_PREFER_EXPONENTIAL);
1258 printf_size_t l = 1U;
1260 if (!(flags & FLAGS_LEFT)) {
1261 while (l++ < width) {
1262 putchar_via_gadget(output,
' ');
1266 putchar_via_gadget(output, (
char) va_arg(args,
int) );
1268 if (flags & FLAGS_LEFT) {
1269 while (l++ < width) {
1270 putchar_via_gadget(output,
' ');
1278 const char* p = va_arg(args,
char*);
1280 out_rev_(output,
")llun(", 6, width, flags);
1283 printf_size_t l = strnlen_s_(p, precision ? precision : PRINTF_MAX_POSSIBLE_BUFFER_SIZE);
1285 if (flags & FLAGS_PRECISION) {
1286 l = (l < precision ? l : precision);
1288 if (!(flags & FLAGS_LEFT)) {
1289 while (l++ < width) {
1290 putchar_via_gadget(output,
' ');
1294 while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision)) {
1295 putchar_via_gadget(output, *(p++));
1299 if (flags & FLAGS_LEFT) {
1300 while (l++ < width) {
1301 putchar_via_gadget(output,
' ');
1310 width =
sizeof(
void*) * 2U + 2;
1311 flags |= FLAGS_ZEROPAD | FLAGS_POINTER;
1312 uintptr_t value = (uintptr_t)va_arg(args,
void*);
1313 (value == (uintptr_t) NULL) ?
1314 out_rev_(output,
")lin(", 5, width, flags) :
1315 print_integer(output, (printf_unsigned_value_t) value, false, BASE_HEX, precision, width, flags);
1321 putchar_via_gadget(output,
'%');
1328#if PRINTF_SUPPORT_WRITEBACK_SPECIFIER
1330 if (flags & FLAGS_CHAR) *(va_arg(args,
char*)) = (
char) output->pos;
1331 else if (flags & FLAGS_SHORT) *(va_arg(args,
short*)) = (
short) output->pos;
1332 else if (flags & FLAGS_LONG) *(va_arg(args,
long*)) = (
long) output->pos;
1333#if PRINTF_SUPPORT_LONG_LONG
1334 else if (flags & FLAGS_LONG_LONG) *(va_arg(args,
long long*)) = (
long long int) output->pos;
1336 else *(va_arg(args,
int*)) = (
int) output->pos;
1343 putchar_via_gadget(output, *format);
1350 append_termination_with_gadget(output);
1353 return (
int)output->pos;
1360int vprintf_(
const char* format, va_list arg)
1363 return _vsnprintf(&gadget, format, arg);
1367int vsnprintf_(
char* s,
size_t n,
const char* format, va_list arg)
1370 return _vsnprintf(&gadget, format, arg);
1373int vsprintf_(
char* s,
const char* format, va_list arg)
1375 return vsnprintf_(s, PRINTF_MAX_POSSIBLE_BUFFER_SIZE, format, arg);
1378int vfctprintf(
void (*out)(
char c,
void* extra_arg),
void* extra_arg,
const char* format, va_list arg)
1381 return _vsnprintf(&gadget, format, arg);
1385int printf_(
const char* format, ...)
1388 va_start(args, format);
1389 const int ret = vprintf_(format, args);
1395int sprintf_(
char* s,
const char* format, ...)
1398 va_start(args, format);
1399 const int ret = vsprintf_(s, format, args);
1404int snprintf_(
char* s,
size_t n,
const char* format, ...)
1407 va_start(args, format);
1408 const int ret = vsnprintf_(s, n, format, args);
1413int fctprintf(
void (*out)(
char c,
void* extra_arg),
void* extra_arg,
const char* format, ...)
1416 va_start(args, format);
1417 const int ret = vfctprintf(out, extra_arg, format, args);
1424 print_callback_t prnt_callback;
1429static inline void prnt_wrapper(
char c,
void* extra_arg)
1435int prnt(print_callback_t out,
void *context,
const char * format, va_list ap)
1440 ret = vfctprintf(&prnt_wrapper, (
void *)&out_prnt_wrap, format, ap);
u32 count
start sector of fragmented bd/file