From a38a674a5356d637e618b637e3515d5f9e2655e1 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 14 Feb 2024 23:20:46 +0100 Subject: [PATCH] userspace: fix printf for unsigned --- userspace/libc.c | 120 +++++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/userspace/libc.c b/userspace/libc.c index 7d5f071..ba0c7b7 100644 --- a/userspace/libc.c +++ b/userspace/libc.c @@ -265,8 +265,57 @@ int puts(const char *str) return ret; \ } +#define PRINT_UINT(name, type) \ + int print##name(type integer, char *str, size_t size) \ + { \ + char num[sizeof(integer) * 3]; \ + int i = 0; \ + int c = 0; \ + int ret = 0; \ + \ + do { \ + int digit = integer % 10; \ + num[i++] = (digit > 0) ? digit : -digit; \ + integer = integer / 10; \ + } while (integer != 0); \ + \ + for (i = i - 1; i >= 0; i--) { \ + if (str) { \ + if (size) { \ + str[c++] = num[i] + '0'; \ + size--; \ + ret++; \ + } else { \ + return ret; \ + } \ + } else { \ + ret++; \ + } \ + } \ + return ret; \ + } + PRINT_INT(Int, int); -PRINT_INT(Int64, long long int); +PRINT_INT(Lint, long int); +PRINT_INT(Llint, long long int); +PRINT_UINT(Uint, unsigned int); +PRINT_UINT(Luint, long unsigned int); +PRINT_UINT(Lluint, long long unsigned int); + +#define PRINT_PART(func, type, str, size, c, ret) \ + { \ + int s; \ + type d = va_arg(ap, type); \ + if (str) \ + s = func(d, &str[c], size); \ + else \ + s = func(d, NULL, size); \ + \ + size -= s; \ + c += s; \ + ret += s; \ + break; \ + } int vsnprintf(char *str, size_t size, const char *format, va_list ap) { @@ -274,24 +323,13 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap) int i = 0; int c = 0; - while (format[i] != '\0' && (size || !str)) { + while (format[i] != '\0' && (size|| !str)) { switch (format[i]) { case '%': switch (format[i + 1]) { case 'i': - case 'd': { - int s; - int d = va_arg(ap, int); - if (str) - s = printInt(d, &str[c], size); - else - s = printInt(d, NULL, size); - - size -= s; - c += s; - ret += s; - break; - } + case 'd': PRINT_PART(printInt, int, str, size, c, ret) + case 'u': PRINT_PART(printUint, uint, str, size, c, ret) case 'p': case 'x': { char val[sizeof(int) * 2]; @@ -352,24 +390,15 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap) switch (format[i + 2]) { case 'l': switch (format[i + 3]) { - case 'd': { - int s; - long long int d = va_arg(ap, long long int); - if (str) - s = printInt64(d, &str[c], size); - else - s = printInt64(d, NULL, size); - - size -= s; - c += s; - ret += s; - break; - } + case 'i': + case 'd': PRINT_PART(printLlint, long long int, str, size, c, ret) + case 'u': PRINT_PART(printLluint, long long unsigned int, str, size, c, ret) case 'p': case 'x': { char val[sizeof(long long int) * 2]; unsigned int valIdx = 0; - long long int d = va_arg(ap, long long int); + unsigned long long int d = + va_arg(ap, unsigned long long int); itoa(d, val, 16); if (str) { while (val[valIdx]) { @@ -390,17 +419,28 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap) i++; break; case 'i': - case 'd': { - int s; - long int d = va_arg(ap, long int); - if (str) - s = printInt64(d, &str[c], size); - else - s = printInt64(d, NULL, size); - - size -= s; - c += s; - ret += s; + case 'd': PRINT_PART(printLint, long int, str, size, c, ret) + case 'u': + PRINT_PART(printLuint, long unsigned int, str, size, c, ret) + case 'p': + case 'x': { + char val[sizeof(int) * 2]; + unsigned int valIdx = 0; + unsigned long int d = va_arg(ap, unsigned long int); + itoa(d, val, 16); + if (str) { + while (val[valIdx]) { + if (size) { + str[c++] = val[valIdx++]; + size--; + ret++; + } else { + return ret; + } + } + } else { + ret += strlen(val); + } break; } }