Skip to content

Commit

Permalink
minimal-printf: Fix handling of the two character sequence %%
Browse files Browse the repository at this point in the history
The two character sequence %% is used in standard implementations of
printf to print a single %. This is because % is essentially printf's
escape character for format specifiers and as \% cannot work printf
uses %%.
Therefore to be compatible with string buffers containing
%%, minimal-printf also needs to only print a single %.
  • Loading branch information
hugueskamba committed Oct 23, 2019
1 parent 5d330bf commit ceffb6d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
46 changes: 46 additions & 0 deletions TESTS/mbed_platform/minimal-printf/compliance/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,21 @@ static control_t test_printf_x(const size_t call_count)
return CaseNext;
}

static control_t test_printf_percent(const size_t call_count)
{
int result_baseline;
int result_minimal;
int result_file;

result_minimal = mbed_printf("%% \r\n");
result_file = mbed_fprintf(stderr, "%% \r\n");
result_baseline = printf("%% \r\n");
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_file);

return CaseNext;
}

/******************************************************************************/
/* */
/* SNPRINTF */
Expand Down Expand Up @@ -721,6 +736,34 @@ static control_t test_snprintf_x(const size_t call_count)
return CaseNext;
}

static control_t test_snprintf_percent(const size_t call_count)
{
char buffer_baseline[100];
char buffer_minimal[100];
int result_baseline;
int result_minimal;

result_minimal = mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "%% \r\n");
result_baseline = snprintf(buffer_baseline, sizeof(buffer_baseline), "%% \r\n");
TEST_ASSERT_EQUAL_STRING(buffer_baseline, buffer_minimal);
TEST_ASSERT_EQUAL_INT(result_baseline, result_minimal);

return CaseNext;
}

static control_t test_snprintf_unsupported_specifier(const size_t call_count)
{
char buffer_minimal[100];

TEST_ASSERT_NOT_EQUAL(
0,
mbed_snprintf(buffer_minimal, sizeof(buffer_minimal), "%a \r\n", 5)
);
TEST_ASSERT_EQUAL_STRING("%a \r\n", buffer_minimal);

return CaseNext;
}

#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
static control_t test_printf_f(const size_t call_count)
{
Expand Down Expand Up @@ -902,6 +945,9 @@ Case cases[] = {
Case("snprintf %u", test_snprintf_u),
Case("printf %x", test_printf_x),
Case("snprintf %x", test_snprintf_x),
Case("printf %%", test_printf_percent),
Case("snprintf %%", test_snprintf_percent),
Case("snprintf unsupported specifier", test_snprintf_unsupported_specifier),
#if MBED_CONF_PLATFORM_MINIMAL_PRINTF_ENABLE_FLOATING_POINT
Case("printf %f", test_printf_f),
Case("snprintf %f", test_snprintf_f),
Expand Down
19 changes: 7 additions & 12 deletions platform/source/minimal-printf/mbed_printf_implementation.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,19 +626,14 @@ int mbed_minimal_formatted_string(char *buffer, size_t length, const char *forma

mbed_minimal_formatted_string_void_pointer(buffer, length, &result, value, stream);
} else {
/* write all characters between format beginning and unrecognied modifier */
while (index < next_index) {
mbed_minimal_formatted_string_character(buffer, length, &result, format[index], stream);
index++;
}

/* if this is not the end of the string, write unrecognized modifier */
if (next != '\0') {
mbed_minimal_formatted_string_character(buffer, length, &result, format[index], stream);
} else {
/* break out of for loop */
break;
// Unrecognised, or `%%`. Print the `%` that led us in.
mbed_minimal_formatted_string_character(buffer, length, &result, '%', stream);
if (next == '%') {
// Continue printing loop after `%%`
index = next_index;
}
// Otherwise we continue the printing loop after the leading `%`, so an
// unrecognised thing like "Blah = %a" will just come out as "Blah = %a"
}
} else
/* not a format specifier */
Expand Down

0 comments on commit ceffb6d

Please sign in to comment.