bidirectional.c - libgrapheme - unicode string library
(HTM) git clone git://git.suckless.org/libgrapheme
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
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 }