Re: [PATCH] printf: Add %B conversion specifier for binary

2020-04-27 Thread Theo de Raadt
Ingo Schwarze  wrote:

> Alejandro Colomar wrote on Mon, Apr 27, 2020 at 08:26:38PM +0200:
> 
> > This patch adds a new feature to the ``printf`` family of functions:
> > ``%B`` conversion specifier for printing unsigned numbers in binary.
> 
> No.  We do not want non-standard extensions to standard functions
> unless they provide unusually important benefit and/or are very
> widely supported elsewhere.
> 
> > I also sent today a patch to add this specifier to glibc.  They are
> > concerned about adding a new non-standard specifier, but if more C libs
> > are going to add it at the same time, it may become a thing.
> 
> Usually, glibc is quite proactive about adding non-standard stuff
> even if it is not really useful.  If even they reject the idea,
> OpenBSD certainly isn't the place to start campaigning.

"campaigning" -- good word.

When non-standard APIs or additions are added, the usual reason is
that a very common operation, done by-hand each time, tend to be
highly error prone.

Printing in binary?  Not common.  And I doubt it is error prone, either.



Re: [PATCH] printf: Add %B conversion specifier for binary

2020-04-27 Thread Ingo Schwarze
Hi,

Alejandro Colomar wrote on Mon, Apr 27, 2020 at 08:26:38PM +0200:

> This patch adds a new feature to the ``printf`` family of functions:
> ``%B`` conversion specifier for printing unsigned numbers in binary.

No.  We do not want non-standard extensions to standard functions
unless they provide unusually important benefit and/or are very
widely supported elsewhere.

> I also sent today a patch to add this specifier to glibc.  They are
> concerned about adding a new non-standard specifier, but if more C libs
> are going to add it at the same time, it may become a thing.

Usually, glibc is quite proactive about adding non-standard stuff
even if it is not really useful.  If even they reject the idea,
OpenBSD certainly isn't the place to start campaigning.

Yours,
  Ingo



Re: [PATCH] printf: Add %B conversion specifier for binary

2020-04-27 Thread Theo de Raadt
Alejandro Colomar  wrote:

> I also sent today a patch to add this specifier to glibc.  They are
> concerned about adding a new non-standard specifier, but if more C libs
> are going to add it at the same time, it may become a thing.

Sorry, but I doubt any of this is going to happen.

The action this performs is trivialy done by hand the extremely rare
pieces of code which need it.



[PATCH] printf: Add %B conversion specifier for binary

2020-04-27 Thread Alejandro Colomar

Hi all,

This patch adds a new feature to the ``printf`` family of functions:

``%B`` conversion specifier for printing unsigned numbers in binary.

Behaviour is exactly as with ``%X``, only changing the base (16 -> 2).

``%b`` is already in use by some ``printf(1)`` implementations, so I
didn't use it for binary.  Anyway, binary doesn't have letters, so only
the ``0b``/``0B`` specifier would change.

I also documented the new specifier in the man pages.

Disclaimer: I couldn't test it myself, so test it before applying it.

I also sent today a patch to add this specifier to glibc.  They are
concerned about adding a new non-standard specifier, but if more C libs
are going to add it at the same time, it may become a thing.

Alex.


From 1a41d44571ccaf9ffaf36b2c2b96dd34e48eb5b7 Mon Sep 17 00:00:00 2001
From: Alejandro Colomar 
Date: Mon, 27 Apr 2020 19:15:55 +0200
Subject: [PATCH 1/2] printf: Add %B conversion specifier for printing binary

---
 lib/libc/stdio/vfprintf.c  | 28 
 lib/libc/stdio/vfwprintf.c | 28 
 2 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 1d451a84f66..1e5cd3ad89b 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -310,9 +310,9 @@ __vfprintf(FILE *fp, const char *fmt0, __va_list ap)
char *dtoaresult = NULL;
 #endif

-   uintmax_t _umax;/* integer arguments %[diouxX] */
-   enum { OCT, DEC, HEX } base;/* base for %[diouxX] conversion */
-   int dprec;  /* a copy of prec if %[diouxX], 0 otherwise */
+   uintmax_t _umax;/* integer arguments %[BdiouxX] */
+   enum { BIN, OCT, DEC, HEX } base; /* base for %[BdiouxX] conversion */
+   int dprec;  /* a copy of prec if %[BdiouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size;   /* size of converted field or string */
const char *xdigs;  /* digits for %[xX] conversion */
@@ -320,7 +320,7 @@ __vfprintf(FILE *fp, const char *fmt0, __va_list ap)
struct __suio uio;  /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
char buf[BUF];  /* buffer with space for digits of uintmax_t */
-   char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
+   char ox[2]; /* space for 0x; ox[1] is either x, X,B or \0 */
union arg *argtable;/* args, built due to positional arg */
union arg statargtable[STATIC_ARG_TBL_SIZE];
size_t argtablesiz;
@@ -891,6 +891,10 @@ fp_common:
_umax = UARG();
base = DEC;
goto nosign;
+   case 'B':
+   _umax = UARG();
+   base = BIN;
+   goto bin;
case 'X':
xdigs = xdigs_upper;
goto hex;
@@ -898,8 +902,8 @@ fp_common:
xdigs = xdigs_lower;
 hex:   _umax = UARG();
base = HEX;
-   /* leading 0x/X only if non-zero */
-   if (flags & ALT && _umax != 0)
+   /* leading 0x/X/B only if non-zero */
+bin:   if (flags & ALT && _umax != 0)
ox[1] = ch;

/* unsigned conversions */
@@ -925,6 +929,13 @@ number:if ((dprec = prec) >= 0)
 * a variable; hence this switch.
 */
switch (base) {
+   case BIN:
+   do {
+   *--cp = to_char(_umax & 1);
+   _umax >>= 1;
+   } while (_umax);
+   break;
+
case OCT:
do {
*--cp = to_char(_umax & 7);
@@ -980,7 +991,7 @@ number: if ((dprec = prec) >= 0)
 * first be prefixed by any sign or other prefix; otherwise,
 * it should be blank padded before the prefix is emitted.
 * After any left-hand padding and prefixing, emit zeroes
-* required by a decimal %[diouxX] precision, then print the
+* required by a decimal %[BdiouxX] precision, then print the
 * string proper, then emit zeroes required by any leftover
 * floating precision; finally, if LADJUST, pad with blanks.
 *
@@ -1000,7 +1011,7 @@ number:   if ((dprec = prec) >= 0)
/* prefix */