Skip to content

Commit 274325c

Browse files
robclarktrini
authored andcommitted
vsprintf.c: add UTF-16 string (%ls) support
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>
1 parent 78178bb commit 274325c

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

examples/api/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ EXT_COBJ-y += lib/div64.o
3434
EXT_COBJ-y += lib/string.o
3535
EXT_COBJ-y += lib/time.o
3636
EXT_COBJ-y += lib/vsprintf.o
37+
EXT_COBJ-y += lib/charset.o
3738
EXT_SOBJ-$(CONFIG_PPC) += arch/powerpc/lib/ppcstring.o
3839
ifeq ($(ARCH),arm)
3940
EXT_SOBJ-$(CONFIG_USE_ARCH_MEMSET) += arch/arm/lib/memset.o

lib/vsprintf.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/ctype.h>
1818

1919
#include <common.h>
20+
#include <charset.h>
2021

2122
#include <div64.h>
2223
#define noinline __attribute__((noinline))
@@ -270,6 +271,26 @@ static char *string(char *buf, char *end, char *s, int field_width,
270271
return buf;
271272
}
272273

274+
static char *string16(char *buf, char *end, u16 *s, int field_width,
275+
int precision, int flags)
276+
{
277+
u16 *str = s ? s : L"<NULL>";
278+
int utf16_len = utf16_strnlen(str, precision);
279+
u8 utf8[utf16_len * MAX_UTF8_PER_UTF16];
280+
int utf8_len, i;
281+
282+
utf8_len = utf16_to_utf8(utf8, str, utf16_len) - utf8;
283+
284+
if (!(flags & LEFT))
285+
while (utf8_len < field_width--)
286+
ADDCH(buf, ' ');
287+
for (i = 0; i < utf8_len; ++i)
288+
ADDCH(buf, utf8[i]);
289+
while (utf8_len < field_width--)
290+
ADDCH(buf, ' ');
291+
return buf;
292+
}
293+
273294
#ifdef CONFIG_CMD_NET
274295
static const char hex_asc[] = "0123456789abcdef";
275296
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
@@ -528,8 +549,13 @@ static int vsnprintf_internal(char *buf, size_t size, const char *fmt,
528549
continue;
529550

530551
case 's':
531-
str = string(str, end, va_arg(args, char *),
532-
field_width, precision, flags);
552+
if (qualifier == 'l' && !IS_ENABLED(CONFIG_SPL_BUILD)) {
553+
str = string16(str, end, va_arg(args, u16 *),
554+
field_width, precision, flags);
555+
} else {
556+
str = string(str, end, va_arg(args, char *),
557+
field_width, precision, flags);
558+
}
533559
continue;
534560

535561
case 'p':

0 commit comments

Comments
 (0)