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 }