diff --git a/platform/source/minimal-printf/README.md b/platform/source/minimal-printf/README.md index d99fe3c124b..4f9367e25d9 100644 --- a/platform/source/minimal-printf/README.md +++ b/platform/source/minimal-printf/README.md @@ -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). diff --git a/platform/source/minimal-printf/mbed_printf_implementation.c b/platform/source/minimal-printf/mbed_printf_implementation.c index 455ec55890d..42aed179726 100644 --- a/platform/source/minimal-printf/mbed_printf_implementation.c +++ b/platform/source/minimal-printf/mbed_printf_implementation.c @@ -21,6 +21,7 @@ #include #include #include +#include #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; - /* use unsigned long int function */ - mbed_minimal_formatted_string_unsigned(buffer, length, result, new_value, stream); -} + 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; + } -/** - * @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; + + 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' + }; + + 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; + /* shift value one decimal position */ + value = value / 10; + } } + } - /* write scratch pad to buffer or output */ - for (; index > 0; index--) { - mbed_minimal_putchar(buffer, length, result, scratch[index - 1], stream); + if (negative_value) { + if (prepend_zeros) { + mbed_minimal_putchar(buffer, length, result, '-', stream); } + index++; // add one to index to count '-' } -} -/** - * @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 filler characters + if (width_size > index) { + for (int i = width_size; i > index; i--) { + mbed_minimal_putchar(buffer, length, result, filler, 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--; // 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); + if (dec_precision == PRECISION_DEFAULT) { + dec_precision = MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS; + } - /* get decimal part */ - double precision = 1.0; + if (dec_precision != 0) { + width_size -= dec_precision + 1; // decimal precision plus '.' + if (width_size < 0) { + width_size = 0; + } + } else { + value = (value - integer) * 1.0; + if (!((value > -0.5) && (value < 0.5))) { + integer++; + } + } - for (size_t index = 0; index < MBED_CONF_PLATFORM_MINIMAL_PRINTF_SET_FLOATING_POINT_MAX_DECIMALS; index++) { - precision *= 10; + /* 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); } - value = (value - integer) * precision; + if (dec_precision != 0) { + /* write decimal point */ + mbed_minimal_putchar(buffer, length, result, '.', stream); - /* convert to unsigned integer */ - MBED_UNSIGNED_STORAGE decimal = 0; + /* get decimal part */ + double precision = 1.0; - if (value < 0) { - MBED_SIGNED_STORAGE temp = value; - decimal = ~((MBED_UNSIGNED_STORAGE) temp) + 1; - } else { - decimal = value; - } + for (size_t index = 0; index < dec_precision; index++) { + precision *= 10; + } - /* round up or down */ - value -= decimal; + /* convert to positive number */ + if (value < 0.0) { + value *= -1.0; + } - if (!((value > -0.5) && (value < 0.5))) { - decimal++; - } + MBED_UNSIGNED_STORAGE decimal = value; - /* convert precision to unsigned integer */ - MBED_UNSIGNED_STORAGE precision_in_uint = precision; - precision_in_uint /= 10; + /* round up or down */ + value -= decimal; - /* 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; - } + if (!((value > -0.5) && (value < 0.5))) { + decimal++; + } - /* write decimal part */ - mbed_minimal_formatted_string_unsigned(buffer, length, result, decimal, stream); + /* write decimal part */ + mbed_minimal_formatted_string_integer(buffer, length, result, decimal, INT_UNSIGNED, dec_precision, true, 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; } - diff --git a/platform/tests/TESTS/mbed_platform/minimal-printf/compliance/main.cpp b/platform/tests/TESTS/mbed_platform/minimal-printf/compliance/main.cpp index 1633ddc5f53..1faf1dd3b86 100644 --- a/platform/tests/TESTS/mbed_platform/minimal-printf/compliance/main.cpp +++ b/platform/tests/TESTS/mbed_platform/minimal-printf/compliance/main.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #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