Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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,
                       &paragraph_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;
}