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
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