1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* This is a test program for the ll_* routines defined in
18 ll.c. This test program aims to be as comprehensive as
19 possible. "gcov -b" should report 100% coverage of lines and
20 branches in the ll_* routines. "valgrind --leak-check=yes
21 --show-reachable=yes" should give a clean report.
23 This test program depends only on ll.c and the standard C
26 See llx-test.c for a similar program for the llx_*
33 #include <libpspp/ll.h>
39 /* Support preliminaries. */
40 #if __GNUC__ >= 2 && !defined UNUSED
41 #define UNUSED __attribute__ ((unused))
46 /* Currently running test. */
47 static const char *test_name;
49 /* Exit with a failure code.
50 (Place a breakpoint on this function while debugging.) */
57 /* If OK is not true, prints a message about failure on the
58 current source file and the given LINE and terminates. */
60 check_func (bool ok, int line)
64 printf ("Check failed in %s test at %s, line %d\n",
65 test_name, __FILE__, line);
70 /* Verifies that EXPR evaluates to true.
71 If not, prints a message citing the calling line number and
73 #define check(EXPR) check_func ((EXPR), __LINE__)
75 /* Prints a message about memory exhaustion and exits with a
80 printf ("virtual memory exhausted\n");
84 /* Allocates and returns N bytes of memory. */
100 /* Allocates and returns N * M bytes of memory. */
102 xnmalloc (size_t n, size_t m)
104 if ((size_t) -1 / m <= n)
106 return xmalloc (n * m);
109 /* List type and support routines. */
111 /* Test data element. */
114 struct ll ll; /* Embedded list element. */
115 int x; /* Primary value. */
116 int y; /* Secondary value. */
121 /* Returns the `struct element' that LL is embedded within. */
122 static struct element *
123 ll_to_element (const struct ll *ll)
125 return ll_data (ll, struct element, ll);
128 /* Prints the elements in LIST. */
130 print_list (struct ll_list *list)
135 for (x = ll_head (list); x != ll_null (list); x = ll_next (x))
137 struct element *e = ll_to_element (x);
138 printf (" %d", e->x);
143 /* Prints the value returned by PREDICATE given auxiliary data
144 AUX for each element in LIST. */
146 print_pred (struct ll_list *list,
147 ll_predicate_func *predicate, void *aux UNUSED)
152 for (x = ll_head (list); x != ll_null (list); x = ll_next (x))
153 printf (" %d", predicate (x, aux));
157 /* Prints the CNT numbers in VALUES. */
159 print_array (int values[], size_t cnt)
164 for (i = 0; i < cnt; i++)
165 printf (" %d", values[i]);
169 /* Compares the `x' values in A and B and returns a strcmp-type
170 return value. Verifies that AUX points to aux_data. */
172 compare_elements (const struct ll *a_, const struct ll *b_, void *aux)
174 const struct element *a = ll_to_element (a_);
175 const struct element *b = ll_to_element (b_);
177 check (aux == &aux_data);
178 return a->x < b->x ? -1 : a->x > b->x;
181 /* Compares the `x' and `y' values in A and B and returns a
182 strcmp-type return value. Verifies that AUX points to
185 compare_elements_x_y (const struct ll *a_, const struct ll *b_, void *aux)
187 const struct element *a = ll_to_element (a_);
188 const struct element *b = ll_to_element (b_);
190 check (aux == &aux_data);
192 return a->x < b->x ? -1 : 1;
193 else if (a->y != b->y)
194 return a->y < b->y ? -1 : 1;
199 /* Compares the `y' values in A and B and returns a strcmp-type
200 return value. Verifies that AUX points to aux_data. */
202 compare_elements_y (const struct ll *a_, const struct ll *b_, void *aux)
204 const struct element *a = ll_to_element (a_);
205 const struct element *b = ll_to_element (b_);
207 check (aux == &aux_data);
208 return a->y < b->y ? -1 : a->y > b->y;
211 /* Returns true if the bit in *PATTERN indicated by `x in
212 *ELEMENT is set, false otherwise. */
214 pattern_pred (const struct ll *element_, void *pattern_)
216 const struct element *element = ll_to_element (element_);
217 unsigned int *pattern = pattern_;
219 return (*pattern & (1u << element->x)) != 0;
222 /* Allocates N elements in *ELEMS.
223 Adds the elements to LIST, if it is nonnull.
224 Puts pointers to the elements' list elements in *ELEMP,
225 followed by a pointer to the list null element, if ELEMP is
227 Allocates space for N values in *VALUES, if VALUES is
230 allocate_elements (size_t n,
231 struct ll_list *list,
232 struct element ***elems,
241 *elems = xnmalloc (n, sizeof **elems);
242 for (i = 0; i < n; i++)
244 (*elems)[i] = xmalloc (sizeof ***elems);
246 ll_push_tail (list, &(*elems)[i]->ll);
251 *elemp = xnmalloc (n + 1, sizeof *elemp);
252 for (i = 0; i < n; i++)
253 (*elemp)[i] = &(*elems)[i]->ll;
254 (*elemp)[n] = ll_null (list);
258 *values = xnmalloc (n, sizeof *values);
261 /* Copies the CNT values of `x' from LIST into VALUES[]. */
263 extract_values (struct ll_list *list, int values[], size_t cnt)
267 check (ll_count (list) == cnt);
268 for (x = ll_head (list); x != ll_null (list); x = ll_next (x))
270 struct element *e = ll_to_element (x);
275 /* As allocate_elements, but sets ascending values, starting
276 from 0, in `x' values in *ELEMS and in *VALUES (if
279 allocate_ascending (size_t n,
280 struct ll_list *list,
281 struct element ***elems,
287 allocate_elements (n, list, elems, elemp, values);
289 for (i = 0; i < n; i++)
292 extract_values (list, *values, n);
295 /* As allocate_elements, but sets binary values extracted from
296 successive bits in PATTERN in `x' values in *ELEMS and in
297 *VALUES (if nonnull). */
299 allocate_pattern (size_t n,
301 struct ll_list *list,
302 struct element ***elems,
308 allocate_elements (n, list, elems, elemp, values);
310 for (i = 0; i < n; i++)
311 (*elems)[i]->x = (pattern & (1 << i)) != 0;
313 extract_values (list, *values, n);
316 /* Randomly shuffles the CNT elements in ARRAY, each of which is
317 SIZE bytes in size. */
319 random_shuffle (void *array_, size_t cnt, size_t size)
321 char *array = array_;
322 char *tmp = xmalloc (size);
325 for (i = 0; i < cnt; i++)
327 size_t j = rand () % (cnt - i) + i;
330 memcpy (tmp, array + j * size, size);
331 memcpy (array + j * size, array + i * size, size);
332 memcpy (array + i * size, tmp, size);
339 /* As allocate_ascending, but orders the values randomly. */
341 allocate_random (size_t n,
342 struct ll_list *list,
343 struct element ***elems,
349 allocate_elements (n, list, elems, elemp, values);
351 for (i = 0; i < n; i++)
353 random_shuffle (*elems, n, sizeof **elems);
355 extract_values (list, *values, n);
358 /* Frees the N elements of ELEMS, ELEMP, and VALUES. */
360 free_elements (size_t n,
361 struct element **elems,
367 for (i = 0; i < n; i++)
374 /* Compares A and B and returns a strcmp-type return value. */
376 compare_ints (const void *a_, const void *b_, void *aux UNUSED)
381 return *a < *b ? -1 : *a > *b;
384 /* Compares A and B and returns a strcmp-type return value. */
386 compare_ints_noaux (const void *a_, const void *b_)
391 return *a < *b ? -1 : *a > *b;
394 /* Checks that LIST contains the CNT values in ELEMENTS. */
396 check_list_contents (struct ll_list *list, int elements[], size_t cnt)
401 check ((cnt == 0) == ll_is_empty (list));
403 /* Iterate in forward order. */
404 for (ll = ll_head (list), i = 0; i < cnt; ll = ll_next (ll), i++)
406 struct element *e = ll_to_element (ll);
407 check (elements[i] == e->x);
408 check (ll != ll_null (list));
410 check (ll == ll_null (list));
412 /* Iterate in reverse order. */
413 for (ll = ll_tail (list), i = 0; i < cnt; ll = ll_prev (ll), i++)
415 struct element *e = ll_to_element (ll);
416 check (elements[cnt - i - 1] == e->x);
417 check (ll != ll_null (list));
419 check (ll == ll_null (list));
421 check (ll_count (list) == cnt);
424 /* Lexicographically compares ARRAY1, which contains COUNT1
425 elements of SIZE bytes each, to ARRAY2, which contains COUNT2
426 elements of SIZE bytes, according to COMPARE. Returns a
427 strcmp-type result. AUX is passed to COMPARE as auxiliary
430 lexicographical_compare_3way (const void *array1, size_t count1,
431 const void *array2, size_t count2,
433 int (*compare) (const void *, const void *,
437 const char *first1 = array1;
438 const char *first2 = array2;
439 size_t min_count = count1 < count2 ? count1 : count2;
441 while (min_count > 0)
443 int cmp = compare (first1, first2, aux);
452 return count1 < count2 ? -1 : count1 > count2;
457 /* Tests list push and pop operations. */
461 const int max_elems = 1024;
464 struct element **elems;
469 allocate_elements (max_elems, NULL, &elems, NULL, &values);
473 check_list_contents (&list, NULL, 0);
474 for (i = 0; i < max_elems; i++)
476 values[i] = elems[i]->x = i;
477 ll_push_tail (&list, &elems[i]->ll);
478 check_list_contents (&list, values, i + 1);
481 /* Remove from tail. */
482 for (i = 0; i < max_elems; i++)
484 struct element *e = ll_to_element (ll_pop_tail (&list));
485 check (e->x == max_elems - i - 1);
486 check_list_contents (&list, values, max_elems - i - 1);
490 check_list_contents (&list, NULL, 0);
491 for (i = 0; i < max_elems; i++)
493 values[max_elems - i - 1] = elems[i]->x = max_elems - i - 1;
494 ll_push_head (&list, &elems[i]->ll);
495 check_list_contents (&list, &values[max_elems - i - 1], i + 1);
498 /* Remove from start. */
499 for (i = 0; i < max_elems; i++)
501 struct element *e = ll_to_element (ll_pop_head (&list));
502 check (e->x == (int) i);
503 check_list_contents (&list, &values[i + 1], max_elems - i - 1);
506 free_elements (max_elems, elems, NULL, values);
509 /* Tests insertion and removal at arbitrary positions. */
511 test_insert_remove (void)
513 const int max_elems = 16;
516 for (cnt = 0; cnt < max_elems; cnt++)
518 struct element **elems;
520 int *values = xnmalloc (cnt + 1, sizeof *values);
523 struct element extra;
526 allocate_ascending (cnt, &list, &elems, &elemp, NULL);
528 for (pos = 0; pos <= cnt; pos++)
532 ll_insert (elemp[pos], &extra.ll);
535 for (i = 0; i < pos; i++)
540 check_list_contents (&list, values, cnt + 1);
542 ll_remove (&extra.ll);
544 check_list_contents (&list, values, cnt);
546 free_elements (cnt, elems, elemp, values);
550 /* Tests swapping individual elements. */
554 const int max_elems = 8;
557 for (cnt = 0; cnt <= max_elems; cnt++)
560 struct element **elems;
565 allocate_ascending (cnt, &list, &elems, NULL, &values);
566 check_list_contents (&list, values, cnt);
568 for (i = 0; i < cnt; i++)
569 for (j = 0; j < cnt; j++)
570 for (k = 0; k < 2; k++)
574 ll_swap (&elems[i]->ll, &elems[j]->ll);
576 values[i] = values[j];
578 check_list_contents (&list, values, cnt);
581 free_elements (cnt, elems, NULL, values);
585 /* Tests swapping ranges of list elements. */
587 test_swap_range (void)
589 const int max_elems = 8;
590 int cnt, a0, a1, b0, b1, r;
592 for (cnt = 0; cnt <= max_elems; cnt++)
593 for (a0 = 0; a0 <= cnt; a0++)
594 for (a1 = a0; a1 <= cnt; a1++)
595 for (b0 = a1; b0 <= cnt; b0++)
596 for (b1 = b0; b1 <= cnt; b1++)
597 for (r = 0; r < 2; r++)
600 struct element **elems;
606 allocate_ascending (cnt, &list, &elems, &elemp, &values);
607 check_list_contents (&list, values, cnt);
610 for (i = 0; i < a0; i++)
612 for (i = b0; i < b1; i++)
614 for (i = a1; i < b0; i++)
616 for (i = a0; i < a1; i++)
618 for (i = b1; i < cnt; i++)
623 ll_swap_range (elemp[a0], elemp[a1], elemp[b0], elemp[b1]);
625 ll_swap_range (elemp[b0], elemp[b1], elemp[a0], elemp[a1]);
626 check_list_contents (&list, values, cnt);
628 free_elements (cnt, elems, elemp, values);
632 /* Tests removing ranges of list elements. */
634 test_remove_range (void)
636 const int max_elems = 8;
640 for (cnt = 0; cnt <= max_elems; cnt++)
641 for (r0 = 0; r0 <= cnt; r0++)
642 for (r1 = r0; r1 <= cnt; r1++)
645 struct element **elems;
651 allocate_ascending (cnt, &list, &elems, &elemp, &values);
652 check_list_contents (&list, values, cnt);
655 for (i = 0; i < r0; i++)
657 for (i = r1; i < cnt; i++)
660 ll_remove_range (elemp[r0], elemp[r1]);
661 check_list_contents (&list, values, j);
663 free_elements (cnt, elems, elemp, values);
667 /* Tests ll_remove_equal. */
669 test_remove_equal (void)
671 const int max_elems = 8;
673 int cnt, r0, r1, eq_pat;
675 for (cnt = 0; cnt <= max_elems; cnt++)
676 for (r0 = 0; r0 <= cnt; r0++)
677 for (r1 = r0; r1 <= cnt; r1++)
678 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
681 struct element **elems;
685 struct element to_remove;
689 allocate_elements (cnt, &list, &elems, &elemp, &values);
692 for (i = 0; i < cnt; i++)
694 int x = eq_pat & (1 << i) ? -1 : i;
695 bool delete = x == -1 && r0 <= i && i < r1;
698 values[remaining++] = x;
702 check ((int) ll_remove_equal (elemp[r0], elemp[r1], &to_remove.ll,
703 compare_elements, &aux_data)
705 check_list_contents (&list, values, remaining);
707 free_elements (cnt, elems, elemp, values);
711 /* Tests ll_remove_if. */
713 test_remove_if (void)
715 const int max_elems = 8;
717 int cnt, r0, r1, pattern;
719 for (cnt = 0; cnt <= max_elems; cnt++)
720 for (r0 = 0; r0 <= cnt; r0++)
721 for (r1 = r0; r1 <= cnt; r1++)
722 for (pattern = 0; pattern <= 1 << cnt; pattern++)
725 struct element **elems;
732 allocate_elements (cnt, &list, &elems, &elemp, &values);
735 for (i = 0; i < cnt; i++)
737 bool delete = (pattern & (1 << i)) && r0 <= i && i < r1;
740 values[remaining++] = i;
743 check ((int) ll_remove_if (elemp[r0], elemp[r1],
744 pattern_pred, &pattern)
746 check_list_contents (&list, values, remaining);
748 free_elements (cnt, elems, elemp, values);
752 /* Tests ll_moved. */
756 const int max_elems = 8;
760 for (cnt = 0; cnt <= max_elems; cnt++)
763 struct element **elems;
764 struct element **new_elems;
769 allocate_ascending (cnt, &list, &elems, NULL, &values);
770 allocate_elements (cnt, NULL, &new_elems, NULL, NULL);
771 check_list_contents (&list, values, cnt);
773 for (i = 0; i < cnt; i++)
775 *new_elems[i] = *elems[i];
776 ll_moved (&new_elems[i]->ll);
777 check_list_contents (&list, values, cnt);
780 free_elements (cnt, elems, NULL, values);
781 free_elements (cnt, new_elems, NULL, NULL);
785 /* Tests, via HELPER, a function that looks at list elements
786 equal to some specified element. */
788 test_examine_equal_range (void (*helper) (int r0, int r1, int eq_pat,
792 const int max_elems = 8;
794 int cnt, r0, r1, eq_pat;
796 for (cnt = 0; cnt <= max_elems; cnt++)
797 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
800 struct element **elems;
804 struct element to_find;
808 allocate_ascending (cnt, &list, &elems, &elemp, &values);
810 for (i = 0; i < cnt; i++)
811 if (eq_pat & (1 << i))
812 values[i] = elems[i]->x = -1;
815 for (r0 = 0; r0 <= cnt; r0++)
816 for (r1 = r0; r1 <= cnt; r1++)
817 helper (r0, r1, eq_pat, &to_find.ll, elemp);
819 check_list_contents (&list, values, cnt);
821 free_elements (cnt, elems, elemp, values);
825 /* Tests, via HELPER, a function that looks at list elements for
826 which a given predicate returns true. */
828 test_examine_if_range (void (*helper) (int r0, int r1, int eq_pat,
831 const int max_elems = 8;
833 int cnt, r0, r1, eq_pat;
835 for (cnt = 0; cnt <= max_elems; cnt++)
836 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
839 struct element **elems;
843 allocate_ascending (cnt, &list, &elems, &elemp, &values);
845 for (r0 = 0; r0 <= cnt; r0++)
846 for (r1 = r0; r1 <= cnt; r1++)
847 helper (r0, r1, eq_pat, elemp);
849 check_list_contents (&list, values, cnt);
851 free_elements (cnt, elems, elemp, values);
855 /* Helper function for testing ll_find_equal. */
857 test_find_equal_helper (int r0, int r1, int eq_pat,
858 struct ll *to_find, struct ll **elemp)
863 match = ll_find_equal (elemp[r0], elemp[r1], to_find,
864 compare_elements, &aux_data);
865 for (i = r0; i < r1; i++)
866 if (eq_pat & (1 << i))
869 check (match == elemp[i]);
872 /* Tests ll_find_equal. */
874 test_find_equal (void)
876 test_examine_equal_range (test_find_equal_helper);
879 /* Helper function for testing ll_find_if. */
881 test_find_if_helper (int r0, int r1, int eq_pat, struct ll **elemp)
883 struct ll *match = ll_find_if (elemp[r0], elemp[r1],
884 pattern_pred, &eq_pat);
887 for (i = r0; i < r1; i++)
888 if (eq_pat & (1 << i))
891 check (match == elemp[i]);
894 /* Tests ll_find_if. */
898 test_examine_if_range (test_find_if_helper);
901 /* Tests ll_find_adjacent_equal. */
903 test_find_adjacent_equal (void)
905 const int max_elems = 8;
909 for (cnt = 0; cnt <= max_elems; cnt++)
910 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
913 struct element **elems;
920 allocate_ascending (cnt, &list, &elems, &elemp, &values);
923 for (i = 0; i < cnt - 1; i++)
926 if (eq_pat & (1 << i))
928 values[i] = elems[i]->x = match;
929 values[i + 1] = elems[i + 1]->x = match;
935 for (i = 0; i <= cnt; i++)
937 struct ll *ll1 = ll_find_adjacent_equal (elemp[i], ll_null (&list),
943 ll2 = ll_null (&list);
944 for (j = i; j < cnt - 1; j++)
945 if (eq_pat & (1 << j))
952 check_list_contents (&list, values, cnt);
954 free_elements (cnt, elems, elemp, values);
958 /* Helper function for testing ll_count_range. */
960 test_count_range_helper (int r0, int r1, int eq_pat UNUSED, struct ll **elemp)
962 check ((int) ll_count_range (elemp[r0], elemp[r1]) == r1 - r0);
965 /* Tests ll_count_range. */
967 test_count_range (void)
969 test_examine_if_range (test_count_range_helper);
972 /* Helper function for testing ll_count_equal. */
974 test_count_equal_helper (int r0, int r1, int eq_pat,
975 struct ll *to_find, struct ll **elemp)
980 count1 = ll_count_equal (elemp[r0], elemp[r1], to_find,
981 compare_elements, &aux_data);
983 for (i = r0; i < r1; i++)
984 if (eq_pat & (1 << i))
987 check (count1 == count2);
990 /* Tests ll_count_equal. */
992 test_count_equal (void)
994 test_examine_equal_range (test_count_equal_helper);
997 /* Helper function for testing ll_count_if. */
999 test_count_if_helper (int r0, int r1, int eq_pat, struct ll **elemp)
1005 count1 = ll_count_if (elemp[r0], elemp[r1], pattern_pred, &eq_pat);
1008 for (i = r0; i < r1; i++)
1009 if (eq_pat & (1 << i))
1012 check (count1 == count2);
1015 /* Tests ll_count_if. */
1017 test_count_if (void)
1019 test_examine_if_range (test_count_if_helper);
1024 factorial (unsigned int n)
1026 unsigned int value = 1;
1032 /* Returns the number of permutations of the CNT values in
1033 VALUES. If VALUES contains duplicates, they must be
1036 expected_perms (int *values, size_t cnt)
1039 unsigned int perm_cnt;
1041 perm_cnt = factorial (cnt);
1042 for (i = 0; i < cnt; i = j)
1044 for (j = i + 1; j < cnt; j++)
1045 if (values[i] != values[j])
1047 perm_cnt /= factorial (j - i);
1052 /* Tests ll_min and ll_max. */
1056 const int max_elems = 6;
1059 for (cnt = 0; cnt <= max_elems; cnt++)
1061 struct ll_list list;
1062 struct element **elems;
1065 int *new_values = xnmalloc (cnt, sizeof *values);
1069 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1072 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1073 compare_elements, &aux_data))
1079 for (i = 0, x = ll_head (&list); x != ll_null (&list);
1080 x = ll_next (x), i++)
1082 struct element *e = ll_to_element (x);
1084 new_values[i] = e->x;
1086 for (r0 = 0; r0 <= cnt; r0++)
1087 for (r1 = r0; r1 <= cnt; r1++)
1089 struct ll *min = ll_min (elemp[r0], elemp[r1],
1090 compare_elements, &aux_data);
1091 struct ll *max = ll_max (elemp[r0], elemp[r1],
1092 compare_elements, &aux_data);
1095 check (min == elemp[r1]);
1096 check (max == elemp[r1]);
1100 int min_int, max_int;
1103 min_int = max_int = new_values[r0];
1104 for (i = r0; i < r1; i++)
1106 int value = new_values[i];
1107 if (value < min_int)
1109 if (value > max_int)
1112 check (min != elemp[r1]
1113 && ll_to_element (min)->x == min_int);
1114 check (max != elemp[r1]
1115 && ll_to_element (max)->x == max_int);
1120 check (perm_cnt == factorial (cnt));
1121 check_list_contents (&list, values, cnt);
1123 free_elements (cnt, elems, elemp, values);
1128 /* Tests ll_lexicographical_compare_3way. */
1130 test_lexicographical_compare_3way (void)
1132 const int max_elems = 4;
1134 int cnt_a, pat_a, cnt_b, pat_b;
1136 for (cnt_a = 0; cnt_a <= max_elems; cnt_a++)
1137 for (pat_a = 0; pat_a <= 1 << cnt_a; pat_a++)
1138 for (cnt_b = 0; cnt_b <= max_elems; cnt_b++)
1139 for (pat_b = 0; pat_b <= 1 << cnt_b; pat_b++)
1141 struct ll_list list_a, list_b;
1142 struct element **elems_a, **elems_b;
1143 struct ll **elemp_a, **elemp_b;
1144 int *values_a, *values_b;
1148 allocate_pattern (cnt_a, pat_a,
1149 &list_a, &elems_a, &elemp_a, &values_a);
1150 allocate_pattern (cnt_b, pat_b,
1151 &list_b, &elems_b, &elemp_b, &values_b);
1153 for (a0 = 0; a0 <= cnt_a; a0++)
1154 for (a1 = a0; a1 <= cnt_a; a1++)
1155 for (b0 = 0; b0 <= cnt_b; b0++)
1156 for (b1 = b0; b1 <= cnt_b; b1++)
1158 int a_ordering = lexicographical_compare_3way (
1159 values_a + a0, a1 - a0,
1160 values_b + b0, b1 - b0,
1162 compare_ints, NULL);
1164 int b_ordering = ll_lexicographical_compare_3way (
1165 elemp_a[a0], elemp_a[a1],
1166 elemp_b[b0], elemp_b[b1],
1167 compare_elements, &aux_data);
1169 check (a_ordering == b_ordering);
1172 free_elements (cnt_a, elems_a, elemp_a, values_a);
1173 free_elements (cnt_b, elems_b, elemp_b, values_b);
1177 /* Appends the `x' value in element E to the array pointed to by
1178 NEXT_OUTPUT, and advances NEXT_OUTPUT to the next position. */
1180 apply_func (struct ll *e_, void *next_output_)
1182 struct element *e = ll_to_element (e_);
1183 int **next_output = next_output_;
1185 *(*next_output)++ = e->x;
1188 /* Tests ll_apply. */
1192 const int max_elems = 8;
1196 for (cnt = 0; cnt <= max_elems; cnt++)
1197 for (r0 = 0; r0 <= cnt; r0++)
1198 for (r1 = r0; r1 <= cnt; r1++)
1200 struct ll_list list;
1201 struct element **elems;
1210 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1211 check_list_contents (&list, values, cnt);
1213 output = next_output = xnmalloc (cnt, sizeof *output);
1214 ll_apply (elemp[r0], elemp[r1], apply_func, &next_output);
1215 check_list_contents (&list, values, cnt);
1217 check (r1 - r0 == next_output - output);
1218 for (i = 0; i < r1 - r0; i++)
1219 check (output[i] == r0 + i);
1221 free_elements (cnt, elems, elemp, values);
1226 /* Tests ll_reverse. */
1230 const int max_elems = 8;
1234 for (cnt = 0; cnt <= max_elems; cnt++)
1235 for (r0 = 0; r0 <= cnt; r0++)
1236 for (r1 = r0; r1 <= cnt; r1++)
1238 struct ll_list list;
1239 struct element **elems;
1245 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1246 check_list_contents (&list, values, cnt);
1249 for (i = 0; i < r0; i++)
1251 for (i = r1 - 1; i >= r0; i--)
1253 for (i = r1; i < cnt; i++)
1256 ll_reverse (elemp[r0], elemp[r1]);
1257 check_list_contents (&list, values, cnt);
1259 free_elements (cnt, elems, elemp, values);
1263 /* Tests ll_next_permutation and ll_prev_permutation when the
1264 permuted values have no duplicates. */
1266 test_permutations_no_dups (void)
1268 const int max_elems = 8;
1271 for (cnt = 0; cnt <= max_elems; cnt++)
1273 struct ll_list list;
1274 struct element **elems;
1276 int *old_values = xnmalloc (cnt, sizeof *values);
1277 int *new_values = xnmalloc (cnt, sizeof *values);
1281 allocate_ascending (cnt, &list, &elems, NULL, &values);
1284 extract_values (&list, old_values, cnt);
1285 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1286 compare_elements, &aux_data))
1288 extract_values (&list, new_values, cnt);
1289 check (lexicographical_compare_3way (new_values, cnt,
1292 compare_ints, NULL) > 0);
1293 memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1296 check (perm_cnt == factorial (cnt));
1297 check_list_contents (&list, values, cnt);
1300 ll_reverse (ll_head (&list), ll_null (&list));
1301 extract_values (&list, old_values, cnt);
1302 while (ll_prev_permutation (ll_head (&list), ll_null (&list),
1303 compare_elements, &aux_data))
1305 extract_values (&list, new_values, cnt);
1306 check (lexicographical_compare_3way (new_values, cnt,
1309 compare_ints, NULL) < 0);
1310 memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1313 check (perm_cnt == factorial (cnt));
1314 ll_reverse (ll_head (&list), ll_null (&list));
1315 check_list_contents (&list, values, cnt);
1317 free_elements (cnt, elems, NULL, values);
1323 /* Tests ll_next_permutation and ll_prev_permutation when the
1324 permuted values contain duplicates. */
1326 test_permutations_with_dups (void)
1328 const int max_elems = 8;
1329 const int max_dup = 3;
1330 const int repetitions = 1024;
1334 for (repeat = 0; repeat < repetitions; repeat++)
1335 for (cnt = 0; cnt < max_elems; cnt++)
1337 struct ll_list list;
1338 struct element **elems;
1340 int *old_values = xnmalloc (max_elems, sizeof *values);
1341 int *new_values = xnmalloc (max_elems, sizeof *values);
1343 unsigned int permutation_cnt;
1347 allocate_elements (cnt, &list, &elems, NULL, &values);
1352 int max = left < max_dup ? left : max_dup;
1353 int n = rand () % max + 1;
1356 int idx = cnt - left--;
1357 values[idx] = elems[idx]->x = value;
1362 permutation_cnt = 1;
1363 extract_values (&list, old_values, cnt);
1364 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1365 compare_elements, &aux_data))
1367 extract_values (&list, new_values, cnt);
1368 check (lexicographical_compare_3way (new_values, cnt,
1371 compare_ints, NULL) > 0);
1372 memcpy (old_values, new_values, cnt * sizeof *old_values);
1375 check (permutation_cnt == expected_perms (values, cnt));
1376 check_list_contents (&list, values, cnt);
1378 permutation_cnt = 1;
1379 ll_reverse (ll_head (&list), ll_null (&list));
1380 extract_values (&list, old_values, cnt);
1381 while (ll_prev_permutation (ll_head (&list), ll_null (&list),
1382 compare_elements, &aux_data))
1384 extract_values (&list, new_values, cnt);
1385 check (lexicographical_compare_3way (new_values, cnt,
1388 compare_ints, NULL) < 0);
1391 ll_reverse (ll_head (&list), ll_null (&list));
1392 check (permutation_cnt == expected_perms (values, cnt));
1393 check_list_contents (&list, values, cnt);
1395 free_elements (cnt, elems, NULL, values);
1401 /* Tests ll_merge when no equal values are to be merged. */
1403 test_merge_no_dups (void)
1405 const int max_elems = 8;
1406 const int max_filler = 3;
1408 int merge_cnt, pattern, pfx, gap, sfx, order;
1410 for (merge_cnt = 0; merge_cnt < max_elems; merge_cnt++)
1411 for (pattern = 0; pattern <= (1 << merge_cnt); pattern++)
1412 for (pfx = 0; pfx < max_filler; pfx++)
1413 for (gap = 0; gap < max_filler; gap++)
1414 for (sfx = 0; sfx < max_filler; sfx++)
1415 for (order = 0; order < 2; order++)
1417 struct ll_list list;
1418 struct element **elems;
1422 int list_cnt = pfx + merge_cnt + gap + sfx;
1426 allocate_elements (list_cnt, &list,
1427 &elems, &elemp, &values);
1430 for (i = 0; i < pfx; i++)
1431 elems[j++]->x = 100 + i;
1433 for (i = 0; i < merge_cnt; i++)
1434 if (pattern & (1u << i))
1437 for (i = 0; i < gap; i++)
1438 elems[j++]->x = 200 + i;
1440 for (i = 0; i < merge_cnt; i++)
1441 if (!(pattern & (1u << i)))
1444 for (i = 0; i < sfx; i++)
1445 elems[j++]->x = 300 + i;
1446 check (list_cnt == j);
1449 for (i = 0; i < pfx; i++)
1450 values[j++] = 100 + i;
1452 for (i = 0; i < merge_cnt; i++)
1454 for (i = 0; i < gap; i++)
1455 values[j++] = 200 + i;
1457 for (i = 0; i < merge_cnt; i++)
1459 for (i = 0; i < sfx; i++)
1460 values[j++] = 300 + i;
1461 check (list_cnt == j);
1464 ll_merge (elemp[a0], elemp[a1], elemp[b0], elemp[b1],
1465 compare_elements, &aux_data);
1467 ll_merge (elemp[b0], elemp[b1], elemp[a0], elemp[a1],
1468 compare_elements, &aux_data);
1470 check_list_contents (&list, values, list_cnt);
1472 free_elements (list_cnt, elems, elemp, values);
1476 /* Tests ll_merge when equal values are to be merged. */
1478 test_merge_with_dups (void)
1480 const int max_elems = 8;
1482 int cnt, merge_pat, inc_pat, order;
1484 for (cnt = 0; cnt <= max_elems; cnt++)
1485 for (merge_pat = 0; merge_pat <= (1 << cnt); merge_pat++)
1486 for (inc_pat = 0; inc_pat <= (1 << cnt); inc_pat++)
1487 for (order = 0; order < 2; order++)
1489 struct ll_list list;
1490 struct element **elems;
1497 allocate_elements (cnt, &list, &elems, &elemp, &values);
1500 for (i = k = 0; i < cnt; i++)
1502 if (merge_pat & (1u << i))
1504 if (inc_pat & (1u << i))
1508 for (i = k = 0; i < cnt; i++)
1510 if (!(merge_pat & (1u << i)))
1512 if (inc_pat & (1u << i))
1519 for (i = 0; i < cnt; i++)
1524 for (i = 0; i < mid; i++)
1525 elems[i]->y = 100 + i;
1526 for (i = mid; i < cnt; i++)
1531 for (i = k = 0; i < cnt; i++)
1534 if (inc_pat & (1u << i))
1540 ll_merge (elemp[0], elemp[mid], elemp[mid], elemp[cnt],
1541 compare_elements, &aux_data);
1543 ll_merge (elemp[mid], elemp[cnt], elemp[0], elemp[mid],
1544 compare_elements, &aux_data);
1546 check_list_contents (&list, values, cnt);
1547 check (ll_is_sorted (ll_head (&list), ll_null (&list),
1548 compare_elements_x_y, &aux_data));
1550 free_elements (cnt, elems, elemp, values);
1554 /* Tests ll_sort on all permutations up to a maximum number of
1557 test_sort_exhaustive (void)
1559 const int max_elems = 8;
1562 for (cnt = 0; cnt <= max_elems; cnt++)
1564 struct ll_list list;
1565 struct element **elems;
1568 struct element **perm_elems;
1573 allocate_ascending (cnt, &list, &elems, NULL, &values);
1574 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1577 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1578 compare_elements, &aux_data))
1580 struct ll_list perm_list;
1583 extract_values (&list, perm_values, cnt);
1584 ll_init (&perm_list);
1585 for (j = 0; j < cnt; j++)
1587 perm_elems[j]->x = perm_values[j];
1588 ll_push_tail (&perm_list, &perm_elems[j]->ll);
1590 ll_sort (ll_head (&perm_list), ll_null (&perm_list),
1591 compare_elements, &aux_data);
1592 check_list_contents (&perm_list, values, cnt);
1593 check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1594 compare_elements, &aux_data));
1597 check (perm_cnt == factorial (cnt));
1599 free_elements (cnt, elems, NULL, values);
1600 free_elements (cnt, perm_elems, NULL, perm_values);
1604 /* Tests that ll_sort is stable in the presence of equal
1607 test_sort_stable (void)
1609 const int max_elems = 6;
1612 for (cnt = 0; cnt <= max_elems; cnt++)
1613 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1615 struct ll_list list;
1616 struct element **elems;
1619 struct element **perm_elems;
1625 allocate_elements (cnt, &list, &elems, NULL, &values);
1626 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1629 for (i = 0; i < cnt; i++)
1631 elems[i]->x = values[i] = j;
1632 if (inc_pat & (1 << i))
1638 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1639 compare_elements_y, &aux_data))
1641 struct ll_list perm_list;
1643 extract_values (&list, perm_values, cnt);
1644 ll_init (&perm_list);
1645 for (i = 0; i < cnt; i++)
1647 perm_elems[i]->x = perm_values[i];
1648 perm_elems[i]->y = i;
1649 ll_push_tail (&perm_list, &perm_elems[i]->ll);
1651 ll_sort (ll_head (&perm_list), ll_null (&perm_list),
1652 compare_elements, &aux_data);
1653 check_list_contents (&perm_list, values, cnt);
1654 check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1655 compare_elements_x_y, &aux_data));
1658 check (perm_cnt == factorial (cnt));
1660 free_elements (cnt, elems, NULL, values);
1661 free_elements (cnt, perm_elems, NULL, perm_values);
1665 /* Tests that ll_sort does not disturb elements outside the
1668 test_sort_subset (void)
1670 const int max_elems = 8;
1672 int cnt, r0, r1, repeat;
1674 for (cnt = 0; cnt <= max_elems; cnt++)
1675 for (repeat = 0; repeat < 100; repeat++)
1676 for (r0 = 0; r0 <= cnt; r0++)
1677 for (r1 = r0; r1 <= cnt; r1++)
1679 struct ll_list list;
1680 struct element **elems;
1684 allocate_random (cnt, &list, &elems, &elemp, &values);
1686 qsort (&values[r0], r1 - r0, sizeof *values, compare_ints_noaux);
1687 ll_sort (elemp[r0], elemp[r1], compare_elements, &aux_data);
1688 check_list_contents (&list, values, cnt);
1690 free_elements (cnt, elems, elemp, values);
1694 /* Tests that ll_sort works with large lists. */
1696 test_sort_big (void)
1698 const int max_elems = 1024;
1702 for (cnt = 0; cnt < max_elems; cnt++)
1704 struct ll_list list;
1705 struct element **elems;
1708 allocate_random (cnt, &list, &elems, NULL, &values);
1710 qsort (values, cnt, sizeof *values, compare_ints_noaux);
1711 ll_sort (ll_head (&list), ll_null (&list), compare_elements, &aux_data);
1712 check_list_contents (&list, values, cnt);
1714 free_elements (cnt, elems, NULL, values);
1718 /* Tests ll_unique. */
1722 const int max_elems = 10;
1724 int *ascending = xnmalloc (max_elems, sizeof *ascending);
1726 int cnt, inc_pat, i, j, unique_values;
1728 for (i = 0; i < max_elems; i++)
1731 for (cnt = 0; cnt < max_elems; cnt++)
1732 for (inc_pat = 0; inc_pat < (1 << cnt); inc_pat++)
1734 struct ll_list list, dups;
1735 struct element **elems;
1738 allocate_elements (cnt, &list, &elems, NULL, &values);
1740 j = unique_values = 0;
1741 for (i = 0; i < cnt; i++)
1743 unique_values = j + 1;
1744 elems[i]->x = values[i] = j;
1745 if (inc_pat & (1 << i))
1748 check_list_contents (&list, values, cnt);
1751 check (ll_unique (ll_head (&list), ll_null (&list), ll_null (&dups),
1752 compare_elements, &aux_data)
1753 == (size_t) unique_values);
1754 check_list_contents (&list, ascending, unique_values);
1756 ll_splice (ll_null (&list), ll_head (&dups), ll_null (&dups));
1757 ll_sort (ll_head (&list), ll_null (&list), compare_elements, &aux_data);
1758 check_list_contents (&list, values, cnt);
1760 free_elements (cnt, elems, NULL, values);
1766 /* Tests ll_sort_unique. */
1768 test_sort_unique (void)
1770 const int max_elems = 7;
1773 for (cnt = 0; cnt <= max_elems; cnt++)
1774 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1776 struct ll_list list;
1777 struct element **elems;
1780 struct element **perm_elems;
1789 allocate_elements (cnt, &list, &elems, NULL, &values);
1790 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1793 for (i = 0; i < cnt; i++)
1795 elems[i]->x = values[i] = j;
1797 if (inc_pat & (1 << i))
1801 unique_values = xnmalloc (unique_cnt, sizeof *unique_values);
1802 for (i = 0; i < unique_cnt; i++)
1803 unique_values[i] = i;
1806 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1807 compare_elements, &aux_data))
1809 struct ll_list perm_list;
1811 extract_values (&list, perm_values, cnt);
1812 ll_init (&perm_list);
1813 for (i = 0; i < cnt; i++)
1815 perm_elems[i]->x = perm_values[i];
1816 perm_elems[i]->y = i;
1817 ll_push_tail (&perm_list, &perm_elems[i]->ll);
1819 ll_sort_unique (ll_head (&perm_list), ll_null (&perm_list), NULL,
1820 compare_elements, &aux_data);
1821 check_list_contents (&perm_list, unique_values, unique_cnt);
1822 check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1823 compare_elements_x_y, &aux_data));
1826 check (perm_cnt == expected_perms (values, cnt));
1828 free_elements (cnt, elems, NULL, values);
1829 free_elements (cnt, perm_elems, NULL, perm_values);
1830 free (unique_values);
1834 /* Tests ll_insert_ordered. */
1836 test_insert_ordered (void)
1838 const int max_elems = 6;
1841 for (cnt = 0; cnt <= max_elems; cnt++)
1842 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1844 struct ll_list list;
1845 struct element **elems;
1848 struct element **perm_elems;
1854 allocate_elements (cnt, &list, &elems, NULL, &values);
1855 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1858 for (i = 0; i < cnt; i++)
1860 elems[i]->x = values[i] = j;
1861 if (inc_pat & (1 << i))
1867 while (ll_next_permutation (ll_head (&list), ll_null (&list),
1868 compare_elements_y, &aux_data))
1870 struct ll_list perm_list;
1872 extract_values (&list, perm_values, cnt);
1873 ll_init (&perm_list);
1874 for (i = 0; i < cnt; i++)
1876 perm_elems[i]->x = perm_values[i];
1877 perm_elems[i]->y = i;
1878 ll_insert_ordered (ll_head (&perm_list), ll_null (&perm_list),
1880 compare_elements, &aux_data);
1882 check (ll_is_sorted (ll_head (&perm_list), ll_null (&perm_list),
1883 compare_elements_x_y, &aux_data));
1886 check (perm_cnt == factorial (cnt));
1888 free_elements (cnt, elems, NULL, values);
1889 free_elements (cnt, perm_elems, NULL, perm_values);
1893 /* Tests ll_partition. */
1895 test_partition (void)
1897 const int max_elems = 10;
1903 for (cnt = 0; cnt < max_elems; cnt++)
1904 for (r0 = 0; r0 <= cnt; r0++)
1905 for (r1 = r0; r1 <= cnt; r1++)
1906 for (pbase = 0; pbase <= (1u << (r1 - r0)); pbase++)
1908 struct ll_list list;
1909 struct element **elems;
1913 unsigned int pattern = pbase << r0;
1918 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1920 /* Check that ll_find_partition works okay in every
1921 case. We use it after partitioning, too, but that
1922 only tests cases where it returns non-null. */
1923 for (i = r0; i < r1; i++)
1924 if (!(pattern & (1u << i)))
1928 if (pattern & (1u << i))
1930 part_ll = ll_find_partition (elemp[r0], elemp[r1],
1934 check (part_ll == elemp[j]);
1936 check (part_ll == NULL);
1938 /* Figure out expected results. */
1941 for (i = 0; i < r0; i++)
1943 for (i = r0; i < r1; i++)
1944 if (pattern & (1u << i))
1946 for (i = r0; i < r1; i++)
1947 if (!(pattern & (1u << i)))
1949 if (first_false == -1)
1953 if (first_false == -1)
1955 for (i = r1; i < cnt; i++)
1959 /* Partition and check for expected results. */
1960 check (ll_partition (elemp[r0], elemp[r1],
1961 pattern_pred, &pattern)
1962 == elemp[first_false]);
1963 check (ll_find_partition (elemp[r0], elemp[r1],
1964 pattern_pred, &pattern)
1965 == elemp[first_false]);
1966 check_list_contents (&list, values, cnt);
1967 check ((int) ll_count (&list) == cnt);
1969 free_elements (cnt, elems, elemp, values);
1975 /* Runs TEST_FUNCTION and prints a message about NAME. */
1977 run_test (void (*test_function) (void), const char *name)
1988 run_test (test_push_pop, "push/pop");
1989 run_test (test_insert_remove, "insert/remove");
1990 run_test (test_swap, "swap");
1991 run_test (test_swap_range, "swap_range");
1992 run_test (test_remove_range, "remove_range");
1993 run_test (test_remove_equal, "remove_equal");
1994 run_test (test_remove_if, "remove_if");
1995 run_test (test_moved, "moved");
1996 run_test (test_find_equal, "find_equal");
1997 run_test (test_find_if, "find_if");
1998 run_test (test_find_adjacent_equal, "find_adjacent_equal");
1999 run_test (test_count_range, "count_range");
2000 run_test (test_count_equal, "count_equal");
2001 run_test (test_count_if, "count_if");
2002 run_test (test_min_max, "min/max");
2003 run_test (test_lexicographical_compare_3way, "lexicographical_compare_3way");
2004 run_test (test_apply, "apply");
2005 run_test (test_reverse, "reverse");
2006 run_test (test_permutations_no_dups, "permutations (no dups)");
2007 run_test (test_permutations_with_dups, "permutations (with dups)");
2008 run_test (test_merge_no_dups, "merge (no dups)");
2009 run_test (test_merge_with_dups, "merge (with dups)");
2010 run_test (test_sort_exhaustive, "sort (exhaustive)");
2011 run_test (test_sort_stable, "sort (stability)");
2012 run_test (test_sort_subset, "sort (subset)");
2013 run_test (test_sort_big, "sort (big)");
2014 run_test (test_unique, "unique");
2015 run_test (test_sort_unique, "sort_unique");
2016 run_test (test_insert_ordered, "insert_ordered");
2017 run_test (test_partition, "partition");
2025 compile-command: "gcc -Wall -Wstrict-prototypes -Wmissing-prototypes ll.c ll-test.c -o ll-test -g"