malta: Rename CONFIG_MALTA to CONFIG_TARGET_MALTA
[platform/kernel/u-boot.git] / test / unicode_ut.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Unit tests for Unicode functions
4  *
5  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
6  */
7
8 #include <common.h>
9 #include <charset.h>
10 #include <command.h>
11 #include <efi_loader.h>
12 #include <errno.h>
13 #include <log.h>
14 #include <malloc.h>
15 #include <test/test.h>
16 #include <test/suites.h>
17 #include <test/ut.h>
18
19 /* Linker list entry for a Unicode test */
20 #define UNICODE_TEST(_name) UNIT_TEST(_name, 0, unicode_test)
21
22 /* Constants c1-c4 and d1-d4 encode the same letters */
23
24 /* Six characters translating to one utf-8 byte each. */
25 static const u16 c1[] = {0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00};
26 /* One character translating to two utf-8 bytes */
27 static const u16 c2[] = {0x6b, 0x61, 0x66, 0x62, 0xe1, 0x74, 0x75, 0x72, 0x00};
28 /* Three characters translating to three utf-8 bytes each */
29 static const u16 c3[] = {0x6f5c, 0x6c34, 0x8266, 0x00};
30 /* Three letters translating to four utf-8 bytes each */
31 static const u16 c4[] = {0xd801, 0xdc8d, 0xd801, 0xdc96, 0xd801, 0xdc87,
32                          0x0000};
33
34 /* Illegal utf-16 strings */
35 static const u16 i1[] = {0x69, 0x31, 0xdc87, 0x6c, 0x00};
36 static const u16 i2[] = {0x69, 0x32, 0xd801, 0xd801, 0x6c, 0x00};
37 static const u16 i3[] = {0x69, 0x33, 0xd801, 0x00};
38
39 /* Six characters translating to one utf-16 word each. */
40 static const char d1[] = {0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00};
41 /* Eight characters translating to one utf-16 word each */
42 static const char d2[] = {0x6b, 0x61, 0x66, 0x62, 0xc3, 0xa1, 0x74, 0x75,
43                           0x72, 0x00};
44 /* Three characters translating to one utf-16 word each */
45 static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89,
46                           0xa6, 0x00};
47 /* Three letters translating to two utf-16 word each */
48 static const char d4[] = {0xf0, 0x90, 0x92, 0x8d, 0xf0, 0x90, 0x92, 0x96,
49                           0xf0, 0x90, 0x92, 0x87, 0x00};
50 /* Letter not in code page 437 */
51 static const char d5[] = {0xCE, 0x92, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F,
52                           0x74, 0x20, 0x42, 0x00};
53
54 /* Illegal utf-8 strings */
55 static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00};
56 static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00};
57 static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00};
58 static const char j4[] = {0xa1, 0x00};
59
60 static int unicode_test_u16_strlen(struct unit_test_state *uts)
61 {
62         ut_asserteq(6, u16_strlen(c1));
63         ut_asserteq(8, u16_strlen(c2));
64         ut_asserteq(3, u16_strlen(c3));
65         ut_asserteq(6, u16_strlen(c4));
66         return 0;
67 }
68 UNICODE_TEST(unicode_test_u16_strlen);
69
70 static int unicode_test_u16_strdup(struct unit_test_state *uts)
71 {
72         u16 *copy = u16_strdup(c4);
73
74         ut_assert(copy != c4);
75         ut_asserteq_mem(copy, c4, sizeof(c4));
76         free(copy);
77
78         return 0;
79 }
80 UNICODE_TEST(unicode_test_u16_strdup);
81
82 static int unicode_test_u16_strcpy(struct unit_test_state *uts)
83 {
84         u16 *r;
85         u16 copy[10];
86
87         r = u16_strcpy(copy, c1);
88         ut_assert(r == copy);
89         ut_asserteq_mem(copy, c1, sizeof(c1));
90
91         return 0;
92 }
93 UNICODE_TEST(unicode_test_u16_strcpy);
94
95 /* U-Boot uses UTF-16 strings in the EFI context only. */
96 #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
97 static int unicode_test_string16(struct unit_test_state *uts)
98 {
99         char buf[20];
100         int ret;
101
102         /* Test length and precision */
103         memset(buf, 0xff, sizeof(buf));
104         sprintf(buf, "%8.6ls", c2);
105         ut_asserteq(' ', buf[1]);
106         ut_assert(!strncmp(&buf[2], d2, 7));
107         ut_assert(!buf[9]);
108
109         memset(buf, 0xff, sizeof(buf));
110         sprintf(buf, "%8.6ls", c4);
111         ut_asserteq(' ', buf[4]);
112         ut_assert(!strncmp(&buf[5], d4, 12));
113         ut_assert(!buf[17]);
114
115         memset(buf, 0xff, sizeof(buf));
116         sprintf(buf, "%-8.2ls", c4);
117         ut_asserteq(' ', buf[8]);
118         ut_assert(!strncmp(buf, d4, 8));
119         ut_assert(!buf[14]);
120
121         /* Test handling of illegal utf-16 sequences */
122         memset(buf, 0xff, sizeof(buf));
123         sprintf(buf, "%ls", i1);
124         ut_asserteq_str("i1?l", buf);
125
126         memset(buf, 0xff, sizeof(buf));
127         sprintf(buf, "%ls", i2);
128         ut_asserteq_str("i2?l", buf);
129
130         memset(buf, 0xff, sizeof(buf));
131         sprintf(buf, "%ls", i3);
132         ut_asserteq_str("i3?", buf);
133
134         memset(buf, 0xff, sizeof(buf));
135         ret = snprintf(buf, 4, "%ls", c1);
136         ut_asserteq(6, ret);
137         ut_asserteq_str("U-B", buf);
138
139         memset(buf, 0xff, sizeof(buf));
140         ret = snprintf(buf, 6, "%ls", c2);
141         ut_asserteq_str("kafb", buf);
142         ut_asserteq(9, ret);
143
144         memset(buf, 0xff, sizeof(buf));
145         ret = snprintf(buf, 7, "%ls", c2);
146         ut_asserteq_str("kafb\xC3\xA1", buf);
147         ut_asserteq(9, ret);
148
149         memset(buf, 0xff, sizeof(buf));
150         ret = snprintf(buf, 8, "%ls", c3);
151         ut_asserteq_str("\xE6\xBD\x9C\xE6\xB0\xB4", buf);
152         ut_asserteq(9, ret);
153
154         memset(buf, 0xff, sizeof(buf));
155         ret = snprintf(buf, 11, "%ls", c4);
156         ut_asserteq_str("\xF0\x90\x92\x8D\xF0\x90\x92\x96", buf);
157         ut_asserteq(12, ret);
158
159         memset(buf, 0xff, sizeof(buf));
160         ret = snprintf(buf, 4, "%ls", c4);
161         ut_asserteq_str("", buf);
162         ut_asserteq(12, ret);
163
164         return 0;
165 }
166 UNICODE_TEST(unicode_test_string16);
167 #endif
168
169 static int unicode_test_utf8_get(struct unit_test_state *uts)
170 {
171         const char *s;
172         s32 code;
173         int i;
174
175         /* Check characters less than 0x800 */
176         s = d2;
177         for (i = 0; i < 8; ++i) {
178                 code = utf8_get((const char **)&s);
179                 /* c2 is the utf-8 encoding of d2 */
180                 ut_asserteq(c2[i], code);
181                 if (!code)
182                         break;
183         }
184         ut_asserteq_ptr(s, d2 + 9)
185
186         /* Check characters less than 0x10000 */
187         s = d3;
188         for (i = 0; i < 4; ++i) {
189                 code = utf8_get((const char **)&s);
190                 /* c3 is the utf-8 encoding of d3 */
191                 ut_asserteq(c3[i], code);
192                 if (!code)
193                         break;
194         }
195         ut_asserteq_ptr(s, d3 + 9)
196
197         /* Check character greater 0xffff */
198         s = d4;
199         code = utf8_get((const char **)&s);
200         ut_asserteq(0x0001048d, code);
201         ut_asserteq_ptr(s, d4 + 4);
202
203         /* Check illegal character */
204         s = j4;
205         code = utf8_get((const char **)&s);
206         ut_asserteq(-1, code);
207         ut_asserteq_ptr(j4 + 1, s);
208
209         return 0;
210 }
211 UNICODE_TEST(unicode_test_utf8_get);
212
213 static int unicode_test_utf8_put(struct unit_test_state *uts)
214 {
215         char buffer[8] = { 0, };
216         char *pos;
217
218         /* Commercial at, translates to one character */
219         pos = buffer;
220         ut_assert(!utf8_put('@', &pos))
221         ut_asserteq(1, pos - buffer);
222         ut_asserteq('@', buffer[0]);
223         ut_assert(!buffer[1]);
224
225         /* Latin letter G with acute, translates to two charactes */
226         pos = buffer;
227         ut_assert(!utf8_put(0x1f4, &pos));
228         ut_asserteq(2, pos - buffer);
229         ut_asserteq_str("\xc7\xb4", buffer);
230
231         /* Tagalog letter i, translates to three characters */
232         pos = buffer;
233         ut_assert(!utf8_put(0x1701, &pos));
234         ut_asserteq(3, pos - buffer);
235         ut_asserteq_str("\xe1\x9c\x81", buffer);
236
237         /* Hamster face, translates to four characters */
238         pos = buffer;
239         ut_assert(!utf8_put(0x1f439, &pos));
240         ut_asserteq(4, pos - buffer);
241         ut_asserteq_str("\xf0\x9f\x90\xb9", buffer);
242
243         /* Illegal code */
244         pos = buffer;
245         ut_asserteq(-1, utf8_put(0xd888, &pos));
246
247         return 0;
248 }
249 UNICODE_TEST(unicode_test_utf8_put);
250
251 static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts)
252 {
253         ut_asserteq(6, utf8_utf16_strlen(d1));
254         ut_asserteq(8, utf8_utf16_strlen(d2));
255         ut_asserteq(3, utf8_utf16_strlen(d3));
256         ut_asserteq(6, utf8_utf16_strlen(d4));
257
258         /* illegal utf-8 sequences */
259         ut_asserteq(4, utf8_utf16_strlen(j1));
260         ut_asserteq(4, utf8_utf16_strlen(j2));
261         ut_asserteq(3, utf8_utf16_strlen(j3));
262
263         return 0;
264 }
265 UNICODE_TEST(unicode_test_utf8_utf16_strlen);
266
267 static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts)
268 {
269         ut_asserteq(3, utf8_utf16_strnlen(d1, 3));
270         ut_asserteq(6, utf8_utf16_strnlen(d1, 13));
271         ut_asserteq(6, utf8_utf16_strnlen(d2, 6));
272         ut_asserteq(2, utf8_utf16_strnlen(d3, 2));
273         ut_asserteq(4, utf8_utf16_strnlen(d4, 2));
274         ut_asserteq(6, utf8_utf16_strnlen(d4, 3));
275
276         /* illegal utf-8 sequences */
277         ut_asserteq(4, utf8_utf16_strnlen(j1, 16));
278         ut_asserteq(4, utf8_utf16_strnlen(j2, 16));
279         ut_asserteq(3, utf8_utf16_strnlen(j3, 16));
280
281         return 0;
282 }
283 UNICODE_TEST(unicode_test_utf8_utf16_strnlen);
284
285 /**
286  * ut_u16_strcmp() - Compare to u16 strings.
287  *
288  * @a1:         first string
289  * @a2:         second string
290  * @count:      number of u16 to compare
291  * Return:      -1 if a1 < a2, 0 if a1 == a2, 1 if a1 > a2
292  */
293 static int unicode_test_u16_strcmp(const u16 *a1, const u16 *a2, size_t count)
294 {
295         for (; (*a1 || *a2) && count; ++a1, ++a2, --count) {
296                 if (*a1 < *a2)
297                         return -1;
298                 if (*a1 > *a2)
299                         return 1;
300         }
301         return 0;
302 }
303
304 static int unicode_test_utf8_utf16_strcpy(struct unit_test_state *uts)
305 {
306         u16 buf[16];
307         u16 *pos;
308
309         pos = buf;
310         utf8_utf16_strcpy(&pos, d1);
311         ut_asserteq(6, pos - buf);
312         ut_assert(!unicode_test_u16_strcmp(buf, c1, SIZE_MAX));
313
314         pos = buf;
315         utf8_utf16_strcpy(&pos, d2);
316         ut_asserteq(8, pos - buf);
317         ut_assert(!unicode_test_u16_strcmp(buf, c2, SIZE_MAX));
318
319         pos = buf;
320         utf8_utf16_strcpy(&pos, d3);
321         ut_asserteq(3, pos - buf);
322         ut_assert(!unicode_test_u16_strcmp(buf, c3, SIZE_MAX));
323
324         pos = buf;
325         utf8_utf16_strcpy(&pos, d4);
326         ut_asserteq(6, pos - buf);
327         ut_assert(!unicode_test_u16_strcmp(buf, c4, SIZE_MAX));
328
329         /* Illegal utf-8 strings */
330         pos = buf;
331         utf8_utf16_strcpy(&pos, j1);
332         ut_asserteq(4, pos - buf);
333         ut_assert(!unicode_test_u16_strcmp(buf, u"j1?l", SIZE_MAX));
334
335         pos = buf;
336         utf8_utf16_strcpy(&pos, j2);
337         ut_asserteq(4, pos - buf);
338         ut_assert(!unicode_test_u16_strcmp(buf, u"j2?l", SIZE_MAX));
339
340         pos = buf;
341         utf8_utf16_strcpy(&pos, j3);
342         ut_asserteq(3, pos - buf);
343         ut_assert(!unicode_test_u16_strcmp(buf, u"j3?", SIZE_MAX));
344
345         return 0;
346 }
347 UNICODE_TEST(unicode_test_utf8_utf16_strcpy);
348
349 static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts)
350 {
351         u16 buf[16];
352         u16 *pos;
353
354         pos = buf;
355         memset(buf, 0, sizeof(buf));
356         utf8_utf16_strncpy(&pos, d1, 4);
357         ut_asserteq(4, pos - buf);
358         ut_assert(!buf[4]);
359         ut_assert(!unicode_test_u16_strcmp(buf, c1, 4));
360
361         pos = buf;
362         memset(buf, 0, sizeof(buf));
363         utf8_utf16_strncpy(&pos, d2, 10);
364         ut_asserteq(8, pos - buf);
365         ut_assert(buf[4]);
366         ut_assert(!unicode_test_u16_strcmp(buf, c2, SIZE_MAX));
367
368         pos = buf;
369         memset(buf, 0, sizeof(buf));
370         utf8_utf16_strncpy(&pos, d3, 2);
371         ut_asserteq(2, pos - buf);
372         ut_assert(!buf[2]);
373         ut_assert(!unicode_test_u16_strcmp(buf, c3, 2));
374
375         pos = buf;
376         memset(buf, 0, sizeof(buf));
377         utf8_utf16_strncpy(&pos, d4, 2);
378         ut_asserteq(4, pos - buf);
379         ut_assert(!buf[4]);
380         ut_assert(!unicode_test_u16_strcmp(buf, c4, 4));
381
382         pos = buf;
383         memset(buf, 0, sizeof(buf));
384         utf8_utf16_strncpy(&pos, d4, 10);
385         ut_asserteq(6, pos - buf);
386         ut_assert(buf[5]);
387         ut_assert(!unicode_test_u16_strcmp(buf, c4, SIZE_MAX));
388
389         return 0;
390 }
391 UNICODE_TEST(unicode_test_utf8_utf16_strncpy);
392
393 static int unicode_test_utf16_get(struct unit_test_state *uts)
394 {
395         const u16 *s;
396         s32 code;
397         int i;
398
399         /* Check characters less than 0x10000 */
400         s = c2;
401         for (i = 0; i < 9; ++i) {
402                 code = utf16_get((const u16 **)&s);
403                 ut_asserteq(c2[i], code);
404                 if (!code)
405                         break;
406         }
407         ut_asserteq_ptr(c2 + 8, s);
408
409         /* Check character greater 0xffff */
410         s = c4;
411         code = utf16_get((const u16 **)&s);
412         ut_asserteq(0x0001048d, code);
413         ut_asserteq_ptr(c4 + 2, s);
414
415         return 0;
416 }
417 UNICODE_TEST(unicode_test_utf16_get);
418
419 static int unicode_test_utf16_put(struct unit_test_state *uts)
420 {
421         u16 buffer[4] = { 0, };
422         u16 *pos;
423
424         /* Commercial at, translates to one word */
425         pos = buffer;
426         ut_assert(!utf16_put('@', &pos));
427         ut_asserteq(1, pos - buffer);
428         ut_asserteq((u16)'@', buffer[0]);
429         ut_assert(!buffer[1]);
430
431         /* Hamster face, translates to two words */
432         pos = buffer;
433         ut_assert(!utf16_put(0x1f439, &pos));
434         ut_asserteq(2, pos - buffer);
435         ut_asserteq((u16)0xd83d, buffer[0]);
436         ut_asserteq((u16)0xdc39, buffer[1]);
437         ut_assert(!buffer[2]);
438
439         /* Illegal code */
440         pos = buffer;
441         ut_asserteq(-1, utf16_put(0xd888, &pos));
442
443         return 0;
444 }
445 UNICODE_TEST(unicode_test_utf16_put);
446
447 static int unicode_test_utf16_strnlen(struct unit_test_state *uts)
448 {
449         ut_asserteq(3, utf16_strnlen(c1, 3));
450         ut_asserteq(6, utf16_strnlen(c1, 13));
451         ut_asserteq(6, utf16_strnlen(c2, 6));
452         ut_asserteq(2, utf16_strnlen(c3, 2));
453         ut_asserteq(2, utf16_strnlen(c4, 2));
454         ut_asserteq(3, utf16_strnlen(c4, 3));
455
456         /* illegal utf-16 word sequences */
457         ut_asserteq(4, utf16_strnlen(i1, 16));
458         ut_asserteq(4, utf16_strnlen(i2, 16));
459         ut_asserteq(3, utf16_strnlen(i3, 16));
460
461         return 0;
462 }
463 UNICODE_TEST(unicode_test_utf16_strnlen);
464
465 static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts)
466 {
467         ut_asserteq(6, utf16_utf8_strlen(c1));
468         ut_asserteq(9, utf16_utf8_strlen(c2));
469         ut_asserteq(9, utf16_utf8_strlen(c3));
470         ut_asserteq(12, utf16_utf8_strlen(c4));
471
472         /* illegal utf-16 word sequences */
473         ut_asserteq(4, utf16_utf8_strlen(i1));
474         ut_asserteq(4, utf16_utf8_strlen(i2));
475         ut_asserteq(3, utf16_utf8_strlen(i3));
476
477         return 0;
478 }
479 UNICODE_TEST(unicode_test_utf16_utf8_strlen);
480
481 static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts)
482 {
483         ut_asserteq(3, utf16_utf8_strnlen(c1, 3));
484         ut_asserteq(6, utf16_utf8_strnlen(c1, 13));
485         ut_asserteq(7, utf16_utf8_strnlen(c2, 6));
486         ut_asserteq(6, utf16_utf8_strnlen(c3, 2));
487         ut_asserteq(8, utf16_utf8_strnlen(c4, 2));
488         ut_asserteq(12, utf16_utf8_strnlen(c4, 3));
489         return 0;
490 }
491 UNICODE_TEST(unicode_test_utf16_utf8_strnlen);
492
493 static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts)
494 {
495         char buf[16];
496         char *pos;
497
498         pos = buf;
499         utf16_utf8_strcpy(&pos, c1);
500         ut_asserteq(6, pos - buf);
501         ut_asserteq_str(d1, buf);
502
503         pos = buf;
504         utf16_utf8_strcpy(&pos, c2);
505         ut_asserteq(9, pos - buf);
506         ut_asserteq_str(d2, buf);
507
508         pos = buf;
509         utf16_utf8_strcpy(&pos, c3);
510         ut_asserteq(9, pos - buf);
511         ut_asserteq_str(d3, buf);
512
513         pos = buf;
514         utf16_utf8_strcpy(&pos, c4);
515         ut_asserteq(12, pos - buf);
516         ut_asserteq_str(d4, buf);
517
518         /* Illegal utf-16 strings */
519         pos = buf;
520         utf16_utf8_strcpy(&pos, i1);
521         ut_asserteq(4, pos - buf);
522         ut_asserteq_str("i1?l", buf);
523
524         pos = buf;
525         utf16_utf8_strcpy(&pos, i2);
526         ut_asserteq(4, pos - buf);
527         ut_asserteq_str("i2?l", buf);
528
529         pos = buf;
530         utf16_utf8_strcpy(&pos, i3);
531         ut_asserteq(3, pos - buf);
532         ut_asserteq_str("i3?", buf);
533
534         return 0;
535 }
536 UNICODE_TEST(unicode_test_utf16_utf8_strcpy);
537
538 static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts)
539 {
540         char buf[16];
541         char *pos;
542
543         pos = buf;
544         memset(buf, 0, sizeof(buf));
545         utf16_utf8_strncpy(&pos, c1, 4);
546         ut_asserteq(4, pos - buf);
547         ut_assert(!buf[4]);
548         ut_assert(!strncmp(buf, d1, 4));
549
550         pos = buf;
551         memset(buf, 0, sizeof(buf));
552         utf16_utf8_strncpy(&pos, c2, 10);
553         ut_asserteq(9, pos - buf);
554         ut_assert(buf[4]);
555         ut_assert(!strncmp(buf, d2, SIZE_MAX));
556
557         pos = buf;
558         memset(buf, 0, sizeof(buf));
559         utf16_utf8_strncpy(&pos, c3, 2);
560         ut_asserteq(6, pos - buf);
561         ut_assert(!buf[6]);
562         ut_assert(!strncmp(buf, d3, 6));
563
564         pos = buf;
565         memset(buf, 0, sizeof(buf));
566         utf16_utf8_strncpy(&pos, c4, 2);
567         ut_asserteq(8, pos - buf);
568         ut_assert(!buf[8]);
569         ut_assert(!strncmp(buf, d4, 8));
570
571         pos = buf;
572         memset(buf, 0, sizeof(buf));
573         utf16_utf8_strncpy(&pos, c4, 10);
574         ut_asserteq(12, pos - buf);
575         ut_assert(buf[5]);
576         ut_assert(!strncmp(buf, d4, SIZE_MAX));
577
578         return 0;
579 }
580 UNICODE_TEST(unicode_test_utf16_utf8_strncpy);
581
582 static int unicode_test_utf_to_lower(struct unit_test_state *uts)
583 {
584         ut_asserteq('@', utf_to_lower('@'));
585         ut_asserteq('a', utf_to_lower('A'));
586         ut_asserteq('z', utf_to_lower('Z'));
587         ut_asserteq('[', utf_to_lower('['));
588         ut_asserteq('m', utf_to_lower('m'));
589         /* Latin letter O with diaresis (umlaut) */
590         ut_asserteq(0x00f6, utf_to_lower(0x00d6));
591 #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
592         /* Cyrillic letter I*/
593         ut_asserteq(0x0438, utf_to_lower(0x0418));
594 #endif
595         return 0;
596 }
597 UNICODE_TEST(unicode_test_utf_to_lower);
598
599 static int unicode_test_utf_to_upper(struct unit_test_state *uts)
600 {
601         ut_asserteq('`', utf_to_upper('`'));
602         ut_asserteq('A', utf_to_upper('a'));
603         ut_asserteq('Z', utf_to_upper('z'));
604         ut_asserteq('{', utf_to_upper('{'));
605         ut_asserteq('M', utf_to_upper('M'));
606         /* Latin letter O with diaresis (umlaut) */
607         ut_asserteq(0x00d6, utf_to_upper(0x00f6));
608 #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
609         /* Cyrillic letter I */
610         ut_asserteq(0x0418, utf_to_upper(0x0438));
611 #endif
612         return 0;
613 }
614 UNICODE_TEST(unicode_test_utf_to_upper);
615
616 static int unicode_test_u16_strncmp(struct unit_test_state *uts)
617 {
618         ut_assert(u16_strncmp(u"abc", u"abc", 3) == 0);
619         ut_assert(u16_strncmp(u"abcdef", u"abcghi", 3) == 0);
620         ut_assert(u16_strncmp(u"abcdef", u"abcghi", 6) < 0);
621         ut_assert(u16_strncmp(u"abcghi", u"abcdef", 6) > 0);
622         ut_assert(u16_strcmp(u"abc", u"abc") == 0);
623         ut_assert(u16_strcmp(u"abcdef", u"deghi") < 0);
624         ut_assert(u16_strcmp(u"deghi", u"abcdef") > 0);
625         return 0;
626 }
627 UNICODE_TEST(unicode_test_u16_strncmp);
628
629 static int unicode_test_u16_strsize(struct unit_test_state *uts)
630 {
631         ut_asserteq_64(u16_strsize(c1), 14);
632         ut_asserteq_64(u16_strsize(c2), 18);
633         ut_asserteq_64(u16_strsize(c3), 8);
634         ut_asserteq_64(u16_strsize(c4), 14);
635         return 0;
636 }
637 UNICODE_TEST(unicode_test_u16_strsize);
638
639 static int unicode_test_utf_to_cp(struct unit_test_state *uts)
640 {
641         int ret;
642         s32 c;
643
644         c = '\n';
645         ret = utf_to_cp(&c, codepage_437);
646         ut_asserteq(0, ret);
647         ut_asserteq('\n', c);
648
649         c = 'a';
650         ret = utf_to_cp(&c, codepage_437);
651         ut_asserteq(0, ret);
652         ut_asserteq('a', c);
653
654         c = 0x03c4; /* Greek small letter tau */
655         ret = utf_to_cp(&c, codepage_437);
656         ut_asserteq(0, ret);
657         ut_asserteq(0xe7, c);
658
659         c = 0x03a4; /* Greek capital letter tau */
660         ret = utf_to_cp(&c, codepage_437);
661         ut_asserteq(-ENOENT, ret);
662         ut_asserteq('?', c);
663
664         return 0;
665 }
666 UNICODE_TEST(unicode_test_utf_to_cp);
667
668 static void utf8_to_cp437_stream_helper(const char *in, char *out)
669 {
670         char buffer[5];
671         int ret;
672
673         *buffer = 0;
674         for (; *in; ++in) {
675                 ret = utf8_to_cp437_stream(*in, buffer);
676                 if (ret)
677                         *out++ = ret;
678         }
679         *out = 0;
680 }
681
682 static int unicode_test_utf8_to_cp437_stream(struct unit_test_state *uts)
683 {
684         char buf[16];
685
686         utf8_to_cp437_stream_helper(d1, buf);
687         ut_asserteq_str("U-Boot", buf);
688         utf8_to_cp437_stream_helper(d2, buf);
689         ut_asserteq_str("kafb\xa0tur", buf);
690         utf8_to_cp437_stream_helper(d5, buf);
691         ut_asserteq_str("? is not B", buf);
692         utf8_to_cp437_stream_helper(j2, buf);
693         ut_asserteq_str("j2l", buf);
694
695         return 0;
696 }
697 UNICODE_TEST(unicode_test_utf8_to_cp437_stream);
698
699 static void utf8_to_utf32_stream_helper(const char *in, s32 *out)
700 {
701         char buffer[5];
702         int ret;
703
704         *buffer = 0;
705         for (; *in; ++in) {
706                 ret = utf8_to_utf32_stream(*in, buffer);
707                 if (ret)
708                         *out++ = ret;
709         }
710         *out = 0;
711 }
712
713 static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts)
714 {
715         s32 buf[16];
716
717         const u32 u1[] = {0x55, 0x2D, 0x42, 0x6F, 0x6F, 0x74, 0x0000};
718         const u32 u2[] = {0x6B, 0x61, 0x66, 0x62, 0xE1, 0x74, 0x75, 0x72, 0x00};
719         const u32 u3[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74,
720                           0x20, 0x42, 0x00};
721         const u32 u4[] = {0x6A, 0x32, 0x6C, 0x00};
722
723         memset(buf, 0, sizeof(buf));
724         utf8_to_utf32_stream_helper(d1, buf);
725         ut_asserteq_mem(u1, buf, sizeof(u1));
726
727         memset(buf, 0, sizeof(buf));
728         utf8_to_utf32_stream_helper(d2, buf);
729         ut_asserteq_mem(u2, buf, sizeof(u2));
730
731         memset(buf, 0, sizeof(buf));
732         utf8_to_utf32_stream_helper(d5, buf);
733         ut_asserteq_mem(u3, buf, sizeof(u3));
734
735         memset(buf, 0, sizeof(buf));
736         utf8_to_utf32_stream_helper(j2, buf);
737         ut_asserteq_mem(u4, buf, sizeof(u4));
738
739         return 0;
740 }
741 UNICODE_TEST(unicode_test_utf8_to_utf32_stream);
742
743 #ifdef CONFIG_EFI_LOADER
744 static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts)
745 {
746         u16 buf[16];
747         u16 const expected[] = u"Capsule0AF9";
748         u16 *pos;
749
750         memset(buf, 0xeb, sizeof(buf));
751         pos = efi_create_indexed_name(buf, sizeof(buf), "Capsule", 0x0af9);
752
753         ut_asserteq_mem(expected, buf, sizeof(expected));
754         ut_asserteq(pos - buf, u16_strnlen(buf, SIZE_MAX));
755
756         return 0;
757 }
758 UNICODE_TEST(unicode_test_efi_create_indexed_name);
759 #endif
760
761 static int unicode_test_u16_strlcat(struct unit_test_state *uts)
762 {
763         u16 buf[40];
764         u16 dest[] = {0x3053, 0x3093, 0x306b, 0x3061, 0x306f, 0};
765         u16 src[] = {0x03B1, 0x2172, 0x6F5C, 0x8247, 0};
766         u16 concat_str[] = {0x3053, 0x3093, 0x306b, 0x3061, 0x306f,
767                             0x03B1, 0x2172, 0x6F5C, 0x8247, 0};
768         u16 null_src = u'\0';
769         size_t ret, expected;
770         int i;
771
772         /* dest and src are empty string */
773         memset(buf, 0, sizeof(buf));
774         ret = u16_strlcat(buf, &null_src, sizeof(buf));
775         ut_asserteq(1, ret);
776
777         /* dest is empty string */
778         memset(buf, 0, sizeof(buf));
779         ret = u16_strlcat(buf, src, sizeof(buf));
780         ut_asserteq(5, ret);
781         ut_assert(!unicode_test_u16_strcmp(buf, src, 40));
782
783         /* src is empty string */
784         memset(buf, 0xCD, (sizeof(buf) - sizeof(u16)));
785         buf[39] = 0;
786         memcpy(buf, dest, sizeof(dest));
787         ret = u16_strlcat(buf, &null_src, sizeof(buf));
788         ut_asserteq(6, ret);
789         ut_assert(!unicode_test_u16_strcmp(buf, dest, 40));
790
791         for (i = 0; i <= 40; i++) {
792                 memset(buf, 0xCD, (sizeof(buf) - sizeof(u16)));
793                 buf[39] = 0;
794                 memcpy(buf, dest, sizeof(dest));
795                 expected = 10;
796                 ret = u16_strlcat(buf, src, i);
797                 ut_asserteq(expected, ret);
798                 if (i <= 6) {
799                         ut_assert(!unicode_test_u16_strcmp(buf, dest, 40));
800                 } else if (i < 10) {
801                         ut_assert(!unicode_test_u16_strcmp(buf, concat_str, i - 1));
802                 } else {
803                         ut_assert(!unicode_test_u16_strcmp(buf, concat_str, 40));
804                 }
805         }
806
807         return 0;
808 }
809 UNICODE_TEST(unicode_test_u16_strlcat);
810
811 int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
812 {
813         struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test);
814         const int n_ents = UNIT_TEST_SUITE_COUNT(unicode_test);
815
816         return cmd_ut_category("Unicode", "unicode_test_",
817                                tests, n_ents, argc, argv);
818 }