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. ...@@ -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" 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 synonims of "%i", and "%p"is a synonim for "%x". The only
are supported, to keep size small. I personally dislike it, because it 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. not powerful enough nor low-level as real hacker's too should be.
However, it matches the requirement of some projects with a little However, it matches the requirement of some projects with a little
user interface, where the "full" code reveals too large and the "mini" 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. ...@@ -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 This is the result of the example. As expected, no size nor precision
directives are obeyed: directives are obeyed:
integer 1024 666 53 integer 1024 666 00053
octal 2000 1232 65 octal 2000 1232 00065
hex 400 29a 35 hex 400 29a 00035
HEX etc 400 666 53 HEX etc 400 666 53
char: A string foo foo verylongstring char: A string foo foo verylongstring
Footprint: 250-700 bytes, plus 100-250 bytes for the frontend 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 The miminal implementaion in detail
...@@ -161,6 +163,8 @@ This table excludes the static buffer (256 in .bss by default) and ...@@ -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 only lists the code size (command "size", column "text"), compiled
with -Os as for this Makefile. 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, printf.o is the frontend and is linked in all four configurations,
the other ones are exclusive one another: the other ones are exclusive one another:
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
static const char hex[] = "0123456789abcdef"; 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]; char tmp[16];
int i = 16, ret; int i = 16, ret;
...@@ -18,8 +18,8 @@ static int number(char *out, int value, int base) ...@@ -18,8 +18,8 @@ static int number(char *out, int value, int base)
tmp[--i] = hex[value % base]; tmp[--i] = hex[value % base];
value /= base; value /= base;
} }
if (i == 16) while (i > 16 - wid)
tmp[--i] = '0'; tmp[--i] = lead;
ret = 16 - i; ret = 16 - i;
while (i < 16) while (i < 16)
*(out++) = tmp[i++]; *(out++) = tmp[i++];
...@@ -29,7 +29,7 @@ static int number(char *out, int value, int base) ...@@ -29,7 +29,7 @@ static int number(char *out, int value, int base)
int pp_vsprintf(char *buf, const char *fmt, va_list args) int pp_vsprintf(char *buf, const char *fmt, va_list args)
{ {
char *s, *str = buf; char *s, *str = buf;
int base; int base, lead, wid;
for (; *fmt ; ++fmt) { for (; *fmt ; ++fmt) {
if (*fmt != '%') { if (*fmt != '%') {
...@@ -37,18 +37,25 @@ int pp_vsprintf(char *buf, const char *fmt, va_list args) ...@@ -37,18 +37,25 @@ int pp_vsprintf(char *buf, const char *fmt, va_list args)
continue; continue;
} }
base = 10;
lead = ' ';
wid = 1;
repeat: repeat:
fmt++; /* Skip '%' initially, other stuff later */ fmt++; /* Skip '%' initially, other stuff later */
base = 10;
/* Skip the complete format string */
switch(*fmt) { switch(*fmt) {
case '\0': case '\0':
goto ret; goto ret;
case '0':
lead = '0';
goto repeat;
case '*': case '*':
/* should be precision, just eat it */ /* should be precision, just eat it */
base = va_arg(args, int); base = va_arg(args, int);
/* fall through: discard unknown stuff */ /* fall through: discard unknown stuff */
default: default:
if (*fmt >= '1' && *fmt <= '9')
wid = *fmt - '0';
goto repeat; goto repeat;
/* Special cases for conversions */ /* Special cases for conversions */
...@@ -78,7 +85,7 @@ int pp_vsprintf(char *buf, const char *fmt, va_list args) ...@@ -78,7 +85,7 @@ int pp_vsprintf(char *buf, const char *fmt, va_list args)
case 'd': case 'd':
case 'i': case 'i':
case 'u': case 'u':
str += number(str, va_arg(args, int), base); str += number(str, va_arg(args, int), base, lead, wid);
break; 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