1 #include <glib.h>
2
3 #define SIZE 50
4 #define NUMBER_MIN 0000
5 #define NUMBER_MAX 9999
6
7
8 static guint32 array[SIZE];
9
10
11 static gint
sort(gconstpointer p1,gconstpointer p2)12 sort (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 */
25 static void
test_slist_sort(void)26 test_slist_sort (void)
27 {
28 GSList *slist = NULL;
29 gint i;
30
31 for (i = 0; i < SIZE; i++)
32 slist = g_slist_append (slist, GINT_TO_POINTER (array[i]));
33
34 slist = g_slist_sort (slist, sort);
35 for (i = 0; i < SIZE - 1; i++)
36 {
37 gpointer p1, p2;
38
39 p1 = g_slist_nth_data (slist, i);
40 p2 = g_slist_nth_data (slist, i+1);
41
42 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
43 }
44
45 g_slist_free (slist);
46 }
47
48 static void
test_slist_sort_with_data(void)49 test_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 (slist, GINT_TO_POINTER (array[i]));
56
57 slist = g_slist_sort_with_data (slist, (GCompareDataFunc)sort, NULL);
58 for (i = 0; i < SIZE - 1; i++)
59 {
60 gpointer p1, p2;
61
62 p1 = g_slist_nth_data (slist, i);
63 p2 = g_slist_nth_data (slist, i+1);
64
65 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
66 }
67
68 g_slist_free (slist);
69 }
70
71 /* Test that the sort is stable. */
72 static void
test_slist_sort_stable(void)73 test_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, g_strdup_printf ("%" G_GSIZE_FORMAT, i / 5));
82
83 /* Take a copy and sort it. */
84 copy = g_slist_copy (list);
85 copy = g_slist_sort (copy, (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, i);
94 p2 = g_slist_nth_data (list, i);
95
96 g_assert (p1 == p2);
97 }
98
99 g_slist_free (copy);
100 g_slist_free_full (list, g_free);
101 }
102
103 static void
test_slist_insert_sorted(void)104 test_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 (slist, GINT_TO_POINTER (array[i]), sort);
111
112 for (i = 0; i < SIZE - 1; i++)
113 {
114 gpointer p1, p2;
115
116 p1 = g_slist_nth_data (slist, i);
117 p2 = g_slist_nth_data (slist, i+1);
118
119 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
120 }
121
122 g_slist_free (slist);
123 }
124
125 static void
test_slist_insert_sorted_with_data(void)126 test_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 (slist,
133 GINT_TO_POINTER (array[i]),
134 (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 (slist, i);
142 p2 = g_slist_nth_data (slist, i+1);
143
144 g_assert (GPOINTER_TO_INT (p1) <= GPOINTER_TO_INT (p2));
145 }
146
147 g_slist_free (slist);
148 }
149
150 static void
test_slist_reverse(void)151 test_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 (slist, &nums[i]);
160
161 slist = g_slist_reverse (slist);
162
163 for (i = 0; i < 10; i++)
164 {
165 st = g_slist_nth (slist, i);
166 g_assert (*((gint*) st->data) == (9 - i));
167 }
168
169 g_slist_free (slist);
170 }
171
172 static void
test_slist_nth(void)173 test_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 (slist, &nums[i]);
182
183 for (i = 0; i < 10; i++)
184 {
185 st = g_slist_nth (slist, i);
186 g_assert (*((gint*) st->data) == i);
187 }
188
189 g_slist_free (slist);
190 }
191
192 static void
test_slist_remove(void)193 test_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 (slist, &nums[i]);
203 slist = g_slist_append (slist, &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 (slist, &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 (slist, i);
218 g_assert (*((gint*) st->data) == i);
219 }
220
221 g_slist_free (slist);
222 }
223
224 static void
test_slist_remove_all(void)225 test_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 (slist, &nums[i]);
234 slist = g_slist_append (slist, &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 (slist, &nums[2 * i + 1]);
242 slist = g_slist_remove_all (slist, &nums[8 - 2 * i]);
243 }
244
245 g_assert_cmpint (g_slist_length (slist), ==, 0);
246 g_assert (slist == NULL);
247 }
248
249 static void
test_slist_insert(void)250 test_slist_insert (void)
251 {
252 GSList *slist = NULL;
253 GSList *st;
254 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
255 gint i;
256
257 slist = g_slist_insert_before (NULL, NULL, &nums[1]);
258 slist = g_slist_insert (slist, &nums[3], 1);
259 slist = g_slist_insert (slist, &nums[4], -1);
260 slist = g_slist_insert (slist, &nums[0], 0);
261 slist = g_slist_insert (slist, &nums[5], 100);
262 slist = g_slist_insert_before (slist, NULL, &nums[6]);
263 slist = g_slist_insert_before (slist, slist->next->next, &nums[2]);
264
265 slist = g_slist_insert (slist, &nums[9], 7);
266 slist = g_slist_insert (slist, &nums[8], 7);
267 slist = g_slist_insert (slist, &nums[7], 7);
268
269 for (i = 0; i < 10; i++)
270 {
271 st = g_slist_nth (slist, i);
272 g_assert (*((gint*) st->data) == i);
273 }
274
275 g_slist_free (slist);
276
277 slist = g_slist_insert (NULL, "a", 1);
278 g_assert (slist->data == (gpointer)"a");
279 g_assert (slist->next == NULL);
280 g_slist_free (slist);
281
282 slist = g_slist_append (NULL, "a");
283 slist = g_slist_append (slist, "b");
284 slist = g_slist_insert (slist, "c", 5);
285
286 g_assert (slist->next->next->data == (gpointer)"c");
287 g_assert (slist->next->next->next == NULL);
288 g_slist_free (slist);
289
290 slist = g_slist_append (NULL, "a");
291 slist = g_slist_insert_before (slist, slist, "b");
292 g_assert (slist->data == (gpointer)"b");
293 g_assert (slist->next->data == (gpointer)"a");
294 g_assert (slist->next->next == NULL);
295 g_slist_free (slist);
296 }
297
298 static gint
find_num(gconstpointer l,gconstpointer data)299 find_num (gconstpointer l, gconstpointer data)
300 {
301 return *(gint*)l - GPOINTER_TO_INT(data);
302 }
303
304 static void
test_slist_position(void)305 test_slist_position (void)
306 {
307 GSList *slist = NULL;
308 GSList *st;
309 gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
310 gint i;
311
312 for (i = 0; i < 10; i++)
313 {
314 slist = g_slist_append (slist, &nums[i]);
315 }
316
317 g_assert_cmpint (g_slist_index (slist, NULL), ==, -1);
318 g_assert_cmpint (g_slist_position (slist, NULL), ==, -1);
319
320 for (i = 0; i < 10; i++)
321 {
322 g_assert_cmpint (g_slist_index (slist, &nums[i]), ==, i);
323 st = g_slist_find_custom (slist, GINT_TO_POINTER(i), find_num);
324 g_assert (st != NULL);
325 g_assert_cmpint (g_slist_position (slist, st), ==, i);
326 }
327
328 st = g_slist_find_custom (slist, GINT_TO_POINTER (1000), find_num);
329 g_assert (st == NULL);
330
331 g_slist_free (slist);
332 }
333
334 static void
test_slist_concat(void)335 test_slist_concat (void)
336 {
337 GSList *s1, *s2, *s;
338
339 s1 = g_slist_append (NULL, "a");
340 s2 = g_slist_append (NULL, "b");
341 s = g_slist_concat (s1, s2);
342 g_assert (s->data == (gpointer)"a");
343 g_assert (s->next->data == (gpointer)"b");
344 g_assert (s->next->next == NULL);
345 g_slist_free (s);
346
347 s1 = g_slist_append (NULL, "a");
348
349 s = g_slist_concat (NULL, s1);
350 g_assert_cmpint (g_slist_length (s), ==, 1);
351 s = g_slist_concat (s1, NULL);
352 g_assert_cmpint (g_slist_length (s), ==, 1);
353
354 g_slist_free (s);
355
356 s = g_slist_concat (NULL, NULL);
357 g_assert (s == NULL);
358 }
359
360 static void
test_slist_copy(void)361 test_slist_copy (void)
362 {
363 GSList *slist = NULL, *copy;
364 GSList *s1, *s2;
365 guint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
366 gsize i;
367
368 /* Copy and test a many-element list. */
369 for (i = 0; i < 10; i++)
370 slist = g_slist_append (slist, &nums[i]);
371
372 copy = g_slist_copy (slist);
373
374 g_assert_cmpuint (g_slist_length (copy), ==, g_slist_length (slist));
375
376 for (s1 = copy, s2 = slist; s1 != NULL && s2 != NULL; s1 = s1->next, s2 = s2->next)
377 g_assert (s1->data == s2->data);
378
379 g_slist_free (copy);
380 g_slist_free (slist);
381
382 /* Copy a NULL list. */
383 copy = g_slist_copy (NULL);
384 g_assert_null (copy);
385 }
386
387 static gpointer
copy_and_count_string(gconstpointer src,gpointer data)388 copy_and_count_string (gconstpointer src,
389 gpointer data)
390 {
391 const gchar *str = src;
392 gsize *count = data;
393
394 *count = *count + 1;
395 return g_strdup (str);
396 }
397
398 static void
test_slist_copy_deep(void)399 test_slist_copy_deep (void)
400 {
401 GSList *slist = NULL, *copy;
402 GSList *s1, *s2;
403 gsize count;
404
405 /* Deep-copy a simple list. */
406 slist = g_slist_append (slist, "a");
407 slist = g_slist_append (slist, "b");
408 slist = g_slist_append (slist, "c");
409
410 count = 0;
411 copy = g_slist_copy_deep (slist, copy_and_count_string, &count);
412
413 g_assert_cmpuint (count, ==, g_slist_length (slist));
414 g_assert_cmpuint (g_slist_length (copy), ==, count);
415 for (s1 = slist, s2 = copy; s1 != NULL && s2 != NULL; s1 = s1->next, s2 = s2->next)
416 {
417 g_assert_cmpstr (s1->data, ==, s2->data);
418 g_assert (s1->data != s2->data);
419 }
420
421 g_slist_free_full (copy, g_free);
422 g_slist_free (slist);
423
424 /* Try with an empty list. */
425 count = 0;
426 copy = g_slist_copy_deep (NULL, copy_and_count_string, &count);
427 g_assert_cmpuint (count, ==, 0);
428 g_assert_null (copy);
429 }
430
431 int
main(int argc,char * argv[])432 main (int argc, char *argv[])
433 {
434 gint i;
435
436 g_test_init (&argc, &argv, NULL);
437
438 /* Create an array of random numbers. */
439 for (i = 0; i < SIZE; i++)
440 array[i] = g_test_rand_int_range (NUMBER_MIN, NUMBER_MAX);
441
442 g_test_add_func ("/slist/sort", test_slist_sort);
443 g_test_add_func ("/slist/sort-with-data", test_slist_sort_with_data);
444 g_test_add_func ("/slist/sort/stable", test_slist_sort_stable);
445 g_test_add_func ("/slist/insert-sorted", test_slist_insert_sorted);
446 g_test_add_func ("/slist/insert-sorted-with-data", test_slist_insert_sorted_with_data);
447 g_test_add_func ("/slist/reverse", test_slist_reverse);
448 g_test_add_func ("/slist/nth", test_slist_nth);
449 g_test_add_func ("/slist/remove", test_slist_remove);
450 g_test_add_func ("/slist/remove-all", test_slist_remove_all);
451 g_test_add_func ("/slist/insert", test_slist_insert);
452 g_test_add_func ("/slist/position", test_slist_position);
453 g_test_add_func ("/slist/concat", test_slist_concat);
454 g_test_add_func ("/slist/copy", test_slist_copy);
455 g_test_add_func ("/slist/copy/deep", test_slist_copy_deep);
456
457 return g_test_run ();
458 }
459