1 /* PSPP - computes sample statistics.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 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, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 /* This is a test program for the llx_* routines defined in
20 ll.c. This test program aims to be as comprehensive as
21 possible. "gcov -b" should report 100% coverage of lines and
22 branches in llx.c and llx.h. "valgrind --leak-check=yes
23 --show-reachable=yes" should give a clean report.
25 This test program depends only on ll.c, llx.c, and the
28 See ll-test.c for a similar program for the ll_* routines. */
34 #include <libpspp/llx.h>
40 /* Support preliminaries. */
41 #if __GNUC__ >= 2 && !defined UNUSED
42 #define UNUSED __attribute__ ((unused))
47 /* Currently running test. */
48 static const char *test_name;
50 /* Exit with a failure code.
51 (Place a breakpoint on this function while debugging.) */
58 /* If OK is not true, prints a message about failure on the
59 current source file and the given LINE and terminates. */
61 check_func (bool ok, int line)
65 printf ("Check failed in %s test at %s, line %d\n",
66 test_name, __FILE__, line);
71 /* Verifies that EXPR evaluates to true.
72 If not, prints a message citing the calling line number and
74 #define check(EXPR) check_func ((EXPR), __LINE__)
76 /* Prints a message about memory exhaustion and exits with a
81 printf ("virtual memory exhausted\n");
85 /* Allocates and returns N bytes of memory. */
101 /* Allocates and returns N * M bytes of memory. */
103 xnmalloc (size_t n, size_t m)
105 if ((size_t) -1 / m <= n)
107 return xmalloc (n * m);
110 /* Always returns a null pointer, failing allocation. */
112 null_allocate_node (void *aux UNUSED)
119 null_release_node (struct llx *llx UNUSED, void *aux UNUSED)
123 /* Memory manager that fails all allocations and does nothing on
125 static const struct llx_manager llx_null_mgr =
132 /* List type and support routines. */
134 /* Test data element. */
137 int x; /* Primary value. */
138 int y; /* Secondary value. */
143 /* Prints the elements in LIST. */
145 print_list (struct llx_list *list)
150 for (x = llx_head (list); x != llx_null (list); x = llx_next (x))
152 const struct element *e = llx_data (x);
153 printf (" %d", e->x);
158 /* Prints the value returned by PREDICATE given auxiliary data
159 AUX for each element in LIST. */
161 print_pred (struct llx_list *list,
162 llx_predicate_func *predicate, void *aux UNUSED)
167 for (x = llx_head (list); x != llx_null (list); x = llx_next (x))
168 printf (" %d", predicate (x, aux));
172 /* Prints the CNT numbers in VALUES. */
174 print_array (int values[], size_t cnt)
179 for (i = 0; i < cnt; i++)
180 printf (" %d", values[i]);
184 /* Compares the `x' values in A and B and returns a strcmp-type
185 return value. Verifies that AUX points to aux_data. */
187 compare_elements (const void *a_, const void *b_, void *aux)
189 const struct element *a = a_;
190 const struct element *b = b_;
192 check (aux == &aux_data);
193 return a->x < b->x ? -1 : a->x > b->x;
196 /* Compares the `x' and `y' values in A and B and returns a
197 strcmp-type return value. Verifies that AUX points to
200 compare_elements_x_y (const void *a_, const void *b_, void *aux)
202 const struct element *a = a_;
203 const struct element *b = b_;
205 check (aux == &aux_data);
207 return a->x < b->x ? -1 : 1;
208 else if (a->y != b->y)
209 return a->y < b->y ? -1 : 1;
214 /* Compares the `y' values in A and B and returns a strcmp-type
215 return value. Verifies that AUX points to aux_data. */
217 compare_elements_y (const void *a_, const void *b_, void *aux)
219 const struct element *a = a_;
220 const struct element *b = b_;
222 check (aux == &aux_data);
223 return a->y < b->y ? -1 : a->y > b->y;
226 /* Returns true if the bit in *PATTERN indicated by `x in
227 *ELEMENT is set, false otherwise. */
229 pattern_pred (const void *element_, void *pattern_)
231 const struct element *element = element_;
232 unsigned int *pattern = pattern_;
234 return (*pattern & (1u << element->x)) != 0;
237 /* Allocates N elements in *ELEMS.
238 Adds the elements to LIST, if it is nonnull.
239 Puts pointers to the elements' list elements in *ELEMP,
240 followed by a pointer to the list null element, if ELEMP is
242 Allocates space for N values in *VALUES, if VALUES is
245 allocate_elements (size_t n,
246 struct llx_list *list,
247 struct element ***elems,
256 *elems = xnmalloc (n, sizeof **elems);
259 *elemp = xnmalloc (n + 1, sizeof *elemp);
260 (*elemp)[n] = llx_null (list);
263 for (i = 0; i < n; i++)
265 (*elems)[i] = xmalloc (sizeof ***elems);
268 struct llx *llx = llx_push_tail (list, (*elems)[i], &llx_malloc_mgr);
275 *values = xnmalloc (n, sizeof *values);
278 /* Copies the CNT values of `x' from LIST into VALUES[]. */
280 extract_values (struct llx_list *list, int values[], size_t cnt)
284 check (llx_count (list) == cnt);
285 for (x = llx_head (list); x != llx_null (list); x = llx_next (x))
287 struct element *e = llx_data (x);
292 /* As allocate_elements, but sets ascending values, starting
293 from 0, in `x' values in *ELEMS and in *VALUES (if
296 allocate_ascending (size_t n,
297 struct llx_list *list,
298 struct element ***elems,
304 allocate_elements (n, list, elems, elemp, values);
306 for (i = 0; i < n; i++)
309 extract_values (list, *values, n);
312 /* As allocate_elements, but sets binary values extracted from
313 successive bits in PATTERN in `x' values in *ELEMS and in
314 *VALUES (if nonnull). */
316 allocate_pattern (size_t n,
318 struct llx_list *list,
319 struct element ***elems,
325 allocate_elements (n, list, elems, elemp, values);
327 for (i = 0; i < n; i++)
328 (*elems)[i]->x = (pattern & (1 << i)) != 0;
330 extract_values (list, *values, n);
333 /* Randomly shuffles the CNT elements in ARRAY, each of which is
334 SIZE bytes in size. */
336 random_shuffle (void *array_, size_t cnt, size_t size)
338 char *array = array_;
339 char *tmp = xmalloc (size);
342 for (i = 0; i < cnt; i++)
344 size_t j = rand () % (cnt - i) + i;
347 memcpy (tmp, array + j * size, size);
348 memcpy (array + j * size, array + i * size, size);
349 memcpy (array + i * size, tmp, size);
356 /* As allocate_ascending, but orders the values randomly. */
358 allocate_random (size_t n,
359 struct llx_list *list,
360 struct element ***elems,
366 allocate_elements (n, list, elems, elemp, values);
368 for (i = 0; i < n; i++)
370 random_shuffle (*elems, n, sizeof **elems);
372 extract_values (list, *values, n);
375 /* Frees LIST, the N elements of ELEMS, ELEMP, and VALUES. */
377 free_elements (size_t n,
378 struct llx_list *list,
379 struct element **elems,
386 llx_destroy (list, NULL, NULL, &llx_malloc_mgr);
387 for (i = 0; i < n; i++)
394 /* Compares A and B and returns a strcmp-type return value. */
396 compare_ints (const void *a_, const void *b_, void *aux UNUSED)
401 return *a < *b ? -1 : *a > *b;
404 /* Compares A and B and returns a strcmp-type return value. */
406 compare_ints_noaux (const void *a_, const void *b_)
411 return *a < *b ? -1 : *a > *b;
414 /* Checks that LIST contains the CNT values in ELEMENTS. */
416 check_list_contents (struct llx_list *list, int elements[], size_t cnt)
421 check ((cnt == 0) == llx_is_empty (list));
423 /* Iterate in forward order. */
424 for (llx = llx_head (list), i = 0; i < cnt; llx = llx_next (llx), i++)
426 struct element *e = llx_data (llx);
427 check (elements[i] == e->x);
428 check (llx != llx_null (list));
430 check (llx == llx_null (list));
432 /* Iterate in reverse order. */
433 for (llx = llx_tail (list), i = 0; i < cnt; llx = llx_prev (llx), i++)
435 struct element *e = llx_data (llx);
436 check (elements[cnt - i - 1] == e->x);
437 check (llx != llx_null (list));
439 check (llx == llx_null (list));
441 check (llx_count (list) == cnt);
444 /* Lexicographicallxy compares ARRAY1, which contains COUNT1
445 elements of SIZE bytes each, to ARRAY2, which contains COUNT2
446 elements of SIZE bytes, according to COMPARE. Returns a
447 strcmp-type result. AUX is passed to COMPARE as auxiliary
450 lexicographical_compare_3way (const void *array1, size_t count1,
451 const void *array2, size_t count2,
453 int (*compare) (const void *, const void *,
457 const char *first1 = array1;
458 const char *first2 = array2;
459 size_t min_count = count1 < count2 ? count1 : count2;
461 while (min_count > 0)
463 int cmp = compare (first1, first2, aux);
472 return count1 < count2 ? -1 : count1 > count2;
477 /* Tests list push and pop operations. */
481 const int max_elems = 1024;
483 struct llx_list list;
484 struct element **elems;
489 allocate_elements (max_elems, NULL, &elems, NULL, &values);
493 check_list_contents (&list, NULL, 0);
494 for (i = 0; i < max_elems; i++)
496 values[i] = elems[i]->x = i;
497 llx_push_tail (&list, elems[i], &llx_malloc_mgr);
498 check_list_contents (&list, values, i + 1);
501 /* Remove from tail. */
502 for (i = 0; i < max_elems; i++)
504 struct element *e = llx_pop_tail (&list, &llx_malloc_mgr);
505 check (e->x == max_elems - i - 1);
506 check_list_contents (&list, values, max_elems - i - 1);
510 check_list_contents (&list, NULL, 0);
511 for (i = 0; i < max_elems; i++)
513 values[max_elems - i - 1] = elems[i]->x = max_elems - i - 1;
514 llx_push_head (&list, elems[i], &llx_malloc_mgr);
515 check_list_contents (&list, &values[max_elems - i - 1], i + 1);
518 /* Remove from start. */
519 for (i = 0; i < max_elems; i++)
521 struct element *e = llx_pop_head (&list, &llx_malloc_mgr);
522 check (e->x == (int) i);
523 check_list_contents (&list, &values[i + 1], max_elems - i - 1);
526 free_elements (max_elems, &list, elems, NULL, values);
529 /* Tests insertion and removal at arbitrary positions. */
531 test_insert_remove (void)
533 const int max_elems = 16;
536 for (cnt = 0; cnt < max_elems; cnt++)
538 struct element **elems;
540 int *values = xnmalloc (cnt + 1, sizeof *values);
542 struct llx_list list;
543 struct element extra;
544 struct llx *extra_llx;
547 allocate_ascending (cnt, &list, &elems, &elemp, NULL);
549 for (pos = 0; pos <= cnt; pos++)
553 extra_llx = llx_insert (elemp[pos], &extra, &llx_malloc_mgr);
554 check (extra_llx != NULL);
557 for (i = 0; i < pos; i++)
562 check_list_contents (&list, values, cnt + 1);
564 llx_remove (extra_llx, &llx_malloc_mgr);
566 check_list_contents (&list, values, cnt);
568 free_elements (cnt, &list, elems, elemp, values);
572 /* Tests swapping individual elements. */
576 const int max_elems = 8;
579 for (cnt = 0; cnt <= max_elems; cnt++)
581 struct llx_list list;
582 struct element **elems;
588 allocate_ascending (cnt, &list, &elems, &elemp, &values);
589 check_list_contents (&list, values, cnt);
591 for (i = 0; i < cnt; i++)
592 for (j = 0; j < cnt; j++)
593 for (k = 0; k < 2; k++)
597 llx_swap (elemp[i], elemp[j]);
599 values[i] = values[j];
601 check_list_contents (&list, values, cnt);
604 free_elements (cnt, &list, elems, elemp, values);
608 /* Tests swapping ranges of list elements. */
610 test_swap_range (void)
612 const int max_elems = 8;
613 int cnt, a0, a1, b0, b1, r;
615 for (cnt = 0; cnt <= max_elems; cnt++)
616 for (a0 = 0; a0 <= cnt; a0++)
617 for (a1 = a0; a1 <= cnt; a1++)
618 for (b0 = a1; b0 <= cnt; b0++)
619 for (b1 = b0; b1 <= cnt; b1++)
620 for (r = 0; r < 2; r++)
622 struct llx_list list;
623 struct element **elems;
629 allocate_ascending (cnt, &list, &elems, &elemp, &values);
630 check_list_contents (&list, values, cnt);
633 for (i = 0; i < a0; i++)
635 for (i = b0; i < b1; i++)
637 for (i = a1; i < b0; i++)
639 for (i = a0; i < a1; i++)
641 for (i = b1; i < cnt; i++)
646 llx_swap_range (elemp[a0], elemp[a1], elemp[b0], elemp[b1]);
648 llx_swap_range (elemp[b0], elemp[b1], elemp[a0], elemp[a1]);
649 check_list_contents (&list, values, cnt);
651 free_elements (cnt, &list, elems, elemp, values);
655 /* Tests removing ranges of list elements. */
657 test_remove_range (void)
659 const int max_elems = 8;
663 for (cnt = 0; cnt <= max_elems; cnt++)
664 for (r0 = 0; r0 <= cnt; r0++)
665 for (r1 = r0; r1 <= cnt; r1++)
667 struct llx_list list;
668 struct element **elems;
674 allocate_ascending (cnt, &list, &elems, &elemp, &values);
675 check_list_contents (&list, values, cnt);
678 for (i = 0; i < r0; i++)
680 for (i = r1; i < cnt; i++)
683 llx_remove_range (elemp[r0], elemp[r1], &llx_malloc_mgr);
684 check_list_contents (&list, values, j);
686 free_elements (cnt, &list, elems, elemp, values);
690 /* Tests llx_remove_equal. */
692 test_remove_equal (void)
694 const int max_elems = 8;
696 int cnt, r0, r1, eq_pat;
698 for (cnt = 0; cnt <= max_elems; cnt++)
699 for (r0 = 0; r0 <= cnt; r0++)
700 for (r1 = r0; r1 <= cnt; r1++)
701 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
703 struct llx_list list;
704 struct element **elems;
708 struct element to_remove;
712 allocate_elements (cnt, &list, &elems, &elemp, &values);
715 for (i = 0; i < cnt; i++)
717 int x = eq_pat & (1 << i) ? -1 : i;
718 bool delete = x == -1 && r0 <= i && i < r1;
721 values[remaining++] = x;
725 check ((int) llx_remove_equal (elemp[r0], elemp[r1], &to_remove,
726 compare_elements, &aux_data,
729 check_list_contents (&list, values, remaining);
731 free_elements (cnt, &list, elems, elemp, values);
735 /* Tests llx_remove_if. */
737 test_remove_if (void)
739 const int max_elems = 8;
741 int cnt, r0, r1, pattern;
743 for (cnt = 0; cnt <= max_elems; cnt++)
744 for (r0 = 0; r0 <= cnt; r0++)
745 for (r1 = r0; r1 <= cnt; r1++)
746 for (pattern = 0; pattern <= 1 << cnt; pattern++)
748 struct llx_list list;
749 struct element **elems;
756 allocate_ascending (cnt, &list, &elems, &elemp, &values);
759 for (i = 0; i < cnt; i++)
761 bool delete = (pattern & (1 << i)) && r0 <= i && i < r1;
763 values[remaining++] = i;
766 check ((int) llx_remove_if (elemp[r0], elemp[r1],
767 pattern_pred, &pattern,
770 check_list_contents (&list, values, remaining);
772 free_elements (cnt, &list, elems, elemp, values);
776 /* Tests, via HELPER, a function that looks at list elements
777 equal to some specified element. */
779 test_examine_equal_range (void (*helper) (int r0, int r1, int eq_pat,
783 const int max_elems = 8;
785 int cnt, r0, r1, eq_pat;
787 for (cnt = 0; cnt <= max_elems; cnt++)
788 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
790 struct llx_list list;
791 struct element **elems;
795 struct element to_find;
799 allocate_ascending (cnt, &list, &elems, &elemp, &values);
801 for (i = 0; i < cnt; i++)
802 if (eq_pat & (1 << i))
803 values[i] = elems[i]->x = -1;
806 for (r0 = 0; r0 <= cnt; r0++)
807 for (r1 = r0; r1 <= cnt; r1++)
808 helper (r0, r1, eq_pat, &to_find, elemp);
810 check_list_contents (&list, values, cnt);
812 free_elements (cnt, &list, elems, elemp, values);
816 /* Tests, via HELPER, a function that looks at list elements for
817 which a given predicate returns true. */
819 test_examine_if_range (void (*helper) (int r0, int r1, int eq_pat,
822 const int max_elems = 8;
824 int cnt, r0, r1, eq_pat;
826 for (cnt = 0; cnt <= max_elems; cnt++)
827 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
829 struct llx_list list;
830 struct element **elems;
834 allocate_ascending (cnt, &list, &elems, &elemp, &values);
836 for (r0 = 0; r0 <= cnt; r0++)
837 for (r1 = r0; r1 <= cnt; r1++)
838 helper (r0, r1, eq_pat, elemp);
840 check_list_contents (&list, values, cnt);
842 free_elements (cnt, &list, elems, elemp, values);
846 /* Helper function for testing llx_find_equal. */
848 test_find_equal_helper (int r0, int r1, int eq_pat,
849 const void *to_find, struct llx **elemp)
854 match = llx_find_equal (elemp[r0], elemp[r1], to_find,
855 compare_elements, &aux_data);
856 for (i = r0; i < r1; i++)
857 if (eq_pat & (1 << i))
860 check (match == elemp[i]);
863 /* Tests llx_find_equal. */
865 test_find_equal (void)
867 test_examine_equal_range (test_find_equal_helper);
870 /* Helper function for testing llx_find_if. */
872 test_find_if_helper (int r0, int r1, int eq_pat, struct llx **elemp)
874 struct llx *match = llx_find_if (elemp[r0], elemp[r1],
875 pattern_pred, &eq_pat);
878 for (i = r0; i < r1; i++)
879 if (eq_pat & (1 << i))
882 check (match == elemp[i]);
885 /* Tests llx_find_if. */
889 test_examine_if_range (test_find_if_helper);
892 /* Tests llx_find_adjacent_equal. */
894 test_find_adjacent_equal (void)
896 const int max_elems = 8;
900 for (cnt = 0; cnt <= max_elems; cnt++)
901 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
903 struct llx_list list;
904 struct element **elems;
911 allocate_ascending (cnt, &list, &elems, &elemp, &values);
914 for (i = 0; i < cnt - 1; i++)
917 if (eq_pat & (1 << i))
919 values[i] = elems[i]->x = match;
920 values[i + 1] = elems[i + 1]->x = match;
926 for (i = 0; i <= cnt; i++)
928 struct llx *llx1 = llx_find_adjacent_equal (elemp[i], llx_null (&list),
934 llx2 = llx_null (&list);
935 for (j = i; j < cnt - 1; j++)
936 if (eq_pat & (1 << j))
941 check (llx1 == llx2);
943 check_list_contents (&list, values, cnt);
945 free_elements (cnt, &list, elems, elemp, values);
949 /* Helper function for testing llx_count_range. */
951 test_count_range_helper (int r0, int r1, int eq_pat UNUSED, struct llx **elemp)
953 check ((int) llx_count_range (elemp[r0], elemp[r1]) == r1 - r0);
956 /* Tests llx_count_range. */
958 test_count_range (void)
960 test_examine_if_range (test_count_range_helper);
963 /* Helper function for testing llx_count_equal. */
965 test_count_equal_helper (int r0, int r1, int eq_pat,
966 const void *to_find, struct llx **elemp)
971 count1 = llx_count_equal (elemp[r0], elemp[r1], to_find,
972 compare_elements, &aux_data);
974 for (i = r0; i < r1; i++)
975 if (eq_pat & (1 << i))
978 check (count1 == count2);
981 /* Tests llx_count_equal. */
983 test_count_equal (void)
985 test_examine_equal_range (test_count_equal_helper);
988 /* Helper function for testing llx_count_if. */
990 test_count_if_helper (int r0, int r1, int eq_pat, struct llx **elemp)
996 count1 = llx_count_if (elemp[r0], elemp[r1], pattern_pred, &eq_pat);
999 for (i = r0; i < r1; i++)
1000 if (eq_pat & (1 << i))
1003 check (count1 == count2);
1006 /* Tests llx_count_if. */
1008 test_count_if (void)
1010 test_examine_if_range (test_count_if_helper);
1015 factorial (unsigned int n)
1017 unsigned int value = 1;
1023 /* Returns the number of permutations of the CNT values in
1024 VALUES. If VALUES contains duplicates, they must be
1027 expected_perms (int *values, size_t cnt)
1030 unsigned int perm_cnt;
1032 perm_cnt = factorial (cnt);
1033 for (i = 0; i < cnt; i = j)
1035 for (j = i + 1; j < cnt; j++)
1036 if (values[i] != values[j])
1038 perm_cnt /= factorial (j - i);
1043 /* Tests llx_min and llx_max. */
1047 const int max_elems = 6;
1050 for (cnt = 0; cnt <= max_elems; cnt++)
1052 struct llx_list list;
1053 struct element **elems;
1056 int *new_values = xnmalloc (cnt, sizeof *values);
1060 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1063 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1064 compare_elements, &aux_data))
1070 for (i = 0, x = llx_head (&list); x != llx_null (&list);
1071 x = llx_next (x), i++)
1073 struct element *e = llx_data (x);
1075 new_values[i] = e->x;
1077 for (r0 = 0; r0 <= cnt; r0++)
1078 for (r1 = r0; r1 <= cnt; r1++)
1080 struct llx *min = llx_min (elemp[r0], elemp[r1],
1081 compare_elements, &aux_data);
1082 struct llx *max = llx_max (elemp[r0], elemp[r1],
1083 compare_elements, &aux_data);
1086 check (min == elemp[r1]);
1087 check (max == elemp[r1]);
1091 struct element *min_elem = llx_data (min);
1092 struct element *max_elem = llx_data (max);
1093 int min_int, max_int;
1096 min_int = max_int = new_values[r0];
1097 for (i = r0; i < r1; i++)
1099 int value = new_values[i];
1100 if (value < min_int)
1102 if (value > max_int)
1105 check (min != elemp[r1] && min_elem->x == min_int);
1106 check (max != elemp[r1] && max_elem->x == max_int);
1111 check (perm_cnt == factorial (cnt));
1112 check_list_contents (&list, values, cnt);
1114 free_elements (cnt, &list, elems, elemp, values);
1119 /* Tests llx_lexicographical_compare_3way. */
1121 test_lexicographical_compare_3way (void)
1123 const int max_elems = 4;
1125 int cnt_a, pat_a, cnt_b, pat_b;
1127 for (cnt_a = 0; cnt_a <= max_elems; cnt_a++)
1128 for (pat_a = 0; pat_a <= 1 << cnt_a; pat_a++)
1129 for (cnt_b = 0; cnt_b <= max_elems; cnt_b++)
1130 for (pat_b = 0; pat_b <= 1 << cnt_b; pat_b++)
1132 struct llx_list list_a, list_b;
1133 struct element **elems_a, **elems_b;
1134 struct llx **elemp_a, **elemp_b;
1135 int *values_a, *values_b;
1139 allocate_pattern (cnt_a, pat_a,
1140 &list_a, &elems_a, &elemp_a, &values_a);
1141 allocate_pattern (cnt_b, pat_b,
1142 &list_b, &elems_b, &elemp_b, &values_b);
1144 for (a0 = 0; a0 <= cnt_a; a0++)
1145 for (a1 = a0; a1 <= cnt_a; a1++)
1146 for (b0 = 0; b0 <= cnt_b; b0++)
1147 for (b1 = b0; b1 <= cnt_b; b1++)
1149 int a_ordering = lexicographical_compare_3way (
1150 values_a + a0, a1 - a0,
1151 values_b + b0, b1 - b0,
1153 compare_ints, NULL);
1155 int b_ordering = llx_lexicographical_compare_3way (
1156 elemp_a[a0], elemp_a[a1],
1157 elemp_b[b0], elemp_b[b1],
1158 compare_elements, &aux_data);
1160 check (a_ordering == b_ordering);
1163 free_elements (cnt_a, &list_a, elems_a, elemp_a, values_a);
1164 free_elements (cnt_b, &list_b, elems_b, elemp_b, values_b);
1168 /* Appends the `x' value in element E to the array pointed to by
1169 NEXT_OUTPUT, and advances NEXT_OUTPUT to the next position. */
1171 apply_func (void *e_, void *next_output_)
1173 struct element *e = e_;
1174 int **next_output = next_output_;
1176 *(*next_output)++ = e->x;
1179 /* Tests llx_apply. */
1183 const int max_elems = 8;
1187 for (cnt = 0; cnt <= max_elems; cnt++)
1188 for (r0 = 0; r0 <= cnt; r0++)
1189 for (r1 = r0; r1 <= cnt; r1++)
1191 struct llx_list list;
1192 struct element **elems;
1200 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1201 check_list_contents (&list, values, cnt);
1203 output = next_output = xnmalloc (cnt, sizeof *output);
1204 llx_apply (elemp[r0], elemp[r1], apply_func, &next_output);
1205 check_list_contents (&list, values, cnt);
1206 llx_destroy (&list, NULL, NULL, &llx_malloc_mgr);
1208 check (r1 - r0 == next_output - output);
1209 for (j = 0; j < r1 - r0; j++)
1210 check (output[j] == r0 + j);
1212 free_elements (cnt, NULL, elems, elemp, values);
1217 /* Tests llx_destroy. */
1221 const int max_elems = 8;
1225 for (cnt = 0; cnt <= max_elems; cnt++)
1227 struct llx_list list;
1228 struct element **elems;
1236 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1237 check_list_contents (&list, values, cnt);
1239 output = next_output = xnmalloc (cnt, sizeof *output);
1240 llx_destroy (&list, apply_func, &next_output, &llx_malloc_mgr);
1242 check (cnt == next_output - output);
1243 for (j = 0; j < cnt; j++)
1244 check (output[j] == j);
1246 free_elements (cnt, NULL, elems, elemp, values);
1251 /* Tests llx_reverse. */
1255 const int max_elems = 8;
1259 for (cnt = 0; cnt <= max_elems; cnt++)
1260 for (r0 = 0; r0 <= cnt; r0++)
1261 for (r1 = r0; r1 <= cnt; r1++)
1263 struct llx_list list;
1264 struct element **elems;
1270 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1271 check_list_contents (&list, values, cnt);
1274 for (i = 0; i < r0; i++)
1276 for (i = r1 - 1; i >= r0; i--)
1278 for (i = r1; i < cnt; i++)
1281 llx_reverse (elemp[r0], elemp[r1]);
1282 check_list_contents (&list, values, cnt);
1284 free_elements (cnt, &list, elems, elemp, values);
1288 /* Tests llx_next_permutation and llx_prev_permutation when the
1289 permuted values have no duplicates. */
1291 test_permutations_no_dups (void)
1293 const int max_elems = 8;
1296 for (cnt = 0; cnt <= max_elems; cnt++)
1298 struct llx_list list;
1299 struct element **elems;
1301 int *old_values = xnmalloc (cnt, sizeof *values);
1302 int *new_values = xnmalloc (cnt, sizeof *values);
1306 allocate_ascending (cnt, &list, &elems, NULL, &values);
1309 extract_values (&list, old_values, cnt);
1310 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1311 compare_elements, &aux_data))
1313 extract_values (&list, new_values, cnt);
1314 check (lexicographical_compare_3way (new_values, cnt,
1317 compare_ints, NULL) > 0);
1318 memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1321 check (perm_cnt == factorial (cnt));
1322 check_list_contents (&list, values, cnt);
1325 llx_reverse (llx_head (&list), llx_null (&list));
1326 extract_values (&list, old_values, cnt);
1327 while (llx_prev_permutation (llx_head (&list), llx_null (&list),
1328 compare_elements, &aux_data))
1330 extract_values (&list, new_values, cnt);
1331 check (lexicographical_compare_3way (new_values, cnt,
1334 compare_ints, NULL) < 0);
1335 memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1338 check (perm_cnt == factorial (cnt));
1339 llx_reverse (llx_head (&list), llx_null (&list));
1340 check_list_contents (&list, values, cnt);
1342 free_elements (cnt, &list, elems, NULL, values);
1348 /* Tests llx_next_permutation and llx_prev_permutation when the
1349 permuted values contain duplicates. */
1351 test_permutations_with_dups (void)
1353 const int max_elems = 8;
1354 const int max_dup = 3;
1355 const int repetitions = 1024;
1359 for (repeat = 0; repeat < repetitions; repeat++)
1360 for (cnt = 0; cnt < max_elems; cnt++)
1362 struct llx_list list;
1363 struct element **elems;
1366 int *old_values = xnmalloc (max_elems, sizeof *values);
1367 int *new_values = xnmalloc (max_elems, sizeof *values);
1369 unsigned int permutation_cnt;
1373 allocate_elements (cnt, &list, &elems, &elemp, &values);
1378 int max = left < max_dup ? left : max_dup;
1379 int n = rand () % max + 1;
1382 int idx = cnt - left--;
1383 values[idx] = elems[idx]->x = value;
1388 permutation_cnt = 1;
1389 extract_values (&list, old_values, cnt);
1390 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1391 compare_elements, &aux_data))
1393 extract_values (&list, new_values, cnt);
1394 check (lexicographical_compare_3way (new_values, cnt,
1397 compare_ints, NULL) > 0);
1398 memcpy (old_values, new_values, cnt * sizeof *old_values);
1401 check (permutation_cnt == expected_perms (values, cnt));
1402 check_list_contents (&list, values, cnt);
1404 permutation_cnt = 1;
1405 llx_reverse (llx_head (&list), llx_null (&list));
1406 extract_values (&list, old_values, cnt);
1407 while (llx_prev_permutation (llx_head (&list), llx_null (&list),
1408 compare_elements, &aux_data))
1410 extract_values (&list, new_values, cnt);
1411 check (lexicographical_compare_3way (new_values, cnt,
1414 compare_ints, NULL) < 0);
1417 llx_reverse (llx_head (&list), llx_null (&list));
1418 check (permutation_cnt == expected_perms (values, cnt));
1419 check_list_contents (&list, values, cnt);
1421 free_elements (cnt, &list, elems, elemp, values);
1427 /* Tests llx_merge when no equal values are to be merged. */
1429 test_merge_no_dups (void)
1431 const int max_elems = 8;
1432 const int max_fillxer = 3;
1434 int merge_cnt, pattern, pfx, gap, sfx, order;
1436 for (merge_cnt = 0; merge_cnt < max_elems; merge_cnt++)
1437 for (pattern = 0; pattern <= (1 << merge_cnt); pattern++)
1438 for (pfx = 0; pfx < max_fillxer; pfx++)
1439 for (gap = 0; gap < max_fillxer; gap++)
1440 for (sfx = 0; sfx < max_fillxer; sfx++)
1441 for (order = 0; order < 2; order++)
1443 struct llx_list list;
1444 struct element **elems;
1448 int list_cnt = pfx + merge_cnt + gap + sfx;
1452 allocate_elements (list_cnt, &list,
1453 &elems, &elemp, &values);
1456 for (i = 0; i < pfx; i++)
1457 elems[j++]->x = 100 + i;
1459 for (i = 0; i < merge_cnt; i++)
1460 if (pattern & (1u << i))
1463 for (i = 0; i < gap; i++)
1464 elems[j++]->x = 200 + i;
1466 for (i = 0; i < merge_cnt; i++)
1467 if (!(pattern & (1u << i)))
1470 for (i = 0; i < sfx; i++)
1471 elems[j++]->x = 300 + i;
1472 check (list_cnt == j);
1475 for (i = 0; i < pfx; i++)
1476 values[j++] = 100 + i;
1478 for (i = 0; i < merge_cnt; i++)
1480 for (i = 0; i < gap; i++)
1481 values[j++] = 200 + i;
1483 for (i = 0; i < merge_cnt; i++)
1485 for (i = 0; i < sfx; i++)
1486 values[j++] = 300 + i;
1487 check (list_cnt == j);
1490 llx_merge (elemp[a0], elemp[a1], elemp[b0], elemp[b1],
1491 compare_elements, &aux_data);
1493 llx_merge (elemp[b0], elemp[b1], elemp[a0], elemp[a1],
1494 compare_elements, &aux_data);
1496 check_list_contents (&list, values, list_cnt);
1498 free_elements (list_cnt, &list, elems, elemp, values);
1502 /* Tests llx_merge when equal values are to be merged. */
1504 test_merge_with_dups (void)
1506 const int max_elems = 8;
1508 int cnt, merge_pat, inc_pat, order;
1510 for (cnt = 0; cnt <= max_elems; cnt++)
1511 for (merge_pat = 0; merge_pat <= (1 << cnt); merge_pat++)
1512 for (inc_pat = 0; inc_pat <= (1 << cnt); inc_pat++)
1513 for (order = 0; order < 2; order++)
1515 struct llx_list list;
1516 struct element **elems;
1523 allocate_elements (cnt, &list, &elems, &elemp, &values);
1526 for (i = k = 0; i < cnt; i++)
1528 if (merge_pat & (1u << i))
1530 if (inc_pat & (1u << i))
1534 for (i = k = 0; i < cnt; i++)
1536 if (!(merge_pat & (1u << i)))
1538 if (inc_pat & (1u << i))
1545 for (i = 0; i < cnt; i++)
1550 for (i = 0; i < mid; i++)
1551 elems[i]->y = 100 + i;
1552 for (i = mid; i < cnt; i++)
1557 for (i = k = 0; i < cnt; i++)
1560 if (inc_pat & (1u << i))
1566 llx_merge (elemp[0], elemp[mid], elemp[mid], elemp[cnt],
1567 compare_elements, &aux_data);
1569 llx_merge (elemp[mid], elemp[cnt], elemp[0], elemp[mid],
1570 compare_elements, &aux_data);
1572 check_list_contents (&list, values, cnt);
1573 check (llx_is_sorted (llx_head (&list), llx_null (&list),
1574 compare_elements_x_y, &aux_data));
1576 free_elements (cnt, &list, elems, elemp, values);
1580 /* Tests llx_sort on all permutations up to a maximum number of
1583 test_sort_exhaustive (void)
1585 const int max_elems = 8;
1588 for (cnt = 0; cnt <= max_elems; cnt++)
1590 struct llx_list list;
1591 struct element **elems;
1594 struct element **perm_elems;
1599 allocate_ascending (cnt, &list, &elems, NULL, &values);
1600 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1603 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1604 compare_elements, &aux_data))
1606 struct llx_list perm_list;
1609 extract_values (&list, perm_values, cnt);
1610 llx_init (&perm_list);
1611 for (j = 0; j < cnt; j++)
1613 perm_elems[j]->x = perm_values[j];
1614 llx_push_tail (&perm_list, perm_elems[j], &llx_malloc_mgr);
1616 llx_sort (llx_head (&perm_list), llx_null (&perm_list),
1617 compare_elements, &aux_data);
1618 check_list_contents (&perm_list, values, cnt);
1619 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1620 compare_elements, &aux_data));
1621 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1624 check (perm_cnt == factorial (cnt));
1626 free_elements (cnt, &list, elems, NULL, values);
1627 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1631 /* Tests that llx_sort is stable in the presence of equal
1634 test_sort_stable (void)
1636 const int max_elems = 6;
1639 for (cnt = 0; cnt <= max_elems; cnt++)
1640 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1642 struct llx_list list;
1643 struct element **elems;
1646 struct element **perm_elems;
1652 allocate_elements (cnt, &list, &elems, NULL, &values);
1653 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1656 for (i = 0; i < cnt; i++)
1658 elems[i]->x = values[i] = j;
1659 if (inc_pat & (1 << i))
1665 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1666 compare_elements_y, &aux_data))
1668 struct llx_list perm_list;
1670 extract_values (&list, perm_values, cnt);
1671 llx_init (&perm_list);
1672 for (i = 0; i < cnt; i++)
1674 perm_elems[i]->x = perm_values[i];
1675 perm_elems[i]->y = i;
1676 llx_push_tail (&perm_list, perm_elems[i], &llx_malloc_mgr);
1678 llx_sort (llx_head (&perm_list), llx_null (&perm_list),
1679 compare_elements, &aux_data);
1680 check_list_contents (&perm_list, values, cnt);
1681 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1682 compare_elements_x_y, &aux_data));
1683 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1686 check (perm_cnt == factorial (cnt));
1688 free_elements (cnt, &list, elems, NULL, values);
1689 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1693 /* Tests that llx_sort does not disturb elements outside the
1696 test_sort_subset (void)
1698 const int max_elems = 8;
1700 int cnt, r0, r1, repeat;
1702 for (cnt = 0; cnt <= max_elems; cnt++)
1703 for (repeat = 0; repeat < 100; repeat++)
1704 for (r0 = 0; r0 <= cnt; r0++)
1705 for (r1 = r0; r1 <= cnt; r1++)
1707 struct llx_list list;
1708 struct element **elems;
1712 allocate_random (cnt, &list, &elems, &elemp, &values);
1714 qsort (&values[r0], r1 - r0, sizeof *values, compare_ints_noaux);
1715 llx_sort (elemp[r0], elemp[r1], compare_elements, &aux_data);
1716 check_list_contents (&list, values, cnt);
1718 free_elements (cnt, &list, elems, elemp, values);
1722 /* Tests that llx_sort works with large lists. */
1724 test_sort_big (void)
1726 const int max_elems = 1024;
1730 for (cnt = 0; cnt < max_elems; cnt++)
1732 struct llx_list list;
1733 struct element **elems;
1736 allocate_random (cnt, &list, &elems, NULL, &values);
1738 qsort (values, cnt, sizeof *values, compare_ints_noaux);
1739 llx_sort (llx_head (&list), llx_null (&list), compare_elements, &aux_data);
1740 check_list_contents (&list, values, cnt);
1742 free_elements (cnt, &list, elems, NULL, values);
1746 /* Tests llx_unique. */
1750 const int max_elems = 10;
1752 int *ascending = xnmalloc (max_elems, sizeof *ascending);
1754 int cnt, inc_pat, i, j, unique_values;
1756 for (i = 0; i < max_elems; i++)
1759 for (cnt = 0; cnt < max_elems; cnt++)
1760 for (inc_pat = 0; inc_pat < (1 << cnt); inc_pat++)
1762 struct llx_list list, dups;
1763 struct element **elems;
1766 allocate_elements (cnt, &list, &elems, NULL, &values);
1768 j = unique_values = 0;
1769 for (i = 0; i < cnt; i++)
1771 unique_values = j + 1;
1772 elems[i]->x = values[i] = j;
1773 if (inc_pat & (1 << i))
1776 check_list_contents (&list, values, cnt);
1779 check (llx_unique (llx_head (&list), llx_null (&list),
1781 compare_elements, &aux_data,
1783 == (size_t) unique_values);
1784 check_list_contents (&list, ascending, unique_values);
1786 llx_splice (llx_null (&list), llx_head (&dups), llx_null (&dups));
1787 llx_sort (llx_head (&list), llx_null (&list), compare_elements, &aux_data);
1788 check_list_contents (&list, values, cnt);
1790 llx_destroy (&dups, NULL, NULL, &llx_malloc_mgr);
1791 free_elements (cnt, &list, elems, NULL, values);
1797 /* Tests llx_sort_unique. */
1799 test_sort_unique (void)
1801 const int max_elems = 7;
1804 for (cnt = 0; cnt <= max_elems; cnt++)
1805 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1807 struct llx_list list;
1808 struct element **elems;
1811 struct element **perm_elems;
1820 allocate_elements (cnt, &list, &elems, NULL, &values);
1821 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1824 for (i = 0; i < cnt; i++)
1826 elems[i]->x = values[i] = j;
1828 if (inc_pat & (1 << i))
1832 unique_values = xnmalloc (unique_cnt, sizeof *unique_values);
1833 for (i = 0; i < unique_cnt; i++)
1834 unique_values[i] = i;
1837 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1838 compare_elements, &aux_data))
1840 struct llx_list perm_list;
1842 extract_values (&list, perm_values, cnt);
1843 llx_init (&perm_list);
1844 for (i = 0; i < cnt; i++)
1846 perm_elems[i]->x = perm_values[i];
1847 perm_elems[i]->y = i;
1848 llx_push_tail (&perm_list, perm_elems[i], &llx_malloc_mgr);
1850 llx_sort_unique (llx_head (&perm_list), llx_null (&perm_list), NULL,
1851 compare_elements, &aux_data,
1853 check_list_contents (&perm_list, unique_values, unique_cnt);
1854 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1855 compare_elements_x_y, &aux_data));
1856 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1859 check (perm_cnt == expected_perms (values, cnt));
1861 free_elements (cnt, &list, elems, NULL, values);
1862 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1863 free (unique_values);
1867 /* Tests llx_insert_ordered. */
1869 test_insert_ordered (void)
1871 const int max_elems = 6;
1874 for (cnt = 0; cnt <= max_elems; cnt++)
1875 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1877 struct llx_list list;
1878 struct element **elems;
1881 struct element **perm_elems;
1887 allocate_elements (cnt, &list, &elems, NULL, &values);
1888 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1891 for (i = 0; i < cnt; i++)
1893 elems[i]->x = values[i] = j;
1894 if (inc_pat & (1 << i))
1900 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1901 compare_elements_y, &aux_data))
1903 struct llx_list perm_list;
1905 extract_values (&list, perm_values, cnt);
1906 llx_init (&perm_list);
1907 for (i = 0; i < cnt; i++)
1909 perm_elems[i]->x = perm_values[i];
1910 perm_elems[i]->y = i;
1911 llx_insert_ordered (llx_head (&perm_list),
1912 llx_null (&perm_list),
1914 compare_elements, &aux_data,
1917 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1918 compare_elements_x_y, &aux_data));
1919 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1922 check (perm_cnt == factorial (cnt));
1924 free_elements (cnt, &list, elems, NULL, values);
1925 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1929 /* Tests llx_partition. */
1931 test_partition (void)
1933 const int max_elems = 10;
1939 for (cnt = 0; cnt < max_elems; cnt++)
1940 for (r0 = 0; r0 <= cnt; r0++)
1941 for (r1 = r0; r1 <= cnt; r1++)
1942 for (pbase = 0; pbase <= (1u << (r1 - r0)); pbase++)
1944 struct llx_list list;
1945 struct element **elems;
1949 unsigned int pattern = pbase << r0;
1952 struct llx *part_llx;
1954 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1956 /* Check that llx_find_partition works okay in every
1957 case. We use it after partitioning, too, but that
1958 only tests cases where it returns non-null. */
1959 for (i = r0; i < r1; i++)
1960 if (!(pattern & (1u << i)))
1964 if (pattern & (1u << i))
1966 part_llx = llx_find_partition (elemp[r0], elemp[r1],
1970 check (part_llx == elemp[j]);
1972 check (part_llx == NULL);
1974 /* Figure out expected results. */
1977 for (i = 0; i < r0; i++)
1979 for (i = r0; i < r1; i++)
1980 if (pattern & (1u << i))
1982 for (i = r0; i < r1; i++)
1983 if (!(pattern & (1u << i)))
1985 if (first_false == -1)
1989 if (first_false == -1)
1991 for (i = r1; i < cnt; i++)
1995 /* Partition and check for expected results. */
1996 check (llx_partition (elemp[r0], elemp[r1],
1997 pattern_pred, &pattern)
1998 == elemp[first_false]);
1999 check (llx_find_partition (elemp[r0], elemp[r1],
2000 pattern_pred, &pattern)
2001 == elemp[first_false]);
2002 check_list_contents (&list, values, cnt);
2003 check ((int) llx_count (&list) == cnt);
2005 free_elements (cnt, &list, elems, elemp, values);
2009 /* Tests that allocation failure is gracefully handled. */
2011 test_allocation_failure (void)
2013 struct llx_list list;
2016 check (llx_push_head (&list, NULL, &llx_null_mgr) == NULL);
2017 check (llx_push_tail (&list, NULL, &llx_null_mgr) == NULL);
2018 check (llx_insert (llx_null (&list), NULL, &llx_null_mgr) == NULL);
2019 check_list_contents (&list, NULL, 0);
2024 /* Runs TEST_FUNCTION and prints a message about NAME. */
2026 run_test (void (*test_function) (void), const char *name)
2037 run_test (test_push_pop, "push/pop");
2038 run_test (test_insert_remove, "insert/remove");
2039 run_test (test_swap, "swap");
2040 run_test (test_swap_range, "swap_range");
2041 run_test (test_remove_range, "remove_range");
2042 run_test (test_remove_equal, "remove_equal");
2043 run_test (test_remove_if, "remove_if");
2044 run_test (test_find_equal, "find_equal");
2045 run_test (test_find_if, "find_if");
2046 run_test (test_find_adjacent_equal, "find_adjacent_equal");
2047 run_test (test_count_range, "count_range");
2048 run_test (test_count_equal, "count_equal");
2049 run_test (test_count_if, "count_if");
2050 run_test (test_min_max, "min/max");
2051 run_test (test_lexicographical_compare_3way, "lexicographical_compare_3way");
2052 run_test (test_apply, "apply");
2053 run_test (test_destroy, "destroy");
2054 run_test (test_reverse, "reverse");
2055 run_test (test_permutations_no_dups, "permutations (no dups)");
2056 run_test (test_permutations_with_dups, "permutations (with dups)");
2057 run_test (test_merge_no_dups, "merge (no dups)");
2058 run_test (test_merge_with_dups, "merge (with dups)");
2059 run_test (test_sort_exhaustive, "sort (exhaustive)");
2060 run_test (test_sort_stable, "sort (stability)");
2061 run_test (test_sort_subset, "sort (subset)");
2062 run_test (test_sort_big, "sort (big)");
2063 run_test (test_unique, "unique");
2064 run_test (test_sort_unique, "sort_unique");
2065 run_test (test_insert_ordered, "insert_ordered");
2066 run_test (test_partition, "partition");
2067 run_test (test_allocation_failure, "allocation failure");
2075 compile-command: "gcc -Wall -Wstrict-prototypes -Wmissing-prototypes ll.c llx.c llx-test.c -o llx-test -g"