utf8-encode.c (2262B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <stddef.h> 3 #include <stdint.h> 4 #include <stdio.h> 5 #include <string.h> 6 7 #include "../grapheme.h" 8 #include "util.h" 9 10 static const struct { 11 uint_least32_t cp; /* input codepoint */ 12 char *exp_arr; /* expected UTF-8 byte sequence */ 13 size_t exp_len; /* expected length of UTF-8 sequence */ 14 } enc_test[] = { 15 { 16 /* invalid codepoint (UTF-16 surrogate half) */ 17 .cp = UINT32_C(0xD800), 18 .exp_arr = (char *)(unsigned char[]){ 0xEF, 0xBF, 0xBD }, 19 .exp_len = 3, 20 }, 21 { 22 /* invalid codepoint (UTF-16-unrepresentable) */ 23 .cp = UINT32_C(0x110000), 24 .exp_arr = (char *)(unsigned char[]){ 0xEF, 0xBF, 0xBD }, 25 .exp_len = 3, 26 }, 27 { 28 /* codepoint encoded to a 1-byte sequence */ 29 .cp = 0x01, 30 .exp_arr = (char *)(unsigned char[]){ 0x01 }, 31 .exp_len = 1, 32 }, 33 { 34 /* codepoint encoded to a 2-byte sequence */ 35 .cp = 0xFF, 36 .exp_arr = (char *)(unsigned char[]){ 0xC3, 0xBF }, 37 .exp_len = 2, 38 }, 39 { 40 /* codepoint encoded to a 3-byte sequence */ 41 .cp = 0xFFF, 42 .exp_arr = (char *)(unsigned char[]){ 0xE0, 0xBF, 0xBF }, 43 .exp_len = 3, 44 }, 45 { 46 /* codepoint encoded to a 4-byte sequence */ 47 .cp = UINT32_C(0xFFFFF), 48 .exp_arr = (char *)(unsigned char[]){ 0xF3, 0xBF, 0xBF, 0xBF }, 49 .exp_len = 4, 50 }, 51 }; 52 53 int 54 main(int argc, char *argv[]) 55 { 56 size_t i, j, failed; 57 58 (void)argc; 59 60 /* UTF-8 encoder test */ 61 for (i = 0, failed = 0; i < LEN(enc_test); i++) { 62 char arr[4]; 63 size_t len; 64 65 len = grapheme_encode_utf8(enc_test[i].cp, arr, LEN(arr)); 66 67 if (len != enc_test[i].exp_len || 68 memcmp(arr, enc_test[i].exp_arr, len)) { 69 fprintf(stderr, "%s, Failed test %zu: " 70 "Expected (", argv[0], i); 71 for (j = 0; j < enc_test[i].exp_len; j++) { 72 fprintf(stderr, "0x%x", 73 enc_test[i].exp_arr[j]); 74 if (j + 1 < enc_test[i].exp_len) { 75 fprintf(stderr, " "); 76 } 77 } 78 fprintf(stderr, "), but got ("); 79 for (j = 0; j < len; j++) { 80 fprintf(stderr, "0x%x", arr[j]); 81 if (j + 1 < len) { 82 fprintf(stderr, " "); 83 } 84 } 85 fprintf(stderr, ").\n"); 86 failed++; 87 } 88 } 89 printf("%s: %zu/%zu tests passed.\n", argv[0], 90 LEN(enc_test) - failed, LEN(enc_test)); 91 92 return (failed > 0) ? 1 : 0; 93 }