* from hush: simple_itoa() was lifted from boa-0.93.15
*/
+#include <common.h>
+#include <charset.h>
+#include <efi_loader.h>
+#include <div64.h>
+#include <hexdump.h>
#include <stdarg.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/ctype.h>
-#include <common.h>
-
-#include <div64.h>
#define noinline __attribute__((noinline))
/* we use this so that we can do without the ctype library */
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]
+/* 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)
+{
+ const u16 *str = s ? s : L"<NULL>";
+ ssize_t i, len = utf16_strnlen(str, precision);
-static inline char *pack_hex_byte(char *buf, u8 byte)
+ if (!(flags & LEFT))
+ for (; len < field_width; --field_width)
+ ADDCH(buf, ' ');
+ 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;
+}
+
+#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 '<NULL>' */
+ 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)
{
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++ = ':';
}
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++ = ':';
}
}
#endif
+#ifdef CONFIG_LIB_UUID
+/*
+ * 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;
+
+ 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':
+ str_format = UUID_STR_FORMAT_STD | UUID_STR_UPPER_CASE;
+ break;
+ default:
+ str_format = UUID_STR_FORMAT_STD;
+ break;
+ }
+
+ if (addr)
+ uuid_bin_to_str(addr, uuid, str_format);
+ else
+ strcpy(uuid, "<NULL>");
+
+ return string(buf, end, uuid, field_width, precision, flags);
+}
+#endif
+
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
* by an extra set of alphanumeric characters that are extended format
flags);
#endif
-#ifdef CONFIG_CMD_NET
switch (*fmt) {
+/* 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;
break;
}
break;
+#ifdef CONFIG_CMD_NET
case 'm':
flags |= SPECIAL;
/* Fallthrough */
precision, flags);
flags &= ~SPECIAL;
break;
- }
#endif
+#ifdef CONFIG_LIB_UUID
+ case 'U':
+ return uuid_string(buf, end, ptr, field_width, precision,
+ flags, fmt);
+#endif
+ default:
+ break;
+ }
flags |= SMALL;
if (field_width == -1) {
field_width = 2*sizeof(void *);
continue;
case 's':
- str = string(str, end, va_arg(args, char *),
- field_width, precision, flags);
+/* 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
+#endif
+ {
+ str = string(str, end, va_arg(args, char *),
+ field_width, precision, flags);
+ }
continue;
case 'p':
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++;
return i;
}
+#if CONFIG_IS_ENABLED(PRINTF)
int printf(const char *fmt, ...)
{
va_list args;
i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args);
+ /* Handle error */
+ if (i <= 0)
+ return i;
/* Print the string */
puts(printbuffer);
return i;
*/
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)
{