• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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