lib/tiny-printf.c: Add tiny printf function for space limited environments
Subsystems (2)
RFC PATCH 1/1 lib/tiny-printf.c: Add tiny printf function for space limited environments
This patch adds a small printf() version that supports all basic formats. Its intented to be used in U-Boot SPL versions on platforms with very limited internal RAM sizes.
To enable it, just define CONFIG_USE_TINY_PRINTF in your defconfig. This will result in the SPL using this tiny function and the main U-Boot still using the full-blown printf() function.
This code was copied from:
http://www.sparetimelabs.com/printfrevisited
With mostly only coding style related changes so that its checkpatch clean.
The size reduction is about 2.5KiB. Here a comparison for the db-88f6820-gp (Marvell A38x) SPL:
Without this patch:
108075 13298 2824 124197 1e525 ./spl/u-boot-spl
With this patch:
105398 13298 2852 121548 1dacc ./spl/u-boot-spl
Note:
To make it possible to compile tiny-printf.c instead of vsprintf.c when CONFIG_USE_TINY_PRINTF is defined, the functions printf() and vprintf() are moved from common/console.c into vsprintf.c in this patch.
--- common/console.c | 39 ---------------- lib/Kconfig | 8 ++++ lib/Makefile | 7 ++- lib/tiny-printf.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/vsprintf.c | 39 ++++++++++++++++ 5 files changed, 183 insertions(+), 40 deletions(-) create mode 100644 lib/tiny-printf.c
common/console.c +0 -39
@@ -535,45 +535,6 @@ void puts(const char *s) } } -int printf (const char *fmt, ...) -{ -va_list args; -uint i; -char printbuffer[CONFIG_SYS_PBSIZE ]; - -va_start (args, fmt); - -/* For this to work, printbuffer must be larger than -* anything we ever want to print. -*/ - i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); -va_end (args); - -/* Print the string */ -puts (printbuffer); -return i; -} - -int vprintf (const char *fmt,va_list args) -{ -uint i; -char printbuffer[CONFIG_SYS_PBSIZE ]; - -#if defined(CONFIG_PRE_CONSOLE_BUFFER ) && !defined(CONFIG_SANDBOX ) -if (!gd->have_console) -return 0 ; -#endif - -/* For this to work, printbuffer must be larger than -* anything we ever want to print. -*/ - i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); - -/* Print the string */ -puts (printbuffer); -return i; -} -/* test if ctrl-c was pressed */ static int ctrlc_disabled =0 ;/* see disable_ctrl() */ static int ctrlc_was_pressed =0 ;
lib/Kconfig +8 -0
@@ -36,6 +36,14 @@ config SYS_VSNPRINTF Thumb-2, about 420 bytes). Enable this option for safety when using sprintf() with data you do not control. +config USE_TINY_PRINTF + bool "Enable tiny printf() version" + help + This option enables a tiny, stripped down printf version. + This should only be used in space limited environments, + like SPL versions with hard memory limits. This version + reduces the code size by about 2.5KiB on armv7. + config REGEX bool "Enable regular expression support" default y if NET
lib/Makefile +6 -1
@@ -79,7 +79,12 @@ obj-y += string.o obj-y += time.o obj-$(CONFIG_TRACE) += trace.o obj-$(CONFIG_LIB_UUID) += uuid.o -obj-y += vsprintf.o obj-$(CONFIG_LIB_RAND) += rand.o +ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_USE_TINY_PRINTF),yy) +obj-y += tiny-printf.o +else +obj-y += vsprintf.o +endif + subdir-ccflags-$(CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED) += -O2
lib/tiny-printf.c new file +130 -0
130 lines not on this page · raw message
lib/vsprintf.c +39 -0
@@ -861,6 +861,45 @@ int sprintf(char *buf, const char *fmt, ...)return i; } +int printf (const char *fmt, ...) +{ +va_list args; +uint i; +char printbuffer[CONFIG_SYS_PBSIZE ]; + +va_start (args, fmt); + +/* For this to work, printbuffer must be larger than +* anything we ever want to print. +*/ + i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); +va_end (args); + +/* Print the string */ +puts (printbuffer); +return i; +} + +int vprintf (const char *fmt,va_list args) +{ +uint i; +char printbuffer[CONFIG_SYS_PBSIZE ]; + +#if defined(CONFIG_PRE_CONSOLE_BUFFER ) && !defined(CONFIG_SANDBOX ) +if (!gd->have_console) +return 0 ; +#endif + +/* For this to work, printbuffer must be larger than +* anything we ever want to print. +*/ + i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); + +/* Print the string */ +puts (printbuffer); +return i; +} +static void panic_finish (void ) __attribute__ ((noreturn));static void panic_finish (void )
Signature · 1 line
2.6.3
RFC PATCH 1/1 lib/tiny-printf.c: Add tiny printf function for space limited environments
Hello Stefan,
Quoted 3 lines · Stefan Roese
This patch adds a small
printf()version that supports all basic formats. Its intented to be used in U-Boot SPL versions on platforms with very limited internal RAM sizes.
It would be very useful to document CONFIG_USE_TINY_PRINTF in ./README, and especially to indicate which format specifiers are supported and which are not.
Amicalement,
Signature · 1 line
Albert.
RFC PATCH 1/1 lib/tiny-printf.c: Add tiny printf function for space limited environments
Hi Albert,
Quoted 8 lines · Albert ARIBAUD
Quoted 3 lines · Stefan Roese
This patch adds a small
printf()version that supports all basic formats. Its intented to be used in U-Boot SPL versions on platforms with very limited internal RAM sizes.It would be very useful to document
CONFIG_USE_TINY_PRINTFin ./README, and especially to indicate which format specifiers are supported and which are not.
We're not documenting the config options in the README any more, if they are introduced via Kconfig. The help text is in Kconfig now. But I surely can add this info about the supported format specifiers, yet in v2. Just waiting for some more review comments...
Thanks,
Stefan
RFC PATCH 1/1 lib/tiny-printf.c: Add tiny printf function for space limited environments
Hello Stefan,
Quoted 8 lines · Stefan Roese
Hi Albert,
Quoted 5 lines · Albert ARIBAUD
Quoted 3 lines · Stefan Roese
This patch adds a small
printf()version that supports all basic formats. Its intented to be used in U-Boot SPL versions on platforms with very limited internal RAM sizes.
Quoted 6 lines
Quoted 3 lines
It would be very useful to document
CONFIG_USE_TINY_PRINTFin ./README, and especially to indicate which format specifiers are supported and which are not.We're not documenting the config options in the README any more, if they are introduced via
Kconfig.
Sorry, that's me being a dinosaur again. :)
Quoted 3 lines
The help text is in
Kconfig
now. But I surely can add this info about the supported format specifiers, yet in v2. Just waiting for some more review comments...
Ok, thanks.
Quoted 2 lines
Thanks,
Stefan
Amicalement,
Signature · 1 line
Albert.
RFC PATCH 1/1 lib/tiny-printf.c: Add tiny printf function for space limited environments
In reply to Stefan RoeseHi Stefan,
Quoted 13 lines · Stefan Roese
This patch adds a small
printf()version that supports all basic formats. Its intented to be used in U-Boot SPL versions on platforms with very limited internal RAM sizes.To enable it, just define
CONFIG_USE_TINY_PRINTFin your defconfig. This will result in the SPL using this tiny function and the main U-Boot still using the full-blownprintf()function.This code was copied from:
http://www.sparetimelabs.com/printfrevisited
With mostly only coding style related changes so that its checkpatch clean.
Quoted 8 lines
The size reduction is about 2.5KiB. Here a comparison for the db-88f6820-gp (Marvell A38x) SPL:
Without this patch:
108075 13298 2824 124197 1e525 ./spl/u-boot-splWith this patch:
105398 13298 2852 121548 1dacc ./spl/u-boot-spl
Great!
Quoted 122 lines
Note:
To make it possible to compiletiny-printf.cinstead ofvsprintf.cwhenCONFIG_USE_TINY_PRINTFis defined, the functionsprintf()andvprintf()are moved fromcommon/console.cintovsprintf.cin this patch.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Hans de Goede <[email protected]>Cc Tom Rini <[email protected]>--- common/console.c | 39 ---------------- lib/Kconfig | 8 ++++ lib/Makefile | 7 ++- lib/tiny-printf.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/vsprintf.c | 39 ++++++++++++++++ 5 files changed, 183 insertions(+), 40 deletions(-) create mode 100644 lib/tiny-printf.ccommon/console.c +0
-39@@ -535,45 +535,6 @@ void puts(const char *s) } } -int printf (const char *fmt, ...) -{ -va_list args; -uint i; -char printbuffer[CONFIG_SYS_PBSIZE ]; - -va_start (args, fmt); - -/* For this to work, printbuffer must be larger than -* anything we ever want to print. -*/ - i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); -va_end (args); - -/* Print the string */ -puts (printbuffer); -return i; -} - -int vprintf (const char *fmt,va_list args) -{ -uint i; -char printbuffer[CONFIG_SYS_PBSIZE ]; - -#if defined(CONFIG_PRE_CONSOLE_BUFFER ) && !defined(CONFIG_SANDBOX ) -if (!gd->have_console) -return 0 ; -#endif - -/* For this to work, printbuffer must be larger than -* anything we ever want to print. -*/ - i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); - -/* Print the string */ -puts (printbuffer); -return i; -} -/* test if ctrl-c was pressed */ static int ctrlc_disabled =0 ;/* see disable_ctrl() */ static int ctrlc_was_pressed =0 ;lib/Kconfig +8
-0@@ -36,6 +36,14 @@ config SYS_VSNPRINTF Thumb-2, about 420 bytes). Enable this option for safety when using sprintf() with data you do not control. +config USE_TINY_PRINTF + bool "Enable tiny printf() version" + help + This option enables a tiny, stripped down printf version. + This should only be used in space limited environments, + like SPL versions with hard memory limits. This version + reduces the code size by about 2.5KiB on armv7. + config REGEX bool "Enable regular expression support" default y if NETlib/Makefile +6
-1@@ -79,7 +79,12 @@ obj-y += string.o obj-y += time.o obj-$(CONFIG_TRACE) += trace.o obj-$(CONFIG_LIB_UUID) += uuid.o -obj-y += vsprintf.o obj-$(CONFIG_LIB_RAND) += rand.o +ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_USE_TINY_PRINTF),yy) +obj-y += tiny-printf.o +else +obj-y += vsprintf.o +endif + subdir-ccflags-$(CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED) += -O2lib/tiny-printf.c new file +10
-0@@ -0,0 +1,130 @@ +/* +* Tiny printf version for SPL +* +* Copied from: +* http://www.sparetimelabs.com/printfrevisited/printfrevisited.php +* +* Copyright (C) 2004,2008 Kustaa Nyholm +* +* SPDX-License-Identifier: LGPL-2.1+ +*/
lib/tiny-printf.c line 20
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+ +#include <common.h> +#include <stdarg.h> +#include <serial.h> + +static char *bf; +static char buf[12 ]; +static unsigned int num; +static char uc; +static char zs;
Do we need all these variables? Perhaps some of them could become parameters instead?
Quoted 41 lines
lib/tiny-printf.c new file +41
-0+ +static void out (char c) +{ + *bf++ = c; +} + +static void out_dgt (char dgt) +{ +out (dgt + (dgt <10 ?'0' : (uc ?'A' :'a' ) -10 )); + zs =1 ; +} + +static void div_out (unsigned int div) +{ +unsigned char dgt =0 ; + + num &=0xffff ;/* just for testing the code with 32 bit ints */ +while (num >= div) { + num -= div; + dgt++; + } + +if (zs || dgt >0 ) +out_dgt (dgt); +} + +int printf (const char *fmt, ...) +{ +va_list va; +char ch; +char *p; + +va_start (va, fmt); + +while ((ch = *(fmt++))) { +if (ch !='%' ) { +putc (ch); + }else { +char lz =0 ; +char w =0 ; +
lib/tiny-printf.c line 71
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+ ch = *(fmt++); +if (ch =='0' ) { + ch = *(fmt++); + lz =1 ; + } + +if (ch >='0' && ch <='9' ) { + w =0 ; +while (ch >='0' && ch <='9' ) { + w = (((w <<2 ) + w) <<1 ) + ch -'0' ;
Doesn't the compiler do the right thing if you say:
w = (w * 10) + ch - '0'
Quoted 8 lines
lib/tiny-printf.c new file +8
-0+ ch = *fmt++; + } + } + bf = buf; + p = bf; + zs =0 ; + +switch (ch) {
lib/tiny-printf.c line 89
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+case 0 : + goto abort; +case 'u' : +case 'd' : + num = va_arg(va, unsigned int); +if (ch =='d' && (int )num <0 ) { + num = -(int )num; +out ('-' ); + } +div_out (10000 );
Does this mean it cannot output numbers larger than 99999?
lib/tiny-printf.c line 99
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+div_out (1000 ); +div_out (100 ); +div_out (10 ); +out_dgt (num); +break ; +case 'x' : +case 'X' : + uc = ch =='X' ; + num = va_arg(va, unsigned int); +div_out (0x1000 );
How about:
for (div = 0x1000; div; div >>= 4)
div_out(div)
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+div_out (0x100 ); +div_out (0x10 ); +out_dgt (num); +break ; +case 'c' : +out ((char )(va_arg (va, int))); +break ; +case 's' : + p = va_arg(va, char*); +break ;
lib/tiny-printf.c line 119
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+case '%' : +out ('%' ); +default : +break ; + } + + *bf =0 ; + bf = p; +while (*bf++ && w >0 ) + w--;
I wonder if the digits could be written to the buffer in reverse order, thus allowing something like this for the decimal case:
for (div = 10; div <= 10000; div *= 10)
div_out(div)
lib/tiny-printf.c line 122
Quoted 3 lines
lib/tiny-printf.c new file +3
-0+while (w-- >0 ) +putc (lz ?'0' :' ' ); +while ((ch = *p++))
and here you could work backwards.
Quoted 34 lines
lib/tiny-printf.c new file +8
-0+putc (ch); + } + } + +abort: +va_end (va); +return 0 ; +}lib/vsprintf.c +18
-0@@ -861,6 +861,45 @@ int sprintf(char *buf, const char *fmt, ...)return i; } +int printf (const char *fmt, ...) +{ +va_list args; +uint i; +char printbuffer[CONFIG_SYS_PBSIZE ]; + +va_start (args, fmt); + +/* For this to work, printbuffer must be larger than +* anything we ever want to print. +*/ + i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); +va_end (args); + +/* Print the string */ +puts (printbuffer); +return i; +}
lib/vsprintf.c int sprintf(char *buf, const char *fmt, ...) · line 891
Quoted 10 lines
lib/vsprintf.c +10
-0+ +int vprintf (const char *fmt,va_list args) +{ +uint i; +char printbuffer[CONFIG_SYS_PBSIZE ]; + +#if defined(CONFIG_PRE_CONSOLE_BUFFER ) && !defined(CONFIG_SANDBOX ) +if (!gd->have_console) +return 0 ; +#endif
Hmm, that code in the #if should be removed. I did it for printf() but forgot vprintf(). If you have time you could add a patch for this.
lib/vsprintf.c int sprintf(char *buf, const char *fmt, ...) · line 893
Quoted 2 lines
lib/vsprintf.c +2
-0+ +/* For this to work, printbuffer must be larger than
/*
* For this to work...
*/
Quoted 13 lines
lib/vsprintf.c +9
-1+* anything we ever want to print. +*/ + i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); + +/* Print the string */ +puts (printbuffer); +return i; +} +static void panic_finish (void ) __attribute__ ((noreturn));static void panic_finish (void ) --
Quoted 2 lines
2.6.3
Regards,
Simon
RFC PATCH 1/1 lib/tiny-printf.c: Add tiny printf function for space limited environments
Hi Simon,
Quoted 19 lines · Simon Glass
Hi Stefan,
Quoted 16 lines · Stefan Roese
This patch adds a small
printf()version that supports all basic formats. Its intented to be used in U-Boot SPL versions on platforms with very limited internal RAM sizes.To enable it, just define
CONFIG_USE_TINY_PRINTFin your defconfig. This will result in the SPL using this tiny function and the main U-Boot still using the full-blownprintf()function.This code was copied from:
http://www.sparetimelabs.com/printfrevisited
With mostly only coding style related changes so that its checkpatch clean.The size reduction is about 2.5KiB. Here a comparison for the db-88f6820-gp (Marvell A38x) SPL:
Quoted 7 lines
Quoted 5 lines
Without this patch:
108075 13298 2824 124197 1e525 ./spl/u-boot-splWith this patch:
105398 13298 2852 121548 1dacc ./spl/u-boot-splGreat!
Thanks. BTW, you might have noticed that I still used MAKEALL for this size outputs here. I somehow failed to get buildman generate these size statistic outputs here. Sometimes buildman starts with the compilation, sometimes it only shows a summary, not really the one that I expected it to show. Here a short log of some experiments:
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman db-mv784mp-gp boards.cfg is up to date. Nothing to do.
Building current source for 1 boards (1 thread, 8 jobs per thread)
1 0 0 /1 db-mv784mp-gp
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman db-mv784mp-gp -s boards.cfg is up to date. Nothing to do.
Summary of current source for 1 boards (1 thread, 8 jobs per thread)
(no errors to report)
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman db-mv784mp-gp -s -c 2 boards.cfg is up to date. Nothing to do.
Summary of current source for 1 boards (1 thread, 8 jobs per thread)
(no errors to report)
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman db-mv784mp-gp -s -c 5 boards.cfg is up to date. Nothing to do.
Summary of current source for 1 boards (1 thread, 8 jobs per thread)
(no errors to report)
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman db-mv784mp-gp -sS -c 5 boards.cfg is up to date. Nothing to do.
Summary of current source for 1 boards (1 thread, 8 jobs per thread)
(no errors to report)
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman mvebu -sS -c 5 boards.cfg is up to date. Nothing to do.
Summary of current source for 4 boards (4 threads, 2 jobs per thread)
arm: + clearfog
[stefan at stefan-work u-boot (tiny-printf-v2-2015-11-16)]$ ./tools/buildman/buildman mvebu -sS -c 10 boards.cfg is up to date. Nothing to do.
Summary of current source for 4 boards (4 threads, 2 jobs per thread)
arm: + clearfog
I'm most likely missing something. Perhaps using a branch name, not sure. I also experimented with using -b <branch> and get here:
$ ./tools/buildman/buildman -b tiny-printf-v2-2015-11-16 mvebu Cannot find a suitable upstream for branch 'tiny-printf-v2-2015-11-16'
which makes perfect sense. As this is absolute work-in-progess and I really don't want to push this into some upstream repo at this point.
I've also noticed the comments in the README about this branch usage (e.g. 'git branch --set-upstream-to upstream/master'). But I assume that there has to be the possibility to use buildman without pushing such working branches upstream.
So please let me know what I'm missing here. Thanks!
Some more comments below.
Quoted 127 lines
Quoted 127 lines
Note:
To make it possible to compiletiny-printf.cinstead ofvsprintf.cwhenCONFIG_USE_TINY_PRINTFis defined, the functionsprintf()andvprintf()are moved fromcommon/console.cintovsprintf.cin this patch.Signed-off-by Stefan Roese <[email protected]>Cc Simon Glass <[email protected]>Cc Hans de Goede <[email protected]>Cc Tom Rini <[email protected]>--- common/console.c | 39 ---------------- lib/Kconfig | 8 ++++ lib/Makefile | 7 ++- lib/tiny-printf.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/vsprintf.c | 39 ++++++++++++++++ 5 files changed, 183 insertions(+), 40 deletions(-)create mode 100644
lib/tiny-printf.ccommon/console.c +0
-39@@ -535,45 +535,6 @@ void puts(const char *s) } } -int printf (const char *fmt, ...) -{ -va_list args; -uint i; -char printbuffer[CONFIG_SYS_PBSIZE ]; - -va_start (args, fmt); - -/* For this to work, printbuffer must be larger than -* anything we ever want to print. -*/ - i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); -va_end (args); - -/* Print the string */ -puts (printbuffer); -return i; -} - -int vprintf (const char *fmt,va_list args) -{ -uint i; -char printbuffer[CONFIG_SYS_PBSIZE ]; - -#if defined(CONFIG_PRE_CONSOLE_BUFFER ) && !defined(CONFIG_SANDBOX ) -if (!gd->have_console) -return 0 ; -#endif - -/* For this to work, printbuffer must be larger than -* anything we ever want to print. -*/ - i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); - -/* Print the string */ -puts (printbuffer); -return i; -} -/* test if ctrl-c was pressed */ static int ctrlc_disabled =0 ;/* see disable_ctrl() */ static int ctrlc_was_pressed =0 ;lib/Kconfig +8
-0@@ -36,6 +36,14 @@ config SYS_VSNPRINTF Thumb-2, about 420 bytes). Enable this option for safety when using sprintf() with data you do not control. +config USE_TINY_PRINTF + bool "Enable tiny printf() version" + help + This option enables a tiny, stripped down printf version. + This should only be used in space limited environments, + like SPL versions with hard memory limits. This version + reduces the code size by about 2.5KiB on armv7. + config REGEX bool "Enable regular expression support" default y if NETlib/Makefile +6
-1@@ -79,7 +79,12 @@ obj-y += string.o obj-y += time.o obj-$(CONFIG_TRACE) += trace.o obj-$(CONFIG_LIB_UUID) += uuid.o -obj-y += vsprintf.o obj-$(CONFIG_LIB_RAND) += rand.o +ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_USE_TINY_PRINTF),yy) +obj-y += tiny-printf.o +else +obj-y += vsprintf.o +endif + subdir-ccflags-$(CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED) += -O2lib/tiny-printf.c new file +15
-0@@ -0,0 +1,130 @@ +/* +* Tiny printf version for SPL +* +* Copied from: +* http://www.sparetimelabs.com/printfrevisited/printfrevisited.php +* +* Copyright (C) 2004,2008 Kustaa Nyholm +* +* SPDX-License-Identifier: LGPL-2.1+ +*/ + +#include <common.h> +#include <stdarg.h> +#include <serial.h> +
Quoted 8 lines
lib/tiny-printf.c line 20
Quoted 5 lines
lib/tiny-printf.c new file +5
-0+static char *bf; +static char buf[12 ]; +static unsigned int num; +static char uc; +static char zs;Do we need all these variables? Perhaps some of them could become parameters instead?
As mentioned in the commit text, this patch just includes the original code as published on the link above. With only some coding style related changes.
I'll take a closer look at the functional changes later and will perhaps send a follow-up patch for this.
Quoted 54 lines
Quoted 41 lines
lib/tiny-printf.c new file +41
-0+ +static void out (char c) +{ + *bf++ = c; +} + +static void out_dgt (char dgt) +{ +out (dgt + (dgt <10 ?'0' : (uc ?'A' :'a' ) -10 )); + zs =1 ; +} + +static void div_out (unsigned int div) +{ +unsigned char dgt =0 ; + + num &=0xffff ;/* just for testing the code with 32 bit ints */ +while (num >= div) { + num -= div; + dgt++; + } + +if (zs || dgt >0 ) +out_dgt (dgt); +} + +int printf (const char *fmt, ...) +{ +va_list va; +char ch; +char *p; + +va_start (va, fmt); + +while ((ch = *(fmt++))) { +if (ch !='%' ) { +putc (ch); + }else { +char lz =0 ; +char w =0 ; +lib/tiny-printf.c line 71
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+ ch = *(fmt++); +if (ch =='0' ) { + ch = *(fmt++); + lz =1 ; + } + +if (ch >='0' && ch <='9' ) { + w =0 ; +while (ch >='0' && ch <='9' ) { + w = (((w <<2 ) + w) <<1 ) + ch -'0' ;Doesn't the compiler do the right thing if you say:
Quoted 1 line
w = (w * 10) + ch - '0'
I'll test this.
Quoted 19 lines
Quoted 8 lines
lib/tiny-printf.c new file +8
-0+ ch = *fmt++; + } + } + bf = buf; + p = bf; + zs =0 ; + +switch (ch) {lib/tiny-printf.c line 89
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+case 0 : + goto abort; +case 'u' : +case 'd' : + num = va_arg(va, unsigned int); +if (ch =='d' && (int )num <0 ) { + num = -(int )num; +out ('-' ); + } +div_out (10000 );
Quoted 1 line
Does this mean it cannot output numbers larger than 99999?
Yes. Seems that the original version only supports numbers up to 0xffff. I'll change this also in a follow-up patch.
Quoted 11 lines
lib/tiny-printf.c line 99
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+div_out (1000 ); +div_out (100 ); +div_out (10 ); +out_dgt (num); +break ; +case 'x' : +case 'X' : + uc = ch =='X' ; + num = va_arg(va, unsigned int); +div_out (0x1000 );
Quoted 4 lines
How about:
for (div =
0x1000; div; div >>= 4)
div_out(div)
Yes.
Quoted 24 lines
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+div_out (0x100 ); +div_out (0x10 ); +out_dgt (num); +break ; +case 'c' : +out ((char )(va_arg (va, int))); +break ; +case 's' : + p = va_arg(va, char*); +break ;lib/tiny-printf.c line 119
Quoted 10 lines
lib/tiny-printf.c new file +10
-0+case '%' : +out ('%' ); +default : +break ; + } + + *bf =0 ; + bf = p; +while (*bf++ && w >0 ) + w--;I wonder if the digits could be written to the buffer in reverse order, thus allowing something like this for the decimal case:
Quoted 8 lines
for (div = 10; div <= 10000; div *= 10)
div_out(div)lib/tiny-printf.c line 122
Quoted 3 lines
lib/tiny-printf.c new file +3
-0+while (w-- >0 ) +putc (lz ?'0' :' ' ); +while ((ch = *p++))and here you could work backwards.
I'll also take a look at this.
Quoted 39 lines
Quoted 39 lines
lib/tiny-printf.c new file +8
-0+putc (ch); + } + } + +abort: +va_end (va); +return 0 ; +}lib/vsprintf.c +23
-0@@ -861,6 +861,45 @@ int sprintf(char *buf, const char *fmt, ...)return i; } +int printf (const char *fmt, ...) +{ +va_list args; +uint i; +char printbuffer[CONFIG_SYS_PBSIZE ]; + +va_start (args, fmt); + +/* For this to work, printbuffer must be larger than +* anything we ever want to print. +*/ + i =vscnprintf (printbuffer,sizeof (printbuffer), fmt, args); +va_end (args); + +/* Print the string */ +puts (printbuffer); +return i; +} + +int vprintf (const char *fmt,va_list args) +{ +uint i; +char printbuffer[CONFIG_SYS_PBSIZE ];
Quoted 8 lines
lib/vsprintf.c int sprintf(char *buf, const char *fmt, ...) · line 891
Quoted 5 lines
lib/vsprintf.c +5
-0+ +#if defined(CONFIG_PRE_CONSOLE_BUFFER ) && !defined(CONFIG_SANDBOX ) +if (!gd->have_console) +return 0 ; +#endif Hmm, that code in the #if should be removed. I did it for
printf()but forgotvprintf(). If you have time you could add a patch for this.
Yes, will do.
Quoted 6 lines
lib/vsprintf.c int sprintf(char *buf, const char *fmt, ...) · line 893
Quoted 2 lines
lib/vsprintf.c +2
-0+ +/* For this to work, printbuffer must be larger than /*
* For this to work...
*/
Its just a copy of the original code. But I can clean this up as well while moving, yes.
Thanks,
Stefan