1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006, 2010 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>
38 /* Support preliminaries. */
39 #if __GNUC__ >= 2 && !defined UNUSED
40 #define UNUSED __attribute__ ((unused))
45 /* Exit with a failure code.
46 (Place a breakpoint on this function while debugging.) */
53 /* If OK is not true, prints a message about failure on the
54 current source file and the given LINE and terminates. */
56 check_func (bool ok
, int line
)
60 fprintf (stderr
, "%s:%d: check failed\n", __FILE__
, line
);
65 /* Verifies that EXPR evaluates to true.
66 If not, prints a message citing the calling line number and
68 #define check(EXPR) check_func ((EXPR), __LINE__)
70 /* Prints a message about memory exhaustion and exits with a
75 printf ("virtual memory exhausted\n");
79 /* Allocates and returns N bytes of memory. */
95 /* Allocates and returns N * M bytes of memory. */
97 xnmalloc (size_t n
, size_t m
)
99 if ((size_t) -1 / m
<= n
)
101 return xmalloc (n
* m
);
104 /* List type and support routines. */
106 /* Test data element. */
109 struct ll ll
; /* Embedded list element. */
110 int x
; /* Primary value. */
111 int y
; /* Secondary value. */
116 /* Returns the `struct element' that LL is embedded within. */
117 static struct element
*
118 ll_to_element (const struct ll
*ll
)
120 return ll_data (ll
, struct element
, ll
);
123 /* Prints the elements in LIST. */
125 print_list (struct ll_list
*list
)
130 for (x
= ll_head (list
); x
!= ll_null (list
); x
= ll_next (x
))
132 struct element
*e
= ll_to_element (x
);
133 printf (" %d", e
->x
);
138 /* Prints the value returned by PREDICATE given auxiliary data
139 AUX for each element in LIST. */
141 print_pred (struct ll_list
*list
,
142 ll_predicate_func
*predicate
, void *aux UNUSED
)
147 for (x
= ll_head (list
); x
!= ll_null (list
); x
= ll_next (x
))
148 printf (" %d", predicate (x
, aux
));
152 /* Prints the N numbers in VALUES. */
154 print_array (int values
[], size_t n
)
159 for (i
= 0; i
< n
; i
++)
160 printf (" %d", values
[i
]);
164 /* Compares the `x' values in A and B and returns a strcmp-type
165 return value. Verifies that AUX points to aux_data. */
167 compare_elements (const struct ll
*a_
, const struct ll
*b_
, void *aux
)
169 const struct element
*a
= ll_to_element (a_
);
170 const struct element
*b
= ll_to_element (b_
);
172 check (aux
== &aux_data
);
173 return a
->x
< b
->x
? -1 : a
->x
> b
->x
;
176 /* Compares the `x' and `y' values in A and B and returns a
177 strcmp-type return value. Verifies that AUX points to
180 compare_elements_x_y (const struct ll
*a_
, const struct ll
*b_
, void *aux
)
182 const struct element
*a
= ll_to_element (a_
);
183 const struct element
*b
= ll_to_element (b_
);
185 check (aux
== &aux_data
);
187 return a
->x
< b
->x
? -1 : 1;
188 else if (a
->y
!= b
->y
)
189 return a
->y
< b
->y
? -1 : 1;
194 /* Compares the `y' values in A and B and returns a strcmp-type
195 return value. Verifies that AUX points to aux_data. */
197 compare_elements_y (const struct ll
*a_
, const struct ll
*b_
, void *aux
)
199 const struct element
*a
= ll_to_element (a_
);
200 const struct element
*b
= ll_to_element (b_
);
202 check (aux
== &aux_data
);
203 return a
->y
< b
->y
? -1 : a
->y
> b
->y
;
206 /* Returns true if the bit in *PATTERN indicated by `x in
207 *ELEMENT is set, false otherwise. */
209 pattern_pred (const struct ll
*element_
, void *pattern_
)
211 const struct element
*element
= ll_to_element (element_
);
212 unsigned int *pattern
= pattern_
;
214 return (*pattern
& (1u << element
->x
)) != 0;
217 /* Allocates N elements in *ELEMS.
218 Adds the elements to LIST, if it is nonnull.
219 Puts pointers to the elements' list elements in *ELEMP,
220 followed by a pointer to the list null element, if ELEMP is
222 Allocates space for N values in *VALUES, if VALUES is
225 allocate_elements (size_t n
,
226 struct ll_list
*list
,
227 struct element
***elems
,
236 *elems
= xnmalloc (n
, sizeof **elems
);
237 for (i
= 0; i
< n
; i
++)
239 (*elems
)[i
] = xmalloc (sizeof ***elems
);
241 ll_push_tail (list
, &(*elems
)[i
]->ll
);
246 *elemp
= xnmalloc (n
+ 1, sizeof *elemp
);
247 for (i
= 0; i
< n
; i
++)
248 (*elemp
)[i
] = &(*elems
)[i
]->ll
;
249 (*elemp
)[n
] = ll_null (list
);
253 *values
= xnmalloc (n
, sizeof *values
);
256 /* Copies the N values of `x' from LIST into VALUES[]. */
258 extract_values (struct ll_list
*list
, int values
[], size_t n
)
262 check (ll_count (list
) == n
);
263 for (x
= ll_head (list
); x
!= ll_null (list
); x
= ll_next (x
))
265 struct element
*e
= ll_to_element (x
);
270 /* As allocate_elements, but sets ascending values, starting
271 from 0, in `x' values in *ELEMS and in *VALUES (if
274 allocate_ascending (size_t n
,
275 struct ll_list
*list
,
276 struct element
***elems
,
282 allocate_elements (n
, list
, elems
, elemp
, values
);
284 for (i
= 0; i
< n
; i
++)
287 extract_values (list
, *values
, n
);
290 /* As allocate_elements, but sets binary values extracted from
291 successive bits in PATTERN in `x' values in *ELEMS and in
292 *VALUES (if nonnull). */
294 allocate_pattern (size_t n
,
296 struct ll_list
*list
,
297 struct element
***elems
,
303 allocate_elements (n
, list
, elems
, elemp
, values
);
305 for (i
= 0; i
< n
; i
++)
306 (*elems
)[i
]->x
= (pattern
& (1 << i
)) != 0;
308 extract_values (list
, *values
, n
);
311 /* Randomly shuffles the N elements in ARRAY, each of which is
312 SIZE bytes in size. */
314 random_shuffle (void *array_
, size_t n
, size_t size
)
316 char *array
= array_
;
317 char *tmp
= xmalloc (size
);
320 for (i
= 0; i
< n
; i
++)
322 size_t j
= rand () % (n
- i
) + i
;
325 memcpy (tmp
, array
+ j
* size
, size
);
326 memcpy (array
+ j
* size
, array
+ i
* size
, size
);
327 memcpy (array
+ i
* size
, tmp
, size
);
334 /* As allocate_ascending, but orders the values randomly. */
336 allocate_random (size_t n
,
337 struct ll_list
*list
,
338 struct element
***elems
,
344 allocate_elements (n
, list
, elems
, elemp
, values
);
346 for (i
= 0; i
< n
; i
++)
348 random_shuffle (*elems
, n
, sizeof **elems
);
350 extract_values (list
, *values
, n
);
353 /* Frees the N elements of ELEMS, ELEMP, and VALUES. */
355 free_elements (size_t n
,
356 struct element
**elems
,
362 for (i
= 0; i
< n
; i
++)
369 /* Compares A and B and returns a strcmp-type return value. */
371 compare_ints (const void *a_
, const void *b_
, void *aux UNUSED
)
376 return *a
< *b
? -1 : *a
> *b
;
379 /* Compares A and B and returns a strcmp-type return value. */
381 compare_ints_noaux (const void *a_
, const void *b_
)
386 return *a
< *b
? -1 : *a
> *b
;
389 /* Checks that LIST contains the N values in ELEMENTS. */
391 check_list_contents (struct ll_list
*list
, int elements
[], size_t n
)
396 check ((n
== 0) == ll_is_empty (list
));
398 /* Iterate in forward order. */
399 for (ll
= ll_head (list
), i
= 0; i
< n
; ll
= ll_next (ll
), i
++)
401 struct element
*e
= ll_to_element (ll
);
402 check (elements
[i
] == e
->x
);
403 check (ll
!= ll_null (list
));
405 check (ll
== ll_null (list
));
407 /* Iterate in reverse order. */
408 for (ll
= ll_tail (list
), i
= 0; i
< n
; ll
= ll_prev (ll
), i
++)
410 struct element
*e
= ll_to_element (ll
);
411 check (elements
[n
- i
- 1] == e
->x
);
412 check (ll
!= ll_null (list
));
414 check (ll
== ll_null (list
));
416 check (ll_count (list
) == n
);
419 /* Lexicographically compares ARRAY1, which contains COUNT1
420 elements of SIZE bytes each, to ARRAY2, which contains COUNT2
421 elements of SIZE bytes, according to COMPARE. Returns a
422 strcmp-type result. AUX is passed to COMPARE as auxiliary
425 lexicographical_compare_3way (const void *array1
, size_t count1
,
426 const void *array2
, size_t count2
,
428 int (*compare
) (const void *, const void *,
432 const char *first1
= array1
;
433 const char *first2
= array2
;
434 size_t min_count
= count1
< count2
? count1
: count2
;
436 while (min_count
> 0)
438 int cmp
= compare (first1
, first2
, aux
);
447 return count1
< count2
? -1 : count1
> count2
;
452 /* Tests list push and pop operations. */
456 const int max_elems
= 1024;
459 struct element
**elems
;
464 allocate_elements (max_elems
, NULL
, &elems
, NULL
, &values
);
468 check_list_contents (&list
, NULL
, 0);
469 for (i
= 0; i
< max_elems
; i
++)
471 values
[i
] = elems
[i
]->x
= i
;
472 ll_push_tail (&list
, &elems
[i
]->ll
);
473 check_list_contents (&list
, values
, i
+ 1);
476 /* Remove from tail. */
477 for (i
= 0; i
< max_elems
; i
++)
479 struct element
*e
= ll_to_element (ll_pop_tail (&list
));
480 check (e
->x
== max_elems
- i
- 1);
481 check_list_contents (&list
, values
, max_elems
- i
- 1);
485 check_list_contents (&list
, NULL
, 0);
486 for (i
= 0; i
< max_elems
; i
++)
488 values
[max_elems
- i
- 1] = elems
[i
]->x
= max_elems
- i
- 1;
489 ll_push_head (&list
, &elems
[i
]->ll
);
490 check_list_contents (&list
, &values
[max_elems
- i
- 1], i
+ 1);
493 /* Remove from start. */
494 for (i
= 0; i
< max_elems
; i
++)
496 struct element
*e
= ll_to_element (ll_pop_head (&list
));
497 check (e
->x
== (int) i
);
498 check_list_contents (&list
, &values
[i
+ 1], max_elems
- i
- 1);
501 free_elements (max_elems
, elems
, NULL
, values
);
504 /* Tests insertion and removal at arbitrary positions. */
506 test_insert_remove (void)
508 const int max_elems
= 16;
511 for (n
= 0; n
< max_elems
; n
++)
513 struct element
**elems
;
515 int *values
= xnmalloc (n
+ 1, sizeof *values
);
518 struct element extra
;
521 allocate_ascending (n
, &list
, &elems
, &elemp
, NULL
);
523 for (pos
= 0; pos
<= n
; pos
++)
527 ll_insert (elemp
[pos
], &extra
.ll
);
530 for (i
= 0; i
< pos
; i
++)
535 check_list_contents (&list
, values
, n
+ 1);
537 ll_remove (&extra
.ll
);
539 check_list_contents (&list
, values
, n
);
541 free_elements (n
, elems
, elemp
, values
);
545 /* Tests swapping individual elements. */
549 const int max_elems
= 8;
552 for (n
= 0; n
<= max_elems
; n
++)
555 struct element
**elems
;
560 allocate_ascending (n
, &list
, &elems
, NULL
, &values
);
561 check_list_contents (&list
, values
, n
);
563 for (i
= 0; i
< n
; i
++)
564 for (j
= 0; j
< n
; j
++)
565 for (k
= 0; k
< 2; k
++)
569 ll_swap (&elems
[i
]->ll
, &elems
[j
]->ll
);
571 values
[i
] = values
[j
];
573 check_list_contents (&list
, values
, n
);
576 free_elements (n
, elems
, NULL
, values
);
580 /* Tests swapping ranges of list elements. */
582 test_swap_range (void)
584 const int max_elems
= 8;
585 int n
, a0
, a1
, b0
, b1
, r
;
587 for (n
= 0; n
<= max_elems
; n
++)
588 for (a0
= 0; a0
<= n
; a0
++)
589 for (a1
= a0
; a1
<= n
; a1
++)
590 for (b0
= a1
; b0
<= n
; b0
++)
591 for (b1
= b0
; b1
<= n
; b1
++)
592 for (r
= 0; r
< 2; r
++)
595 struct element
**elems
;
601 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
602 check_list_contents (&list
, values
, n
);
605 for (i
= 0; i
< a0
; i
++)
607 for (i
= b0
; i
< b1
; i
++)
609 for (i
= a1
; i
< b0
; i
++)
611 for (i
= a0
; i
< a1
; i
++)
613 for (i
= b1
; i
< n
; i
++)
618 ll_swap_range (elemp
[a0
], elemp
[a1
], elemp
[b0
], elemp
[b1
]);
620 ll_swap_range (elemp
[b0
], elemp
[b1
], elemp
[a0
], elemp
[a1
]);
621 check_list_contents (&list
, values
, n
);
623 free_elements (n
, elems
, elemp
, values
);
627 /* Tests removing ranges of list elements. */
629 test_remove_range (void)
631 const int max_elems
= 8;
635 for (n
= 0; n
<= max_elems
; n
++)
636 for (r0
= 0; r0
<= n
; r0
++)
637 for (r1
= r0
; r1
<= n
; r1
++)
640 struct element
**elems
;
646 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
647 check_list_contents (&list
, values
, n
);
650 for (i
= 0; i
< r0
; i
++)
652 for (i
= r1
; i
< n
; i
++)
655 ll_remove_range (elemp
[r0
], elemp
[r1
]);
656 check_list_contents (&list
, values
, j
);
658 free_elements (n
, elems
, elemp
, values
);
662 /* Tests ll_remove_equal. */
664 test_remove_equal (void)
666 const int max_elems
= 8;
668 int n
, r0
, r1
, eq_pat
;
670 for (n
= 0; n
<= max_elems
; n
++)
671 for (r0
= 0; r0
<= n
; r0
++)
672 for (r1
= r0
; r1
<= n
; r1
++)
673 for (eq_pat
= 0; eq_pat
<= 1 << n
; eq_pat
++)
676 struct element
**elems
;
680 struct element to_remove
;
684 allocate_elements (n
, &list
, &elems
, &elemp
, &values
);
687 for (i
= 0; i
< n
; i
++)
689 int x
= eq_pat
& (1 << i
) ? -1 : i
;
690 bool delete = x
== -1 && r0
<= i
&& i
< r1
;
693 values
[remaining
++] = x
;
697 check ((int) ll_remove_equal (elemp
[r0
], elemp
[r1
], &to_remove
.ll
,
698 compare_elements
, &aux_data
)
700 check_list_contents (&list
, values
, remaining
);
702 free_elements (n
, elems
, elemp
, values
);
706 /* Tests ll_remove_if. */
708 test_remove_if (void)
710 const int max_elems
= 8;
712 int n
, r0
, r1
, pattern
;
714 for (n
= 0; n
<= max_elems
; n
++)
715 for (r0
= 0; r0
<= n
; r0
++)
716 for (r1
= r0
; r1
<= n
; r1
++)
717 for (pattern
= 0; pattern
<= 1 << n
; pattern
++)
720 struct element
**elems
;
727 allocate_elements (n
, &list
, &elems
, &elemp
, &values
);
730 for (i
= 0; i
< n
; i
++)
732 bool delete = (pattern
& (1 << i
)) && r0
<= i
&& i
< r1
;
735 values
[remaining
++] = i
;
738 check ((int) ll_remove_if (elemp
[r0
], elemp
[r1
],
739 pattern_pred
, &pattern
)
741 check_list_contents (&list
, values
, remaining
);
743 free_elements (n
, elems
, elemp
, values
);
747 /* Tests ll_moved. */
751 const int max_elems
= 8;
755 for (n
= 0; n
<= max_elems
; n
++)
758 struct element
**elems
;
759 struct element
**new_elems
;
764 allocate_ascending (n
, &list
, &elems
, NULL
, &values
);
765 allocate_elements (n
, NULL
, &new_elems
, NULL
, NULL
);
766 check_list_contents (&list
, values
, n
);
768 for (i
= 0; i
< n
; i
++)
770 *new_elems
[i
] = *elems
[i
];
771 ll_moved (&new_elems
[i
]->ll
);
772 check_list_contents (&list
, values
, n
);
775 free_elements (n
, elems
, NULL
, values
);
776 free_elements (n
, new_elems
, NULL
, NULL
);
780 /* Tests, via HELPER, a function that looks at list elements
781 equal to some specified element. */
783 test_examine_equal_range (void (*helper
) (int r0
, int r1
, int eq_pat
,
787 const int max_elems
= 8;
789 int n
, r0
, r1
, eq_pat
;
791 for (n
= 0; n
<= max_elems
; n
++)
792 for (eq_pat
= 0; eq_pat
<= 1 << n
; eq_pat
++)
795 struct element
**elems
;
799 struct element to_find
;
803 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
805 for (i
= 0; i
< n
; i
++)
806 if (eq_pat
& (1 << i
))
807 values
[i
] = elems
[i
]->x
= -1;
810 for (r0
= 0; r0
<= n
; r0
++)
811 for (r1
= r0
; r1
<= n
; r1
++)
812 helper (r0
, r1
, eq_pat
, &to_find
.ll
, elemp
);
814 check_list_contents (&list
, values
, n
);
816 free_elements (n
, elems
, elemp
, values
);
820 /* Tests, via HELPER, a function that looks at list elements for
821 which a given predicate returns true. */
823 test_examine_if_range (void (*helper
) (int r0
, int r1
, int eq_pat
,
826 const int max_elems
= 8;
828 int n
, r0
, r1
, eq_pat
;
830 for (n
= 0; n
<= max_elems
; n
++)
831 for (eq_pat
= 0; eq_pat
<= 1 << n
; eq_pat
++)
834 struct element
**elems
;
838 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
840 for (r0
= 0; r0
<= n
; r0
++)
841 for (r1
= r0
; r1
<= n
; r1
++)
842 helper (r0
, r1
, eq_pat
, elemp
);
844 check_list_contents (&list
, values
, n
);
846 free_elements (n
, elems
, elemp
, values
);
850 /* Helper function for testing ll_find_equal. */
852 test_find_equal_helper (int r0
, int r1
, int eq_pat
,
853 struct ll
*to_find
, struct ll
**elemp
)
858 match
= ll_find_equal (elemp
[r0
], elemp
[r1
], to_find
,
859 compare_elements
, &aux_data
);
860 for (i
= r0
; i
< r1
; i
++)
861 if (eq_pat
& (1 << i
))
864 check (match
== elemp
[i
]);
867 /* Tests ll_find_equal. */
869 test_find_equal (void)
871 test_examine_equal_range (test_find_equal_helper
);
874 /* Helper function for testing ll_find_if. */
876 test_find_if_helper (int r0
, int r1
, int eq_pat
, struct ll
**elemp
)
878 struct ll
*match
= ll_find_if (elemp
[r0
], elemp
[r1
],
879 pattern_pred
, &eq_pat
);
882 for (i
= r0
; i
< r1
; i
++)
883 if (eq_pat
& (1 << i
))
886 check (match
== elemp
[i
]);
889 /* Tests ll_find_if. */
893 test_examine_if_range (test_find_if_helper
);
896 /* Tests ll_find_adjacent_equal. */
898 test_find_adjacent_equal (void)
900 const int max_elems
= 8;
904 for (n
= 0; n
<= max_elems
; n
++)
905 for (eq_pat
= 0; eq_pat
<= 1 << n
; eq_pat
++)
908 struct element
**elems
;
915 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
918 for (i
= 0; i
< n
- 1; i
++)
921 if (eq_pat
& (1 << i
))
923 values
[i
] = elems
[i
]->x
= match
;
924 values
[i
+ 1] = elems
[i
+ 1]->x
= match
;
930 for (i
= 0; i
<= n
; i
++)
932 struct ll
*ll1
= ll_find_adjacent_equal (elemp
[i
], ll_null (&list
),
938 ll2
= ll_null (&list
);
939 for (j
= i
; j
< n
- 1; j
++)
940 if (eq_pat
& (1 << j
))
947 check_list_contents (&list
, values
, n
);
949 free_elements (n
, elems
, elemp
, values
);
953 /* Helper function for testing ll_count_range. */
955 test_count_range_helper (int r0
, int r1
, int eq_pat UNUSED
, struct ll
**elemp
)
957 check ((int) ll_count_range (elemp
[r0
], elemp
[r1
]) == r1
- r0
);
960 /* Tests ll_count_range. */
962 test_count_range (void)
964 test_examine_if_range (test_count_range_helper
);
967 /* Helper function for testing ll_count_equal. */
969 test_count_equal_helper (int r0
, int r1
, int eq_pat
,
970 struct ll
*to_find
, struct ll
**elemp
)
975 count1
= ll_count_equal (elemp
[r0
], elemp
[r1
], to_find
,
976 compare_elements
, &aux_data
);
978 for (i
= r0
; i
< r1
; i
++)
979 if (eq_pat
& (1 << i
))
982 check (count1
== count2
);
985 /* Tests ll_count_equal. */
987 test_count_equal (void)
989 test_examine_equal_range (test_count_equal_helper
);
992 /* Helper function for testing ll_count_if. */
994 test_count_if_helper (int r0
, int r1
, int eq_pat
, struct ll
**elemp
)
1000 count1
= ll_count_if (elemp
[r0
], elemp
[r1
], pattern_pred
, &eq_pat
);
1003 for (i
= r0
; i
< r1
; i
++)
1004 if (eq_pat
& (1 << i
))
1007 check (count1
== count2
);
1010 /* Tests ll_count_if. */
1012 test_count_if (void)
1014 test_examine_if_range (test_count_if_helper
);
1019 factorial (unsigned int n
)
1021 unsigned int value
= 1;
1027 /* Returns the number of permutations of the N values in
1028 VALUES. If VALUES contains duplicates, they must be
1031 expected_perms (int *values
, size_t n
)
1034 unsigned int n_perms
;
1036 n_perms
= factorial (n
);
1037 for (i
= 0; i
< n
; i
= j
)
1039 for (j
= i
+ 1; j
< n
; j
++)
1040 if (values
[i
] != values
[j
])
1042 n_perms
/= factorial (j
- i
);
1047 /* Tests ll_min and ll_max. */
1051 const int max_elems
= 6;
1054 for (n
= 0; n
<= max_elems
; n
++)
1056 struct ll_list list
;
1057 struct element
**elems
;
1060 int *new_values
= xnmalloc (n
, sizeof *values
);
1064 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
1067 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1068 compare_elements
, &aux_data
))
1074 for (i
= 0, x
= ll_head (&list
); x
!= ll_null (&list
);
1075 x
= ll_next (x
), i
++)
1077 struct element
*e
= ll_to_element (x
);
1079 new_values
[i
] = e
->x
;
1081 for (r0
= 0; r0
<= n
; r0
++)
1082 for (r1
= r0
; r1
<= n
; r1
++)
1084 struct ll
*min
= ll_min (elemp
[r0
], elemp
[r1
],
1085 compare_elements
, &aux_data
);
1086 struct ll
*max
= ll_max (elemp
[r0
], elemp
[r1
],
1087 compare_elements
, &aux_data
);
1090 check (min
== elemp
[r1
]);
1091 check (max
== elemp
[r1
]);
1095 int min_int
, max_int
;
1098 min_int
= max_int
= new_values
[r0
];
1099 for (i
= r0
; i
< r1
; i
++)
1101 int value
= new_values
[i
];
1102 if (value
< min_int
)
1104 if (value
> max_int
)
1107 check (min
!= elemp
[r1
]
1108 && ll_to_element (min
)->x
== min_int
);
1109 check (max
!= elemp
[r1
]
1110 && ll_to_element (max
)->x
== max_int
);
1115 check (n_perms
== factorial (n
));
1116 check_list_contents (&list
, values
, n
);
1118 free_elements (n
, elems
, elemp
, values
);
1123 /* Tests ll_lexicographical_compare_3way. */
1125 test_lexicographical_compare_3way (void)
1127 const int max_elems
= 4;
1129 int n_a
, pat_a
, n_b
, pat_b
;
1131 for (n_a
= 0; n_a
<= max_elems
; n_a
++)
1132 for (pat_a
= 0; pat_a
<= 1 << n_a
; pat_a
++)
1133 for (n_b
= 0; n_b
<= max_elems
; n_b
++)
1134 for (pat_b
= 0; pat_b
<= 1 << n_b
; pat_b
++)
1136 struct ll_list list_a
, list_b
;
1137 struct element
**elems_a
, **elems_b
;
1138 struct ll
**elemp_a
, **elemp_b
;
1139 int *values_a
, *values_b
;
1143 allocate_pattern (n_a
, pat_a
,
1144 &list_a
, &elems_a
, &elemp_a
, &values_a
);
1145 allocate_pattern (n_b
, pat_b
,
1146 &list_b
, &elems_b
, &elemp_b
, &values_b
);
1148 for (a0
= 0; a0
<= n_a
; a0
++)
1149 for (a1
= a0
; a1
<= n_a
; a1
++)
1150 for (b0
= 0; b0
<= n_b
; b0
++)
1151 for (b1
= b0
; b1
<= n_b
; b1
++)
1153 int a_ordering
= lexicographical_compare_3way (
1154 values_a
+ a0
, a1
- a0
,
1155 values_b
+ b0
, b1
- b0
,
1157 compare_ints
, NULL
);
1159 int b_ordering
= ll_lexicographical_compare_3way (
1160 elemp_a
[a0
], elemp_a
[a1
],
1161 elemp_b
[b0
], elemp_b
[b1
],
1162 compare_elements
, &aux_data
);
1164 check (a_ordering
== b_ordering
);
1167 free_elements (n_a
, elems_a
, elemp_a
, values_a
);
1168 free_elements (n_b
, elems_b
, elemp_b
, values_b
);
1172 /* Appends the `x' value in element E to the array pointed to by
1173 NEXT_OUTPUT, and advances NEXT_OUTPUT to the next position. */
1175 apply_func (struct ll
*e_
, void *next_output_
)
1177 struct element
*e
= ll_to_element (e_
);
1178 int **next_output
= next_output_
;
1180 *(*next_output
)++ = e
->x
;
1183 /* Tests ll_apply. */
1187 const int max_elems
= 8;
1191 for (n
= 0; n
<= max_elems
; n
++)
1192 for (r0
= 0; r0
<= n
; r0
++)
1193 for (r1
= r0
; r1
<= n
; r1
++)
1195 struct ll_list list
;
1196 struct element
**elems
;
1205 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
1206 check_list_contents (&list
, values
, n
);
1208 output
= next_output
= xnmalloc (n
, sizeof *output
);
1209 ll_apply (elemp
[r0
], elemp
[r1
], apply_func
, &next_output
);
1210 check_list_contents (&list
, values
, n
);
1212 check (r1
- r0
== next_output
- output
);
1213 for (i
= 0; i
< r1
- r0
; i
++)
1214 check (output
[i
] == r0
+ i
);
1216 free_elements (n
, elems
, elemp
, values
);
1221 /* Tests ll_reverse. */
1225 const int max_elems
= 8;
1229 for (n
= 0; n
<= max_elems
; n
++)
1230 for (r0
= 0; r0
<= n
; r0
++)
1231 for (r1
= r0
; r1
<= n
; r1
++)
1233 struct ll_list list
;
1234 struct element
**elems
;
1240 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
1241 check_list_contents (&list
, values
, n
);
1244 for (i
= 0; i
< r0
; i
++)
1246 for (i
= r1
- 1; i
>= r0
; i
--)
1248 for (i
= r1
; i
< n
; i
++)
1251 ll_reverse (elemp
[r0
], elemp
[r1
]);
1252 check_list_contents (&list
, values
, n
);
1254 free_elements (n
, elems
, elemp
, values
);
1258 /* Tests ll_next_permutation and ll_prev_permutation when the
1259 permuted values have no duplicates. */
1261 test_permutations_no_dups (void)
1263 const int max_elems
= 8;
1266 for (n
= 0; n
<= max_elems
; n
++)
1268 struct ll_list list
;
1269 struct element
**elems
;
1271 int *old_values
= xnmalloc (n
, sizeof *values
);
1272 int *new_values
= xnmalloc (n
, sizeof *values
);
1276 allocate_ascending (n
, &list
, &elems
, NULL
, &values
);
1279 extract_values (&list
, old_values
, n
);
1280 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1281 compare_elements
, &aux_data
))
1283 extract_values (&list
, new_values
, n
);
1284 check (lexicographical_compare_3way (new_values
, n
,
1287 compare_ints
, NULL
) > 0);
1288 memcpy (old_values
, new_values
, (n
) * sizeof *old_values
);
1291 check (n_perms
== factorial (n
));
1292 check_list_contents (&list
, values
, n
);
1295 ll_reverse (ll_head (&list
), ll_null (&list
));
1296 extract_values (&list
, old_values
, n
);
1297 while (ll_prev_permutation (ll_head (&list
), ll_null (&list
),
1298 compare_elements
, &aux_data
))
1300 extract_values (&list
, new_values
, n
);
1301 check (lexicographical_compare_3way (new_values
, n
,
1304 compare_ints
, NULL
) < 0);
1305 memcpy (old_values
, new_values
, (n
) * sizeof *old_values
);
1308 check (n_perms
== factorial (n
));
1309 ll_reverse (ll_head (&list
), ll_null (&list
));
1310 check_list_contents (&list
, values
, n
);
1312 free_elements (n
, elems
, NULL
, values
);
1318 /* Tests ll_next_permutation and ll_prev_permutation when the
1319 permuted values contain duplicates. */
1321 test_permutations_with_dups (void)
1323 const int max_elems
= 8;
1324 const int max_dup
= 3;
1325 const int repetitions
= 1024;
1327 for (int repeat
= 0; repeat
< repetitions
; repeat
++)
1328 for (int n_elems
= 0; n_elems
< max_elems
; n_elems
++)
1330 struct ll_list list
;
1331 struct element
**elems
;
1333 int *old_values
= xnmalloc (max_elems
, sizeof *values
);
1334 int *new_values
= xnmalloc (max_elems
, sizeof *values
);
1336 unsigned int n_permutations
;
1340 allocate_elements (n_elems
, &list
, &elems
, NULL
, &values
);
1345 int max
= left
< max_dup
? left
: max_dup
;
1346 int n
= rand () % max
+ 1;
1349 int idx
= n_elems
- left
--;
1350 values
[idx
] = elems
[idx
]->x
= value
;
1356 extract_values (&list
, old_values
, n_elems
);
1357 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1358 compare_elements
, &aux_data
))
1360 extract_values (&list
, new_values
, n_elems
);
1361 check (lexicographical_compare_3way (new_values
, n_elems
,
1362 old_values
, n_elems
,
1364 compare_ints
, NULL
) > 0);
1365 memcpy (old_values
, new_values
, n_elems
* sizeof *old_values
);
1368 check (n_permutations
== expected_perms (values
, n_elems
));
1369 check_list_contents (&list
, values
, n_elems
);
1372 ll_reverse (ll_head (&list
), ll_null (&list
));
1373 extract_values (&list
, old_values
, n_elems
);
1374 while (ll_prev_permutation (ll_head (&list
), ll_null (&list
),
1375 compare_elements
, &aux_data
))
1377 extract_values (&list
, new_values
, n_elems
);
1378 check (lexicographical_compare_3way (new_values
, n_elems
,
1379 old_values
, n_elems
,
1381 compare_ints
, NULL
) < 0);
1384 ll_reverse (ll_head (&list
), ll_null (&list
));
1385 check (n_permutations
== expected_perms (values
, n_elems
));
1386 check_list_contents (&list
, values
, n_elems
);
1388 free_elements (n_elems
, elems
, NULL
, values
);
1394 /* Tests ll_merge when no equal values are to be merged. */
1396 test_merge_no_dups (void)
1398 const int max_elems
= 8;
1399 const int max_filler
= 3;
1401 int n_merges
, pattern
, pfx
, gap
, sfx
, order
;
1403 for (n_merges
= 0; n_merges
< max_elems
; n_merges
++)
1404 for (pattern
= 0; pattern
<= (1 << n_merges
); pattern
++)
1405 for (pfx
= 0; pfx
< max_filler
; pfx
++)
1406 for (gap
= 0; gap
< max_filler
; gap
++)
1407 for (sfx
= 0; sfx
< max_filler
; sfx
++)
1408 for (order
= 0; order
< 2; order
++)
1410 struct ll_list list
;
1411 struct element
**elems
;
1415 int n_lists
= pfx
+ n_merges
+ gap
+ sfx
;
1419 allocate_elements (n_lists
, &list
,
1420 &elems
, &elemp
, &values
);
1423 for (i
= 0; i
< pfx
; i
++)
1424 elems
[j
++]->x
= 100 + i
;
1426 for (i
= 0; i
< n_merges
; i
++)
1427 if (pattern
& (1u << i
))
1430 for (i
= 0; i
< gap
; i
++)
1431 elems
[j
++]->x
= 200 + i
;
1433 for (i
= 0; i
< n_merges
; i
++)
1434 if (!(pattern
& (1u << i
)))
1437 for (i
= 0; i
< sfx
; i
++)
1438 elems
[j
++]->x
= 300 + i
;
1439 check (n_lists
== j
);
1442 for (i
= 0; i
< pfx
; i
++)
1443 values
[j
++] = 100 + i
;
1445 for (i
= 0; i
< n_merges
; i
++)
1447 for (i
= 0; i
< gap
; i
++)
1448 values
[j
++] = 200 + i
;
1450 for (i
= 0; i
< n_merges
; i
++)
1452 for (i
= 0; i
< sfx
; i
++)
1453 values
[j
++] = 300 + i
;
1454 check (n_lists
== j
);
1457 ll_merge (elemp
[a0
], elemp
[a1
], elemp
[b0
], elemp
[b1
],
1458 compare_elements
, &aux_data
);
1460 ll_merge (elemp
[b0
], elemp
[b1
], elemp
[a0
], elemp
[a1
],
1461 compare_elements
, &aux_data
);
1463 check_list_contents (&list
, values
, n_lists
);
1465 free_elements (n_lists
, elems
, elemp
, values
);
1469 /* Tests ll_merge when equal values are to be merged. */
1471 test_merge_with_dups (void)
1473 const int max_elems
= 8;
1475 int n
, merge_pat
, inc_pat
, order
;
1477 for (n
= 0; n
<= max_elems
; n
++)
1478 for (merge_pat
= 0; merge_pat
<= (1 << n
); merge_pat
++)
1479 for (inc_pat
= 0; inc_pat
<= (1 << n
); inc_pat
++)
1480 for (order
= 0; order
< 2; order
++)
1482 struct ll_list list
;
1483 struct element
**elems
;
1490 allocate_elements (n
, &list
, &elems
, &elemp
, &values
);
1493 for (i
= k
= 0; i
< n
; i
++)
1495 if (merge_pat
& (1u << i
))
1497 if (inc_pat
& (1u << i
))
1501 for (i
= k
= 0; i
< n
; i
++)
1503 if (!(merge_pat
& (1u << i
)))
1505 if (inc_pat
& (1u << i
))
1512 for (i
= 0; i
< n
; i
++)
1517 for (i
= 0; i
< mid
; i
++)
1518 elems
[i
]->y
= 100 + i
;
1519 for (i
= mid
; i
< n
; i
++)
1524 for (i
= k
= 0; i
< n
; i
++)
1527 if (inc_pat
& (1u << i
))
1533 ll_merge (elemp
[0], elemp
[mid
], elemp
[mid
], elemp
[n
],
1534 compare_elements
, &aux_data
);
1536 ll_merge (elemp
[mid
], elemp
[n
], elemp
[0], elemp
[mid
],
1537 compare_elements
, &aux_data
);
1539 check_list_contents (&list
, values
, n
);
1540 check (ll_is_sorted (ll_head (&list
), ll_null (&list
),
1541 compare_elements_x_y
, &aux_data
));
1543 free_elements (n
, elems
, elemp
, values
);
1547 /* Tests ll_sort on all permutations up to a maximum number of
1550 test_sort_exhaustive (void)
1552 const int max_elems
= 8;
1555 for (n
= 0; n
<= max_elems
; n
++)
1557 struct ll_list list
;
1558 struct element
**elems
;
1561 struct element
**perm_elems
;
1566 allocate_ascending (n
, &list
, &elems
, NULL
, &values
);
1567 allocate_elements (n
, NULL
, &perm_elems
, NULL
, &perm_values
);
1570 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1571 compare_elements
, &aux_data
))
1573 struct ll_list perm_list
;
1576 extract_values (&list
, perm_values
, n
);
1577 ll_init (&perm_list
);
1578 for (j
= 0; j
< n
; j
++)
1580 perm_elems
[j
]->x
= perm_values
[j
];
1581 ll_push_tail (&perm_list
, &perm_elems
[j
]->ll
);
1583 ll_sort (ll_head (&perm_list
), ll_null (&perm_list
),
1584 compare_elements
, &aux_data
);
1585 check_list_contents (&perm_list
, values
, n
);
1586 check (ll_is_sorted (ll_head (&perm_list
), ll_null (&perm_list
),
1587 compare_elements
, &aux_data
));
1590 check (n_perms
== factorial (n
));
1592 free_elements (n
, elems
, NULL
, values
);
1593 free_elements (n
, perm_elems
, NULL
, perm_values
);
1597 /* Tests that ll_sort is stable in the presence of equal
1600 test_sort_stable (void)
1602 const int max_elems
= 6;
1605 for (n
= 0; n
<= max_elems
; n
++)
1606 for (inc_pat
= 0; inc_pat
<= 1 << n
; inc_pat
++)
1608 struct ll_list list
;
1609 struct element
**elems
;
1612 struct element
**perm_elems
;
1618 allocate_elements (n
, &list
, &elems
, NULL
, &values
);
1619 allocate_elements (n
, NULL
, &perm_elems
, NULL
, &perm_values
);
1622 for (i
= 0; i
< n
; i
++)
1624 elems
[i
]->x
= values
[i
] = j
;
1625 if (inc_pat
& (1 << i
))
1631 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1632 compare_elements_y
, &aux_data
))
1634 struct ll_list perm_list
;
1636 extract_values (&list
, perm_values
, n
);
1637 ll_init (&perm_list
);
1638 for (i
= 0; i
< n
; i
++)
1640 perm_elems
[i
]->x
= perm_values
[i
];
1641 perm_elems
[i
]->y
= i
;
1642 ll_push_tail (&perm_list
, &perm_elems
[i
]->ll
);
1644 ll_sort (ll_head (&perm_list
), ll_null (&perm_list
),
1645 compare_elements
, &aux_data
);
1646 check_list_contents (&perm_list
, values
, n
);
1647 check (ll_is_sorted (ll_head (&perm_list
), ll_null (&perm_list
),
1648 compare_elements_x_y
, &aux_data
));
1651 check (n_perms
== factorial (n
));
1653 free_elements (n
, elems
, NULL
, values
);
1654 free_elements (n
, perm_elems
, NULL
, perm_values
);
1658 /* Tests that ll_sort does not disturb elements outside the
1661 test_sort_subset (void)
1663 const int max_elems
= 8;
1665 int n
, r0
, r1
, repeat
;
1667 for (n
= 0; n
<= max_elems
; n
++)
1668 for (repeat
= 0; repeat
< 100; repeat
++)
1669 for (r0
= 0; r0
<= n
; r0
++)
1670 for (r1
= r0
; r1
<= n
; r1
++)
1672 struct ll_list list
;
1673 struct element
**elems
;
1677 allocate_random (n
, &list
, &elems
, &elemp
, &values
);
1679 qsort (&values
[r0
], r1
- r0
, sizeof *values
, compare_ints_noaux
);
1680 ll_sort (elemp
[r0
], elemp
[r1
], compare_elements
, &aux_data
);
1681 check_list_contents (&list
, values
, n
);
1683 free_elements (n
, elems
, elemp
, values
);
1687 /* Tests that ll_sort works with large lists. */
1689 test_sort_big (void)
1691 const int max_elems
= 1024;
1695 for (n
= 0; n
< max_elems
; n
++)
1697 struct ll_list list
;
1698 struct element
**elems
;
1701 allocate_random (n
, &list
, &elems
, NULL
, &values
);
1703 qsort (values
, n
, sizeof *values
, compare_ints_noaux
);
1704 ll_sort (ll_head (&list
), ll_null (&list
), compare_elements
, &aux_data
);
1705 check_list_contents (&list
, values
, n
);
1707 free_elements (n
, elems
, NULL
, values
);
1711 /* Tests ll_unique. */
1715 const int max_elems
= 10;
1717 int *ascending
= xnmalloc (max_elems
, sizeof *ascending
);
1719 int n
, inc_pat
, i
, j
, unique_values
;
1721 for (i
= 0; i
< max_elems
; i
++)
1724 for (n
= 0; n
< max_elems
; n
++)
1725 for (inc_pat
= 0; inc_pat
< (1 << n
); inc_pat
++)
1727 struct ll_list list
, dups
;
1728 struct element
**elems
;
1731 allocate_elements (n
, &list
, &elems
, NULL
, &values
);
1733 j
= unique_values
= 0;
1734 for (i
= 0; i
< n
; i
++)
1736 unique_values
= j
+ 1;
1737 elems
[i
]->x
= values
[i
] = j
;
1738 if (inc_pat
& (1 << i
))
1741 check_list_contents (&list
, values
, n
);
1744 check (ll_unique (ll_head (&list
), ll_null (&list
), ll_null (&dups
),
1745 compare_elements
, &aux_data
)
1746 == (size_t) unique_values
);
1747 check_list_contents (&list
, ascending
, unique_values
);
1749 ll_splice (ll_null (&list
), ll_head (&dups
), ll_null (&dups
));
1750 ll_sort (ll_head (&list
), ll_null (&list
), compare_elements
, &aux_data
);
1751 check_list_contents (&list
, values
, n
);
1753 free_elements (n
, elems
, NULL
, values
);
1759 /* Tests ll_sort_unique. */
1761 test_sort_unique (void)
1763 const int max_elems
= 7;
1766 for (n
= 0; n
<= max_elems
; n
++)
1767 for (inc_pat
= 0; inc_pat
<= 1 << n
; inc_pat
++)
1769 struct ll_list list
;
1770 struct element
**elems
;
1773 struct element
**perm_elems
;
1782 allocate_elements (n
, &list
, &elems
, NULL
, &values
);
1783 allocate_elements (n
, NULL
, &perm_elems
, NULL
, &perm_values
);
1786 for (i
= 0; i
< n
; i
++)
1788 elems
[i
]->x
= values
[i
] = j
;
1790 if (inc_pat
& (1 << i
))
1794 unique_values
= xnmalloc (n_uniques
, sizeof *unique_values
);
1795 for (i
= 0; i
< n_uniques
; i
++)
1796 unique_values
[i
] = i
;
1799 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1800 compare_elements
, &aux_data
))
1802 struct ll_list perm_list
;
1804 extract_values (&list
, perm_values
, n
);
1805 ll_init (&perm_list
);
1806 for (i
= 0; i
< n
; i
++)
1808 perm_elems
[i
]->x
= perm_values
[i
];
1809 perm_elems
[i
]->y
= i
;
1810 ll_push_tail (&perm_list
, &perm_elems
[i
]->ll
);
1812 ll_sort_unique (ll_head (&perm_list
), ll_null (&perm_list
), NULL
,
1813 compare_elements
, &aux_data
);
1814 check_list_contents (&perm_list
, unique_values
, n_uniques
);
1815 check (ll_is_sorted (ll_head (&perm_list
), ll_null (&perm_list
),
1816 compare_elements_x_y
, &aux_data
));
1819 check (n_perms
== expected_perms (values
, n
));
1821 free_elements (n
, elems
, NULL
, values
);
1822 free_elements (n
, perm_elems
, NULL
, perm_values
);
1823 free (unique_values
);
1827 /* Tests ll_insert_ordered. */
1829 test_insert_ordered (void)
1831 const int max_elems
= 6;
1834 for (n
= 0; n
<= max_elems
; n
++)
1835 for (inc_pat
= 0; inc_pat
<= 1 << n
; inc_pat
++)
1837 struct ll_list list
;
1838 struct element
**elems
;
1841 struct element
**perm_elems
;
1847 allocate_elements (n
, &list
, &elems
, NULL
, &values
);
1848 allocate_elements (n
, NULL
, &perm_elems
, NULL
, &perm_values
);
1851 for (i
= 0; i
< n
; i
++)
1853 elems
[i
]->x
= values
[i
] = j
;
1854 if (inc_pat
& (1 << i
))
1860 while (ll_next_permutation (ll_head (&list
), ll_null (&list
),
1861 compare_elements_y
, &aux_data
))
1863 struct ll_list perm_list
;
1865 extract_values (&list
, perm_values
, n
);
1866 ll_init (&perm_list
);
1867 for (i
= 0; i
< n
; i
++)
1869 perm_elems
[i
]->x
= perm_values
[i
];
1870 perm_elems
[i
]->y
= i
;
1871 ll_insert_ordered (ll_head (&perm_list
), ll_null (&perm_list
),
1873 compare_elements
, &aux_data
);
1875 check (ll_is_sorted (ll_head (&perm_list
), ll_null (&perm_list
),
1876 compare_elements_x_y
, &aux_data
));
1879 check (n_perms
== factorial (n
));
1881 free_elements (n
, elems
, NULL
, values
);
1882 free_elements (n
, perm_elems
, NULL
, perm_values
);
1886 /* Tests ll_partition. */
1888 test_partition (void)
1890 const int max_elems
= 10;
1896 for (n
= 0; n
< max_elems
; n
++)
1897 for (r0
= 0; r0
<= n
; r0
++)
1898 for (r1
= r0
; r1
<= n
; r1
++)
1899 for (pbase
= 0; pbase
<= (1u << (r1
- r0
)); pbase
++)
1901 struct ll_list list
;
1902 struct element
**elems
;
1906 unsigned int pattern
= pbase
<< r0
;
1911 allocate_ascending (n
, &list
, &elems
, &elemp
, &values
);
1913 /* Check that ll_find_partition works okay in every
1914 case. We use it after partitioning, too, but that
1915 only tests cases where it returns non-null. */
1916 for (i
= r0
; i
< r1
; i
++)
1917 if (!(pattern
& (1u << i
)))
1921 if (pattern
& (1u << i
))
1923 part_ll
= ll_find_partition (elemp
[r0
], elemp
[r1
],
1927 check (part_ll
== elemp
[j
]);
1929 check (part_ll
== NULL
);
1931 /* Figure out expected results. */
1934 for (i
= 0; i
< r0
; i
++)
1936 for (i
= r0
; i
< r1
; i
++)
1937 if (pattern
& (1u << i
))
1939 for (i
= r0
; i
< r1
; i
++)
1940 if (!(pattern
& (1u << i
)))
1942 if (first_false
== -1)
1946 if (first_false
== -1)
1948 for (i
= r1
; i
< n
; i
++)
1952 /* Partition and check for expected results. */
1953 check (ll_partition (elemp
[r0
], elemp
[r1
],
1954 pattern_pred
, &pattern
)
1955 == elemp
[first_false
]);
1956 check (ll_find_partition (elemp
[r0
], elemp
[r1
],
1957 pattern_pred
, &pattern
)
1958 == elemp
[first_false
]);
1959 check_list_contents (&list
, values
, n
);
1960 check ((int) ll_count (&list
) == n
);
1962 free_elements (n
, elems
, elemp
, values
);
1971 const char *description
;
1972 void (*function
) (void);
1975 static const struct test tests
[] =
2028 "find-adjacent-equal",
2029 "find_adjacent_equal",
2030 test_find_adjacent_equal
2053 "lexicographical-compare-3way",
2054 "lexicographical_compare_3way",
2055 test_lexicographical_compare_3way
2068 "permutations-no-dups",
2069 "permutations (no dups)",
2070 test_permutations_no_dups
2073 "permutations-with-dups",
2074 "permutations (with dups)",
2075 test_permutations_with_dups
2084 "merge (with dups)",
2085 test_merge_with_dups
2089 "sort (exhaustive)",
2090 test_sort_exhaustive
2129 enum { N_TESTS
= sizeof tests
/ sizeof *tests
};
2132 main (int argc
, char *argv
[])
2138 fprintf (stderr
, "exactly one argument required; use --help for help\n");
2139 return EXIT_FAILURE
;
2141 else if (!strcmp (argv
[1], "--help"))
2143 printf ("%s: test doubly linked list (ll) library\n"
2144 "usage: %s TEST-NAME\n"
2145 "where TEST-NAME is one of the following:\n",
2147 for (i
= 0; i
< N_TESTS
; i
++)
2148 printf (" %s\n %s\n", tests
[i
].name
, tests
[i
].description
);
2153 for (i
= 0; i
< N_TESTS
; i
++)
2154 if (!strcmp (argv
[1], tests
[i
].name
))
2156 tests
[i
].function ();
2160 fprintf (stderr
, "unknown test %s; use --help for help\n", argv
[1]);
2161 return EXIT_FAILURE
;