Skip to content

Commit 64e2b3e

Browse files
committed
* 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 eyalroz#114. * Our fix for eyalroz#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.
1 parent 8cedb17 commit 64e2b3e

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

printf.c

+23-10
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,16 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl
305305
if (!value) {
306306
if ( !(flags & FLAGS_PRECISION) ) {
307307
buf[len++] = '0';
308-
flags &= ~FLAGS_HASH;
309-
// We drop this flag this since either the alternative and regular modes of the specifier
310-
// don't differ on 0 values, or (in the case of octal) we've already provided the special
311-
// handling for this mode.
312-
}
308+
flags &= ~FLAGS_HASH;
309+
// We drop this flag this since either the alternative and regular modes of the specifier
310+
// don't differ on 0 values, or (in the case of octal) we've already provided the special
311+
// handling for this mode.
312+
}
313+
else if (base != 8U) {
314+
flags &= ~FLAGS_HASH;
315+
// We drop this flag this since either the alternative and regular modes of the specifier
316+
// don't differ on 0 values
317+
}
313318
}
314319
else {
315320
do {
@@ -330,13 +335,21 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t
330335
char buf[PRINTF_NTOA_BUFFER_SIZE];
331336
size_t len = 0U;
332337

333-
// no hash for 0 values
334338
if (!value) {
335-
flags &= ~FLAGS_HASH;
339+
if ( !(flags & FLAGS_PRECISION) ) {
340+
buf[len++] = '0';
341+
flags &= ~FLAGS_HASH;
342+
// We drop this flag this since either the alternative and regular modes of the specifier
343+
// don't differ on 0 values, or (in the case of octal) we've already provided the special
344+
// handling for this mode.
345+
}
346+
else if (base == 16U) {
347+
flags &= ~FLAGS_HASH;
348+
// We drop this flag this since either the alternative and regular modes of the specifier
349+
// don't differ on 0 values
350+
}
336351
}
337-
338-
// write if precision != 0 and value is != 0
339-
if (!(flags & FLAGS_PRECISION) || value) {
352+
else {
340353
do {
341354
const char digit = (char)(value % base);
342355
buf[len++] = (char)(digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10);

test/test_suite.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ TEST_CASE("# flag", "[]" ) {
379379
PRINTING_CHECK("0001", ==, test::sprintf_, buffer, "%#.4o", 1 );
380380
PRINTING_CHECK("0x1001", ==, test::sprintf_, buffer, "%#04x", 0x1001 );
381381
PRINTING_CHECK("01001", ==, test::sprintf_, buffer, "%#04o", 01001 );
382-
PRINTING_CHECK("", ==, test::sprintf_, buffer, "%#.0llx", (long long) 0);
382+
PRINTING_CHECK("", ==, test::sprintf_, buffer, "%#.0x", 0 );
383383
PRINTING_CHECK("0x0000614e", ==, test::sprintf_, buffer, "%#.8x", 0x614e );
384384
}
385385

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

393+
TEST_CASE("# flag with long-long", "[]" ) {
394+
char buffer[100];
395+
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#llo", (long long) 0 );
396+
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#0llo", (long long) 0 );
397+
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#.0llo", (long long) 0 );
398+
PRINTING_CHECK("0", ==, test::sprintf_, buffer, "%#.1llo", (long long) 0 );
399+
PRINTING_CHECK(" 0", ==, test::sprintf_, buffer, "%#4llo", (long long) 0 );
400+
PRINTING_CHECK("0000", ==, test::sprintf_, buffer, "%#.4llo", (long long) 0 );
401+
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#llo", (long long) 1 );
402+
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#0llo", (long long) 1 );
403+
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#.0llo", (long long) 1 );
404+
PRINTING_CHECK("01", ==, test::sprintf_, buffer, "%#.1llo", (long long) 1 );
405+
PRINTING_CHECK(" 01", ==, test::sprintf_, buffer, "%#4llo", (long long) 1 );
406+
PRINTING_CHECK("0001", ==, test::sprintf_, buffer, "%#.4llo", (long long) 1 );
407+
PRINTING_CHECK("0x1001", ==, test::sprintf_, buffer, "%#04llx", (long long) 0x1001 );
408+
PRINTING_CHECK("01001", ==, test::sprintf_, buffer, "%#04llo", (long long) 01001 );
409+
PRINTING_CHECK("", ==, test::sprintf_, buffer, "%#.0llx", (long long) 0 );
410+
PRINTING_CHECK("0x0000614e", ==, test::sprintf_, buffer, "%#.8llx", (long long) 0x614e );
411+
}
412+
413+
#ifdef TEST_WITH_NON_STANDARD_FORMAT_STRINGS
414+
TEST_CASE("# flag with long-long - non-standard format", "[]" ) {
415+
char buffer[100];
416+
PRINTING_CHECK("0b110", ==, test::sprintf_, buffer, "%#llb", (long long) 6);
417+
}
418+
#endif
419+
420+
393421
TEST_CASE("specifier", "[]" ) {
394422
char buffer[100];
395423
PRINTING_CHECK("Hello testing", ==, test::sprintf_, buffer, "Hello testing");

0 commit comments

Comments
 (0)