Merge pull request #13548 from evva-sfw/enhance-minimal-printf

Add width modifier and prepending zeros for hexadecimal output and decimal precision for floating point
pull/13977/head
Martin Kojtal 2020-12-10 09:14:59 +00:00 committed by GitHub
commit c06fcaf5c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 526 additions and 158 deletions

View File

@ -3,7 +3,7 @@
Library supports both printf and snprintf in around 1300 bytes of flash.
Prints directly to stdio/UART without using malloc. All flags and precision modifiers are ignored.
Prints directly to stdio/UART without using malloc. Width size and prepending zero modifiers are supported. All other flags are ignored.
There is no error handling if a writing error occurs.
Supports:
@ -12,10 +12,10 @@ Supports:
* %u: unsigned integer [h, hh, (none), l, ll, z, j, t].
* %x: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., ff).
* %X: unsigned integer [h, hh, (none), l, ll, z, j, t], printed as hexadecimal number (e.g., FF).
* %f: floating point (disabled by default).
* %F: floating point (disabled by default, treated as %f).
* %g: floating point (disabled by default, treated as %f).
* %G: floating point (disabled by default, treated as %f).
* %f: floating point (disabled by default). Precision modifier is supported (e.g. %.5f).
* %F: floating point (disabled by default, treated as %f). Precision modifier is supported (e.g. %.5F).
* %g: floating point (disabled by default, treated as %f). Precision modifier is supported (e.g. %.5g).
* %G: floating point (disabled by default, treated as %f). Precision modifier is supported (e.g. %.5G).
* %c: character.
* %s: string.
* %p: pointer (e.g. 0x00123456).

View File

@ -21,6 +21,7 @@
#include <limits.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#if !TARGET_LIKE_MBED
/* Linux implementation is for debug only */
@ -86,12 +87,21 @@ typedef enum {
LENGTH_LL = 0x82
} length_t;
/**
* Enum for integer printing type
*/
typedef enum {
INT_UNSIGNED,
INT_SIGNED,
HEX_LOWER,
HEX_UPPER,
ZERO_NEGATIVE /* special case when printing integer part of double values where it is 0 and the value is negative */
} integer_type_t;
/**
* Prototypes
*/
static void mbed_minimal_formatted_string_signed(char *buffer, size_t length, int *result, MBED_SIGNED_STORAGE value, FILE *stream);
static void mbed_minimal_formatted_string_unsigned(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, FILE *stream);
static void mbed_minimal_formatted_string_hexadecimal(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, FILE *stream, bool upper);
static void mbed_minimal_formatted_string_integer(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, integer_type_t type, int width_size, bool prepend_zeros, FILE *stream);
static void mbed_minimal_formatted_string_void_pointer(char *buffer, size_t length, int *result, const void *value, FILE *stream);
static void mbed_minimal_formatted_string_string(char *buffer, size_t length, int *result, const char *string, size_t precision, FILE *stream);
@ -130,105 +140,96 @@ static void mbed_minimal_putchar(char *buffer, size_t length, int *result, char
}
/**
* @brief Print signed integer.
* @brief Print integer in signed, unsigned or hexadecimal format.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param type The type of integer format that shall be printed (signed, unsigend or hexadecimal)
* @param width_size The width modifier.
* @param prepend_zeros Flag to prepends zeros when the width_size is greater than 0
*/
static void mbed_minimal_formatted_string_signed(char *buffer, size_t length, int *result, MBED_SIGNED_STORAGE value, FILE *stream)
static void mbed_minimal_formatted_string_integer(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, integer_type_t type, int width_size, bool prepend_zeros, FILE *stream)
{
MBED_UNSIGNED_STORAGE new_value = 0;
/* allocate 3 digits per byte */
char scratch[sizeof(MBED_UNSIGNED_STORAGE) * 3] = { 0 };
/* if value is negative print sign and treat as positive number */
if (value < 0) {
/* write sign */
mbed_minimal_putchar(buffer, length, result, '-', stream);
int index = 0;
/* get absolute value using two's complement */
new_value = ~((MBED_UNSIGNED_STORAGE) value) + 1;
} else {
new_value = value;
bool negative_value = false;
const char filler = prepend_zeros ? '0' : ' ';
if (type == INT_SIGNED) {
if ((MBED_SIGNED_STORAGE) value < 0) {
/* get absolute value using two's complement */
value = ~value + 1;
negative_value = true;
}
} else if (type == ZERO_NEGATIVE) {
negative_value = true;
}
/* use unsigned long int function */
mbed_minimal_formatted_string_unsigned(buffer, length, result, new_value, stream);
}
/**
* @brief Print unsigned integer.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
*/
static void mbed_minimal_formatted_string_unsigned(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, FILE *stream)
{
/* treat 0 as a corner case */
if (value == 0) {
mbed_minimal_putchar(buffer, length, result, '0', stream);
scratch[index] = '0';
index++;
} else {
/* allocate 3 digits per byte */
char scratch[sizeof(MBED_UNSIGNED_STORAGE) * 3] = { 0 };
size_t index = 0;
/* write numbers in reverse order to scratch pad */
for (; value > 0; index++) {
/* use '0' as base and add digit */
scratch[index] = '0' + (value % 10);
if (type == HEX_LOWER || type == HEX_UPPER) {
/* get least significant byte */
const uint8_t output = value & 0x0F;
/* shift value one decimal position */
value = value / 10;
}
static const char int2hex_lower[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
static const char int2hex_upper[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
/* write scratch pad to buffer or output */
for (; index > 0; index--) {
mbed_minimal_putchar(buffer, length, result, scratch[index - 1], stream);
if (type == HEX_LOWER) {
scratch[index] = int2hex_lower[output];
} else {
scratch[index] = int2hex_upper[output];
}
/* shift value one byte position */
value = value >> 4;
} else {
/* use '0' as base and add digit */
scratch[index] = '0' + (value % 10);
/* shift value one decimal position */
value = value / 10;
}
}
}
}
/**
* @brief Print hexadecimal.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param upper Flag to print the hexadecimal in upper or lower case.
*/
static void mbed_minimal_formatted_string_hexadecimal(char *buffer, size_t length, int *result, MBED_UNSIGNED_STORAGE value, FILE *stream, bool upper)
{
bool print_leading_zero = false;
for (int index = 7; index >= 0; index--) {
/* get most significant byte */
uint8_t output = value >> (8 * index);
/* only print leading zeros when set */
if (print_leading_zero || (output != 0) || (index == 0)) {
unsigned int nibble_one = (output >> 4);
unsigned int nibble_two = (output & 0x0F);
static const char int2hex_lower[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
static const char int2hex_upper[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
const char *int2hex = upper ? int2hex_upper : int2hex_lower;
if (print_leading_zero || nibble_one != 0) {
mbed_minimal_putchar(buffer, length, result, int2hex[nibble_one], stream);
}
mbed_minimal_putchar(buffer, length, result, int2hex[nibble_two], stream);
/* print zeroes after the first non-zero byte */
print_leading_zero = true;
if (negative_value) {
if (prepend_zeros) {
mbed_minimal_putchar(buffer, length, result, '-', stream);
}
index++; // add one to index to count '-'
}
// print filler characters
if (width_size > index) {
for (int i = width_size; i > index; i--) {
mbed_minimal_putchar(buffer, length, result, filler, stream);
}
}
if (negative_value) {
if (!prepend_zeros) {
mbed_minimal_putchar(buffer, length, result, '-', stream);
}
index--; // Restore index to correct position
}
/* print absolute value of integer */
for (; index > 0; index--) {
mbed_minimal_putchar(buffer, length, result, scratch[index - 1], stream);
}
}
@ -247,69 +248,77 @@ static void mbed_minimal_formatted_string_void_pointer(char *buffer, size_t leng
mbed_minimal_putchar(buffer, length, result, 'x', stream);
/* write rest as a regular hexadecimal number */
mbed_minimal_formatted_string_hexadecimal(buffer, length, result, (ptrdiff_t) value, stream, true);
mbed_minimal_formatted_string_integer(buffer, length, result, (ptrdiff_t) value, HEX_UPPER, 0, false, stream);
}
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
/**
* @brief Write double.
*
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param buffer The buffer to store output (NULL for stdout).
* @param[in] length The length of the buffer.
* @param result The current output location.
* @param[in] value The value to be printed.
* @param[in] dec_precision The decimal precision. If PRECISION_DEFAULT MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS is used.
* @param width_size The width modifier.
* @param prepend_zeros Flag to prepends zeros when the width_size is greater than 0
*/
static void mbed_minimal_formatted_string_double(char *buffer, size_t length, int *result, double value, FILE *stream)
static void mbed_minimal_formatted_string_double(char *buffer, size_t length, int *result, double value, int dec_precision, int width_size, bool prepend_zeros, FILE *stream)
{
/* get integer part */
MBED_SIGNED_STORAGE integer = value;
/* write integer part */
mbed_minimal_formatted_string_signed(buffer, length, result, integer, stream);
/* write decimal point */
mbed_minimal_putchar(buffer, length, result, '.', stream);
/* get decimal part */
double precision = 1.0;
for (size_t index = 0; index < MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS; index++) {
precision *= 10;
if (dec_precision == PRECISION_DEFAULT) {
dec_precision = MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS;
}
value = (value - integer) * precision;
/* convert to unsigned integer */
MBED_UNSIGNED_STORAGE decimal = 0;
if (value < 0) {
MBED_SIGNED_STORAGE temp = value;
decimal = ~((MBED_UNSIGNED_STORAGE) temp) + 1;
if (dec_precision != 0) {
width_size -= dec_precision + 1; // decimal precision plus '.'
if (width_size < 0) {
width_size = 0;
}
} else {
decimal = value;
value = (value - integer) * 1.0;
if (!((value > -0.5) && (value < 0.5))) {
integer++;
}
}
/* round up or down */
value -= decimal;
if (!((value > -0.5) && (value < 0.5))) {
decimal++;
/* write integer part */
if (integer == 0 && value < 0) {
mbed_minimal_formatted_string_integer(buffer, length, result, integer, ZERO_NEGATIVE, width_size, prepend_zeros, stream);
} else {
mbed_minimal_formatted_string_integer(buffer, length, result, integer, INT_SIGNED, width_size, prepend_zeros, stream);
}
/* convert precision to unsigned integer */
MBED_UNSIGNED_STORAGE precision_in_uint = precision;
precision_in_uint /= 10;
if (dec_precision != 0) {
/* write decimal point */
mbed_minimal_putchar(buffer, length, result, '.', stream);
/* ensure that leading zeros are printed if decimal equals 0 */
MBED_UNSIGNED_STORAGE val = decimal ? decimal : decimal + 1;
while (precision_in_uint > val) {
/* print leading zeros */
mbed_minimal_putchar(buffer, length, result, '0', stream);
precision_in_uint /= 10;
/* get decimal part */
double precision = 1.0;
for (size_t index = 0; index < dec_precision; index++) {
precision *= 10;
}
/* convert to positive number */
if (value < 0.0) {
value *= -1.0;
}
MBED_UNSIGNED_STORAGE decimal = value;
/* round up or down */
value -= decimal;
if (!((value > -0.5) && (value < 0.5))) {
decimal++;
}
/* write decimal part */
mbed_minimal_formatted_string_integer(buffer, length, result, decimal, INT_UNSIGNED, dec_precision, true, stream);
}
/* write decimal part */
mbed_minimal_formatted_string_unsigned(buffer, length, result, decimal, stream);
}
#endif
@ -331,6 +340,26 @@ static void mbed_minimal_formatted_string_string(char *buffer, size_t length, in
}
}
/**
* @brief Parse a string to an integer value as long as there are numerical characters in the string
*
* @param[in] string The input string. Has to begin with a numerical character to parse
* @param[out] value The output value.
* @return size_t The number of numerical characters parsed
*/
static size_t parse_string_to_integer(const char *string, int *value)
{
size_t inner_index = 0;
while ((string[inner_index] >= '0') && (string[inner_index] <= '9')) {
*value = *value * 10 + (string[inner_index] - '0');
inner_index++;
}
return inner_index;
}
/**
* @brief Parse formatted string and invoke write handlers based on type.
*
@ -364,20 +393,22 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
size_t next_index = index + 1;
/**************************************************************
* skip and ignore flags [-+(space)#0]
* skip and ignore flags [-+(space)#]
*************************************************************/
if ((format[next_index] == '-') ||
(format[next_index] == '+') ||
(format[next_index] == ' ') ||
(format[next_index] == '#') ||
(format[next_index] == '0')) {
(format[next_index] == '#')) {
/* skip to next character */
next_index++;
}
/**************************************************************
* skip and ignore width [(number)*]
* look for width and prepending zeros [(number)], skip [*]
*************************************************************/
bool prepend_zeros = false;
int width_size = 0;
if (format[next_index] == '*') {
/* skip to next character */
next_index++;
@ -385,11 +416,15 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
/* discard argument */
va_arg(arguments, MBED_SIGNED_NATIVE_TYPE);
} else {
while ((format[next_index] >= '0') &&
(format[next_index] <= '9')) {
/* skip to next character */
next_index++;
if (format[next_index] == '0') {
prepend_zeros = true;
do {
next_index++;
} while (format[next_index] == '0');
}
/* parse width modifier until not a decimal */
next_index += parse_string_to_integer(&format[next_index], &width_size);
}
/**************************************************************
@ -409,17 +444,7 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
precision = 0;
/* parse precision until not a decimal */
size_t inner_index = 0;
while ((format[next_index + inner_index] >= '0') &&
(format[next_index + inner_index] <= '9')) {
precision = precision * 10 + (format[next_index + inner_index] - '0');
inner_index++;
}
/* move index forward to point at next character */
next_index += inner_index;
next_index += parse_string_to_integer(&format[next_index], &precision);
}
/**************************************************************
@ -514,7 +539,7 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
index = next_index;
mbed_minimal_formatted_string_signed(buffer, length, &result, value, stream);
mbed_minimal_formatted_string_integer(buffer, length, &result, value, INT_SIGNED, width_size, prepend_zeros, stream);
}
/* unsigned integer */
else if ((next == 'u') || (next == 'x') || (next == 'X')) {
@ -578,9 +603,11 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
/* write unsigned or hexadecimal */
if (next == 'u') {
mbed_minimal_formatted_string_unsigned(buffer, length, &result, value, stream);
mbed_minimal_formatted_string_integer(buffer, length, &result, value, INT_UNSIGNED, width_size, prepend_zeros, stream);
} else if (next == 'X') {
mbed_minimal_formatted_string_integer(buffer, length, &result, value, HEX_UPPER, width_size, prepend_zeros, stream);
} else {
mbed_minimal_formatted_string_hexadecimal(buffer, length, &result, value, stream, next == 'X');
mbed_minimal_formatted_string_integer(buffer, length, &result, value, HEX_LOWER, width_size, prepend_zeros, stream);
}
}
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
@ -589,7 +616,7 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
double value = va_arg(arguments, double);
index = next_index;
mbed_minimal_formatted_string_double(buffer, length, &result, value, stream);
mbed_minimal_formatted_string_double(buffer, length, &result, value, precision, width_size, prepend_zeros, stream);
}
#endif
/* character */
@ -643,4 +670,3 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma
return result;
}

View File

@ -28,6 +28,7 @@
#include <stdbool.h>
#include <limits.h>
#include <inttypes.h>
#include <cstring>
#ifndef ULLONG_MAX
#define ULLONG_MAX UINT64_MAX
@ -268,6 +269,42 @@ static control_t test_printf_d(const size_t call_count)
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
result_minimal = mbed_printf("06d: %06d\r\n", -1234);
result_file = mbed_fprintf(stderr, "06d: %06d\r\n", -1234);
result_baseline = sizeof("06d: -01234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("6d: %6d\r\n", -1234);
result_file = mbed_fprintf(stderr, "6d: %6d\r\n", -1234);
result_baseline = sizeof("6d: -1234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("2d: %2d\r\n", -1234);
result_file = mbed_fprintf(stderr, "2d: %2d\r\n", -1234);
result_baseline = sizeof("2d: -1234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("02d: %02d\r\n", -1234);
result_file = mbed_fprintf(stderr, "02d: %02d\r\n", -1234);
result_baseline = sizeof("02d: -1234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("4d: %4d\r\n", 0);
result_file = mbed_fprintf(stderr, "4d: %4d\r\n", 0);
result_baseline = sizeof("4d: 0\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("04d: %04d\r\n", 0);
result_file = mbed_fprintf(stderr, "04d: %04d\r\n", 0);
result_baseline = sizeof("04d: 0000\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
return CaseNext;
}
@ -387,6 +424,30 @@ static control_t test_printf_u(const size_t call_count)
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
#endif
result_minimal = mbed_printf("06u: %06u\r\n", 1234);
result_file = mbed_fprintf(stderr, "06u: %06u\r\n", 1234);
result_baseline = sizeof("06u: 001234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("6u: %6u\r\n", 1234);
result_file = mbed_fprintf(stderr, "6u: %6u\r\n", 1234);
result_baseline = sizeof("6u: 1234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("2u: %2u\r\n", 1234);
result_file = mbed_fprintf(stderr, "2u: %2u\r\n", 1234);
result_baseline = sizeof("2u: 1234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("02u: %02u\r\n", 1234);
result_file = mbed_fprintf(stderr, "02u: %02u\r\n", 1234);
result_baseline = sizeof("02u: 1234\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
return CaseNext;
}
@ -510,6 +571,43 @@ static control_t test_printf_x(const size_t call_count)
result_baseline = make_test_string("x: ", 11259375, BASE_16, "\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
// Test prepending zeros and width size
result_minimal = mbed_printf("04X: %04X\r\n", 0x04F6);
result_file = mbed_fprintf(stderr, "04X: %04X\r\n", 0x04F6);
result_baseline = sizeof("04X: 04F6\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("0X: %0X\r\n", 0x04F6);
result_file = mbed_fprintf(stderr, "0X: %0X\r\n", 0x04F6);
result_baseline = sizeof("0X: 4F6\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("6X: %6X\r\n", 0x04F6);
result_file = mbed_fprintf(stderr, "6X: %6X\r\n", 0x04F6);
result_baseline = sizeof("6X: 4F6\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("4X: %4X\r\n", 0xFF04F6);
result_file = mbed_fprintf(stderr, "4X: %4X\r\n", 0xFF04F6);
result_baseline = sizeof("4X: FF04F6\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("4X: %4X\r\n", 0);
result_file = mbed_fprintf(stderr, "4X: %4X\r\n", 0);
result_baseline = sizeof("4X: 0\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
result_minimal = mbed_printf("04X: %04X\r\n", 0);
result_file = mbed_fprintf(stderr, "04X: %04X\r\n", 0);
result_baseline = sizeof("04X: 0000\r\n") - 1;
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);
return CaseNext;
}
@ -640,6 +738,42 @@ static control_t test_snprintf_d(const size_t call_count)
result_minimal = mbed_snprintf(0, 0, "%d + %d = %d\n", a, b, a + b);
TEST_ASSERT_EQUAL_INT(10, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "06d: %06d\r\n", -1234);
strcpy(expected_string, "06d: -01234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "6d: %6d\r\n", -1234);
strcpy(expected_string, "6d: -1234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "2d: %2d\r\n", -1234);
strcpy(expected_string, "2d: -1234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "02d: %02d\r\n", -1234);
strcpy(expected_string, "02d: -1234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "4d: %4d\r\n", 0);
strcpy(expected_string, "4d: 0\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "04d: %04d\r\n", 0);
strcpy(expected_string, "04d: 0000\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
@ -743,6 +877,30 @@ static control_t test_snprintf_u(const size_t call_count)
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "06u: %06u\r\n", 1234);
strcpy(expected_string, "06u: 001234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "6u: %6u\r\n", 1234);
strcpy(expected_string, "6u: 1234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "2u: %2u\r\n", 1234);
strcpy(expected_string, "2u: 1234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "02u: %02u\r\n", 1234);
strcpy(expected_string, "02u: 1234\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
@ -845,6 +1003,43 @@ static control_t test_snprintf_x(const size_t call_count)
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
#endif
// Test prepending zeros and width size
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "04X: %04X\r\n", 0x04F6);
strcpy(expected_string, "04X: 04F6\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "0X: %0X\r\n", 0x04F6);
strcpy(expected_string, "0X: 4F6\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "6X: %6X\r\n", 0x04F6);
strcpy(expected_string, "6X: 4F6\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "4X: %4X\r\n", 0xFF04F6);
strcpy(expected_string, "4X: FF04F6\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "4X: %4X\r\n", 0);
strcpy(expected_string, "4X: 0\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "04X: %04X\r\n", 0);
strcpy(expected_string, "04X: 0000\r\n");
result_baseline = strlen(expected_string);
TEST_ASSERT_EQUAL_STRING(expected_string, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
@ -914,6 +1109,74 @@ static control_t test_printf_f(const size_t call_count)
result_minimal = mbed_printf("f: %f\r\n", 2.12345649);
result_baseline = sprintf(buffer_baseline, "f: 2.123456\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %.3f\r\n", 2.12345649);
result_baseline = sprintf(buffer_baseline, "f: 2.123\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %.8f\r\n", 2.12345649);
result_baseline = sprintf(buffer_baseline, "f: 2.12345649\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %.10f\r\n", 2.12345649);
result_baseline = sprintf(buffer_baseline, "f: 2.1234564900\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %05.3f\r\n", 22.12345649);
result_baseline = sprintf(buffer_baseline, "f: 22.123\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %5.3f\r\n", 22.1);
result_baseline = sprintf(buffer_baseline, "f: 22.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %08.3f\r\n", 22.1);
result_baseline = sprintf(buffer_baseline, "f: 0022.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %8.3f\r\n", 22.1);
result_baseline = sprintf(buffer_baseline, "f: 22.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %05.3f\r\n", -22.12345649);
result_baseline = sprintf(buffer_baseline, "f: -22.123\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %5.3f\r\n", -22.1);
result_baseline = sprintf(buffer_baseline, "f: -22.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %08.3f\r\n", -22.1);
result_baseline = sprintf(buffer_baseline, "f: -022.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %8.3f\r\n", -22.1);
result_baseline = sprintf(buffer_baseline, "f: -22.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %8.3f\r\n", 0.1);
result_baseline = sprintf(buffer_baseline, "f: 0.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %8.3f\r\n", -0.1);
result_baseline = sprintf(buffer_baseline, "f: -0.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %08.3f\r\n", 0.1);
result_baseline = sprintf(buffer_baseline, "f: 0000.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %08.3f\r\n", -0.1);
result_baseline = sprintf(buffer_baseline, "f: -000.100\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("f: %05.3f\r\n", -22.1236);
result_baseline = sprintf(buffer_baseline, "f: -22.124\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_printf("05.0f: %05.0f\r\n", 7.9);
result_baseline = sprintf(buffer_baseline, "05.0f: 00008\r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
@ -953,7 +1216,86 @@ static control_t test_snprintf_f(const size_t call_count)
result_baseline = sprintf(buffer_baseline, "f: 3.141593\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %.3f\r\n", 2.12345649);
result_baseline = sprintf(buffer_baseline, "f: 2.123\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %.8f\r\n", 2.12345649);
result_baseline = sprintf(buffer_baseline, "f: 2.12345649\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %05.3f\r\n", 22.12345649);
result_baseline = sprintf(buffer_baseline, "f: 22.123\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %5.3f\r\n", 22.1);
result_baseline = sprintf(buffer_baseline, "f: 22.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %08.3f\r\n", 22.1);
result_baseline = sprintf(buffer_baseline, "f: 0022.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %8.3f\r\n", 22.1);
result_baseline = sprintf(buffer_baseline, "f: 22.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %05.3f\r\n", -22.12345649);
result_baseline = sprintf(buffer_baseline, "f: -22.123\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %5.3f\r\n", -22.1);
result_baseline = sprintf(buffer_baseline, "f: -22.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %08.3f\r\n", -22.1);
result_baseline = sprintf(buffer_baseline, "f: -022.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %8.3f\r\n", -22.1);
result_baseline = sprintf(buffer_baseline, "f: -22.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %8.3f\r\n", 0.1);
result_baseline = sprintf(buffer_baseline, "f: 0.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %8.3f\r\n", -0.1);
result_baseline = sprintf(buffer_baseline, "f: -0.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %08.3f\r\n", 0.1);
result_baseline = sprintf(buffer_baseline, "f: 0000.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %08.3f\r\n", -0.1);
result_baseline = sprintf(buffer_baseline, "f: -000.100\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "f: %05.3f\r\n", -22.1236);
result_baseline = sprintf(buffer_baseline, "f: -22.124\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
CLEAN_BUFFER;
result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "05.0f: %05.0f\r\n", 7.9);
result_baseline = sprintf(buffer_baseline, "05.0f: 00008\r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
return CaseNext;
}
#endif