1 /* PSPP - computes sample statistics.
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /* This is a test program for the llx_* routines defined in
21 ll.c. This test program aims to be as comprehensive as
22 possible. "gcov -b" should report 100% coverage of lines and
23 branches in llx.c and llx.h. "valgrind --leak-check=yes
24 --show-reachable=yes" should give a clean report.
26 This test program depends only on ll.c, llx.c, and the
29 See ll-test.c for a similar program for the ll_* routines. */
31 #include <libpspp/llx.h>
37 /* Support preliminaries. */
38 #if __GNUC__ >= 2 && !defined UNUSED
39 #define UNUSED __attribute__ ((unused))
44 /* Currently running test. */
45 static const char *test_name;
47 /* Exit with a failure code.
48 (Place a breakpoint on this function while debugging.) */
55 /* If OK is not true, prints a message about failure on the
56 current source file and the given LINE and terminates. */
58 check_func (bool ok, int line)
62 printf ("Check failed in %s test at %s, line %d\n",
63 test_name, __FILE__, line);
68 /* Verifies that EXPR evaluates to true.
69 If not, prints a message citing the calling line number and
71 #define check(EXPR) check_func ((EXPR), __LINE__)
73 /* Prints a message about memory exhaustion and exits with a
78 printf ("virtual memory exhausted\n");
82 /* Allocates and returns N bytes of memory. */
98 /* Allocates and returns N * M bytes of memory. */
100 xnmalloc (size_t n, size_t m)
102 if ((size_t) -1 / m <= n)
104 return xmalloc (n * m);
107 /* Always returns a null pointer, failing allocation. */
109 null_allocate_node (void *aux UNUSED)
116 null_release_node (struct llx *llx UNUSED, void *aux UNUSED)
120 /* Memory manager that fails all allocations and does nothing on
122 static const struct llx_manager llx_null_mgr =
129 /* List type and support routines. */
131 /* Test data element. */
134 int x; /* Primary value. */
135 int y; /* Secondary value. */
140 /* Prints the elements in LIST. */
142 print_list (struct llx_list *list)
147 for (x = llx_head (list); x != llx_null (list); x = llx_next (x))
149 const struct element *e = llx_data (x);
150 printf (" %d", e->x);
155 /* Prints the value returned by PREDICATE given auxiliary data
156 AUX for each element in LIST. */
158 print_pred (struct llx_list *list,
159 llx_predicate_func *predicate, void *aux UNUSED)
164 for (x = llx_head (list); x != llx_null (list); x = llx_next (x))
165 printf (" %d", predicate (x, aux));
169 /* Prints the CNT numbers in VALUES. */
171 print_array (int values[], size_t cnt)
176 for (i = 0; i < cnt; i++)
177 printf (" %d", values[i]);
181 /* Compares the `x' values in A and B and returns a strcmp-type
182 return value. Verifies that AUX points to aux_data. */
184 compare_elements (const void *a_, const void *b_, void *aux)
186 const struct element *a = a_;
187 const struct element *b = b_;
189 check (aux == &aux_data);
190 return a->x < b->x ? -1 : a->x > b->x;
193 /* Compares the `x' and `y' values in A and B and returns a
194 strcmp-type return value. Verifies that AUX points to
197 compare_elements_x_y (const void *a_, const void *b_, void *aux)
199 const struct element *a = a_;
200 const struct element *b = b_;
202 check (aux == &aux_data);
204 return a->x < b->x ? -1 : 1;
205 else if (a->y != b->y)
206 return a->y < b->y ? -1 : 1;
211 /* Compares the `y' values in A and B and returns a strcmp-type
212 return value. Verifies that AUX points to aux_data. */
214 compare_elements_y (const void *a_, const void *b_, void *aux)
216 const struct element *a = a_;
217 const struct element *b = b_;
219 check (aux == &aux_data);
220 return a->y < b->y ? -1 : a->y > b->y;
223 /* Returns true if the bit in *PATTERN indicated by `x in
224 *ELEMENT is set, false otherwise. */
226 pattern_pred (const void *element_, void *pattern_)
228 const struct element *element = element_;
229 unsigned *pattern = pattern_;
231 return (*pattern & (1u << element->x)) != 0;
234 /* Allocates N elements in *ELEMS.
235 Adds the elements to LIST, if it is nonnull.
236 Puts pointers to the elements' list elements in *ELEMP,
237 followed by a pointer to the list null element, if ELEMP is
239 Allocates space for N values in *VALUES, if VALUES is
242 allocate_elements (size_t n,
243 struct llx_list *list,
244 struct element ***elems,
253 *elems = xnmalloc (n, sizeof **elems);
256 *elemp = xnmalloc (n + 1, sizeof *elemp);
257 (*elemp)[n] = llx_null (list);
260 for (i = 0; i < n; i++)
262 (*elems)[i] = xmalloc (sizeof ***elems);
265 struct llx *llx = llx_push_tail (list, (*elems)[i], &llx_malloc_mgr);
272 *values = xnmalloc (n, sizeof *values);
275 /* Copies the CNT values of `x' from LIST into VALUES[]. */
277 extract_values (struct llx_list *list, int values[], size_t cnt)
281 check (llx_count (list) == cnt);
282 for (x = llx_head (list); x != llx_null (list); x = llx_next (x))
284 struct element *e = llx_data (x);
289 /* As allocate_elements, but sets ascending values, starting
290 from 0, in `x' values in *ELEMS and in *VALUES (if
293 allocate_ascending (size_t n,
294 struct llx_list *list,
295 struct element ***elems,
301 allocate_elements (n, list, elems, elemp, values);
303 for (i = 0; i < n; i++)
306 extract_values (list, *values, n);
309 /* As allocate_elements, but sets binary values extracted from
310 successive bits in PATTERN in `x' values in *ELEMS and in
311 *VALUES (if nonnull). */
313 allocate_pattern (size_t n,
315 struct llx_list *list,
316 struct element ***elems,
322 allocate_elements (n, list, elems, elemp, values);
324 for (i = 0; i < n; i++)
325 (*elems)[i]->x = (pattern & (1 << i)) != 0;
327 extract_values (list, *values, n);
330 /* Randomly shuffles the CNT elements in ARRAY, each of which is
331 SIZE bytes in size. */
333 random_shuffle (void *array_, size_t cnt, size_t size)
335 char *array = array_;
336 char *tmp = xmalloc (size);
339 for (i = 0; i < cnt; i++)
341 size_t j = rand () % (cnt - i) + i;
344 memcpy (tmp, array + j * size, size);
345 memcpy (array + j * size, array + i * size, size);
346 memcpy (array + i * size, tmp, size);
353 /* As allocate_ascending, but orders the values randomly. */
355 allocate_random (size_t n,
356 struct llx_list *list,
357 struct element ***elems,
363 allocate_elements (n, list, elems, elemp, values);
365 for (i = 0; i < n; i++)
367 random_shuffle (*elems, n, sizeof **elems);
369 extract_values (list, *values, n);
372 /* Frees LIST, the N elements of ELEMS, ELEMP, and VALUES. */
374 free_elements (size_t n,
375 struct llx_list *list,
376 struct element **elems,
383 llx_destroy (list, NULL, NULL, &llx_malloc_mgr);
384 for (i = 0; i < n; i++)
391 /* Compares A and B and returns a strcmp-type return value. */
393 compare_ints (const void *a_, const void *b_, void *aux UNUSED)
398 return *a < *b ? -1 : *a > *b;
401 /* Compares A and B and returns a strcmp-type return value. */
403 compare_ints_noaux (const void *a_, const void *b_)
408 return *a < *b ? -1 : *a > *b;
411 /* Checks that LIST contains the CNT values in ELEMENTS. */
413 check_list_contents (struct llx_list *list, int elements[], size_t cnt)
418 check ((cnt == 0) == llx_is_empty (list));
420 /* Iterate in forward order. */
421 for (llx = llx_head (list), i = 0; i < cnt; llx = llx_next (llx), i++)
423 struct element *e = llx_data (llx);
424 check (elements[i] == e->x);
425 check (llx != llx_null (list));
427 check (llx == llx_null (list));
429 /* Iterate in reverse order. */
430 for (llx = llx_tail (list), i = 0; i < cnt; llx = llx_prev (llx), i++)
432 struct element *e = llx_data (llx);
433 check (elements[cnt - i - 1] == e->x);
434 check (llx != llx_null (list));
436 check (llx == llx_null (list));
438 check (llx_count (list) == cnt);
441 /* Lexicographicallxy compares ARRAY1, which contains COUNT1
442 elements of SIZE bytes each, to ARRAY2, which contains COUNT2
443 elements of SIZE bytes, according to COMPARE. Returns a
444 strcmp-type result. AUX is passed to COMPARE as auxiliary
447 lexicographical_compare_3way (const void *array1, size_t count1,
448 const void *array2, size_t count2,
450 int (*compare) (const void *, const void *,
454 const char *first1 = array1;
455 const char *first2 = array2;
456 size_t min_count = count1 < count2 ? count1 : count2;
458 while (min_count > 0)
460 int cmp = compare (first1, first2, aux);
469 return count1 < count2 ? -1 : count1 > count2;
474 /* Tests list push and pop operations. */
478 const int max_elems = 1024;
480 struct llx_list list;
481 struct element **elems;
486 allocate_elements (max_elems, NULL, &elems, NULL, &values);
490 check_list_contents (&list, NULL, 0);
491 for (i = 0; i < max_elems; i++)
493 values[i] = elems[i]->x = i;
494 llx_push_tail (&list, elems[i], &llx_malloc_mgr);
495 check_list_contents (&list, values, i + 1);
498 /* Remove from tail. */
499 for (i = 0; i < max_elems; i++)
501 struct element *e = llx_pop_tail (&list, &llx_malloc_mgr);
502 check (e->x == max_elems - i - 1);
503 check_list_contents (&list, values, max_elems - i - 1);
507 check_list_contents (&list, NULL, 0);
508 for (i = 0; i < max_elems; i++)
510 values[max_elems - i - 1] = elems[i]->x = max_elems - i - 1;
511 llx_push_head (&list, elems[i], &llx_malloc_mgr);
512 check_list_contents (&list, &values[max_elems - i - 1], i + 1);
515 /* Remove from start. */
516 for (i = 0; i < max_elems; i++)
518 struct element *e = llx_pop_head (&list, &llx_malloc_mgr);
519 check (e->x == (int) i);
520 check_list_contents (&list, &values[i + 1], max_elems - i - 1);
523 free_elements (max_elems, &list, elems, NULL, values);
526 /* Tests insertion and removal at arbitrary positions. */
528 test_insert_remove (void)
530 const int max_elems = 16;
533 for (cnt = 0; cnt < max_elems; cnt++)
535 struct element **elems;
537 int *values = xnmalloc (cnt + 1, sizeof *values);
539 struct llx_list list;
540 struct element extra;
541 struct llx *extra_llx;
544 allocate_ascending (cnt, &list, &elems, &elemp, NULL);
546 for (pos = 0; pos <= cnt; pos++)
550 extra_llx = llx_insert (elemp[pos], &extra, &llx_malloc_mgr);
551 check (extra_llx != NULL);
554 for (i = 0; i < pos; i++)
559 check_list_contents (&list, values, cnt + 1);
561 llx_remove (extra_llx, &llx_malloc_mgr);
563 check_list_contents (&list, values, cnt);
565 free_elements (cnt, &list, elems, elemp, values);
569 /* Tests swapping individual elements. */
573 const int max_elems = 8;
576 for (cnt = 0; cnt <= max_elems; cnt++)
578 struct llx_list list;
579 struct element **elems;
585 allocate_ascending (cnt, &list, &elems, &elemp, &values);
586 check_list_contents (&list, values, cnt);
588 for (i = 0; i < cnt; i++)
589 for (j = 0; j < cnt; j++)
590 for (k = 0; k < 2; k++)
594 llx_swap (elemp[i], elemp[j]);
596 values[i] = values[j];
598 check_list_contents (&list, values, cnt);
601 free_elements (cnt, &list, elems, elemp, values);
605 /* Tests swapping ranges of list elements. */
607 test_swap_range (void)
609 const int max_elems = 8;
610 int cnt, a0, a1, b0, b1, r;
612 for (cnt = 0; cnt <= max_elems; cnt++)
613 for (a0 = 0; a0 <= cnt; a0++)
614 for (a1 = a0; a1 <= cnt; a1++)
615 for (b0 = a1; b0 <= cnt; b0++)
616 for (b1 = b0; b1 <= cnt; b1++)
617 for (r = 0; r < 2; r++)
619 struct llx_list list;
620 struct element **elems;
626 allocate_ascending (cnt, &list, &elems, &elemp, &values);
627 check_list_contents (&list, values, cnt);
630 for (i = 0; i < a0; i++)
632 for (i = b0; i < b1; i++)
634 for (i = a1; i < b0; i++)
636 for (i = a0; i < a1; i++)
638 for (i = b1; i < cnt; i++)
643 llx_swap_range (elemp[a0], elemp[a1], elemp[b0], elemp[b1]);
645 llx_swap_range (elemp[b0], elemp[b1], elemp[a0], elemp[a1]);
646 check_list_contents (&list, values, cnt);
648 free_elements (cnt, &list, elems, elemp, values);
652 /* Tests removing ranges of list elements. */
654 test_remove_range (void)
656 const int max_elems = 8;
660 for (cnt = 0; cnt <= max_elems; cnt++)
661 for (r0 = 0; r0 <= cnt; r0++)
662 for (r1 = r0; r1 <= cnt; r1++)
664 struct llx_list list;
665 struct element **elems;
671 allocate_ascending (cnt, &list, &elems, &elemp, &values);
672 check_list_contents (&list, values, cnt);
675 for (i = 0; i < r0; i++)
677 for (i = r1; i < cnt; i++)
680 llx_remove_range (elemp[r0], elemp[r1], &llx_malloc_mgr);
681 check_list_contents (&list, values, j);
683 free_elements (cnt, &list, elems, elemp, values);
687 /* Tests llx_remove_equal. */
689 test_remove_equal (void)
691 const int max_elems = 8;
693 int cnt, r0, r1, eq_pat;
695 for (cnt = 0; cnt <= max_elems; cnt++)
696 for (r0 = 0; r0 <= cnt; r0++)
697 for (r1 = r0; r1 <= cnt; r1++)
698 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
700 struct llx_list list;
701 struct element **elems;
705 struct element to_remove;
709 allocate_elements (cnt, &list, &elems, &elemp, &values);
712 for (i = 0; i < cnt; i++)
714 int x = eq_pat & (1 << i) ? -1 : i;
715 bool delete = x == -1 && r0 <= i && i < r1;
718 values[remaining++] = x;
722 check ((int) llx_remove_equal (elemp[r0], elemp[r1], &to_remove,
723 compare_elements, &aux_data,
726 check_list_contents (&list, values, remaining);
728 free_elements (cnt, &list, elems, elemp, values);
732 /* Tests llx_remove_if. */
734 test_remove_if (void)
736 const int max_elems = 8;
738 int cnt, r0, r1, pattern;
740 for (cnt = 0; cnt <= max_elems; cnt++)
741 for (r0 = 0; r0 <= cnt; r0++)
742 for (r1 = r0; r1 <= cnt; r1++)
743 for (pattern = 0; pattern <= 1 << cnt; pattern++)
745 struct llx_list list;
746 struct element **elems;
753 allocate_ascending (cnt, &list, &elems, &elemp, &values);
756 for (i = 0; i < cnt; i++)
758 bool delete = (pattern & (1 << i)) && r0 <= i && i < r1;
760 values[remaining++] = i;
763 check ((int) llx_remove_if (elemp[r0], elemp[r1],
764 pattern_pred, &pattern,
767 check_list_contents (&list, values, remaining);
769 free_elements (cnt, &list, elems, elemp, values);
773 /* Tests, via HELPER, a function that looks at list elements
774 equal to some specified element. */
776 test_examine_equal_range (void (*helper) (int r0, int r1, int eq_pat,
780 const int max_elems = 8;
782 int cnt, r0, r1, eq_pat;
784 for (cnt = 0; cnt <= max_elems; cnt++)
785 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
787 struct llx_list list;
788 struct element **elems;
792 struct element to_find;
796 allocate_ascending (cnt, &list, &elems, &elemp, &values);
798 for (i = 0; i < cnt; i++)
799 if (eq_pat & (1 << i))
800 values[i] = elems[i]->x = -1;
803 for (r0 = 0; r0 <= cnt; r0++)
804 for (r1 = r0; r1 <= cnt; r1++)
805 helper (r0, r1, eq_pat, &to_find, elemp);
807 check_list_contents (&list, values, cnt);
809 free_elements (cnt, &list, elems, elemp, values);
813 /* Tests, via HELPER, a function that looks at list elements for
814 which a given predicate returns true. */
816 test_examine_if_range (void (*helper) (int r0, int r1, int eq_pat,
819 const int max_elems = 8;
821 int cnt, r0, r1, eq_pat;
823 for (cnt = 0; cnt <= max_elems; cnt++)
824 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
826 struct llx_list list;
827 struct element **elems;
831 allocate_ascending (cnt, &list, &elems, &elemp, &values);
833 for (r0 = 0; r0 <= cnt; r0++)
834 for (r1 = r0; r1 <= cnt; r1++)
835 helper (r0, r1, eq_pat, elemp);
837 check_list_contents (&list, values, cnt);
839 free_elements (cnt, &list, elems, elemp, values);
843 /* Helper function for testing llx_find_equal. */
845 test_find_equal_helper (int r0, int r1, int eq_pat,
846 const void *to_find, struct llx **elemp)
851 match = llx_find_equal (elemp[r0], elemp[r1], to_find,
852 compare_elements, &aux_data);
853 for (i = r0; i < r1; i++)
854 if (eq_pat & (1 << i))
857 check (match == elemp[i]);
860 /* Tests llx_find_equal. */
862 test_find_equal (void)
864 test_examine_equal_range (test_find_equal_helper);
867 /* Helper function for testing llx_find_if. */
869 test_find_if_helper (int r0, int r1, int eq_pat, struct llx **elemp)
871 struct llx *match = llx_find_if (elemp[r0], elemp[r1],
872 pattern_pred, &eq_pat);
875 for (i = r0; i < r1; i++)
876 if (eq_pat & (1 << i))
879 check (match == elemp[i]);
882 /* Tests llx_find_if. */
886 test_examine_if_range (test_find_if_helper);
889 /* Tests llx_find_adjacent_equal. */
891 test_find_adjacent_equal (void)
893 const int max_elems = 8;
897 for (cnt = 0; cnt <= max_elems; cnt++)
898 for (eq_pat = 0; eq_pat <= 1 << cnt; eq_pat++)
900 struct llx_list list;
901 struct element **elems;
908 allocate_ascending (cnt, &list, &elems, &elemp, &values);
911 for (i = 0; i < cnt - 1; i++)
914 if (eq_pat & (1 << i))
916 values[i] = elems[i]->x = match;
917 values[i + 1] = elems[i + 1]->x = match;
923 for (i = 0; i <= cnt; i++)
925 struct llx *llx1 = llx_find_adjacent_equal (elemp[i], llx_null (&list),
931 llx2 = llx_null (&list);
932 for (j = i; j < cnt - 1; j++)
933 if (eq_pat & (1 << j))
938 check (llx1 == llx2);
940 check_list_contents (&list, values, cnt);
942 free_elements (cnt, &list, elems, elemp, values);
946 /* Helper function for testing llx_count_range. */
948 test_count_range_helper (int r0, int r1, int eq_pat UNUSED, struct llx **elemp)
950 check ((int) llx_count_range (elemp[r0], elemp[r1]) == r1 - r0);
953 /* Tests llx_count_range. */
955 test_count_range (void)
957 test_examine_if_range (test_count_range_helper);
960 /* Helper function for testing llx_count_equal. */
962 test_count_equal_helper (int r0, int r1, int eq_pat,
963 const void *to_find, struct llx **elemp)
968 count1 = llx_count_equal (elemp[r0], elemp[r1], to_find,
969 compare_elements, &aux_data);
971 for (i = r0; i < r1; i++)
972 if (eq_pat & (1 << i))
975 check (count1 == count2);
978 /* Tests llx_count_equal. */
980 test_count_equal (void)
982 test_examine_equal_range (test_count_equal_helper);
985 /* Helper function for testing llx_count_if. */
987 test_count_if_helper (int r0, int r1, int eq_pat, struct llx **elemp)
993 count1 = llx_count_if (elemp[r0], elemp[r1], pattern_pred, &eq_pat);
996 for (i = r0; i < r1; i++)
997 if (eq_pat & (1 << i))
1000 check (count1 == count2);
1003 /* Tests llx_count_if. */
1005 test_count_if (void)
1007 test_examine_if_range (test_count_if_helper);
1012 factorial (unsigned n)
1020 /* Returns the number of permutations of the CNT values in
1021 VALUES. If VALUES contains duplicates, they must be
1024 expected_perms (int *values, size_t cnt)
1029 perm_cnt = factorial (cnt);
1030 for (i = 0; i < cnt; i = j)
1032 for (j = i + 1; j < cnt; j++)
1033 if (values[i] != values[j])
1035 perm_cnt /= factorial (j - i);
1040 /* Tests llx_min and llx_max. */
1044 const int max_elems = 6;
1047 for (cnt = 0; cnt <= max_elems; cnt++)
1049 struct llx_list list;
1050 struct element **elems;
1053 int *new_values = xnmalloc (cnt, sizeof *values);
1057 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1060 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1061 compare_elements, &aux_data))
1067 for (i = 0, x = llx_head (&list); x != llx_null (&list);
1068 x = llx_next (x), i++)
1070 struct element *e = llx_data (x);
1072 new_values[i] = e->x;
1074 for (r0 = 0; r0 <= cnt; r0++)
1075 for (r1 = r0; r1 <= cnt; r1++)
1077 struct llx *min = llx_min (elemp[r0], elemp[r1],
1078 compare_elements, &aux_data);
1079 struct llx *max = llx_max (elemp[r0], elemp[r1],
1080 compare_elements, &aux_data);
1083 check (min == elemp[r1]);
1084 check (max == elemp[r1]);
1088 struct element *min_elem = llx_data (min);
1089 struct element *max_elem = llx_data (max);
1090 int min_int, max_int;
1093 min_int = max_int = new_values[r0];
1094 for (i = r0; i < r1; i++)
1096 int value = new_values[i];
1097 if (value < min_int)
1099 if (value > max_int)
1102 check (min != elemp[r1] && min_elem->x == min_int);
1103 check (max != elemp[r1] && max_elem->x == max_int);
1108 check (perm_cnt == factorial (cnt));
1109 check_list_contents (&list, values, cnt);
1111 free_elements (cnt, &list, elems, elemp, values);
1116 /* Tests llx_lexicographical_compare_3way. */
1118 test_lexicographical_compare_3way (void)
1120 const int max_elems = 4;
1122 int cnt_a, pat_a, cnt_b, pat_b;
1124 for (cnt_a = 0; cnt_a <= max_elems; cnt_a++)
1125 for (pat_a = 0; pat_a <= 1 << cnt_a; pat_a++)
1126 for (cnt_b = 0; cnt_b <= max_elems; cnt_b++)
1127 for (pat_b = 0; pat_b <= 1 << cnt_b; pat_b++)
1129 struct llx_list list_a, list_b;
1130 struct element **elems_a, **elems_b;
1131 struct llx **elemp_a, **elemp_b;
1132 int *values_a, *values_b;
1136 allocate_pattern (cnt_a, pat_a,
1137 &list_a, &elems_a, &elemp_a, &values_a);
1138 allocate_pattern (cnt_b, pat_b,
1139 &list_b, &elems_b, &elemp_b, &values_b);
1141 for (a0 = 0; a0 <= cnt_a; a0++)
1142 for (a1 = a0; a1 <= cnt_a; a1++)
1143 for (b0 = 0; b0 <= cnt_b; b0++)
1144 for (b1 = b0; b1 <= cnt_b; b1++)
1146 int a_ordering = lexicographical_compare_3way (
1147 values_a + a0, a1 - a0,
1148 values_b + b0, b1 - b0,
1150 compare_ints, NULL);
1152 int b_ordering = llx_lexicographical_compare_3way (
1153 elemp_a[a0], elemp_a[a1],
1154 elemp_b[b0], elemp_b[b1],
1155 compare_elements, &aux_data);
1157 check (a_ordering == b_ordering);
1160 free_elements (cnt_a, &list_a, elems_a, elemp_a, values_a);
1161 free_elements (cnt_b, &list_b, elems_b, elemp_b, values_b);
1165 /* Appends the `x' value in element E to the array pointed to by
1166 NEXT_OUTPUT, and advances NEXT_OUTPUT to the next position. */
1168 apply_func (void *e_, void *next_output_)
1170 struct element *e = e_;
1171 int **next_output = next_output_;
1173 *(*next_output)++ = e->x;
1176 /* Tests llx_apply. */
1180 const int max_elems = 8;
1184 for (cnt = 0; cnt <= max_elems; cnt++)
1185 for (r0 = 0; r0 <= cnt; r0++)
1186 for (r1 = r0; r1 <= cnt; r1++)
1188 struct llx_list list;
1189 struct element **elems;
1197 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1198 check_list_contents (&list, values, cnt);
1200 output = next_output = xnmalloc (cnt, sizeof *output);
1201 llx_apply (elemp[r0], elemp[r1], apply_func, &next_output);
1202 check_list_contents (&list, values, cnt);
1203 llx_destroy (&list, NULL, NULL, &llx_malloc_mgr);
1205 check (r1 - r0 == next_output - output);
1206 for (j = 0; j < r1 - r0; j++)
1207 check (output[j] == r0 + j);
1209 free_elements (cnt, NULL, elems, elemp, values);
1214 /* Tests llx_destroy. */
1218 const int max_elems = 8;
1222 for (cnt = 0; cnt <= max_elems; cnt++)
1224 struct llx_list list;
1225 struct element **elems;
1233 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1234 check_list_contents (&list, values, cnt);
1236 output = next_output = xnmalloc (cnt, sizeof *output);
1237 llx_destroy (&list, apply_func, &next_output, &llx_malloc_mgr);
1239 check (cnt == next_output - output);
1240 for (j = 0; j < cnt; j++)
1241 check (output[j] == j);
1243 free_elements (cnt, NULL, elems, elemp, values);
1248 /* Tests llx_reverse. */
1252 const int max_elems = 8;
1256 for (cnt = 0; cnt <= max_elems; cnt++)
1257 for (r0 = 0; r0 <= cnt; r0++)
1258 for (r1 = r0; r1 <= cnt; r1++)
1260 struct llx_list list;
1261 struct element **elems;
1267 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1268 check_list_contents (&list, values, cnt);
1271 for (i = 0; i < r0; i++)
1273 for (i = r1 - 1; i >= r0; i--)
1275 for (i = r1; i < cnt; i++)
1278 llx_reverse (elemp[r0], elemp[r1]);
1279 check_list_contents (&list, values, cnt);
1281 free_elements (cnt, &list, elems, elemp, values);
1285 /* Tests llx_next_permutation and llx_prev_permutation when the
1286 permuted values have no duplicates. */
1288 test_permutations_no_dups (void)
1290 const int max_elems = 8;
1293 for (cnt = 0; cnt <= max_elems; cnt++)
1295 struct llx_list list;
1296 struct element **elems;
1298 int *old_values = xnmalloc (cnt, sizeof *values);
1299 int *new_values = xnmalloc (cnt, sizeof *values);
1303 allocate_ascending (cnt, &list, &elems, NULL, &values);
1306 extract_values (&list, old_values, cnt);
1307 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1308 compare_elements, &aux_data))
1310 extract_values (&list, new_values, cnt);
1311 check (lexicographical_compare_3way (new_values, cnt,
1314 compare_ints, NULL) > 0);
1315 memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1318 check (perm_cnt == factorial (cnt));
1319 check_list_contents (&list, values, cnt);
1322 llx_reverse (llx_head (&list), llx_null (&list));
1323 extract_values (&list, old_values, cnt);
1324 while (llx_prev_permutation (llx_head (&list), llx_null (&list),
1325 compare_elements, &aux_data))
1327 extract_values (&list, new_values, cnt);
1328 check (lexicographical_compare_3way (new_values, cnt,
1331 compare_ints, NULL) < 0);
1332 memcpy (old_values, new_values, (cnt) * sizeof *old_values);
1335 check (perm_cnt == factorial (cnt));
1336 llx_reverse (llx_head (&list), llx_null (&list));
1337 check_list_contents (&list, values, cnt);
1339 free_elements (cnt, &list, elems, NULL, values);
1345 /* Tests llx_next_permutation and llx_prev_permutation when the
1346 permuted values contain duplicates. */
1348 test_permutations_with_dups (void)
1350 const int max_elems = 8;
1351 const int max_dup = 3;
1352 const int repetitions = 1024;
1356 for (repeat = 0; repeat < repetitions; repeat++)
1357 for (cnt = 0; cnt < max_elems; cnt++)
1359 struct llx_list list;
1360 struct element **elems;
1363 int *old_values = xnmalloc (max_elems, sizeof *values);
1364 int *new_values = xnmalloc (max_elems, sizeof *values);
1366 unsigned permutation_cnt;
1370 allocate_elements (cnt, &list, &elems, &elemp, &values);
1375 int max = left < max_dup ? left : max_dup;
1376 int n = rand () % max + 1;
1379 int idx = cnt - left--;
1380 values[idx] = elems[idx]->x = value;
1385 permutation_cnt = 1;
1386 extract_values (&list, old_values, cnt);
1387 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1388 compare_elements, &aux_data))
1390 extract_values (&list, new_values, cnt);
1391 check (lexicographical_compare_3way (new_values, cnt,
1394 compare_ints, NULL) > 0);
1395 memcpy (old_values, new_values, cnt * sizeof *old_values);
1398 check (permutation_cnt == expected_perms (values, cnt));
1399 check_list_contents (&list, values, cnt);
1401 permutation_cnt = 1;
1402 llx_reverse (llx_head (&list), llx_null (&list));
1403 extract_values (&list, old_values, cnt);
1404 while (llx_prev_permutation (llx_head (&list), llx_null (&list),
1405 compare_elements, &aux_data))
1407 extract_values (&list, new_values, cnt);
1408 check (lexicographical_compare_3way (new_values, cnt,
1411 compare_ints, NULL) < 0);
1414 llx_reverse (llx_head (&list), llx_null (&list));
1415 check (permutation_cnt == expected_perms (values, cnt));
1416 check_list_contents (&list, values, cnt);
1418 free_elements (cnt, &list, elems, elemp, values);
1424 /* Tests llx_merge when no equal values are to be merged. */
1426 test_merge_no_dups (void)
1428 const int max_elems = 8;
1429 const int max_fillxer = 3;
1431 int merge_cnt, pattern, pfx, gap, sfx, order;
1433 for (merge_cnt = 0; merge_cnt < max_elems; merge_cnt++)
1434 for (pattern = 0; pattern <= (1 << merge_cnt); pattern++)
1435 for (pfx = 0; pfx < max_fillxer; pfx++)
1436 for (gap = 0; gap < max_fillxer; gap++)
1437 for (sfx = 0; sfx < max_fillxer; sfx++)
1438 for (order = 0; order < 2; order++)
1440 struct llx_list list;
1441 struct element **elems;
1445 int list_cnt = pfx + merge_cnt + gap + sfx;
1449 allocate_elements (list_cnt, &list,
1450 &elems, &elemp, &values);
1453 for (i = 0; i < pfx; i++)
1454 elems[j++]->x = 100 + i;
1456 for (i = 0; i < merge_cnt; i++)
1457 if (pattern & (1u << i))
1460 for (i = 0; i < gap; i++)
1461 elems[j++]->x = 200 + i;
1463 for (i = 0; i < merge_cnt; i++)
1464 if (!(pattern & (1u << i)))
1467 for (i = 0; i < sfx; i++)
1468 elems[j++]->x = 300 + i;
1469 check (list_cnt == j);
1472 for (i = 0; i < pfx; i++)
1473 values[j++] = 100 + i;
1475 for (i = 0; i < merge_cnt; i++)
1477 for (i = 0; i < gap; i++)
1478 values[j++] = 200 + i;
1480 for (i = 0; i < merge_cnt; i++)
1482 for (i = 0; i < sfx; i++)
1483 values[j++] = 300 + i;
1484 check (list_cnt == j);
1487 llx_merge (elemp[a0], elemp[a1], elemp[b0], elemp[b1],
1488 compare_elements, &aux_data);
1490 llx_merge (elemp[b0], elemp[b1], elemp[a0], elemp[a1],
1491 compare_elements, &aux_data);
1493 check_list_contents (&list, values, list_cnt);
1495 free_elements (list_cnt, &list, elems, elemp, values);
1499 /* Tests llx_merge when equal values are to be merged. */
1501 test_merge_with_dups (void)
1503 const int max_elems = 8;
1505 int cnt, merge_pat, inc_pat, order;
1507 for (cnt = 0; cnt <= max_elems; cnt++)
1508 for (merge_pat = 0; merge_pat <= (1 << cnt); merge_pat++)
1509 for (inc_pat = 0; inc_pat <= (1 << cnt); inc_pat++)
1510 for (order = 0; order < 2; order++)
1512 struct llx_list list;
1513 struct element **elems;
1520 allocate_elements (cnt, &list, &elems, &elemp, &values);
1523 for (i = k = 0; i < cnt; i++)
1525 if (merge_pat & (1u << i))
1527 if (inc_pat & (1u << i))
1531 for (i = k = 0; i < cnt; i++)
1533 if (!(merge_pat & (1u << i)))
1535 if (inc_pat & (1u << i))
1542 for (i = 0; i < cnt; i++)
1547 for (i = 0; i < mid; i++)
1548 elems[i]->y = 100 + i;
1549 for (i = mid; i < cnt; i++)
1554 for (i = k = 0; i < cnt; i++)
1557 if (inc_pat & (1u << i))
1563 llx_merge (elemp[0], elemp[mid], elemp[mid], elemp[cnt],
1564 compare_elements, &aux_data);
1566 llx_merge (elemp[mid], elemp[cnt], elemp[0], elemp[mid],
1567 compare_elements, &aux_data);
1569 check_list_contents (&list, values, cnt);
1570 check (llx_is_sorted (llx_head (&list), llx_null (&list),
1571 compare_elements_x_y, &aux_data));
1573 free_elements (cnt, &list, elems, elemp, values);
1577 /* Tests llx_sort on all permutations up to a maximum number of
1580 test_sort_exhaustive (void)
1582 const int max_elems = 8;
1585 for (cnt = 0; cnt <= max_elems; cnt++)
1587 struct llx_list list;
1588 struct element **elems;
1591 struct element **perm_elems;
1596 allocate_ascending (cnt, &list, &elems, NULL, &values);
1597 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1600 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1601 compare_elements, &aux_data))
1603 struct llx_list perm_list;
1606 extract_values (&list, perm_values, cnt);
1607 llx_init (&perm_list);
1608 for (j = 0; j < cnt; j++)
1610 perm_elems[j]->x = perm_values[j];
1611 llx_push_tail (&perm_list, perm_elems[j], &llx_malloc_mgr);
1613 llx_sort (llx_head (&perm_list), llx_null (&perm_list),
1614 compare_elements, &aux_data);
1615 check_list_contents (&perm_list, values, cnt);
1616 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1617 compare_elements, &aux_data));
1618 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1621 check (perm_cnt == factorial (cnt));
1623 free_elements (cnt, &list, elems, NULL, values);
1624 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1628 /* Tests that llx_sort is stable in the presence of equal
1631 test_sort_stable (void)
1633 const int max_elems = 6;
1636 for (cnt = 0; cnt <= max_elems; cnt++)
1637 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1639 struct llx_list list;
1640 struct element **elems;
1643 struct element **perm_elems;
1649 allocate_elements (cnt, &list, &elems, NULL, &values);
1650 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1653 for (i = 0; i < cnt; i++)
1655 elems[i]->x = values[i] = j;
1656 if (inc_pat & (1 << i))
1662 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1663 compare_elements_y, &aux_data))
1665 struct llx_list perm_list;
1667 extract_values (&list, perm_values, cnt);
1668 llx_init (&perm_list);
1669 for (i = 0; i < cnt; i++)
1671 perm_elems[i]->x = perm_values[i];
1672 perm_elems[i]->y = i;
1673 llx_push_tail (&perm_list, perm_elems[i], &llx_malloc_mgr);
1675 llx_sort (llx_head (&perm_list), llx_null (&perm_list),
1676 compare_elements, &aux_data);
1677 check_list_contents (&perm_list, values, cnt);
1678 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1679 compare_elements_x_y, &aux_data));
1680 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1683 check (perm_cnt == factorial (cnt));
1685 free_elements (cnt, &list, elems, NULL, values);
1686 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1690 /* Tests that llx_sort does not disturb elements outside the
1693 test_sort_subset (void)
1695 const int max_elems = 8;
1697 int cnt, r0, r1, repeat;
1699 for (cnt = 0; cnt <= max_elems; cnt++)
1700 for (repeat = 0; repeat < 100; repeat++)
1701 for (r0 = 0; r0 <= cnt; r0++)
1702 for (r1 = r0; r1 <= cnt; r1++)
1704 struct llx_list list;
1705 struct element **elems;
1709 allocate_random (cnt, &list, &elems, &elemp, &values);
1711 qsort (&values[r0], r1 - r0, sizeof *values, compare_ints_noaux);
1712 llx_sort (elemp[r0], elemp[r1], compare_elements, &aux_data);
1713 check_list_contents (&list, values, cnt);
1715 free_elements (cnt, &list, elems, elemp, values);
1719 /* Tests that llx_sort works with large lists. */
1721 test_sort_big (void)
1723 const int max_elems = 1024;
1727 for (cnt = 0; cnt < max_elems; cnt++)
1729 struct llx_list list;
1730 struct element **elems;
1733 allocate_random (cnt, &list, &elems, NULL, &values);
1735 qsort (values, cnt, sizeof *values, compare_ints_noaux);
1736 llx_sort (llx_head (&list), llx_null (&list), compare_elements, &aux_data);
1737 check_list_contents (&list, values, cnt);
1739 free_elements (cnt, &list, elems, NULL, values);
1743 /* Tests llx_unique. */
1747 const int max_elems = 10;
1749 int *ascending = xnmalloc (max_elems, sizeof *ascending);
1751 int cnt, inc_pat, i, j, unique_values;
1753 for (i = 0; i < max_elems; i++)
1756 for (cnt = 0; cnt < max_elems; cnt++)
1757 for (inc_pat = 0; inc_pat < (1 << cnt); inc_pat++)
1759 struct llx_list list, dups;
1760 struct element **elems;
1763 allocate_elements (cnt, &list, &elems, NULL, &values);
1765 j = unique_values = 0;
1766 for (i = 0; i < cnt; i++)
1768 unique_values = j + 1;
1769 elems[i]->x = values[i] = j;
1770 if (inc_pat & (1 << i))
1773 check_list_contents (&list, values, cnt);
1776 check (llx_unique (llx_head (&list), llx_null (&list),
1778 compare_elements, &aux_data,
1780 == (size_t) unique_values);
1781 check_list_contents (&list, ascending, unique_values);
1783 llx_splice (llx_null (&list), llx_head (&dups), llx_null (&dups));
1784 llx_sort (llx_head (&list), llx_null (&list), compare_elements, &aux_data);
1785 check_list_contents (&list, values, cnt);
1787 llx_destroy (&dups, NULL, NULL, &llx_malloc_mgr);
1788 free_elements (cnt, &list, elems, NULL, values);
1794 /* Tests llx_sort_unique. */
1796 test_sort_unique (void)
1798 const int max_elems = 7;
1801 for (cnt = 0; cnt <= max_elems; cnt++)
1802 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1804 struct llx_list list;
1805 struct element **elems;
1808 struct element **perm_elems;
1817 allocate_elements (cnt, &list, &elems, NULL, &values);
1818 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1821 for (i = 0; i < cnt; i++)
1823 elems[i]->x = values[i] = j;
1825 if (inc_pat & (1 << i))
1829 unique_values = xnmalloc (unique_cnt, sizeof *unique_values);
1830 for (i = 0; i < unique_cnt; i++)
1831 unique_values[i] = i;
1834 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1835 compare_elements, &aux_data))
1837 struct llx_list perm_list;
1839 extract_values (&list, perm_values, cnt);
1840 llx_init (&perm_list);
1841 for (i = 0; i < cnt; i++)
1843 perm_elems[i]->x = perm_values[i];
1844 perm_elems[i]->y = i;
1845 llx_push_tail (&perm_list, perm_elems[i], &llx_malloc_mgr);
1847 llx_sort_unique (llx_head (&perm_list), llx_null (&perm_list), NULL,
1848 compare_elements, &aux_data,
1850 check_list_contents (&perm_list, unique_values, unique_cnt);
1851 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1852 compare_elements_x_y, &aux_data));
1853 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1856 check (perm_cnt == expected_perms (values, cnt));
1858 free_elements (cnt, &list, elems, NULL, values);
1859 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1860 free (unique_values);
1864 /* Tests llx_insert_ordered. */
1866 test_insert_ordered (void)
1868 const int max_elems = 6;
1871 for (cnt = 0; cnt <= max_elems; cnt++)
1872 for (inc_pat = 0; inc_pat <= 1 << cnt; inc_pat++)
1874 struct llx_list list;
1875 struct element **elems;
1878 struct element **perm_elems;
1884 allocate_elements (cnt, &list, &elems, NULL, &values);
1885 allocate_elements (cnt, NULL, &perm_elems, NULL, &perm_values);
1888 for (i = 0; i < cnt; i++)
1890 elems[i]->x = values[i] = j;
1891 if (inc_pat & (1 << i))
1897 while (llx_next_permutation (llx_head (&list), llx_null (&list),
1898 compare_elements_y, &aux_data))
1900 struct llx_list perm_list;
1902 extract_values (&list, perm_values, cnt);
1903 llx_init (&perm_list);
1904 for (i = 0; i < cnt; i++)
1906 perm_elems[i]->x = perm_values[i];
1907 perm_elems[i]->y = i;
1908 llx_insert_ordered (llx_head (&perm_list),
1909 llx_null (&perm_list),
1911 compare_elements, &aux_data,
1914 check (llx_is_sorted (llx_head (&perm_list), llx_null (&perm_list),
1915 compare_elements_x_y, &aux_data));
1916 llx_destroy (&perm_list, NULL, NULL, &llx_malloc_mgr);
1919 check (perm_cnt == factorial (cnt));
1921 free_elements (cnt, &list, elems, NULL, values);
1922 free_elements (cnt, NULL, perm_elems, NULL, perm_values);
1926 /* Tests llx_partition. */
1928 test_partition (void)
1930 const int max_elems = 10;
1936 for (cnt = 0; cnt < max_elems; cnt++)
1937 for (r0 = 0; r0 <= cnt; r0++)
1938 for (r1 = r0; r1 <= cnt; r1++)
1939 for (pbase = 0; pbase <= (1u << (r1 - r0)); pbase++)
1941 struct llx_list list;
1942 struct element **elems;
1946 unsigned pattern = pbase << r0;
1949 struct llx *part_llx;
1951 allocate_ascending (cnt, &list, &elems, &elemp, &values);
1953 /* Check that llx_find_partition works okay in every
1954 case. We use it after partitioning, too, but that
1955 only tests cases where it returns non-null. */
1956 for (i = r0; i < r1; i++)
1957 if (!(pattern & (1u << i)))
1961 if (pattern & (1u << i))
1963 part_llx = llx_find_partition (elemp[r0], elemp[r1],
1967 check (part_llx == elemp[j]);
1969 check (part_llx == NULL);
1971 /* Figure out expected results. */
1974 for (i = 0; i < r0; i++)
1976 for (i = r0; i < r1; i++)
1977 if (pattern & (1u << i))
1979 for (i = r0; i < r1; i++)
1980 if (!(pattern & (1u << i)))
1982 if (first_false == -1)
1986 if (first_false == -1)
1988 for (i = r1; i < cnt; i++)
1992 /* Partition and check for expected results. */
1993 check (llx_partition (elemp[r0], elemp[r1],
1994 pattern_pred, &pattern)
1995 == elemp[first_false]);
1996 check (llx_find_partition (elemp[r0], elemp[r1],
1997 pattern_pred, &pattern)
1998 == elemp[first_false]);
1999 check_list_contents (&list, values, cnt);
2000 check ((int) llx_count (&list) == cnt);
2002 free_elements (cnt, &list, elems, elemp, values);
2006 /* Tests that allocation failure is gracefully handled. */
2008 test_allocation_failure (void)
2010 struct llx_list list;
2013 check (llx_push_head (&list, NULL, &llx_null_mgr) == NULL);
2014 check (llx_push_tail (&list, NULL, &llx_null_mgr) == NULL);
2015 check (llx_insert (llx_null (&list), NULL, &llx_null_mgr) == NULL);
2016 check_list_contents (&list, NULL, 0);
2021 /* Runs TEST_FUNCTION and prints a message about NAME. */
2023 run_test (void (*test_function) (void), const char *name)
2034 run_test (test_push_pop, "push/pop");
2035 run_test (test_insert_remove, "insert/remove");
2036 run_test (test_swap, "swap");
2037 run_test (test_swap_range, "swap_range");
2038 run_test (test_remove_range, "remove_range");
2039 run_test (test_remove_equal, "remove_equal");
2040 run_test (test_remove_if, "remove_if");
2041 run_test (test_find_equal, "find_equal");
2042 run_test (test_find_if, "find_if");
2043 run_test (test_find_adjacent_equal, "find_adjacent_equal");
2044 run_test (test_count_range, "count_range");
2045 run_test (test_count_equal, "count_equal");
2046 run_test (test_count_if, "count_if");
2047 run_test (test_min_max, "min/max");
2048 run_test (test_lexicographical_compare_3way, "lexicographical_compare_3way");
2049 run_test (test_apply, "apply");
2050 run_test (test_destroy, "destroy");
2051 run_test (test_reverse, "reverse");
2052 run_test (test_permutations_no_dups, "permutations (no dups)");
2053 run_test (test_permutations_with_dups, "permutations (with dups)");
2054 run_test (test_merge_no_dups, "merge (no dups)");
2055 run_test (test_merge_with_dups, "merge (with dups)");
2056 run_test (test_sort_exhaustive, "sort (exhaustive)");
2057 run_test (test_sort_stable, "sort (stability)");
2058 run_test (test_sort_subset, "sort (subset)");
2059 run_test (test_sort_big, "sort (big)");
2060 run_test (test_unique, "unique");
2061 run_test (test_sort_unique, "sort_unique");
2062 run_test (test_insert_ordered, "insert_ordered");
2063 run_test (test_partition, "partition");
2064 run_test (test_allocation_failure, "allocation failure");
2072 compile-command: "gcc -Wall -Wstrict-prototypes -Wmissing-prototypes ll.c llx.c llx-test.c -o llx-test -g"