(root)/
glib-2.79.0/
glib/
tests/
collate.c
       1  #include "config.h"
       2  
       3  #include <glib.h>
       4  #include <locale.h>
       5  #include <stdlib.h>
       6  #include <string.h>
       7  
       8  static gboolean missing_locale = FALSE;
       9  
      10  typedef struct {
      11    const gchar **input;
      12    const gchar **sorted;
      13    const gchar **file_sorted;
      14  } CollateTest;
      15  
      16  typedef struct {
      17    gchar *key;
      18    const gchar *str;
      19  } Line;
      20  
      21  static void
      22  clear_line (Line *line)
      23  {
      24    g_free (line->key);
      25  }
      26  
      27  static int
      28  compare_collate (const void *a, const void *b)
      29  {
      30    const Line *line_a = a;
      31    const Line *line_b = b;
      32  
      33    return g_utf8_collate (line_a->str, line_b->str);
      34  }
      35  
      36  static int
      37  compare_key (const void *a, const void *b)
      38  {
      39    const Line *line_a = a;
      40    const Line *line_b = b;
      41  
      42    return strcmp (line_a->key, line_b->key);
      43  }
      44  
      45  static void
      46  do_collate (gboolean for_file, gboolean use_key, const CollateTest *test)
      47  {
      48    GArray *line_array;
      49    Line line;
      50    gint i;
      51  
      52    if (missing_locale)
      53      {
      54        g_test_skip ("no en_US locale");
      55        return;
      56      }
      57  
      58    line_array = g_array_new (FALSE, FALSE, sizeof(Line));
      59    g_array_set_clear_func (line_array, (GDestroyNotify)clear_line);
      60  
      61    for (i = 0; test->input[i]; i++)
      62      {
      63        line.str = test->input[i];
      64        if (for_file)
      65          line.key = g_utf8_collate_key_for_filename (line.str, -1);
      66        else
      67          line.key = g_utf8_collate_key (line.str, -1);
      68  
      69        g_array_append_val (line_array, line);
      70      }
      71  
      72    qsort (line_array->data, line_array->len, sizeof (Line), use_key ? compare_key : compare_collate);
      73  
      74    for (i = 0; test->input[i]; i++)
      75      {
      76        const gchar *str;
      77        str = g_array_index (line_array, Line, i).str;
      78        if (for_file)
      79          g_assert_cmpstr (str, ==, test->file_sorted[i]);
      80        else
      81          g_assert_cmpstr (str, ==, test->sorted[i]);
      82      }
      83  
      84    g_array_free (line_array, TRUE);
      85  }
      86  
      87  static void
      88  test_collate (gconstpointer d)
      89  {
      90    const CollateTest *test = d;
      91    do_collate (FALSE, FALSE, test);
      92  }
      93  
      94  static void
      95  test_collate_key (gconstpointer d)
      96  {
      97    const CollateTest *test = d;
      98    do_collate (FALSE, TRUE, test);
      99  }
     100  
     101  static void
     102  test_collate_file (gconstpointer d)
     103  {
     104    const CollateTest *test = d;
     105    do_collate (TRUE, TRUE, test);
     106  }
     107  
     108  const gchar *input0[] = {
     109    "z",
     110    "c",
     111    "eer34",
     112    "223",
     113    "er1",
     114    "üĠണ",
     115    "foo",
     116    "bar",
     117    "baz",
     118    "GTK+",
     119    NULL
     120  };
     121  
     122  const gchar *sorted0[] = {
     123    "223",
     124    "bar",
     125    "baz",
     126    "c",
     127    "eer34",
     128    "er1",
     129    "foo",
     130    "GTK+",
     131    "üĠണ",
     132    "z",
     133    NULL
     134  };
     135  
     136  const gchar *file_sorted0[] = {
     137    "223",
     138    "bar",
     139    "baz",
     140    "c",
     141    "eer34",
     142    "er1",
     143    "foo",
     144    "GTK+",
     145    "üĠണ",
     146    "z",
     147    NULL
     148  };
     149  
     150  const gchar *input1[] = {
     151    "file.txt",
     152    "file2.bla",
     153    "file.c",
     154    "file3.xx",
     155    "bla001",
     156    "bla02",
     157    "bla03",
     158    "bla4",
     159    "bla10",
     160    "bla100",
     161    "event.c",
     162    "eventgenerator.c",
     163    "event.h",
     164    NULL
     165  };
     166  
     167  const gchar *sorted1[] = {
     168    "bla001",
     169    "bla02",
     170    "bla03",
     171    "bla10",
     172    "bla100",
     173    "bla4",
     174    "event.c",
     175    "eventgenerator.c",
     176    "event.h",
     177    "file2.bla",
     178    "file3.xx",
     179    "file.c",
     180    "file.txt",
     181    NULL
     182  };
     183  
     184  const gchar *file_sorted1[] = {
     185    "bla001",
     186    "bla02",
     187    "bla03",
     188    "bla4",
     189    "bla10",
     190    "bla100",
     191    "event.c",
     192    "event.h",
     193    "eventgenerator.c",
     194    "file.c",
     195    "file.txt",
     196    "file2.bla",
     197    "file3.xx",
     198    NULL
     199  };
     200  
     201  const gchar *input2[] = {
     202    "file26",
     203    "file100",
     204    "file1",
     205    "file:foo",
     206    "a.a",
     207    "file027",
     208    "file10",
     209    "aa.a",
     210    "file5",
     211    "file0027",
     212    "a-.a",
     213    "file0000",
     214    "file000x",
     215    NULL
     216  };
     217  
     218  const gchar *sorted2[] = {
     219    "a-.a",
     220    "a.a",
     221    "aa.a",
     222    "file0000",
     223    "file000x",
     224    "file0027",
     225    "file027",
     226    "file1",
     227    "file10",
     228    "file100",
     229    "file26",
     230    "file5",
     231    "file:foo",
     232    NULL
     233  };
     234  
     235  const gchar *file_sorted2[] = {
     236    /* Filename collation in OS X follows Finder style which gives
     237     * a slightly different order from usual Linux locales. */
     238  #ifdef HAVE_CARBON
     239    "a-.a",
     240    "a.a",
     241    "aa.a",
     242    "file:foo",
     243    "file0000",
     244    "file000x",
     245    "file1",
     246    "file5",
     247    "file10",
     248    "file26",
     249    "file0027",
     250    "file027",
     251    "file100",
     252  #else
     253    "a.a",
     254    "a-.a",
     255    "aa.a",
     256    "file0000",
     257    "file000x",
     258    "file1",
     259    "file5",
     260    "file10",
     261    "file26",
     262    "file027",
     263    "file0027",
     264    "file100",
     265    "file:foo",
     266  #endif
     267    NULL
     268  };
     269  
     270  int
     271  main (int argc, char *argv[])
     272  {
     273    gchar *path;
     274    guint i;
     275    const gchar *locale;
     276    CollateTest test[3];
     277  
     278    g_test_init (&argc, &argv, NULL);
     279  
     280    g_setenv ("LC_ALL", "en_US", TRUE);
     281    locale = setlocale (LC_ALL, "");
     282    if (locale == NULL || strcmp (locale, "en_US") != 0)
     283      {
     284        g_test_message ("No suitable locale, skipping tests");
     285        missing_locale = TRUE;
     286        /* let the tests run to completion so they show up as SKIP'd in TAP
     287         * output */
     288      }
     289  
     290    test[0].input = input0;
     291    test[0].sorted = sorted0;
     292    test[0].file_sorted = file_sorted0;
     293    test[1].input = input1;
     294    test[1].sorted = sorted1;
     295    test[1].file_sorted = file_sorted1;
     296    test[2].input = input2;
     297    test[2].sorted = sorted2;
     298    test[2].file_sorted = file_sorted2;
     299  
     300    for (i = 0; i < G_N_ELEMENTS (test); i++)
     301      {
     302        path = g_strdup_printf ("/unicode/collate/%d", i);
     303        g_test_add_data_func (path, &test[i], test_collate);
     304        g_free (path);
     305        path = g_strdup_printf ("/unicode/collate-key/%d", i);
     306        g_test_add_data_func (path, &test[i], test_collate_key);
     307        g_free (path);
     308        path = g_strdup_printf ("/unicode/collate-filename/%d", i);
     309        g_test_add_data_func (path, &test[i], test_collate_file);
     310        g_free (path);
     311      }
     312  
     313    return g_test_run ();
     314  }