int main (int argc, char *argv[]) { int exit_val; fribidi_boolean file_found; char *s; FILE *IN; text_width = 80; do_break = FRIBIDI_TRUE; do_pad = FRIBIDI_TRUE; do_mirror = FRIBIDI_TRUE; do_clean = FRIBIDI_FALSE; do_reorder_nsm = FRIBIDI_FALSE; show_input = FRIBIDI_FALSE; show_visual = FRIBIDI_TRUE; show_basedir = FRIBIDI_FALSE; show_ltov = FRIBIDI_FALSE; show_vtol = FRIBIDI_FALSE; show_levels = FRIBIDI_FALSE; show_changes = FRIBIDI_FALSE; char_set = "UTF-8"; bol_text = NULL; eol_text = NULL; input_base_direction = FRIBIDI_TYPE_ON; if ((s = getenv ("COLUMNS"))) { int i; i = atoi (s); if (i > 0) text_width = i; } #define CHARSETDESC 257 #define CAPRTL 258 /* Parse the command line with getopt library */ /* Must set argv[0], getopt uses it to generate error messages */ argv[0] = appname; while (1) { int option_index = 0, c; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"verbose", 0, 0, 'v'}, {"debug", 0, 0, 'd'}, {"test", 0, 0, 't'}, {"charset", 1, 0, 'c'}, #ifndef FRIBIDI_NO_CHARSETS {"charsetdesc", 1, 0, CHARSETDESC}, {"caprtl", 0, 0, CAPRTL}, #endif {"showinput", 0, &show_input, FRIBIDI_TRUE}, {"nopad", 0, &do_pad, FRIBIDI_FALSE}, {"nobreak", 0, &do_break, FRIBIDI_FALSE}, {"width", 1, 0, 'w'}, {"bol", 1, 0, 'B'}, {"eol", 1, 0, 'E'}, {"nomirror", 0, &do_mirror, FRIBIDI_FALSE}, {"reordernsm", 0, &do_reorder_nsm, FRIBIDI_TRUE}, {"clean", 0, &do_clean, FRIBIDI_TRUE}, {"ltr", 0, (int *) &input_base_direction, FRIBIDI_TYPE_L}, {"rtl", 0, (int *) &input_base_direction, FRIBIDI_TYPE_R}, {"wltr", 0, (int *) &input_base_direction, FRIBIDI_TYPE_WL}, {"wrtl", 0, (int *) &input_base_direction, FRIBIDI_TYPE_WR}, {"basedir", 0, &show_basedir, FRIBIDI_TRUE}, {"ltov", 0, &show_ltov, FRIBIDI_TRUE}, {"vtol", 0, &show_vtol, FRIBIDI_TRUE}, {"levels", 0, &show_levels, FRIBIDI_TRUE}, {"changes", 0, &show_changes, FRIBIDI_TRUE}, {"novisual", 0, &show_visual, FRIBIDI_FALSE}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "hVvdtc:w:B:E:", long_options, &option_index); if (c == -1) break; switch (c) { case 0: break; case 'h': help (); break; case 'V': version (); break; case 'v': show_basedir = FRIBIDI_TRUE; show_ltov = FRIBIDI_TRUE; show_vtol = FRIBIDI_TRUE; show_levels = FRIBIDI_TRUE; show_changes = FRIBIDI_TRUE; break; case 'w': text_width = atoi (optarg); if (text_width <= 0) die ("invalid screen width `%s'\n", optarg); break; case 'B': bol_text = optarg; break; case 'E': eol_text = optarg; break; case 'd': if (!fribidi_set_debug (FRIBIDI_TRUE)) die ("%s lib must be compiled with DEBUG option to enable\nturn debug info on.\n", FRIBIDI_PACKAGE); break; case 't': do_clean = FRIBIDI_TRUE; show_input = FRIBIDI_TRUE; do_break = FRIBIDI_FALSE; do_reorder_nsm = FRIBIDI_TRUE; break; case 'c': char_set = strdup (optarg); break; #ifndef FRIBIDI_NO_CHARSETS case CAPRTL: char_set = "CapRTL"; break; case CHARSETDESC: char_set = strdup (optarg); char_set_num = fribidi_parse_charset (char_set); if (!char_set_num) die ("unrecognized character set `%s'\n", char_set); if (!fribidi_char_set_desc (char_set_num)) die ("no description available for character set `%s'\n", fribidi_char_set_name (char_set_num)); else printf ("Descriptions for character set %s:\n" "\n" "%s", fribidi_char_set_title (char_set_num), fribidi_char_set_desc (char_set_num)); exit (0); break; #endif case ':': case '?': die (NULL); break; default: break; } } #ifdef FRIBIDI_NO_CHARSETS to_ucs4 = iconv_open ("WCHAR_T", char_set); from_ucs4 = iconv_open (char_set, "WCHAR_T"); #else char_set_num = fribidi_parse_charset (char_set); #endif #ifdef FRIBIDI_NO_CHARSETS if (to_ucs4 == (iconv_t) (-1) || from_ucs4 == (iconv_t) (-1)) #else if (!char_set_num) #endif die ("unrecognized character set `%s'\n", char_set); fribidi_set_mirroring (do_mirror); fribidi_set_reorder_nsm (do_reorder_nsm); exit_val = 0; file_found = FRIBIDI_FALSE; while (optind < argc || !file_found) { char *S_; S_ = optind < argc ? argv[optind++] : "-"; file_found = FRIBIDI_TRUE; /* Open the infile for reading */ if (S_[0] == '-' && !S_[1]) { IN = stdin; } else { IN = fopen (S_, "r"); if (!IN) { fprintf (stderr, "%s: %s: no such file or directory\n", appname, S_); exit_val = 1; continue; } } /* Read and process input one line at a time */ { char S_[MAX_STR_LEN]; int padding_width, break_width; padding_width = show_input ? (text_width - 10) / 2 : text_width; break_width = do_break ? padding_width : 3 * MAX_STR_LEN; while (fgets (S_, sizeof (S_) - 1, IN)) { char *new_line, *nl_found; FriBidiChar logical[MAX_STR_LEN]; char outstring[MAX_STR_LEN]; FriBidiCharType base; FriBidiStrIndex len; nl_found = ""; S_[sizeof (S_) - 1] = 0; len = strlen (S_); /* chop */ if (S_[len - 1] == '\n') { len--; S_[len] = '\0'; new_line = "\n"; } else new_line = ""; #ifdef FRIBIDI_NO_CHARSETS { char *st = S_, *ust = (char *) logical; int in_len = (int) len; len = sizeof logical; iconv (to_ucs4, &st, &in_len, &ust, (int *) &len); len = (FriBidiChar *) ust - logical; } #else len = fribidi_charset_to_unicode (char_set_num, S_, len, logical); #endif { FriBidiChar *visual; FriBidiStrIndex *ltov, *vtol; FriBidiLevel *levels; FriBidiStrIndex new_len; fribidi_boolean log2vis; visual = show_visual ? ALLOCATE (FriBidiChar, len + 1) : NULL; ltov = show_ltov ? ALLOCATE (FriBidiStrIndex, len + 1) : NULL; vtol = show_vtol ? ALLOCATE (FriBidiStrIndex, len + 1) : NULL; levels = show_levels ? ALLOCATE (FriBidiLevel, len + 1) : NULL; /* Create a bidi string. */ base = input_base_direction; log2vis = fribidi_log2vis (logical, len, &base, /* output */ visual, ltov, vtol, levels); if (log2vis) { if (show_input) printf ("%-*s => ", padding_width, S_); new_len = len; /* Remove explicit marks, if asked for. */ if (do_clean) len = fribidi_remove_bidi_marks (visual, len, ltov, vtol, levels); if (show_visual) { printf (nl_found); if (bol_text) printf ("%s", bol_text); /* Convert it to input charset and print. */ { FriBidiStrIndex idx, st; for (idx = 0; idx < len;) { FriBidiStrIndex wid, inlen; wid = break_width; st = idx; #ifndef FRIBIDI_NO_CHARSETS if (char_set_num != FRIBIDI_CHAR_SET_CAP_RTL) #endif while (wid > 0 && idx < len) wid -= fribidi_wcwidth (visual[idx++]); #ifndef FRIBIDI_NO_CHARSETS else while (wid > 0 && idx < len) { wid--; idx++; } #endif if (wid < 0 && idx > st + 1) idx--; inlen = idx - st; #ifdef FRIBIDI_NO_CHARSETS { char *str = outstring, *ust = (char *) (visual + st); int in_len = inlen * sizeof visual[0]; new_len = sizeof outstring; iconv (from_ucs4, &ust, &in_len, &str, (int *) &new_len); *str = '\0'; new_len = str - outstring; } #else new_len = fribidi_unicode_to_charset (char_set_num, visual + st, inlen, outstring); #endif if (FRIBIDI_IS_RTL (base)) printf ("%*s", (int) (do_pad ? (padding_width + strlen (outstring) - (break_width - wid)) : 0), outstring); else printf ("%s", outstring); if (idx < len) printf ("\n"); } } if (eol_text) printf ("%s", eol_text); nl_found = "\n"; } if (show_basedir) { printf (nl_found); printf ("Base direction: %s", (FRIBIDI_DIR_TO_LEVEL (base) ? "R" : "L")); nl_found = "\n"; } if (show_ltov) { FriBidiStrIndex i; printf (nl_found); for (i = 0; i < len; i++) printf ("%ld ", (long) ltov[i]); nl_found = "\n"; } if (show_vtol) { FriBidiStrIndex i; printf (nl_found); for (i = 0; i < len; i++) printf ("%ld ", (long) vtol[i]); nl_found = "\n"; } if (show_levels) { FriBidiStrIndex i; printf (nl_found); for (i = 0; i < len; i++) printf ("%d ", (int) levels[i]); nl_found = "\n"; } if (show_changes) { FriBidiStrIndex change_start, change_len; fribidi_find_string_changes (logical, len, visual, new_len, &change_start, &change_len); printf ("%sChange start[length] = %d[%d]", nl_found, change_start, change_len); nl_found = "\n"; } } else { exit_val = 2; } if (show_visual) free (visual); if (show_ltov) free (ltov); if (show_vtol) free (vtol); if (show_levels) free (levels); } if (*nl_found) printf (new_line); } } } return exit_val; }
int main (int argc, char **argv) { GIOChannel *channel; GIOStatus status; GError *error; gchar *line = NULL; gsize length, terminator_pos; FriBidiStrIndex *expected_ltor = NULL; FriBidiStrIndex expected_ltor_len = 0; FriBidiStrIndex *ltor = NULL; FriBidiStrIndex ltor_len = 0; FriBidiCharType *types = NULL; FriBidiStrIndex types_len = 0; FriBidiLevel *expected_levels = NULL; FriBidiLevel expected_levels_len = 0; FriBidiLevel *levels = NULL; FriBidiStrIndex levels_len = 0; int base_dir_flags, base_dir_mode; int numerrs = 0; int numtests = 0; int line_no = 0; gboolean debug = FALSE; const char *filename; int next_arg; if (argc < 2) { g_printerr ("usage: %s [--debug] test-file-name\n", argv[0]); exit (1); } next_arg = 1; if (!strcmp (argv[next_arg], "--debug")) { debug = TRUE; next_arg++; } filename = argv[next_arg++]; error = NULL; channel = g_io_channel_new_file (filename, "r", &error); if (!channel) { g_printerr ("%s\n", error->message); exit (1); } while (TRUE) { error = NULL; g_free (line); status = g_io_channel_read_line (channel, &line, &length, &terminator_pos, &error); switch (status) { case G_IO_STATUS_ERROR: g_printerr ("%s\n", error->message); exit (1); case G_IO_STATUS_EOF: goto done; case G_IO_STATUS_AGAIN: continue; case G_IO_STATUS_NORMAL: line[terminator_pos] = '\0'; break; } line_no++; if (line[0] == '#' || line[0] == '\0') continue; if (line[0] == '@') { if (!strncmp (line, "@Reorder:", 9)) { g_free (expected_ltor); expected_ltor = parse_reorder_line (line, &expected_ltor_len); continue; } if (!strncmp (line, "@Levels:", 8)) { g_free (expected_levels); expected_levels = parse_levels_line (line, &expected_levels_len); continue; } continue; } /* Test line */ g_free (types); types = parse_test_line (line, &types_len, &base_dir_flags); g_free (levels); levels = g_malloc (sizeof (FriBidiLevel) * types_len); levels_len = types_len; g_free (ltor); ltor = g_malloc (sizeof (FriBidiStrIndex) * types_len); /* Test it */ for (base_dir_mode = 0; base_dir_mode < 3; base_dir_mode++) { FriBidiParType base_dir; int i, j; gboolean matches; if ((base_dir_flags & (1<<base_dir_mode)) == 0) continue; numtests++; switch (base_dir_mode) { case 0: base_dir = FRIBIDI_PAR_ON; break; case 1: base_dir = FRIBIDI_PAR_LTR; break; case 2: base_dir = FRIBIDI_PAR_RTL; break; } fribidi_get_par_embedding_levels (types, types_len, &base_dir, levels); for (i = 0; i < types_len; i++) ltor[i] = i; fribidi_reorder_line (0 /*FRIBIDI_FLAG_REORDER_NSM*/, types, types_len, 0, base_dir, levels, NULL, ltor); j = 0; for (i = 0; i < types_len; i++) if (!FRIBIDI_IS_EXPLICIT_OR_BN (types[ltor[i]])) ltor[j++] = ltor[i]; ltor_len = j; /* Compare */ matches = TRUE; if (levels_len != expected_levels_len) matches = FALSE; if (matches) for (i = 0; i < levels_len; i++) if (levels[i] != expected_levels[i] && expected_levels[i] != (FriBidiLevel) -1) { matches = FALSE; break; } if (ltor_len != expected_ltor_len) matches = FALSE; if (matches) for (i = 0; i < ltor_len; i++) if (ltor[i] != expected_ltor[i]) { matches = FALSE; break; } if (!matches) { numerrs++; g_printerr ("failure on line %d\n", line_no); g_printerr ("input is: %s\n", line); g_printerr ("base dir: %s\n", base_dir_mode==0 ? "auto" : base_dir_mode==1 ? "LTR" : "RTL"); g_printerr ("expected levels:"); for (i = 0; i < expected_levels_len; i++) if (expected_levels[i] == (FriBidiLevel) -1) g_printerr (" x"); else g_printerr (" %d", expected_levels[i]); g_printerr ("\n"); g_printerr ("returned levels:"); for (i = 0; i < levels_len; i++) g_printerr (" %d", levels[i]); g_printerr ("\n"); g_printerr ("expected order:"); for (i = 0; i < expected_ltor_len; i++) g_printerr (" %d", expected_ltor[i]); g_printerr ("\n"); g_printerr ("returned order:"); for (i = 0; i < ltor_len; i++) g_printerr (" %d", ltor[i]); g_printerr ("\n"); if (debug) { FriBidiParType base_dir; fribidi_set_debug (1); switch (base_dir_mode) { case 0: base_dir = FRIBIDI_PAR_ON; break; case 1: base_dir = FRIBIDI_PAR_LTR; break; case 2: base_dir = FRIBIDI_PAR_RTL; break; } fribidi_get_par_embedding_levels (types, types_len, &base_dir, levels); fribidi_set_debug (0); } g_printerr ("\n"); } } } done: g_free (ltor); g_free (levels); g_free (expected_ltor); g_free (types); g_free (line); g_io_channel_unref (channel); if (error) g_error_free (error); if (numerrs) g_printerr ("%d errors out of %d total tests\n", numerrs, numtests); return numerrs; }
int main (int argc, char **argv) { GError *error; int next_arg; GIOChannel *channel; GIOStatus status; const char *filename; gchar *line = NULL; gsize length, terminator_pos; int numerrs = 0; int line_no = 0; FriBidiChar *code_points = NULL; int code_points_len = 0; int expected_ltor_len = 0; int base_dir_mode = 0, paragraph_dir; FriBidiLevel *expected_levels = NULL; int *expected_ltor = NULL; int resolved_paragraph_embedding_level; FriBidiLevel *levels = NULL; FriBidiCharType *types = NULL; FriBidiBracketType *bracket_types = NULL; FriBidiStrIndex *ltor = NULL; int ltor_len; gboolean debug = FALSE; if (argc < 2) { g_printerr ("usage: %s [--debug] test-file-name\n", argv[0]); exit (1); } next_arg = 1; while(next_arg < argc && argv[next_arg][0]=='-') { const char *arg = argv[next_arg++]; if (strcmp(arg, "--debug")==0) { debug=TRUE; continue; } die("Unknown option %s!\n", arg); } filename = argv[next_arg++]; error = NULL; channel = g_io_channel_new_file (filename, "r", &error); if (!channel) { g_printerr ("%s\n", error->message); exit (1); } fribidi_set_debug(debug); while (TRUE) { error = NULL; g_free (line); status = g_io_channel_read_line (channel, &line, &length, &terminator_pos, &error); switch (status) { case G_IO_STATUS_ERROR: g_printerr ("%s\n", error->message); exit (1); case G_IO_STATUS_EOF: goto done; case G_IO_STATUS_AGAIN: continue; case G_IO_STATUS_NORMAL: line[terminator_pos] = '\0'; break; } line_no++; if (line[0] == '#' || line[0] == '\0') continue; parse_test_line (line, line_no, &code_points, /* Field 0 */ &code_points_len, ¶graph_dir, /* Field 1 */ &resolved_paragraph_embedding_level, /* Field 2 */ &expected_levels, /* Field 3 */ &expected_ltor, /* Field 4 */ &expected_ltor_len ); /* Test it */ g_free(bracket_types); bracket_types = g_malloc ( sizeof(FriBidiBracketType) * code_points_len); g_free(types); types = g_malloc ( sizeof(FriBidiCharType) * code_points_len); g_free(levels); levels = g_malloc (sizeof (FriBidiLevel) * code_points_len); g_free (ltor); ltor = g_malloc (sizeof (FriBidiStrIndex) * code_points_len); { FriBidiParType base_dir; int i, j; gboolean matches; int types_len = code_points_len; int levels_len = types_len; FriBidiBracketType NoBracket = FRIBIDI_NO_BRACKET; for (i=0; i<code_points_len; i++) { types[i] = fribidi_get_bidi_type(code_points[i]); /* Note the optimization that a bracket is always of type neutral */ if (types[i] == FRIBIDI_TYPE_ON) bracket_types[i] = fribidi_get_bracket(code_points[i]); else bracket_types[i] = NoBracket; } if ((paragraph_dir & (1<<base_dir_mode)) == 0) continue; switch (paragraph_dir) { case 0: base_dir = FRIBIDI_PAR_LTR; break; case 1: base_dir = FRIBIDI_PAR_RTL; break; case 2: base_dir = FRIBIDI_PAR_ON; break; } if (fribidi_get_par_embedding_levels_ex (types, bracket_types, types_len, &base_dir, levels)) ; for (i = 0; i < types_len; i++) ltor[i] = i; if (fribidi_reorder_line (0 /*FRIBIDI_FLAG_REORDER_NSM*/, types, types_len, 0, base_dir, levels, NULL, ltor)) ; j = 0; for (i = 0; i < types_len; i++) if (!FRIBIDI_IS_EXPLICIT_OR_BN (types[ltor[i]])) ltor[j++] = ltor[i]; ltor_len = j; /* Compare */ matches = TRUE; if (matches) for (i = 0; i < code_points_len; i++) if (levels[i] != expected_levels[i] && expected_levels[i] != (FriBidiLevel) -1) { matches = FALSE; break; } if (ltor_len != expected_ltor_len) matches = FALSE; if (matches) for (i = 0; i < ltor_len; i++) if (ltor[i] != expected_ltor[i]) { matches = FALSE; break; } if (!matches) { numerrs++; g_printerr ("failure on line %d\n", line_no); g_printerr ("input is: %s\n", line); g_printerr ("base dir: %s\n", paragraph_dir==0 ? "LTR" : paragraph_dir==1 ? "RTL" : "AUTO"); g_printerr ("expected levels:"); for (i = 0; i < code_points_len; i++) if (expected_levels[i] == (FriBidiLevel) -1) g_printerr (" x"); else g_printerr (" %d", expected_levels[i]); g_printerr ("\n"); g_printerr ("returned levels:"); for (i = 0; i < levels_len; i++) g_printerr (" %d", levels[i]); g_printerr ("\n"); g_printerr ("expected order:"); for (i = 0; i < expected_ltor_len; i++) g_printerr (" %d", expected_ltor[i]); g_printerr ("\n"); g_printerr ("returned order:"); for (i = 0; i < ltor_len; i++) g_printerr (" %d", ltor[i]); g_printerr ("\n"); if (debug) { FriBidiParType base_dir; fribidi_set_debug (1); switch (base_dir_mode) { case 0: base_dir = FRIBIDI_PAR_ON; break; case 1: base_dir = FRIBIDI_PAR_LTR; break; case 2: base_dir = FRIBIDI_PAR_RTL; break; } if (fribidi_get_par_embedding_levels_ex (types, bracket_types, types_len, &base_dir, levels)) ; fribidi_set_debug (0); } g_printerr ("\n"); } } } done: if (error) g_error_free (error); if (numerrs) g_printerr ("%d errors\n", numerrs); else printf("No errors found! :-)\n"); return numerrs; }