1 3448adb0 2022-11-02 op /* See LICENSE file for copyright and license details. */
2 3448adb0 2022-11-02 op #include <stdbool.h>
3 3448adb0 2022-11-02 op #include <stdint.h>
4 3448adb0 2022-11-02 op #include <stdio.h>
5 3448adb0 2022-11-02 op #include <string.h>
7 3448adb0 2022-11-02 op #include "../grapheme.h"
8 3448adb0 2022-11-02 op #include "util.h"
10 3448adb0 2022-11-02 op struct unit_test_is_case_utf8 {
11 3448adb0 2022-11-02 op const char *description;
13 3448adb0 2022-11-02 op const char *src;
14 3448adb0 2022-11-02 op size_t srclen;
18 3448adb0 2022-11-02 op size_t caselen;
22 3448adb0 2022-11-02 op struct unit_test_to_case_utf8 {
23 3448adb0 2022-11-02 op const char *description;
25 3448adb0 2022-11-02 op const char *src;
26 3448adb0 2022-11-02 op size_t srclen;
27 3448adb0 2022-11-02 op size_t destlen;
30 3448adb0 2022-11-02 op const char *dest;
35 3448adb0 2022-11-02 op static const struct unit_test_is_case_utf8 is_lowercase_utf8[] = {
37 3448adb0 2022-11-02 op .description = "empty input",
38 3448adb0 2022-11-02 op .input = { "", 0 },
39 3448adb0 2022-11-02 op .output = { true, 0 },
42 3448adb0 2022-11-02 op .description = "one character, violation",
43 3448adb0 2022-11-02 op .input = { "A", 1 },
44 3448adb0 2022-11-02 op .output = { false, 0 },
47 3448adb0 2022-11-02 op .description = "one character, confirmation",
48 3448adb0 2022-11-02 op .input = { "\xC3\x9F", 2 },
49 3448adb0 2022-11-02 op .output = { true, 2 },
52 3448adb0 2022-11-02 op .description = "one character, violation, NUL-terminated",
53 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX },
54 3448adb0 2022-11-02 op .output = { false, 0 },
57 3448adb0 2022-11-02 op .description = "one character, confirmation, NUL-terminated",
58 3448adb0 2022-11-02 op .input = { "\xC3\x9F", SIZE_MAX },
59 3448adb0 2022-11-02 op .output = { true, 2 },
62 3448adb0 2022-11-02 op .description = "one word, violation",
63 3448adb0 2022-11-02 op .input = { "Hello", 5 },
64 3448adb0 2022-11-02 op .output = { false, 0 },
67 3448adb0 2022-11-02 op .description = "one word, partial confirmation",
68 3448adb0 2022-11-02 op .input = { "gru" "\xC3\x9F" "fOrmel", 11 },
69 3448adb0 2022-11-02 op .output = { false, 6 },
72 3448adb0 2022-11-02 op .description = "one word, full confirmation",
73 3448adb0 2022-11-02 op .input = { "gru" "\xC3\x9F" "formel", 11 },
74 3448adb0 2022-11-02 op .output = { true, 11 },
77 3448adb0 2022-11-02 op .description = "one word, violation, NUL-terminated",
78 3448adb0 2022-11-02 op .input = { "Hello", SIZE_MAX },
79 3448adb0 2022-11-02 op .output = { false, 0 },
82 3448adb0 2022-11-02 op .description = "one word, partial confirmation, NUL-terminated",
83 3448adb0 2022-11-02 op .input = { "gru" "\xC3\x9F" "fOrmel", SIZE_MAX },
84 3448adb0 2022-11-02 op .output = { false, 6 },
87 3448adb0 2022-11-02 op .description = "one word, full confirmation, NUL-terminated",
88 3448adb0 2022-11-02 op .input = { "gru" "\xC3\x9F" "formel", SIZE_MAX },
89 3448adb0 2022-11-02 op .output = { true, 11 },
93 3448adb0 2022-11-02 op static const struct unit_test_is_case_utf8 is_uppercase_utf8[] = {
95 3448adb0 2022-11-02 op .description = "empty input",
96 3448adb0 2022-11-02 op .input = { "", 0 },
97 3448adb0 2022-11-02 op .output = { true, 0 },
100 3448adb0 2022-11-02 op .description = "one character, violation",
101 3448adb0 2022-11-02 op .input = { "\xC3\x9F", 2 },
102 3448adb0 2022-11-02 op .output = { false, 0 },
105 3448adb0 2022-11-02 op .description = "one character, confirmation",
106 3448adb0 2022-11-02 op .input = { "A", 1 },
107 3448adb0 2022-11-02 op .output = { true, 1 },
110 3448adb0 2022-11-02 op .description = "one character, violation, NUL-terminated",
111 3448adb0 2022-11-02 op .input = { "\xC3\x9F", SIZE_MAX },
112 3448adb0 2022-11-02 op .output = { false, 0 },
115 3448adb0 2022-11-02 op .description = "one character, confirmation, NUL-terminated",
116 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX },
117 3448adb0 2022-11-02 op .output = { true, 1 },
120 3448adb0 2022-11-02 op .description = "one word, violation",
121 3448adb0 2022-11-02 op .input = { "hello", 5 },
122 3448adb0 2022-11-02 op .output = { false, 0 },
125 3448adb0 2022-11-02 op .description = "one word, partial confirmation",
126 3448adb0 2022-11-02 op .input = { "GRU" "\xC3\x9F" "formel", 11 },
127 3448adb0 2022-11-02 op .output = { false, 3 },
130 3448adb0 2022-11-02 op .description = "one word, full confirmation",
131 3448adb0 2022-11-02 op .input = { "HELLO", 5 },
132 3448adb0 2022-11-02 op .output = { true, 5 },
135 3448adb0 2022-11-02 op .description = "one word, violation, NUL-terminated",
136 3448adb0 2022-11-02 op .input = { "hello", SIZE_MAX },
137 3448adb0 2022-11-02 op .output = { false, 0 },
140 3448adb0 2022-11-02 op .description = "one word, partial confirmation, NUL-terminated",
141 3448adb0 2022-11-02 op .input = { "GRU" "\xC3\x9F" "formel", SIZE_MAX },
142 3448adb0 2022-11-02 op .output = { false, 3 },
145 3448adb0 2022-11-02 op .description = "one word, full confirmation, NUL-terminated",
146 3448adb0 2022-11-02 op .input = { "HELLO", SIZE_MAX },
147 3448adb0 2022-11-02 op .output = { true, 5 },
151 3448adb0 2022-11-02 op static const struct unit_test_is_case_utf8 is_titlecase_utf8[] = {
153 3448adb0 2022-11-02 op .description = "empty input",
154 3448adb0 2022-11-02 op .input = { "", 0 },
155 3448adb0 2022-11-02 op .output = { true, 0 },
158 3448adb0 2022-11-02 op .description = "one character, violation",
159 3448adb0 2022-11-02 op .input = { "\xC3\x9F", 2 },
160 3448adb0 2022-11-02 op .output = { false, 0 },
163 3448adb0 2022-11-02 op .description = "one character, confirmation",
164 3448adb0 2022-11-02 op .input = { "A", 1 },
165 3448adb0 2022-11-02 op .output = { true, 1 },
168 3448adb0 2022-11-02 op .description = "one character, violation, NUL-terminated",
169 3448adb0 2022-11-02 op .input = { "\xC3\x9F", SIZE_MAX },
170 3448adb0 2022-11-02 op .output = { false, 0 },
173 3448adb0 2022-11-02 op .description = "one character, confirmation, NUL-terminated",
174 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX },
175 3448adb0 2022-11-02 op .output = { true, 1 },
178 3448adb0 2022-11-02 op .description = "one word, violation",
179 3448adb0 2022-11-02 op .input = { "hello", 5 },
180 3448adb0 2022-11-02 op .output = { false, 0 },
183 3448adb0 2022-11-02 op .description = "one word, partial confirmation",
184 3448adb0 2022-11-02 op .input = { "Gru" "\xC3\x9F" "fOrmel", 11 },
185 3448adb0 2022-11-02 op .output = { false, 6 },
188 3448adb0 2022-11-02 op .description = "one word, full confirmation",
189 3448adb0 2022-11-02 op .input = { "Gru" "\xC3\x9F" "formel", 11 },
190 3448adb0 2022-11-02 op .output = { true, 11 },
193 3448adb0 2022-11-02 op .description = "one word, violation, NUL-terminated",
194 3448adb0 2022-11-02 op .input = { "hello", SIZE_MAX },
195 3448adb0 2022-11-02 op .output = { false, 0 },
198 3448adb0 2022-11-02 op .description = "one word, partial confirmation, NUL-terminated",
199 3448adb0 2022-11-02 op .input = { "Gru" "\xC3\x9F" "fOrmel", SIZE_MAX },
200 3448adb0 2022-11-02 op .output = { false, 6 },
203 3448adb0 2022-11-02 op .description = "one word, full confirmation, NUL-terminated",
204 3448adb0 2022-11-02 op .input = { "Gru" "\xC3\x9F" "formel", SIZE_MAX },
205 3448adb0 2022-11-02 op .output = { true, 11 },
208 3448adb0 2022-11-02 op .description = "multiple words, partial confirmation",
209 3448adb0 2022-11-02 op .input = { "Hello Gru" "\xC3\x9F" "fOrmel!", 18 },
210 3448adb0 2022-11-02 op .output = { false, 12 },
213 3448adb0 2022-11-02 op .description = "multiple words, full confirmation",
214 3448adb0 2022-11-02 op .input = { "Hello Gru" "\xC3\x9F" "formel!", 18 },
215 3448adb0 2022-11-02 op .output = { true, 18 },
218 3448adb0 2022-11-02 op .description = "multiple words, partial confirmation, NUL-terminated",
219 3448adb0 2022-11-02 op .input = { "Hello Gru" "\xC3\x9F" "fOrmel!", SIZE_MAX },
220 3448adb0 2022-11-02 op .output = { false, 12 },
223 3448adb0 2022-11-02 op .description = "multiple words, full confirmation, NUL-terminated",
224 3448adb0 2022-11-02 op .input = { "Hello Gru" "\xC3\x9F" "formel!", SIZE_MAX },
225 3448adb0 2022-11-02 op .output = { true, 18 },
229 3448adb0 2022-11-02 op static const struct unit_test_to_case_utf8 to_lowercase_utf8[] = {
231 3448adb0 2022-11-02 op .description = "empty input",
232 3448adb0 2022-11-02 op .input = { "", 0, 10 },
233 3448adb0 2022-11-02 op .output = { "", 0 },
236 3448adb0 2022-11-02 op .description = "empty output",
237 3448adb0 2022-11-02 op .input = { "hello", 5, 0 },
238 3448adb0 2022-11-02 op .output = { "", 5 },
241 3448adb0 2022-11-02 op .description = "one character, conversion",
242 3448adb0 2022-11-02 op .input = { "A", 1, 10 },
243 3448adb0 2022-11-02 op .output = { "a", 1 },
246 3448adb0 2022-11-02 op .description = "one character, no conversion",
247 3448adb0 2022-11-02 op .input = { "\xC3\x9F", 2, 10 },
248 3448adb0 2022-11-02 op .output = { "\xC3\x9F", 2 },
251 3448adb0 2022-11-02 op .description = "one character, conversion, truncation",
252 3448adb0 2022-11-02 op .input = { "A", 1, 0 },
253 3448adb0 2022-11-02 op .output = { "", 1 },
256 3448adb0 2022-11-02 op .description = "one character, conversion, NUL-terminated",
257 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX, 10 },
258 3448adb0 2022-11-02 op .output = { "a", 1 },
261 3448adb0 2022-11-02 op .description = "one character, no conversion, NUL-terminated",
262 3448adb0 2022-11-02 op .input = { "\xC3\x9F", SIZE_MAX, 10 },
263 3448adb0 2022-11-02 op .output = { "\xC3\x9F", 2 },
266 3448adb0 2022-11-02 op .description = "one character, conversion, NUL-terminated, truncation",
267 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX, 0 },
268 3448adb0 2022-11-02 op .output = { "", 1 },
271 3448adb0 2022-11-02 op .description = "one word, conversion",
272 3448adb0 2022-11-02 op .input = { "wOrD", 4, 10 },
273 3448adb0 2022-11-02 op .output = { "word", 4 },
276 3448adb0 2022-11-02 op .description = "one word, no conversion",
277 3448adb0 2022-11-02 op .input = { "word", 4, 10 },
278 3448adb0 2022-11-02 op .output = { "word", 4 },
281 3448adb0 2022-11-02 op .description = "one word, conversion, truncation",
282 3448adb0 2022-11-02 op .input = { "wOrD", 4, 3 },
283 3448adb0 2022-11-02 op .output = { "wo", 4 },
286 3448adb0 2022-11-02 op .description = "one word, conversion, NUL-terminated",
287 3448adb0 2022-11-02 op .input = { "wOrD", SIZE_MAX, 10 },
288 3448adb0 2022-11-02 op .output = { "word", 4 },
291 3448adb0 2022-11-02 op .description = "one word, no conversion, NUL-terminated",
292 3448adb0 2022-11-02 op .input = { "word", SIZE_MAX, 10 },
293 3448adb0 2022-11-02 op .output = { "word", 4 },
296 3448adb0 2022-11-02 op .description = "one word, conversion, NUL-terminated, truncation",
297 3448adb0 2022-11-02 op .input = { "wOrD", SIZE_MAX, 3 },
298 3448adb0 2022-11-02 op .output = { "wo", 4 },
302 3448adb0 2022-11-02 op static const struct unit_test_to_case_utf8 to_uppercase_utf8[] = {
304 3448adb0 2022-11-02 op .description = "empty input",
305 3448adb0 2022-11-02 op .input = { "", 0, 10 },
306 3448adb0 2022-11-02 op .output = { "", 0 },
309 3448adb0 2022-11-02 op .description = "empty output",
310 3448adb0 2022-11-02 op .input = { "hello", 5, 0 },
311 3448adb0 2022-11-02 op .output = { "", 5 },
314 3448adb0 2022-11-02 op .description = "one character, conversion",
315 3448adb0 2022-11-02 op .input = { "\xC3\x9F", 2, 10 },
316 3448adb0 2022-11-02 op .output = { "SS", 2 },
319 3448adb0 2022-11-02 op .description = "one character, no conversion",
320 3448adb0 2022-11-02 op .input = { "A", 1, 10 },
321 3448adb0 2022-11-02 op .output = { "A", 1 },
324 3448adb0 2022-11-02 op .description = "one character, conversion, truncation",
325 3448adb0 2022-11-02 op .input = { "\xC3\x9F", 2, 0 },
326 3448adb0 2022-11-02 op .output = { "", 2 },
329 3448adb0 2022-11-02 op .description = "one character, conversion, NUL-terminated",
330 3448adb0 2022-11-02 op .input = { "\xC3\x9F", SIZE_MAX, 10 },
331 3448adb0 2022-11-02 op .output = { "SS", 2 },
334 3448adb0 2022-11-02 op .description = "one character, no conversion, NUL-terminated",
335 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX, 10 },
336 3448adb0 2022-11-02 op .output = { "A", 1 },
339 3448adb0 2022-11-02 op .description = "one character, conversion, NUL-terminated, truncation",
340 3448adb0 2022-11-02 op .input = { "\xC3\x9F", SIZE_MAX, 0 },
341 3448adb0 2022-11-02 op .output = { "", 2 },
344 3448adb0 2022-11-02 op .description = "one word, conversion",
345 3448adb0 2022-11-02 op .input = { "gRu" "\xC3\x9F" "fOrMel", 11, 15 },
346 3448adb0 2022-11-02 op .output = { "GRUSSFORMEL", 11 },
349 3448adb0 2022-11-02 op .description = "one word, no conversion",
350 3448adb0 2022-11-02 op .input = { "WORD", 4, 10 },
351 3448adb0 2022-11-02 op .output = { "WORD", 4 },
354 3448adb0 2022-11-02 op .description = "one word, conversion, truncation",
355 3448adb0 2022-11-02 op .input = { "gRu" "\xC3\x9F" "formel", 11, 5 },
356 3448adb0 2022-11-02 op .output = { "GRUS", 11 },
359 3448adb0 2022-11-02 op .description = "one word, conversion, NUL-terminated",
360 3448adb0 2022-11-02 op .input = { "gRu" "\xC3\x9F" "formel", SIZE_MAX, 15 },
361 3448adb0 2022-11-02 op .output = { "GRUSSFORMEL", 11 },
364 3448adb0 2022-11-02 op .description = "one word, no conversion, NUL-terminated",
365 3448adb0 2022-11-02 op .input = { "WORD", SIZE_MAX, 10 },
366 3448adb0 2022-11-02 op .output = { "WORD", 4 },
369 3448adb0 2022-11-02 op .description = "one word, conversion, NUL-terminated, truncation",
370 3448adb0 2022-11-02 op .input = { "gRu" "\xC3\x9F" "formel", SIZE_MAX, 5 },
371 3448adb0 2022-11-02 op .output = { "GRUS", 11 },
375 3448adb0 2022-11-02 op static const struct unit_test_to_case_utf8 to_titlecase_utf8[] = {
377 3448adb0 2022-11-02 op .description = "empty input",
378 3448adb0 2022-11-02 op .input = { "", 0, 10 },
379 3448adb0 2022-11-02 op .output = { "", 0 },
382 3448adb0 2022-11-02 op .description = "empty output",
383 3448adb0 2022-11-02 op .input = { "hello", 5, 0 },
384 3448adb0 2022-11-02 op .output = { "", 5 },
387 3448adb0 2022-11-02 op .description = "one character, conversion",
388 3448adb0 2022-11-02 op .input = { "a", 1, 10 },
389 3448adb0 2022-11-02 op .output = { "A", 1 },
392 3448adb0 2022-11-02 op .description = "one character, no conversion",
393 3448adb0 2022-11-02 op .input = { "A", 1, 10 },
394 3448adb0 2022-11-02 op .output = { "A", 1 },
397 3448adb0 2022-11-02 op .description = "one character, conversion, truncation",
398 3448adb0 2022-11-02 op .input = { "a", 1, 0 },
399 3448adb0 2022-11-02 op .output = { "", 1 },
402 3448adb0 2022-11-02 op .description = "one character, conversion, NUL-terminated",
403 3448adb0 2022-11-02 op .input = { "a", SIZE_MAX, 10 },
404 3448adb0 2022-11-02 op .output = { "A", 1 },
407 3448adb0 2022-11-02 op .description = "one character, no conversion, NUL-terminated",
408 3448adb0 2022-11-02 op .input = { "A", SIZE_MAX, 10 },
409 3448adb0 2022-11-02 op .output = { "A", 1 },
412 3448adb0 2022-11-02 op .description = "one character, conversion, NUL-terminated, truncation",
413 3448adb0 2022-11-02 op .input = { "a", SIZE_MAX, 0 },
414 3448adb0 2022-11-02 op .output = { "", 1 },
417 3448adb0 2022-11-02 op .description = "one word, conversion",
418 3448adb0 2022-11-02 op .input = { "heLlo", 5, 10 },
419 3448adb0 2022-11-02 op .output = { "Hello", 5 },
422 3448adb0 2022-11-02 op .description = "one word, no conversion",
423 3448adb0 2022-11-02 op .input = { "Hello", 5, 10 },
424 3448adb0 2022-11-02 op .output = { "Hello", 5 },
427 3448adb0 2022-11-02 op .description = "one word, conversion, truncation",
428 3448adb0 2022-11-02 op .input = { "heLlo", 5, 2 },
429 3448adb0 2022-11-02 op .output = { "H", 5 },
432 3448adb0 2022-11-02 op .description = "one word, conversion, NUL-terminated",
433 3448adb0 2022-11-02 op .input = { "heLlo", SIZE_MAX, 10 },
434 3448adb0 2022-11-02 op .output = { "Hello", 5 },
437 3448adb0 2022-11-02 op .description = "one word, no conversion, NUL-terminated",
438 3448adb0 2022-11-02 op .input = { "Hello", SIZE_MAX, 10 },
439 3448adb0 2022-11-02 op .output = { "Hello", 5 },
442 3448adb0 2022-11-02 op .description = "one word, conversion, NUL-terminated, truncation",
443 3448adb0 2022-11-02 op .input = { "heLlo", SIZE_MAX, 3 },
444 3448adb0 2022-11-02 op .output = { "He", 5 },
447 3448adb0 2022-11-02 op .description = "two words, conversion",
448 3448adb0 2022-11-02 op .input = { "heLlo wORLd!", 12, 20 },
449 3448adb0 2022-11-02 op .output = { "Hello World!", 12 },
452 3448adb0 2022-11-02 op .description = "two words, no conversion",
453 3448adb0 2022-11-02 op .input = { "Hello World!", 12, 20 },
454 3448adb0 2022-11-02 op .output = { "Hello World!", 12 },
457 3448adb0 2022-11-02 op .description = "two words, conversion, truncation",
458 3448adb0 2022-11-02 op .input = { "heLlo wORLd!", 12, 8 },
459 3448adb0 2022-11-02 op .output = { "Hello W", 12 },
462 3448adb0 2022-11-02 op .description = "two words, conversion, NUL-terminated",
463 3448adb0 2022-11-02 op .input = { "heLlo wORLd!", SIZE_MAX, 20 },
464 3448adb0 2022-11-02 op .output = { "Hello World!", 12 },
467 3448adb0 2022-11-02 op .description = "two words, no conversion, NUL-terminated",
468 3448adb0 2022-11-02 op .input = { "Hello World!", SIZE_MAX, 20 },
469 3448adb0 2022-11-02 op .output = { "Hello World!", 12 },
472 3448adb0 2022-11-02 op .description = "two words, conversion, NUL-terminated, truncation",
473 3448adb0 2022-11-02 op .input = { "heLlo wORLd!", SIZE_MAX, 4 },
474 3448adb0 2022-11-02 op .output = { "Hel", 12 },
479 3448adb0 2022-11-02 op unit_test_callback_is_case_utf8(const void *t, size_t off, const char *name,
480 3448adb0 2022-11-02 op const char *argv0)
482 3448adb0 2022-11-02 op const struct unit_test_is_case_utf8 *test =
483 3448adb0 2022-11-02 op (const struct unit_test_is_case_utf8 *)t + off;
484 3448adb0 2022-11-02 op bool ret = false;
485 3448adb0 2022-11-02 op size_t caselen = 0x7f;
487 3448adb0 2022-11-02 op if (t == is_lowercase_utf8) {
488 3448adb0 2022-11-02 op ret = grapheme_is_lowercase_utf8(test->input.src, test->input.srclen,
490 3448adb0 2022-11-02 op } else if (t == is_uppercase_utf8) {
491 3448adb0 2022-11-02 op ret = grapheme_is_uppercase_utf8(test->input.src, test->input.srclen,
493 3448adb0 2022-11-02 op } else if (t == is_titlecase_utf8) {
494 3448adb0 2022-11-02 op ret = grapheme_is_titlecase_utf8(test->input.src, test->input.srclen,
501 3448adb0 2022-11-02 op /* check results */
502 3448adb0 2022-11-02 op if (ret != test->output.ret || caselen != test->output.caselen) {
508 3448adb0 2022-11-02 op fprintf(stderr, "%s: %s: Failed unit test %zu \"%s\" "
509 3448adb0 2022-11-02 op "(returned (%s, %zu) instead of (%s, %zu)).\n", argv0,
510 3448adb0 2022-11-02 op name, off, test->description, ret ? "true" : "false",
511 3448adb0 2022-11-02 op caselen, test->output.ret ? "true" : "false",
512 3448adb0 2022-11-02 op test->output.caselen);
517 3448adb0 2022-11-02 op unit_test_callback_to_case_utf8(const void *t, size_t off, const char *name,
518 3448adb0 2022-11-02 op const char *argv0)
520 3448adb0 2022-11-02 op const struct unit_test_to_case_utf8 *test =
521 3448adb0 2022-11-02 op (const struct unit_test_to_case_utf8 *)t + off;
522 3448adb0 2022-11-02 op size_t ret = 0, i;
523 3448adb0 2022-11-02 op char buf[512];
525 3448adb0 2022-11-02 op /* fill the array with canary values */
526 3448adb0 2022-11-02 op memset(buf, 0x7f, LEN(buf));
528 3448adb0 2022-11-02 op if (t == to_lowercase_utf8) {
529 3448adb0 2022-11-02 op ret = grapheme_to_lowercase_utf8(test->input.src, test->input.srclen,
530 3448adb0 2022-11-02 op buf, test->input.destlen);
531 3448adb0 2022-11-02 op } else if (t == to_uppercase_utf8) {
532 3448adb0 2022-11-02 op ret = grapheme_to_uppercase_utf8(test->input.src, test->input.srclen,
533 3448adb0 2022-11-02 op buf, test->input.destlen);
534 3448adb0 2022-11-02 op } else if (t == to_titlecase_utf8) {
535 3448adb0 2022-11-02 op ret = grapheme_to_titlecase_utf8(test->input.src, test->input.srclen,
536 3448adb0 2022-11-02 op buf, test->input.destlen);
541 3448adb0 2022-11-02 op /* check results */
542 3448adb0 2022-11-02 op if (ret != test->output.ret ||
543 3448adb0 2022-11-02 op memcmp(buf, test->output.dest, MIN(test->input.destlen, test->output.ret))) {
547 3448adb0 2022-11-02 op /* check that none of the canary values have been overwritten */
548 3448adb0 2022-11-02 op for (i = test->input.destlen; i < LEN(buf); i++) {
549 3448adb0 2022-11-02 op if (buf[i] != 0x7f) {
556 3448adb0 2022-11-02 op fprintf(stderr, "%s: %s: Failed unit test %zu \"%s\" "
557 3448adb0 2022-11-02 op "(returned (\"%.*s\", %zu) instead of (\"%.*s\", %zu)).\n", argv0,
558 3448adb0 2022-11-02 op name, off, test->description, (int)ret, buf, ret,
559 3448adb0 2022-11-02 op (int)test->output.ret, test->output.dest, test->output.ret);
564 3448adb0 2022-11-02 op main(int argc, char *argv[])
568 3448adb0 2022-11-02 op return run_unit_tests(unit_test_callback_is_case_utf8, is_lowercase_utf8,
569 3448adb0 2022-11-02 op LEN(is_lowercase_utf8), "grapheme_is_lowercase_utf8", argv[0]) +
570 3448adb0 2022-11-02 op run_unit_tests(unit_test_callback_is_case_utf8, is_uppercase_utf8,
571 3448adb0 2022-11-02 op LEN(is_uppercase_utf8), "grapheme_is_uppercase_utf8", argv[0]) +
572 3448adb0 2022-11-02 op run_unit_tests(unit_test_callback_is_case_utf8, is_titlecase_utf8,
573 3448adb0 2022-11-02 op LEN(is_titlecase_utf8), "grapheme_is_titlecase_utf8", argv[0]) +
574 3448adb0 2022-11-02 op run_unit_tests(unit_test_callback_to_case_utf8, to_lowercase_utf8,
575 3448adb0 2022-11-02 op LEN(to_lowercase_utf8), "grapheme_to_lowercase_utf8", argv[0]) +
576 3448adb0 2022-11-02 op run_unit_tests(unit_test_callback_to_case_utf8, to_uppercase_utf8,
577 3448adb0 2022-11-02 op LEN(to_uppercase_utf8), "grapheme_to_uppercase_utf8", argv[0]) +
578 3448adb0 2022-11-02 op run_unit_tests(unit_test_callback_to_case_utf8, to_titlecase_utf8,
579 3448adb0 2022-11-02 op LEN(to_titlecase_utf8), "grapheme_to_titlecase_utf8", argv[0]);