1#include "config.h"
2
3#include <glib.h>
4#include <locale.h>
5#include <stdlib.h>
6#include <string.h>
7
8static gboolean missing_locale = FALSE;
9
10typedef struct {
11 const gchar **input;
12 const gchar **sorted;
13 const gchar **file_sorted;
14} CollateTest;
15
16typedef struct {
17 gchar *key;
18 const gchar *str;
19} Line;
20
21static void
22clear_line (Line *line)
23{
24 g_free (mem: line->key);
25}
26
27static int
28compare_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 (str1: line_a->str, str2: line_b->str);
34}
35
36static int
37compare_key (const void *a, const void *b)
38{
39 const Line *line_a = a;
40 const Line *line_b = b;
41
42 return strcmp (s1: line_a->key, s2: line_b->key);
43}
44
45static void
46do_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 (msg: "no en_US locale");
55 return;
56 }
57
58 line_array = g_array_new (FALSE, FALSE, element_size: sizeof(Line));
59 g_array_set_clear_func (array: line_array, clear_func: (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 (str: line.str, len: -1);
66 else
67 line.key = g_utf8_collate_key (str: line.str, len: -1);
68
69 g_array_append_val (line_array, line);
70 }
71
72 qsort (base: line_array->data, nmemb: line_array->len, size: sizeof (Line), compar: 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 (array: line_array, TRUE);
85}
86
87static void
88test_collate (gconstpointer d)
89{
90 const CollateTest *test = d;
91 do_collate (FALSE, FALSE, test);
92}
93
94static void
95test_collate_key (gconstpointer d)
96{
97 const CollateTest *test = d;
98 do_collate (FALSE, TRUE, test);
99}
100
101static void
102test_collate_file (gconstpointer d)
103{
104 const CollateTest *test = d;
105 do_collate (TRUE, TRUE, test);
106}
107
108const 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
122const 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
136const 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
150const 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
167const 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
184const 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
201const 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
218const 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
235const 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
270int
271main (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: &argc, argv: &argv, NULL);
279
280 g_setenv (variable: "LC_ALL", value: "en_US", TRUE);
281 locale = setlocale (LC_ALL, locale: "");
282 if (locale == NULL || strcmp (s1: locale, s2: "en_US") != 0)
283 {
284 g_test_message (format: "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 (format: "/unicode/collate/%d", i);
303 g_test_add_data_func (testpath: path, test_data: &test[i], test_func: test_collate);
304 g_free (mem: path);
305 path = g_strdup_printf (format: "/unicode/collate-key/%d", i);
306 g_test_add_data_func (testpath: path, test_data: &test[i], test_func: test_collate_key);
307 g_free (mem: path);
308 path = g_strdup_printf (format: "/unicode/collate-filename/%d", i);
309 g_test_add_data_func (testpath: path, test_data: &test[i], test_func: test_collate_file);
310 g_free (mem: path);
311 }
312
313 return g_test_run ();
314}
315

source code of gtk/subprojects/glib/glib/tests/collate.c