diff options
-rw-r--r-- | src/estream-printf.c | 38 | ||||
-rw-r--r-- | tests/t-printf.c | 26 |
2 files changed, 57 insertions, 7 deletions
diff --git a/src/estream-printf.c b/src/estream-printf.c index f419a1e..8e71db7 100644 --- a/src/estream-printf.c +++ b/src/estream-printf.c @@ -163,6 +163,7 @@ typedef enum CONSPEC_UNSIGNED, CONSPEC_HEX, CONSPEC_HEX_UP, + CONSPEC_BIN, CONSPEC_FLOAT, CONSPEC_FLOAT_UP, CONSPEC_EXP, @@ -367,6 +368,7 @@ compute_type (argspec_t arg) case CONSPEC_UNSIGNED: case CONSPEC_HEX: case CONSPEC_HEX_UP: + case CONSPEC_BIN: switch (arg->lenmod) { case LENMOD_CHAR: arg->vt = VALTYPE_UCHAR; break; @@ -627,6 +629,7 @@ parse_format (const char *format, case 'u': conspec = CONSPEC_UNSIGNED; break; case 'x': conspec = CONSPEC_HEX; break; case 'X': conspec = CONSPEC_HEX_UP; break; + case 'b': conspec = CONSPEC_BIN; break; case 'f': conspec = CONSPEC_FLOAT; break; case 'F': conspec = CONSPEC_FLOAT_UP; break; case 'e': conspec = CONSPEC_EXP; break; @@ -844,7 +847,7 @@ pr_integer (estream_printf_out_t outfnc, void *outfncarg, #else unsigned long aulong; #endif - char numbuf[100]; + char numbuf[150]; /* Should be sufficient for %b with 128 bit integers */ char *p, *pend; size_t n; char signchar = 0; @@ -955,6 +958,17 @@ pr_integer (estream_printf_out_t outfnc, void *outfncarg, if ((arg->flags & FLAG_ALT_CONV) && *p != '0') *--p = '0'; } + else if (arg->conspec == CONSPEC_BIN) + { + do + { + *--p = '0' + (aulong % 2); + aulong /= 2; + } + while (aulong); + if ((arg->flags & FLAG_ALT_CONV)) + n_extra += 2; + } else /* HEX or HEXUP */ { const char *digits = ((arg->conspec == CONSPEC_HEX) @@ -998,13 +1012,22 @@ pr_integer (estream_printf_out_t outfnc, void *outfncarg, *nbytes += 1; } - if ((arg->flags & FLAG_ALT_CONV) - && (arg->conspec == CONSPEC_HEX || arg->conspec == CONSPEC_HEX_UP)) + if ((arg->flags & FLAG_ALT_CONV)) { - rc = outfnc (outfncarg, arg->conspec == CONSPEC_HEX? "0x": "0X", 2); - if (rc) - return rc; - *nbytes += 2; + if (arg->conspec == CONSPEC_HEX || arg->conspec == CONSPEC_HEX_UP) + { + rc = outfnc (outfncarg, arg->conspec == CONSPEC_HEX? "0x": "0X", 2); + if (rc) + return rc; + *nbytes += 2; + } + else if (arg->conspec == CONSPEC_BIN) + { + rc = outfnc (outfncarg, "0b", 2); + if (rc) + return rc; + *nbytes += 2; + } } if (n_prec) @@ -1445,6 +1468,7 @@ do_format (estream_printf_out_t outfnc, void *outfncarg, case CONSPEC_OCTAL: case CONSPEC_HEX: case CONSPEC_HEX_UP: + case CONSPEC_BIN: rc = pr_integer (outfnc, outfncarg, arg, value, nbytes); break; case CONSPEC_FLOAT: diff --git a/tests/t-printf.c b/tests/t-printf.c index 87c201d..eb54750 100644 --- a/tests/t-printf.c +++ b/tests/t-printf.c @@ -486,6 +486,32 @@ check_fprintf_sf (void) } free (result); + gpgrt_fprintf_sf (stream, string_filter, &sfstate, + "a=%x b=%b c=%X", + 19410909u, 19410909u, 19410909u); + expect = "a=1282fdd b=1001010000010111111011101 c=1282FDD"; + result = stream_to_string (stream); + if (strcmp (result, expect)) + { + show ("expect: '%s'\n", expect); + show ("result: '%s'\n", result); + fail ("fprintf_sf failed at %d\n", __LINE__); + } + free (result); + + gpgrt_fprintf_sf (stream, string_filter, &sfstate, + "a=%#x b=%#b c=%#X", + 19420130u, 19420130u, 19420130u); + expect = "a=0x12853e2 b=0b1001010000101001111100010 c=0X12853E2"; + result = stream_to_string (stream); + if (strcmp (result, expect)) + { + show ("expect: '%s'\n", expect); + show ("result: '%s'\n", result); + fail ("fprintf_sf failed at %d\n", __LINE__); + } + free (result); + gpgrt_fclose (stream); } |