Skip to content

Commit

Permalink
Fixes #114; regards #109, #99, #110.
Browse files Browse the repository at this point in the history
* Added a couple of test cases for exposing the behavior of the `#` modifier (alternative mode) together with `ll` (long long modifier), and specifically exposing the example format string mentioned in bug #114.
* Our fix for #109 was too eager to keep `FLAG_HASH` - it dropped it only when a precision wasn't specified. We're now going part of the way back - dropping `FLAG_HASH` even when precision wasn't specific - except for octal.
* The `long long` version of ntoa now behaves just like the `long` version.
  • Loading branch information
eyalroz committed Jul 31, 2021
1 parent 1c7ce52 commit e178f4e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
33 changes: 23 additions & 10 deletions printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,16 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl
if (!value) {
if ( !(flags & FLAGS_PRECISION) ) {
buf[len++] = '0';
flags &= ~FLAGS_HASH;
// We drop this flag this since either the alternative and regular modes of the specifier
// don't differ on 0 values, or (in the case of octal) we've already provided the special
// handling for this mode.
}
flags &= ~FLAGS_HASH;
// We drop this flag this since either the alternative and regular modes of the specifier
// don't differ on 0 values, or (in the case of octal) we've already provided the special
// handling for this mode.
}
else if (base != 8U) {
flags &= ~FLAGS_HASH;
// We drop this flag this since either the alternative and regular modes of the specifier
// don't differ on 0 values
}
}
else {
do {
Expand All @@ -330,13 +335,21 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;

// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
if ( !(flags & FLAGS_PRECISION) ) {
buf[len++] = '0';
flags &= ~FLAGS_HASH;
// We drop this flag this since either the alternative and regular modes of the specifier
// don't differ on 0 values, or (in the case of octal) we've already provided the special
// handling for this mode.
}
else if (base == 16U) {
flags &= ~FLAGS_HASH;
// We drop this flag this since either the alternative and regular modes of the specifier
// don't differ on 0 values
}
}

// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
else {
do {
const char digit = (char)(value % base);
buf[len++] = (char)(digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10);
Expand Down
30 changes: 29 additions & 1 deletion test/test_suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ TEST_CASE("# flag", "[]" ) {
PRINTING_CHECK("0001", ==, test::sprintf_, buffer, "%#.4o", 1 );
PRINTING_CHECK("0x1001", ==, test::sprintf_, buffer, "%#04x", 0x1001 );
PRINTING_CHECK("01001", ==, test::sprintf_, buffer, "%#04o", 01001 );
PRINTING_CHECK("", ==, test::sprintf_, buffer, "%#.0llx", (long long) 0);
PRINTING_CHECK("", ==, test::sprintf_, buffer, "%#.0x", 0 );
PRINTING_CHECK("0x0000614e", ==, test::sprintf_, buffer, "%#.8x", 0x614e );
}

Expand All @@ -390,6 +390,34 @@ TEST_CASE("# flag - non-standard format", "[]" ) {
}
#endif

TEST_CASE("# flag with long-long", "[]" ) {
char buffer[100];
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#llo", (long long) 0 );
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#0llo", (long long) 0 );
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#.0llo", (long long) 0 );
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#.1llo", (long long) 0 );
PRINTING_CHECK(" 0", ==, test::sprintf_, buffer, "%#4llo", (long long) 0 );
PRINTING_CHECK("0000", ==, test::sprintf_, buffer, "%#.4llo", (long long) 0 );
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#llo", (long long) 1 );
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#0llo", (long long) 1 );
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#.0llo", (long long) 1 );
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#.1llo", (long long) 1 );
PRINTING_CHECK(" 01", ==, test::sprintf_, buffer, "%#4llo", (long long) 1 );
PRINTING_CHECK("0001", ==, test::sprintf_, buffer, "%#.4llo", (long long) 1 );
PRINTING_CHECK("0x1001", ==, test::sprintf_, buffer, "%#04llx", (long long) 0x1001 );
PRINTING_CHECK("01001", ==, test::sprintf_, buffer, "%#04llo", (long long) 01001 );
PRINTING_CHECK("", ==, test::sprintf_, buffer, "%#.0llx", (long long) 0 );
PRINTING_CHECK("0x0000614e", ==, test::sprintf_, buffer, "%#.8llx", (long long) 0x614e );
}

#ifdef TEST_WITH_NON_STANDARD_FORMAT_STRINGS
TEST_CASE("# flag with long-long - non-standard format", "[]" ) {
char buffer[100];
PRINTING_CHECK("0b110", ==, test::sprintf_, buffer, "%#llb", (long long) 6);
}
#endif


TEST_CASE("specifier", "[]" ) {
char buffer[100];
PRINTING_CHECK("Hello testing", ==, test::sprintf_, buffer, "Hello testing");
Expand Down

0 comments on commit e178f4e

Please sign in to comment.