1
0
Fork 0

Convert _ntoa template in discrete functions

This reduces the compiled size and makes this file 'c' compatible
development
Marco Paland 8 years ago
parent aa47054dd8
commit 4c48045bff

@ -47,6 +47,8 @@
// define this to support floating point (%f)
#define PRINTF_FLOAT_SUPPORT
// define this to support long long types (%llu or %p)
#define PRINTF_LONG_LONG_SUPPORT
///////////////////////////////////////////////////////////////////////////////
@ -64,8 +66,8 @@
// internal strlen, returns the length of the string
static inline size_t _strlen(const char* str)
{
static inline size_t _strlen(const char* str)
{
size_t len = 0U;
while (str[len] != '\0') {
len++;
@ -92,33 +94,15 @@ static inline unsigned int _atoi(const char** str)
}
// internal itoa
template<typename T>
static size_t _ntoa(T value, char* buffer, unsigned int base, size_t maxlen, unsigned int prec, unsigned int width, unsigned int flags)
// internal itoa format
static size_t _ntoa_format(char* buffer, char* buf, size_t len, bool negative, unsigned int base, size_t maxlen, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[NTOA_BUFFER_SIZE];
size_t len = 0U;
unsigned int negative = 0U;
if (maxlen == 0U) {
return 0U;
}
if (base > 16U) {
return 0U;
}
if (value < 0) {
negative = 1U;
value = 0 - value;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || (value != 0)) {
do {
char digit = (char)(value % (T)base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= (T)base;
} while ((len < NTOA_BUFFER_SIZE) && (value > 0));
}
// pad leading zeros
while (!(flags & FLAGS_LEFT) && (len < prec) && (len < NTOA_BUFFER_SIZE)) {
@ -172,7 +156,7 @@ static size_t _ntoa(T value, char* buffer, unsigned int base, size_t maxlen, uns
// reverse string
for (size_t i = 0U; (i < len) && (i < maxlen); ++i) {
buffer[i] = buf[len - i - 1];
buffer[i] = buf[len - i - 1U];
}
// append pad spaces up to given width
@ -186,24 +170,65 @@ static size_t _ntoa(T value, char* buffer, unsigned int base, size_t maxlen, uns
}
// internal itoa for 'long' type
static size_t _ntoa_long(char* buffer, unsigned long value, bool negative, unsigned long base, size_t maxlen, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[NTOA_BUFFER_SIZE];
size_t len = 0U;
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || (value != 0)) {
do {
char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while ((len < NTOA_BUFFER_SIZE) && (value > 0));
}
return _ntoa_format(buffer, buf, len, negative, (unsigned int)base, maxlen, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_LONG_LONG_SUPPORT)
static size_t _ntoa_long_long(char* buffer, unsigned long long value, bool negative, unsigned long long base, size_t maxlen, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[NTOA_BUFFER_SIZE];
size_t len = 0U;
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || (value != 0)) {
do {
char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while ((len < NTOA_BUFFER_SIZE) && (value > 0));
}
return _ntoa_format(buffer, buf, len, negative, (unsigned int)base, maxlen, prec, width, flags);
}
#endif // PRINTF_LONG_LONG_SUPPORT
#if defined(PRINTF_FLOAT_SUPPORT)
static size_t _ftoa(double value, char* buffer, size_t maxlen, unsigned int prec, unsigned int width, unsigned int flags)
{
// test for NaN
if (!(value == value) && (maxlen > 2U)) {
buffer[0] = 'n'; buffer[1] = 'a'; buffer[2] = 'n';
return (size_t)3U;
}
char buf[FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0.0;
// if input is larger than thres_max, revert to exponential
const double thres_max = (double)0x7FFFFFFF;
char buf[FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0;
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
// test for NaN
if (!(value == value) && (maxlen > 2U)) {
buffer[0] = 'n'; buffer[1] = 'a'; buffer[2] = 'n';
return (size_t)3U;
}
// limit precision
if (!(flags & FLAGS_PRECISION)) {
prec = 6U; // by default, precesion is 6
@ -279,7 +304,7 @@ static size_t _ftoa(double value, char* buffer, size_t maxlen, unsigned int prec
break;
}
}
// pad leading zeros
while (!(flags & FLAGS_LEFT) && (len < prec) && (len < FTOA_BUFFER_SIZE)) {
buf[len++] = '0';
@ -443,25 +468,32 @@ static size_t vsnprintf(char* buffer, size_t buffer_len, const char* format, va_
if ((*format == 'i') || (*format == 'd')) {
// signed
if (flags & FLAGS_LONG_LONG) {
idx += _ntoa<long long>(va_arg(va, long long), &buffer[idx], base, buffer_len - idx, precision, width, flags);
#if defined(PRINTF_LONG_LONG_SUPPORT)
const long long value = va_arg(va, long long);
idx += _ntoa_long_long(&buffer[idx], (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, buffer_len - idx, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
idx += _ntoa<long>(va_arg(va, long), &buffer[idx], base, buffer_len - idx, precision, width, flags);
const long value = va_arg(va, long);
idx += _ntoa_long(&buffer[idx], (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, buffer_len - idx, precision, width, flags);
}
else {
idx += _ntoa<int>(va_arg(va, int), &buffer[idx], base, buffer_len - idx, precision, width, flags);
const int value = va_arg(va, int);
idx += _ntoa_long(&buffer[idx], (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, buffer_len - idx, precision, width, flags);
}
}
else {
// unsigned
if (flags & FLAGS_LONG_LONG) {
idx += _ntoa<unsigned long long>(va_arg(va, unsigned long long), &buffer[idx], base, buffer_len - idx, precision, width, flags);
#if defined(PRINTF_LONG_LONG_SUPPORT)
idx += _ntoa_long_long(&buffer[idx], va_arg(va, unsigned long long), false, base, buffer_len - idx, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
idx += _ntoa<unsigned long>(va_arg(va, unsigned long), &buffer[idx], base, buffer_len - idx, precision, width, flags);
idx += _ntoa_long(&buffer[idx], va_arg(va, unsigned long), false, base, buffer_len - idx, precision, width, flags);
}
else {
idx += _ntoa<unsigned int>(va_arg(va, unsigned int), &buffer[idx], base, buffer_len - idx, precision, width, flags);
idx += _ntoa_long(&buffer[idx], va_arg(va, unsigned int), false, base, buffer_len - idx, precision, width, flags);
}
}
format++;
@ -525,10 +557,12 @@ static size_t vsnprintf(char* buffer, size_t buffer_len, const char* format, va_
flags |= FLAGS_ZEROPAD;
size_t size_void = sizeof(void*);
if (size_void > sizeof(long)) {
idx +=_ntoa<unsigned long long>(reinterpret_cast<unsigned long long>(va_arg(va, void*)), &buffer[idx], 16U, buffer_len - idx, precision, width, flags);
#if defined(PRINTF_LONG_LONG_SUPPORT)
idx += _ntoa_long_long(&buffer[idx], (unsigned long long)va_arg(va, void*), false, 16U, buffer_len - idx, precision, width, flags);
#endif
}
else {
idx += _ntoa<unsigned long>(reinterpret_cast<unsigned long>(va_arg(va, void*)), &buffer[idx], 16U, buffer_len - idx, precision, width, flags);
idx += _ntoa_long(&buffer[idx], (unsigned long)va_arg(va, void*), false, 16U, buffer_len - idx, precision, width, flags);
}
format++;
break;

Loading…
Cancel
Save