forked from mpaland/printf
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* More use of typedef's over raw primitive C types. Specifically, using `printf_size_t` in many relevant places * Regards mpaland#77 * Removed redundant parentheses * Comment tweaks
- Loading branch information
Showing
1 changed file
with
48 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,8 @@ typedef unsigned int printf_flags_t; | |
#define BASE_DECIMAL 10 | ||
#define BASE_HEX 16 | ||
|
||
typedef uint8_t numeric_base_t; | ||
|
||
#if PRINTF_SUPPORT_LONG_LONG | ||
typedef unsigned long long printf_unsigned_value_t; | ||
typedef long long printf_signed_value_t; | ||
|
@@ -152,10 +154,12 @@ typedef unsigned long printf_unsigned_value_t; | |
typedef long printf_signed_value_t; | ||
#endif | ||
|
||
typedef uint8_t numeric_base_t; | ||
|
||
typedef unsigned int printf_precision_t; | ||
typedef unsigned int printf_width_t; | ||
// The printf()-family functions return an `int`; it is therefore | ||
// unnecessary/inappropriate to use size_t - often larger than int | ||
// in practice - for non-negative related values, such as widths, | ||
// precisions, offsets into buffers used for printing and the sizes | ||
// of these buffers. instead, we use: | ||
typedef unsigned int printf_size_t; | ||
|
||
#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) | ||
#include <float.h> | ||
|
@@ -188,7 +192,9 @@ typedef union { | |
} double_with_bit_access; | ||
|
||
// This is unnecessary in C99, since compound initializers can be used, | ||
// but: 1. Some compilers are finicky about this; 2. Some people may want to convert this to C89; | ||
// but: | ||
// 1. Some compilers are finicky about this; | ||
// 2. Some people may want to convert this to C89; | ||
// 3. If you try to use it as C++, only C++20 supports compound literals | ||
static inline double_with_bit_access get_bit_access(double x) | ||
{ | ||
|
@@ -270,11 +276,13 @@ static inline void out_wrapped_function(char character, void* wrapped_function, | |
|
||
// internal secure strlen | ||
// @return The length of the string (excluding the terminating 0) limited by 'maxsize' | ||
static inline size_t strnlen_s_(const char* str, size_t maxsize) | ||
// @note strlen uses size_t, but wes only use this function with printf_size_t | ||
// variables - hence the signature. | ||
static inline printf_size_t strnlen_s_(const char* str, printf_size_t maxsize) | ||
{ | ||
const char* s; | ||
for (s = str; *s && maxsize--; ++s); | ||
return (size_t)(s - str); | ||
return (printf_size_t)(s - str); | ||
} | ||
|
||
|
||
|
@@ -286,19 +294,19 @@ static inline bool is_digit_(char ch) | |
} | ||
|
||
|
||
// internal ASCII string to unsigned int conversion | ||
static unsigned int atoi_(const char** str) | ||
// internal ASCII string to printf_size_t conversion | ||
static printf_size_t atou_(const char** str) | ||
{ | ||
unsigned int i = 0U; | ||
printf_size_t i = 0U; | ||
while (is_digit_(**str)) { | ||
i = i * 10U + (unsigned int)(*((*str)++) - '0'); | ||
i = i * 10U + (printf_size_t)(*((*str)++) - '0'); | ||
} | ||
return i; | ||
} | ||
|
||
|
||
// output the specified string in reverse, taking care of any zero-padding | ||
static size_t out_rev_(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, printf_width_t width, printf_flags_t flags) | ||
static size_t out_rev_(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, printf_size_t width, printf_flags_t flags) | ||
{ | ||
const size_t start_idx = idx; | ||
|
||
|
@@ -327,7 +335,7 @@ static size_t out_rev_(out_fct_type out, char* buffer, size_t idx, size_t maxlen | |
|
||
// Invoked by print_integer after the actual number has been printed, performing necessary | ||
// work on the number's prefix (as the number is initially printed in reverse order) | ||
static size_t print_integer_finalization(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, numeric_base_t base, printf_precision_t precision, printf_width_t width, printf_flags_t flags) | ||
static size_t print_integer_finalization(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) | ||
{ | ||
size_t unpadded_len = len; | ||
|
||
|
@@ -394,7 +402,7 @@ static size_t print_integer_finalization(out_fct_type out, char* buffer, size_t | |
} | ||
|
||
// An internal itoa-like function | ||
static size_t print_integer(out_fct_type out, char* buffer, size_t idx, size_t maxlen, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_precision_t precision, printf_width_t width, printf_flags_t flags) | ||
static size_t print_integer(out_fct_type out, char* buffer, size_t idx, size_t maxlen, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) | ||
{ | ||
char buf[PRINTF_INTEGER_BUFFER_SIZE]; | ||
size_t len = 0U; | ||
|
@@ -445,7 +453,7 @@ static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { | |
// Break up a double number - which is known to be a finite non-negative number - | ||
// into its base-10 parts: integral - before the decimal point, and fractional - after it. | ||
// Taken the precision into account, but does not change it even internally. | ||
static struct double_components get_components(double number, printf_precision_t precision) | ||
static struct double_components get_components(double number, printf_size_t precision) | ||
{ | ||
struct double_components number_; | ||
number_.is_negative = get_sign(number); | ||
|
@@ -520,7 +528,7 @@ static struct scaling_factor update_normalization(struct scaling_factor sf, doub | |
return result; | ||
} | ||
|
||
static struct double_components get_normalized_components(bool negative, printf_precision_t precision, double non_normalized, struct scaling_factor normalization) | ||
static struct double_components get_normalized_components(bool negative, printf_size_t precision, double non_normalized, struct scaling_factor normalization) | ||
{ | ||
struct double_components components; | ||
components.is_negative = negative; | ||
|
@@ -560,13 +568,13 @@ static struct double_components get_normalized_components(bool negative, printf_ | |
#endif | ||
|
||
static size_t print_broken_up_decimal( | ||
struct double_components number_, out_fct_type out, char *buffer, size_t idx, size_t maxlen, printf_precision_t precision, | ||
printf_width_t width, printf_flags_t flags, char *buf, size_t len) | ||
struct double_components number_, out_fct_type out, char *buffer, size_t idx, size_t maxlen, printf_size_t precision, | ||
printf_size_t width, printf_flags_t flags, char *buf, size_t len) | ||
{ | ||
if (precision != 0U) { | ||
// do fractional part, as an unsigned number | ||
|
||
unsigned int count = precision; | ||
printf_size_t count = precision; | ||
|
||
// %g/%G mandates we skip the trailing 0 digits... | ||
if ((flags & FLAGS_ADAPT_EXP) && !(flags & FLAGS_HASH) && (number_.fractional > 0)) { | ||
|
@@ -642,15 +650,15 @@ static size_t print_broken_up_decimal( | |
} | ||
|
||
// internal ftoa for fixed decimal floating point | ||
static size_t print_decimal_number(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double number, printf_precision_t precision, printf_width_t width, printf_flags_t flags, char* buf, size_t len) | ||
static size_t print_decimal_number(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, size_t len) | ||
{ | ||
struct double_components value_ = get_components(number, precision); | ||
return print_broken_up_decimal(value_, out, buffer, idx, maxlen, precision, width, flags, buf, len); | ||
} | ||
|
||
#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS | ||
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <[email protected]> | ||
static size_t print_exponential_number(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double number, printf_precision_t precision, printf_width_t width, printf_flags_t flags, char* buf, size_t len) | ||
static size_t print_exponential_number(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, size_t len) | ||
{ | ||
const bool negative = get_sign(number); | ||
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it | ||
|
@@ -707,7 +715,7 @@ static size_t print_exponential_number(out_fct_type out, char* buffer, size_t id | |
// This also decided how we adjust the precision value - as in "%g" mode, | ||
// "precision" is the number of _significant digits_, and this is when we "translate" | ||
// the precision value to an actual number of decimal digits. | ||
int precision_ = (fall_back_to_decimal_only_mode) ? | ||
int precision_ = fall_back_to_decimal_only_mode ? | ||
(int) precision - 1 - exp10 : | ||
(int) precision - 1; // the presence of the exponent ensures only one significant digit comes before the decimal point | ||
precision = (precision_ > 0 ? (unsigned) precision_ : 0U); | ||
|
@@ -741,9 +749,9 @@ static size_t print_exponential_number(out_fct_type out, char* buffer, size_t id | |
|
||
// the exp10 format is "E%+03d" and largest possible exp10 value for a 64-bit double | ||
// is "307" (for 2^1023), so we set aside 4-5 characters overall | ||
printf_width_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(exp10) < 100) ? 4U : 5U; | ||
printf_size_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(exp10) < 100) ? 4U : 5U; | ||
|
||
printf_width_t decimal_part_width = | ||
printf_size_t decimal_part_width = | ||
((flags & FLAGS_LEFT) && exp10_part_width) ? | ||
// We're padding on the right, so the width constraint is the exponent part's | ||
// problem, not the decimal part's, so we'll use as many characters as we need: | ||
|
@@ -776,7 +784,7 @@ static size_t print_exponential_number(out_fct_type out, char* buffer, size_t id | |
} | ||
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS | ||
|
||
static size_t print_floating_point(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, printf_precision_t precision, printf_width_t width, printf_flags_t flags, bool prefer_exponential) | ||
static size_t print_floating_point(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) | ||
{ | ||
char buf[PRINTF_FTOA_BUFFER_SIZE]; | ||
size_t len = 0U; | ||
|
@@ -822,13 +830,11 @@ static size_t print_floating_point(out_fct_type out, char* buffer, size_t idx, s | |
#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) | ||
|
||
// internal vsnprintf | ||
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) | ||
static int _vsnprintf(out_fct_type out, char* buffer, printf_size_t maxlen, const char* format, va_list va) | ||
{ | ||
printf_flags_t flags; | ||
printf_width_t width; | ||
printf_precision_t precision; | ||
unsigned int n; | ||
size_t idx = 0U; | ||
printf_size_t width, precision, n; | ||
printf_size_t idx = 0U; | ||
|
||
if (!buffer) { | ||
// use null output function | ||
|
@@ -865,16 +871,16 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const | |
// evaluate width field | ||
width = 0U; | ||
if (is_digit_(*format)) { | ||
width = atoi_(&format); | ||
width = (printf_size_t) atou_(&format); | ||
} | ||
else if (*format == '*') { | ||
const int w = va_arg(va, int); | ||
if (w < 0) { | ||
flags |= FLAGS_LEFT; // reverse padding | ||
width = (printf_width_t)-w; | ||
width = (printf_size_t)-w; | ||
} | ||
else { | ||
width = (printf_width_t)w; | ||
width = (printf_size_t)w; | ||
} | ||
format++; | ||
} | ||
|
@@ -885,11 +891,11 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const | |
flags |= FLAGS_PRECISION; | ||
format++; | ||
if (is_digit_(*format)) { | ||
precision = atoi_(&format); | ||
precision = (printf_size_t) atou_(&format); | ||
} | ||
else if (*format == '*') { | ||
const int precision_ = va_arg(va, int); | ||
precision = precision_ > 0 ? (printf_precision_t)precision_ : 0U; | ||
precision = precision_ > 0 ? (printf_size_t) precision_ : 0U; | ||
format++; | ||
} | ||
} | ||
|
@@ -1023,7 +1029,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const | |
break; | ||
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS | ||
case 'c' : { | ||
unsigned int l = 1U; | ||
printf_size_t l = 1U; | ||
// pre padding | ||
if (!(flags & FLAGS_LEFT)) { | ||
while (l++ < width) { | ||
|
@@ -1048,7 +1054,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const | |
idx = out_rev_(out, buffer, idx, maxlen, ")llun(", 6, width, flags); | ||
} | ||
else { | ||
unsigned int l = strnlen_s_(p, precision ? precision : (size_t)-1); | ||
printf_size_t l = strnlen_s_(p, precision ? precision : (printf_size_t) -1); | ||
// pre padding | ||
if (flags & FLAGS_PRECISION) { | ||
l = (l < precision ? l : precision); | ||
|
@@ -1129,7 +1135,7 @@ int printf_(const char* format, ...) | |
va_list va; | ||
va_start(va, format); | ||
char buffer[1]; | ||
const int ret = _vsnprintf(&out_putchar, buffer, (size_t)-1, format, va); | ||
const int ret = _vsnprintf(&out_putchar, buffer, (printf_size_t)-1, format, va); | ||
va_end(va); | ||
return ret; | ||
} | ||
|
@@ -1139,7 +1145,7 @@ int sprintf_(char* buffer, const char* format, ...) | |
{ | ||
va_list va; | ||
va_start(va, format); | ||
const int ret = _vsnprintf(out_buffer, buffer, (size_t)-1, format, va); | ||
const int ret = _vsnprintf(out_buffer, buffer, (printf_size_t)-1, format, va); | ||
va_end(va); | ||
return ret; | ||
} | ||
|
@@ -1158,12 +1164,12 @@ int snprintf_(char* buffer, size_t count, const char* format, ...) | |
int vprintf_(const char* format, va_list va) | ||
{ | ||
char buffer[1]; | ||
return _vsnprintf(&out_putchar, buffer, (size_t)-1, format, va); | ||
return _vsnprintf(&out_putchar, buffer, (printf_size_t)-1, format, va); | ||
} | ||
|
||
int vsprintf_(char* buffer, const char* format, va_list va) | ||
{ | ||
return _vsnprintf(out_buffer, buffer, (size_t)-1, format, va); | ||
return _vsnprintf(out_buffer, buffer, (printf_size_t)-1, format, va); | ||
} | ||
|
||
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) | ||
|
@@ -1184,7 +1190,7 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for | |
int vfctprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va) | ||
{ | ||
const out_function_wrapper_type out_fct_wrap = { out, arg }; | ||
return _vsnprintf(out_wrapped_function, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); | ||
return _vsnprintf(out_wrapped_function, (char*)(uintptr_t)&out_fct_wrap, (printf_size_t)-1, format, va); | ||
} | ||
|
||
#ifdef __cplusplus | ||
|