Skip to content

Commit

Permalink
Fixed whitespace, added %e/%g to README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
mjasperse committed Feb 1, 2019
1 parent 56d9df0 commit 0fea7e5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 41 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Therefore I decided to write an own, final implementation which meets the follow
- Support of decimal/floating number representation (with an own fast itoa/ftoa)
- Reentrant and thread-safe, malloc free, no static vars/buffers
- LINT and compiler L4 warning free, mature, coverity clean, automotive ready
- Extensive test suite (> 370 test cases) passing
- Extensive test suite (> 390 test cases) passing
- Simply the best *printf* around the net
- MIT license

Expand Down Expand Up @@ -92,6 +92,8 @@ The following format specifiers are supported:
| x | Unsigned hexadecimal integer (lowercase) |
| X | Unsigned hexadecimal integer (uppercase) |
| f or F | Decimal floating point |
| e or E | Scientific-notation (exponential) floating point |
| g or G | Scientific or decimal floating point |
| c | Single character |
| s | String of characters |
| p | Pointer address |
Expand Down Expand Up @@ -164,6 +166,7 @@ int length = sprintf(NULL, "Hello, world"); // length is set to 12
| PRINTF_NTOA_BUFFER_SIZE | 32 | ntoa (integer) conversion buffer size. This must be big enough to hold one converted numeric number _including_ leading zeros, normally 32 is a sufficient value. Created on the stack |
| PRINTF_FTOA_BUFFER_SIZE | 32 | ftoa (float) conversion buffer size. This must be big enough to hold one converted float number _including_ leading zeros, normally 32 is a sufficient value. Created on the stack |
| PRINTF_DISABLE_SUPPORT_FLOAT | undefined | Define this to disable floating point (%f) support |
| PRINTF_DISABLE_SUPPORT_EXPONENTIAL | undefined | Define this to disable exponential floating point (%e) support |
| PRINTF_DISABLE_SUPPORT_LONG_LONG | undefined | Define this to disable long long (%ll) support |
| PRINTF_DISABLE_SUPPORT_PTRDIFF_T | undefined | Define this to disable ptrdiff_t (%t) support |

Expand Down
80 changes: 40 additions & 40 deletions printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
#define FLAGS_ADAPT_EXP (1U << 11U)


// output function type
Expand Down Expand Up @@ -337,7 +337,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
if (value < -DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
if (value > DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4 : 3, width, flags);
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4 : 3, width, flags);

// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
Expand Down Expand Up @@ -456,14 +456,14 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
{
// check for special values
if ((value != value)||(value > DBL_MAX)||(value < -DBL_MAX))
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);

// determine the sign
bool negative = value < 0;
if (negative) value = -value;

// determine the decimal exponent
int expval = (int)floor(log10(value)); // "value" must be +ve
int expval = (int)floor(log10(value)); // "value" must be +ve

// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
unsigned int minwidth = ((expval < 100)&&(expval > -100)) ? 4 : 5;
Expand All @@ -475,36 +475,36 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d

// in "%g" mode, "prec" is the number of *significant figures* not decimals
if (flags & FLAGS_ADAPT_EXP) {
// do we want to fall-back to "%f" mode for small number?
if ((expval > -5)&&(expval < 6)) {
if ((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
// do we want to fall-back to "%f" mode for small number?
if ((expval > -5)&&(expval < 6)) {
if ((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
} else {
prec = 0;
}
// TODO: there's also a special case where we're supposed to ELIMINATE digits from the whole part
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0;
expval = 0;
} else {
// we use one sigfig for the whole part
if ((prec > 0)&&(flags & FLAGS_PRECISION)) --prec;
}
prec = 0;
}
// TODO: there's also a special case where we're supposed to ELIMINATE digits from the whole part
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0;
expval = 0;
} else {
// we use one sigfig for the whole part
if ((prec > 0)&&(flags & FLAGS_PRECISION)) --prec;
}
}
// will everything fit?
unsigned int fwidth = width;
if (width > minwidth) {
// we didn't fall-back so subtract the characters required for the exponent
fwidth -= minwidth;
} else {
// not enough characters, so go back to default sizing
fwidth = 0;
// not enough characters, so go back to default sizing
fwidth = 0;
}
if ((flags & FLAGS_LEFT) && minwidth) {
// if we're padding on the right, DON'T pad the floating part
fwidth = 0;
// if we're padding on the right, DON'T pad the floating part
fwidth = 0;
}

// rescale the float value
Expand All @@ -516,14 +516,14 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d

// output the exponent part
if (minwidth) {
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
Expand Down Expand Up @@ -716,20 +716,20 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
#if defined(PRINTF_SUPPORT_FLOAT)
case 'f' :
case 'F' :
if (*format == 'F') flags |= FLAGS_UPPERCASE;
if (*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e':
case 'E':
case 'E':
case 'g':
case 'G':
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
case 'G':
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
case 'c' : {
Expand Down

0 comments on commit 0fea7e5

Please sign in to comment.