Skip to content

Commit

Permalink
printf: Handle binary format specifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
Qwinci committed Aug 2, 2024
1 parent 6b08458 commit 49b8bf9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
6 changes: 3 additions & 3 deletions include/frg/formatting.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ enum class format_error {

namespace _fmt_basics {
// width: Minimum width of the output (padded with spaces by default).
// precision: Minimum number of digits in the ouput (always padded with zeros).
// precision: Minimum number of digits in the output (always padded with zeros).
template<Sink S, typename T>
void print_digits(S &sink, T number, bool negative, int radix,
int width, int precision, char padding, bool left_justify,
bool group_thousands, bool always_sign, bool plus_becomes_space,
bool use_capitals, locale_options locale_opts) {
const char *digits = use_capitals ? "0123456789ABCDEF" : "0123456789abcdef";
char buffer[32];
char buffer[64];

int k = 0; // number of digits
int c = 0; // number of chars since last grouping
Expand Down Expand Up @@ -137,7 +137,7 @@ namespace _fmt_basics {

// print the number in reverse order and determine #digits.
do {
FRG_ASSERT(k < 32); // TODO: variable number of digits
FRG_ASSERT(k < 64); // TODO: variable number of digits
buffer[k++] = digits[number % radix];
number /= radix;
step_grouping();
Expand Down
18 changes: 10 additions & 8 deletions include/frg/printf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,16 @@ void do_printf_ints(S &sink, char t, format_options opts,
opts.plus_becomes_space, false, locale_opts);
}
} break;
case 'o': {
case 'b':
case 'B' : {
auto print = [&] (auto number) {
if (number && opts.alt_conversion)
sink.append('0');
sink.append(t == 'b' ? "0b" : "0B");

if(opts.precision && *opts.precision == 0 && !number) {
// print nothing in this case
}else{
_fmt_basics::print_int(sink, number, 8, opts.minimum_width,
_fmt_basics::print_int(sink, number, 2, opts.minimum_width,
opts.precision ? *opts.precision : 1, opts.fill_zeros ? '0' : ' ',
opts.left_justify, false, opts.always_sign, opts.plus_becomes_space,
false, locale_opts);
Expand All @@ -367,15 +368,15 @@ void do_printf_ints(S &sink, char t, format_options opts,
print(pop_arg<unsigned int>(vsp, &opts));
}
} break;
case 'x': {
case 'o': {
auto print = [&] (auto number) {
if (number && opts.alt_conversion)
sink.append("0x");
sink.append('0');

if(opts.precision && *opts.precision == 0 && !number) {
// print nothing in this case
}else{
_fmt_basics::print_int(sink, number, 16, opts.minimum_width,
_fmt_basics::print_int(sink, number, 8, opts.minimum_width,
opts.precision ? *opts.precision : 1, opts.fill_zeros ? '0' : ' ',
opts.left_justify, false, opts.always_sign, opts.plus_becomes_space,
false, locale_opts);
Expand All @@ -399,18 +400,19 @@ void do_printf_ints(S &sink, char t, format_options opts,
print(pop_arg<unsigned int>(vsp, &opts));
}
} break;
case 'x':
case 'X': {
auto print = [&] (auto number) {
if (number && opts.alt_conversion)
sink.append("0X");
sink.append(t == 'x' ? "0x" : "0X");

if(opts.precision && *opts.precision == 0 && !number) {
// print nothing in this case
}else{
_fmt_basics::print_int(sink, number, 16, opts.minimum_width,
opts.precision ? *opts.precision : 1, opts.fill_zeros ? '0' : ' ',
opts.left_justify, false, opts.always_sign, opts.plus_becomes_space,
true, locale_opts);
t == 'X', locale_opts);
}
};

Expand Down
14 changes: 13 additions & 1 deletion tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ TEST(formatting, printf) {
case 'p': case 's':
frg::do_printf_chars(*sink_, t, opts, szmod, vsp_);
break;
case 'd': case 'i': case 'o': case 'x': case 'X': case 'u':
case 'd': case 'i': case 'o': case 'x': case 'X': case 'b': case 'B': case 'u':
frg::do_printf_ints(*sink_, t, opts, szmod, vsp_);
break;
default:
Expand Down Expand Up @@ -333,6 +333,8 @@ TEST(formatting, printf) {
// Test '#' flag.
do_test("0xc", "%#x", 12);
do_test("0XC", "%#X", 12);
do_test("0b1100", "%#b", 12);
do_test("0B1100", "%#B", 12);
do_test("014", "%#o", 12);
do_test("0", "%#x", 0);
do_test("0", "%#X", 0);
Expand Down Expand Up @@ -368,6 +370,16 @@ TEST(formatting, printf) {
do_test("C", "%hhX", 12);
do_test("C", "%jX", (uintmax_t)12);

// Test 'b' with different size mods to see
// if they work
do_test("1100", "%b", 12);
do_test("1100", "%lb", 12L);
do_test("1100", "%llb", 12LL);
do_test("1100", "%zb", (size_t)12);
do_test("1100", "%hb", 12);
do_test("1100", "%hhb", 12);
do_test("1100", "%jb", (uintmax_t)12);

// Test 'o' with different size mods to see
// if they work
do_test("14", "%o", 12);
Expand Down

0 comments on commit 49b8bf9

Please sign in to comment.