1#include <glib.h>
2
3#define SIZE 50
4#define NUMBER_MIN 0000
5#define NUMBER_MAX 9999
6
7
8static guint32 array[SIZE];
9
10
11static gint
12sort (gconstpointer p1, gconstpointer p2)
13{
14 gint32 a, b;
15
16 a = GPOINTER_TO_INT (p1);
17 b = GPOINTER_TO_INT (p2);
18
19 return (a > b ? +1 : a == b ? 0 : -1);
20}
21
22/*
23 * gslist sort tests
24 */
25static void
26test_slist_sort (void)
27{
28 GSList *slist = NULL;
29 gint i;
30
31 for (i = 0; i < SIZE; i++)
32 slist = g_slist_append (list: slist, GINT_TO_POINTER (array[i]));
33
34 slist = g_slist_sort (list: slist, compare_func: sort);
35 for (i = 0; i < SIZE - 1; i++)
36 {
37 gpointer p1, p2;
38
39 p1 = g_slist_nth_data (list: slist, n: i);
40 p2 = g_slist_nth_data (list: slist, n: i+1);
41
42 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
43 }
44
45 g_slist_free (list: slist);
46}
47
48static void
49test_slist_sort_with_data (void)
50{
51 GSList *slist = NULL;
52 gint i;
53
54 for (i = 0; i < SIZE; i++)
55 slist = g_slist_append (list: slist, GINT_TO_POINTER (array[i]));
56
57 slist = g_slist_sort_with_data (list: slist, compare_func: (GCompareDataFunc)sort, NULL);
58 for (i = 0; i < SIZE - 1; i++)
59 {
60 gpointer p1, p2;
61
62 p1 = g_slist_nth_data (list: slist, n: i);
63 p2 = g_slist_nth_data (list: slist, n: i+1);
64
65 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
66 }
67
68 g_slist_free (list: slist);
69}
70
71/* Test that the sort is stable. */
72static void
73test_slist_sort_stable (void)
74{
75 GSList *list = NULL; /* (element-type utf8) */
76 GSList *copy = NULL; /* (element-type utf8) */
77 gsize i;
78
79 /* Build a test list, already ordered. */
80 for (i = 0; i < SIZE; i++)
81 list = g_slist_append (list, data: g_strdup_printf (format: "%" G_GSIZE_FORMAT, i / 5));
82
83 /* Take a copy and sort it. */
84 copy = g_slist_copy (list);
85 copy = g_slist_sort (list: copy, compare_func: (GCompareFunc) g_strcmp0);
86
87 /* Compare the two lists, checking pointers are equal to ensure the elements
88 * have been kept stable. */
89 for (i = 0; i < SIZE; i++)
90 {
91 gpointer p1, p2;
92
93 p1 = g_slist_nth_data (list, n: i);
94 p2 = g_slist_nth_data (list, n: i);
95
96 g_assert (p1 == p2);
97 }
98
99 g_slist_free (list: copy);
100 g_slist_free_full (list, free_func: g_free);
101}
102
103static void
104test_slist_insert_sorted (void)
105{
106 GSList *slist = NULL;
107 gint i;
108
109 for (i = 0; i < SIZE; i++)
110 slist = g_slist_insert_sorted (list: slist, GINT_TO_POINTER (array[i]), func: sort);
111
112 for (i = 0; i < SIZE - 1; i++)
113 {
114 gpointer p1, p2;
115
116 p1 = g_slist_nth_data (list: slist, n: i);
117 p2 = g_slist_nth_data (list: slist, n: i+1);
118
119 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
120 }
121
122 g_slist_free (list: slist);
123}
124
125static void
126test_slist_insert_sorted_with_data (void)
127{
128 GSList *slist = NULL;
129 gint i;
130
131 for (i = 0; i < SIZE; i++)
132 slist = g_slist_insert_sorted_with_data (list: slist,
133 GINT_TO_POINTER (array[i]),
134 func: (GCompareDataFunc)sort,
135 NULL);
136
137 for (i = 0; i < SIZE - 1; i++)
138 {
139 gpointer p1, p2;
140
141 p1 = g_slist_nth_data (list: slist, n: i);
142 p2 = g_slist_nth_data (list: slist, n: i+1);
143
144 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
145 }
146
147 g_slist_free (list: slist);
148}
149
150static void
151test_slist_reverse (void)
152{
153 GSList *slist = NULL;
154 GSList *st;
155 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
156 gint i;
157
158 for (i = 0; i < 10; i++)
159 slist = g_slist_append (list: slist, data: &nums[i]);
160
161 slist = g_slist_reverse (list: slist);
162
163 for (i = 0; i < 10; i++)
164 {
165 st = g_slist_nth (list: slist, n: i);
166 g_assert (*((gint*) st->data) == (9 - i));
167 }
168
169 g_slist_free (list: slist);
170}
171
172static void
173test_slist_nth (void)
174{
175 GSList *slist = NULL;
176 GSList *st;
177 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
178 gint i;
179
180 for (i = 0; i < 10; i++)
181 slist = g_slist_append (list: slist, data: &nums[i]);
182
183 for (i = 0; i < 10; i++)
184 {
185 st = g_slist_nth (list: slist, n: i);
186 g_assert (*((gint*) st->data) == i);
187 }
188
189 g_slist_free (list: slist);
190}
191
192static void
193test_slist_remove (void)
194{
195 GSList *slist = NULL;
196 GSList *st;
197 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
198 gint i;
199
200 for (i = 0; i < 10; i++)
201 {
202 slist = g_slist_append (list: slist, data: &nums[i]);
203 slist = g_slist_append (list: slist, data: &nums[i]);
204 }
205
206 g_assert_cmpint (g_slist_length (slist), ==, 20);
207
208 for (i = 0; i < 10; i++)
209 {
210 slist = g_slist_remove (list: slist, data: &nums[i]);
211 }
212
213 g_assert_cmpint (g_slist_length (slist), ==, 10);
214
215 for (i = 0; i < 10; i++)
216 {
217 st = g_slist_nth (list: slist, n: i);
218 g_assert (*((gint*) st->data) == i);
219 }
220
221 g_slist_free (list: slist);
222}
223
224static void
225test_slist_remove_all (void)
226{
227 GSList *slist = NULL;
228 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
229 gint i;
230
231 for (i = 0; i < 10; i++)
232 {
233 slist = g_slist_append (list: slist, data: &nums[i]);
234 slist = g_slist_append (list: slist, data: &nums[i]);
235 }
236
237 g_assert_cmpint (g_slist_length (slist), ==, 20);
238
239 for (i = 0; i < 5; i++)
240 {
241 slist = g_slist_remove_all (list: slist, data: &nums[2 * i + 1]);
242 slist = g_slist_remove_all (list: slist, data: &nums[8 - 2 * i]);
243 }
244
245 g_assert_cmpint (g_slist_length (slist), ==, 0);
246 g_assert (slist == NULL);
247}
248
249static void
250test_slist_insert (void)
251{
252 gpointer a = "a";
253 gpointer b = "b";
254 gpointer c = "c";
255 GSList *slist = NULL;
256 GSList *st;
257 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
258 gint i;
259
260 slist = g_slist_insert_before (NULL, NULL, data: &nums[1]);
261 slist = g_slist_insert (list: slist, data: &nums[3], position: 1);
262 slist = g_slist_insert (list: slist, data: &nums[4], position: -1);
263 slist = g_slist_insert (list: slist, data: &nums[0], position: 0);
264 slist = g_slist_insert (list: slist, data: &nums[5], position: 100);
265 slist = g_slist_insert_before (slist, NULL, data: &nums[6]);
266 slist = g_slist_insert_before (slist, sibling: slist->next->next, data: &nums[2]);
267
268 slist = g_slist_insert (list: slist, data: &nums[9], position: 7);
269 slist = g_slist_insert (list: slist, data: &nums[8], position: 7);
270 slist = g_slist_insert (list: slist, data: &nums[7], position: 7);
271
272 for (i = 0; i < 10; i++)
273 {
274 st = g_slist_nth (list: slist, n: i);
275 g_assert (*((gint*) st->data) == i);
276 }
277
278 g_slist_free (list: slist);
279
280 slist = g_slist_insert (NULL, data: a, position: 1);
281 g_assert (slist->data == a);
282 g_assert (slist->next == NULL);
283 g_slist_free (list: slist);
284
285 slist = g_slist_append (NULL, data: a);
286 slist = g_slist_append (list: slist, data: b);
287 slist = g_slist_insert (list: slist, data: c, position: 5);
288
289 g_assert (slist->next->next->data == c);
290 g_assert (slist->next->next->next == NULL);
291 g_slist_free (list: slist);
292
293 slist = g_slist_append (NULL, data: a);
294 slist = g_slist_insert_before (slist, sibling: slist, data: b);
295 g_assert (slist->data == b);
296 g_assert (slist->next->data == a);
297 g_assert (slist->next->next == NULL);
298 g_slist_free (list: slist);
299}
300
301static gint
302find_num (gconstpointer l, gconstpointer data)
303{
304 return *(gint*)l - GPOINTER_TO_INT(data);
305}
306
307static void
308test_slist_position (void)
309{
310 GSList *slist = NULL;
311 GSList *st;
312 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
313 gint i;
314
315 for (i = 0; i < 10; i++)
316 {
317 slist = g_slist_append (list: slist, data: &nums[i]);
318 }
319
320 g_assert_cmpint (g_slist_index (slist, NULL), ==, -1);
321 g_assert_cmpint (g_slist_position (slist, NULL), ==, -1);
322
323 for (i = 0; i < 10; i++)
324 {
325 g_assert_cmpint (g_slist_index (slist, &nums[i]), ==, i);
326 st = g_slist_find_custom (list: slist, GINT_TO_POINTER(i), func: find_num);
327 g_assert (st != NULL);
328 g_assert_cmpint (g_slist_position (slist, st), ==, i);
329 }
330
331 st = g_slist_find_custom (list: slist, GINT_TO_POINTER (1000), func: find_num);
332 g_assert (st == NULL);
333
334 g_slist_free (list: slist);
335}
336
337static void
338test_slist_concat (void)
339{
340 gpointer a = "a";
341 gpointer b = "b";
342 GSList *s1, *s2, *s;
343
344 s1 = g_slist_append (NULL, data: a);
345 s2 = g_slist_append (NULL, data: b);
346 s = g_slist_concat (list1: s1, list2: s2);
347 g_assert (s->data == a);
348 g_assert (s->next->data == b);
349 g_assert (s->next->next == NULL);
350 g_slist_free (list: s);
351
352 s1 = g_slist_append (NULL, data: a);
353
354 s = g_slist_concat (NULL, list2: s1);
355 g_assert_cmpint (g_slist_length (s), ==, 1);
356 s = g_slist_concat (list1: s1, NULL);
357 g_assert_cmpint (g_slist_length (s), ==, 1);
358
359 g_slist_free (list: s);
360
361 s = g_slist_concat (NULL, NULL);
362 g_assert (s == NULL);
363}
364
365static void
366test_slist_copy (void)
367{
368 GSList *slist = NULL, *copy;
369 GSList *s1, *s2;
370 guint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
371 gsize i;
372
373 /* Copy and test a many-element list. */
374 for (i = 0; i < 10; i++)
375 slist = g_slist_append (list: slist, data: &nums[i]);
376
377 copy = g_slist_copy (list: slist);
378
379 g_assert_cmpuint (g_slist_length (copy), ==, g_slist_length (slist));
380
381 for (s1 = copy, s2 = slist; s1 != NULL && s2 != NULL; s1 = s1->next, s2 = s2->next)
382 g_assert (s1->data == s2->data);
383
384 g_slist_free (list: copy);
385 g_slist_free (list: slist);
386
387 /* Copy a NULL list. */
388 copy = g_slist_copy (NULL);
389 g_assert_null (copy);
390}
391
392static gpointer
393copy_and_count_string (gconstpointer src,
394 gpointer data)
395{
396 const gchar *str = src;
397 gsize *count = data;
398
399 *count = *count + 1;
400 return g_strdup (str);
401}
402
403static void
404test_slist_copy_deep (void)
405{
406 GSList *slist = NULL, *copy;
407 GSList *s1, *s2;
408 gsize count;
409
410 /* Deep-copy a simple list. */
411 slist = g_slist_append (list: slist, data: "a");
412 slist = g_slist_append (list: slist, data: "b");
413 slist = g_slist_append (list: slist, data: "c");
414
415 count = 0;
416 copy = g_slist_copy_deep (list: slist, func: copy_and_count_string, user_data: &count);
417
418 g_assert_cmpuint (count, ==, g_slist_length (slist));
419 g_assert_cmpuint (g_slist_length (copy), ==, count);
420 for (s1 = slist, s2 = copy; s1 != NULL && s2 != NULL; s1 = s1->next, s2 = s2->next)
421 {
422 g_assert_cmpstr (s1->data, ==, s2->data);
423 g_assert (s1->data != s2->data);
424 }
425
426 g_slist_free_full (list: copy, free_func: g_free);
427 g_slist_free (list: slist);
428
429 /* Try with an empty list. */
430 count = 0;
431 copy = g_slist_copy_deep (NULL, func: copy_and_count_string, user_data: &count);
432 g_assert_cmpuint (count, ==, 0);
433 g_assert_null (copy);
434}
435
436int
437main (int argc, char *argv[])
438{
439 gint i;
440
441 g_test_init (argc: &argc, argv: &argv, NULL);
442
443 /* Create an array of random numbers. */
444 for (i = 0; i < SIZE; i++)
445 array[i] = g_test_rand_int_range (NUMBER_MIN, NUMBER_MAX);
446
447 g_test_add_func (testpath: "/slist/sort", test_func: test_slist_sort);
448 g_test_add_func (testpath: "/slist/sort-with-data", test_func: test_slist_sort_with_data);
449 g_test_add_func (testpath: "/slist/sort/stable", test_func: test_slist_sort_stable);
450 g_test_add_func (testpath: "/slist/insert-sorted", test_func: test_slist_insert_sorted);
451 g_test_add_func (testpath: "/slist/insert-sorted-with-data", test_func: test_slist_insert_sorted_with_data);
452 g_test_add_func (testpath: "/slist/reverse", test_func: test_slist_reverse);
453 g_test_add_func (testpath: "/slist/nth", test_func: test_slist_nth);
454 g_test_add_func (testpath: "/slist/remove", test_func: test_slist_remove);
455 g_test_add_func (testpath: "/slist/remove-all", test_func: test_slist_remove_all);
456 g_test_add_func (testpath: "/slist/insert", test_func: test_slist_insert);
457 g_test_add_func (testpath: "/slist/position", test_func: test_slist_position);
458 g_test_add_func (testpath: "/slist/concat", test_func: test_slist_concat);
459 g_test_add_func (testpath: "/slist/copy", test_func: test_slist_copy);
460 g_test_add_func (testpath: "/slist/copy/deep", test_func: test_slist_copy_deep);
461
462 return g_test_run ();
463}
464

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