userspace: fix printf for unsigned

This commit is contained in:
Mathieu Maret 2024-02-14 23:20:46 +01:00 committed by Mathieu Maret
parent 0688afa76d
commit a38a674a53

View File

@ -265,8 +265,57 @@ int puts(const char *str)
return ret; \ 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(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) int vsnprintf(char *str, size_t size, const char *format, va_list ap)
{ {
@ -279,19 +328,8 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
case '%': case '%':
switch (format[i + 1]) { switch (format[i + 1]) {
case 'i': case 'i':
case 'd': { case 'd': PRINT_PART(printInt, int, str, size, c, ret)
int s; case 'u': PRINT_PART(printUint, uint, str, size, c, ret)
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 'p': case 'p':
case 'x': { case 'x': {
char val[sizeof(int) * 2]; 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]) { switch (format[i + 2]) {
case 'l': case 'l':
switch (format[i + 3]) { switch (format[i + 3]) {
case 'd': { case 'i':
int s; case 'd': PRINT_PART(printLlint, long long int, str, size, c, ret)
long long int d = va_arg(ap, long long int); case 'u': PRINT_PART(printLluint, long long unsigned int, str, size, c, ret)
if (str)
s = printInt64(d, &str[c], size);
else
s = printInt64(d, NULL, size);
size -= s;
c += s;
ret += s;
break;
}
case 'p': case 'p':
case 'x': { case 'x': {
char val[sizeof(long long int) * 2]; char val[sizeof(long long int) * 2];
unsigned int valIdx = 0; 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); itoa(d, val, 16);
if (str) { if (str) {
while (val[valIdx]) { while (val[valIdx]) {
@ -390,17 +419,28 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap)
i++; i++;
break; break;
case 'i': case 'i':
case 'd': { case 'd': PRINT_PART(printLint, long int, str, size, c, ret)
int s; case 'u':
long int d = va_arg(ap, long int); PRINT_PART(printLuint, long unsigned int, str, size, c, ret)
if (str) case 'p':
s = printInt64(d, &str[c], size); case 'x': {
else char val[sizeof(int) * 2];
s = printInt64(d, NULL, size); unsigned int valIdx = 0;
unsigned long int d = va_arg(ap, unsigned long int);
size -= s; itoa(d, val, 16);
c += s; if (str) {
ret += s; while (val[valIdx]) {
if (size) {
str[c++] = val[valIdx++];
size--;
ret++;
} else {
return ret;
}
}
} else {
ret += strlen(val);
}
break; break;
} }
} }