[kservice] 完善rt_vsnprintf (#8558)

This commit is contained in:
Meco Man 2024-02-24 11:11:28 -05:00 committed by GitHub
parent 0400fffafc
commit dee05d2c42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 42 additions and 52 deletions

View File

@ -49,10 +49,6 @@
#include <console.h> #include <console.h>
#endif #endif
/* use precision */
#define RT_PRINTF_PRECISION
#define RT_PRINTF_SPECIAL
/** /**
* @addtogroup KernelService * @addtogroup KernelService
* @{ * @{
@ -806,9 +802,7 @@ static char *print_number(char *buf,
int base, int base,
int qualifier, int qualifier,
int s, int s,
#ifdef RT_PRINTF_PRECISION
int precision, int precision,
#endif /* RT_PRINTF_PRECISION */
int type) int type)
{ {
char c = 0, sign = 0; char c = 0, sign = 0;
@ -878,7 +872,6 @@ static char *print_number(char *buf,
} }
} }
#ifdef RT_PRINTF_SPECIAL
if (type & SPECIAL) if (type & SPECIAL)
{ {
if (base == 2 || base == 16) if (base == 2 || base == 16)
@ -890,7 +883,6 @@ static char *print_number(char *buf,
size--; size--;
} }
} }
#endif /* RT_PRINTF_SPECIAL */
i = 0; i = 0;
if (num == 0) if (num == 0)
@ -903,15 +895,11 @@ static char *print_number(char *buf,
tmp[i++] = digits[divide(&num, base)]; tmp[i++] = digits[divide(&num, base)];
} }
#ifdef RT_PRINTF_PRECISION
if (i > precision) if (i > precision)
{ {
precision = i; precision = i;
} }
size -= precision; size -= precision;
#else
size -= i;
#endif /* RT_PRINTF_PRECISION */
if (!(type & (ZEROPAD | LEFT))) if (!(type & (ZEROPAD | LEFT)))
{ {
@ -941,7 +929,6 @@ static char *print_number(char *buf,
++ buf; ++ buf;
} }
#ifdef RT_PRINTF_SPECIAL
if (type & SPECIAL) if (type & SPECIAL)
{ {
if (base == 2) if (base == 2)
@ -974,7 +961,6 @@ static char *print_number(char *buf,
++ buf; ++ buf;
} }
} }
#endif /* RT_PRINTF_SPECIAL */
/* no align to the left */ /* no align to the left */
if (!(type & LEFT)) if (!(type & LEFT))
@ -990,7 +976,6 @@ static char *print_number(char *buf,
} }
} }
#ifdef RT_PRINTF_PRECISION
while (i < precision--) while (i < precision--)
{ {
if (buf < end) if (buf < end)
@ -1000,7 +985,6 @@ static char *print_number(char *buf,
++ buf; ++ buf;
} }
#endif /* RT_PRINTF_PRECISION */
/* put number in the temporary buffer */ /* put number in the temporary buffer */
while (i-- > 0 && (precision_bak != 0)) while (i-- > 0 && (precision_bak != 0))
@ -1059,10 +1043,7 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
rt_uint8_t flags = 0; /* flags to print number */ rt_uint8_t flags = 0; /* flags to print number */
rt_uint8_t qualifier = 0; /* 'h', 'l', or 'L' for integer fields */ rt_uint8_t qualifier = 0; /* 'h', 'l', or 'L' for integer fields */
rt_int32_t field_width = 0; /* width of output field */ rt_int32_t field_width = 0; /* width of output field */
#ifdef RT_PRINTF_PRECISION
int precision = 0; /* min. # of digits for integers and max for a string */ int precision = 0; /* min. # of digits for integers and max for a string */
#endif /* RT_PRINTF_PRECISION */
str = buf; str = buf;
end = buf + size; end = buf + size;
@ -1093,7 +1074,7 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
while (1) while (1)
{ {
/* skips the first '%' also */ /* skips the first '%' also */
++ fmt; ++fmt;
if (*fmt == '-') flags |= LEFT; if (*fmt == '-') flags |= LEFT;
else if (*fmt == '+') flags |= PLUS; else if (*fmt == '+') flags |= PLUS;
else if (*fmt == ' ') flags |= SPACE; else if (*fmt == ' ') flags |= SPACE;
@ -1110,7 +1091,7 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
} }
else if (*fmt == '*') else if (*fmt == '*')
{ {
++ fmt; ++fmt;
/* it's the next argument */ /* it's the next argument */
field_width = va_arg(args, int); field_width = va_arg(args, int);
if (field_width < 0) if (field_width < 0)
@ -1120,19 +1101,18 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
} }
} }
#ifdef RT_PRINTF_PRECISION
/* get the precision */ /* get the precision */
precision = -1; precision = -1;
if (*fmt == '.') if (*fmt == '.')
{ {
++ fmt; ++fmt;
if (_ISDIGIT(*fmt)) if (_ISDIGIT(*fmt))
{ {
precision = skip_atoi(&fmt); precision = skip_atoi(&fmt);
} }
else if (*fmt == '*') else if (*fmt == '*')
{ {
++ fmt; ++fmt;
/* it's the next argument */ /* it's the next argument */
precision = va_arg(args, int); precision = va_arg(args, int);
} }
@ -1141,24 +1121,29 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
precision = 0; precision = 0;
} }
} }
#endif /* RT_PRINTF_PRECISION */
/* get the conversion qualifier */ qualifier = 0; /* get the conversion qualifier */
qualifier = 0;
if (*fmt == 'h' || *fmt == 'l' ||
#ifdef RT_KPRINTF_USING_LONGLONG #ifdef RT_KPRINTF_USING_LONGLONG
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') *fmt == 'L' ||
#else
if (*fmt == 'h' || *fmt == 'l')
#endif /* RT_KPRINTF_USING_LONGLONG */ #endif /* RT_KPRINTF_USING_LONGLONG */
*fmt == 'z')
{ {
qualifier = *fmt; qualifier = *fmt;
++ fmt; ++fmt;
#ifdef RT_KPRINTF_USING_LONGLONG #ifdef RT_KPRINTF_USING_LONGLONG
if (qualifier == 'l' && *fmt == 'l') if (qualifier == 'l' && *fmt == 'l')
{ {
qualifier = 'L'; qualifier = 'L';
++ fmt; ++fmt;
} }
#endif /* RT_KPRINTF_USING_LONGLONG */ #endif /* RT_KPRINTF_USING_LONGLONG */
if (qualifier == 'h' && *fmt == 'h')
{
qualifier = 'H';
++fmt;
}
} }
/* the default base */ /* the default base */
@ -1200,12 +1185,11 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
} }
for (len = 0; (len != field_width) && (s[len] != '\0'); len++); for (len = 0; (len != field_width) && (s[len] != '\0'); len++);
#ifdef RT_PRINTF_PRECISION
if (precision > 0 && len > precision) if (precision > 0 && len > precision)
{ {
len = precision; len = precision;
} }
#endif /* RT_PRINTF_PRECISION */
if (!(flags & LEFT)) if (!(flags & LEFT))
{ {
@ -1234,21 +1218,12 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
if (field_width == -1) if (field_width == -1)
{ {
field_width = sizeof(void *) << 1; field_width = sizeof(void *) << 1;
#ifdef RT_PRINTF_SPECIAL
field_width += 2; /* `0x` prefix */ field_width += 2; /* `0x` prefix */
flags |= SPECIAL; flags |= SPECIAL;
#endif
flags |= ZEROPAD; flags |= ZEROPAD;
} }
#ifdef RT_PRINTF_PRECISION str = print_number(str, end, (unsigned long)va_arg(args, void *),
str = print_number(str, end,
(unsigned long)va_arg(args, void *),
16, qualifier, field_width, precision, flags); 16, qualifier, field_width, precision, flags);
#else
str = print_number(str, end,
(unsigned long)va_arg(args, void *),
16, qualifier, field_width, flags);
#endif
continue; continue;
case '%': case '%':
@ -1279,6 +1254,13 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
case 'u': case 'u':
break; break;
case 'e':
case 'E':
case 'G':
case 'g':
case 'f':
case 'F':
va_arg(args, double);
default: default:
if (str < end) if (str < end)
{ {
@ -1301,18 +1283,22 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
continue; continue;
} }
#ifdef RT_KPRINTF_USING_LONGLONG
if (qualifier == 'L') if (qualifier == 'L')
{ {
num = va_arg(args, unsigned long long); num = va_arg(args, unsigned long long);
} }
else if (qualifier == 'l') else if (qualifier == 'l')
#else
if (qualifier == 'l')
#endif /* RT_KPRINTF_USING_LONGLONG */
{ {
num = va_arg(args, unsigned long); num = va_arg(args, unsigned long);
} }
else if (qualifier == 'H')
{
num = (rt_int8_t)va_arg(args, rt_int32_t);
if (flags & SIGN)
{
num = (rt_int8_t)num;
}
}
else if (qualifier == 'h') else if (qualifier == 'h')
{ {
num = (rt_uint16_t)va_arg(args, rt_int32_t); num = (rt_uint16_t)va_arg(args, rt_int32_t);
@ -1321,15 +1307,19 @@ rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list arg
num = (rt_int16_t)num; num = (rt_int16_t)num;
} }
} }
else if (qualifier == 'z')
{
num = va_arg(args, rt_size_t);
if (flags & SIGN)
{
num = (rt_ssize_t)num;
}
}
else else
{ {
num = (rt_uint32_t)va_arg(args, unsigned long); num = (rt_uint32_t)va_arg(args, unsigned long);
} }
#ifdef RT_PRINTF_PRECISION
str = print_number(str, end, num, base, qualifier, field_width, precision, flags); str = print_number(str, end, num, base, qualifier, field_width, precision, flags);
#else
str = print_number(str, end, num, base, qualifier, field_width, flags);
#endif
} }
if (size > 0) if (size > 0)