[U-Boot] [PATCH] lib: tiny-printf: Add "%ll" modifier support
Ley Foon Tan
ley.foon.tan at intel.com
Thu Mar 21 17:12:14 UTC 2019
Add "%ll" modifier support for tiny printf.
- Tested on ARM32 and ARM64 systems.
- Tested "%lld", "%llu", "%llx" and "%p" format with
minimum and maximum ranges. Compared tiny printf
output with full printf.
Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
---
lib/tiny-printf.c | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c
index ebef92fc9f..692430efac 100644
--- a/lib/tiny-printf.c
+++ b/lib/tiny-printf.c
@@ -33,8 +33,8 @@ static void out_dgt(struct printf_info *info, char dgt)
info->zs = 1;
}
-static void div_out(struct printf_info *info, unsigned long *num,
- unsigned long div)
+static void div_out(struct printf_info *info, unsigned long long *num,
+ unsigned long long div)
{
unsigned char dgt = 0;
@@ -160,8 +160,8 @@ static void ip4_addr_string(struct printf_info *info, u8 *addr)
static void pointer(struct printf_info *info, const char *fmt, void *ptr)
{
#ifdef DEBUG
- unsigned long num = (uintptr_t)ptr;
- unsigned long div;
+ unsigned long long num = (uintptr_t)ptr;
+ unsigned long long div;
#endif
switch (*fmt) {
@@ -199,9 +199,9 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
{
char ch;
char *p;
- unsigned long num;
- char buf[12];
- unsigned long div;
+ unsigned long long num;
+ char buf[22];
+ unsigned long long div;
while ((ch = *(fmt++))) {
if (ch != '%') {
@@ -210,6 +210,7 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
bool lz = false;
int width = 0;
bool islong = false;
+ bool islonglong = false;
ch = *(fmt++);
if (ch == '-')
@@ -229,7 +230,13 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
}
if (ch == 'l') {
ch = *(fmt++);
- islong = true;
+ if (ch == 'l') {
+ islonglong = true;
+ ch = *(fmt++);
+ } else {
+ islong = true;
+ }
+
}
info->bf = buf;
@@ -242,7 +249,10 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
case 'u':
case 'd':
div = 1000000000;
- if (islong) {
+ if (islonglong) {
+ num = va_arg(va, unsigned long long);
+ div *= div * 10;
+ } else if (islong) {
num = va_arg(va, unsigned long);
if (sizeof(long) > 4)
div *= div * 10;
@@ -251,10 +261,13 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
}
if (ch == 'd') {
- if (islong && (long)num < 0) {
+ if (islonglong && (long long)num < 0) {
+ num = -(long long)num;
+ out(info, '-');
+ } else if (islong && (long)num < 0) {
num = -(long)num;
out(info, '-');
- } else if (!islong && (int)num < 0) {
+ } else if ((!islong && !islonglong) && (int)num < 0) {
num = -(int)num;
out(info, '-');
}
@@ -267,9 +280,12 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
}
break;
case 'x':
- if (islong) {
+ if (islonglong) {
+ num = va_arg(va, unsigned long long);
+ div = 1ULL << (sizeof(long long) * 8 - 4);
+ } else if (islong) {
num = va_arg(va, unsigned long);
- div = 1UL << (sizeof(long) * 8 - 4);
+ div = 1ULL << (sizeof(long) * 8 - 4);
} else {
num = va_arg(va, unsigned int);
div = 0x10000000;
--
2.19.0
More information about the U-Boot
mailing list