X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=lib%2Fvsprintf.c;h=425f2f53f79770d53047a27893aad6b0b776216b;hb=039c031e080c5b127c036a5db73e1ba91f5c0ed1;hp=dd572d2868a5453c8cd99326a944f3ee4e20cd25;hpb=2dc5b553b9bcd701bd7abd60f99f407cb0c37762;p=oweals%2Fu-boot.git diff --git a/lib/vsprintf.c b/lib/vsprintf.c index dd572d2868..425f2f53f7 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -11,16 +11,17 @@ * from hush: simple_itoa() was lifted from boa-0.93.15 */ +#include +#include +#include +#include +#include #include +#include +#include #include #include -#include -#include -#include -#include - -#include #define noinline __attribute__((noinline)) /* we use this so that we can do without the ctype library */ @@ -272,38 +273,51 @@ static char *string(char *buf, char *end, char *s, int field_width, return buf; } +/* U-Boot uses UTF-16 strings in the EFI context only. */ +#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) static char *string16(char *buf, char *end, u16 *s, int field_width, int precision, int flags) { - u16 *str = s ? s : L""; - int utf16_len = utf16_strnlen(str, precision); - u8 utf8[utf16_len * MAX_UTF8_PER_UTF16]; - int utf8_len, i; - - utf8_len = utf16_to_utf8(utf8, str, utf16_len) - utf8; + const u16 *str = s ? s : L""; + ssize_t i, len = utf16_strnlen(str, precision); if (!(flags & LEFT)) - while (utf8_len < field_width--) + for (; len < field_width; --field_width) ADDCH(buf, ' '); - for (i = 0; i < utf8_len; ++i) - ADDCH(buf, utf8[i]); - while (utf8_len < field_width--) + for (i = 0; i < len && buf + utf16_utf8_strnlen(str, 1) <= end; ++i) { + s32 s = utf16_get(&str); + + if (s < 0) + s = '?'; + utf8_put(s, &buf); + } + for (; len < field_width; --field_width) ADDCH(buf, ' '); return buf; } -#ifdef CONFIG_CMD_NET -static const char hex_asc[] = "0123456789abcdef"; -#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] -#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] - -static inline char *pack_hex_byte(char *buf, u8 byte) +#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT) +static char *device_path_string(char *buf, char *end, void *dp, int field_width, + int precision, int flags) { - *buf++ = hex_asc_hi(byte); - *buf++ = hex_asc_lo(byte); + u16 *str; + + /* If dp == NULL output the string '' */ + if (!dp) + return string16(buf, end, dp, field_width, precision, flags); + + str = efi_dp_str((struct efi_device_path *)dp); + if (!str) + return ERR_PTR(-ENOMEM); + + buf = string16(buf, end, str, field_width, precision, flags); + efi_free_pool(str); return buf; } +#endif +#endif +#ifdef CONFIG_CMD_NET static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width, int precision, int flags) { @@ -313,7 +327,7 @@ static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width, int i; for (i = 0; i < 6; i++) { - p = pack_hex_byte(p, addr[i]); + p = hex_byte_pack(p, addr[i]); if (!(flags & SPECIAL) && i != 5) *p++ = ':'; } @@ -332,8 +346,8 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, int i; for (i = 0; i < 8; i++) { - p = pack_hex_byte(p, addr[2 * i]); - p = pack_hex_byte(p, addr[2 * i + 1]); + p = hex_byte_pack(p, addr[2 * i]); + p = hex_byte_pack(p, addr[2 * i + 1]); if (!(flags & SPECIAL) && i != 7) *p++ = ':'; } @@ -369,33 +383,38 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, #ifdef CONFIG_LIB_UUID /* - * This works (roughly) the same way as linux's, but we currently always - * print lower-case (ie. we just keep %pUB and %pUL for compat with linux), - * mostly just because that is what uuid_bin_to_str() supports. + * This works (roughly) the same way as Linux's. * * %pUb: 01020304-0506-0708-090a-0b0c0d0e0f10 + * %pUB: 01020304-0506-0708-090A-0B0C0D0E0F10 * %pUl: 04030201-0605-0807-090a-0b0c0d0e0f10 + * %pUL: 04030201-0605-0807-090A-0B0C0D0E0F10 */ static char *uuid_string(char *buf, char *end, u8 *addr, int field_width, int precision, int flags, const char *fmt) { char uuid[UUID_STR_LEN + 1]; - int str_format = UUID_STR_FORMAT_STD; + int str_format; switch (*(++fmt)) { case 'L': + str_format = UUID_STR_FORMAT_GUID | UUID_STR_UPPER_CASE; + break; case 'l': str_format = UUID_STR_FORMAT_GUID; break; case 'B': - case 'b': - /* this is the default */ + str_format = UUID_STR_FORMAT_STD | UUID_STR_UPPER_CASE; break; default: + str_format = UUID_STR_FORMAT_STD; break; } - uuid_bin_to_str(addr, uuid, str_format); + if (addr) + uuid_bin_to_str(addr, uuid, str_format); + else + strcpy(uuid, ""); return string(buf, end, uuid, field_width, precision, flags); } @@ -435,7 +454,12 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, #endif switch (*fmt) { -#ifdef CONFIG_CMD_NET +/* Device paths only exist in the EFI context. */ +#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT) && !defined(API_BUILD) + case 'D': + return device_path_string(buf, end, ptr, field_width, + precision, flags); +#endif case 'a': flags |= SPECIAL | ZEROPAD; @@ -447,6 +471,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, break; } break; +#ifdef CONFIG_CMD_NET case 'm': flags |= SPECIAL; /* Fallthrough */ @@ -591,10 +616,14 @@ repeat: continue; case 's': - if (qualifier == 'l' && !IS_ENABLED(CONFIG_SPL_BUILD)) { +/* U-Boot uses UTF-16 strings in the EFI context only. */ +#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) + if (qualifier == 'l') { str = string16(str, end, va_arg(args, u16 *), field_width, precision, flags); - } else { + } else +#endif + { str = string(str, end, va_arg(args, char *), field_width, precision, flags); } @@ -604,6 +633,8 @@ repeat: str = pointer(fmt + 1, str, end, va_arg(args, void *), field_width, precision, flags); + if (IS_ERR(str)) + return PTR_ERR(str); /* Skip all alphanumeric pointer suffixes */ while (isalnum(fmt[1])) fmt++; @@ -753,6 +784,7 @@ int sprintf(char *buf, const char *fmt, ...) return i; } +#if CONFIG_IS_ENABLED(PRINTF) int printf(const char *fmt, ...) { va_list args; @@ -768,6 +800,9 @@ int printf(const char *fmt, ...) i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); + /* Handle error */ + if (i <= 0) + return i; /* Print the string */ puts(printbuffer); return i; @@ -784,19 +819,14 @@ int vprintf(const char *fmt, va_list args) */ i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); + /* Handle error */ + if (i <= 0) + return i; /* Print the string */ puts(printbuffer); return i; } - - -void __assert_fail(const char *assertion, const char *file, unsigned line, - const char *function) -{ - /* This will not return */ - panic("%s:%u: %s: Assertion `%s' failed.", file, line, function, - assertion); -} +#endif char *simple_itoa(ulong i) {