Commit cf5b69c5 authored by Alessandro Rubini's avatar Alessandro Rubini

pp_printf: added digit attributes (e.g. "%02x")

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent aa08158c
......@@ -72,8 +72,9 @@ Footprint: 1500-3300 bytes, plus 100-400 bytes for the frontend.
================================
This prints correctly "%c", "%s", "%i", "%x". Formats "%u" and "%d"
are synonims of "%i", and "%p"is a synonim for "%x". No attributes
are supported, to keep size small. I personally dislike it, because it
are synonims of "%i", and "%p"is a synonim for "%x". The only
supported attributes are '0' and a one-digit width (e.g.: "%08x"
works). I personally dislike it, because it
not powerful enough nor low-level as real hacker's too should be.
However, it matches the requirement of some projects with a little
user interface, where the "full" code reveals too large and the "mini"
......@@ -83,13 +84,14 @@ please set "CONFIG_PRINTF_XINT=y" in your environment or Makefile.
This is the result of the example. As expected, no size nor precision
directives are obeyed:
integer 1024 666 53
octal 2000 1232 65
hex 400 29a 35
HEX etc 400 666 53
integer 1024 666 00053
octal 2000 1232 00065
hex 400 29a 00035
HEX etc 400 666 53
char: A string foo foo verylongstring
Footprint: 250-700 bytes, plus 100-250 bytes for the frontend
(FIXME: The figure hasn't been updated after I added the attributes)
The miminal implementaion in detail
......@@ -161,6 +163,8 @@ This table excludes the static buffer (256 in .bss by default) and
only lists the code size (command "size", column "text"), compiled
with -Os as for this Makefile.
(FIXME: The figure fox xint must be redone, as I added the attributes)
printf.o is the frontend and is linked in all four configurations,
the other ones are exclusive one another:
......
......@@ -8,7 +8,7 @@
static const char hex[] = "0123456789abcdef";
static int number(char *out, int value, int base)
static int number(char *out, int value, int base, int lead, int wid)
{
char tmp[16];
int i = 16, ret;
......@@ -18,8 +18,8 @@ static int number(char *out, int value, int base)
tmp[--i] = hex[value % base];
value /= base;
}
if (i == 16)
tmp[--i] = '0';
while (i > 16 - wid)
tmp[--i] = lead;
ret = 16 - i;
while (i < 16)
*(out++) = tmp[i++];
......@@ -29,7 +29,7 @@ static int number(char *out, int value, int base)
int pp_vsprintf(char *buf, const char *fmt, va_list args)
{
char *s, *str = buf;
int base;
int base, lead, wid;
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
......@@ -37,18 +37,25 @@ int pp_vsprintf(char *buf, const char *fmt, va_list args)
continue;
}
base = 10;
lead = ' ';
wid = 1;
repeat:
fmt++; /* Skip '%' initially, other stuff later */
base = 10;
/* Skip the complete format string */
switch(*fmt) {
case '\0':
goto ret;
case '0':
lead = '0';
goto repeat;
case '*':
/* should be precision, just eat it */
base = va_arg(args, int);
/* fall through: discard unknown stuff */
default:
if (*fmt >= '1' && *fmt <= '9')
wid = *fmt - '0';
goto repeat;
/* Special cases for conversions */
......@@ -78,7 +85,7 @@ int pp_vsprintf(char *buf, const char *fmt, va_list args)
case 'd':
case 'i':
case 'u':
str += number(str, va_arg(args, int), base);
str += number(str, va_arg(args, int), base, lead, wid);
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment