bidirectional.c (3630B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <inttypes.h> 3 #include <stdbool.h> 4 #include <stdint.h> 5 #include <stdio.h> 6 7 #include "../gen/bidirectional-test.h" 8 #include "../gen/bidirectional.h" 9 #include "../gen/types.h" 10 #include "../grapheme.h" 11 #include "util.h" 12 13 static inline int_least16_t 14 get_mirror_offset(uint_least32_t cp) 15 { 16 if (cp <= UINT32_C(0x10FFFF)) { 17 return mirror_minor[mirror_major[cp >> 8] + (cp & 0xFF)]; 18 } else { 19 return 0; 20 } 21 } 22 23 int 24 main(int argc, char *argv[]) 25 { 26 enum grapheme_bidirectional_direction resolved; 27 uint_least32_t data[512], output[512], 28 target; /* TODO iterate and get max, allocate */ 29 int_least8_t lev[512]; 30 size_t i, num_tests, failed, datalen, levlen, outputlen, ret, j, m, 31 ret2; 32 33 datalen = LEN(data); 34 levlen = LEN(lev); 35 outputlen = LEN(output); 36 37 (void)argc; 38 39 for (i = 0, num_tests = 0; i < LEN(bidirectional_test); i++) { 40 num_tests += bidirectional_test[i].modelen; 41 } 42 43 for (i = 0, failed = 0; i < LEN(bidirectional_test); i++) { 44 for (m = 0; m < bidirectional_test[i].modelen; m++) { 45 ret = grapheme_bidirectional_preprocess_paragraph( 46 bidirectional_test[i].cp, 47 bidirectional_test[i].cplen, 48 bidirectional_test[i].mode[m], data, datalen, 49 &resolved); 50 ret2 = 0; 51 52 if (ret != bidirectional_test[i].cplen || 53 ret > datalen) { 54 goto err; 55 } 56 57 /* resolved paragraph level (if specified in the test) 58 */ 59 if (bidirectional_test[i].resolved != 60 GRAPHEME_BIDIRECTIONAL_DIRECTION_NEUTRAL && 61 resolved != bidirectional_test[i].resolved) { 62 goto err; 63 } 64 65 /* line levels */ 66 ret = grapheme_bidirectional_get_line_embedding_levels( 67 data, ret, lev, levlen); 68 69 if (ret > levlen) { 70 goto err; 71 } 72 73 for (j = 0; j < ret; j++) { 74 if (lev[j] != bidirectional_test[i].level[j]) { 75 goto err; 76 } 77 } 78 79 /* reordering */ 80 ret2 = grapheme_bidirectional_reorder_line( 81 bidirectional_test[i].cp, data, ret, output, 82 outputlen); 83 84 if (ret2 != bidirectional_test[i].reorderlen) { 85 goto err; 86 } 87 88 for (j = 0; j < ret2; j++) { 89 target = bidirectional_test[i] 90 .cp[bidirectional_test[i] 91 .reorder[j]]; 92 if (output[j] != 93 (uint_least32_t)((int_least32_t)target + 94 get_mirror_offset( 95 target))) { 96 goto err; 97 } 98 } 99 100 continue; 101 err: 102 fprintf(stderr, 103 "%s: Failed conformance test %zu (mode %i) [", 104 argv[0], i, bidirectional_test[i].mode[m]); 105 for (j = 0; j < bidirectional_test[i].cplen; j++) { 106 fprintf(stderr, " 0x%04" PRIXLEAST32, 107 bidirectional_test[i].cp[j]); 108 } 109 fprintf(stderr, " ],\n\tlevels: got ("); 110 for (j = 0; j < ret; j++) { 111 fprintf(stderr, " %" PRIdLEAST8, 112 (int_least8_t)lev[j]); 113 } 114 fprintf(stderr, " ),\n\tlevels: expected ("); 115 for (j = 0; j < ret; j++) { 116 fprintf(stderr, " %" PRIdLEAST8, 117 bidirectional_test[i].level[j]); 118 } 119 fprintf(stderr, " ).\n"); 120 121 fprintf(stderr, "\treordering: got ("); 122 for (j = 0; j < ret2; j++) { 123 fprintf(stderr, " 0x%04" PRIxLEAST32, 124 output[j]); 125 } 126 fprintf(stderr, " ),\n\treordering: expected ("); 127 for (j = 0; j < bidirectional_test[i].reorderlen; j++) { 128 fprintf(stderr, " 0x%04" PRIxLEAST32, 129 bidirectional_test[i] 130 .cp[bidirectional_test[i] 131 .reorder[j]]); 132 } 133 fprintf(stderr, " ).\n"); 134 135 failed++; 136 } 137 } 138 printf("%s: %zu/%zu conformance tests passed.\n", argv[0], 139 num_tests - failed, num_tests); 140 141 return 0; 142 }