diff options
author | Werner Koch <[email protected]> | 2025-08-14 15:03:22 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2025-08-14 15:04:08 +0000 |
commit | 6ac5332e4f6988112f4272cfe7a2eee31173ff3f (patch) | |
tree | 8029968512906204b183ad546c70ec7999bc0fc0 /src | |
parent | Set build specific variable for zOS (diff) | |
download | libgpg-error-master.tar.gz libgpg-error-master.zip |
* src/estream-printf.c (CONSSPEC_BIN): New.
(compute_type): Handle it.
(parse_format): Support 'b'.
(do_format): Divert 'b' to pr_integer.
(pr_integer): Print binary format.
* tests/t-printf.c (check_fprintf_sf): Add two simple testcases.
--
Might be handy in some cases and is easy to implement. Minor drawback
is that this increases a stack based buffer from 100 to 150 bytes.
Diffstat (limited to 'src')
-rw-r--r-- | src/estream-printf.c | 38 |
1 files changed, 31 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: |