vsprintf.c: add UTF-16 string (%ls) support
authorRob Clark <robdclark@gmail.com>
Sat, 9 Sep 2017 10:47:41 +0000 (06:47 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 12 Sep 2017 21:57:59 +0000 (17:57 -0400)
This is convenient for efi_loader which deals a lot with UTF-16.  Only
enabled with CC_SHORT_WCHAR, leaving room to add a UTF-32 version when
CC_SHORT_WCHAR is not enabled.

Signed-off-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
examples/api/Makefile
lib/vsprintf.c

index dab6398bab824d83f4b90674cec10ddf55ec9f64..87c15d0f683c046688921c9b1ae4f1827c8439f0 100644 (file)
@@ -34,6 +34,7 @@ EXT_COBJ-y += lib/div64.o
 EXT_COBJ-y += lib/string.o
 EXT_COBJ-y += lib/time.o
 EXT_COBJ-y += lib/vsprintf.o
+EXT_COBJ-y += lib/charset.o
 EXT_SOBJ-$(CONFIG_PPC) += arch/powerpc/lib/ppcstring.o
 ifeq ($(ARCH),arm)
 EXT_SOBJ-$(CONFIG_USE_ARCH_MEMSET) += arch/arm/lib/memset.o
index 874a2951f7053ef395cfee8ffe78464eee855039..97bed9d36dc2878be42e017166739e7912808ae9 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/ctype.h>
 
 #include <common.h>
+#include <charset.h>
 
 #include <div64.h>
 #define noinline __attribute__((noinline))
@@ -270,6 +271,26 @@ static char *string(char *buf, char *end, char *s, int field_width,
        return buf;
 }
 
+static char *string16(char *buf, char *end, u16 *s, int field_width,
+               int precision, int flags)
+{
+       u16 *str = s ? s : L"<NULL>";
+       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;
+
+       if (!(flags & LEFT))
+               while (utf8_len < field_width--)
+                       ADDCH(buf, ' ');
+       for (i = 0; i < utf8_len; ++i)
+               ADDCH(buf, utf8[i]);
+       while (utf8_len < 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)]
@@ -528,8 +549,13 @@ repeat:
                        continue;
 
                case 's':
-                       str = string(str, end, va_arg(args, char *),
-                                    field_width, precision, flags);
+                       if (qualifier == 'l' && !IS_ENABLED(CONFIG_SPL_BUILD)) {
+                               str = string16(str, end, va_arg(args, u16 *),
+                                              field_width, precision, flags);
+                       } else {
+                               str = string(str, end, va_arg(args, char *),
+                                            field_width, precision, flags);
+                       }
                        continue;
 
                case 'p':