unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* printf %b
@ 2020-04-25 13:33 Alejandro Colomar via Libc-alpha
  2020-04-26  0:54 ` Jonathan Nieder via Libc-alpha
  0 siblings, 1 reply; 4+ messages in thread
From: Alejandro Colomar via Libc-alpha @ 2020-04-25 13:33 UTC (permalink / raw
  To: libc-alpha

Hi all,

In my personal library, about a year ago, I wrote a function to register 
the ``b`` and ``B`` conversion specifiers using 
``register_printf_specifier()``.

They work the closest possible to ``o``, ``u``, ``x`` & ``X``:

  - All "flag characters" behave as in ``x``, ``X`` (or as close as 
possible, while being meaningful).
  - "Field width" and "precision" behave as in ``x``, ``X`` (or as close 
as possible, while being meaningful).
  - All "length modifiers" that are valid on ``o``, ``u``, ``x``, ``X`` 
are valid.
  - There are some flags that override others in the case of ``o``, 
``u``, ``x``, ``X``. Those behaviours have been kept the same.
  - I decided that the ``'`` flag character, which normally should group 
the output in thousands in decimal numbers, and is ignored in 
hexadecimal numbers, would be more meaningful here if it grouped nibbles 
(half bytes), and instead of using the locale for thousands separator, 
it should use ``_``.

Basically, from reading the documentation for other conversion 
specifiers, one should have a good idea of how it works.

Here's the source code:

https://github.com/alejandro-colomar/libalx/blob/master/src/base/stdio/printf/b.c

I did some testing, and it works as expected.  It is interesting to show 
how it works:

.. code-block:: c

	#include <stddef.h>
	#include <stdint.h>
	#include <stdio.h>
	#include <string.h>

	#include <libalx/base/stdio/printf/b.h>


	int main(void)
	{
		int len;
		char buff[BUFSIZ];

		alx_printf_b_init();

		snprintf(buff, 30, "Hey, %i == %#b :)\n", 5, 5);
		printf("%s", buff);
		printf("\n");

		printf("....----....----....----....----\n");
		len = printf("%llb;\n", 0x5Ellu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%lB;\n", 0x5Elu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%b;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%hB;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%hhb;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%jb;\n", (uintmax_t)0x5E);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%zb;\n", (size_t)0x5E);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%#b;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#B;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%10b;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%010b;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%.10b;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%-10B;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'B;\n", 0x5Eu);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		printf("....----....----....----....----\n");
		len = printf("%#16.12b;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%-#'20.12b;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'020B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%#020B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'020B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%020B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%#021B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'021B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%021B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%#022B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'022B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%022B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%#023B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'023B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%023B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%-#'19.11b;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'019B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#019B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'019B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%019B;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#016b;\n", 0xAB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		printf("....----....----....----....----\n");
		len = printf("%'010B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'010B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'010B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'010B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'010B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'010B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'011B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'011B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'012B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'012B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'013B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'013B;\n", 0xB);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'010B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'011B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'011B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'012B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'012B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'013B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'013B;\n", 0x1B);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'010B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'011B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'011B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'012B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'012B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'013B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'013B;\n", 0x2B);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'010B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'011B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'011B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'012B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'012B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'013B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'013B;\n", 0x4B);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");
		len = printf("%'010B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'010B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'011B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'011B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'012B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'012B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%'013B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		len = printf("%#'013B;\n", 0x8B);
		printf("%i\n", len - strlen(";\n"));
		printf("....----....----....----....----\n");

		return 0;
	}

And the results:

::

	Hey, 5 == 0b101 :)

	....----....----....----....----
	11111111111111000000000000000000000000001011110;
	47
	11111111111111000000000000000000000000001011110;
	47
	1011110;
	7
	1011110;
	7
	1011110;
	7
	11111111111111000000000000000000000000001011110;
	47
	11111111111111000000000000000000000000001011110;
	47
	....----....----....----....----
	0b1011110;
	9
	0B1011110;
	9
	....----....----....----....----
	   1011110;
	10
	0001011110;
	10
	0001011110;
	10
	....----....----....----....----
	1011110   ;
	10
	....----....----....----....----
	101_1110;
	8
	....----....----....----....----
	....----....----....----....----
	  0b000010101011;
	16
	0b0000_1010_1011    ;
	20
	0B000_0000_1010_1011;
	20
	....----....----....----....----
	0B000000000010101011;
	20
	0_0000_0000_1010_1011;
	21
	00000000000010101011;
	20
	....----....----....----....----
	0B0000000000010101011;
	21
	0_0000_0000_1010_1011;
	21
	000000000000010101011;
	21
	....----....----....----....----
	0B00000000000010101011;
	22
	00_0000_0000_1010_1011;
	22
	0000000000000010101011;
	22
	....----....----....----....----
	0B000000000000010101011;
	23
	000_0000_0000_1010_1011;
	23
	00000000000000010101011;
	23
	....----....----....----....----
	0b000_1010_1011    ;
	19
	0B00_0000_1010_1011;
	19
	0B00000000010101011;
	19
	....----....----....----....----
	0000_0000_1010_1011;
	19
	0000000000010101011;
	19
	0b00000010101011;
	16
	....----....----....----....----
	....----....----....----....----
	0_0000_1011;
	11
	0B000_1011;
	10
	0_0001_1011;
	11
	0B001_1011;
	10
	0_0010_1011;
	11
	0B010_1011;
	10
	0_0100_1011;
	11
	0B100_1011;
	10
	0_1000_1011;
	11
	0B1000_1011;
	11
	....----....----....----....----
	0_0000_1011;
	11
	0B000_1011;
	10
	0_0000_1011;
	11
	0B0000_1011;
	11
	00_0000_1011;
	12
	0B0_0000_1011;
	13
	000_0000_1011;
	13
	0B0_0000_1011;
	13
	....----....----....----....----
	0_0001_1011;
	11
	0B001_1011;
	10
	0_0001_1011;
	11
	0B0001_1011;
	11
	00_0001_1011;
	12
	0B0_0001_1011;
	13
	000_0001_1011;
	13
	0B0_0001_1011;
	13
	....----....----....----....----
	0_0010_1011;
	11
	0B010_1011;
	10
	0_0010_1011;
	11
	0B0010_1011;
	11
	00_0010_1011;
	12
	0B0_0010_1011;
	13
	000_0010_1011;
	13
	0B0_0010_1011;
	13
	....----....----....----....----
	0_0100_1011;
	11
	0B100_1011;
	10
	0_0100_1011;
	11
	0B0100_1011;
	11
	00_0100_1011;
	12
	0B0_0100_1011;
	13
	000_0100_1011;
	13
	0B0_0100_1011;
	13
	....----....----....----....----
	0_1000_1011;
	11
	0B1000_1011;
	11
	0_1000_1011;
	11
	0B1000_1011;
	11
	00_1000_1011;
	12
	0B0_1000_1011;
	13
	000_1000_1011;
	13
	0B0_1000_1011;
	13
	....----....----....----....----


I would like to add this feature to glibc, if you are interested in it.
I have been reading through the glibc source code, and I guess the only 
file I should modify is ``stdio-common/vfprintf-internal.c`` (correct me 
if I'm missing something).

How should I document the new feature?  Which files should I modify for 
that?

This is the first time I step into glibc code seriously, so I don't have 
any experience in how the library is organized at all.  Please tell me 
which steps should I follow to write this patch.

After this, I would like to write another patch for the ``scanf`` family 
of functions, but that's future.

		Alex.

P.S.:  Please CC me as I'm not subscribed to this mailing list.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-04-26 19:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-25 13:33 printf %b Alejandro Colomar via Libc-alpha
2020-04-26  0:54 ` Jonathan Nieder via Libc-alpha
2020-04-26  2:29   ` Alejandro Colomar via Libc-alpha
2020-04-26 19:18     ` Alejandro Colomar via Libc-alpha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).